User script

From GreaseSpot Wiki
Revision as of 11:12, 10 February 2010 by 110.164.87.168 (talk)
Jump to navigationJump to search

// ==UserScript== // @name Travian Building Mover // @namespace Travian Building Mover // @description This repositions the buildings on the dorf2.php page // @version 1.5.1 // @include http://*.travian.*/dorf2.php* // @license GPL 3 or any later version // ==/UserScript==

/*****************************************************************************

* Copyright (C) 2009 Adriaan Tichler
*
* This is free software; you can redistribute it and/or modify it under the
* terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Public License for more details
*
* To obtain a copy of the GNU General Public License, please see
* <http://www.gnu.org.licenses/>
*****************************************************************************/

// First, get the user mappings... var mapping = eval(GM_getValue('mapping', '({})'));

function reset_vil(){

   if (!window.confirm("Reset this village's buildings to their original position?")) return;
   delete mapping[did];
   GM_setValue('mapping', uneval(mapping));
   location.reload();

}

// Register these first, in case the script fails later and we still want to reset things GM_registerMenuCommand("BM: Reset this village's buildings", reset_vil); GM_registerMenuCommand("BM: Reset all buildings", function(){

       if (!window.confirm("Reset all buildings in all villages to their original position?")) return;
       GM_setValue('mapping', '({})');
       location.reload();
   });
// Init

var server = location.host; var uid = document.evaluate("id('side_navi')//a[contains(@href, 'spieler.php')]/@href", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue.textContent.match(/uid=(\d+)/)[1];

// Add support for the 'toggle building levels' button, so we can make it persistent // Otherwise, this value keeps getting cleared whenever cookies get cleared, which for the more paranoid of us would be every time the browser restarts ;-) var toggle = eval(GM_getValue('show_building_level', '({})')); var button = document.getElementById('lswitch'); if (button != undefined){

   var current_toggle = button.className == "on";
   // If we don't have a saved setting for this server and user, then take the present value of the toggle
   if (toggle[server+'_'+uid] == undefined){
       toggle[server+'_'+uid] = current_toggle;
       GM_setValue('show_building_level', uneval(toggle));
   }
   // Otherwise, correct the value of the toggle to what we have saved
   // *note* calling vil_levels_toggle() in this fashion is safer than using unsafeWindow, because unsafeWindow would elevate the privilege of the function.
   else if (current_toggle != toggle[server+'_'+uid]) location.href = "javascript:void(vil_levels_toggle());";
   // Either way, add a listener to update our version of the toggle when it's clicked
   button.addEventListener('click', function(){
           toggle[server+'_'+uid] = !toggle[server+'_'+uid];
           GM_setValue('show_building_level', uneval(toggle));
       }, false);

}

// Look at where the original buildings are *first* var data = []; var poly = document.getElementById('map2').childNodes; var img = document.getElementById('map2').nextSibling.nextSibling.childNodes;

// Raw_num won't have the right number of elements if there are unused building spots in the village var num = []; var raw_num = document.getElementById('village2_levels'); // Some servers use a different ID... if (raw_num == undefined) raw_num = document.getElementById('levels'); if (raw_num != undefined){

   raw_num = raw_num.childNodes;
   for (var i in raw_num){
       if (raw_num[i].className == undefined || raw_num[i].className.indexOf('level') >= 0) continue; // Don't do walls, closing divs, or the rally point
       num[raw_num[i].className.split('d')[1] - 0] = raw_num[i]; // re-index these nodes so they don't get mistakenly translated by an empty spot
   }

}

// Store the current info about all of the buildings... for (var i=1; i <= 20; i++){

   data[i] = [];
   //GM_log(i + ' ' + img[i].alt + ' | ' + poly[i].title);
   data[i]['className'] = img[i].className.split(' ')[2];
   if (num[i] != undefined) data[i]['num'] = num[i].className;
   data[i]['title'] = poly[i].title;
   data[i]['href'] = poly[i].href;

}

// Get the active village, to store the new mappings // We don't have to worry about postfixes because we're only running on one page var did = document.evaluate('//tr[@class="sel"]/td[@class="text"]/a', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; if (did) did = did.href.match('newdid=([0-9]*)')[1]; else {

   // If this fails, there's a possibility that we're just running the other type of travian (??? still 3.5, but with different code...)
   did = document.evaluate('//table[@id="vlist"]/tbody/tr/td[@class="dot hl"]', document, null, XPathResult.ANY_UNORDERED_NODE_TYPE,null).singleNodeValue;
   if (did) did = did.parentNode.innerHTML.match('newdid=([0-9]*)')[1];

} // Single village support courtesy of Booboo if (!did) {

   var single_villages = eval(GM_getValue('single_villages', '({})'));
   if (!single_villages[server + "_" + uid]){

GM_xmlhttpRequest({

               method: 'GET',
               url: "http://" + server + "/dorf3.php",
               onload: function(xhr){
                   var did = xhr.responseText.match(/newdid=(\d+)/)[1];
                   single_villages[server + "_" + uid] = did;
                   GM_setValue('single_villages', uneval(single_villages));
                   window.location.reload();
               }
           });
       return;
   }
   else did = single_villages[server + "_" + uid];

}

if (mapping[did] == undefined) mapping[did] = {};

// This moves a building from src to dest. function move(dest, src){

   //GM_log('Moving '+src+' to '+dest);
   var base = img[dest].className.split(' '); // We only change the last part of the class name
   img[dest].className = base[0]+' '+base[1]+' '+data[src].className;
   if (num[src] != undefined) num[src].className = 'd'+dest; // Move the building numbers. This goes backwards from everything else...
   poly[dest].title = data[src].title;
   poly[dest].href = data[src].href;

}

