``` // ==UserScript== // @name AutoFarm Asisstent - Multe sate // @namespace http://tw.radu-stoica.ro // @version 1.0 // @description Automation for Loot Assistant // @author Stamatescu // @match https://*.triburile.ro/*screen=am_farm* // @match https://*.tribalwars.net/*screen=am_farm* // @grant none // ==/UserScript== (function() { 'use strict'; let defaultSettings = {interval: 250, pause: 300, next_time: 5, last: 0, running:false, continue_last:false, bot_attemps:0, group: null, villages: 0, village_counter: 1, date_stop:"", bot_alert:false, sent:0, distance_A:"", distance_B:"", time_h_A:"", time_m_A:"", time_s_A:"", time_h_B:"", time_m_B:"", time_s_B:"", prevent_clashing:false}; let lastPage = parseInt($('.paged-nav-item:last').text().replace(/[^0-9]/g, '')); let villageList = []; let sent=0; let counter=0; let templateKey = []; let unitData = []; let groups; let currGroup; let currVillage = game_data.village.id; let lastVillage = getData('last'); let totalSent = getData('sent'); let fetchFailCounter=0; let ToolTips = { info: "Last update: 07.12.2021<br>Current version: 1.0<br><br> <img alt='Mnk' src='https://tw.radu-stoica.ro/images/16.png' />Mnk Platform &copy; 2018", interval: "Interval between attacks", pause: "Pause time before restart", continue_last: "Continue from last attacked village", bot_alert: "Play alarm for bot check", village_counter: "Village counter", bot_attemps: "Number of bot attemps", sent_counter: "Number of sent attacks on this time from this village", sent: "Total number of sent attacks", timer: "Countdown before next action <br/>Color actions:</br><span style='color:green'>Pause (two villages)</span> <br/><span style='color:red'>Pause (multiple villages)</span> <br/><span style='color:blue'>Next village</span>" }; function getData(data){ if(!window.localStorage.getItem('Mnk')){ window.localStorage.setItem('Mnk', "{}"); } if(!JSON.parse(window.localStorage.getItem('Mnk')).farm){ let currentSettings = JSON.parse(window.localStorage.getItem('Mnk')); currentSettings.farm = defaultSettings; window.localStorage.setItem('Mnk', JSON.stringify(currentSettings)); return defaultSettings[data]; }else{ if(!JSON.parse(window.localStorage.getItem('Mnk')).farm[data]){ setData(data, defaultSettings[data]); return defaultSettings[data]; } } return JSON.parse(window.localStorage.getItem('Mnk')).farm[data]; } function setData(data, value){ let currentSettings = JSON.parse(window.localStorage.getItem('Mnk')); currentSettings.farm[data] = value; window.localStorage.setItem('Mnk', JSON.stringify(currentSettings)); } function multipleVillages(){ if($('#menu_row2 .village_switch_link').length) return true; return false; } function playAlarm(){ if(!$('#Mnk_alarm').length && getData('bot_alert')) $('<audio id="Mnk_alarm" autoplay="autoplay" style="display:none;" loop>' + '<source src="https://tw.radu-stoica.ro/audio/bot.ogg" />' + '<embed src="https://tw.radu-stoica.ro/audio/bot.ogg" hidden="true" autostart="true" loop="true"/>' + '</audio>' ).appendTo('body'); } function stopAlarm(){ if($('#Mnk_alarm').length) $("#Mnk_alarm").remove(); } function botCheck(){ if($('#bot_check').length){ playAlarm(); return true; } stopAlarm(); return false; } function playerMultipleVillages(){ if(parseInt(game_data.player.villages) > 1) return true; else return false; } function dateTime(){ let currDate = new Date(); let date = currDate.getFullYear() + '-' + ('0' + currDate.getMonth()).slice(-2) + '-' + ('0' + currDate.getDate()).slice(-2); let hour = ('0' + currDate.getHours()).slice(-2) + ':' + ('0' + currDate.getMinutes()).slice(-2) + ':' + ('0' + currDate.getSeconds()).slice(-2); return date+'T'+hour; } function generatePanel(){ let panel = "<div class='vis' id='Mnk_farm'>"+ "<h4 style='text-align:center;'><img src='https://tw.radu-stoica.ro/images/16.png' />[Mnk] AutoFarm <img id='img_info' src='https://tw.radu-stoica.ro/images/16info.png' style='float:right'></h4>"+ "<table style='width:100%;'>"+ "<tr>"+ "<td><label for='interval'><img id='img_interval' src='https://tw.radu-stoica.ro/images/16watch.png' /> <input type='number' id='interval' min='200' value='" + getData('interval') + "' /> (ms)</label></td>"+ "<td><label for='pause'><img id='img_pause' src='https://tw.radu-stoica.ro/images/16sleep.png' /> <input type='number' id='pause' min='30' value='" + getData('pause') + "' /> (s)</label></td>"+ "<td><button id='reset' class='btn'>Reset Settings</button></td>"+ "<td><button id='start_stop' class='btn'>" + (getData('running') ? "Stop" : "Start") + "</button></td>"+ "</tr></table><table style='width:100%;'><tr>"+ "<td rowspan='2'><label for='date_stop'>Stop script at: <input type='datetime-local' id='date_stop' min='" + dateTime() + "' value='" + getData('date_stop') + "' step='1' /></label></td>"+ "<td><b>A</b></td>"+ "<td><label for='distance_A'>Maximum distance: <input type='number' id='distance_A' min='1' value='" + getData('distance_A') + "'/>(fields)</label></td>"+ "<td>Maximum time: <span id='time'><input type='number' id='time_h_A' min='0' value='" + getData('time_h_A') + "'/>:<input type='number' id='time_m_A' min='0' max='59' value='" + getData('time_m_A') + "'/>:<input type='number' id='time_s_A' min='0' max='59' value='" + getData('time_s_A') + "'/></span></td>"+ "</tr><tr><td><b>B</b></td>"+ "<td><label for='distance_B'>Maximum distance: <input type='number' id='distance_B' min='1' value='" + getData('distance_B') + "'/>(fields)</label></td>"+ "<td>Maximum time: <span id='time'><input type='number' id='time_h_B' min='0' value='" + getData('time_h_B') + "'/>:<input type='number' id='time_m_B' min='0' max='59' value='" + getData('time_m_B') + "'/>:<input type='number' id='time_s_B' min='0' max='59' value='" + getData('time_s_B') + "'/></span></td>"+ "</tr></table><table style='width:100%;'><tr>" + "<td><label for='continue_last'><input type='checkbox' id='continue_last' " + (getData('continue_last') ? 'checked' : '') + "/> <img id='img_continue_last' src='https://tw.radu-stoica.ro/images/16lock.png' /></label></td>"+ "<td><label for='bot_alert'><input type='checkbox' id='bot_alert' " + (getData('bot_alert') ? 'checked' : '') + "/> <img id='img_bot_alert' src='https://tw.radu-stoica.ro/images/16alarm.png' /></label></td>"+ "<td><label for='prevent_clashing'><input type='checkbox' id='prevent_clashing' " + (getData('prevent_clashing') ? 'checked' : '') + "/> Prevent clashing commands</label></td>"+ "<td><label for='explain'>I farm B then A</label></td>"+ "</tr></table>"; if(multipleVillages()) panel += "<table style='width:100%;'><tr>"+ "<td><label for='next_time'>Change village after: <input type='number' id='next_time' min='0' value='" + getData('next_time') + "' /> (s)</label></td>"+ "<td><img id='img_village_counter' src='https://tw.radu-stoica.ro/images/18village.png' /> <span id='counter'>" + Format.number(getData('village_counter')) + "/" + Format.number(getData('villages')) + "</span></td>"+ "<td><button id='reset_counter' class='btn'>Reset Counters</button></td>"+ "</tr></table>"; if(game_data.features.Premium.active && playerMultipleVillages() && groups.length > 1){ panel+="<table style='width:100%;'><tr>"+ "<td>Farm from:<select id='group'>"; groups.forEach(function(val){ if(val.group_id) panel += "<option value='" + val.group_id + "' "+((currGroup == val.group_id) ? 'selected' : '')+">" + val.name + "</option>"; else panel += "<option disabled></option>"; }); panel += "</select></td></tr></table>"; } panel += "<table style='width:100%'><tr>"+ "<td><img id='img_bot_attemps' src='https://tw.radu-stoica.ro/images/16bot.png' /> <span id='bot_attemps'>" + Format.number(getData('bot_attemps')) + "</span></td>" + "<td><img id='img_sent_counter' src='https://tw.radu-stoica.ro/images/16arrowrightgreen.png' /> <span id='sent_counter'>-</span></td>"+ "<td><img id='img_sent' src='https://tw.radu-stoica.ro/images/16arrowrightred.png' /> <span id='sent'>" + Format.number(totalSent) + "</span>"+ "<td><img id='img_timer'src='https://tw.radu-stoica.ro/images/16refresh.png' /> <span id='timer'>-</span></td>"+ "</tr></table></div>"; $(panel).insertBefore("#am_widget_Farm"); } function messageBox(msg, type = "error", time = 5000){ let content = "<table style='width:100%'><tr><td style='width:100px'><img alt='Mnk' src='https://tw.radu-stoica.ro/images/32.png' /></td><td>" + msg + "</td></tr></table>"; return UI.InfoMessage(content, time, type); } function eraseList(){ $('#plunder_list tbody tr:nth-child(n+3)').remove(); if($('#plunder_list_nav').length) $('#plunder_list_nav').remove(); } function fetchList(first = 0, last = lastPage){ if(first < last){ let url = location.origin + game_data.link_base_pure + "am_farm&order=distance&dir=asc&Farm_page=" + first; if(!botCheck()){ $.get(url,function(data){ $("#plunder_list tr:nth-child(n+3)", data).each(function(i, content){ $("#plunder_list tr:last").after(content); }); fetchList( (first+1) , last); }).fail(function(first, last, url){ messageBox("Getting page " + first + "/" + last + " failed... <br> URL: " + url); console.error("Getting page " + first + "/" + last + " failed... \n URL: " + url); fetchFailCounter++; if(fetchFailCounter==10) location.reload(); fetchList(first, last); }); }else{ setData('bot_attemps', getData('bot_attemps') + 1); var botSolveCheck = setInterval(function(){ if(!botCheck()){ clearInterval(botSolveCheck); fetchList(first, last); } }, 2000); } }else{ $.each($("#plunder_list tr td:nth-child(8)"), function(i,val){ let village = {distance: parseFloat($(this).text()), link: $(this).next().find('.farm_icon_a'), link2: $(this).next().next().find('.farm_icon_b')}; villageList[i] = village; }); $('#Mnk_farm #sent_counter').html("<span id='sent_now'>0</span>/" + Format.number(villageList.length)); Accountmanager.farm.reloadPlunderWidget(); attack( (getData('continue_last') ? (getData('last')+1) : 0 )); } } function finished(){ let time; let action; if(!multipleVillages()){ $("#Mnk_farm #timer").css('color', 'green'); time = parseInt(getData('pause')); time += -200*Math.random(); action = function(){ location.reload(); }; }else{ if(getData('village_counter') < getData('villages')){ $("#Mnk_farm #timer").css('color', 'blue'); time = parseInt(getData('next_time')); time += 15*Math.random(); setData('village_counter', (getData('village_counter')+1)); }else{ $("#Mnk_farm #timer").css('color', 'red'); time = parseInt(getData('pause')); time += 100*Math.random(); setData('village_counter', 1); } action = function(){ $('#menu_row2 #village_switch_right span').click(); }; } time = Math.round(time); Timing.tickHandlers.timers.initTimer($('#Mnk_farm #timer'), parseInt(Date.now()/1e3 + time), function(){action();}, parseInt(Date.now()/1e3), true); } function attack(i=0){ if(getData('running')){ if(getData('prevent_clashing') && (!TribalWars.isTabActive() && TribalWars.isAnyTabActive())){ let preventClashingCheck = setInterval(function(){ if(TribalWars.isTabActive() || !TribalWars.isAnyTabActive()){ clearInterval(preventClashingCheck); attack(i);} },1000); return; } if(villageList.length){ if(!botCheck()){ let valid = 2; let time = (parseInt(getData('interval'))+Math.random()*200); console.log(villageList[i]); if(villageList[i] !== undefined && villageList[i].distance && counter<villageList.length && Accountmanager.farm.unitsAppearAvailableAB(templateKey[1]) && !(getData('distance_B') && parseFloat(getData('distance_B')) < villageList[i].distance)){ valid = 2; time = (parseInt(getData('interval'))+Math.random()*200); if(i==villageList.length) i=0; if(getData('date_stop')){ if(new Date(getData('date_stop')) < new Date()) $("#Mnk_farm #start_stop").click(); } if(getData('time_h_B') || getData('time_m_B') || getData('time_s_B')){ if(unitData[0].speed*villageList[i].distance*60 > (getData('time_h_B')*3600 + getData('time_m_B')*60 +getData('time_s_B'))){ valid = 0; time=1; } } if(getData('distance_B') && parseFloat(getData('distance_B')) < villageList[i].distance){ valid = 0; time = 1; } if(valid == 2){ villageList[i].link2.click(); setData('last', i); setData('sent', (++totalSent)); $('#Mnk_farm #sent_now').html(Format.number(++sent)); $('#Mnk_farm #sent').html(Format.number(totalSent)); } setTimeout(function(){attack(i+1);}, time); counter++; }else if(counter<villageList.length && Accountmanager.farm.unitsAppearAvailableAB(templateKey[0])){ valid = 1; time = (parseInt(getData('interval'))+Math.random()*200); if(i==villageList.length) i=0; if(getData('date_stop') && valid == 1){ if(new Date(getData('date_stop')) < new Date()) $("#Mnk_farm #start_stop").click(); } if(getData('time_h_A') || getData('time_m_A') || getData('time_s_A')){ if(unitData[0].speed*villageList[i].distance*60 > (getData('time_h_A')*3600 + getData('time_m_A')*60 +getData('time_s_A')) && valid == 1){ valid = 0; time=1; } } if((getData('distance_A') && parseFloat(getData('distance_A')) < villageList[i].distance) && valid == 1){ valid = 0; time = 1; } if(valid == 1){ villageList[i].link.click(); setData('last', i); setData('sent', (++totalSent)); $('#Mnk_farm #sent_now').html(Format.number(++sent)); $('#Mnk_farm #sent').html(Format.number(totalSent)); } setTimeout(function(){attack(i+1);}, time); counter++; }else finished(); }else{ setData('bot_attemps', getData('bot_attemps') + 1); $('#bot_attemps').text(Format.number(getData('bot_attemps'))); var botSolveCheck = setInterval(function(){ if(!botCheck()){ clearInterval(botSolveCheck); attack(i); } }, 2000); } }else attack(i); }else setData('last', i); } function eventActions(){ $('#Mnk_farm input[type=number]').change(function(){ setData(this.id, this.value); }); $('#Mnk_farm input[type=checkbox]').change(function(){ setData(this.id, this.checked); }); $('#Mnk_farm input[type=datetime-local]').change(function() { setData(this.id, this.value); }); $('#Mnk_farm select').change(function(){ setData(this.id, this.value); changeGroup(this.value); }); $('#Mnk_farm #start_stop').click(function(){ setData('running', !getData('running')); if(getData('running')){ if(new Date(getData('date_stop')) < new Date()){ $("#Mnk_farm input[type=datetime-local]").val(""); setData('date_stop',""); } $(this).text('Stop'); messageBox('[Mnk] AutoFarm <br /> Script successfully started!', 'success'); attack(getData('last')); }else{ $(this).text('Start'); messageBox('[Mnk] AutoFarm <br/> Script successfully stopped !', 'success'); } }); $('#Mnk_farm #reset_counter').click(function(){ let reset = ['bot_attemps', 'sent']; setData('village_counter', 1); $('#Mnk_farm #counter').html("1/" + Format.number(getData('villages'))); $.when($.each(defaultSettings, function(key,val){ if(Object(reset).includes(key)) setData(key,val);})).then(function(){ messageBox('Counters successfully reseted. <br/> Please wait ...', 'success', 2500); setTimeout(function(){ location.reload();}, 3000); }); }); $('#Mnk_farm #reset').click(function(){ let no_reset = ['running', 'bot_attemps', 'sent']; $.when($.each(defaultSettings, function(key,val){ if(!((Object(no_reset).includes(key)))) setData(key,val);})).then(function(){ messageBox('Settings successfully reseted. <br/> Please wait ...', 'success', 2500); setTimeout(function(){ location.reload();}, 3000); }); }); } function changeGroup(g_id){ $.post('/game.php?village=' + currVillage + '&screen=groups&ajax=load_villages_from_group&mode=overview', {mode: 'overview', group_id: g_id}, function(response){ let html = document.createElement('div'); html.innerHTML = response.html; if(html.querySelectorAll('a').length){ setData('villages', html.querySelectorAll('a').length); setData('village_counter', 1); setData('group', g_id); location.href = html.querySelectorAll('a')[0].href; } else{ setData('group', "0"); changeGroup("0"); } }); } function checkGroup(){ let farmGroup; $.get(villageDock.loadLink, function(response){ currGroup = response.group_id; groups = response.result; groups.forEach(function(data){ if(data.group_id == getData('group')) farmGroup = data.group_id; }); }).then(function(){ if(farmGroup){ if(farmGroup !== currGroup) changeGroup(farmGroup); }else changeGroup("0"); setScript(); }); } function setGameSettings(){ if(Accountmanager.farm.page_size !== 100) Accountmanager.farm.setPageSize(100); if(!$('#attacked_checkbox:checked').length) {$('#attacked_checkbox').click(); } templateKey[0] = Object.keys(Accountmanager.farm.templates)[0].match(/[\d]/g).join(''); templateKey[1] = Object.keys(Accountmanager.farm.templates)[1].match(/[\d]/g).join(''); unitData[0] = Accountmanager.farm.templates["t_"+templateKey[0]]; $.get('/interface.php?func=get_unit_info', function(data){$.each($(data).find('speed'), function(){ if(Object.keys(unitData[0]).includes($(this).parent().prop('tagName'))) if(!unitData[0].speed || unitData[0].speed < parseFloat($(this).text())) unitData[0].speed = parseFloat($(this).text()); }); }); } function setStyles(){ $("#Mnk_farm span").css('font-weight', 'bold'); $("#Mnk_farm input[type=number]").css('width', '36px'); $("#Mnk_farm #time").css('white-space', 'nowrap'); } function generateToolTips(){ $.each(ToolTips, function(key, text){ let t = $('#Mnk_farm #img_'+key); t.attr('title', text); UI.ToolTip(t); }); } function setScript(){ $.when(setGameSettings()).then(generatePanel()).then(eraseList()).then(fetchList()).then(setStyles()).then(eventActions()).then(generateToolTips); } $(document).ready(function(){ if(playerMultipleVillages() && game_data.features.Premium.active) checkGroup(); else setScript(); }); })(); ```