---
# System prepended metadata

title: farm

---

```
// ==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();
    });

})();
```