// The index is the destination, the value the source for (var i in mapping[did]) move(i, mapping[did][i]);

// Get input from the user... add the moving truck. var div = document.createElement('div'); div.setAttribute('style', 'position:absolute; top:489px; left:163px; padding:2px; z-index:100; border:none; cursor:pointer'); div.innerHTML = '<img title="Swap Buildings" src="data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/4QCURXhpZgAASUkqAAgAAAABAGmHBAABAAAAGgAAAAAAAAABAIaSBwBgAAAALAAAAAAAAABBU0NJSQAAAFdpbmRvd0V4dDogMzAzNSwgMjY3NA1XaW5kb3dPcmc6IDAsIDANQ29udGVudDogMTAsIDI2LCAzMDEyLCAyNjcyDUlnbm9yZWQgT3Bjb2RlczoNJDEwNQD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAcACEDASIAAhEBAxEB/8QAGQAAAwEBAQAAAAAAAAAAAAAAAAcIBgED/8QAMRAAAgIBAwMCAwUJAAAAAAAAAQIDBAUGERIABxMhMQgVFxQiMmGUIzRRUlNWcZHS/8QAGAEBAAMBAAAAAAAAAAAAAAAABQAEBgH/xAAkEQABAwMDBAMAAAAAAAAAAAABAAIDBBExEiEiBRRRYUFSwf/aAAwDAQACEQMRAD8AoP4khmPoxqF8FlbmJvRRxSpbqTtDLEqTxtIVdSCPuBh+e/UNyYPW8unY83FqS/NesTeCpG1mQ2rTjcSEFSTupjb3A9Nt2I2DXN3uzWLl7Sa2px2uVk4G+EVY2P3xBJt7D+PUZZm/Rg7lYiOu9z5LirMzJY8TVuAmaWWX9oxU7gsoB5KNh6b9F175w5ojxuceFcpGsJ5Khuxd7WmE0hJmEzGd1VjPmVmGShkyzXEhifxcq7OeXNWjfeF2Kt6cSjDZ35iMlQzGMr5PHTpYqWI/JFIu+zL/AIPqD+R9R0kex+pdOVu2tQ2M5jqvK/kZeNi+hYK96wykuWPL0P4tzv779ZrSmu27e5HIaiuajqZTT2dyd94MYbpHgX7XMyzQMzuhaVWJEYESMCrEjg7HL9F6/UPrZ6asHFruBsd/WLbeVJ4m5Yqe4j+dv99HWJ+o+nP6l79M/wD10dbfu4fsqtnrHfEm+PuURpDGN5NT5pAVroRwirhwWsTggjx7rwCkHy7lOLDmVUGL7ZrrCtFofQjY6pisFMnzPMT0o53uWVIYxBSNnCkqWDNsAVADbb9eT53J2e8Wd00bLRS5vUjUrWXT9+WE2jCqo53RQkahVHDYe+2/r1V2h9M4XSWHjweCpitSqjxxruWYj8RLMfUks7Ek+5Y9IEiOK4y5BxskrKxz3u4RYHk/JP4oqxvw0d6slnaz5VcNQr17CFZRPD4I039WjhjHEbbctuI3J3I39enlW+FrSlqtTj1RqDMZZqcgKGAmBZYw0hIlVjJzdg4VnUo2yLx4kEmhB109HljL3tum9RS/+jHa3+wdO/oV6Ot90dTX6XdRX//Z">'; document.body.appendChild(div);

function notify(msg){

   var div = document.createElement('div');
   div.setAttribute('style', 'position:absolute; top:350px; left:400px; padding:2px; z-index:160; border:solid black 1px; background:#fff; -moz-border-radius:5px;');
   div.innerHTML = msg;
   document.body.appendChild(div);
   window.setTimeout(function(){div.parentNode.removeChild(div);}, 2000);

}

var truck_stage = 0; div.addEventListener('click', function(){

       // If the truck gets clicked a second time...
       if (truck_stage == 1){
           reset_vil();
           return;
       }
       truck_stage++;
       div.childNodes[0].title = 'Restore building positions';
       // Add listeners to all of the objects
       var stage = 0;
       var src;
       // Cut all of the village links, so clicking on the villages no longer redirects
       // Also, store index info in here - it's the easiest way I can think of getting this info to the click listener routine
       for (var i in poly)
           if (poly[i].href != undefined)
               poly[i].href = '#'+(poly[i].href.split('id=')[1] - 18);
       var wall = document.getElementById('map1').childNodes;
       for (var i in wall)
           if (wall[i].href != undefined)
               wall[i].href = '#22';
       // Listen for a click on each building
       for (var i in poly) poly[i].addEventListener('click', function(e){
               var dest = e.target.href.split('#')[1]; // Extract the index info from above
               // Error conditions
               if (dest == '21'){
                   notify('You cannot move the rally point');
                   return;
               }
               if (dest == '22'){
                   notify('You cannot move the walls');
                   return;
               }
               // This is the first click
               if (stage == 0){
                   src = dest; // actually...
                   notify('Click on the second one');
                   stage++;
               } else { // Now we have to save said data
                   var m = mapping[did];
                   //GM_log('src='+src+' dest='+dest);
                   // First, find who *holds* src right now
                   var temp = src;
                   while (m[temp] != undefined && m[temp] != src) temp = m[temp];
                   // Find who *holds* dest right now
                   var temp2 = dest;
                   while (m[temp2] != undefined && m[temp2] != dest) temp2 = m[temp2];
                   //GM_log('m['+temp+']='+dest);
                   //GM_log('m['+temp2+']='+src);
                   m[temp] = parseInt(dest);
                   m[temp2] = parseInt(src);
                   GM_setValue('mapping', uneval(mapping));
                   window.location.reload();
               }
           }, false);
       notify('Click on the first building');
   }, false);