UD Event Saver

By Ben2 Last update May 29, 2008 — Installed 225 times.
// ==UserScript==
// @name           UD Event Saver
// @namespace      -
// @description    To save last 'x' events in Urban Dead
// @include        http://*urbandead.com/map.cgi*
// ==/UserScript==

// Global variables
var gDate = new Date();
var gMaltonTime = window.document.lastModified;

gDate.setDate(parseInt(gMaltonTime.substring(0,2)));
gDate.setMonth(parseInt(gMaltonTime.substring(3,5)));
gDate.setFullYear(parseInt(gMaltonTime.substring(6,10)));
gDate.setHours(parseInt(gMaltonTime.substring(11,13)));
gDate.setMinutes(parseInt(gMaltonTime.substring(14,16)));
gDate.setSeconds(parseInt(gMaltonTime.substring(17)));

var gMilliSecs = Math.floor( gDate.getTime() / 1000) * 1000;
var gUDID = getUDID();
var gCoords = getCoords();
var noEvents = GM_getValue(gUDID + '|pref', 5);
var showEvents = GM_getValue(gUDID + '|show', true);
var movedEvents = 0;
var parsedEvents = new Array();
var oldEvents = new Array();

function divAdd(txt,id) {
	var div = document.createElement('div');
	div.innerHTML = txt;
	div.id = id;
	div.style.textAlign = 'center';
	//div.style.fontWeight = 'bold';
	div.style.display = 'block';
	document.body.insertBefore(div,document.body.firstChild);
}

function parseEvents() {
	var query = "//td[@class='gp']/ul";
	var ul = document.evaluate(query, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null).snapshotItem(0);
	
	// if GM_getValue(key, defaultValue) exist and < noEvents, then pointerKey add
	var pointerKey = 0;
	movedEvents = 0;
	var pointerEvent = ul.childNodes.length - noEvents;
	// while (var i = 0; i < ul.childNodes.length; i++) {
	while (pointerKey < noEvents) {
	    if(pointerEvent > -1) {
    		var li = ul.childNodes[pointerEvent];
    		var liClass = li.className;
    		
    		// <i class="ls">(35 minutes ago)</i>
    		event = li.innerHTML;
    		
    		// Remove UDwidget addCOntact or removeContact
    		var sup1 = event.indexOf('\<sup\>');
    		var sup2 = event.indexOf('\<\/sup\>');
    		if((sup1 != -1) &&(sup2 != -1)) {
    		    event = event.substring(0,sup1) + event.substring(sup2 + 6);
    		}
    		
    		// Replace coordinates with absolute coordinates
    		//'A flare was fired' 11 blocks to the east and 3 blocks to the north.
    		//'You heard a' loud and distant 'groaning' 4 blocks to the west and 4 blocks to the south.
    		// (\d+) block[s] to the (\w+)
    		if((event.indexOf('A flare was fired') > -1) || (event.indexOf('You heard a') > -1)) {
                if(coordArr = event.match(/(\d+) block[s] to the (\w+)/g)) {
                    var diffX = 0;
                    var diffY = 0;
                    //divAdd('l '+coordArr.length)
            		for (var j = 0; j < coordArr.length; j++) {
            		    var element = coordArr[j].match(/(\d+) block[s] to the (\w+)/);
            		    if(element[2].indexOf("north") > -1) {
            				diffY -= parseInt(element[1]);
            			} else if(element[2].indexOf("east") > -1) {
            				diffX += parseInt(element[1]);
            			} else if(element[2].indexOf("south") > -1) {
            				diffY += parseInt(element[1]);
            			} else if(element[2].indexOf("west") > -1) {
            				diffX -= parseInt(element[1]);
            			}
            		}
            		var newCoords = new Array(gCoords[0] + diffX, gCoords[1] + diffY);
            		//(north|east|south|west)
            		if (event.indexOf('A flare was fired') > -1) {
                        var sub1 = event.indexOf('.');
                        event = 'A flare was fired at (' + newCoords.join(',') + ')' + event.substring(sub1);
                    } else if (event.indexOf('You heard a') > -1) {
                        var sub1 = event.indexOf('groaning');
                        var sub2 = event.indexOf('.');
                        event = event.substring(0, sub1 + 8) + ' at (' + newCoords.join(',') + ')' + event.substring(sub2);
                    }
        		//'You heard a' loud 'groaning' from 'very close by'.
        		//'You heard a' low 'groaning' from 'somewhere nearby'.
            	} else { // no coordinates, 'very close by' or 'from somewhere nearby'
                    var sub1 = event.indexOf('groaning');
                    var sub2 = event.indexOf('.');
                    event = event.substring(0, sub1 + 8) + ' at (' + gCoords.join(',') + ')' + event.substring(sub2);
                }
            }
    		
            var timeStrArr;
            var absTimeArr;
            var pointer = 0;
            // <i class="lsf"> OR <i class="lsfe">
            var pos1 = event.indexOf('<i class=\"ls'+ liClass +'\">',pos1); // 14 chars
            var pos2 = event.indexOf('<\/i>', pos1 + 14); // 4 chars
            
            // Multiple timestamps in 1 action
            while ((pos1 > -1)&&(pos2 > -1)) {
                timeStrArr = event.substring(pos1 + 15 + liClass.length, pos2 - 1);
                
                var d = new Date(); 
                d.setTime(gMilliSecs - timeStrToMilliSec(timeStrArr));
                
                var dateFormat = d.toGMTString(); // 'Sun, 20 Apr 2008 12:40:43 GMT'
                absTimeArr = dateFormat.substring(5,25); // '20 Apr 2008 12:40:43'
                
                // Replace timestamp to absolute timestamp
                event = event.substring(0,pos1 + 15 + liClass.length) + absTimeArr + event.substring(pos2 - 1);
                
                // Replace timestamp class to 'lsfe'
                //event.replace(/\s/g, '_');
                if(liClass != 'fe') {
                    var ls = event.indexOf('\"ls\"',pos1);
                    event = event.substring(0,ls) + '\"lsfe\"' + event.substring(ls+4);
                }
                
                pointer++;
                pos1 += 14 + liClass.length;
                pos2 += 4;
                pos1 = event.indexOf('<i class=\"ls'+ liClass +'\">', pos1); // 14 chars
                pos2 = event.indexOf('<\/i>', pos1 + 14); // 4 chars
            }
            
    		//divAdd('<span style="color: #0000ff">('+pointerKey+','+pointerEvent+')</span> ['+event+']-<span style="color: #9999ff">');
    		
    		GM_setValue(gUDID + '|' +pointerKey, event);
    		parsedEvents[pointerKey] = event;
		} else {
            movedEvents++; // No of old events to be moved
        }
		
		pointerKey++;
		pointerEvent++;
	}
	//divAdd('movedEvents: '+ movedEvents);
}

function timeStrToMilliSec(strTime) {
    // <i class="ls">(21 hours and 31 minutes ago)</i>
    // (exactly 9 hours ago)  (7 hours and 34 minutes ago) (1 hour and 35 minutes ago) (3 hours and 1 minute ago)
    // (1 minute ago)  (12 minutes ago)
    // (1 second ago)  (18 seconds ago)
    
	var eventTime = 0;
	if(timeArr = strTime.match(/(\d+) (\w+)/g)) {
		for (var j = 0; j < timeArr.length; j++) {
			var element = timeArr[j].match(/(\d+) (\w+)/);
			var multiplier = 1000;
			if(element[2].indexOf("day") > -1) {
				multiplier = 86400000;
			} else if(element[2].indexOf("hour") > -1) {
				multiplier = 3600000;
			} else if(element[2].indexOf("minute") > -1) {
				multiplier = 60000;
			}
			eventTime += multiplier * element[1];
		}
	} else if(strTime.indexOf("yesterday") > -1) {
		eventTime += 86400000;
	}
	return eventTime;
}

function mainMethod() {
	var query = "//td[@class='gp']/p/b"; // 'Since your last turn:'
	var pb = document.evaluate(query, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	
	// Get saved events
	for(var i=0; i<noEvents; i++) {
        oldEvents[i] = GM_getValue(gUDID + '|' +i, "");
    }
	
	var eventFound = false;
	var i = 0;
	while ((i < pb.snapshotLength) && (!eventFound)) {
	    if (pb.snapshotItem(i).innerHTML.indexOf('Since your last turn:') > -1) {
            eventFound = true;
            
            // save last 'x' events
		    parseEvents();
		    
		    // Move old events
		    if(movedEvents > 0) {
                for(var j=0; j<movedEvents; j++) {
                    parsedEvents[j] = oldEvents[noEvents-movedEvents+j];
                }
            }
            
            // Persist events
            for(var j=0; j<noEvents; j++) {
                GM_setValue(gUDID + '|' +j, parsedEvents[j]);
            }
        }
        i++;
	}
	
	if (!eventFound && showEvents) {
	    //divAdd('Empty!');
	    
	    // Find position to add
        query = "//td[@class='gp']/p";
	    pb = document.evaluate(query, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	    var anchorElement;
	    i = 0;
	    var anchorFound = false;
	    while ((i < pb.snapshotLength) && (!anchorFound)) {
            if (pb.snapshotItem(i).innerHTML.indexOf('Possible actions:') > -1) {
                anchorElement = pb.snapshotItem(i);
                anchorFound = true;
            }
            i++;
        }
	    
        // Create 'Since your last turn'
        var p = document.createElement('p');
        p.className = 'fe';
        p.innerHTML = '<b>Past events:</b>';
        var ul = document.createElement('ul');
        var li;
        eventFound = false;
        for (i=0; i < noEvents; i++) {
            li = document.createElement('li');
            li.className = 'fe';
            var event = GM_getValue(gUDID + '|' +i, "");
            if (event != '') {
                li.innerHTML = event;
                //li.innerHTML = 'test event';
                ul.appendChild(li);
                eventFound = true;
            }
        }
        
        // Insert 'p' and 'ul'
        if (eventFound) {
            anchorElement.parentNode.insertBefore(p, anchorElement);
            anchorElement.parentNode.insertBefore(ul, anchorElement);
        }
    }
}

function getCoords() {
	var query = "//input[@type='hidden' and @name='v']";
	var grid = document.evaluate(query, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	// searches for the top left cell in the map 
	var input = grid.snapshotItem(0);
	if(coords = input.value.match(/^(\d+)-(\d+)$/)) {
		x = parseInt(coords[1]);
		y = parseInt(coords[2]);
		if (grid.snapshotLength == 3) { // 4 corners
			if(x == 98 && y == 98) { x +=1; y += 1; } // bottom-right
			if(x == 0 && y == 98) { y += 1; } // bottom-left
			if(x == 98 && y == 0) { x +=1; } // top-right
			if(x == 0 && y == 1) { y -= 1; } // top-left
		} else if(grid.snapshotLength == 5) { // 4 borders
			if(x == 98 || y == 98) { x +=1; y += 1; } // bottom OR right
			if(y == 0) { x +=1; } // top
			if(x == 0) { y += 1; } // left
		} else { // snapshotLength = 8 -> normal
			x += 1;
			y += 1;
		}
	}
	var out = new Array(x,y);
	
	return out;
}

function getUDID() {
	var query = "//p[@class='gt']";
	var grid = document.evaluate(query, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);
	for(var i = 0; i < grid.snapshotLength; i++) {
		var pText = grid.snapshotItem(i).innerHTML;
		//divAdd(pText);
		if(matches = pText.match(/You are <a href=\"profile\.cgi\?id=([0-9]+)\">/))
			return matches[1];
		else if(matches = pText.match(/<li><a href=\"profile\.cgi\?id=([0-9]+)\">/))
			return matches[1];
	}
	return -1;
	//return 'dummy';
}

function setPref() {
    var userPref = prompt('Please insert new number',noEvents);
    if (!isNaN(userPref)) {
        GM_setValue(gUDID + '|pref', userPref);
        //divAdd(userPref);
    } else {
        alert('Please insert only numbers!');
    }
}

function setShow() {
    var showPref = confirm('Show past events?');
    //divAdd(showPref);
    GM_setValue(gUDID + '|show', showPref);
    showEvents = showPref;
}

window.addEventListener(
    'load', 
    function() {
        GM_registerMenuCommand( "Set no of events", setPref, "", "", "s" );
        GM_registerMenuCommand( "Toggle show past events", setShow, "", "", "t" );
        
    	//divAdd('CurrentTime: '+ gDate.toGMTString(), 'time');
    	
    	//divAdd('CurrentCoords: ' + getCoords().join(','));
    	mainMethod();
	},
    true);