Fichier #tsfgrh03-3478 - JAVASCRIPT - Code source

Téléchargé par Domnic Harris - 20/07/2010 0:11 - 57 affichages
Code source
  1. // ==UserScript==
  2. // @name           FallenSwordHelper
  3. // @namespace      terrasoft.gr
  4. // @description    Fallen Sword Helper
  5. // @include        http://www.fallensword.com/*
  6. // @include        http://fallensword.com/*
  7. // @include        http://*.fallensword.com/*
  8. // @exclude        http://forum.fallensword.com/*
  9. // @exclude        http://wiki.fallensword.com/*
  10. // @require        json2.js
  11. // @require        calfSystem.js
  12. // @require        fsLayout.js
  13. // @require        fsData.js
  14. // ==/UserScript==
  15.  
  16. // No warranty expressed or implied. Use at your own risk.
  17.  
  18. var Helper = {
  19. 	// System functions
  20. 	init: function (e) {
  21. 		Helper.initSettings();
  22. 		Helper.beginAutoUpdate();
  23. 		Helper.readInfo();
  24. 		this.initialized = true;
  25. 	},
  26.  
  27. 	initSettings: function () {
  28. 		System.setDefault("currentTile", "");
  29. 		System.setDefault("lastActiveQuestPage", "");
  30. 		System.setDefault("lastCompletedQuestPage", "");
  31. 		System.setDefault("lastNotStartedQuestPage", "");
  32. 		System.setDefault("questBeingTracked", "");
  33. 		System.setDefault("lastWorld", "");
  34. 		System.setDefault("questsNotStarted", false);
  35. 		System.setDefault("questsNotComplete", false);
  36. 		System.setDefault("checkForQuestsInWorld", false);
  37. 		System.setDefault("enableLogColoring", true);
  38. 		System.setDefault("enableChatParsing", true);
  39. 		System.setDefault("enableCreatureColoring", true);
  40. 		System.setDefault("showCombatLog", true);
  41. 		System.setDefault("showCreatureInfo", true);
  42. 		System.setDefault("keepLogs", false);
  43.  
  44. 		System.setDefault("showExtraLinks", true);
  45. 		System.setDefault("huntingBuffs", "Doubler,Librarian,Adept Learner,Merchant,Treasure Hunter,Animal Magnetism,Conserve");
  46. 		System.setDefault("showHuntingBuffs", true);
  47. 		System.setDefault("moveFSBox", false);
  48.  
  49. 		System.setDefault("guildSelf", "");
  50. 		System.setDefault("guildFrnd", "");
  51. 		System.setDefault("guildPast", "");
  52. 		System.setDefault("guildEnmy", "");
  53. 		System.setDefault("goldRecipient", "");
  54. 		System.setDefault("goldAmount", "");
  55. 		System.setDefault("sendGoldonWorld", false);
  56. 		System.setDefault("goldConfirm", "");
  57. 		System.setDefault("guildSelfMessage", "green|Member of your own guild");
  58. 		System.setDefault("guildFrndMessage", "yellow|Do not attack - Guild is friendly!");
  59. 		System.setDefault("guildPastMessage", "gray|Do not attack - You've been in that guild once!");
  60. 		System.setDefault("guildEnmyMessage", "red|Enemy guild. Attack at will!");
  61.  
  62. 		System.setDefault("hideKrulPortal", false);
  63. 		System.setDefault("hideQuests", false);
  64. 		System.setDefault("hideQuestNames", "");
  65. 		System.setDefault("hideRecipes", false);
  66. 		System.setDefault("hideRecipeNames", "");
  67. 		System.setDefault("hideBanner", false);
  68. 		System.setDefault("showSTUpTop", true);
  69. 		System.setDefault("footprintsColor", "silver");
  70. 		System.setDefault("enableGuildInfoWidgets", true);
  71. 		System.setDefault("guildOnlineRefreshTime", 300);
  72. 		System.setDefault("hideGuildInfoSecureTrade", false);
  73. 		System.setDefault("hideGuildInfoTrade", false);
  74. 		System.setDefault("hideGuildInfoMessage", false);
  75. 		System.setDefault("hideGuildInfoBuff", false);
  76.  
  77. 		System.setDefault("buyBuffsGreeting", "Hello {playername}, can I buy {buffs} for {cost} please?");
  78. 		System.setDefault("renderSelfBio", true);
  79. 		System.setDefault("showBPSlotsOnProfile", false);
  80. 		System.setDefault("bioEditLines", 10);
  81. 		System.setDefault("renderOtherBios", true);
  82. 		System.setDefault("playNewMessageSound", false);
  83. 		System.setDefault("showSpeakerOnWorld", true);
  84. 		System.setDefault("defaultMessageSound", "http://dl.getdropbox.com/u/2144065/chimes.wav");
  85. 		System.setDefault("highlightPlayersNearMyLvl", true);
  86. 		System.setDefault("highlightGvGPlayersNearMyLvl", true);
  87. 		System.setDefault("detailedConflictInfo", false);
  88. 		System.setDefault("gameHelpLink", true);
  89. 		System.setDefault("navigateToLogAfterMsg", true);
  90.  
  91. 		System.setDefault("enableAllyOnlineList", false);
  92. 		System.setDefault("enableEnemyOnlineList", false);
  93. 		System.setDefault("allyEnemyOnlineRefreshTime", 60);
  94. 		System.setDefault("moveGuildList", false);
  95.  
  96. 		System.setDefault("hideMatchesForCompletedMoves", false);
  97. 		System.setDefault("quickKill", true);
  98. 		System.setDefault("doNotKillList", "");
  99. 		System.setDefault("enableBioCompressor", false);
  100. 		System.setDefault("maxCompressedCharacters", 1500);
  101. 		System.setDefault("maxCompressedLines", 25);
  102. 		System.setDefault("hideArenaPrizes", "");
  103. 		System.setDefault("autoSortArenaList", false);
  104.  
  105. 		System.setDefault("currentGoldSentTotal", 0);
  106. 		System.setDefault("keepBuffLog", true);
  107. 		System.setDefault("buffLog", "");
  108.  
  109. 		System.setDefault("enableActiveBountyList", false);
  110. 		System.setDefault("bountyListRefreshTime", 30);
  111. 		System.setDefault("enableWantedList", false);
  112. 		System.setDefault("wantedNames", "");
  113. 		System.setDefault("bwNeedsRefresh", true);
  114.  
  115. 		System.setDefault("enableBulkSell", false);
  116. 		System.setDefault("bulkSellAllBags", false);
  117.  
  118. 		System.setDefault("fsboxlog", true);
  119. 		System.setDefault("fsboxcontent", "");
  120. 		System.setDefault("itemRecipient", "");
  121. 		System.setDefault("quickAHPref",JSON.stringify([{"name":"NoGold","min":"","max":"","gold":true,"fsp":false},{"name":"NoFSP","min":"","max":"","gold":false,"fsp":true},{"name":"All","min":"","max":"","gold":false,"fsp":false}]));
  122. 		System.setDefault("quickMsg",JSON.stringify(["Thank you very much ^_^", "Happy hunting, {playername}"]));
  123. 		System.setDefault("quickLinks","[]");
  124. 		System.setDefault("enableAttackHelper", false);
  125. 		System.setDefault("minGroupLevel", 1);
  126. 		System.setDefault("combatEvaluatorBias", 0);
  127. 		System.setDefault("hideRelicOffline", false);
  128.  
  129. 		System.setDefault("enterForSendMessage", false);
  130. 		System.setDefault("trackKillStreak", true);
  131. 		System.setDefault("showFSGIcon", false);
  132. 		System.setDefault("storeLastQuestPage", true);
  133. 		System.setDefault("enableAHItemWidgets", false);
  134. 		System.setDefault("addAttackLinkToLog", false);
  135. 		System.setDefault("showStatBonusTotal", true);
  136.  
  137. 		System.setDefault("newGuildLogHistoryPages", 3);
  138. 		System.setDefault("useNewGuildLog", true);
  139. 		System.setDefault("enhanceChatTextEntry", true);
  140.  
  141. 		System.setDefault("ajaxifyRankControls", true);
  142. 		System.setDefault("disablePageShiftToGuildStore", false);
  143.  
  144. 		System.setDefault("enableMaxGroupSizeToJoin", true);
  145. 		System.setDefault("maxGroupSizeToJoin", 11);
  146.  
  147. 		System.setDefault("enableTitanLog", false);
  148. 		System.setDefault("titanLogRefreshTime", 5);
  149.  
  150. 		System.setDefault("enableTempleAlert", true);
  151. 		System.setDefault("showGoldOnFindPlayer", true);
  152.  
  153. 		Helper.itemFilters = [
  154. 		{"id":"showGloveTypeItems", "type":"Gloves"},
  155. 		{"id":"showHelmetTypeItems", "type":"Helmet"},
  156. 		{"id":"showAmuletTypeItems", "type":"Amulet"},
  157. 		{"id":"showWeaponTypeItems", "type":"Weapon"},
  158. 		{"id":"showAmorTypeItems", "type":"Armor"},
  159. 		{"id":"showShieldTypeItems", "type":"Shield"},
  160. 		{"id":"showRingTypeItems", "type":"Ring"},
  161. 		{"id":"showBootTypeItems", "type":"Boots"},
  162. 		{"id":"showRuneTypeItems", "type":"Rune"}
  163. 		];
  164.  
  165. 		for (var i=0; i<Helper.itemFilters.length; i++) {
  166. 			System.setDefault(Helper.itemFilters[i].id, true);
  167. 		}
  168.  
  169. 		Helper.guildLogFilters = [
  170. 		{"id":"showRecallMessages", "type":"Store/Recall"},
  171. 		{"id":"showRelicMessages", "type":"Relic"},
  172. 		{"id":"showMercenaryMessages", "type":"Mercenary"},
  173. 		{"id":"showGroupCombatMessages", "type":"Group Combat"},
  174. 		{"id":"showDonationMessages", "type":"Donation"},
  175. 		{"id":"showRankingMessages", "type":"Ranking"},
  176. 		{"id":"showGvGMessages", "type":"GvG"},
  177. 		{"id":"showTaggingMessages", "type":"Tag/UnTag"}
  178. 		];
  179.  
  180. 		for (var i=0; i<Helper.guildLogFilters.length; i++) {
  181. 			System.setDefault(Helper.guildLogFilters[i].id, true);
  182. 		}
  183.  
  184. 		System.setDefault("showQuickDropLinks", false);
  185.  
  186. 		try {
  187. 			var quickSearchList = System.getValueJSON("quickSearchList");
  188. 		}
  189. 		catch (err) {
  190. 			GM_log(err);
  191. 			quickSearchList = null;
  192. 		}
  193.  
  194. 		if (!quickSearchList) {
  195. 			quickSearchList = Data.quickSearchList();
  196. 			Helper.sortAsc = true;
  197. 			Helper.sortBy = "category";
  198. 			quickSearchList.sort(Helper.stringSort);
  199. 			System.setValueJSON("quickSearchList", quickSearchList);
  200. 		}
  201.  
  202. 		var memberList = System.getValueJSON("memberlist");
  203. 		if (!memberList || !memberList.lastUpdate) {GM_setValue("memberlist", "");}
  204. 	},
  205.  
  206. 	readInfo: function() {
  207. 		var charInfo = System.findNode("//img[contains(@src,'skin/icon_player.gif')]");
  208. 		if (!charInfo) { return; }
  209. 		var charInfoText = charInfo.getAttribute("onmouseover");
  210. 		Helper.characterName = charInfoText.match(/Name:\s*<\/td><td width=\\\'90%\\\'>([0-9a-z]+)/i)[1];
  211. 		Helper.characterLevel = System.getIntFromRegExp(charInfoText, /Level:\s*<\/td><td width=\\\'90%\\\'>(\d+)/i);
  212. 		Helper.characterAttack = System.getIntFromRegExp(charInfoText, /Attack:\s*<\/td><td width=\\\'90%\\\'>(\d+)/i);
  213. 		Helper.characterDefense = System.getIntFromRegExp(charInfoText, /Defense:\s*<\/td><td width=\\\'90%\\\'>(\d+)/i);
  214. 		Helper.characterHP = charInfoText.match(/HP:\s*<\/td><td width=\\\'90%\\\'>(\d+)/i)[1];
  215. 		Helper.characterArmor = charInfoText.match(/Armor:\s*<\/td><td width=\\\'90%\\\'>(\d+)/i)[1];
  216. 		Helper.characterDamage = charInfoText.match(/Damage:\s*<\/td><td width=\\\'90%\\\'>(\d+)/i)[1];
  217. 		GM_setValue("CharacterName", Helper.characterName);
  218.  
  219. 		Helper.savedItemData = [];
  220. 	},
  221.  
  222. 	// Autoupdate
  223. 	beginAutoUpdate: function() {
  224. 		var lastCheck = GM_getValue("lastVersionCheck");
  225. 		var now = (new Date()).getTime();
  226. 		if (!lastCheck) {lastCheck = 0;}
  227. 		var haveToCheck = ((now - lastCheck) > 6 * 60 * 60 * 1000);
  228. 		if (haveToCheck) {
  229. 			Helper.checkForUpdate();
  230. 		}
  231. 	},
  232.  
  233. 	checkForUpdate: function() {
  234. 		GM_log("Checking for new version...");
  235. 		var now = (new Date()).getTime();
  236. 		GM_setValue("lastVersionCheck", now.toString());
  237. 		GM_xmlhttpRequest({
  238. 			method: 'GET',
  239. 			url: "http://fallenswordhelper.googlecode.com/svn/trunk/?nonce=" + now,
  240. 			headers: {
  241. 				"User-Agent": navigator.userAgent,
  242. 				"Referer": document.location
  243. 			},
  244. 			onload: function(responseDetails) {
  245. 				Helper.autoUpdate(responseDetails);
  246. 			}
  247. 		});
  248. 	},
  249.  
  250. 	autoUpdate: function(responseDetails) {
  251. 		if (responseDetails.status != 200) {return;}
  252. 		var now = (new Date()).getTime();
  253. 		GM_setValue("lastVersionCheck", now.toString());
  254. 		var currentVersion = GM_getValue("currentVersion");
  255. 		if (!currentVersion) {currentVersion = 0;}
  256. 		var versionRE = /Revision\s*([0-9]+):/;
  257. 		var latestVersion = responseDetails.responseText.match(versionRE)[1];
  258. 		GM_log("Current version: " + currentVersion);
  259. 		GM_log("Found version: " + latestVersion);
  260.  
  261. 		if (currentVersion != latestVersion) {
  262. 			GM_xmlhttpRequest({
  263. 				method: 'GET',
  264. 				url: "http://fallenswordhelper.googlecode.com/svn/wiki/ChangeLog.wiki?nonce=" + now,
  265. 				headers: {
  266. 					"User-Agent": navigator.userAgent,
  267. 					"Referer": document.location
  268. 				},
  269. 				onload: function(responseDetails) {
  270. 					Helper.autoUpdateConfirm(responseDetails, currentVersion, latestVersion);
  271. 				}
  272. 			});
  273. 		}
  274. 	},
  275.  
  276. 	autoUpdateConfirm: function(responseDetails, oldVersion, newVersion) {
  277. 		var theChanges = Layout.formatWiki(responseDetails.responseText, oldVersion, newVersion);
  278. 		var confirmAlert = document.createElement("DIV");
  279. 		confirmAlert.id = 'Helper:ConfirmAlert';
  280. 		var divHeight = window.innerHeight - 160;
  281.  
  282. 		confirmAlert.style.position = "absolute";
  283. 		confirmAlert.style.left = (window.innerWidth - 500) / 2 + "px";
  284. 		confirmAlert.style.top = (80 + window.scrollY) + "px";
  285. 		confirmAlert.style.width = "500px";
  286. 		confirmAlert.style.height = divHeight + "px";
  287. 		confirmAlert.style.display = 'block';
  288. 		confirmAlert.style.zIndex = '90';
  289. 		confirmAlert.style.filter = 'alpha';
  290. 		confirmAlert.style.opacity = '0.9';
  291. 		confirmAlert.style.background = 'black';
  292. 		confirmAlert.style.color = 'white';
  293. 		confirmAlert.style.border = 'ridge';
  294.  
  295. 		confirmAlert.innerHTML = '<div height="20" style="background-color:#4a3918;">' +
  296. 			'<div style="color:yellow;position:absolute;top:0px;left:0px">New version (' + newVersion + ') found. Update from version ' + oldVersion + '?' +
  297. 			'</div><div style="position:absolute;top:0px;right:0px">' +
  298. 			'<input type="button" id="Helper:AutoUpdateOk" value="Ok" class="custombutton">' +
  299. 			'&nbsp;<input type="button" id="Helper:AutoUpdateCancel" value="Cancel" class="custombutton"></div></div>' +
  300. 			'<div id="Helper:Output" style="margin-top:20px;height:' + (divHeight-20) + 'px;overflow:auto;">' + theChanges + '</div>';
  301. 		document.body.insertBefore(confirmAlert, document.body.firstChild);
  302. 		document.getElementById("Helper:AutoUpdateOk").addEventListener("click", Helper.autoUpdateConfirmOk, true);
  303. 		document.getElementById("Helper:AutoUpdateOk").setAttribute("newVersion", newVersion);
  304. 		document.getElementById("Helper:AutoUpdateCancel").addEventListener("click", Helper.autoUpdateConfirmCancel, true);
  305. 	},
  306.  
  307. 	autoUpdateConfirmOk: function(evt) {
  308. 		var newVersion = parseInt(evt.target.getAttribute("newVersion"),10);
  309. 		GM_setValue("currentVersion", newVersion);
  310. 		GM_openInTab("http://fallenswordhelper.googlecode.com/svn-history/r" + newVersion + "/trunk/fallenswordhelper.user.js");
  311. 		Helper.autoUpdateConfirmCancel(evt);
  312. 	},
  313.  
  314. 	autoUpdateConfirmCancel: function(evt) {
  315. 		var confirmAlert = document.getElementById("Helper:ConfirmAlert");
  316. 		confirmAlert.style.display = "none";
  317. 		confirmAlert.visibility = "hidden";
  318. 	},
  319.  
  320. 	// main event dispatcher
  321. 	onPageLoad: function(anEvent) {
  322. 		//TODO: These are only meant to be a temporary fix for people using *nix based systems, remove when HCS fixes the slash issue
  323. 		if (System.imageServer != System.imageServerHTTP) {
  324. 			var changeCount = 0;
  325. 			var td = System.findNodes("//td[contains(@background, 'file://') and contains(@background, 'tiles')]");
  326. 			if (td) {
  327. 				for (var i = 0; i < td.length; i++) {
  328. 					var src = td[i].getAttribute("background");
  329. 					if (src) {
  330. 						if (src.indexOf("file://") != -1 && src.indexOf("\\") != -1) {
  331. 							td[i].setAttribute("background", src.replace(/\\/g, "/"));
  332. 							changeCount++;
  333. 						}
  334. 					}
  335. 				}
  336. 			}
  337. 			if (changeCount === 0 && td !== null) {
  338. 				GM_log("Time to remove the temporary HCS tile image slash fix.");
  339. 			} /*else {
  340. 				GM_log("Changed " + changeCount + " references.");
  341. 			}*/
  342. 		}
  343. 		if (GM_getValue("gameHelpLink")) {
  344. 			var gameHelpNode = System.findNode("//b[contains(.,'Game Help')]");
  345. 			if (gameHelpNode) {
  346. 				gameHelpNode.innerHTML = "<a href='index.php?cmd=settings' style='color: #FFFFFF; text-decoration: underline'>" + gameHelpNode.innerHTML + "</a>";
  347. 			}
  348. 		}
  349.  
  350. 		if (GM_getValue("huntingMode")) {
  351. 			Helper.readInfo();
  352. 			Helper.replaceKeyHandler();
  353. 		} else {
  354. 			Helper.init();
  355. 			Layout.hideBanner();
  356. 			Layout.moveFSBox();
  357. 			Helper.prepareAllyEnemyList();
  358. 			Layout.moveGuildOnlineList();
  359. 			Helper.prepareGuildList();
  360. 			Helper.prepareBountyData();
  361. 			Helper.injectStaminaCalculator();
  362. 			Helper.injectLevelupCalculator();
  363. 			Layout.injectMenu();
  364. 			Helper.replaceKeyHandler();
  365. 			Helper.injectFSBoxLog();
  366. 			Helper.fixOnlineGuildBuffLinks();
  367. 			Helper.addGuildInfoWidgets();
  368. 			Helper.injectJoinAllLink();
  369. 			Helper.changeGuildLogHREF();
  370. 			Helper.injectTHsearch();
  371. 			Helper.updateTitanLogs();
  372. 			Helper.injectHomePageTwoLink();
  373. 			Helper.injectTempleAlert();
  374. 		}
  375. 		var pageId, subPageId, subPage2Id, subsequentPageId;
  376. 		if (document.location.search !== "") {
  377. 			var re=/cmd=([a-z]+)/;
  378. 			var pageIdRE = re.exec(document.location.search);
  379. 			pageId="-";
  380. 			if (pageIdRE) {pageId=pageIdRE[1];}
  381.  
  382. 			re=/subcmd=([a-z]+)/;
  383. 			var subPageIdRE = re.exec(document.location.search);
  384. 			subPageId="-";
  385. 			if (subPageIdRE){subPageId=subPageIdRE[1];}
  386.  
  387. 			re=/subcmd2=([a-z]+)/;
  388. 			var subPage2IdRE = re.exec(document.location.search);
  389. 			subPage2Id="-";
  390. 			if (subPage2IdRE) {subPage2Id=subPage2IdRE[1];}
  391.  
  392. 			re=/page=([0-9]+)/;
  393. 			var subsequentPageIdRE = re.exec(document.location.search);
  394. 			subsequentPageId="-";
  395. 			if (subsequentPageIdRE) {subsequentPageId=subsequentPageIdRE[1];}
  396. 		} else {
  397. 			pageId=System.findNode("//input[@type='hidden' and @name='cmd']");
  398. 			pageId = pageId?pageId.getAttribute("value"):"-";
  399.  
  400. 			subPageId=System.findNode("//input[@type='hidden' and @name='subcmd']");
  401. 			subPageId=subPageId?subPageId.getAttribute("value"):"-";
  402. 			if (subPageId=="dochat") {pageId="-"; subPageId="-";}
  403.  
  404. 			subPage2Id=System.findNode("//input[@type='hidden' and @name='subcmd2']");
  405. 			subPage2Id=subPage2Id?subPage2Id.getAttribute("value"):"-";
  406.  
  407. 			subsequentPageId=System.findNode("//input[@type='hidden' and @name='page']");
  408. 			subsequentPageId=subsequentPageId?subsequentPageId.getAttribute("value"):"-";
  409. 		}
  410.  
  411. 		Helper.page = pageId + "/" + subPageId + "/" + subPage2Id + "(" + subsequentPageId + ")";
  412.  
  413. 		switch (pageId) {
  414. 		case "settings":
  415. 			Helper.injectSettings();
  416. 			break;
  417. 		case "world":
  418. 			switch (subPageId) {
  419. 			case "viewcreature":
  420. 				Helper.injectCreature();
  421. 				break;
  422. 			case "map":
  423. 				Helper.injectWorldMap();
  424. 				break;
  425. 			default:
  426. 				Helper.injectWorld();
  427. 				break;
  428. 			}
  429. 			break;
  430. 		case "news":
  431. 			switch (subPageId) {
  432. 			case "fsbox":
  433. 				Helper.injectShoutboxWidgets('fsbox_input', 100);
  434. 				break;
  435. 			case "shoutbox":
  436. 				Helper.injectShoutboxWidgets('shoutbox_input', 150);
  437. 				break;
  438. 			default:
  439. 				break;
  440. 			}
  441. 			break;
  442. 		case "blacksmith":
  443. 			switch (subPageId) {
  444. 			case "repairall":
  445. 				Helper.injectWorld();
  446. 				break;
  447. 			default:
  448. 				break;
  449. 			}
  450. 			break;
  451. 		case "arena":
  452. 			switch (subPageId) {
  453. 			case "-":
  454. 				Helper.injectArena();
  455. 				break;
  456. 			case "completed":
  457. 				Helper.storeCompletedArenas();
  458. 				break;
  459. 			case "pickmove":
  460. 				Helper.storeArenaMoves();
  461. 				break;
  462. 			case "results":
  463. 				Helper.injectTournament();
  464. 				break;
  465. 			case "dojoin":
  466. 				Helper.injectTournament();
  467. 				break;
  468. 			default:
  469. 				break;
  470. 			}
  471. 			break;
  472. 		case "questbook":
  473. 			switch (subPageId) {
  474. 			case "viewquest":
  475. 				Helper.injectQuestTracker();
  476. 				break;
  477. 			default:
  478. 				break;
  479. 			}
  480. 			if (subPageId == "-") {
  481. 				Helper.injectQuestBookFull();
  482. 			}
  483. 			break;
  484. 		case "profile":
  485. 			switch (subPageId) {
  486. 			case "dropitems":
  487. 				Helper.injectDropItems();
  488. 				Helper.injectMoveItems();
  489. 				break;
  490. 			case "changebio":
  491. 				Helper.injectBioWidgets();
  492. 				break;
  493. 			case "-":
  494. 				Helper.injectProfile();
  495. 				break;
  496. 			default:
  497. 				break;
  498. 			}
  499. 			break;
  500. 		case "auctionhouse":
  501. 			switch (subPageId) {
  502. 			case "create":
  503. 				Helper.injectCreateAuctionTemplate();
  504. 				Helper.injectCreateAuctionBulkSell();
  505. 				break;
  506. 			case "preferences":
  507. 				break;
  508. 			default:
  509. 				Helper.injectAuctionHouse();
  510. 				break;
  511. 			}
  512. 			break;
  513. 		case "guild":
  514. 			switch (subPageId) {
  515. 			case "inventory":
  516. 				switch (subPage2Id) {
  517. 					case "report":
  518. 						Helper.injectReportPaint();
  519. 						break;
  520. 					case "addtags":
  521. 						Helper.injectGuildAddTagsWidgets();
  522. 						break;
  523. 					case "removetags":
  524. 						Helper.injectGuildAddTagsWidgets();
  525. 						break;
  526. 					default:
  527. 						Helper.injectDropItems();
  528. 						break;
  529. 				}
  530. 				break;
  531. 			case "chat":
  532. 				Helper.addChatTextArea();
  533. 				Helper.addLogColoring("Chat", 0);
  534. 				break;
  535. 			case "reliclist":
  536. 				Helper.injectRelicList();
  537. 				break;
  538. 			case "log":
  539. 				Helper.addLogColoring("GuildLog", 1);
  540. 				Helper.addGuildLogWidgets();
  541. 				break;
  542. 			case "groups":
  543. 				switch (subPage2Id) {
  544. 					case "viewstats":
  545. 						Helper.injectGroupStats();
  546. 						break;
  547. 					default:
  548. 						Helper.injectGroups();
  549. 						break;
  550. 				}
  551. 				break;
  552. 			case "manage":
  553. 				Helper.parseGuildForWorld();
  554. 				Helper.injectGuild();
  555. 				break;
  556. 			case "advisor":
  557. 				Helper.injectAdvisor(subPage2Id);
  558. 				break;
  559. 			case "history":
  560. 				Helper.addHistoryWidgets();
  561. 				break;
  562. 			case "view":
  563. 				Helper.injectViewGuild();
  564. 				break;
  565. 			case "scouttower":
  566. 				Helper.injectScouttower();
  567. 				break;
  568. 			case "mailbox":
  569. 				Helper.injectMailbox();
  570. 				break;
  571. 			case "ranks":
  572. 				Helper.injectGuildRanks();
  573. 				break;
  574. 			default:
  575. 				break;
  576. 			}
  577. 			break;
  578. 		case "bank":
  579. 			Helper.injectBank();
  580. 			break;
  581. 		case "log":
  582. 			switch (subPageId) {
  583. 			case "outbox":
  584. 				Helper.addLogColoring("OutBox", 1);
  585. 				break;
  586. 			case "-":
  587. 				Helper.addLogColoring("PlayerLog", 1);
  588. 				Helper.addLogWidgets();
  589. 				break;
  590. 			default:
  591. 				break;
  592. 			}
  593. 			break;
  594. 		case "marketplace":
  595. 			switch (subPageId) {
  596. 			case "createreq":
  597. 				Helper.addMarketplaceWidgets();
  598. 				break;
  599. 			default:
  600. 				break;
  601. 			}
  602. 			break;
  603. 		case "quickbuff":
  604. 			Helper.injectQuickBuff();
  605. 			break;
  606. 		case "notepad":
  607. 			switch (subPageId) {
  608. 			case "showlogs":
  609. 				Helper.injectNotepadShowLogs();
  610. 				break;
  611. 			case "invmanager":
  612. 				Helper.injectInventoryManager();
  613. 				break;
  614. 			case "guildinvmanager":
  615. 				Helper.injectGuildInventoryManager();
  616. 				break;
  617. 			case "recipemanager":
  618. 				Helper.injectRecipeManager();
  619. 				break;
  620. 			case "questmanager":
  621. 				Helper.injectQuestManager();
  622. 				break;
  623. 			case "auctionsearch":
  624. 				Helper.injectAuctionSearch();
  625. 				break;
  626. 			case "onlineplayers":
  627. 				Helper.injectOnlinePlayers();
  628. 				break;
  629. 			case "quicklinkmanager":
  630. 				Helper.injectQuickLinkManager();
  631. 				break;
  632. 			case "monsterlog":
  633. 				Helper.injectMonsterLog();
  634. 				break;
  635. 			case "quickextract":
  636. 				Helper.insertQuickExtract();
  637. 				break;
  638. 			case "quickwear":
  639. 				Helper.insertQuickWear();
  640. 				break;
  641. 			case "fsboxcontent":
  642. 				Helper.injectFsBoxContent();
  643. 				break;
  644. 			case "bufflogcontent":
  645. 				Helper.injectBuffLog();
  646. 				break;
  647. 			case "guildlog":
  648. 				Helper.injectGuildLogSummary();
  649. 				break;
  650. 			case "quickahpreftemplate":
  651. 				Helper.injectAHPrefTemplate();
  652. 				break;
  653. 			case "newguildlog":
  654. 				Helper.injectNewGuildLog();
  655. 				break;
  656. 			case "checkwear":
  657. 				Helper.injectCheckWearingItem();
  658. 				break;
  659. 			default:
  660. 				Helper.injectNotepad();
  661. 				break;
  662. 			}
  663. 			break;
  664. 		case "points":
  665. 			switch (subPageId) {
  666. 			case "shop":
  667. 				Helper.storePlayerUpgrades();
  668. 				Helper.injectPoints();
  669. 				break;
  670. 			case "-":
  671. 				Helper.storePlayerUpgrades();
  672. 				Helper.injectPoints();
  673. 				break;
  674. 			default:
  675. 				break;
  676. 			}
  677. 			break;
  678. 		case "trade":
  679. 			Helper.retrieveTradeConfirm();
  680. 			switch (subPageId) {
  681. 			case "createsecure":
  682. 				Helper.injectSecureTrade();
  683. 				break;
  684. 			case "-":
  685. 				Helper.injectStandardTrade();
  686. 				break;
  687. 			default:
  688. 				break;
  689. 			}
  690. 			break;
  691. 		case "titan":
  692. 			Helper.injectTitan();
  693. 			break;
  694. 		case "toprated":
  695. 			switch (subPageId) {
  696. 			case "xp":
  697. 				Helper.injectTopRated();
  698. 				break;
  699. 			default:
  700. 				break;
  701. 			}
  702. 			break;
  703. 		case "inventing":
  704. 			switch (subPageId) {
  705. 			case "viewrecipe":
  706. 				Helper.injectViewRecipe();
  707. 				break;
  708. 			default:
  709. 				break;
  710. 			}
  711. 			break;
  712. 		case "message":
  713. 			Helper.injectMessageTemplate();
  714. 			break;
  715. 		case "tempinv":
  716. 			Helper.injectMailbox();
  717. 			break;
  718. 		case "attackplayer":
  719. 			Helper.injectAttackPlayer();
  720. 			break;
  721. 		case "findplayer":
  722. 			Helper.injectFindPlayer();
  723. 			break;
  724. 		case "scavenging":
  725. 			switch (subPageId) {
  726. 			case "process":
  727. 				Helper.injectScavenging();
  728. 				break;
  729. 			default:
  730. 				break;
  731. 			}
  732. 			break;
  733. 		case "-":
  734. 			var isRelicPage = System.findNode("//td[contains(.,'Below is the current status for the relic')]/b");
  735. 			if (isRelicPage) {
  736. 				Helper.injectRelic(isRelicPage);
  737. 			}
  738. 			var isBuffResult = System.findNode("//td[contains(.,'Back to Quick Buff Menu')]");
  739. 			if (isBuffResult) {
  740. 				Helper.updateBuffLog();
  741. 			}
  742. 			var isAuctionPage = System.findNode("//img[contains(@title,'Auction House')]");
  743. 			if (isAuctionPage) {
  744. 				Helper.injectAuctionHouse();
  745. 			}
  746. 			var isShopPage = System.findNode("//td[contains(.,'then click to purchase for the price listed below the item.')]");
  747. 			if (isShopPage) {
  748. 				Helper.injectShop();
  749. 			}
  750. 			var isQuestBookPage = System.findNode("//td[.='Quest Name']");
  751. 			if (isQuestBookPage) {
  752. 				Helper.injectQuestBookFull();
  753. 			}
  754. 			var isAdvisorPageClue1 = System.findNode("//font[@size=2 and .='Advisor']");
  755. 			var clue2 = "//a[@href='index.php?cmd=guild&amp;subcmd=manage' and .='Back to Guild Management']";
  756. 			var isAdvisorPageClue2 = System.findNode(clue2);
  757. 			if (isAdvisorPageClue1 && isAdvisorPageClue2) {
  758. 				Helper.injectAdvisor(subPage2Id);
  759. 			}
  760. 			var isArenaTournamentPage = System.findNode("//b[contains(.,'Tournament #')]");
  761. 			if (isArenaTournamentPage) {
  762. 				Helper.injectTournament();
  763. 			}
  764. 			if (System.findNode("//a[.='Back to Scavenging']")) {
  765. 				Helper.injectScavenging();
  766. 			}
  767. 			break;
  768. 		case "skills":
  769. 			Helper.injectSkillsPage();
  770. 			break;
  771. 		default:
  772. 			break;
  773. 		}
  774. 		if (GM_getValue("playNewMessageSound")) {
  775. 			var unreadLog = System.findNode("//font[contains(.,'unread log messages.')]");
  776.  
  777. 			if (unreadLog)
  778. 			{
  779. 			  if (unreadLog.innerHTML == ("You have unread log messages."))
  780. 			  {
  781. 				unreadLog.innerHTML += "<audio src='" + GM_getValue("defaultMessageSound") + "' autoplay=true />";
  782. 			  }
  783. 			}
  784. 		}
  785.  
  786. 		//This must be at the end in order not to screw up other System.findNode calls (Issue 351)
  787. 		if (GM_getValue("huntingMode") === false) {
  788. 			Layout.injectQuickLinks();
  789. 		}
  790. 	},
  791.  
  792. 	injectSkillsPage: function() {
  793. 		var buffs = System.findNodes("//a[contains(@href,'index.php?cmd=skills&tree_id=') and contains(@href,'&skill_id=')][img[@border=0]]");
  794.  
  795. 		for (var i = 0; i < buffs.length; i++) {
  796. 			var parNode = buffs[i];
  797. 			var mouseoverText = buffs[i].firstChild.getAttribute("onmouseover");
  798. 			var buffIndex = parNode.getAttribute("href").match(/skill_id=(\d*)/)[1];
  799. 			var buffList = Data.buffList();
  800. 			for (var j = 0; j < buffList.length; j++) {
  801. 				if (buffList[j].skillId == buffIndex) {
  802. 					mouseoverText = mouseoverText.replace("Click for Details", buffList[j].buff);
  803. 					break;
  804. 				}
  805. 			}
  806. 			mouseoverText = mouseoverText.replace(/tt_setWidth\(\d*\)/, "tt_setWidth(150)");
  807. 			buffs[i].setAttribute("onmouseover", mouseoverText);
  808.  
  809. 		}
  810. 	},
  811.  
  812. 	injectViewGuild: function() {
  813. 		var highlightPlayersNearMyLvl = GM_getValue("highlightPlayersNearMyLvl");
  814. 		var highlightGvGPlayersNearMyLvl = GM_getValue("highlightGvGPlayersNearMyLvl");
  815. 		if (highlightPlayersNearMyLvl || highlightGvGPlayersNearMyLvl) {
  816. 			var memberList = System.findNode("//tr[td/b[.='Members']]/following-sibling::tr/td/table");
  817. 			for (var i=2;i<memberList.rows.length;i+=4) {
  818. 				var iplus1 = i+1;
  819. 				var level = memberList.rows[i].cells[2].innerHTML;
  820. 				var aRow = memberList.rows[i];
  821. 				if (highlightPlayersNearMyLvl && Math.abs(level - Helper.characterLevel) <= 5) {
  822. 					aRow.style.backgroundColor = "#4671C8";
  823. 				} else if (highlightGvGPlayersNearMyLvl && Math.abs(level - Helper.characterLevel) <= 25) {
  824. 					aRow.style.backgroundColor = "#FF9900";
  825. 				}
  826. 			}
  827. 		}
  828. 	},
  829. 	updateBuffLog: function() {
  830. 		if (GM_getValue("keepBuffLog")) {
  831. 			//Skill Inventor level 175 was activated on 'yuuzhan'.
  832. 			var buffLog=GM_getValue("buffLog");
  833. 			var buffsAttempted = document.body.innerHTML.split('<li>');
  834. 			document.body.innerHTML+= "<span id='buff_Log' style='color:yellow'></span>";
  835. 			var buffsNotCastRE = /The skill ([\w ]*) of current or higher level is currently active on \'(\w*)\'/;
  836. 			var buffsCastRE = /Skill ([\w ]*) level (\d*) was activated on \'(\w*)\'/;
  837. 			var buffList = Data.buffList();
  838. 			//var buffsNotCast = buffsCastRE.exec(document.body.innerHTML);
  839. 			for (var i=0;i<buffsAttempted.length ;i++ )
  840. 			{
  841. 				var buffsCast = buffsCastRE.exec(buffsAttempted[i]);
  842. 				var buffsNotCast = buffsNotCastRE.exec(buffsAttempted[i]);
  843. 				var stamina = 0;
  844. 				if (buffsCast) {
  845. 					//document.getElementById('buff_Log').innerHTML+='<br>'+buffsCast[0];
  846.  
  847. 				for (var j = 0; j < buffList.length; j++) {
  848. 					if (buffList[j].name == buffsCast[1]) {
  849. 						stamina = buffList[j].stamina;
  850. 						break;
  851. 					}
  852. 				}
  853. 					buffLog=buffsCast[0] + ' (' + stamina + ' stamina) <br>'+buffLog;
  854. 				}
  855. 				if (buffsNotCast) {
  856.  
  857. 					buffLog='<span style="color: red;">' + buffsNotCast[0] + '</span><br>' + buffLog;
  858.  
  859. 				}
  860.  
  861. 			}
  862. 			GM_setValue("buffLog",buffLog);
  863. 			//document.getElementById('buff_Log').innerHTML+='<br><br><br>'+buffLog;
  864. 		}
  865.  
  866. 	},
  867. 	injectBuffLog: function() {
  868. 		Layout.notebookContent().innerHTML=Helper.makePageTemplate('Buff Log','','clearBuffs','Clear','bufflog');
  869. 		document.getElementById('clearBuffs').addEventListener('click',function() {GM_setValue("buffLog",'');window.location=window.location;},true);
  870. 		document.getElementById('bufflog').innerHTML=GM_getValue("buffLog");
  871. 	},
  872.  
  873. 	injectFSBoxLog: function() {
  874. 		if (GM_getValue("fsboxlog")) {
  875. 			var node=System.findNode("//input[@value='Send Msg']/../font[1]");
  876. 			if (node) {
  877. 				var fsbox=node.innerHTML.replace('<br><br>',' ');
  878. 				var boxList=GM_getValue("fsboxcontent");
  879. 				if (boxList.indexOf(fsbox)<0) {boxList=fsbox+boxList;}
  880. 				if (boxList.length>10000) {boxList=boxList.substring(0,10000);}
  881. 				GM_setValue("fsboxcontent",boxList);
  882. 				node.innerHTML+="<a href='index.php?cmd=notepad&subcmd=fsboxcontent' style='color:yellow'>[Log]</a>";
  883. 			}
  884. 		}
  885. 	},
  886.  
  887. 	injectFsBoxContent: function() {
  888. 		Layout.notebookContent().innerHTML=Helper.makePageTemplate('FS Box Log','','fsboxclear','Clear','fsboxdetail');
  889. 		document.getElementById('fsboxclear').addEventListener('click',function() {GM_setValue("fsboxcontent",'');window.location=window.location;},true);
  890. 		document.getElementById('fsboxdetail').innerHTML=GM_getValue("fsboxcontent");
  891. 	},
  892.  
  893. 	injectGuild: function() {
  894. 		var guildMiniSRC = System.findNode("//img[contains(@src,'_mini.jpg')]").getAttribute("src");
  895. 		var guildID = /guilds\/(\d+)_mini.jpg/.exec(guildMiniSRC)[1];
  896. 		GM_setValue("guildID",guildID);
  897.  
  898. 		var xpLock = System.findNode('//a[contains(@onmouseover,"tt_setWidth(150); Tip\(\'<b>Guild XP</b><br><br>")]');
  899. 		if (xpLock) {
  900. 			var xpLockmouseover = xpLock.getAttribute("onmouseover");
  901. 			var xpLockXP = xpLockmouseover.replace(/,/g,"").match(/XP Lock: <b>(\d*)/);
  902. 			if (xpLockXP && xpLockXP.length == 2) {
  903. 				xpLockXP = xpLockXP[1];
  904. 				var actualXP = xpLockmouseover.replace(/,/g,"").match(/XP: <b>(\d*)/);
  905. 				if (actualXP && actualXP.length == 2) {
  906. 					actualXP = actualXP[1];
  907. 					if (actualXP < xpLockXP) {
  908. 						try {
  909. 							var xpNode = xpLock.parentNode.parentNode;
  910. 							xpNode.cells[1].innerHTML += ' (<b>' + System.addCommas(xpLockXP - actualXP) + '</b>)';
  911. 						} catch (err) {
  912. 							GM_log(err);
  913. 						}
  914. 					}
  915. 				}
  916. 			}
  917.  
  918.  
  919. 		}
  920.  
  921.  
  922. 		var leftHandSideColumnTable = System.findNode("//table[tbody/tr/td/font/a[contains(.,'Change Logo')]]");
  923. 		var changeLogoCell = leftHandSideColumnTable.rows[0].cells[1].firstChild;
  924. 		changeLogoCell.innerHTML += "[ <span style='cursor:pointer; text-decoration:underline;' " +
  925. 			"id='toggleGuildLogoControl' linkto='guildLogoControl' title='Toggle Section'>X</span> ]";
  926. 		var guildLogoElement = leftHandSideColumnTable.rows[2].cells[0].firstChild.nextSibling;
  927. 		guildLogoElement.id = "guildLogoControl";
  928. 		if (GM_getValue("guildLogoControl")) {
  929. 			guildLogoElement.style.display = "none";
  930. 			guildLogoElement.style.visibility = "hidden";
  931. 		}
  932. 		var leaveGuildCell = leftHandSideColumnTable.rows[4].cells[1].firstChild;
  933. 		leaveGuildCell.innerHTML += "[ <span style='cursor:pointer; text-decoration:underline;' " +
  934. 			"id='toggleStatisticsControl' linkto='statisticsControl' title='Toggle Section'>X</span> ]";
  935. 		statisticsControlElement = leftHandSideColumnTable.rows[6].cells[0].firstChild.nextSibling;
  936. 		statisticsControlElement.id = "statisticsControl";
  937. 		if (GM_getValue("statisticsControl")) {
  938. 			statisticsControlElement.style.display = "none";
  939. 			statisticsControlElement.style.visibility = "hidden";
  940. 		}
  941. 		var buildCell = leftHandSideColumnTable.rows[11].cells[1].firstChild;
  942. 		buildCell.innerHTML += "[ <span style='cursor:pointer; text-decoration:underline;' " +
  943. 			"id='toggleGuildStructureControl' linkto='guildStructureControl' title='Toggle Section'>X</span> ]";
  944. 		guildStructureControlElement = leftHandSideColumnTable.rows[13].cells[0].firstChild.nextSibling;
  945. 		guildStructureControlElement.id = "guildStructureControl";
  946. 		if (GM_getValue("guildStructureControl")) {
  947. 			guildStructureControlElement.style.display = "none";
  948. 			guildStructureControlElement.style.visibility = "hidden";
  949. 		}
  950.  
  951. 		document.getElementById('toggleGuildLogoControl').addEventListener('click', System.toggleVisibilty, true);
  952. 		document.getElementById('toggleStatisticsControl').addEventListener('click', System.toggleVisibilty, true);
  953. 		document.getElementById('toggleGuildStructureControl').addEventListener('click', System.toggleVisibilty, true);
  954.  
  955. 		//Add functionality to remove the skip to guildstoresection
  956. 		if (GM_getValue("disablePageShiftToGuildStore")) {
  957. 			var guildStoreLinks = System.findNodes("//a[contains(@href,'#guildStoreSection')]");
  958. 			for (var i=0;i<guildStoreLinks.length ;i++ ) {
  959. 				var guildStoreLink = guildStoreLinks[i];
  960. 				var linkHREF = guildStoreLink.getAttribute("href");
  961. 				guildStoreLink.setAttribute("href", linkHREF.replace(/#guildStoreSection/,""));
  962. 			}
  963. 		}
  964.  
  965. 		//Update the guild online list, since we are already on the page.
  966. 		doc = document.firstChild.nextSibling;
  967. 		Helper.parseGuildForWorld(doc.innerHTML, true);
  968.  
  969. 		// Fast Take
  970.  
  971. 		var guildStore = leftHandSideColumnTable.rows[23].cells[0].firstChild.nextSibling;
  972. 		var guildStoreIDRE = /guildstore_id=(\d+)/i;
  973.  
  974. 		var guildStoreBox = [];
  975. 		var guildStoreBoxItem = [];
  976. 		var guildStoreBoxID = [];
  977. 		for (var i=0;i<12;i++) {
  978. 			if (guildStore.rows[i >> 2]) {guildStoreBox[i]=guildStore.rows[i >> 2].cells[i % 4];}
  979. 			if (guildStoreBox[i]) {guildStoreBoxItem[i] = guildStoreBox[i].firstChild;}
  980. 			if (guildStoreBoxItem[i]) {guildStoreBoxID[i] = guildStoreIDRE(guildStoreBoxItem[i].firstChild.getAttribute("href"))[1];}
  981. 		}
  982.  
  983. 		var newRow;
  984.  
  985. 		for (i=0;i<12;i++) {
  986. 			if ((i % 4===0) && guildStoreBoxItem[i]) {newRow = guildStore.insertRow(2*(i >> 2)+1);}
  987. 			if (guildStoreBoxItem[i]) {
  988. 				var newCell = newRow.insertCell(i % 4);
  989. 				newCell.innerHTML = '<span style="cursor:pointer; text-decoration:underline; color:blue; font-size:x-small;" '+
  990. 					'id="Helper:recallGuildStoreItem' + guildStoreBoxID[i] + '" ' +
  991. 					'itemID="' + guildStoreBoxID[i] + '">Take</span> | '+
  992. 					'<span style="cursor:pointer; text-decoration:underline; color:blue; font-size:x-small;" '+
  993. 					'id="Helper:wearGuildStoreItem' + guildStoreBoxID[i] + '" ' +
  994. 					'href="index.php?cmd=guild&subcmd=inventory&subcmd2=takeitem&guildstore_id=' + guildStoreBoxID[i] + '">Wear</span>';
  995. 				document.getElementById('Helper:recallGuildStoreItem' + guildStoreBoxID[i]).
  996. 					addEventListener('click', Helper.recallGuildStoreItem, true);
  997. 				document.getElementById('Helper:wearGuildStoreItem' + guildStoreBoxID[i]).
  998. 					addEventListener('click', Helper.recallItemNWear, true);
  999. 			}
  1000. 		}
  1001.  
  1002. 		// self recall
  1003. 		var selfRecall = leftHandSideColumnTable.rows[22].cells[0];
  1004. 		selfRecall.innerHTML+=" [<a href='index.php?cmd=guild&subcmd=inventory&subcmd2=report&user="+Helper.characterName+"' title='Self Recall'>SR</a>]";
  1005.  
  1006. 		//Detailed conflict information
  1007. 		if (GM_getValue("detailedConflictInfo") === true) {
  1008. 			var confNode = System.findNode("//table[contains(@id,'statisticsControl')]");
  1009. 			System.xmlhttp("index.php?cmd=guild&subcmd=conflicts",
  1010. 				Helper.getConflictInfo,	{"node": confNode});
  1011.  
  1012. 		}
  1013. 	},
  1014.  
  1015. 	getConflictInfo: function(responseText, callback) {
  1016. 		try {
  1017. 			var insertHere = callback.node;
  1018. 			var doc = System.createDocument(responseText);
  1019.  
  1020. 			var page = System.findNode("//td[contains(.,'Page:')]", doc);
  1021. 			var curPage = parseInt(System.findNode("//input[@name='page']", doc).value,10);
  1022. 			var maxPage = page.innerHTML.match(/of&nbsp;(\d*)/);
  1023.  
  1024. 			var conflictTable = System.findNode("//table[@width='600' and @cellspacing='0' and @cellpadding='3' and @border='0' and @align='center']", doc);
  1025. 			if (conflictTable && conflictTable.rows.length > 3) {
  1026. 				if (curPage == 1) {
  1027. 					var newNode = insertHere.insertRow(insertHere.rows.length-2);
  1028. 					newNode.insertCell(0);
  1029. 					newNode.insertCell(0);
  1030. 					newNode.cells[0].innerHTML = "<a href='index.php?cmd=guild&subcmd=conflicts'>Active Conflicts</a>";
  1031. 					newNode.cells[1].innerHTML = "Score";
  1032. 				}
  1033. 				for (var i = 1; i <= conflictTable.rows.length - 4; i+=2) {
  1034. 					var newRow = insertHere.insertRow(insertHere.rows.length-2);
  1035. 					newRow.insertCell(0);
  1036. 					newRow.insertCell(0);
  1037. 					newRow.cells[0].innerHTML = conflictTable.rows[i].cells[0].innerHTML;
  1038. 					newRow.cells[1].innerHTML = "<b>" + conflictTable.rows[i].cells[5].innerHTML + "</b>";
  1039. 				}
  1040. 			}
  1041. 			if (maxPage && parseInt(maxPage[1],10) > curPage) {
  1042. 				//http://www.fallensword.com/index.php?cmd=guild&subcmd=conflicts&subcmd2=&page=2&search_text=
  1043. 				System.xmlhttp("index.php?cmd=guild&subcmd=conflicts&subcmd2=&page=" + (curPage + 1) + "&search_text=",
  1044. 					Helper.getConflictInfo,
  1045. 					{"node": callback.node});
  1046. 			}
  1047. 		} catch (err) {
  1048. 			GM_log(err);
  1049. 		}
  1050. 	},
  1051.  
  1052. 	recallGuildStoreItem: function(evt) {
  1053. 		var guildStoreID=evt.target.getAttribute("itemID");
  1054. 		var recallHref = "index.php?cmd=guild&subcmd=inventory&subcmd2=takeitem&guildstore_id=" + guildStoreID;
  1055. 		System.xmlhttp(recallHref,
  1056. 			Helper.recallGuildStoreItemReturnMessage,
  1057. 			{"item": guildStoreID, "target": evt.target, "url": recallHref});
  1058. 	},
  1059.  
  1060. 	recallGuildStoreItemReturnMessage: function(responseText, callback) {
  1061. 		var itemID = callback.item;
  1062. 		var target = callback.target;
  1063. 		var info = Layout.infoBox(responseText);
  1064. 		var itemCellElement = target.parentNode; //System.findNode("//td[@title='" + itemID + "']");
  1065. 		if (info.search("You successfully took the item into your backpack") != -1) {
  1066. 			itemCellElement.innerHTML = "<span style='color:green; font-weight:bold;'>Taken</span>";
  1067. 		} else if (info!=="") {
  1068. 			itemCellElement.innerHTML = "<span style='color:red; font-weight:bold;'>Error:" + info + "</span>";
  1069. 		} else {
  1070. 			itemCellElement.innerHTML = "Weird Error: check the Tools>Error Console";
  1071. 			GM_log("Post the previous HTML and the following message to the code.google.com site or to the forum to help us debug this error");
  1072. 			GM_log(callback.url);
  1073. 		}
  1074. 	},
  1075.  
  1076. 	injectStaminaCalculator: function() {
  1077. 		var staminaImageElement = System.findNode("//img[contains(@src,'/skin/icon_stamina.gif')]");
  1078. 		if (!staminaImageElement) {return;}
  1079.  
  1080. 		var mouseoverText = staminaImageElement.getAttribute("onmouseover");
  1081. 		var staminaRE = /Stamina:\s<\/td><td width=\\'90%\\'>([,0-9]+)\s\/\s([,0-9]+)<\/td>/;
  1082. 		var curStamina = System.intValue(staminaRE.exec(mouseoverText)[1]);
  1083. 		var maxStamina = System.intValue(staminaRE.exec(mouseoverText)[2]);
  1084. 		var gainPerHourRE = /Gain\sPer\sHour:\s<\/td><td width=\\'90%\\'>\+([,0-9]+)<\/td>/;
  1085. 		var gainPerHour = System.intValue(gainPerHourRE.exec(mouseoverText)[1]);
  1086. 		var nextGainRE = /Next\sGain\s:\s<\/td><td width=\\'90%\\'>([,0-9]+)m ([,0-9]+)s/;
  1087. 		var nextGainMinutes = System.intValue(nextGainRE.exec(mouseoverText)[1]);
  1088. 		var nextGainSeconds = System.intValue(nextGainRE.exec(mouseoverText)[2]);
  1089. 		nextGainHours = nextGainMinutes/60;
  1090. 		//get the max hours to still be inside stamina maximum
  1091. 		var hoursToMaxStamina = Math.floor((maxStamina - curStamina)/gainPerHour);
  1092. 		var millisecondsToMaxStamina = 1000*60*60*(hoursToMaxStamina + nextGainHours);
  1093. 		var now = (new Date()).getTime();
  1094. 		var nextHuntMilliseconds = (now + millisecondsToMaxStamina);
  1095.  
  1096. 		var d = new Date(nextHuntMilliseconds);
  1097. 		var nextHuntTimeText = d.toFormatString("HH:mm ddd dd/MMM/yyyy");
  1098. 		var newPart = "<tr><td><font color=\\'#FFF380\\'>Max Stam At: </td><td width=\\'90%\\'>" +
  1099. 			nextHuntTimeText + "</td></tr><tr>";
  1100. 		var newMouseoverText = mouseoverText.replace("</table>", newPart + "</table>");
  1101. 		//newMouseoverText = newMouseoverText.replace(/\s:/,":"); //this breaks the fallen sword addon, so removing this line.
  1102. 		staminaImageElement.setAttribute("onmouseover", newMouseoverText);
  1103. 	},
  1104.  
  1105. 	injectLevelupCalculator: function() {
  1106. 		var levelupImageElement = System.findNode("//img[contains(@src,'/skin/icon_xp.gif')]");
  1107. 		if (!levelupImageElement) {return;}
  1108. 		var mouseoverText = levelupImageElement.getAttribute("onmouseover");
  1109. 		var remainingXPRE = /Remaining:\s<\/td><td width=\\\'90%\\\'>([0-9,]+)/i;
  1110. 		var gainRE = /Gain\sPer\sHour:\s<\/td><td width=\\\'90%\\\'>\+([0-9,]+)/i;
  1111. 		var nextGainRE = /Next\sGain\s*:\s*<\/td><td width=\\\'90%\\\'>([0-9]*)m\s*([0-9]*)s/i;
  1112. 		var remainingXP = parseInt(remainingXPRE.exec(mouseoverText)[1].replace(/,/g,""),10);
  1113. 		var gain = parseInt(gainRE.exec(mouseoverText)[1].replace(/,/g,""),10);
  1114. 		var nextGainMin = parseInt(nextGainRE.exec(mouseoverText)[1],10);
  1115. 		var nextGainSec = parseInt(nextGainRE.exec(mouseoverText)[1],10);
  1116. 		var hoursToNextLevel = Math.ceil(remainingXP/gain);
  1117. 		var millisecsToNextGain = (hoursToNextLevel*60*60+nextGainMin*60+nextGainSec)*1000;
  1118.  
  1119. 		var nextGainTime  = new Date((new Date()).getTime() + millisecsToNextGain);
  1120. 		var mouseoverTextAddition = "<tr><td><font color=\\'#FFF380\\'>Next Level At: </td><td width=\\'90%\\'>" +
  1121. 			nextGainTime.toFormatString("HH:mm ddd dd/MMM/yyyy") + "</td></tr><tr>";
  1122. 		newMouseoverText = mouseoverText.replace("</table>", mouseoverTextAddition + "</table>");
  1123. 		newMouseoverText = newMouseoverText.replace("tt_setWidth(175)", "tt_setWidth(200)");
  1124. 		levelupImageElement.setAttribute("onmouseover", newMouseoverText);
  1125. 		return;
  1126. 	},
  1127.  
  1128. 	injectShop: function() {
  1129. 		var injectHere=System.findNode("//td/center[img[contains(@src,'_banner.jpg')]]");
  1130. 		var itemNodes=System.findNodes("//td/center/a/img[contains(@src,'/items/')]");
  1131.  
  1132. 		var selector="<span style='font-size:xx-small'>Select an item to quick-buy:<br>Select how many to quick-buy <input style='font-size:xx-small' value=1 id='buy_amount' name='buy_amount' size=1 class='custominput'><table cellpadding=2><tr>";
  1133. 		var itemId;
  1134. 		for (var i=0;i<itemNodes.length;i++) {
  1135. 			var item=itemNodes[i];
  1136. 			var src=item.getAttribute("src");
  1137. 			var text=item.parentNode.parentNode.textContent;
  1138. 			var onmouseover=item.getAttribute("onmouseover").replace("Click to Buy","Click to Select");
  1139. 			itemId=item.parentNode.getAttribute("href").match(/&item_id=(\d+)&/)[1];
  1140. 			selector+="<td width=20 height=20 ><img width=20 height=20 id=select"+itemId+" itemId="+itemId+" src='"+src+
  1141. 				"' onmouseover=\""+onmouseover+"\">"+text+"</td>";
  1142. 			if (i%6==5 && i!=itemNodes.length-1) {selector+="</tr><tr>";}
  1143. 		}
  1144. 		selector+="</tr><tr><td colspan=3>Selected item:</td><td colspan=3 align=center>"+
  1145. 			"<table><tr><td width=45 height=45 id=selectedItem align=center></td></tr></table>"+
  1146. 			"<td></tr><tr><td id=warningMsg colspan=6 align=center></td></tr><tr><td id=buy_result colspan=6 align=center></td></tr></table>";
  1147. 		injectHere.innerHTML="<table><tr><td>"+injectHere.innerHTML+"</td><td>"+selector+"</td></tr></table>";
  1148. 		for (i=0;i<itemNodes.length;i++) {
  1149. 			itemId=itemNodes[i].parentNode.getAttribute("href").match(/&item_id=(\d+)&/)[1];
  1150. 			document.getElementById("select"+itemId).addEventListener("click",Helper.selectShopItem,true);
  1151. 		}
  1152. 		Helper.shopId=itemNodes[0].parentNode.getAttribute("href").match(/&shop_id=(\d+)/)[1];
  1153. 	},
  1154.  
  1155. 	selectShopItem: function(evt) {
  1156. 		Helper.shopItemId=evt.target.getAttribute("itemId");
  1157. 		document.getElementById('warningMsg').innerHTML='<span style="color:red;font-size:small">Warning:<br> pressing "t" now will buy the '+document.getElementById('buy_amount').value+' item(s) WITHOUT confirmation!</span>';
  1158. 		document.getElementById('selectedItem').innerHTML=
  1159. 			document.getElementById("select"+Helper.shopItemId).parentNode.innerHTML.replace(/="20"/g,'=45');
  1160. 	},
  1161.  
  1162. 	quickBuyItem: function() {
  1163. 		//
  1164. 		if (!Helper.shopItemId || !Helper.shopId) {return;}
  1165. 		document.getElementById('buy_result').innerHTML="Buying "+document.getElementById('buy_amount').value+" Items";
  1166. 		for (var i=0;i<document.getElementById('buy_amount').value;i++) {
  1167. 			System.xmlhttp("index.php?cmd=shop&subcmd=buyitem&item_id="+Helper.shopItemId+"&shop_id="+Helper.shopId,
  1168. 				Helper.quickDone);
  1169.  
  1170. 		}
  1171. 	},
  1172. 	quickDone: function(responseText) {
  1173. 		var infoMessage = Layout.infoBox(responseText);
  1174. 		//unsafeWindow.tt_setWidth(200);
  1175. 		//unsafeWindow.Tip(infoMessage);
  1176. 		document.getElementById('buy_result').innerHTML+="<br />"+infoMessage;
  1177. 	},
  1178.  
  1179. 	injectRelic: function(isRelicPage) {
  1180. 		var empowerThing = System.findNode("//html/body/table/tbody/tr[3]/td[2]/table/tbody/tr[3]/td[2]/table/tbody/tr[10]/td/table/tbody/tr[5]/td/a");
  1181. 		if (empowerThing) {
  1182. 			var mouseover = empowerThing.getAttribute("onmouseover");
  1183. 			var indx1 = mouseover.indexOf("'");
  1184. 			var indx2 = mouseover.lastIndexOf("'");
  1185. 			var insideText = mouseover.substring(indx1 + 1, indx2);
  1186. 			empowerThing.setAttribute("onmouseover", mouseover.substring(0, indx1 + 1) +
  1187. 				insideText.replace(/'/g, "&#39;") +
  1188. 				mouseover.substring(indx2));
  1189. 		}
  1190. 		var relicNameElement = System.findNode("//td[contains(.,'Below is the current status for the relic')]/b");
  1191. 		relicNameElement.parentNode.style.fontSize = "x-small";
  1192.  
  1193. 		var injectHere = System.findNode("//table[@width='400']/tbody/tr/td[@valign = 'top' and contains(.,'Defended')]");
  1194. 		if (injectHere) {
  1195. 			var defendingGuildMiniSRC = System.findNode("//img[contains(@src,'_mini.jpg')]").getAttribute("src");
  1196. 			var defendingGuildID = /guilds\/(\d+)_mini.jpg/.exec(defendingGuildMiniSRC)[1];
  1197. 			var myGuildID = GM_getValue("guildID");
  1198. 			if (defendingGuildID == myGuildID) {
  1199. 				var listOfDefenders = injectHere.nextSibling.textContent.split(","); // quick buff only supports 16
  1200. 				var shortList = new Array();
  1201. 				if (listOfDefenders) {
  1202. 					var modifierWord;
  1203. 					for (var i = 0; i < listOfDefenders.length; i++) {
  1204. 						shortList.push(listOfDefenders[i]);
  1205. 						if (((i + 1) % 16 === 0 && i !== 0) || (i == listOfDefenders.length - 1)) {
  1206. 							modifierWord = Helper.getGroupBuffModifierWord(i);
  1207. 							injectHere.innerHTML += "<br><nobr><a href='#' id='buffAll" + modifierWord + "'><span style='color:blue; font-size:x-small;' title='Quick buff functionality from HCS only does 16'>"+
  1208. 							"Buff " + modifierWord + " 16</span></a></nobr>";
  1209. 							var buffAllLink = System.findNode("//a[@id='buffAll" + modifierWord + "']");
  1210. 							buffAllLink.setAttribute("href","javascript:openWindow('index.php?cmd=quickbuff&t=" + shortList + "', 'fsQuickBuff', 618, 1000, ',scrollbars')");
  1211. 							shortList = new Array();
  1212. 						}
  1213.  
  1214. 					}
  1215.  
  1216. 				}
  1217.  
  1218. 			}
  1219.  
  1220. 		injectHere.innerHTML = injectHere.innerHTML + '<input id="calculatedefenderstats" type="button" value="Fetch Stats" title="Calculate the stats of the players defending the relic." ' +
  1221. 			'class="custombutton">';
  1222. 		document.getElementById('calculatedefenderstats').addEventListener('click', Helper.calculateRelicDefenderStats, true);
  1223. 		}
  1224. 		injectHere = System.findNode("//table[@width='400']/tbody/tr/td[@valign = 'top' and contains(.,'Empower')]");
  1225. 		if (injectHere) {
  1226. 			injectHere.innerHTML = "Empower&nbsp;Level <nobr>" +
  1227. 				injectHere.innerHTML.substring(injectHere.innerHTML.indexOf("["),injectHere.innerHTML.length) +
  1228. 				"</nobr>";
  1229. 		}
  1230. 	},
  1231.  
  1232. 	calculateRelicDefenderStats: function(evt) {
  1233. 		var calcButton = System.findNode("//input[@id='calculatedefenderstats']");
  1234. 		calcButton.style.visibility = "hidden";
  1235. 		var relicNameElement = System.findNode("//td[contains(.,'Below is the current status for the relic')]/b");
  1236. 		relicNameElement.parentNode.style.fontSize = "x-small";
  1237. 		var tableElement = System.findNode("//table[@width='600']");
  1238. 		for (var i=0;i<tableElement.rows.length;i++) {
  1239. 			var aRow = tableElement.rows[i];
  1240. 			if (i==2 ||
  1241. 				i==3 || //Relic picture
  1242. 				i==4 ||
  1243. 				i==5 || //back to world
  1244. 				i==6 ||
  1245. 				i==7 || //Relic instructions
  1246. 				i==8 ||
  1247. 				i==10 ||
  1248. 				i==11) { // attempt group capture button
  1249. 				aRow.firstChild.colSpan = '3';
  1250. 			}
  1251. 		}
  1252. 		var relicName = relicNameElement.innerHTML;
  1253. 		var tableWithBorderElement = System.findNode("//table[@cellpadding='5']");
  1254. 		tableWithBorderElement.align = "left";
  1255. 		tableWithBorderElement.parentNode.colSpan = "2";
  1256. 		var tableInsertPoint = tableWithBorderElement.parentNode.parentNode;
  1257. 		tableInsertPoint.innerHTML += "<td colspan='1'><table width='200' style='border:1px solid #A07720;'>" +
  1258. 			"<tbody><tr><td id='InsertSpot'></td></tr></tbody></table></td>";
  1259. 		var extraTextInsertPoint = System.findNode("//td[@id='InsertSpot']");
  1260. 		var defendingGuild = System.findNode("//a[contains(@href,'index.php?cmd=guild&subcmd=view&guild_id=')]");
  1261. 		var defendingGuildHref = defendingGuild.getAttribute("href");
  1262. 		Helper.getRelicGuildData(extraTextInsertPoint,defendingGuildHref);
  1263.  
  1264. 		var defendingGuildMiniSRC = System.findNode("//img[contains(@src,'_mini.jpg')]").getAttribute("src");
  1265. 		var defendingGuildID = /guilds\/(\d+)_mini.jpg/.exec(defendingGuildMiniSRC)[1];
  1266. 		var myGuildID = GM_getValue("guildID");
  1267.  
  1268. 		var hideRelicOffline = GM_getValue("hideRelicOffline");
  1269. 		if (defendingGuildID == myGuildID && !hideRelicOffline) {
  1270. 			var validMemberString = "";
  1271. 			var memberList = System.getValueJSON("memberlist");
  1272. 			if (memberList) {
  1273. 				for (i=0;i<memberList.members.length;i++) {
  1274. 					var member=memberList.members[i];
  1275. 					if (member.status == "Offline" &&
  1276. 						(member.level < 400 || (member.level > 421 && member.level < 441 ) || member.level > 450)) {
  1277. 						validMemberString += member.name + " ";
  1278. 					}
  1279. 				}
  1280. 			}
  1281. 		}
  1282.  
  1283. 		var listOfDefenders = System.findNodes("//b/a[contains(@href,'index.php?cmd=profile&player_id=')]");
  1284. 		var defenderCount = 0;
  1285. 		var testList = "";
  1286. 		for (i=0; i<listOfDefenders.length; i++) {
  1287. 			var hrefpointer = listOfDefenders[i].getAttribute("href");
  1288. //if (i<3) { //I put this in to limit the number of calls this function makes.
  1289. 					//I don't want to hammer the server too much.
  1290. 				Helper.getRelicPlayerData(defenderCount,extraTextInsertPoint,hrefpointer);
  1291. //}
  1292. 			testList += listOfDefenders[i].innerHTML + " ";
  1293. 			if (defendingGuildID == myGuildID && !hideRelicOffline) validMemberString = validMemberString.replace(listOfDefenders[i].innerHTML + " ","");
  1294. 			defenderCount++;
  1295. 		}
  1296. 		//extraTextInsertPoint.innerHTML += "<tr><td style='font-size:x-small;'>" + testList + "<td><tr>";
  1297. 		extraTextInsertPoint.innerHTML += "<tr><td><table style='font-size:small; border-top:2px black solid;'>" +
  1298. 			"<tr><td>Number of Defenders:</td><td>" + defenderCount + "</td></tr>" +
  1299. 			"<tr><td>Defending Guild Relic Count:</td><td title='relicCount'>0</td></tr>" +
  1300. 			"<tr><td>Lead Defender Bonus:</td><td title='LDPercentage'>0</td></tr>" +
  1301. 			"<tr style='display:none; visibility:hidden;'><td>Relic Count Processed:</td><td title='relicProcessed'>0</td></tr>" +
  1302. 			"<tr style='display:none; visibility:hidden;'><td colspan='2' style='border-top:2px black solid;'>Lead Defender Full Stats</td></tr>" +
  1303. 			"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>Attack:</td><td align='right' title='LDattackValue'>0</td></tr>" +
  1304. 			"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>Defense:</td><td align='right' title='LDdefenseValue'>0</td></tr>" +
  1305. 			"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>Armor:</td><td align='right' title='LDarmorValue'>0</td></tr>" +
  1306. 			"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>Damage:</td><td align='right' title='LDdamageValue'>0</td></tr>" +
  1307. 			"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>HP:</td><td align='right' title='LDhpValue'>0</td></tr>" +
  1308. 			"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>Processed:</td><td align='right' title='LDProcessed'>0</td></tr>" +
  1309. 			"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>LDFlinchLevel:</td><td align='right' title='LDFlinchLevel'>0</td></tr>" +
  1310. 			"<tr><td colspan='2' style='border-top:2px black solid;'>Other Defender Stats</td></tr>" +
  1311. 			"<tr><td align='right' style='color:brown;'>Attack:</td><td align='right' title='attackValue'>0</td></tr>" +
  1312. 			"<tr><td align='right' style='color:brown;'>Defense:</td><td align='right' title='defenseValue'>0</td></tr>" +
  1313. 			"<tr><td align='right' style='color:brown;'>Armor:</td><td align='right' title='armorValue'>0</td></tr>" +
  1314. 			"<tr><td align='right' style='color:brown;'>Damage:</td><td align='right' title='damageValue'>0</td></tr>" +
  1315. 			"<tr><td align='right' style='color:brown;'>HP:</td><td align='right' title='hpValue'>0</td></tr>" +
  1316. 			"<tr><td align='right' style='color:brown;'>Processed:</td><td align='right' title='defendersProcessed'>0</td></tr>" +
  1317. 			"<tr><td style='border-top:2px black solid;' colspan=2>DC and Flinch adjusted defense values:</td></tr>" +
  1318. 			"<tr><td style='font-size:x-small;' align='right'>DC225:</td><td style='font-size:x-small;' align='right' title='DC225'>0</td></tr>" +
  1319. 			"<tr><td style='font-size:x-small;' align='right'>DC175:</td><td style='font-size:x-small;' align='right' title='DC175'>0</td></tr>" +
  1320. 			"<tr><td style='font-size:x-small;' align='right'>Flinch effect:</td><td style='font-size:x-small;' align='right' title='FlinchEffect'>0</td></tr>" +
  1321. 			"<tr><td style='font-size:x-small;' align='right'>DC225 + Flinch effect:</td><td style='font-size:x-small;' align='right' title='DC225Flinch'>0</td></tr>" +
  1322. 			"<tr><td style='font-size:x-small;' align='right'>DC175 + Flinch effect:</td><td style='font-size:x-small;' align='right' title='DC175Flinch'>0</td></tr>" +
  1323. 			"<tr><td colspan='2' style='font-size:x-small; color:gray;'>Above calculations include Constitution, Flinch and Nightmare Visage bonus calculations on lead defender. " +
  1324. 				"Note: Assumption is that for these three buffs, the effects only apply to the lead defender/attacker.</td></tr>";
  1325. 		if (defendingGuildID == myGuildID && !hideRelicOffline) {
  1326. 			var validMemberArray = validMemberString.split(" ");
  1327. 			memberList = System.getValueJSON("memberlist");
  1328. 			for (i=0;i<validMemberArray.length-1;i++) {
  1329. 				var guildMemberName = validMemberArray[i];
  1330. 				for (var j=0; j<memberList.members.length; j++) {
  1331. 					if (memberList.members[j].name == guildMemberName) {
  1332. 						var memberId = memberList.members[j].id;
  1333. 						break;
  1334. 					}
  1335. 				}
  1336. 				href = System.server + "?cmd=profile&player_id=" + memberId;
  1337. 				System.xmlhttp(href, Helper.checkPlayerActivity, {"playerName":guildMemberName,"playerId":memberId});
  1338. 			}
  1339. 			extraTextInsertPoint.innerHTML += "<tr><td style='border-top:2px black solid;' colspan=2>Offline guild members not at relic:</td></tr>" +
  1340. 				"<tr title='offlinePlayerListControl' style='display:none; visibility:hidden;'><td style='font-size:x-small; color:red;' colspan=2 title='offlinePlayerList'>" + validMemberString + "</td></tr>" +
  1341. 				"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>OfflinePlayerCount:</td><td align='right' title='offlinePlayerCount'>" + validMemberArray.length + "</td></tr>" +
  1342. 				"<tr style='display:none; visibility:hidden;'><td align='right' style='color:brown;'>OfflinePlayersProcessed:</td><td align='right' title='offlinePlayersProcessed'>0</td></tr>" +
  1343. 				"<tr title='offlinePlayerListControlTemp' style='display:block;'><td style='font-size:small; color:green;' colspan=2>Processing ...</td></tr>";
  1344. 		}
  1345. 		extraTextInsertPoint.innerHTML += "</table><td><tr>";
  1346. 	},
  1347.  
  1348. 	checkPlayerActivity: function(responseText, callback) {
  1349. 		var doc = System.createDocument(responseText);
  1350. 		var lastActivity = System.findNode("//h2[contains(.,'Last Activity:')]", doc);
  1351. 		var playerName = callback.playerName;
  1352. 		var playerId = callback.playerId;
  1353. 		var offlinePlayerList = System.findNode("//td[@title='offlinePlayerList']");
  1354. 		var offlinePlayerCount = System.intValue(System.findNode("//td[@title='offlinePlayerCount']").innerHTML);
  1355. 		var offlinePlayersProcessed = System.findNode("//td[@title='offlinePlayersProcessed']");
  1356. 		offlinePlayersProcessed.innerHTML = System.intValue(offlinePlayersProcessed.innerHTML) + 1;
  1357. 		if (System.intValue(offlinePlayersProcessed.innerHTML) == (offlinePlayerCount - 1)) {
  1358. 			var offlinePlayerListControl = System.findNode("//tr[@title='offlinePlayerListControl']");
  1359. 			var offlinePlayerListControlTemp = System.findNode("//tr[@title='offlinePlayerListControlTemp']");
  1360. 			offlinePlayerListControl.style.display = "block";
  1361. 			offlinePlayerListControl.style.visibility = "visible";
  1362. 			offlinePlayerListControlTemp.style.display = "none";
  1363. 			offlinePlayerListControlTemp.style.visibility = "hidden";
  1364. 		}
  1365. 		if (!lastActivity || lastActivity.innerHTML == 'Last Activity: Inactive Account') {
  1366. 			offlinePlayerList.innerHTML = offlinePlayerList.innerHTML.replace(playerName + " ","");
  1367. 		} else if (lastActivity.innerHTML.search("days") != -1 && /(\d+) days/.exec(lastActivity.innerHTML)[1] >= 7) {
  1368. 			offlinePlayerList.innerHTML = offlinePlayerList.innerHTML.replace(playerName + " ","");
  1369. 		} else {
  1370. 			offlinePlayerList.innerHTML =
  1371. 				offlinePlayerList.innerHTML.replace(playerName + " ", "<a style='color:red;' href='index.php?cmd=profile&player_id=" + playerId + "'><span style='color:red;'>" + playerName + "</span></a> ");
  1372. 		}
  1373. 	},
  1374.  
  1375. 	getRelicGuildData: function(extraTextInsertPoint,hrefpointer) {
  1376. 		System.xmlhttp(hrefpointer, Helper.parseRelicGuildData, {"extraTextInsertPoint":extraTextInsertPoint});
  1377. 	},
  1378.  
  1379. 	parseRelicGuildData: function(responseText, callback) {
  1380. 		var extraTextInsertPoint = callback.extraTextInsertPoint;
  1381. 		var doc=System.createDocument(responseText);
  1382. 		var allItems = doc.getElementsByTagName("IMG");
  1383. 		var relicCount = 0;
  1384. 		for (var i=0;i<allItems.length-1;i++) {
  1385. 			var anItem=allItems[i];
  1386. 			var mouseoverText = anItem.getAttribute("onmouseover");
  1387. 			if (mouseoverText && mouseoverText.search("Relic Bonuses") != -1){
  1388. 				relicCount++;
  1389. 			}
  1390. 		}
  1391. 		var relicCountValue = System.findNode("//td[@title='relicCount']");
  1392. 		relicCountValue.innerHTML = relicCount;
  1393. 		var relicProcessedValue = System.findNode("//td[@title='relicProcessed']");
  1394. 		relicProcessedValue.innerHTML = 1;
  1395. 		var relicMultiplier = 1;
  1396. 		if (relicCount == 1) {
  1397. 			relicMultiplier = 1.5;
  1398. 		}
  1399. 		else if (relicCount >= 2) {
  1400. 			relicMultiplier = Math.round((1.1 - (relicCount/10))*100)/100;
  1401. 		}
  1402. 		var LDProcessedValue = System.findNode("//td[@title='LDProcessed']");
  1403. 		if (LDProcessedValue.innerHTML == "1") {
  1404. 			var attackValue              = System.findNode("//td[@title='attackValue']");
  1405. 			var LDattackValue            = System.findNode("//td[@title='LDattackValue']");
  1406. 			attackNumber                 = System.intValue(attackValue.innerHTML);
  1407. 			LDattackNumber               = System.intValue(LDattackValue.innerHTML);
  1408. 			attackValue.innerHTML        = System.addCommas(attackNumber + Math.round(LDattackNumber*relicMultiplier));
  1409. 			var defenseValue             = System.findNode("//td[@title='defenseValue']");
  1410. 			var LDdefenseValue           = System.findNode("//td[@title='LDdefenseValue']");
  1411. 			defenseNumber                = System.intValue(defenseValue.innerHTML);
  1412. 			LDdefenseNumber              = System.intValue(LDdefenseValue.innerHTML);
  1413. 			var overallDefense           = defenseNumber + Math.round(LDdefenseNumber*relicMultiplier);
  1414. 			defenseValue.innerHTML       = System.addCommas(overallDefense);
  1415. 			var storedFlinchLevel        = System.intValue(System.findNode("//td[@title='LDFlinchLevel']").textContent);
  1416. 			var dc225                    = System.findNode("//td[@title='DC225']");
  1417. 			var dc175                    = System.findNode("//td[@title='DC175']");
  1418. 			dc225.innerHTML              = System.addCommas(Math.ceil(overallDefense * (1 - (225 * 0.002))));
  1419. 			dc175.innerHTML              = System.addCommas(Math.ceil(overallDefense * (1 - (175 * 0.002))));
  1420. 			var flinchEffect             = System.findNode("//td[@title='FlinchEffect']");
  1421. 			var flinchEffectValue        = Helper.characterAttack * storedFlinchLevel * 0.001;
  1422. 			flinchEffect.innerHTML       = Math.ceil(flinchEffectValue);
  1423. 			var dc225Flinch              = System.findNode("//td[@title='DC225Flinch']");
  1424. 			var dc175Flinch              = System.findNode("//td[@title='DC175Flinch']");
  1425. 			dc225Flinch.innerHTML        = System.addCommas(Math.ceil(overallDefense * (1 - (225 * 0.002)) + flinchEffectValue));
  1426. 			dc175Flinch.innerHTML        = System.addCommas(Math.ceil(overallDefense * (1 - (175 * 0.002)) + flinchEffectValue));
  1427. 			var armorValue               = System.findNode("//td[@title='armorValue']");
  1428. 			var LDarmorValue             = System.findNode("//td[@title='LDarmorValue']");
  1429. 			armorNumber                  = System.intValue(armorValue.innerHTML);
  1430. 			LDarmorNumber                = System.intValue(LDarmorValue.innerHTML);
  1431. 			armorValue.innerHTML         = System.addCommas(armorNumber + Math.round(LDarmorNumber*relicMultiplier));
  1432. 			var damageValue              = System.findNode("//td[@title='damageValue']");
  1433. 			var LDdamageValue            = System.findNode("//td[@title='LDdamageValue']");
  1434. 			damageNumber                 = System.intValue(damageValue.innerHTML);
  1435. 			LDdamageNumber               = System.intValue(LDdamageValue.innerHTML);
  1436. 			damageValue.innerHTML        = System.addCommas(damageNumber + Math.round(LDdamageNumber*relicMultiplier));
  1437. 			var hpValue                  = System.findNode("//td[@title='hpValue']");
  1438. 			var LDhpValue                = System.findNode("//td[@title='LDhpValue']");
  1439. 			hpNumber                     = System.intValue(hpValue.innerHTML);
  1440. 			LDhpNumber                   = System.intValue(LDhpValue.innerHTML);
  1441. 			hpValue.innerHTML            = System.addCommas(hpNumber + Math.round(LDhpNumber*relicMultiplier));
  1442. 			var defendersProcessed       = System.findNode("//td[@title='defendersProcessed']");
  1443. 			var defendersProcessedNumber = System.intValue(defendersProcessed.innerHTML);
  1444. 			defendersProcessed.innerHTML = System.addCommas(defendersProcessedNumber + 1);
  1445. 			var LDpercentageValue        = System.findNode("//td[@title='LDPercentage']");
  1446. 			LDpercentageValue.innerHTML  = (relicMultiplier*100) + "%";
  1447. 		}
  1448. 	},
  1449.  
  1450. 	getRelicPlayerData: function(defenderCount,extraTextInsertPoint,hrefpointer) {
  1451. 		System.xmlhttp(hrefpointer, Helper.parseRelicPlayerData, {"defenderCount": defenderCount, "extraTextInsertPoint": extraTextInsertPoint});
  1452. 	},
  1453.  
  1454. 	parseRelicPlayerData: function(responseText, callback) {
  1455. 		var defenderCount = callback.defenderCount;
  1456. 		var extraTextInsertPoint = callback.extraTextInsertPoint;
  1457. 		var doc = System.createDocument(responseText);
  1458. 		var allItems = doc.getElementsByTagName("B");
  1459. 		var playerAttackValue = 0, playerDefenseValue = 0, playerArmorValue = 0, playerDamageValue = 0, playerHPValue = 0;
  1460. 		for (var i=0;i<allItems.length;i++) {
  1461. 			var anItem=allItems[i];
  1462. 			if (anItem.innerHTML == "Attack:&nbsp;"){
  1463. 				var attackText = anItem;
  1464. 				var attackLocation = attackText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  1465. 				playerAttackValue = attackLocation.textContent;
  1466. 				var defenseText = attackText.parentNode.nextSibling.nextSibling.nextSibling.firstChild;
  1467. 				var defenseLocation = defenseText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  1468. 				playerDefenseValue = defenseLocation.textContent;
  1469. 				var armorText = defenseText.parentNode.parentNode.nextSibling.nextSibling.firstChild.nextSibling.firstChild;
  1470. 				var armorLocation = armorText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  1471. 				playerArmorValue = armorLocation.textContent;
  1472. 				var damageText = armorText.parentNode.nextSibling.nextSibling.nextSibling.firstChild;
  1473. 				var damageLocation = damageText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  1474. 				playerDamageValue = damageLocation.textContent;
  1475. 				var hpText = damageText.parentNode.parentNode.nextSibling.nextSibling.firstChild.nextSibling.firstChild;
  1476. 				var hpLocation = hpText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  1477. 				playerHPValue = hpLocation.textContent;
  1478. 			}
  1479. 		}
  1480.  
  1481. 		if (defenderCount !== 0) {
  1482. 			var defenderMultiplier       = 0.2;
  1483. 			var attackValue              = System.findNode("//td[@title='attackValue']");
  1484. 			attackNumber                 = System.intValue(attackValue.innerHTML);
  1485. 			attackValue.innerHTML        = System.addCommas(attackNumber + Math.round(playerAttackValue*defenderMultiplier));
  1486. 			var defenseValue             = System.findNode("//td[@title='defenseValue']");
  1487. 			defenseNumber                = System.intValue(defenseValue.innerHTML);
  1488. 			var overallDefense           = defenseNumber + Math.round(playerDefenseValue*defenderMultiplier);
  1489. 			defenseValue.innerHTML       = System.addCommas(overallDefense);
  1490. 			var storedFlinchLevel        = System.intValue(System.findNode("//td[@title='LDFlinchLevel']").textContent);
  1491. 			var dc225                    = System.findNode("//td[@title='DC225']");
  1492. 			var dc175                    = System.findNode("//td[@title='DC175']");
  1493. 			dc225.innerHTML              = System.addCommas(Math.ceil(overallDefense * (1 - (225 * 0.002))));
  1494. 			dc175.innerHTML              = System.addCommas(Math.ceil(overallDefense * (1 - (175 * 0.002))));
  1495. 			var flinchEffect             = System.findNode("//td[@title='FlinchEffect']");
  1496. 			var flinchEffectValue        = Helper.characterAttack * storedFlinchLevel * 0.001;
  1497. 			flinchEffect.innerHTML       = Math.ceil(flinchEffectValue);
  1498. 			var dc225Flinch              = System.findNode("//td[@title='DC225Flinch']");
  1499. 			var dc175Flinch              = System.findNode("//td[@title='DC175Flinch']");
  1500. 			dc225Flinch.innerHTML        = System.addCommas(Math.ceil(overallDefense * (1 - (225 * 0.002)) + flinchEffectValue));
  1501. 			dc175Flinch.innerHTML        = System.addCommas(Math.ceil(overallDefense * (1 - (175 * 0.002)) + flinchEffectValue));
  1502. 			var armorValue               = System.findNode("//td[@title='armorValue']");
  1503. 			armorNumber                  = System.intValue(armorValue.innerHTML);
  1504. 			armorValue.innerHTML         = System.addCommas(armorNumber + Math.round(playerArmorValue*defenderMultiplier));
  1505. 			var damageValue              = System.findNode("//td[@title='damageValue']");
  1506. 			damageNumber                 = System.intValue(damageValue.innerHTML);
  1507. 			damageValue.innerHTML        = System.addCommas(damageNumber + Math.round(playerDamageValue*defenderMultiplier));
  1508. 			var hpValue                  = System.findNode("//td[@title='hpValue']");
  1509. 			hpNumber                     = System.intValue(hpValue.innerHTML);
  1510. 			hpValue.innerHTML            = System.addCommas(hpNumber + Math.round(playerHPValue*defenderMultiplier));
  1511. 			var defendersProcessed       = System.findNode("//td[@title='defendersProcessed']");
  1512. 			var defendersProcessedNumber = System.intValue(defendersProcessed.innerHTML);
  1513. 			defendersProcessed.innerHTML = System.addCommas(defendersProcessedNumber + 1);
  1514. 		}
  1515. 		else {
  1516. 			//get relavent buffs here later ... just Constitution atm
  1517. 			allItems = doc.getElementsByTagName("IMG");
  1518. 			var constitutionLevel = 0, flinchLevel = 0, nightmareVisageLevel = 0;
  1519. 			for (i=0;i<allItems.length;i++) {
  1520. 				anItem=allItems[i];
  1521. 				if (anItem.getAttribute("src").search("/skills/") != -1) {
  1522. 					var onmouseover = anItem.getAttribute("onmouseover");
  1523. 					var constitutionRE = /<b>Constitution<\/b> \(Level: (\d+)\)/;
  1524. 					var constitution =  constitutionRE.exec(onmouseover);
  1525. 					if (constitution) {
  1526. 						constitutionLevel = constitution[1];
  1527. 						continue;
  1528. 					}
  1529. 					var flinchRE = /<b>Flinch<\/b> \(Level: (\d+)\)/;
  1530. 					var flinch = flinchRE.exec(onmouseover);
  1531. 					if (flinch) {
  1532. 						flinchLevel = flinch[1];
  1533. 						continue;
  1534. 					}
  1535. 					var nightmareVisageRE = /<b>Nightmare Visage<\/b> \(Level: (\d+)\)/;
  1536. 					var nightmareVisage = nightmareVisageRE.exec(onmouseover);
  1537. 					if (nightmareVisage) {
  1538. 						nightmareVisageLevel = nightmareVisage[1];
  1539. 						continue;
  1540. 					}
  1541. 				}
  1542. 			}
  1543.  
  1544. 			defenderMultiplier = 1;
  1545. 			attackValue = System.findNode("//td[@title='LDattackValue']");
  1546. 			attackNumber = System.intValue(attackValue.innerHTML);
  1547. 			var nightmareVisageEffect = Math.ceil(System.intValue(playerAttackValue)*(nightmareVisageLevel * 0.0025));
  1548. 			playerAttackValue = playerAttackValue - nightmareVisageEffect;
  1549. 			attackValue.innerHTML = System.addCommas(attackNumber + Math.round(playerAttackValue*defenderMultiplier));
  1550. 			defenseValue = System.findNode("//td[@title='LDdefenseValue']");
  1551. 			defenseNumber = System.intValue(defenseValue.innerHTML);
  1552. 			playerDefenseValue = Math.ceil(System.intValue(playerDefenseValue) * (1 + constitutionLevel * 0.001)) + nightmareVisageEffect;
  1553. 			defenseValue.innerHTML = System.addCommas(defenseNumber + Math.round(playerDefenseValue*defenderMultiplier));
  1554. 			armorValue = System.findNode("//td[@title='LDarmorValue']");
  1555. 			armorNumber=System.intValue(armorValue.innerHTML);
  1556. 			armorValue.innerHTML = System.addCommas(armorNumber + Math.round(playerArmorValue*defenderMultiplier));
  1557. 			damageValue = System.findNode("//td[@title='LDdamageValue']");
  1558. 			damageNumber=System.intValue(damageValue.innerHTML);
  1559. 			damageValue.innerHTML = System.addCommas(damageNumber + Math.round(playerDamageValue*defenderMultiplier));
  1560. 			hpValue = System.findNode("//td[@title='LDhpValue']");
  1561. 			hpNumber=System.intValue(hpValue.innerHTML);
  1562. 			hpValue.innerHTML = System.addCommas(hpNumber + Math.round(playerHPValue*defenderMultiplier));
  1563. 			defendersProcessed = System.findNode("//td[@title='LDProcessed']");
  1564. 			defendersProcessedNumber=System.intValue(defendersProcessed.innerHTML);
  1565. 			defendersProcessed.innerHTML = System.addCommas(defendersProcessedNumber + 1);
  1566. 			storedFlinchLevel = System.findNode("//td[@title='LDFlinchLevel']");
  1567. 			storedFlinchLevel.innerHTML = System.intValue(flinchLevel);
  1568. 		}
  1569. 		var relicProcessedValue = System.findNode("//td[@title='relicProcessed']");
  1570. 		var relicCountValue = System.findNode("//td[@title='relicCount']");
  1571. 		var relicCount = System.intValue(relicCountValue.innerHTML);
  1572.  
  1573. 		var relicMultiplier = 1;
  1574. 		if (relicCount == 1) {
  1575. 			relicMultiplier = 1.5;
  1576. 		}
  1577. 		else if (relicCount >= 2) {
  1578. 			relicMultiplier = Math.round((1.1 - (relicCount/10))*100)/100;
  1579. 		}
  1580.  
  1581. 		if (defenderCount === 0 && relicProcessedValue.innerHTML == "1") {
  1582. 			attackValue              = System.findNode("//td[@title='attackValue']");
  1583. 			var LDattackValue            = System.findNode("//td[@title='LDattackValue']");
  1584. 			attackNumber                 = System.intValue(attackValue.innerHTML);
  1585. 			LDattackNumber               = System.intValue(LDattackValue.innerHTML);
  1586. 			attackValue.innerHTML        = System.addCommas(attackNumber + Math.round(LDattackNumber*relicMultiplier));
  1587. 			defenseValue             = System.findNode("//td[@title='defenseValue']");
  1588. 			var LDdefenseValue           = System.findNode("//td[@title='LDdefenseValue']");
  1589. 			defenseNumber                = System.intValue(defenseValue.innerHTML);
  1590. 			LDdefenseNumber              = System.intValue(LDdefenseValue.innerHTML);
  1591. 			overallDefense           = defenseNumber + Math.round(LDdefenseNumber*relicMultiplier);
  1592. 			defenseValue.innerHTML       = System.addCommas(overallDefense);
  1593. 			storedFlinchLevel        = System.intValue(System.findNode("//td[@title='LDFlinchLevel']").textContent);
  1594. 			dc225                    = System.findNode("//td[@title='DC225']");
  1595. 			dc175                    = System.findNode("//td[@title='DC175']");
  1596. 			dc225.innerHTML              = System.addCommas(Math.ceil(overallDefense * (1 - (225 * 0.002))));
  1597. 			dc175.innerHTML              = System.addCommas(Math.ceil(overallDefense * (1 - (175 * 0.002))));
  1598. 			flinchEffect             = System.findNode("//td[@title='FlinchEffect']");
  1599. 			flinchEffectValue        = Helper.characterAttack * storedFlinchLevel * 0.001;
  1600. 			flinchEffect.innerHTML       = Math.ceil(flinchEffectValue);
  1601. 			dc225Flinch              = System.findNode("//td[@title='DC225Flinch']");
  1602. 			dc175Flinch              = System.findNode("//td[@title='DC175Flinch']");
  1603. 			dc225Flinch.innerHTML        = System.addCommas(Math.ceil(overallDefense * (1 - (225 * 0.002)) + flinchEffectValue));
  1604. 			dc175Flinch.innerHTML        = System.addCommas(Math.ceil(overallDefense * (1 - (175 * 0.002)) + flinchEffectValue));
  1605. 			armorValue               = System.findNode("//td[@title='armorValue']");
  1606. 			var LDarmorValue             = System.findNode("//td[@title='LDarmorValue']");
  1607. 			armorNumber                  = System.intValue(armorValue.innerHTML);
  1608. 			LDarmorNumber                = System.intValue(LDarmorValue.innerHTML);
  1609. 			armorValue.innerHTML         = System.addCommas(armorNumber + Math.round(LDarmorNumber*relicMultiplier));
  1610. 			damageValue              = System.findNode("//td[@title='damageValue']");
  1611. 			var LDdamageValue            = System.findNode("//td[@title='LDdamageValue']");
  1612. 			damageNumber                 = System.intValue(damageValue.innerHTML);
  1613. 			LDdamageNumber               = System.intValue(LDdamageValue.innerHTML);
  1614. 			damageValue.innerHTML        = System.addCommas(damageNumber + Math.round(LDdamageNumber*relicMultiplier));
  1615. 			hpValue                  = System.findNode("//td[@title='hpValue']");
  1616. 			var LDhpValue                = System.findNode("//td[@title='LDhpValue']");
  1617. 			hpNumber                     = System.intValue(hpValue.innerHTML);
  1618. 			LDhpNumber                   = System.intValue(LDhpValue.innerHTML);
  1619. 			hpValue.innerHTML            = System.addCommas(hpNumber + Math.round(LDhpNumber*relicMultiplier));
  1620. 			defendersProcessed       = System.findNode("//td[@title='defendersProcessed']");
  1621. 			defendersProcessedNumber     = System.intValue(defendersProcessed.innerHTML);
  1622. 			defendersProcessed.innerHTML = System.addCommas(defendersProcessedNumber + 1);
  1623. 			var LDpercentageValue        = System.findNode("//td[@title='LDPercentage']");
  1624. 			LDpercentageValue.innerHTML  = (relicMultiplier*100) + "%";
  1625. 		}
  1626. 	},
  1627.  
  1628. 	position: function() {
  1629. 		var result = {};
  1630. 		if (Helper.page=="world/map/-(-)") {
  1631. 			var playerTile=System.findNode("//img[contains(@src,'player_tile.gif')]/../../../../../..");
  1632. 			result.X=playerTile.cellIndex;
  1633. 			result.Y=playerTile.parentNode.rowIndex;
  1634. 			result.type="worldmap";
  1635. 		}
  1636. 		else {
  1637. 			var posit = System.findNode("//td[contains(@background,'/skin/realm_top_b4.jpg')]//center/nobr");
  1638. 			if (!posit) {return;}
  1639. 			var thePosition=posit.innerHTML;
  1640. 			var positionRE=/\((\d+),\s*(\d+)\)/;
  1641. 			var positionX = parseInt(thePosition.match(positionRE)[1],10);
  1642. 			var positionY = parseInt(thePosition.match(positionRE)[2],10);
  1643. 			result.X=positionX;
  1644. 			result.Y=positionY;
  1645. 			result.type="normal";
  1646. 		}
  1647. 		return result;
  1648. 	},
  1649.  
  1650. 	mapThis: function() {
  1651. 		if (!GM_getValue("footprints")) {return;}
  1652. 		var realm = System.findNode("//td[contains(@background,'/skin/realm_top_b2.jpg')]/center/nobr/b");
  1653. 		var posit = Helper.position();
  1654.  
  1655. 		if ((realm) && (posit)) {
  1656. 			var levelName=realm.innerHTML;
  1657. 			Helper.levelName = levelName;
  1658. 			var theMap = System.getValueJSON("map");
  1659. 			if (!theMap) {
  1660. 				theMap = {};
  1661. 				theMap["levels"] = {};
  1662. 			}
  1663. 			if (!theMap["levels"][levelName]) theMap["levels"][levelName] = {};
  1664. 			if (!theMap["levels"][levelName][posit.X]) theMap["levels"][levelName][posit.X]={};
  1665. 			theMap["levels"][levelName][posit.X][posit.Y]="!";
  1666. 			System.setValueJSON("map", theMap);
  1667. 		}
  1668. 	},
  1669.  
  1670. 	showMap: function(isLarge) {
  1671. 		if (!GM_getValue("footprints")) {return;}
  1672. 		if (isLarge) {
  1673. 			var realm = System.findNode("//b");
  1674. 			Helper.levelName = realm.textContent.replace(" Map Overview", "");
  1675. 		}
  1676. 		// GM_log(Helper.levelName);
  1677. 		var theMap = System.getValueJSON("map");
  1678. 		var displayedMap = System.findNode(isLarge ? "//table[@width]" : "//table[@width='200']");
  1679. 		if (!displayedMap) {return;}
  1680. 		var footprintsColor = GM_getValue("footprintsColor");
  1681. 		var posit = Helper.position();
  1682.  
  1683. 		for (var y = 0; y < displayedMap.rows.length; y++) {
  1684. 			var aRow = displayedMap.rows[y];
  1685. 			for (var x = 0; x < aRow.cells.length; x++) {
  1686. 				var aCell = aRow.cells[x];
  1687. 				var dx = isLarge ? x : posit.X + (x - 2);
  1688. 				var dy = isLarge ? y : posit.Y + (y - 2);
  1689. 				// GM_log(dx + ":" + dy)
  1690. 				if (theMap["levels"][Helper.levelName] && theMap["levels"][Helper.levelName][dx] && theMap["levels"][Helper.levelName][dx][dy] && (theMap["levels"][Helper.levelName][dx][dy] == "!")) {
  1691. 					// aCell.setAttribute("background", "http://66.7.192.165/tiles/9_50.gif");
  1692.  
  1693. 					if (x != (isLarge ? posit.X : 2) || y != (isLarge ? posit.Y : 2)) {
  1694. 						aCell.style.color = footprintsColor;
  1695. 						if (aCell.innerHTML.indexOf("table") > 0)
  1696. 							aCell.firstChild.firstChild.firstChild.firstChild.firstChild.innerHTML +="**";
  1697. 						else
  1698. 							aCell.innerHTML+="**";
  1699. 					}
  1700.  
  1701. 									}
  1702. 				// GM_log(x + ":" + y + " >> " + aCell.getAttribute("background"));
  1703. 			}
  1704. 		}
  1705. 	},
  1706.  
  1707. 	injectTHsearch: function() {
  1708. 		var items=System.findNodes("//img[contains(@onmouseover,'ajaxLoadItem') and contains(@src,'/items/')]");
  1709. 		if (items)
  1710. 			for (var i=0; i<items.length; i++) {
  1711. 				if (items[i].parentNode.tagName!='A') {
  1712. 					items[i].addEventListener('click', Helper.searchTHforItem, true);
  1713. 					items[i].style.cursor='pointer';
  1714. 				}
  1715. 			}
  1716. 	},
  1717.  
  1718. 	searchTHforItem: function(evt) {
  1719. 		var mo=evt.target.getAttribute("onmouseover");
  1720. 		System.xmlhttp(Helper.linkFromMouseover(mo), function(responseText) {
  1721. 				var name=responseText.match(/<b>([^<]*)<\/b>/)[1];
  1722. 				if (responseText.indexOf('Bound (Non-Tradable)') > 0)
  1723. 					if (!confirm(name + " is Bound (Non-Tradable), cannot be found in TH!\n"+
  1724. 						"Do you still want to try?")) return;
  1725. 				window.location='index.php?cmd=auctionhouse&type=-1&search_text='+name;
  1726. 			});
  1727. 	},
  1728.  
  1729. 	injectViewRecipe: function() {
  1730. 		var components = System.findNodes("//b[.='Components Required']/../../following-sibling::tr[2]//img");
  1731. 		for (var i = 0; i < components.length; i++) {
  1732. 			var mo = components[i].getAttribute("onmouseover");
  1733. 			System.xmlhttp(Helper.linkFromMouseoverCustom(mo), Helper.injectViewRecipeLinks, components[i]);
  1734. 		}
  1735. 	},
  1736.  
  1737. 	injectViewRecipeLinks: function(responseText, callback) {
  1738. 		var itemRE = /<b>([^<]+)<\/b>/i;
  1739. 		var itemName = itemRE.exec(responseText);
  1740. 		if (itemName) itemName=itemName[1];
  1741. 		var itemLinks = document.createElement("td");
  1742. 		itemLinks.innerHTML =
  1743. 			'<a href="' + System.server + '?cmd=auctionhouse&type=-1&order_by=1&search_text='+
  1744. 			escape(Data.plantFromComponent(itemName))+
  1745. 			'">AH</a>';
  1746. 		var counter=System.findNode("../../../../tr[2]/td", callback);
  1747. 		counter.setAttribute("colspan", "2");
  1748. 		callback.parentNode.parentNode.parentNode.appendChild(itemLinks);
  1749. 	},
  1750.  
  1751. 	injectAdvisor: function(subPage2Id) {
  1752. 		var list=System.findNode("//tr[td/b='Member']/../..");
  1753. 		if (!list) return;
  1754.  
  1755. 		// insert weekly summary link
  1756. 		var injectHere=System.findNode("//td/select/..");
  1757. 		if (injectHere) {
  1758. 			var elem=document.createElement("span");
  1759. 			elem.innerHTML=" <a href='index.php?cmd=guild&subcmd=advisor&subcmd2=weekly'>7-Day Summary</a>";
  1760. 			injectHere.appendChild(elem);
  1761. 		}
  1762. 		GM_addStyle(
  1763. 			'.HelperAdvisorRow1 {background-color:#e7c473;font-size:x-small}\n' +
  1764. 			'.HelperAdvisorRow1:hover {background-color:white}\n' +
  1765. 			'.HelperAdvisorRow2 {background-color:#e2b960;font-size:x-small}\n' +
  1766. 			'.HelperAdvisorRow2:hover {background-color:white}');
  1767.  
  1768. 		var memberList = System.getValueJSON("memberlist");
  1769. 		if (memberList) Helper.generateAdvisorRows(list);
  1770.  
  1771. 		if (! Helper.advisorHeader) {
  1772. 			Helper.advisorHeader = '<tr>';
  1773. 			titleCells = ["Member", "Lvl", "Rank", "Gold From Deposits", "Gold From Tax", "Gold Total", "FSPs", "Skills Cast", "Groups Created", "Groups Joined", "Relics Captured", "XP Contrib"];
  1774. 			for (var i=0; i<titleCells.length; i++) {
  1775. 				Helper.advisorHeader += "<th bgcolor=#cd9e4b align=center width=8% style='text-decoration: underline; cursor: pointer; font-size:x-small;'>" + titleCells[i] + "</td>";
  1776. 			}
  1777. 			Helper.advisorHeader += '</tr>';
  1778. 		}
  1779.  
  1780. 		if (! Helper.advisorFooter) {
  1781. 			Helper.advisorFooter = '<tr><td colspan=3 align=right>Total: </td>';
  1782. 			for (i=1; i<list.rows[list.rows.length-1].cells.length; i++) {
  1783. 				Helper.advisorFooter += "<td align=center>" + list.rows[list.rows.length-1].cells[i].innerHTML + '</td>';
  1784. 			}
  1785. 			Helper.advisorFooter +='</tr>';
  1786. 		}
  1787. 		if (subPage2Id!='-') {
  1788. 			Helper.advisorFooter='';
  1789. 		}
  1790.  
  1791. 		Helper.sortAsc = true;
  1792. 		if (subPage2Id == '-' && memberList) {
  1793. 			Helper.generateAdvisorRows(list);
  1794. 			Helper.sortAdvisor(list, "Member");
  1795. 		} else if (memberList){
  1796. 			list.innerHTML='Retrieving daily data ...';
  1797. 			Helper.generateWeeklyAdvisorRows('',{'day':0,'inject':list});
  1798. 		}
  1799. 	},
  1800.  
  1801. 	generateWeeklyAdvisorRows: function(responseText, callback) {
  1802. 		var day=callback.day;
  1803. 		if (day <= 7) {
  1804. 			if (day > 0) {
  1805. 				callback.inject.innerHTML+=' day '+day+',';
  1806. 				var doc=System.createDocument(responseText);
  1807. 				var list=System.findNode("//tr[td/b='Member']/../..",doc);
  1808. 				Helper.generateAdvisorRows(list);
  1809. 				if (day == 1) {
  1810. 					Helper.weeklyAdvisorRows = Helper.advisorRows;
  1811. 					Helper.advisorColumns = ['GoldFromDeposits','GoldFromTax',
  1812. 						'GoldTotal','FSPs','SkillsCast','GroupsCreated',
  1813. 						'GroupsJoined','RelicsCaptured','XPContrib'];
  1814. 				}
  1815. 				for (var i=1; i<list.rows.length-1; i++){
  1816. 					for (var id=0; id<Helper.advisorColumns.length; id++){
  1817. 						var columnName=Helper.advisorColumns[id];
  1818. 						if (day==1)
  1819. 							Helper.weeklyAdvisorRows[i-1][columnName]=
  1820. 								System.intValue(Helper.weeklyAdvisorRows[i-1][columnName]);
  1821. 						else
  1822. 							Helper.weeklyAdvisorRows[i-1][columnName]+=
  1823. 								System.intValue(Helper.advisorRows[i-1][columnName]);
  1824. 					}
  1825. 				}
  1826. 			}
  1827. 			System.xmlhttp("index.php?cmd=guild&subcmd=advisor&period="+(day+1),
  1828. 				Helper.generateWeeklyAdvisorRows, {'day':(day+1),'inject':callback.inject});
  1829. 		} else {
  1830. 			Helper.advisorRows = Helper.weeklyAdvisorRows;
  1831. 			for (i=1; i<=Helper.advisorRows.length; i++){
  1832. 				for (id=0; id<Helper.advisorColumns.length; id++){
  1833. 					columnName=Helper.advisorColumns[id];
  1834. 					Helper.advisorRows[i-1][columnName]=
  1835. 						System.addCommas(Helper.advisorRows[i-1][columnName]);
  1836. 				}
  1837. 			}
  1838. 			Helper.sortAdvisor(callback.inject, "Member");
  1839. 		}
  1840. 	},
  1841.  
  1842. 	generateAdvisorRows: function(list) {
  1843. 		Helper.advisorRows = [];
  1844. 		var memberList = System.getValueJSON("memberlist");
  1845. 		for (var i=1; i<list.rows.length-1; i++){
  1846. 			var theRow=list.rows[i];
  1847. 			var name = theRow.cells[0].textContent.replace(/\s/, "");
  1848. 			for (var j=0; j<memberList.members.length; j++) {
  1849. 				if (memberList.members[j].name == name) {
  1850. 					var member = memberList.members[j];
  1851. 					break;
  1852. 				}
  1853. 			}
  1854. 			Helper.advisorRows[i-1] = {
  1855. 				'Id':(member != undefined ? member.id : -1),
  1856. 				'Member': theRow.cells[0].textContent,
  1857. 				'Lvl':(member != undefined ? member.level : -1),
  1858. 				'Rank':(member != undefined ? member.rank : ""),
  1859. 				'GoldFromDeposits': theRow.cells[1].textContent,
  1860. 				'GoldFromTax': theRow.cells[2].textContent,
  1861. 				'GoldTotal': theRow.cells[3].textContent,
  1862. 				'FSPs': theRow.cells[4].textContent,
  1863. 				'SkillsCast': theRow.cells[5].textContent,
  1864. 				'GroupsCreated': theRow.cells[6].textContent,
  1865. 				'GroupsJoined': theRow.cells[7].textContent,
  1866. 				'RelicsCaptured': theRow.cells[8].textContent,
  1867. 				'XPContrib': theRow.cells[9].textContent
  1868. 			};
  1869. 		}
  1870. 	},
  1871.  
  1872. 	advisorHeaderClicked: function(evt) {
  1873. 		var headerClicked=evt.target.textContent;
  1874. 		var list=evt.target.parentNode.parentNode;
  1875. 		Helper.sortAdvisor(list, headerClicked.replace(/ /g, ""));
  1876. 	},
  1877.  
  1878. 	sortAdvisor: function(list, sortBy) {
  1879. 		if (Helper.sortAsc==undefined) Helper.sortAsc=true;
  1880. 		if (Helper.sortBy && Helper.sortBy==sortBy) {
  1881. 			Helper.sortAsc=!Helper.sortAsc;
  1882. 		}
  1883. 		Helper.sortBy=sortBy;
  1884.  
  1885. 		if (sortBy=="Member" || sortBy=="Rank") {
  1886. 			Helper.advisorRows.sort(Helper.stringSort);
  1887. 		}
  1888. 		else {
  1889. 			Helper.advisorRows.sort(Helper.numberSort);
  1890. 		}
  1891.  
  1892. 		var result = Helper.advisorHeader;
  1893.  
  1894. 		for (var i=0; i<Helper.advisorRows.length; i++){
  1895. 			var r = Helper.advisorRows[i];
  1896. 			result += '<tr class="HelperAdvisorRow'+(1+i % 2)+'">'+
  1897. 			'<td> <a href="index.php?cmd=profile&player_id=' + r.Id +'">' +r.Member+ '</a></td>'+
  1898. 			'<td align="center"> '+r.Lvl+'</td>'+
  1899. 			'<td align="center"> '+r.Rank.substr(0,9)+ (r.Rank.length>9 ? '...' : '') + '</td>'+
  1900. 			'<td align="center">'+r.GoldFromDeposits+'</td>'+
  1901. 			'<td align="center">'+r.GoldFromTax+'</td>'+
  1902. 			'<td align="center">'+r.GoldTotal+'</td>'+
  1903. 			'<td align="center">'+r.FSPs+'</td>'+
  1904. 			'<td align="center">'+r.SkillsCast+'</td>'+
  1905. 			'<td align="center">'+r.GroupsCreated+'</td>'+
  1906. 			'<td align="center">'+r.GroupsJoined+'</td>'+
  1907. 			'<td align="center">'+r.RelicsCaptured+'</td>'+
  1908. 			'<td align="center">'+r.XPContrib+'</td></tr>';
  1909. 		}
  1910. 		if (Helper.advisorFooter!=='')
  1911. 			result+=Helper.advisorFooter;
  1912. 		else {
  1913. 			Helper.advisorFooter='<tr><td align="right" colspan="3">Total: </td>';
  1914. 			for (var id=0; id<Helper.advisorColumns.length; id++){
  1915. 				var sum=0;
  1916. 				var columnName=Helper.advisorColumns[id];
  1917. 				for (i=0; i<Helper.advisorRows.length; i++)
  1918. 					sum+=System.intValue(Helper.advisorRows[i][columnName]);
  1919. 				Helper.advisorFooter+='<td align="center" style="text-decoration:underline;font-weight:bold;font-size:x-small">'+System.addCommas(sum)+'</td>';
  1920. 			}
  1921. 			Helper.advisorFooter+='</tr>';
  1922. 			result+=Helper.advisorFooter;
  1923. 		}
  1924.  
  1925. 		list.innerHTML=result;
  1926.  
  1927. 		for (i=0; i<list.rows[0].cells.length; i++) {
  1928. 			var cell=list.rows[0].cells[i];
  1929. 			cell.style.textDecoration="underline";
  1930. 			cell.style.cursor="pointer";
  1931. 			cell.addEventListener('click', Helper.advisorHeaderClicked, true);
  1932. 		}
  1933.  
  1934. 	},
  1935.  
  1936. 	stringSort: function(a,b) {
  1937. 		var result=0;
  1938. 		if (a[Helper.sortBy].toLowerCase()<b[Helper.sortBy].toLowerCase()) result=-1;
  1939. 		if (a[Helper.sortBy].toLowerCase()>b[Helper.sortBy].toLowerCase()) result=+1;
  1940. 		if (!Helper.sortAsc) result=-result;
  1941. 		return result;
  1942. 	},
  1943.  
  1944. 	numberSort: function(a,b) {
  1945. 		var result=0;
  1946. 		var valueA=a[Helper.sortBy];
  1947. 		var valueB=b[Helper.sortBy];
  1948. 		if (typeof valueA=="string") valueA=parseInt(valueA.replace(/,/g,"").replace(/#/g,""),10);
  1949. 		if (typeof valueB=="string") valueB=parseInt(valueB.replace(/,/g,"").replace(/#/g,""),10);
  1950. 		result = valueA-valueB;
  1951. 		if (!Helper.sortAsc) result=-result;
  1952. 		return result;
  1953. 	},
  1954.  
  1955. 	questStatusSort: function(a,b) {
  1956. 		var result=0;
  1957. 		var valueA,valueB;
  1958. 		var statuses = ["Incomplete", "Complete", ""];
  1959. 		if (!a[Helper.sortBy]) {
  1960. 			valueA=Helper.sortAsc?50:-50;
  1961. 		}
  1962. 		else {
  1963. 			valueA=statuses.indexOf(a[Helper.sortBy]);
  1964. 		}
  1965. 		if (!b[Helper.sortBy]) {
  1966. 			valueB=Helper.sortAsc?50:-50;
  1967. 		}
  1968. 		else {
  1969. 			valueB=statuses.indexOf(b[Helper.sortBy]);
  1970. 		}
  1971.  
  1972. 		result = valueA-valueB;
  1973. 		if (!Helper.sortAsc) result=-result;
  1974. 		return result;
  1975. 	},
  1976.  
  1977. 	checkBuffs: function() {
  1978. 		//code to remove buffs but stay on the same screen
  1979. 		var currentBuffs = System.findNodes("//a[contains(@href,'index.php?cmd=profile&subcmd=removeskill&skill_id=')]");
  1980. 		var buffHash={};
  1981. 		if (currentBuffs) {
  1982. 			for (var i=0;i<currentBuffs.length;i++) {
  1983. 				var currentBuff = currentBuffs[i];
  1984. 				var buffHref = currentBuff.getAttribute("href");
  1985. 				var buffTest = /remove\sthe\s([ a-zA-Z]+)\sskill/.exec(currentBuff.getAttribute("onclick"));
  1986. 				if (buffTest) {
  1987. 					var buffName = buffTest[1];
  1988. 				} else {
  1989. 					buffTest = /remove\sthe\s([ a-zA-Z]+)<br>/.exec(currentBuff.getAttribute("onclick"));
  1990. 					if (buffTest) buffName = buffTest[1]; else GM_log("Error getting buff");
  1991. 				}
  1992. 				buffHash[buffName]=true;
  1993. 				var imageHTML = currentBuff.innerHTML;
  1994. 				var buffCell = currentBuff.parentNode;
  1995. 				var buffHTML = buffCell.innerHTML;
  1996. 				var lastPart = buffHTML.substring(buffHTML.indexOf("</a>")+4, buffHTML.length);
  1997. 				var newCellContents = '<span id="Helper:removeSkill' + i + '" style="cursor:pointer;" buffName="' + buffName + '" buffHref="' + buffHref + '">' + imageHTML +
  1998. 					'</span>' + lastPart;
  1999. 				buffCell.innerHTML = newCellContents;
  2000. 				buffCell.firstChild.addEventListener('click', Helper.removeSkill, true);
  2001. 			}
  2002. 		}
  2003.  
  2004. 		//extra world screen text
  2005. 		var replacementText = "<td background='" + System.imageServer + "/skin/realm_right_bg.jpg'>";
  2006. 		replacementText += "<table width='280' cellpadding='1' style='margin-left:28px; margin-right:28px; " +
  2007. 			"font-size:medium; border-spacing: 1px; border-collapse: collapse;'>";
  2008. 		replacementText += "<tr><td colspan='2' height='10'></td></tr><tr>";
  2009. 		var hasShieldImp = System.findNode("//img[contains(@onmouseover,'Summon Shield Imp')]");
  2010. 		var hasDeathDealer = System.findNode("//img[contains(@onmouseover,'Death Dealer')]");
  2011. 		if (hasDeathDealer || hasShieldImp) {
  2012. 			var re=/(\d) HP remaining/;
  2013. 			var impsRemaining = 0;
  2014. 			if (hasShieldImp) {
  2015. 				//textToTest = "tt_setWidth(105); Tip('<center><b>Summon Shield Imp<br>2 HP remaining<br></b> (Level: 150)</b><br>[Click to De-Activate]</center>');";
  2016. 				textToTest = hasShieldImp.getAttribute("onmouseover");
  2017. 				impsRemainingRE = re.exec(textToTest);
  2018. 				impsRemaining = impsRemainingRE[1];
  2019. 			}
  2020. 			var applyImpWarningColor = " style='color:green; font-size:medium;'";
  2021. 			if (impsRemaining==2){
  2022. 				applyImpWarningColor = " style='color:Orangered; font-size:medium; font-weight:bold;'";
  2023. 			}
  2024. 			if (impsRemaining==1){
  2025. 				applyImpWarningColor = " style='color:Orangered; font-size:large; font-weight:bold'";
  2026. 			}
  2027. 			if (impsRemaining===0){
  2028. 				applyImpWarningColor = " style='color:red; font-size:large; font-weight:bold'";
  2029. 			}
  2030. 			replacementText += "<tr><td" + applyImpWarningColor + ">Shield Imps Remaining: " +  impsRemaining +
  2031. 				(impsRemaining === 0?"&nbsp;<span id='Helper:recastImpAndRefresh' style='color:blue;cursor:pointer;text-decoration:underline;font-size:xx-small;'>Recast</span>":"") + "</td></tr>";
  2032. 			if (hasDeathDealer) {
  2033. 				if (GM_getValue("lastDeathDealerPercentage")==undefined) GM_setValue("lastDeathDealerPercentage", 0);
  2034. 				if (GM_getValue("lastKillStreak")==undefined) GM_setValue("lastKillStreak", 0);
  2035. 				var lastDeathDealerPercentage = GM_getValue("lastDeathDealerPercentage");
  2036. 				var lastKillStreak = GM_getValue("lastKillStreak");
  2037. 				if (impsRemaining>0 && lastDeathDealerPercentage == 20) {
  2038. 					replacementText += "<tr><td style='font-size:small; color:black'>Kill Streak: <span findme='killstreak'>&gt;" + System.addCommas(lastKillStreak) +
  2039. 						"</span> Damage bonus: <span findme='damagebonus'>20</span>%</td></tr>";
  2040. 				} else {
  2041. 					if (!GM_getValue('trackKillStreak')) {
  2042. 						replacementText += "<tr><td style='font-size:small; color:navy' nowrap>KillStreak tracker disabled. "+
  2043. 							"<span style='font-size:xx-small'>Track: <span id=Helper:toggleKStracker style='color:navy;cursor:pointer;text-decoration:underline;' title='Click to toggle'>"+
  2044. 							(GM_getValue('trackKillStreak')?"ON":"off")+
  2045. 							"</span></span></td></tr>";
  2046. 					} else {
  2047. 						replacementText += "<tr><td style='font-size:small; color:navy' nowrap>KillStreak: <span findme='killstreak'>" + System.addCommas(lastKillStreak) +
  2048. 							"</span> Damage bonus: <span findme='damagebonus'>" + Math.round(lastDeathDealerPercentage*100)/100 + "</span>%&nbsp;"+
  2049. 							"<span style='font-size:xx-small'>Track: <span id=Helper:toggleKStracker style='color:navy;cursor:pointer;text-decoration:underline;' title='Click to toggle'>"+
  2050. 							(GM_getValue('trackKillStreak')?"ON":"off")+
  2051. 							"</span></span></td></tr>";
  2052. 						System.xmlhttp("index.php?cmd=profile", Helper.getKillStreak);
  2053. 					}
  2054. 				}
  2055. 			}
  2056. 		}
  2057. 		var hasCounterAttack = System.findNode("//img[contains(@onmouseover,'Counter Attack')]");
  2058. 		if (hasCounterAttack) {
  2059. 			if (hasCounterAttack.getAttribute("src").search("/skills/") != -1) {
  2060. 				var onmouseover = hasCounterAttack.getAttribute("onmouseover");
  2061. 				var counterAttackRE = /<b>Counter Attack<\/b> \(Level: (\d+)\)/;
  2062. 				var counterAttack = counterAttackRE.exec(onmouseover);
  2063. 				if (counterAttack) {
  2064. 					counterAttackLevel = counterAttack[1];
  2065. 				}
  2066. 			}
  2067. 			replacementText += "<tr><td style='font-size:small; color:blue'>CA" + counterAttackLevel + " active</td></tr>";
  2068. 		}
  2069. 		replacementText += "<tr><td colspan='2' height='10'></td></tr>";
  2070. 		if (GM_getValue("showHuntingBuffs")) {
  2071. 			var buffs=GM_getValue("huntingBuffs");
  2072. 			var buffAry=buffs.split(",");
  2073. 			var missingBuffs = new Array();
  2074. 			for (i=0;i<buffAry.length;i++) {
  2075. 				if (!buffHash[buffAry[i].trim()]) {
  2076. 					missingBuffs.push(buffAry[i]);
  2077. 				}
  2078. 			}
  2079. 			if (missingBuffs.length>0) {
  2080. 				replacementText += "<tr><td colspan='2' align='center'><span style='font-size:x-small; color:navy;'>" +
  2081. 					"You are missing some hunting buffs<br/>(";
  2082. 				replacementText += missingBuffs.join(", ");
  2083. 				replacementText += ")</span></td></tr>";
  2084. 			}
  2085. 			replacementText += "<tr><td colspan='2' height='10'></td></tr>";
  2086. 			replacementText += "</table>";
  2087. 		}
  2088. 		replacementText += "</td>" ;
  2089.  
  2090. 		var injectHere = System.findNode("//div[table[@class='centered' and @style='width: 270px;']]");
  2091. 		if (!injectHere) {return;}
  2092. 		//insert after kill all monsters image and text
  2093. 		var newSpan = document.createElement("SPAN");
  2094. 		newSpan.innerHTML=replacementText;
  2095. 		injectHere.appendChild(newSpan);
  2096.  
  2097. 		if ((hasDeathDealer || hasShieldImp) && impsRemaining ===0) {
  2098. 			var recastImpAndRefresh=document.getElementById('Helper:recastImpAndRefresh');
  2099. 			var impHref = "index.php?cmd=quickbuff&subcmd=activate&targetPlayers=" + Helper.characterName + "&skills%5B%5D=55";
  2100. 			recastImpAndRefresh.addEventListener('click', function() {
  2101. 				System.xmlhttp(impHref, Helper.recastImpAndRefresh, true);
  2102. 			},true);
  2103. 		}
  2104.  
  2105. 		var trackKS=document.getElementById('Helper:toggleKStracker');
  2106. 		if (trackKS) trackKS.addEventListener('click', function() {
  2107. 				GM_setValue('trackKillStreak', GM_getValue('trackKillStreak')?false:true);
  2108. 				window.location=window.location;
  2109. 			},true);
  2110. 	},
  2111.  
  2112. 	recastImpAndRefresh: function(responseText) {
  2113. 		var doc=System.createDocument(responseText);
  2114. 		if (doc) {
  2115. 			window.location=window.location;
  2116. 		}
  2117. 	},
  2118.  
  2119. 	removeSkill: function(evt) {
  2120. 		var buffName = evt.target.parentNode.getAttribute("buffName");
  2121. 		var buffHref = evt.target.parentNode.getAttribute("buffHref");
  2122. 		if (confirm('Are you sure you wish to remove the ' + buffName + ' skill?')) {
  2123. 			System.xmlhttp(buffHref, function() {window.location="index.php?cmd=world";});
  2124. 		}
  2125. 	},
  2126.  
  2127. 	injectQuestBookFull: function() {
  2128.  
  2129. 		var lastQBPage = location.search;
  2130. 		//TODO: Make this configurable on/off
  2131. 		if (lastQBPage.indexOf("&mode=0") != -1) {
  2132. 			GM_setValue("lastActiveQuestPage", lastQBPage);
  2133. 		} else if (lastQBPage.indexOf("&mode=1") != -1) {
  2134. 			GM_setValue("lastCompletedQuestPage", lastQBPage);
  2135. 		} else if (lastQBPage.indexOf("&mode=2") != -1) {
  2136. 			GM_setValue("lastNotStartedQuestPage", lastQBPage);
  2137. 		}
  2138. 		if (GM_getValue("storeLastQuestPage")) {
  2139. 			if (GM_getValue("lastActiveQuestPage").length > 0) {
  2140. 				var activeLink = System.findNode('//a[contains(@HREF,"index.php?cmd=questbook&mode=0")]');
  2141. 				activeLink.setAttribute("href", GM_getValue("lastActiveQuestPage"));
  2142. 			}
  2143. 			if (GM_getValue("lastCompletedQuestPage").length > 0) {
  2144. 				var completedLink = System.findNode('//a[contains(@HREF,"index.php?cmd=questbook&mode=1")]');
  2145. 				completedLink.setAttribute("href", GM_getValue("lastCompletedQuestPage"));
  2146. 			}
  2147. 			if (GM_getValue("lastNotStartedQuestPage").length > 0) {
  2148. 				var notStartedLink = System.findNode('//a[contains(@HREF,"index.php?cmd=questbook&mode=2")]');
  2149. 				notStartedLink.setAttribute("href", GM_getValue("lastNotStartedQuestPage"));
  2150. 			}
  2151. 		}
  2152.  
  2153. 		var questTable = System.findNode("//table[tbody/tr/td[.='Guide']]");
  2154. 		if (!questTable) {return;}
  2155. 		var hideQuests=[];
  2156. 		if (GM_getValue("hideQuests")) hideQuests=GM_getValue("hideQuestNames").split(",");
  2157. 		for (var i=0;i<questTable.rows.length;i++) {
  2158. 			var aRow = questTable.rows[i];
  2159. 			if (i!==0) {
  2160. 				if (aRow.cells[0].innerHTML) {
  2161. 					var questName = aRow.cells[0].firstChild.innerHTML.replace(/  /g," ").trim();
  2162. 					if (hideQuests.indexOf(questName)>=0) {
  2163. 						aRow.parentNode.removeChild(aRow.nextSibling);
  2164. 						aRow.parentNode.removeChild(aRow.nextSibling);
  2165. 						aRow.parentNode.removeChild(aRow);
  2166. 					}
  2167. 					//<a href="http://guide.fallensword.com/index.php?cmd=quests&amp;subcmd=view&amp;quest_id=17&amp;search_name=&amp;search_level_min=&amp;search_level_max=&amp;sort_by=" target="_blank"><img src="http://72.29.91.222//skin/fs_wiki.gif" title="Search for this quest on the Ultimate Fallen Sword Guide" border="0"></a>
  2168. 					var questID = /quest_id=(\d+)/.exec(aRow.cells[4].innerHTML)[1];
  2169. 					aRow.cells[4].innerHTML = '<a href="http://wiki.fallensword.com/index.php/' + questName.replace(/ /g,'_') + '" target="_blank">' +
  2170. 						'<img src="http://72.29.91.222//skin/fs_wiki.gif" title="Search for this quest on the Wiki" border="0"></a>';
  2171. 					aRow.cells[4].innerHTML += '&nbsp;<a href="http://www.fallenswordguide.com/quests/index.php?realm=0&search=' + questName.replace(/ /g,'+') +
  2172. 						'" target="_blank"><img border=0 title="Search for this quest on the Fallensword Guide" src="http://www.fallenswordguide.com/favicon.ico"/></a>';
  2173. 					aRow.cells[4].innerHTML += '&nbsp;<a href="http://guide.fallensword.com/index.php?cmd=quests&amp;subcmd=view&amp;quest_id=' + questID + '&amp;search_name=&amp;search_level_min=&amp;search_level_max=&amp;sort_by=" target="_blank">' +
  2174. 						'<img border=0 title="Search quest in Ultimate FSG" src="'+ System.imageServerHTTP + '/temple/1.gif"/></a>';
  2175. 				}
  2176. 			}
  2177. 		}
  2178. 	},
  2179.  
  2180. 	toggleSound: function() {
  2181. 		if (GM_getValue("playNewMessageSound"))
  2182. 		{
  2183. 			GM_setValue("playNewMessageSound", false);
  2184. 		} else {
  2185. 			GM_setValue("playNewMessageSound", true);
  2186. 		}
  2187. 		window.location.reload();
  2188. 	},
  2189.  
  2190. 	isQuestBeingTracked: function (questHREF) {
  2191. 		//quests are stored as their address after index.php: ?cmd=questbook....
  2192. 		var questsBeingTracked = GM_getValue("questBeingTracked").split(";");
  2193. 		for (var i = 0; i < questsBeingTracked.length; i++) {
  2194. 			if (questsBeingTracked[i] == questHREF) {
  2195. 				return true;
  2196. 			}
  2197. 		}
  2198. 		return false;
  2199. 	},
  2200.  
  2201. 	checkForNotCompletedQuests: function(responseText, callback) {
  2202. 		//gets the maximum page number and goes through the pages.
  2203. 		var doc=System.createDocument(responseText);
  2204. 		var page = System.findNode("//td[contains(.,'Page:')]", doc);
  2205. 		var maxPage = page.innerHTML.match(/of&nbsp;(\d*)/);
  2206.  
  2207.  
  2208. 		if (maxPage && maxPage.length >= 2) {
  2209. 			GM_setValue("questsNotComplete", false);
  2210. 			for (var i = 0; i < maxPage[1].replace(/of&nbsp;/g, ""); i++) {
  2211. 				System.xmlhttp("index.php?cmd=questbook&subcmd=&subcmd2=&page=" + i + "&search_text=&mode=0&letter=*&sortby=min_level&sortbydir=0",
  2212. 				Helper.checkForNotCompletedQuestRecurse,
  2213. 				{"insertHere" : callback.insertHere});
  2214. 			}
  2215. 		}
  2216. 	},
  2217.  
  2218. 	checkForNotCompletedQuestRecurse: function(responseText, callback) {
  2219. 		var doc=System.createDocument(responseText);
  2220. 		var insertHere = callback.insertHere;
  2221.  
  2222. 		var table = System.findNode("//table[@width='100%' and @cellspacing=0 and @cellpadding=0 and @border=0]", doc);
  2223. 		if (table) {
  2224. 			table = table.lastChild.getElementsByTagName("TABLE")[2];
  2225.  
  2226. 			for (var i = 2; i < table.rows.length; i+=2) {
  2227. 				if (table.rows[i].cells.length > 1) {
  2228. 					var questHREF = table.rows[i].cells[0].getElementsByTagName("a")[0].getAttribute("href").match(/(\?.*)/)[1];
  2229. 					if (table.rows[i].cells[2].innerHTML == GM_getValue("lastWorld") && !Helper.isQuestBeingTracked(questHREF)) {
  2230. 						if (GM_getValue("questsNotComplete") === false) {
  2231. 							insertHere.innerHTML += "<br><span style='color:red;font-size:12px;'>Quest(s) in zone not completed:</span><br>";
  2232. 							GM_setValue("questsNotComplete", true);
  2233. 						}
  2234. 						insertHere.innerHTML += "<span style='font-size:12px;'>" +table.rows[i].cells[0].innerHTML + "</span><br>";
  2235. 					}
  2236. 				}
  2237. 			}
  2238. 		}
  2239. 	},
  2240.  
  2241. 	checkForNotStartedQuests: function(responseText, callback) {
  2242.  
  2243. 		var doc=System.createDocument(responseText);
  2244. 		var page = System.findNode("//td[contains(.,'Page:')]", doc);
  2245. 		var maxPage = page.innerHTML.match(/of&nbsp;(\d*)/g);
  2246.  
  2247. 		if (maxPage && maxPage.length >= 2) {
  2248. 			GM_setValue("questsNotStarted", false);
  2249. 			for (var i = 0; i < maxPage[1].replace(/of&nbsp;/g, ""); i++) {
  2250. 				System.xmlhttp("index.php?cmd=questbook&subcmd=&subcmd2=&page=" + i + "&search_text=&mode=2&letter=*&sortby=min_level&sortbydir=0",
  2251. 				Helper.checkForQuestRecurse,
  2252. 				{"insertHere" : callback.insertHere});
  2253. 			}
  2254. 		}
  2255. 	},
  2256.  
  2257. 	checkForQuestRecurse: function(responseText, callback) {
  2258. 		var doc=System.createDocument(responseText);
  2259. 		var insertHere = callback.insertHere;
  2260.  
  2261. 		var table = System.findNode("//table[@width='100%' and @cellspacing=0 and @cellpadding=0 and @border=0]", doc);
  2262. 		if (table) {
  2263. 			table = table.lastChild.getElementsByTagName("TABLE")[2];
  2264.  
  2265. 			for (var i = 2; i < table.rows.length; i+=2) {
  2266. 				if (table.rows[i].cells.length > 1) {
  2267. 					if (table.rows[i].cells[2].innerHTML == GM_getValue("lastWorld")) {
  2268. 						if (GM_getValue("questsNotStarted") === false) {
  2269. 							insertHere.innerHTML += "<br><span style='color:red;font-size:12px;'>Quest(s) in zone not started:</span><br>";
  2270. 							GM_setValue("questsNotStarted", true);
  2271. 						}
  2272. 						insertHere.innerHTML += "<span style='font-size:12px;'>" + Helper.removeHTML(table.rows[i].cells[0].innerHTML) + "</span><br>";
  2273. 					}
  2274. 				}
  2275. 			}
  2276. 		}
  2277. 	},
  2278.  
  2279. 	injectWorld: function() {
  2280. 		try {
  2281. 			var curTile = System.findNode("//img[contains(@title, 'You are here')]/ancestor::td[@width='40' and @height='40']").getAttribute("background");
  2282. 			if (GM_getValue("currentTile") != curTile) {
  2283. 				GM_setValue("currentTile", curTile);
  2284. 			}
  2285. 		} catch (err) {
  2286. 			//just eat it and move on
  2287. 		}
  2288. 		Helper.mapThis();
  2289. 		Helper.showMap(false);
  2290.  
  2291. 		/*var injectHere = System.findNode("//tr[contains(td/img/@src, 'realm_right_bottom.jpg')]/../..");
  2292. 		if (!injectHere) {return;}
  2293. 		var newRow=injectHere.insertRow(1);
  2294. 		var newCell=newRow.insertCell(0);
  2295. 		newCell.setAttribute("background", System.imageServer + "/skin/realm_right_bg.jpg");*/
  2296.  
  2297. 		var buttonRow = System.findNode("//tr[td/a/img[@title='Open Realm Map']]");
  2298.  
  2299. 		if (GM_getValue("sendGoldonWorld")){
  2300. 			currentGoldSentTotal = System.addCommas(GM_getValue("currentGoldSentTotal"));
  2301. 			var recipient_text = "Send " + GM_getValue("goldAmount") + " gold to " + GM_getValue("goldRecipient") +
  2302. 				". Current gold sent total is " + currentGoldSentTotal;
  2303. 			buttonRow.innerHTML += '<td valign="top" width="5"></td>' +
  2304. 				'<td valign="top"><img style="cursor:pointer" id="Helper:SendGold" src="' + System.imageServer +
  2305. 				'/skin/gold_button.gif" title= "' + recipient_text + '" border="1" />';
  2306. 		}
  2307.  
  2308. 		if (!GM_getValue("hideKrulPortal")) {
  2309. 			buttonRow.innerHTML += '<td valign="top" width="5"></td>' +
  2310. 				'<td valign="top"><img style="cursor:pointer" id="Helper:PortalToStart" src="' + System.imageServerHTTP +
  2311. 				'/temple/3.gif" title="Instant port to Krul Island" border="1" /></span></td>';
  2312. 		}
  2313.  
  2314. 		var footprints = GM_getValue("footprints");
  2315.  
  2316. 		buttonRow.innerHTML += '<td valign="top" width="5"></td>' +
  2317. 			'<td valign="top"><img style="cursor:pointer" id="Helper:ToggleFootprints" src="' + System.imageServer +
  2318. 			'/skin/' + (footprints?'quest_complete':'quest_incomplete') + '.gif" title="Toggle Footprints" border="0"></td>';
  2319. 		if (GM_getValue("sendGoldonWorld")){
  2320. 			//document.getElementById('Helper:PortalToStart').addEventListener('click', Helper.portalToStartArea, true);
  2321. 			document.getElementById('Helper:SendGold').addEventListener('click', Helper.sendGoldToPlayer, true);
  2322. 		}
  2323. 		if (!GM_getValue("hideKrulPortal")) {
  2324. 			document.getElementById('Helper:PortalToStart').addEventListener('click', Helper.portalToStartArea, true);
  2325. 		}
  2326.  
  2327. 		// One may ask why the separation of creating the button and the event handling code.
  2328. 		// Well, obviously (so obvious it took me 3 hours to figure out), when you change the HTML of
  2329. 		// a region, all attached events are destroyed (because the original elements are also destroyed)
  2330.  
  2331. 		document.getElementById('Helper:ToggleFootprints').addEventListener('click', Helper.toggleFootprints, true);
  2332.  
  2333. 		Helper.checkBuffs();
  2334. 		Helper.prepareCheckMonster();
  2335. 		Helper.prepareCombatLog();
  2336. 		var mapName = System.findNode('//td[contains(@background,"/skin/realm_top_b2.jpg")]/center/nobr');
  2337. 		//Checking if there are quests on current map
  2338. 		if (GM_getValue("checkForQuestsInWorld") === true) {
  2339. 			if (mapName.textContent !== null &&
  2340. 				(GM_getValue("lastWorld") != mapName.textContent.trim() ||
  2341. 					GM_getValue("questsNotStarted") === true ||
  2342. 					GM_getValue("questsNotComplete") === true)) {
  2343. 				GM_setValue("lastWorld", mapName.textContent.trim());
  2344. 				var insertToHere = System.findNode("//html/body/table/tbody/tr[3]/td[2]/table/tbody/tr[5]/td[2]/table/tbody/tr[3]/td/table/tbody/tr[4]/td");
  2345. 				System.xmlhttp("index.php?cmd=questbook&mode=2&letter=*", Helper.checkForNotStartedQuests, {"insertHere" : insertToHere});
  2346. 				System.xmlhttp("index.php?cmd=questbook&mode=0&letter=*", Helper.checkForNotCompletedQuests,{"insertHere" : insertToHere});
  2347. 			}
  2348. 		}
  2349. 		//quest tracker
  2350. 		var questBeingTracked = GM_getValue("questBeingTracked").split(";");
  2351. 		if (questBeingTracked.length > 0 & questBeingTracked[0].trim().length > 0) {
  2352. 			var injectHere = System.findNode("//div[table[@class='centered' and @style='width: 270px;']]");
  2353. 			if (!injectHere) {return;}
  2354. 			var replacementText = "<td background='" + System.imageServer + "/skin/realm_right_bg.jpg'>";
  2355. 			replacementText += "<table width='280' cellpadding='1' style='margin-left:28px; margin-right:28px; " +
  2356. 				"font-size:medium; border-spacing: 1px; border-collapse: collapse;'>";
  2357. 			replacementText += "<tr><td colspan='2' height='10'></td>";
  2358. 			for (var i = 0; i < questBeingTracked.length; i++) {
  2359.  
  2360. 				replacementText += "<tr><td style='font-size:small; color:black'><a id='qiLink" + i + "' href=" + questBeingTracked[i] + "></a>&nbsp;";
  2361. 				replacementText += "<input id='dontTrackThisQuest" + i + "' data='" + questBeingTracked[i] + "' type='button' value='Stop Tracking' title='Stops tracking quest progress.' class='custombutton'><br>";
  2362. 				replacementText += "<span findme='questinfo" + i + "'></span></td></tr>";
  2363. 				if (i != questBeingTracked.length - 1) {
  2364. 					replacementText += '<tr><td height="10" colspan="2"/></tr>' +
  2365. 					'<tr><td height="10" colspan="2"/></tr>';
  2366. 				}
  2367. 			}
  2368.  
  2369. 			replacementText += "</table>";
  2370. 			replacementText += "</td>";
  2371.  
  2372. 			var newSpan = document.createElement("SPAN");
  2373. 			newSpan.innerHTML=replacementText;
  2374. 			injectHere.appendChild(newSpan);
  2375.  
  2376. 			for (i = 0; i < questBeingTracked.length; i++) {
  2377. 				System.xmlhttp(questBeingTracked[i], Helper.getQuestInfo, {"data" : i});
  2378. 			}
  2379. 		}
  2380.  
  2381.  
  2382. 		if (mapName) {
  2383.  
  2384. 			mapName.innerHTML += ' <a href="http://guide.fallensword.com/index.php?cmd=realms&search_name=' + mapName.textContent + '&search_level_min=&search_level_max=" target="_blank">' +
  2385. 				'<img border=0 title="Search map in Ultimate FSG" width=10 height=10 src="'+ System.imageServerHTTP + '/temple/1.gif"/></a>';
  2386. 			if (GM_getValue("showFSGIcon")) {
  2387. 				mapName.innerHTML += ' <a href="http://www.fallenswordguide.com/realms/?search=' + mapName.textContent + '" target="_blank">' +
  2388. 					'<img border=0 title="Search map in FSG" width=10 height=10 src="http://www.fallenswordguide.com/favicon.ico"/></a>';
  2389. 			}
  2390. 			mapName.innerHTML += ' <a href="http://wiki.fallensword.com/index.php/Special:Search?search=' + mapName.textContent + '&go=Go" target="_blank">' +
  2391. 				'<img border=0 title="Search map in Wiki" width=10 height=10 src="/favicon.ico"/></a>';
  2392.  
  2393. 			var uaStr = navigator.userAgent;
  2394. 			var FFindex = uaStr.indexOf("Firefox");
  2395. 			var huntingMode = GM_getValue("huntingMode");
  2396. 			var imgSource = huntingMode === true ? Data.huntingOnImage() : Data.huntingOffImage();
  2397. 			var altText = huntingMode === true ? "Hunting mode is ON" : "Hunting mode is OFF";
  2398. 			mapName.innerHTML += " <a href=# id='Helper:ToggleHuntingMode'><img title='" + altText + "' src='" + imgSource + "' border=0 width=10 height=10/></a>";
  2399.  
  2400. 			if (FFindex && uaStr.substring(FFindex+8,uaStr.indexOf(" ", FFindex)) >= "3.5" && GM_getValue("showSpeakerOnWorld")) {
  2401. 				if (GM_getValue("playNewMessageSound"))
  2402. 				{
  2403. 					mapName.innerHTML += '<a href="#" id="toggleSoundLink"><img border=0 title="Turn Off Sound when you have a new log message" width=10 height=10 src="' + Data.soundMuteImage() + '"/></a>';
  2404. 				} else {
  2405. 					mapName.innerHTML += '<a href="#" id="toggleSoundLink"><img border=0 title="Turn On Sound when you have a new log message" width=10 height=10 src="' + Data.soundImage() + '"/></a>';
  2406. 				}
  2407. 				document.getElementById("toggleSoundLink").addEventListener("click", Helper.toggleSound, true);
  2408.  
  2409. 			}
  2410. 			document.getElementById('Helper:ToggleHuntingMode').addEventListener('click',
  2411. 				function() {
  2412. 					GM_setValue("huntingMode",!GM_getValue("huntingMode")); window.location.reload();
  2413. 				},true);
  2414.  
  2415. 		}
  2416. 		if (GM_getValue("quickKill")) {
  2417. 			var doNotKillList = GM_getValue("doNotKillList");
  2418. 			var doNotKillListAry = doNotKillList.split(",");
  2419. 			if (doNotKillListAry.length > 0) {
  2420. 				for (i=1; i<9; i++) {
  2421. 					var monster = System.findNode("//a[@id='aLink" + i + "']");
  2422. 					if (monster) {
  2423. 						var monsterName = monster.parentNode.parentNode.previousSibling.textContent.trim();
  2424. 						for (var j=0; j<doNotKillListAry.length; j++) {
  2425. 							var doNotKillName = doNotKillListAry[j].trim();
  2426. 							if (monsterName == doNotKillName){
  2427. 								var monsterNameCell = monster.parentNode.parentNode.previousSibling;
  2428. 								monsterNameCell.innerHTML = '<span style="color:blue;">' + monsterNameCell.innerHTML + '</span>';
  2429. 								break;
  2430. 							}
  2431. 						}
  2432. 					}
  2433. 					else
  2434. 						break;
  2435. 				}
  2436. 			}
  2437. 		}
  2438.  
  2439.  
  2440. 	},
  2441.  
  2442. 	fixOnlineGuildBuffLinks: function() {
  2443. 		var guildInfoOnlineMembersTable = System.findNodes("//tr[td/a[contains(@href,'index.php?cmd=quickbuff&t=')]/font[.='B']]");
  2444. 		if (guildInfoOnlineMembersTable) {
  2445. 			for (var i=0; i<guildInfoOnlineMembersTable.length; i++){
  2446. 				var guildInfoOnlineMember = guildInfoOnlineMembersTable[i];
  2447. 				var playerLink = System.findNode("./td/table/tbody/tr/td/a[contains(@href,'index.php?cmd=profile&player_id=')]", guildInfoOnlineMember);
  2448. 				var playerID = /player_id=(\d+)/.exec(playerLink)[1];
  2449. 				var buffLink = System.findNode("./td/a[contains(@href,'index.php?cmd=quickbuff&t=')]", guildInfoOnlineMember);
  2450. 				var oldHref = buffLink.getAttribute('href');
  2451. 				var playerName = /cmd=quickbuff\&t=([,a-zA-Z0-9]+)'/.exec(oldHref);
  2452. 				buffLink.setAttribute('href', "javascript:openWindow('index.php?cmd=quickbuff&tid=" + playerID + "', 'fsQuickBuff', 618, 1000, ',scrollbars')");
  2453. 			}
  2454. 		}
  2455. 	},
  2456.  
  2457. 	addGuildInfoWidgets: function() {
  2458. 		if (!GM_getValue("enableGuildInfoWidgets")) {return;}
  2459. 		var onlineMembersTable = System.findNode("//table/tbody/tr/td[font/i/b[.='Online Members']]//table");
  2460. 		if (onlineMembersTable) {
  2461. 			for (var i=0; i<onlineMembersTable.rows.length; i++){
  2462. 				var onlineMemberFirstCell = onlineMembersTable.rows[i].cells[0];
  2463. 				var onlineMemberSecondCell = onlineMembersTable.rows[i].cells[1];
  2464. 				if (onlineMemberSecondCell) {
  2465. 					var playerTable = onlineMemberFirstCell.getElementsByTagName('TABLE')[0];
  2466. 					var checkboxColumn = playerTable.rows[0].cells[0];
  2467. 					var playernameColumn = playerTable.rows[0].cells[1];
  2468. 					var playerNameLinkElement = playernameColumn.firstChild;
  2469. 					var onMouseOver = playerNameLinkElement.getAttribute("onmouseover");
  2470. 					var lastActivityMinutes = /Last Activity:<\/td><td>(\d+) mins/.exec(onMouseOver)[1];
  2471. 			//Hide the Guild info Links
  2472. 					if (GM_getValue("hideGuildInfoTrade")) {
  2473. 						var messageLink = onlineMemberSecondCell.firstChild.nextSibling;
  2474. 						var buffLink = messageLink.nextSibling.nextSibling;
  2475. 						var secureTradeLink = buffLink.nextSibling.nextSibling;
  2476. 						var tradeLink = secureTradeLink.nextSibling.nextSibling;
  2477. 						tradeLink.style.display = 'none';
  2478. 						tradeLink.style.visibility = 'hidden';
  2479. 					}
  2480. 					if (GM_getValue("hideGuildInfoSecureTrade")) {
  2481. 						messageLink = onlineMemberSecondCell.firstChild.nextSibling;
  2482. 						buffLink = messageLink.nextSibling.nextSibling;
  2483. 						secureTradeLink = buffLink.nextSibling.nextSibling;
  2484. 						secureTradeLink.style.display = 'none';
  2485. 						secureTradeLink.style.visibility = 'hidden';
  2486. 					}
  2487. 					if (GM_getValue("hideGuildInfoBuff")) {
  2488. 						messageLink = onlineMemberSecondCell.firstChild.nextSibling;
  2489. 						buffLink = messageLink.nextSibling.nextSibling;
  2490. 						buffLink.style.display = 'none';
  2491. 						buffLink.style.visibility = 'hidden';
  2492. 					}
  2493.  
  2494. 					if (GM_getValue("hideGuildInfoMessage")) {
  2495. 						messageLink = onlineMemberSecondCell.firstChild.nextSibling;
  2496. 						if (messageLink.style) {
  2497. 							messageLink.style.display = 'none';
  2498. 							messageLink.style.visibility = 'hidden';
  2499. 						}
  2500. 					}
  2501.  
  2502. 				// Set Color for Activity
  2503. 					if (lastActivityMinutes < 2) {
  2504. 						playerNameLinkElement.style.color = 'green';
  2505. 						playerNameLinkElement.firstChild.style.color = 'green';
  2506. 					} else if (lastActivityMinutes < 5) {
  2507. 						playerNameLinkElement.style.color = 'white';
  2508. 						playerNameLinkElement.firstChild.style.color = 'white';
  2509. 					} else {
  2510. 						playerNameLinkElement.style.color = 'gray';
  2511. 						playerNameLinkElement.firstChild.style.color = 'gray';
  2512. 					}
  2513. 					if (playernameColumn.textContent.trim() == Helper.characterName.trim()) {
  2514. 						messageLink = onlineMemberSecondCell.firstChild.nextSibling;
  2515. 						if (messageLink.style) messageLink.style.visibility = 'hidden';
  2516. 						buffLink = messageLink.nextSibling.nextSibling;
  2517. 						secureTradeLink = buffLink.nextSibling.nextSibling;
  2518. 						secureTradeLink.style.visibility = 'hidden';
  2519. 						tradeLink = secureTradeLink.nextSibling.nextSibling;
  2520. 						tradeLink.style.visibility = 'hidden';
  2521. 					}
  2522. 					onlineMemberSecondCell.innerHTML = '<nobr>' + onlineMemberSecondCell.innerHTML + '</nobr>';
  2523. 				}
  2524. 			}
  2525. 		}
  2526. 	},
  2527.  
  2528. 	injectWorldMap: function() {
  2529. 		Helper.showMap(true);
  2530. 	},
  2531.  
  2532. 	retrieveTradeConfirm: function() {
  2533. 		var xcNumber;
  2534. 		xcNumber=System.findNode("//input[@type='hidden' and @name='xc']");
  2535. 		xcNumber=xcNumber?xcNumber.getAttribute("value"):"-";
  2536. 		GM_setValue("goldConfirm", xcNumber);
  2537. 	},
  2538.  
  2539. 	sendGoldToPlayer: function(){
  2540. 		var injectHere = System.findNode("//div[table[@class='centered' and @style='width: 270px;']]");
  2541. 		if (!injectHere) {return;}
  2542. 		var recipient = GM_getValue("goldRecipient");
  2543. 		var amount = GM_getValue("goldAmount");
  2544. 		System.xmlhttp('index.php?cmd=trade');
  2545. 		var xcNum = GM_getValue("goldConfirm");
  2546. 		if (xcNum === "") {
  2547. 			window.alert("You have to visit the trade page once to use the send gold functionality");
  2548. 			return;
  2549. 		}
  2550. 		var url = 'index.php?cmd=trade&subcmd=sendgold&xc=' + xcNum + '&target_username=' + recipient +'&gold_amount='+ amount;
  2551. 		System.xmlhttp(url, Helper.goldToPlayerSent, {"amount": amount, "recipient": recipient} );
  2552. 	},
  2553.  
  2554. 	goldToPlayerSent: function(responseText, callback) {
  2555. 		var injectHere = System.findNode("//div[table[@class='centered' and @style='width: 270px;']]");
  2556. 		if (!injectHere) {return;}
  2557. 		var newSpan = document.createElement("SPAN");
  2558. 		injectHere.appendChild(newSpan);
  2559. 		newSpan.setAttribute("background", System.imageServer + "/skin/realm_right_bg.jpg");
  2560. 		var info = Layout.infoBox(responseText);
  2561. 		if (info==="" || info==="You successfully sent gold!") {
  2562. 			var currentGoldSentTotal = GM_getValue("currentGoldSentTotal")*1;
  2563. 			currentGoldSentTotal += System.intValue(callback.amount);
  2564. 			info = 'You successfully sent ' + callback.amount + ' gold to ' + callback.recipient + '! Current total sent is '+currentGoldSentTotal+' gold.';
  2565. 			GM_setValue("currentGoldSentTotal", currentGoldSentTotal);
  2566. 		}
  2567. 		newSpan.innerHTML='<div style="margin-left:28px; margin-right:28px; color:navy; font-size:xx-small;">' + info + '</div>';
  2568. 	},
  2569.  
  2570. 	insertQuickWear: function() {
  2571. 		Helper.itemList = {};
  2572. 		var layout=Layout.notebookContent();
  2573. 		layout.innerHTML="Getting item list from: ";
  2574. 		System.xmlhttp("/index.php?cmd=profile&subcmd=dropitems&folder_id=-1", Helper.getItemFromBackpack, {"inject":layout,"id":0});
  2575. 	},
  2576.  
  2577. 	getItemFromBackpack: function(responseText, callback) {
  2578. 		var layout=callback.inject;
  2579. 		layout.innerHTML+="backpack folder "+(callback.id+1)+", ";
  2580. 		var doc=System.createDocument(responseText);
  2581. 		if (responseText.indexOf('Back to Profile') > 0){
  2582. 			Helper.retrieveItemInfor(doc);
  2583. 		}
  2584. 		var folderNodes=System.findNodes("//a[contains(@href,'cmd=profile&subcmd=dropitems&folder_id=')]",doc);
  2585. 		if (folderNodes && folderNodes.length > 0 && callback.id < folderNodes.length - 1)
  2586. 			System.xmlhttp(folderNodes[callback.id+1].getAttribute("href"),
  2587. 				Helper.getItemFromBackpack, {"inject":layout,"id":callback.id+1});
  2588. 		else
  2589. 			System.xmlhttp("/index.php?cmd=guild&subcmd=inventory&subcmd2=storeitems",
  2590. 				Helper.getItemFromStoreItemPage, callback);
  2591. 	},
  2592.  
  2593. 	getItemFromStoreItemPage: function(responseText, callback) {
  2594. 		var layout=callback.inject;
  2595. 		layout.innerHTML+="store item page.";
  2596. 		var doc=System.createDocument(responseText);
  2597. 		if (responseText.indexOf('Store Items') > 0){
  2598. 			Helper.retrieveItemInfor(doc);
  2599. 		}
  2600. 		Helper.showQuickWear(callback);
  2601. 	},
  2602.  
  2603. 	showQuickWear: function(callback) {
  2604. 		var output='<table width=100%><tr style="background-color:#CD9E4B;"><td nobr><b> Quick Wear / Use / Extract Manager</b></td></tr></table>'+
  2605. 			'Please select the appropriate action for each item. When inappropriate action is selected, unexpected output can be displayed<br/>'+
  2606. 			'<table width=100%><tr><th width=20%>Actions</th><th colspan=4>Items</th></tr>';
  2607. 		for (var key in Helper.itemList) {
  2608. 			var itemID=Helper.itemList[key].id;
  2609. 			output+='<tr><td align=center>'+
  2610. 				'<span style="cursor:pointer; text-decoration:underline; color:#blue; font-size:x-small;" '+
  2611. 				'id="Helper:equipProfileInventoryItem' + itemID + '" ' +
  2612. 				'itemID="' + itemID + '">Wear</span>&nbsp;|&nbsp;' +
  2613. 				'<span style="cursor:pointer; text-decoration:underline; color:#blue; font-size:x-small;" '+
  2614. 				'id="Helper:useProfileInventoryItem' + itemID + '" ' +
  2615. 				'itemID="' + itemID + '">Use/Ext</span>'+
  2616. 				'</td>'+Helper.itemList[key].html+'</tr>';
  2617. 		}
  2618. 		output+='</table>';
  2619. 		callback.inject.innerHTML=output;
  2620. 		for (key in Helper.itemList) {
  2621. 			itemID=Helper.itemList[key].id;
  2622. 			document.getElementById('Helper:equipProfileInventoryItem' + itemID).
  2623. 				addEventListener('click', Helper.equipProfileInventoryItem, true);
  2624. 			document.getElementById('Helper:useProfileInventoryItem' + itemID).
  2625. 				addEventListener('click', Helper.useProfileInventoryItem, true);
  2626. 		}
  2627. 	},
  2628.  
  2629. 	insertQuickExtract: function() {
  2630. 		Helper.itemList = {};
  2631. 		var layout=Layout.notebookContent();
  2632. 		layout.innerHTML="Getting item list from: ";
  2633. 		Helper.resourceList={};
  2634. 		System.xmlhttp("/index.php?cmd=profile&subcmd=dropitems&folder_id=-1", Helper.getPlantsFromBackpack, {"inject":layout,"id":0});
  2635. 	},
  2636.  
  2637. 	getPlantsFromBackpack: function(responseText, callback) {
  2638. 		var layout=callback.inject;
  2639. 		layout.innerHTML+="Parsing main pack for plants.";
  2640. 		var doc=System.createDocument(responseText);
  2641. 		if (responseText.indexOf('Back to Profile') > 0){
  2642. 			Helper.retrieveItemInfor(doc);
  2643. 		}
  2644. 		Helper.showQuickExtract(callback);
  2645. 	},
  2646.  
  2647. 	showQuickExtract: function(callback) {
  2648. 		var output='<table width=100%><tr style="background-color:#CD9E4B;"><td nobr><b>Quick Extract</b></td></tr></table>'+
  2649. 			'Select which type of plants you wish to extract all of.  Only select extractable resources.<br/>'+
  2650. 			'<table width=100%><tr><th width=20%>Actions</th><th colspan=6>Items</th></tr><tr><td id=buy_result colspan=12></td></tr>';
  2651. 		for (var key in Helper.itemList) {
  2652. 			var itemID=Helper.itemList[key].id;
  2653. 			var	itemStats = /ajaxLoadItem\((\d+), (\d+), (\d+), (\d+)/.exec(Helper.itemList[key].html); //add this line
  2654. 			var plantType = itemStats[1];
  2655. 			if (Helper.resourceList[plantType]){
  2656. 				Helper.resourceList[plantType].invIDs+=","+itemID;
  2657. 				Helper.resourceList[plantType].count++;
  2658. 			}
  2659. 			else {
  2660. 				Helper.resourceList[plantType]={'count':1,'invIDs':itemID,'src':Helper.itemList[key].html};
  2661. 			}
  2662. 		}
  2663.  
  2664. 		for (var id in Helper.resourceList) {
  2665. 			var res=Helper.resourceList[id];
  2666. 			output+='<tr><td align=center>'+
  2667. 				'<span style="cursor:pointer; text-decoration:underline; color:#blue; font-size:x-small;" '+
  2668. 				'id="Helper:extractAllSimilar' + id + '" invIDs="'+res.invIDs+'">Extract all '+res.count +'</span></td>'+res.src+'</tr>';
  2669. 		}
  2670. 		output+='</table>';
  2671.  
  2672. 		callback.inject.innerHTML=output;
  2673. 		for (id in Helper.resourceList) {
  2674. 			document.getElementById('Helper:extractAllSimilar' + id).
  2675. 				addEventListener('click', Helper.extractAllSimilar, true);
  2676. 			}
  2677. 	},
  2678.  
  2679. 	extractAllSimilar: function(evt) {
  2680. 		if (!window.confirm("Are you sure you want to extract all similar items?")) {return;}
  2681. 		var InventoryIDs=evt.target.getAttribute("invIDs").split(",");
  2682. 		//evt.target.parentNode.innerHTML = InventoryIDs;
  2683. 		var output= '';
  2684. 		evt.target.parentNode.innerHTML = 'extracting all ' + InventoryIDs.length + ' resources';
  2685. 		for (var i=0; i<InventoryIDs.length; i++){
  2686. 			//output+='index.php?cmd=profile&subcmd=useitem&inventory_id='+InventoryIDs[i]+'<br>';
  2687. 			System.xmlhttp('index.php?cmd=profile&subcmd=useitem&inventory_id='+InventoryIDs[i], Helper.quickDoneExtracted);
  2688. 		}
  2689. 		//evt.target.parentNode.innerHTML = output;
  2690. 	},
  2691. 	quickDoneExtracted: function(responseText) {
  2692. 		var infoMessage = Layout.infoBox(responseText);
  2693. 		//unsafeWindow.tt_setWidth(200);
  2694. 		//unsafeWindow.Tip(infoMessage);
  2695. 		document.getElementById('buy_result').innerHTML+="<br />"+infoMessage;
  2696. 	},
  2697.  
  2698. 	retrieveItemInfor: function(doc) {
  2699. 		var table=System.findNode("//td[@colspan=3]/table[@width='100%']",doc);
  2700. 		for (var i=0; i<table.rows.length/2; i++){
  2701. 			var row=table.rows[i*2];
  2702. 			var item={
  2703. 				"id":System.getIntFromRegExp(row.innerHTML,/value="(\d+)"/),
  2704. 				"html":row.innerHTML.replace(/<input[^>]*>/g, '')
  2705. 				};
  2706. 			Helper.itemList["id"+item.id]=item;
  2707. 		}
  2708. 	},
  2709.  
  2710. 	toggleFootprints: function() {
  2711. 		var footprints = GM_getValue("footprints");
  2712. 		if (footprints == undefined) footprints=false;
  2713. 		footprints = !footprints;
  2714. 		GM_setValue("footprints", footprints);
  2715.  
  2716. 		if (!footprints) { // clear footprints
  2717. 			var theMap = System.getValueJSON("map");
  2718. 			var realm = System.findNode("//td[contains(@background,'/skin/realm_top_b2.jpg')]/center/nobr/b");
  2719. 			var levelName=realm.innerHTML;
  2720. 			Helper.levelName = levelName;
  2721. 			theMap["levels"][Helper.levelName]={};
  2722. 			System.setValueJSON("map", theMap);
  2723. 		}
  2724.  
  2725. 		document.getElementById('Helper:ToggleFootprints').src =
  2726. 			System.imageServer +
  2727. 			'/skin/' + (footprints?'quest_complete':'quest_incomplete') + '.gif';
  2728. 	},
  2729.  
  2730. 	prepareCombatLog: function() {
  2731. 		//if (!GM_getValue("showCombatLog")) {return;}
  2732. 		var reportsTable=System.findNode("//div[table[@class='centered' and @style='width: 270px;']]");
  2733. 		if (!reportsTable) {return;}
  2734. 		var tempLog=document.createElement("div");
  2735. 		tempLog.id="reportsLog";
  2736. 		var injLog=reportsTable.appendChild(tempLog);
  2737. 		var is=injLog.style;
  2738. 		is.color = 'black';
  2739. 		is.backgroundImage='url(' + System.imageServerHTTP + '/skin/realm_right_bg.jpg)';
  2740. 		is.maxHeight = '240px';
  2741. 		is.width = '277px';
  2742. 		is.maxWidth = is.width;
  2743. 		is.marginLeft = '0px';
  2744. 		is.marginRight = '0px';
  2745. 		is.paddingLeft = '26px';
  2746. 		is.paddingRight = '24px';
  2747. 		is.overflow = 'hidden';
  2748. 		is.fontSize = 'xx-small';
  2749. 		is.textAlign = 'justify';
  2750. 	},
  2751.  
  2752. 	getMonster: function(index) {
  2753. 		return System.findNode("//a[@id='aLink" + index + "']");
  2754. 	},
  2755.  
  2756. 	killSingleMonster: function(monsterNumber) {
  2757. 		if (!GM_getValue("quickKill")) {return;}
  2758. 		var kills=0;
  2759. 		var monster = Helper.getMonster(monsterNumber);
  2760.  
  2761. 		var doNotKillList = GM_getValue("doNotKillList");
  2762. 		var doNotKillListAry = doNotKillList.split(",");
  2763.  
  2764. 		if (monster) {
  2765. 			var monsterName = monster.parentNode.parentNode.previousSibling.textContent.trim();
  2766. 			var injectHere = monster.parentNode.parentNode;
  2767. 			var monsterFound = false;
  2768. 			for (var j=0; j<doNotKillListAry.length; j++) {
  2769. 				var doNotKillName = doNotKillListAry[j].trim();
  2770. 				if (monsterName == doNotKillName){
  2771. 					injectHere.innerHTML = '<nobr><span style="color:blue; font-size:x-small;">On do not kill list&nbsp;</span></nobr>';
  2772. 					monsterFound = true;
  2773. 					break;
  2774. 				}
  2775. 			}
  2776. 			if (!monsterFound) {
  2777. 				kills+=1;
  2778. 				System.xmlhttp(monster.getAttribute("href"), Helper.killedMonster, {"node": monster, "index": monsterNumber});
  2779. 			}
  2780. 		}
  2781. 	},
  2782.  
  2783. 	prepareCheckMonster: function() {
  2784. 		Helper.colorMonsters();
  2785. 		Helper.getMonsterInfo();
  2786. 	},
  2787.  
  2788. 	colorMonsters: function() {
  2789. 		if (!GM_getValue("enableCreatureColoring")) {return;}
  2790. 		monsters = System.findNodes("//a[contains(@href,'cmd=combat') and not(contains(@href,'max_turns='))]");
  2791. 		if (!monsters) {return;}
  2792. 		for (var i=0; i<monsters.length; i++) {
  2793. 			var monster = monsters[i];
  2794. 			if (monster) {
  2795. 				// add monster color based on elite types
  2796. 				var monsterText = monster.parentNode.parentNode.parentNode.cells[1];
  2797. 				if (monsterText.textContent.match(/\(Champion\)/i))
  2798. 					monsterText.style.color = 'green';
  2799. 				if (monsterText.textContent.match(/\(Elite\)/i))
  2800. 					monsterText.style.color = 'yellow';
  2801. 				if (monsterText.textContent.match(/\(Super Elite\)/i))
  2802. 					monsterText.style.color = 'red';
  2803. 			}
  2804. 		}
  2805. 	},
  2806.  
  2807. 	getMonsterInfo: function() {
  2808. 		if (!GM_getValue("showCreatureInfo")) {return;}
  2809. 		var monsters = System.findNodes("//a[contains(@href,'cmd=world&subcmd=viewcreature&creature_id=')]");
  2810. 		if (!monsters) {return;}
  2811. 		for (var i=0; i<monsters.length; i++) {
  2812. 			var monster = monsters[i];
  2813. 			if (monster) {
  2814. 				var href=monster.getAttribute("href");
  2815. 				if (GM_getValue("showMonsterLog"))
  2816. 					System.xmlhttp(monster.getAttribute("href"), Helper.checkedMonster, {'monster':monster,'showTip':false});
  2817. 				else
  2818. 					monster.addEventListener("mouseover", Helper.showTipCreatureInfo, true);
  2819. 			}
  2820. 		}
  2821. 	},
  2822.  
  2823. 	showTipCreatureInfo: function(evt) {
  2824. 		var monster=evt.target.parentNode;
  2825. 		if (monster.getAttribute("mouseovertext")!=undefined) {
  2826. 			evt.target.removeEventListener("mouseover", Helper.showTipCreatureInfo, true);
  2827. 			return;
  2828. 		}
  2829. 		System.xmlhttp(monster.getAttribute("href"), Helper.checkedMonster, {'monster':monster,'showTip':true});
  2830. 	},
  2831.  
  2832. 	checkedMonster: function(responseText, callback) {
  2833. 		var creatureInfo=System.createDocument(responseText);
  2834. 		var statsNode = System.findNode("//table[@width='400']", creatureInfo);
  2835. 		if (!statsNode) {return;} // FF2 error fix
  2836. 		var showMonsterLog = GM_getValue("showMonsterLog");
  2837. 		//store the stats
  2838. 		var classNode = statsNode.rows[1].cells[1];
  2839. 		var levelNode = statsNode.rows[1].cells[3];
  2840. 		var attackNode = statsNode.rows[2].cells[1];
  2841. 		var defenseNode = statsNode.rows[2].cells[3];
  2842. 		var armorNode = statsNode.rows[3].cells[1];
  2843. 		var damageNode = statsNode.rows[3].cells[3];
  2844. 		var hitpointsNode = statsNode.rows[4].cells[1];
  2845. 		var goldNode = statsNode.rows[4].cells[3];
  2846. 		var hitpoints = parseInt(hitpointsNode.textContent.replace(/,/g,""),10);
  2847. 		var armorNumber = parseInt(armorNode.textContent.replace(/,/g,""),10);
  2848. 		var combatEvaluatorBias = GM_getValue("combatEvaluatorBias");
  2849. 		var attackVariable = 1.1053, generalVariable = 1.1053, hpVariable = 1.1;
  2850. 		if (combatEvaluatorBias == 1) {
  2851. 			generalVariable = 1.1;
  2852. 			hpVariable = 1.053;
  2853. 		} else if (combatEvaluatorBias == 2) {
  2854. 			generalVariable = 1.053;
  2855. 			hpVariable = 1;
  2856. 		}
  2857. 		var oneHitNumber = Math.ceil((hitpoints*hpVariable)+(armorNumber*generalVariable));
  2858.  
  2859. 		var hideRestOfRows = false;
  2860. 		var collectEnchantments = true;
  2861. 		var enchantmentsList = [];
  2862. 		for (var i=0; i<statsNode.rows.length; i++) {
  2863. 			var enchantment = {};
  2864. 			var firstCell = statsNode.rows[i].cells[0];
  2865. 			var thirdCell = statsNode.rows[i].cells[2];
  2866. 			//color titles black
  2867. 			if (firstCell.getAttribute("bgcolor") == "#cd9e4b") firstCell.style.color="black";
  2868. 			//color text white so it can be read
  2869. 			if (firstCell.firstChild && firstCell.firstChild.tagName) firstCell.firstChild.style.color="#cccccc";
  2870. 			if (thirdCell && thirdCell.firstChild && thirdCell.firstChild.tagName) thirdCell.firstChild.style.color="#cccccc";
  2871. 			//
  2872. 			if (firstCell.textContent == 'Actions') {
  2873. 				hideRestOfRows = true;
  2874. 			}
  2875. 			if (hideRestOfRows) {
  2876. 				firstCell.style.display = 'none';
  2877. 				firstCell.style.visibility = 'hidden';
  2878. 			}
  2879.  
  2880. 			//store the enchantment min and max values in the monster log (if enabled)
  2881. 			if (showMonsterLog && i >= 7 && collectEnchantments) { //first enchantment row
  2882. 				var ThisRowFirstCell = statsNode.rows[i].cells[0];
  2883. 				if (ThisRowFirstCell.textContent != '[no enhancements]') {
  2884. 					var SecondNextRowFirstCell = statsNode.rows[i+2].cells[0];
  2885. 					if (SecondNextRowFirstCell.textContent == 'Description') collectEnchantments = false;
  2886. 					enchantment.name = statsNode.rows[i].cells[0].textContent;
  2887. 					enchantment.value = statsNode.rows[i].cells[1].textContent*1;
  2888. 					enchantmentsList.push(enchantment);
  2889. 				} else {
  2890. 					collectEnchantments = false;
  2891. 				}
  2892. 			}
  2893. 		}
  2894.  
  2895. 		var imageTable = System.findNode("//table[tbody/tr/td/img[contains(@src, '/creatures/')]]", creatureInfo);
  2896. 		var imageNode = imageTable.rows[0].cells[0].firstChild;
  2897. 		var nameNode = imageTable.rows[1].cells[0].firstChild;
  2898. 		var imageNodeSRC = imageNode.src.replace(/.jpg(.*)/,".jpg");
  2899.  
  2900. 		if (showMonsterLog) {
  2901. 			Helper.pushMonsterInfo({"key0":nameNode.textContent, "key1":imageNodeSRC, "key2":classNode.textContent, "key3":levelNode.textContent,
  2902. 				"key4":attackNode.textContent, "key5":defenseNode.textContent, "key6":armorNode.textContent, "key7":damageNode.textContent,
  2903. 				"key8":hitpointsNode.textContent, "key9":goldNode.textContent, "key10":enchantmentsList});
  2904. 		}
  2905.  
  2906. 		levelNode.innerHTML += " (your level:<span style='color:yellow'>" + Helper.characterLevel + "</span>)";
  2907. 		attackNode.innerHTML += " (your defense:<span style='color:yellow'>" + Helper.characterDefense + "</span>) ";
  2908. 		defenseNode.innerHTML += " (your attack:<span style='color:yellow'>" + Helper.characterAttack + "</span>)";
  2909. 		armorNode.innerHTML += " (your damage:<span style='color:yellow'>" + Helper.characterDamage + "</span>)";
  2910. 		damageNode.innerHTML += " (your armor:<span style='color:yellow'>" + Helper.characterArmor + "</span>)";
  2911. 		hitpointsNode.innerHTML += " (your HP:<span style='color:yellow'>" + Helper.characterHP + "</span>)" +
  2912. 			"(1H: <span style='color:red'>" + oneHitNumber + "</span>)";
  2913.  
  2914. 		callback.monster.setAttribute("mouseOverText", "<table>" +
  2915. 			"<tr><td valign=top>" + imageNode.parentNode.innerHTML + "</td>" +
  2916. 			"<td rowspan=2>" + statsNode.parentNode.innerHTML + "</td></tr>" +
  2917. 			"<tr><td align=center valign=top>" + nameNode.innerHTML + "</td></tr></table>");
  2918. 		callback.monster.setAttribute("mouseOverWidth", "600");
  2919. 		callback.monster.addEventListener("mouseover", Helper.clientTip, true);
  2920. 		if (callback.showTip) Helper.clientTip({'target':callback.monster});
  2921. 	},
  2922.  
  2923. 	pushMonsterInfo: function(monster) {
  2924. 		// name, img, cls, lvl, atk, def, arm, dmg, hp, gold
  2925. 		var name = monster.key0;
  2926. 		var monsterLog = System.getValueJSON("monsterLog");
  2927. 		if (!monsterLog) monsterLog = {};
  2928. 		if (!monsterLog[name]) {
  2929. 			monsterLog[name] = {"min":{}, "max":{}};
  2930. 			for (i = 1; i < 10; i++) {
  2931. 				monsterLog[name]["min"]["key" + i] = 1e+100;
  2932. 				monsterLog[name]["max"]["key" + i] = 0;
  2933. 			}
  2934. 			//monsterLog[name]["min"] = {"cls":1e+100, "lvl":1e+100, "atk":1e+100, "def":1e+100, "arm":1e+100, "dmg":1e+100, "hp":1e+100, "gold":1e+100};
  2935. 			//monsterLog[name]["max"] = {"cls":0, "lvl":0, "atk":0, "def":0, "arm":0, "dmg":0, "hp":0, "gold":0};
  2936. 			for (i = 10; i < 11; i++) {// enchantments
  2937. 				if (monster["key" + i]) { //does this critter have enchantments, if so, then see min and max with the initial list
  2938. 					monsterLog[name]["min"]["key" + i] = monster["key" + i];
  2939. 					monsterLog[name]["max"]["key" + i] = monster["key" + i];
  2940. 				}
  2941. 			}
  2942. 		}
  2943. 		for (i = 1; i < 4; i++)
  2944. 			monsterLog[name]["min"]["key" + i] = monster["key" + i];
  2945. 		for (i = 4; i < 10; i++) {
  2946. 			var value = System.intValue(monster["key" + i]);
  2947. 			monsterLog[name]["min"]["key" + i] = monsterLog[name]["min"]["key" + i] < value?
  2948. 				monsterLog[name]["min"]["key" + i] : value;
  2949. 			monsterLog[name]["max"]["key" + i] = monsterLog[name]["max"]["key" + i] > value?
  2950. 				monsterLog[name]["max"]["key" + i] : value;
  2951. 		}
  2952. 		for (i = 10; i < 11; i++) {// enchantments
  2953. 			if (monster["key" + i]) { //does this critter have enchantments
  2954. 				if (!monsterLog[name]["min"]["key" + i] || !monsterLog[name]["min"]["key" + i]) {
  2955. 					monsterLog[name]["min"]["key" + i] = monster["key" + i];
  2956. 					monsterLog[name]["max"]["key" + i] = monster["key" + i];
  2957. 				}
  2958. 				for (j = 0; j < monster["key" + i].length; j++) {
  2959. 					var enchantName = monster["key" + i][j].name;
  2960. 					var enchantValue = monster["key" + i][j].value*1;
  2961. 					monsterLog[name]["min"]["key" + i][j].value = monsterLog[name]["min"]["key" + i][j].value*1 < enchantValue?
  2962. 						monsterLog[name]["min"]["key" + i][j].value : enchantValue;
  2963. 					monsterLog[name]["max"]["key" + i][j].value = monsterLog[name]["max"]["key" + i][j].value*1 > enchantValue?
  2964. 						monsterLog[name]["max"]["key" + i][j].value : enchantValue;
  2965. 				}
  2966. 			}
  2967. 		}
  2968. 		System.setValueJSON("monsterLog", monsterLog);
  2969. 	},
  2970.  
  2971. 	injectMonsterLog: function() {
  2972. 		var entityLog = System.getValueJSON("monsterLog");
  2973. 		if (entityLog) {
  2974. 			Helper.entityLogTable = {entity:[]};
  2975. 			for (var name in entityLog) {
  2976. 				var newEntity = {};
  2977. 				newEntity["name"] = name;
  2978. 				newEntity["key1"] = entityLog[name]["min"]["key1"];
  2979. 				for (i = 2; i < 4; i++)
  2980. 					newEntity["key" + i] = entityLog[name]["min"]["key" + i];
  2981. 				for (i = 4; i < 10; i++)
  2982. 					newEntity["key" + i] = System.addCommas(entityLog[name]["min"]["key"+i]) + ' - ' +
  2983. 						System.addCommas(entityLog[name]["max"]["key"+i]);
  2984. 				for (i = 10; i < 11; i++) {
  2985. 					if (entityLog[name]["min"]["key" + i]) {
  2986. 						newEntity["key" + i] = "";
  2987. 						for (j = 0; j < entityLog[name]["min"]["key" + i].length; j++) {
  2988. 							newEntity["key" + i] += '<nobr>' + entityLog[name]["min"]["key"+i][j].name + ' ' + 
  2989. 								entityLog[name]["min"]["key"+i][j].value + ' - ' + entityLog[name]["max"]["key"+i][j].value + '<nobr>' + 
  2990. 								(j != entityLog[name]["min"]["key" + i].length - 1? '<br/>':'');
  2991. 						}
  2992. 					}
  2993. 				}
  2994. 				Helper.entityLogTable.entity.push(newEntity);
  2995. 			}
  2996. 			Helper.sortBy = 'key3';
  2997. 			Helper.sortAsc = true;
  2998. 			Helper.entityLogTable.entity.sort(Helper.numberSort);
  2999. 		}
  3000. 		var content=Layout.notebookContent();
  3001. 		content.innerHTML = '<span id=Helper.entityTableOutput>No monster information! Please enable entity log and travel a bit to see the world</span>';
  3002. 		Helper.generateEntityTable();
  3003. 	},
  3004.  
  3005. 	generateEntityTable: function() {
  3006. 		var content = document.getElementById("Helper.entityTableOutput");
  3007. 		if (!Helper.entityLogTable || !content) {return;}
  3008. 		GM_addStyle(
  3009. 			'.HelperMonsterLogRow1 {background-color:#e7c473;font-size:small}\n' +
  3010. 			'.HelperMonsterLogRow1:hover {background-color:white}\n' +
  3011. 			'.HelperMonsterLogRow2 {background-color:#e2b960;font-size:small}\n' +
  3012. 			'.HelperMonsterLogRow2:hover {background-color:white}');
  3013.  
  3014. 		var result = '<table cellspacing="0" cellpadding="0" border="0" width="100%"><tr style="background-color:#110011; color:white;">'+
  3015. 			'<td width="90%" nobr align=center><b>&nbsp;Entity Information</b></td>'+
  3016. 			'<td width="10%" nobr>[<span id="Helper.clearEntityLog">Clear</span>]</td>'+
  3017. 			'</tr>' +
  3018. 			'</table>'+
  3019. 			'<table id="Helper:EntityInfo" cellspacing="1" cellpadding="2" border="0" style="font-size:small;"><tr style="background-color:#e2b960;">' +
  3020. 			'<th width="25%" align="left" sortkey="name" colspan="2">Entity</th>' +
  3021. 			'<th align="center" sortkey="key2">Class</th>' +
  3022. 			'<th align="center" sortkey="key3" sorttype="number">Lvl</th>' +
  3023. 			'<th align="center">Attack</th>' +
  3024. 			'<th align="center">Defence</th>' +
  3025. 			'<th align="center">Armor</th>' +
  3026. 			'<th align="center">Damage</th>' +
  3027. 			'<th align="center">HP</th>' +
  3028. 			//'<th align="center">Gold</th>' +
  3029. 			'<th align="center">Enhancements</th>' +
  3030. 			'</tr>';
  3031. 		for (var k=0;k<Helper.entityLogTable.entity.length;k++) {
  3032. 			result += '<tr class="HelperMonsterLogRow'+(1+k % 2)+'"><td align="center"><img width=40 height=40 ' +
  3033. 					'onmouseover="tt_setWidth(200);Tip(\'<img src=' + Helper.entityLogTable.entity[k]["key1"] + '/>\');" ' +
  3034. 					'src="' + Helper.entityLogTable.entity[k]["key1"] + '"/></td>';
  3035. 			result += '<td align="left">' + Helper.entityLogTable.entity[k]["name"] + '</td>';
  3036. 			for (i = 2; i < 4; i++)
  3037. 				result += '<td align="center">' + System.addCommas(Helper.entityLogTable.entity[k]["key"+i]) + '</td>';
  3038. 			for (i = 4; i < 9; i++) // 10 is gold, we don't need to show this
  3039. 				result += '<td align="center">' + Helper.entityLogTable.entity[k]["key"+i] + '</td>';
  3040. 			for (i = 10; i < 11; i++) {
  3041. 				var entityInformationValue = Helper.entityLogTable.entity[k]["key"+i];
  3042. 				if (!entityInformationValue) {
  3043. 					result += '<td align="center" style="font-size:small; color:gray;">**Missing**</td>';
  3044. 				} else {
  3045. 					result += '<td align="center" style="font-size:xx-small;">' + entityInformationValue + '</td>';
  3046. 				}
  3047. 			}
  3048. 		}
  3049. 		result += "</table>";
  3050. 		content.innerHTML = result;
  3051. 		document.getElementById("Helper.clearEntityLog").addEventListener("click", Helper.clearEntityLog, true);
  3052.  
  3053. 		var theTable=document.getElementById('Helper:EntityInfo');
  3054. 		for (var i=0; i<theTable.rows[0].cells.length; i++) {
  3055. 			var cell=theTable.rows[0].cells[i];
  3056. 			if (cell.getAttribute("sortkey")) {
  3057. 				cell.style.textDecoration="underline";
  3058. 				cell.style.cursor="pointer";
  3059. 				cell.addEventListener('click', Helper.sortEntityLogTable, true);
  3060. 			}
  3061. 		}
  3062. 	},
  3063.  
  3064. 	clearEntityLog: function() {
  3065. 		GM_setValue("monsterLog", "");
  3066. 		window.location="index.php?cmd=notepad&subcmd=monsterlog";
  3067. 	},
  3068.  
  3069. 	sortEntityLogTable: function(evt) {
  3070. 		var headerClicked = evt.target.getAttribute("sortKey");
  3071. 		var sortType = evt.target.getAttribute("sortType");
  3072. 		if (!sortType) sortType="string";
  3073. 		if (Helper.sortAsc==undefined) Helper.sortAsc=true;
  3074. 		if (Helper.sortBy && Helper.sortBy==headerClicked) {
  3075. 			Helper.sortAsc=!Helper.sortAsc;
  3076. 		}
  3077.  
  3078. 		Helper.sortBy=headerClicked;
  3079. 		GM_log(Helper.sortAsc + " " + Helper.sortBy + " " + sortType);
  3080.  
  3081. 		switch(sortType) {
  3082. 			case "string":
  3083. 				Helper.entityLogTable.entity.sort(Helper.stringSort);
  3084. 				break;
  3085. 			case "number":
  3086. 				Helper.entityLogTable.entity.sort(Helper.numberSort);
  3087. 				break;
  3088. 			default:
  3089. 				break;
  3090. 		}
  3091. 		Helper.generateEntityTable();
  3092. 	},
  3093.  
  3094. 	backpackUpdater: function(count){
  3095. 		var slots = System.findNode(".//font[contains(.,'/') and @size='1']");
  3096. 		if (slots !== null){
  3097. 			bpslots = slots.childNodes[0].nodeValue.split("/");
  3098. 			//note the - 0 is to insure that math is used
  3099. 			slots.childNodes[0].nodeValue = (bpslots[0] - 0 + count) + " /" + bpslots[1];
  3100. 		}
  3101. 	},
  3102.  
  3103.  
  3104. 	killedMonster: function(responseText, callback) {
  3105. 		var doc=System.createDocument(responseText);
  3106.  
  3107. 		var reportRE=/var\s+report=new\s+Array;\n(report\[[0-9]+\]="[^"]+";\n)*/;
  3108. 		var report=responseText.match(reportRE);
  3109. 		if (report) report=report[0];
  3110.  
  3111. 		// var specialsRE=/<div id="specialsDiv" style="position:relative; display:block;"><font color='#FF0000'><b>Azlorie Witch Doctor was withered.</b></font>/
  3112. 		var specials=System.findNodes("//div[@id='specialsDiv']", doc);
  3113.  
  3114. 		var playerId = Layout.playerId();
  3115.  
  3116. 		var xpGain       = System.getIntFromRegExp(responseText, /var\s+xpGain=(-?[0-9]+);/i);
  3117. 		var goldGain     = System.getIntFromRegExp(responseText, /var\s+goldGain=(-?[0-9]+);/i);
  3118. 		var guildTaxGain = System.getIntFromRegExp(responseText, /var\s+guildTaxGain=(-?[0-9]+);/i);
  3119. 		var levelUp      = System.getIntFromRegExp(responseText, /var\s+levelUp=(-?[0-9]+);/i);
  3120. 		var lootRE=/You looted the item '<font color='(\#[0-9A-F]+)'>([^<]+)<\/font>'<\/b><br><br><img src=\"http:\/\/[0-9.]+\/items\/(\d+).gif\"\s+onmouseover="ajaxLoadCustom\([0-9]+,\s-1,\s+([0-9a-f]+),\s+[0-9]+,\s+''\);\">/;
  3121. 		var info         = Layout.infoBox(responseText);
  3122. 		var lootMatch=responseText.match(lootRE);
  3123. 		var lootedItem = "";
  3124. 		var lootedItemId = "";
  3125. 		var lootedItemVerify="";
  3126. 		if (lootMatch && lootMatch.length>0) {
  3127. 			lootedItem=lootMatch[2];
  3128. 			lootedItemId=lootMatch[3];
  3129. 			lootedItemVerify=lootMatch[4];
  3130. 		}
  3131. 		var shieldImpDeathRE = /Shield Imp absorbed all damage/;
  3132. 		var shieldImpDeath = responseText.match(shieldImpDeathRE);
  3133.  
  3134. 		var monster = callback.node;
  3135. 		var showCombatLog = false;
  3136. 		if (monster) {
  3137. 			var result=document.createElement("div");
  3138. 			var resultHtml = "<small><small>"+callback.index+". XP:" + xpGain + " Gold:" + goldGain + " (" + guildTaxGain + ")</small></small>";
  3139. 			var resultText = "XP:" + xpGain + " Gold:" + goldGain + " (" + guildTaxGain + ")\n";
  3140. 			if (info!=="") {
  3141. 				resultHtml += "<br/><div style='font-size:x-small;width:120px;overflow:hidden;' title='" + info + "'>" + info + "</div>";
  3142. 				resultText += info + "\n";
  3143. 			}
  3144. 			if (lootedItem!=="") {
  3145. 				Helper.backpackUpdater(1);
  3146. 				// I've temporarily disabled the ajax thingie, as it doesn't seem to work anyway.
  3147. 				resultHtml += "<br/><small><small>Looted item:<span onclickDISABLED=\"ajaxLoadItem(" +
  3148. 					lootedItemId + ", -1, 2, " + playerId + ", '');\" >" +
  3149. 					lootedItem + "</span></small></small>";
  3150. 				resultText += "Looted item:" + lootedItem + "\n";
  3151. 			}
  3152. 			if (shieldImpDeath) {
  3153. 				resultHtml += "<br/><small><small><span style='color:red;'>Shield Imp Death</span></small></small>";
  3154. 				resultText += "Shield Imp Death\n";
  3155. 				showCombatLog = true;
  3156. 			}
  3157. 			if (levelUp=="1") {
  3158. 				resultHtml += '<br/><br/><div style="color:#999900;font-weight:bold;>Your level has increased!</div>';
  3159. 				resultText += "Your level has increased!\n";
  3160. 				showCombatLog = true;
  3161. 			}
  3162. 			if (levelUp=="-1") {
  3163. 				resultHtml += '<br/><br/><div style="color:#991100;font-weight:bold;">Your level has decreased!</div>';
  3164. 				resultText += "Your level has decreased!\n";
  3165. 				showCombatLog = true;
  3166. 			}
  3167. 			if (xpGain<0) {result.style.color='red'; showCombatLog = true;}
  3168. 			result.innerHTML=resultHtml;
  3169. 			var monsterParent = monster.parentNode;
  3170. 			result.id = "result" + callback.index;
  3171. 			if (report) {
  3172. 				var reportLines=report.split("\n");
  3173. 				var reportHtml="";
  3174. 				var reportText="";
  3175. 				if (specials) {
  3176. 					reportHtml += "<div style='color:red'>";
  3177. 					for (var i=0; i<specials.length; i++) {
  3178. 						reportHtml += specials[i].textContent + "<br/>";
  3179. 						reportText += specials[i].textContent + "\n";
  3180. 					}
  3181. 					reportHtml += "</div>";
  3182. 				}
  3183. 				for (i=0; i<reportLines.length; i++) {
  3184. 					var reportMatch = reportLines[i].match(/\"(.*)\"/);
  3185. 					if (reportMatch) {
  3186. 						reportHtml += "<br/>" + reportMatch[1];
  3187. 						reportText += reportMatch[1].replace(/<br>/g, "\n") + "\n";
  3188. 					}
  3189. 				}
  3190. 				mouseOverText = "<div><div style='color:#FFF380;text-align:center;'>Combat Results</div>" + reportHtml + "</div>";
  3191. 				Helper.appendCombatLog(reportHtml, showCombatLog);
  3192. 				result.setAttribute("mouseOverText", mouseOverText);
  3193. 				if (GM_getValue("keepLogs")) {
  3194. 					var now=new Date();
  3195. 					Helper.appendSavedLog("\n================================\n" + now.toLocaleFormat("%Y-%M-%d %H:%m:%S") + "\n" + resultText + "\n" + reportText);
  3196. 				}
  3197. 			}
  3198. 			monsterParent.innerHTML = "";
  3199. 			monsterParent.insertBefore(result, monsterParent.nextSibling);
  3200. 			if (report) {
  3201. 				document.getElementById("result" + callback.index).addEventListener("mouseover", Helper.clientTip, true);
  3202. 			}
  3203. 		}
  3204. 	},
  3205.  
  3206. 	appendSavedLog: function(text) {
  3207. 		var theLog=GM_getValue("CombatLog");
  3208. 		if (!theLog) theLog="";
  3209. 		theLog+=text;
  3210. 		GM_setValue("CombatLog", theLog);
  3211. 	},
  3212.  
  3213. 	appendCombatLog: function(text, showCombatLog) {
  3214. 		var reportLog = System.findNode("//div[@id='reportsLog']");
  3215. 		if (!reportLog) {return;}
  3216. 		if (GM_getValue("showCombatLog") || showCombatLog) reportLog.innerHTML += text + "<br/>";
  3217. 	},
  3218.  
  3219. 	scrollUpCombatLog: function() {
  3220. 		var reportLog = System.findNode("//div[@id='reportsLog']");
  3221. 		reportLog.scrollTop-=10;
  3222. 	},
  3223.  
  3224. 	scrollDownCombatLog: function() {
  3225. 		var reportLog = System.findNode("//div[@id='reportsLog']");
  3226. 		reportLog.scrollTop+=10;
  3227. 	},
  3228.  
  3229. 	clientTip: function(evt) {
  3230. 		var target=evt.target;
  3231. 		var value, width;
  3232. 		do {
  3233. 			if (target.getAttribute) {
  3234. 				value=target.getAttribute("mouseovertext");
  3235. 				width=target.getAttribute("mouseoverwidth");
  3236. 			}
  3237. 			target=target.parentNode;
  3238. 		} while (!value && target);
  3239. 		if (value) {
  3240. 			if (!width) width="250";
  3241. 			unsafeWindow.tt_setWidth(parseInt(width,10));
  3242. 			unsafeWindow.Tip(value);
  3243. 		}
  3244. 	},
  3245.  
  3246. 	prepareGuildList: function() {
  3247. 		Helper.retrieveGuildData();
  3248. 	},
  3249.  
  3250. 	retrieveGuildData: function() {
  3251. 		var memberList = System.getValueJSON("memberlist");
  3252. 		var guildOnlineRefreshTime = GM_getValue("guildOnlineRefreshTime");
  3253. 		if (guildOnlineRefreshTime != 300) GM_setValue("guildOnlineRefreshTime", 300); //set refresh to 300 if not equal to 300
  3254. 		guildOnlineRefreshTime *= 1000;
  3255. 		if (memberList) {
  3256. 			if ((new Date()).getTime() - memberList.lastUpdate.getTime() > guildOnlineRefreshTime) memberList = null; // invalidate cache
  3257. 		}
  3258.  
  3259. 		if (!memberList) {
  3260. 			System.xmlhttp("index.php?cmd=guild&subcmd=manage", Helper.parseGuildForWorld, true);
  3261. 		}
  3262. 	},
  3263.  
  3264. 	parseGuildForWorld: function(details) {
  3265. 		var doc=System.createDocument(details);
  3266. 		var allTables = doc.getElementsByTagName("TABLE");
  3267. 		var membersTable;
  3268. 		for (var i=0;i<allTables.length;i++) {
  3269. 			var oneTable=allTables[i];
  3270. 			if (oneTable.rows.length>=1 && oneTable.rows[0].cells.length>=1 && (/<b>Members<\/b>/i).test(oneTable.rows[0].cells[0].innerHTML)) {
  3271. 				membersTable=oneTable;
  3272. 			}
  3273. 		}
  3274.  
  3275. 		if (membersTable) {
  3276. 			var membersDetails=membersTable.getElementsByTagName("TABLE")[0];
  3277. 			var memberList = System.getValueJSON("memberlist");
  3278. 			if (!memberList) {
  3279. 				memberList = {};
  3280. 				memberList.members = [];
  3281. 			}
  3282.  
  3283. 			memberList.members.forEach(function(e) {e.status="Deleted";});
  3284.  
  3285. 			for (i=0;i<membersDetails.rows.length;i++) {
  3286. 				var aRow = membersDetails.rows[i];
  3287. 				if (aRow.cells.length==5 && aRow.cells[0].firstChild.title) {
  3288. 					var playerLink   = aRow.cells[1].firstChild.nextSibling;
  3289. 					var memberId     = System.intValue((/[0-9]+$/).exec(playerLink.getAttribute("href"))[0]);
  3290. 					var memberName   = playerLink.textContent;
  3291. 					var memberLevel  = System.intValue(aRow.cells[2].textContent);
  3292. 					var memberRank   = aRow.cells[3].textContent;
  3293. 					var memberXP     = System.intValue(aRow.cells[4].textContent);
  3294. 					var memberStatus = aRow.cells[0].firstChild.title;
  3295.  
  3296. 					var aMember;
  3297.  
  3298. 					// find member in member list, to modify data instead of replacing it
  3299.  
  3300. 					var findMembers = memberList.members.filter(function (e) {return e.id==memberId;});
  3301. 					if (findMembers.length>0) {
  3302. 						aMember = findMembers[0];
  3303. 					}
  3304. 					else { // member was not found, must be a new player
  3305. 						aMember = {};
  3306. 						// You can still modify an object, even if you have added it to something else
  3307. 						memberList.members.push(aMember);
  3308. 						aMember.firstSeen = new Date();
  3309. 						aMember.status = "Offline"; // new players are supposed to be offline
  3310. 					}
  3311. 					Helper.getFullPlayerData(aMember);
  3312.  
  3313. 					if (aMember.status == "Offline" && memberStatus=="Online") {
  3314. 						aMember.loggedInAt = new Date();
  3315. 					}
  3316.  
  3317. 					if (!aMember.loggedInAt) {
  3318. 						aMember.loggedInAt = new Date();
  3319. 					}
  3320.  
  3321. 					aMember.status = memberStatus;
  3322. 					aMember.id     = memberId;
  3323. 					aMember.name   = memberName;
  3324. 					aMember.level  = memberLevel;
  3325. 					aMember.rank   = memberRank;
  3326. 					aMember.xp     = memberXP;
  3327. 				}
  3328. 			}
  3329.  
  3330. 			// remove not existing players
  3331. 			memberList.members = memberList.members.filter(function(e) {return e.status!="Deleted";});
  3332. 			// damn, I love javascript array functions :)
  3333.  
  3334. 			memberList.lastUpdate = new Date();
  3335. 			memberList.isRefreshed = true;
  3336. 			System.setValueJSON("memberlist", memberList);
  3337.  
  3338. 			if (location.search == "?cmd=guild&subcmd=ranks") {
  3339. 				Helper.injectGuildRanksMembers(memberList);
  3340. 			}
  3341. 		}
  3342. 	},
  3343.  
  3344. 	replaceKeyHandler: function() {
  3345. 		unsafeWindow.document.onkeypress = null;
  3346. 		unsafeWindow.document.onkeypress = Helper.keyPress;
  3347. 	},
  3348.  
  3349. 	moveMe: function(dx, dy) {
  3350. 		var pos=Helper.position();
  3351. 		if (pos) {
  3352. 			if (pos.type=="normal") {
  3353. 				window.location = 'index.php?cmd=world&subcmd=move&x=' + (pos.X+dx) + '&y=' + (pos.Y+dy);
  3354. 			}
  3355. 			if (pos.type=="worldmap") {
  3356. 				System.xmlhttp('index.php?cmd=world&subcmd=move&x=' + (pos.X+dx) + '&y=' + (pos.Y+dy), function() {window.location = System.server + "index.php?cmd=world&subcmd=map";});
  3357. 			}
  3358. 		}
  3359. 	},
  3360.  
  3361. 	killMonsterAt: function(index) {
  3362. 		var linkObj	= Helper.getMonster(index);
  3363. 		if (linkObj!==null) {
  3364. 			if (GM_getValue("quickKill")) {
  3365. 				Helper.killSingleMonster(index);
  3366. 			}
  3367. 			else {
  3368. 				window.location = linkObj.getAttribute("href");
  3369. 			}
  3370. 		}
  3371. 	},
  3372.  
  3373. 	keyPress: function (evt) {
  3374. 		var r, s;
  3375. 		if (evt.target.tagName!="HTML" && evt.target.tagName!="BODY") {return;}
  3376.  
  3377. 		// ignore control, alt and meta keys (I think meta is the command key in Macintoshes)
  3378. 		if (evt.ctrlKey) {return;}
  3379. 		if (evt.metaKey) {return;}
  3380. 		if (evt.altKey) {return;}
  3381.  
  3382. 		r = evt.charCode;
  3383. 		s = evt.keyCode;
  3384.  
  3385. 		switch (r) {
  3386. 		case 113: // nw
  3387. 			Helper.moveMe(-1,-1);
  3388. 			break;
  3389. 		case 119: // n
  3390. 			Helper.moveMe(0,-1);
  3391. 			break;
  3392. 		case 101: // ne
  3393. 			Helper.moveMe(1,-1);
  3394. 			break;
  3395. 		case 97: // w
  3396. 			Helper.moveMe(-1,0);
  3397. 			break;
  3398. 		case 100: // e
  3399. 			Helper.moveMe(1,0);
  3400. 			break;
  3401. 		case 122: // sw
  3402. 			Helper.moveMe(-1,1);
  3403. 			break;
  3404. 		case 120: // s
  3405. 			Helper.moveMe(0,1);
  3406. 			break;
  3407. 		case 99: // se
  3408. 			Helper.moveMe(1,1);
  3409. 			break;
  3410. 		case 114: // repair
  3411. 			window.location = 'index.php?cmd=blacksmith&subcmd=repairall&fromworld=1';
  3412. 			break;
  3413. 		case 71: // create group [G]
  3414. 			window.location = 'index.php?cmd=guild&subcmd=groups&subcmd2=create&fromworld=1';
  3415. 			break;
  3416. 		case 103: // go to guild [g]
  3417. 			window.location = 'index.php?cmd=guild&subcmd=manage';
  3418. 			break;
  3419. 		case 106: // join all group [j]
  3420. 			if (!GM_getValue("enableMaxGroupSizeToJoin")) {
  3421. 				window.location = 'index.php?cmd=guild&subcmd=groups&subcmd2=joinall';
  3422. 			} else {
  3423. 				window.location = 'index.php?cmd=guild&subcmd=groups&subcmd2=joinallgroupsundersize';
  3424. 			}
  3425. 			break;
  3426. 		case 49:
  3427. 		case 50:
  3428. 		case 51:
  3429. 		case 52:
  3430. 		case 53:
  3431. 		case 54:
  3432. 		case 55:
  3433. 		case 56: // keyed combat
  3434. 			Helper.killMonsterAt(r-48);
  3435. 			break;
  3436. 		case 98: // backpack [b]
  3437. 			window.location = 'index.php?cmd=profile&subcmd=dropitems&fromworld=1';
  3438. 			break;
  3439. 		case 116: // quick buy [t]
  3440. 			Helper.quickBuyItem();
  3441. 			break;
  3442. 		case 118: // fast wear manager [v]
  3443. 			window.location = 'index.php?cmd=notepad&subcmd=quickwear';
  3444. 			break;
  3445. 		case 121: // fast send gold [y]
  3446. 			Helper.sendGoldToPlayer();
  3447. 			break;
  3448. 		case 19: // quick buffs
  3449. 			// openWindow("", "fsQuickBuff", 618, 800, ",scrollbars");
  3450. 			GM_openInTab(System.server + "index.php?cmd=quickbuff");
  3451. 			break;
  3452. 		case 48: // return to world
  3453. 			window.location = 'index.php?cmd=world';
  3454. 			break;
  3455. 		case 109: // map
  3456. 			// window.open('index.php?cmd=world&subcmd=map', 'fsMap');
  3457. 			// openWindow('index.php?cmd=world&subcmd=map', 'fsMap', 650, 650, ',scrollbars,resizable');
  3458. 			GM_openInTab(System.server + "index.php?cmd=world&subcmd=map");
  3459. 			break;
  3460. 		case 112: // profile
  3461. 			window.location = 'index.php?cmd=profile';
  3462. 			break;
  3463. 		case 110: // mini map [n]
  3464. 			Helper.displayMiniMap();
  3465. 			break;
  3466. 		case 78: // auto move in mini map [N]
  3467. 			Helper.autoMoveMiniMap();
  3468. 			break;
  3469. 		case 62: // move to next page [>]
  3470. 		case 60: // move to prev page [<]
  3471. 			Helper.movePage({62:'>', 60:'<'}[r]);
  3472. 			break;
  3473. 		case 33: // Shift+1
  3474. 		case 64: // Shift+2
  3475. 		case 34: // Shift+2 -- for UK keyboards, I think
  3476. 		case 35: // Shift+3
  3477. 		case 36: // Shift+4
  3478. 		case 37: // Shift+5
  3479. 		case 94: // Shift+6
  3480. 		case 38: // Shift+7
  3481. 		case 42: // Shift+8
  3482. 		case 40: // Shift+9
  3483. 			var keyMap = {"key33":1, "key64":2, "key34":2, "key35":3, "key36":4, "key37":5,
  3484. 				"key94":6, "key38":7, "key42":8, "key40":9};
  3485. 			// I'm using "key??" because I don't feel comfortable of naming properties with integers
  3486. 			var itemIndex = keyMap["key" + r];
  3487. 			System.xmlhttp("index.php?cmd=profile", Helper.changeCombatSet, itemIndex);
  3488. 			break;
  3489. 		case 41: // Shift+0
  3490. 			// TODO: ask for a number, check isnumeric, then call changeCombatSet with that index.
  3491. 			break;
  3492. 		case 0: // special key
  3493. 			switch (s) {
  3494. 			case 37: // w
  3495. 				Helper.moveMe(-1,0);
  3496. 				evt.preventDefault();
  3497. 				evt.stopPropagation();
  3498. 				break;
  3499. 			case 38: // n
  3500. 				Helper.moveMe(0,-1);
  3501. 				evt.preventDefault();
  3502. 				evt.stopPropagation();
  3503. 				break;
  3504. 			case 39: // e
  3505. 				Helper.moveMe(1,0);
  3506. 				evt.preventDefault();
  3507. 				evt.stopPropagation();
  3508. 				break;
  3509. 			case 40: // s
  3510. 				Helper.moveMe(0,1);
  3511. 				evt.preventDefault();
  3512. 				evt.stopPropagation();
  3513. 				break;
  3514. 			case 33:
  3515. 				if (System.findNode("//div[@id='reportsLog']")) {
  3516. 					Helper.scrollUpCombatLog();
  3517. 					evt.preventDefault();
  3518. 					evt.stopPropagation();
  3519. 				}
  3520. 				break;
  3521. 			case 34:
  3522. 				if (System.findNode("//div[@id='reportsLog']")) {
  3523. 					Helper.scrollDownCombatLog();
  3524. 					evt.preventDefault();
  3525. 					evt.stopPropagation();
  3526. 				}
  3527. 				break;
  3528. 			default:
  3529. 				// GM_log('special key: ' +s);
  3530. 				break;
  3531. 			}
  3532. 			break;
  3533. 		default:
  3534. 			// GM_log('standard key: ' +r);
  3535. 			break;
  3536. 		}
  3537. 		//return true;
  3538. 	},
  3539.  
  3540. 	addLogColoring: function(logScreen, dateColumn) {
  3541. 		if (!GM_getValue("enableLogColoring")) {return;}
  3542. 		var lastCheckScreen = "last" + logScreen + "Check";
  3543. 		var localLastCheckMilli=GM_getValue(lastCheckScreen);
  3544. 		if (!localLastCheckMilli) localLastCheckMilli=(new Date()).getTime();
  3545. 		var chatTable = System.findNode("//table[@class='width_full']");
  3546. 		if (!chatTable) {chatTable = System.findNode("//table[tbody/tr/td[.='Message']]");}
  3547. 		if (!chatTable) {chatTable = System.findNode("//table[tbody/tr/td/span[contains(.,'Currently showing:')]]");} //personal log
  3548. 		if (!chatTable) {return;}
  3549.  
  3550. 		var localDateMilli = (new Date()).getTime();
  3551. 		var gmtOffsetMinutes = (new Date()).getTimezoneOffset();
  3552. 		var gmtOffsetMilli = gmtOffsetMinutes*60*1000;
  3553.  
  3554. 		var newRow = chatTable.insertRow(1);
  3555. 		var newCell = newRow.insertCell(0);
  3556. 		for (var i=2;i<chatTable.rows.length;i+=2) {
  3557. 			var aRow = chatTable.rows[i];
  3558. 			var addBuffTag = true;
  3559. 			if (aRow.cells[0].innerHTML) {
  3560. 				//GM_log(aRow.cells[dateColumn].innerHTML);
  3561. 				var cellContents = aRow.cells[dateColumn].innerHTML;
  3562. 				if (logScreen != 'Chat' && logScreen != 'GuildLog') cellContents = cellContents.substring(6,23); // fix for player log screen.
  3563. 				postDateAsDate = System.parseDate(cellContents);
  3564. 				postDateAsLocalMilli = postDateAsDate.getTime() - gmtOffsetMilli;
  3565. 				postAge = (localDateMilli - postDateAsLocalMilli)/(1000*60);
  3566. 				if (postDateAsLocalMilli > localLastCheckMilli) {
  3567. 					aRow.style.backgroundColor = "#F5F298";
  3568. 				}
  3569. 				else if (postAge > 20 && postDateAsLocalMilli <= localLastCheckMilli) {
  3570. 					aRow.style.backgroundColor = "#CD9E4B";
  3571. 					addBuffTag = false;
  3572. 				}
  3573. 				if (logScreen == 'Chat' && addBuffTag) {
  3574. 					var playerIDRE = /player_id=(\d+)/;
  3575. 					var playerID = playerIDRE.exec(aRow.cells[1].innerHTML)[1];
  3576. 					aRow.cells[1].innerHTML += " <a style='color:blue;font-size:10px;' " +
  3577. 						Layout.quickBuffHref(playerID) + ">[b]</a>";
  3578. 				}
  3579. 			}
  3580. 		}
  3581. 		now=(new Date()).getTime();
  3582. 		GM_setValue(lastCheckScreen, now.toString());
  3583. 	},
  3584.  
  3585. 	addLogWidgets: function() {
  3586. 		var addAttackLinkToLog = GM_getValue('addAttackLinkToLog');
  3587. 		var logTable = System.findNode("//table[tbody/tr/td/span[contains(.,'Currently showing:')]]");
  3588. 		if (!logTable) {return;}
  3589. 		var memberList = System.getValueJSON("memberlist");
  3590. 		var memberNameString = "";
  3591. 		if (memberList) {
  3592. 			for (var i=0;i<memberList.members.length;i++) {
  3593. 				var member=memberList.members[i];
  3594. 				memberNameString += member.name + " ";
  3595. 			}
  3596. 		}
  3597. 		var listOfEnemies = GM_getValue("listOfEnemies");
  3598. 		if (!listOfEnemies) listOfEnemies = "";
  3599. 		var listOfAllies = GM_getValue("listOfAllies");
  3600. 		if (!listOfAllies) listOfAllies = "";
  3601. 		var buffList = Data.buffList();
  3602. 		for (i=0;i<logTable.rows.length;i++) {
  3603. 			var aRow = logTable.rows[i];
  3604. 			if (i !== 0) {
  3605. 				if (aRow.cells[0].innerHTML) {
  3606. 					firstCell = aRow.cells[0];
  3607. 					//Valid Types: General, Chat, Guild
  3608. 					messageType = firstCell.firstChild.getAttribute("title");
  3609. 					var colorPlayerName = false;
  3610. 					var isGuildMate = false;
  3611. 					if (messageType == "Chat") {
  3612. 						var playerElement = aRow.cells[2].firstChild;
  3613. 						var playerName = playerElement.innerHTML;
  3614. 						colorPlayerName = true;
  3615. 					}
  3616. 					if (messageType == "General") {
  3617. 						if (aRow.cells[2].firstChild.nextSibling && aRow.cells[2].firstChild.nextSibling.nodeName == 'A') {
  3618. 							if (aRow.cells[2].firstChild.nextSibling.getAttribute("href").search("player_id") != -1) {
  3619. 								playerElement = aRow.cells[2].firstChild.nextSibling;
  3620. 								playerName = playerElement.innerHTML;
  3621. 								colorPlayerName = true;
  3622. 							}
  3623. 						}
  3624. 					}
  3625.  
  3626. 					if (colorPlayerName) {
  3627. 						if (memberNameString.search(playerName) !=-1) {
  3628. 							playerElement.style.color="green";
  3629. 							isGuildMate = true;
  3630. 						}
  3631. 						if (listOfEnemies.search(playerName) !=-1) {
  3632. 							playerElement.style.color="red";
  3633. 						}
  3634. 						if (listOfAllies.search(playerName) !=-1) {
  3635. 							playerElement.style.color="blue";
  3636. 						}
  3637. 					}
  3638. 					if (messageType == "Chat") {
  3639. 						var dateHTML = aRow.cells[1].innerHTML;
  3640. 						var dateFirstPart = dateHTML.substring(0, dateHTML.indexOf(">Report") + 7);
  3641. 						var dateLastPart = dateHTML.substring(dateHTML.indexOf("Message</a>") + 11, dateHTML.length);
  3642. 						var extraPart = "";
  3643. 						if (!isGuildMate) {
  3644. 							extraPart = " | <a title='Add to Ignore List' href='index.php?cmd=log&subcmd=doaddignore&ignore_username=" + playerName +
  3645. 							"'>Ignore</a>";
  3646. 						}
  3647. 						aRow.cells[1].innerHTML = dateFirstPart + '</a>' + extraPart + dateLastPart;
  3648.  
  3649. 						var messageHTML = aRow.cells[2].innerHTML;
  3650. 						var firstPart = messageHTML.substring(0, messageHTML.indexOf("<small>") + 7);
  3651. 						var secondPart = messageHTML.substring(messageHTML.indexOf("<small>") + 7, messageHTML.indexOf(">Reply</a>") + 10);
  3652. 						var thirdPart = messageHTML.substring(messageHTML.indexOf(">Reply</a>") + 10, messageHTML.indexOf(">Buff</a>") + 9);
  3653. 						var targetPlayerID = /quickBuff\((\d+)\)/.exec(thirdPart)[1];
  3654. 						thirdPart = " | <a " + Layout.quickBuffHref(targetPlayerID) + ">Buff</a></span>";
  3655. 						var fourthPart = messageHTML.substring(messageHTML.indexOf(">Trade</a>") + 10, messageHTML.indexOf("</small>"));
  3656. 						var lastPart = messageHTML.substring(messageHTML.indexOf("</small>"), messageHTML.length);
  3657. 						extraPart = " | <a href='index.php?cmd=trade&target_player=" + playerName + "'>Trade</a> | " +
  3658. 							"<a title='Secure Trade' href='index.php?cmd=trade&subcmd=createsecure&target_username=" + playerName +
  3659. 							"'>ST</a>";
  3660.  
  3661. 						var attackPart = "";
  3662. 						if  (addAttackLinkToLog) {
  3663. 							var attackPart = " | <a href='index.php?cmd=attackplayer&target_username=" + playerName +"'>Attack</a>";
  3664. 						}
  3665.  
  3666. 						var buffsSent = aRow.cells[2].innerHTML.match(/`~.*?~`/);
  3667. 						var quickBuff = "";
  3668. 						if (buffsSent) {
  3669.  
  3670. 							buffsSent = new String(buffsSent).replace("`~","").replace("~`", "").split(",");
  3671. 							var theBuffPack = System.getValueJSON("buffpack");
  3672. 							for (var j = 0; j < buffsSent.length; j++) {
  3673. 								var bBuffFound = false;
  3674. 								for (var m = 0; m < buffList.length; m++) {
  3675. 									var nicks = buffList[m].nicks.split(",");
  3676. 									var exitOuter = false;
  3677.  
  3678. 									for (var k = 0; k < nicks.length; k++) {
  3679. 										if (buffsSent[j].toLowerCase().trim() == nicks[k].toLowerCase().trim()) {
  3680.  
  3681. 											quickBuff += m + ";";
  3682. 											exitOuter = true;
  3683. 											bBuffFound = true;
  3684. 											break;
  3685.  
  3686. 										}
  3687. 									}
  3688. 									if (exitOuter) {
  3689. 										break;
  3690. 									}
  3691. 								}
  3692. 								if (!bBuffFound) {
  3693.  
  3694. 									if (!theBuffPack) continue;
  3695.  
  3696. 									if (!theBuffPack["nickname"]) { //avoid bugs if the new array is not populated yet
  3697. 										theBuffPack["nickname"] = {};
  3698. 									}
  3699. 									if (!theBuffPack["staminaTotal"]) { //avoid bugs if the new array is not populated yet
  3700. 										theBuffPack["staminaTotal"] = {};
  3701. 									}
  3702.  
  3703. 									for (var idx = 0; idx < theBuffPack["size"]; idx++) {
  3704. 										var nickname = (theBuffPack["nickname"][idx]? theBuffPack["nickname"][idx]:"");
  3705. 										if (nickname.toLowerCase().trim() == buffsSent[j].toLowerCase().trim()) {
  3706. 											//82 is the number of buffs in the game currently. When they add new buffs, this will need to be updated, along with the fsData.buffList variable!
  3707. 											quickBuff += (82+idx) + ";";
  3708. 											break;
  3709. 										}
  3710. 									}
  3711. 								}
  3712.  
  3713. 							}
  3714. 							thirdPart = " | <a " + Layout.quickBuffHref(targetPlayerID, quickBuff) + ">Buff</a></span>";
  3715. 						}
  3716.  
  3717. 						var msgReplyTo = (GM_getValue("enableChatParsing") === true) ? secondPart.replace(/"([^"]*?)"/, secondPart.match(/"([^"]*?)"/)[1] + "&replyTo='" +
  3718. 							Helper.removeHTML(firstPart.replace(/&nbsp;/g, "")).replace(/[\s*]/g, "_") + "'") : secondPart;
  3719. 						aRow.cells[2].innerHTML = firstPart + "<nobr>" + msgReplyTo + extraPart + thirdPart + attackPart + fourthPart + "</nobr>" + lastPart;
  3720. 					}
  3721. 					if (aRow.cells[2].innerHTML.search("You have just been outbid at the auction house") != -1) {
  3722. 						aRow.cells[2].innerHTML += ". Go to <a href='/index.php?cmd=auctionhouse&type=-50'>My Bids</a>.";
  3723. 					}
  3724. 					if (messageType == "General") {
  3725. 						if (aRow.cells[2].firstChild.nextSibling && aRow.cells[2].firstChild.nextSibling.nodeName == 'A') {
  3726. 							if (aRow.cells[2].firstChild.nextSibling.getAttribute("href").search("player_id") != -1) {
  3727. 								if (!isGuildMate) {
  3728. 									dateHTML = aRow.cells[1].innerHTML;
  3729. 									var dateExtraText = "<nobr><span style='font-size:x-small;'>[ <a title='Add to Ignore List' href='index.php?cmd=log&subcmd=doaddignore&ignore_username=" + playerName +
  3730. 									"'>Ignore</a> ]</span></nobr>";
  3731. 									aRow.cells[1].innerHTML = aRow.cells[1].innerHTML + '<br>' + dateExtraText;
  3732. 								}
  3733. 								var buffingPlayerIDRE = /player_id=(\d+)/;
  3734. 								var buffingPlayerID = buffingPlayerIDRE.exec(aRow.cells[2].innerHTML)[1];
  3735. 								var buffingPlayerName = aRow.cells[2].firstChild.nextSibling.innerHTML;
  3736. 								var extraText = " <span style='font-size:x-small;'><nobr>[ <a href='index.php?cmd=message&target_player=" + buffingPlayerName +
  3737. 									"'>Reply</a> | <a href='index.php?cmd=trade&target_player=" + buffingPlayerName +
  3738. 									"'>Trade</a> | <a title='Secure Trade' href='index.php?cmd=trade&subcmd=createsecure&target_username=" + buffingPlayerName +
  3739. 									"'>ST</a>";
  3740. 								extraText += " | <a " + Layout.quickBuffHref(buffingPlayerID) + ">Buff</a>";
  3741. 								if (addAttackLinkToLog) {
  3742. 									extraText += " | <a href='index.php?cmd=attackplayer&target_username=" + buffingPlayerName +"'>Attack</a>"
  3743. 								}
  3744. 								extraText += " ]</nobr></span>";
  3745.  
  3746. 								aRow.cells[2].innerHTML += extraText;
  3747. 							}
  3748. 						}
  3749. 					}
  3750. 				}
  3751. 			}
  3752. 			else {
  3753. 				var messageNameCell = aRow.cells[2];
  3754. 				if (messageNameCell) messageNameCell.innerHTML += "&nbsp;&nbsp;<span style='color:white;'>(Guild mates show up in <span style='color:green;'>green</span>)</span>";
  3755. 			}
  3756. 		}
  3757. 	},
  3758.  
  3759. 	addGuildLogWidgets: function() {
  3760. 		var node=System.findNode("//font[@size=3]/b[contains(.,'s Log')]/..");
  3761. 		if (node) node.innerHTML+=' [ <a href="index.php?cmd=notepad&subcmd=guildlog">Guild Log Summary</a> ]';
  3762. 		if (!GM_getValue("hideNonPlayerGuildLogMessages")) {return;}
  3763. 		var playerId=Layout.playerId();
  3764. 		var logTable = System.findNode("//table[@border='0' and @cellpadding='2' and @width='100%']");
  3765. 		var hideNextRows = 0;
  3766. 		for (var i=0;i<logTable.rows.length;i++) {
  3767. 			var aRow = logTable.rows[i];
  3768. 			var firstPlayerID = 0;
  3769. 			var secondPlayerID = 0;
  3770. 			if (i !== 0) {
  3771. 				if (hideNextRows>0) {
  3772. 					//aRow.style.display = "none";
  3773. 					hideNextRows --;
  3774. 				}
  3775. 				if (aRow.cells[0].innerHTML) {
  3776. 					var messageHTML = aRow.cells[2].innerHTML;
  3777. 					var doublerPlayerMessageRE = /member\s<a\shref="index.php\?cmd=profile\&amp;player_id=(\d+)/;
  3778. 					secondPlayer = doublerPlayerMessageRE.exec(messageHTML);
  3779. 					var singlePlayerMessageRE = /<a\shref="index.php\?cmd=profile\&amp;player_id=(\d+)/;
  3780. 					firstPlayer = singlePlayerMessageRE.exec(messageHTML);
  3781. 					if (secondPlayer) {
  3782. 						firstPlayerID = firstPlayer[1]*1;
  3783. 						secondPlayerID = secondPlayer[1]*1;
  3784. 					}
  3785. 					if (firstPlayer && !secondPlayer) {
  3786. 						firstPlayerID = firstPlayer[1]*1;
  3787. 					}
  3788. 					if (firstPlayer && firstPlayerID != playerId && secondPlayerID != playerId) {
  3789. 						//aRow.style.display = "none";
  3790. 						aRow.style.fontSize = "x-small";
  3791. 						aRow.style.color = "gray";
  3792. 						hideNextRows = 3;
  3793. 					}
  3794. 					if (aRow.cells[2].textContent.charAt(0) == '\'' || aRow.cells[2].textContent.search("has invited the player") != -1) {
  3795. 						message = aRow.cells[2].innerHTML;
  3796. 						firstQuote = message.indexOf('\'');
  3797. 						var firstPart = '';
  3798. 						firstPart = message.substring(0,firstQuote);
  3799. 						secondQuote = message.indexOf('\'',firstQuote+1);
  3800. 						targetPlayerName = message.substring(firstQuote+1,secondQuote);
  3801. 						aRow.cells[2].innerHTML = firstPart + '\'' +
  3802. 							'<a href="index.php?cmd=findplayer&search_active=1&search_username=' + targetPlayerName + '&search_show_first=1">' + targetPlayerName + '</a>' +
  3803. 							message.substring(secondQuote, message.length);
  3804. 					}
  3805. 				}
  3806. 			}
  3807. 			else {
  3808. 				var messageNameCell = aRow.firstChild.nextSibling.nextSibling.nextSibling;
  3809. 				if (messageNameCell) messageNameCell.innerHTML += "&nbsp;&nbsp;<font style='color:white;'>(Guild Log messages not involving self are dimmed!)</font>";
  3810. 			}
  3811.  
  3812. 		}
  3813. 	},
  3814.  
  3815. 	injectGuildLogSummary: function() {
  3816. 		Layout.notebookContent().innerHTML=Helper.makePageTemplate('Guild Log Summary','','guillogrefresh','Refresh','guildlogdetail');
  3817.  
  3818. 		var lastCheck=GM_getValue("lastGuildLogSumCheck");
  3819. 		var now=(new Date()).getTime();
  3820. 		if (!lastCheck) lastCheck=0;
  3821. 		var haveToCheck=((now - lastCheck) > 60*60*1000);
  3822. 		if (haveToCheck)
  3823. 			document.getElementById('guillogrefresh').addEventListener('click',Helper.guildLogSummaryRefresh,true);
  3824. 		else
  3825. 			document.getElementById('guillogrefresh').innerHTML='[ Wait '+ Math.round(60 - ((now - lastCheck)/60000)) +'m ]';
  3826. 		var logDetail=GM_getValue("guildlogdetail");
  3827. 		if (logDetail)
  3828. 			Helper.guildLogDisplay(logDetail);
  3829. 		else
  3830. 			Helper.guildLogSummaryRefresh();
  3831. 	},
  3832.  
  3833. 	guildLogSummaryRefresh: function() {
  3834. 		var now=(new Date()).getTime();
  3835. 		GM_setValue("lastGuildLogSumCheck", now.toString());
  3836. 		GM_setValue("guildlogdetail",'');
  3837. 		document.getElementById('guillogrefresh').innerHTML='';
  3838. 		document.getElementById('guildlogdetail').innerHTML='Parsing page 1';
  3839. 		System.xmlhttp('index.php?cmd=guild&subcmd=log&page=0',Helper.guidLogRetrieve,1);
  3840. 	},
  3841.  
  3842. 	guidLogRetrieve: function(responseText, callback) {
  3843. 		var doc=System.createDocument(responseText);
  3844. 		var logTable = System.findNode("//table[@border='0' and @cellpadding='2' and @width='100%']",doc);
  3845. 		logTable.deleteRow(0);
  3846. 		log=logTable.innerHTML.replace('<tbody>','').replace('</tbody>','');
  3847. 		var logDetail=GM_getValue("guildlogdetail");
  3848. 		if (!logDetail) logDetail='';
  3849. 		logDetail+=log;
  3850. 		GM_setValue("guildlogdetail", logDetail);
  3851. 		var page=System.findNode("//select",doc);
  3852. 		if (callback==15 || callback==page.length)
  3853. 			Helper.guildLogDisplay(logDetail);
  3854. 		else {
  3855. 			document.getElementById('guildlogdetail').innerHTML+=', '+(callback+1);
  3856. 			System.xmlhttp('index.php?cmd=guild&subcmd=log&page='+callback,Helper.guidLogRetrieve,callback+1);
  3857. 		}
  3858. 	},
  3859.  
  3860. 	guildLogDisplay: function(logDetail) {
  3861. 		document.getElementById('guildlogdetail').innerHTML='<table width=100% cellpadding=2 border=0 style="font-size:x-small">'+
  3862. 			logDetail+'</table>';
  3863. 	},
  3864.  
  3865. 	getFullPlayerData: function(member) {
  3866. 		return;
  3867. 		//System.xmlhttp("index.php?cmd=profile&player_id=" + member.id, Helper.parsePlayerData, member.id);
  3868. 	},
  3869.  
  3870. 	parsePlayerData: function(responseText, memberId) {
  3871. 		// return;
  3872. 		var doc=System.createDocument(responseText);
  3873. 		// var statistics = System.findNode("//table[contains(tr/td/b,'Level:')]",0,doc);
  3874. 		var statistics = System.findNode("//table[contains(tbody/tr/td/b,'Level:')]",0,doc);
  3875. 		var levelNode = System.findNode("//td[contains(b,'Level:')]",0,statistics);
  3876. 		var levelValue = levelNode.nextSibling.innerHTML;
  3877. 		GM_log(levelValue);
  3878. 		// GM_log(statistics.innerHTML); //parentNode.parentNode.nextSibling.nextSibling.nextSibling.innerHTML);
  3879. 	},
  3880.  
  3881. 	injectBank: function() {
  3882. 		var injectHere;
  3883. 		var bank = System.findNode("//b[contains(.,'Bank')]");
  3884. 		if (bank) {
  3885. 			bank.innerHTML+="<br><a href='/index.php?cmd=guild&subcmd=bank'>Guild Bank</a>";
  3886. 		}
  3887. 	},
  3888.  
  3889. 	injectAuctionHouse: function() {
  3890. 		var isAuctionPage = System.findNode("//img[contains(@title,'Auction House')]");
  3891. 		if (isAuctionPage) {
  3892. 			var imageCell = isAuctionPage.parentNode;
  3893. 			var imageHTML = imageCell.innerHTML; //hold on to this for later.
  3894.  
  3895. 			var auctionTable = System.findNode("//img[contains(@title,'Auction House')]/../../../..");
  3896.  
  3897. 			//Add functionality to hide the text block at the top.
  3898. 			var textRow = auctionTable.rows[2];
  3899. 			textRow.id = 'auctionTextControl';
  3900. 			var myBidsButton = System.findNode("//input[@value='My Bids']/..");
  3901. 			myBidsButton.innerHTML += " [ <span style='cursor:pointer; text-decoration:underline;' " +
  3902. 				"id='toggleAuctionTextControl' linkto='auctionTextControl' title='Click on this to Show/Hide the AH text.'>X</span> ]";
  3903. 			if (GM_getValue("auctionTextControl")) {
  3904. 				textRow.style.display = "none";
  3905. 				textRow.style.visibility = "hidden";
  3906. 			}
  3907. 			document.getElementById('toggleAuctionTextControl').addEventListener('click', System.toggleVisibilty, true);
  3908.  
  3909. 			//fix button class and add go to first and last
  3910. 			var prevButton = System.findNode("//input[@value='<']");
  3911. 			var nextButton = System.findNode("//input[@value='>']");
  3912. 			if (prevButton) {
  3913. 				prevButton.setAttribute("class", "custombutton");
  3914. 				var startButton = document.createElement("input");
  3915. 				startButton.setAttribute("type", "button");
  3916. 				startButton.setAttribute("onclick", prevButton.getAttribute("onclick").replace(/\&page=[0-9]*/, "&page=1"));
  3917. 				startButton.setAttribute("class", "custombutton");
  3918. 				startButton.setAttribute("value", "<<");
  3919. 				prevButton.parentNode.insertBefore(startButton,prevButton);
  3920. 			}
  3921. 			if (nextButton) {
  3922. 				nextButton.setAttribute("class", "custombutton");
  3923. 				var lastPageNode=System.findNode("//input[@value='Go']/../preceding-sibling::td");
  3924. 				lastPage = lastPageNode.textContent.replace(/\D/g,"");
  3925. 				var finishButton = document.createElement("input");
  3926. 				finishButton.setAttribute("type", "button");
  3927. 				finishButton.setAttribute("onclick", nextButton.getAttribute("onclick").replace(/\&page=[0-9]*/, "&page=" + lastPage));
  3928. 				finishButton.setAttribute("class", "custombutton");
  3929. 				finishButton.setAttribute("value", ">>");
  3930. 				nextButton.parentNode.insertBefore(finishButton, nextButton.nextSibling);
  3931. 			}
  3932.  
  3933. 			//insert another page change block at the top of the screen.
  3934. 			var insertPageChangeBlockHere = auctionTable.rows[5].cells[0];
  3935. 			var pageChangeBlock = System.findNode("//input[@name='page' and @class='custominput']/../../../../../..");
  3936. 			var newPageChangeBlock = pageChangeBlock.innerHTML.replace('</form>','');
  3937. 			newPageChangeBlock += "</form>";
  3938. 			var insertPageChangeBlock=document.createElement("SPAN");
  3939. 			insertPageChangeBlock.innerHTML = newPageChangeBlock;
  3940. 			insertPageChangeBlockHere.align = "right";
  3941. 			insertPageChangeBlockHere.appendChild(insertPageChangeBlock);
  3942.  
  3943. 			var quickSearchList = System.getValueJSON("quickSearchList");
  3944.  
  3945. 			var finalHTML = "<span style='font-size:x-small; color:blue;'><table><tbody><tr><td rowspan='7'>" + imageHTML + "</td>" +
  3946. 				"<td colspan='3' style='text-align:center;color:#7D2252;background-color:#CD9E4B'><a style='color:#7D2252' href='" +
  3947. 							System.server +
  3948. 							"index.php?cmd=notepad&subcmd=auctionsearch'>" +
  3949. 							"Configure Quick Search</a></td></tr>";
  3950. 			var lp=0;
  3951. 			var rowCount = 0;
  3952. 			for (var p=0;p<quickSearchList.length;p++) {
  3953. 				if (lp % 3===0 && rowCount == 6) break; //18 searches on the screen so don't display any more
  3954. 				var quickSearch=quickSearchList[p];
  3955. 				if (quickSearch.displayOnAH) {
  3956. 					if (lp % 3===0) {
  3957. 						finalHTML += "<tr>";
  3958. 						rowCount++;
  3959. 					}
  3960. 					finalHTML += "<td";
  3961. 					finalHTML += "><a href='index.php?cmd=auctionhouse&type=-1&search_text=" +
  3962. 						quickSearch.searchname + "&page=1&order_by=1'>" +
  3963. 						quickSearch.nickname + "</a></td>";
  3964. 					if (lp % 3==2) finalHTML += "</tr>";
  3965. 					if (lp % 3==2) finalHTML += "</tr>";
  3966. 					lp++;
  3967. 				}
  3968. 			}
  3969. 			imageCell.innerHTML = finalHTML;
  3970. 		}
  3971.  
  3972. 		if (GM_getValue('enableAHItemWidgets')) {
  3973. 			var allItems = document.getElementsByTagName("IMG");
  3974. 			for (i=0; i<allItems.length; i++) {
  3975. 				anItem = allItems[i];
  3976. 				if (anItem.src.search("items") != -1) {
  3977. 					var theImage = anItem;
  3978. 					var theUrl = Helper.linkFromMouseover(anItem.getAttribute("onmouseover"));
  3979. 					if (theUrl === null) {
  3980. 						continue;
  3981. 					}
  3982. 					System.xmlhttp(theUrl,
  3983. 						function(responseText, callback) {
  3984. 							var itemNameRE = /<td colspan=6><center><font color='(#[0-9a-fA-F]{6})' size=2><b>([^<]+)<\/b>/;
  3985. 							if (itemNameRE) {
  3986. 								var itemName = itemNameRE.exec(responseText)[2];
  3987. 							}
  3988. 							var craft="";
  3989. 							if (responseText.search(/Uncrafted|Very Poor|Poor|Average|Good|Very Good|Excellent|Perfect/) != -1){
  3990. 								var fontLineRE=/<\/b><\/font><br>([^<]+)(<font color='(#[0-9a-fA-F]{6})'>[^<]+<\/font>)/;
  3991. 								var fontLineRX=fontLineRE.exec(responseText);
  3992. 								craft = fontLineRX[2];
  3993. 							}
  3994. 							var forgeCount=0, re=/hellforge\/forgelevel.gif/ig;
  3995. 							while(re.exec(responseText)) {
  3996. 								forgeCount++;
  3997. 							}
  3998. 							if (responseText.search(/Crystalline/) != -1) {
  3999. 								var durabilityRE =/<font color='#999999'>Durability:<\/font><\/nobr><\/td><td width='50%' align='right'>(\d+)\&nbsp;\/\&nbsp;(\d+)\&nbsp;/;
  4000. 								var durability = '<span style="font-size:x-small; color:gray;"><br>Dur: ' +
  4001. 									durabilityRE.exec(responseText)[1] + '/' + durabilityRE.exec(responseText)[2] + '</span>';
  4002. 							}
  4003. 							Helper.injectAuctionExtraText(this.callback,itemName,craft,forgeCount,durability);
  4004. 						},
  4005. 						theImage);
  4006. 				}
  4007. 			}
  4008. 		}
  4009. 		var minBidLink = System.findNode("//a[contains(@href,'&order_by=1&tid=')]");
  4010. 		auctionTable = minBidLink.parentNode.parentNode.parentNode.parentNode;
  4011.  
  4012. 		var playerId = Layout.playerId();
  4013.  
  4014. 		var memberList = System.getValueJSON("memberlist");
  4015. 		var memberNameString = "";
  4016. 		if (memberList) {
  4017. 			for (i=0;i<memberList.members.length;i++) {
  4018. 				var member=memberList.members[i];
  4019. 				memberNameString += member.name + " ";
  4020. 			}
  4021. 		}
  4022. 		var listOfEnemies = GM_getValue("listOfEnemies");
  4023. 		if (!listOfEnemies) listOfEnemies = "";
  4024. 		var listOfAllies = GM_getValue("listOfAllies");
  4025. 		if (!listOfAllies) listOfAllies = "";
  4026.  
  4027. 		var newRow, newCell, winningBidBuyoutCell;
  4028. 		for (i=0;i<auctionTable.rows.length;i++) {
  4029. 			var aRow = auctionTable.rows[i];
  4030. 			if (i>0 && // the title row - ignore this
  4031. 				aRow.cells[1]) { // a separator row - ignore this
  4032. 				if (aRow.cells[5].innerHTML == '<font size="1">[ended]</font>') { //time left column
  4033. 					aRow.cells[6].innerHTML = ""; // text field and button column
  4034. 				} else {
  4035. 					var timeLeft = aRow.cells[5].firstChild.innerHTML;
  4036. 					var secondsLeft = timeLeft.substring(timeLeft.indexOf('m')+1).trim();
  4037. 					timeLeft = timeLeft.substring(0, timeLeft.indexOf('m'));
  4038. 					if (timeLeft >= 60) {
  4039. 						var hoursLeft = Math.floor(timeLeft / 60);
  4040. 						if (hoursLeft < 24) {
  4041. 							var minutesLeft = timeLeft - (hoursLeft * 60);
  4042. 							aRow.cells[5].firstChild.innerHTML = hoursLeft + "h " + minutesLeft + "m " + secondsLeft;
  4043. 						} else {
  4044. 							var daysLeft = Math.floor(hoursLeft / 24);
  4045. 							hoursLeft = hoursLeft - (daysLeft * 24);
  4046. 							minutesLeft = timeLeft - (hoursLeft * 60) - (daysLeft * 1440);
  4047. 							aRow.cells[5].firstChild.innerHTML = daysLeft + "d " + hoursLeft + "h " + minutesLeft + "m " + secondsLeft;
  4048. 						}
  4049.  
  4050. 					}
  4051.  
  4052. 					winningBidValue = "-";
  4053. 					var bidExistsOnItem = false;
  4054. 					var playerListedItem = false;
  4055. 					if (aRow.cells[1].innerHTML != '<font size="1">Auction House</font>') {
  4056. 						var sellerElement = aRow.cells[1].firstChild.firstChild;
  4057. 						sellerHref = sellerElement.getAttribute("href");
  4058. 						var sellerIDRE = /player_id=(\d+)/;
  4059. 						var sellerID = sellerIDRE.exec(sellerHref)[1];
  4060. 						if (playerId == sellerID) {
  4061. 							playerListedItem = true;
  4062. 						}
  4063. 					}
  4064. 					if (aRow.cells[3].innerHTML != '<font size="1">-</font>') {
  4065. 						var winningBidTable = aRow.cells[3].firstChild.firstChild;
  4066. 						var winningBidCell = winningBidTable.rows[0].cells[0];
  4067. 						var winningBidderCell = winningBidTable.rows[1].cells[0].firstChild.nextSibling;
  4068. 						var winningBidder = winningBidderCell.innerHTML;
  4069. 						if (memberNameString.search(winningBidder) !=-1) {
  4070. 							winningBidderCell.style.color="green";
  4071. 						}
  4072. 						if (listOfEnemies.search(winningBidder) !=-1) {
  4073. 							winningBidderCell.style.color="red";
  4074. 						}
  4075. 						if (listOfAllies.search(winningBidder) !=-1) {
  4076. 							winningBidderCell.style.color="blue";
  4077. 						}
  4078. 						var isGold = winningBidTable.rows[0].cells[1].firstChild.getAttribute("title")=="Gold";
  4079. 						var winningBidValue = System.intValue(winningBidCell.textContent);
  4080. 						newRow = winningBidTable.insertRow(2);
  4081. 						winningBidBuyoutCell = newRow.insertCell(0);
  4082. 						winningBidBuyoutCell.colSpan = "2";
  4083. 						winningBidBuyoutCell.align = "center";
  4084. 						var winningBidderHTML = winningBidTable.rows[1].cells[0].innerHTML;
  4085. 						var winningBidderIDRE = /player_id=(\d+)/;
  4086. 						var winningBidderID = winningBidderIDRE.exec(winningBidderHTML)[1];
  4087. 						if (playerId == winningBidderID) {
  4088. 							playerListedItem = true;
  4089. 						}
  4090. 					}
  4091.  
  4092. 					if (!bidExistsOnItem && !playerListedItem) 
  4093. 					{
  4094. 						var bidValueButton = aRow.cells[6].getElementsByTagName("input");
  4095. 						if (winningBidValue != "-")
  4096. 						{
  4097. 							var overBid = isGold?Math.ceil(winningBidValue * 1.05):(winningBidValue+1);
  4098. 							winningBidBuyoutCell.innerHTML = '<span style="color:blue;" title="Overbid value">Overbid ' + System.addCommas(overBid) + '</span>&nbsp';
  4099. 							bidValueButton[0].value = overBid;
  4100. 						}
  4101. 						else
  4102. 						{
  4103. 							var minBid = System.intValue(aRow.cells[4].firstChild.firstChild.firstChild.firstChild.firstChild.textContent);
  4104. 							bidValueButton[0].value = minBid;
  4105. 						}
  4106. 					}
  4107.  
  4108. 					var inputTableCell;
  4109. 					if (!playerListedItem) {
  4110. 						var inputTable = aRow.cells[6].firstChild.firstChild;
  4111. 						var inputCell = inputTable.rows[0].cells[0];
  4112. 						var textInput = inputCell.firstChild;
  4113. 						textInput.id = 'auction' + i + 'text';
  4114. 						var bidCell = inputTable.rows[0].cells[1];
  4115. 						bidCell.align = "right";
  4116. 						//spacer row
  4117. 						newRow = inputTable.insertRow(1);
  4118. 						inputTableCell = newRow.insertCell(0);
  4119. 						inputTableCell.colSpan = "2";
  4120. 						inputTableCell.height = "2";
  4121. 						//get itemID for bid no refresh
  4122. 						var itemIMG = aRow.cells[0].firstChild;
  4123. 						var itemStats = /ajaxLoadItem\((\d+), (\d+), (\d+), (\d+)/.exec(itemIMG.getAttribute("onmouseover"));
  4124. 						invID = itemStats[2];
  4125. 						//new bid no refresh button
  4126. 						newRow = inputTable.insertRow(2);
  4127. 						inputTableCell = newRow.insertCell(0);
  4128. 						inputTableCell.colSpan = "2";
  4129. 						inputTableCell.align = "center";
  4130. 						inputTableCell.innerHTML = '<span id="auction' + i + 'text">'+
  4131. 							'<input id="bidNoRefresh" invID="'+ invID +
  4132. 								'" linkto="auction' + i + 'text" value="Bid no Refresh" class="custombutton" type="submit"></span>';
  4133. 					}
  4134. 					var inputText = aRow.cells[6];
  4135. 				}
  4136. 			}
  4137. 		}
  4138. 		bidNoRefreshList = System.findNodes("//input[@id='bidNoRefresh']");
  4139. 		if (bidNoRefreshList) {
  4140. 			for (i=0; i<bidNoRefreshList.length; i++) {
  4141. 				var bidNoRefreshItem = bidNoRefreshList[i];
  4142. 				bidNoRefreshItem.addEventListener('click', Helper.bidNoRefresh, true);
  4143. 			}
  4144. 		}
  4145.  
  4146. 		var searchPrefs = System.findNode("//a[contains(@href, 'cmd=auctionhouse&subcmd=preferences')]");
  4147. 		var preparePreferences = System.findNode("//a[contains(@href, 'cmd=auctionhouse&subcmd=preferences')]/../../../..");
  4148. 		searchPrefs.setAttribute("href", "#prefs");
  4149.  
  4150. 		newRow = document.createElement("TR");
  4151. 		newCell = newRow.insertCell(0);
  4152. 		newCell.setAttribute("colspan", 5);
  4153.  
  4154. 		newCell.innerHTML = '<div id="Helper:AuctionHousePreferences" style="font-size:xx-small;text-align:right;visibility:hidden;display:none;">' +
  4155. 			'<form onsubmit="return false;">' +
  4156. 			'&nbsp;Min: <input type=text size=3 style="font-size:xx-small" class=custominput name=pref_minlevel value="wait" />' +
  4157. 			'&nbsp;Max: <input type=text size=3 style="font-size:xx-small" class=custominput name=pref_maxlevel value="wait" />' +
  4158. 			'&nbsp;Gold: <input type=checkbox style="font-size:xx-small" class=custominput name=pref_hidegold value="1" />' +
  4159. 			'&nbsp;FSP: <input type=checkbox style="font-size:xx-small" class=custominput name=pref_hidefsp value="1" />' +
  4160. 			'<input type=submit class=custombutton id="Helper:AuctionHouseSavePreferences" value="Save" /></form>'+
  4161. 			'<div style="font-size:x-small"><a href="index.php?cmd=notepad&subcmd=quickahpreftemplate">Template</a>:&nbsp;<span id=Helper:AHquickPref></span>' +
  4162. 			'</div></div>';
  4163.  
  4164. 		// preparePreferences.appendChild(prefArea);
  4165. 		preparePreferences.appendChild(newRow);
  4166.  
  4167. 		searchPrefs.addEventListener("click", Helper.auctionHouseTogglePreferences, true);
  4168. 		document.getElementById("Helper:AuctionHouseSavePreferences").addEventListener("click", Helper.auctionHouseSavePreferences, true);
  4169. 		// document.getElementById("Helper:QuickSearch").addEventListener("click", Helper.auctionHouseQuickSearch, true);
  4170.  
  4171. 		//litte something to default to sorting by min bid
  4172. 		var hiddenOrderByInput = System.findNode("//input[@name='order_by']");
  4173. 		hiddenOrderByInput.value = 1;
  4174.  
  4175. 		Helper.injectAuctionQuickCancel();
  4176. 		Helper.injectAuctionQuickPreference();
  4177. 	},
  4178.  
  4179. 	injectAuctionQuickPreference: function() {
  4180. 		Helper.qAHPref=System.getValueJSON("quickAHPref");
  4181. 		if (!Helper.qAHPref || Helper.qAHPref.length<=0) {return;}
  4182.  
  4183. 		var injectHere = document.getElementById("Helper:AHquickPref");
  4184. 		for (var i=0; i<Helper.qAHPref.length; i++) {
  4185. 			injectHere.innerHTML+="[ <span id=qAHPref"+i+" prefId="+i+">"+Helper.qAHPref[i].name+"</span> ] ";
  4186. 		}
  4187. 		for (i=0; i<Helper.qAHPref.length; i++) {
  4188. 			document.getElementById("qAHPref"+i).addEventListener("click", Helper.changeAuctionQuickPreference, true);
  4189. 		}
  4190. 	},
  4191.  
  4192. 	changeAuctionQuickPreference: function(evt) {
  4193. 		var pref=Helper.qAHPref[evt.target.getAttribute("prefId")];
  4194. 		System.findNode("//input[@name='pref_minlevel']").value=pref.min;
  4195. 		System.findNode("//input[@name='pref_maxlevel']").value=pref.max;
  4196. 		System.findNode("//input[@name='pref_hidegold']").checked=pref.gold;
  4197. 		System.findNode("//input[@name='pref_hidefsp']").checked=pref.fsp;
  4198. 		Helper.auctionHouseSavePreferences();
  4199. 	},
  4200.  
  4201. 	injectAHPrefTemplate: function() {
  4202. 		Layout.notebookContent().innerHTML=Helper.makePageTemplate('Quick TH Preference Template','','','','qTHPrefTempId');
  4203.  
  4204. 		// global parameters for the meta function generateManageTable
  4205. 		Helper.param={};
  4206. 		Helper.param={'id':'qTHPrefTempId',
  4207. 			'headers':["Name","Min","Max","Credit","FC"],
  4208. 			'fields':["name","min","max","gold","fsp"],
  4209. 			'tags':["textbox","textbox","textbox","checkbox","checkbox"],
  4210. 			'currentItems':System.getValueJSON("quickAHPref"),
  4211. 			'gmname':"quickAHPref"};
  4212. 		Helper.generateManageTable();
  4213. 	},
  4214.  
  4215. 	generateManageTable: function() {
  4216. 		GM_addStyle('.HelperTextLink {color:blue;font-size:x-small;cursor:pointer;}\n' +
  4217. 			'.HelperTextLink:hover {text-decoration:underline;}\n');
  4218. 		var i, j, result='<table cellspacing=2 cellpadding=2 width=100%><tr bgcolor=#CD9E4B>';
  4219. 		var isArrayOnly=(Helper.param.fields.length===0);
  4220. 		for (i=0;i<Helper.param.headers.length;i++)
  4221. 			result+='<th>'+Helper.param.headers[i]+'</th>';
  4222. 		result+='<th>Action</th></tr>';
  4223. 		var currentCategory = "";
  4224. 		for (i=0;i<Helper.param.currentItems.length;i++) {
  4225. 			result+="<tr>";
  4226. 			if (isArrayOnly) {
  4227. 				result+='<td align=center>'+Helper.param.currentItems[i]+'</td>';
  4228. 			} else {
  4229. 				if (Helper.param.categoryField && currentCategory != Helper.param.currentItems[i][Helper.param.categoryField]) {
  4230. 					currentCategory = Helper.param.currentItems[i][Helper.param.categoryField];
  4231. 					result += "<td><span style='font-weight:bold; font-size:large;'>" + currentCategory + "</span></td></tr><tr>";
  4232. 				}
  4233. 				for (j=0;j<Helper.param.fields.length;j++) {
  4234. 					result+='<td align=center>';
  4235. 					if (Helper.param.fields[j]!=Helper.param.categoryField){
  4236. 						if (Helper.param.tags[j]=="checkbox"){
  4237. 							result+="<input type=checkbox "+(Helper.param.currentItems[i][Helper.param.fields[j]]?'checked':'')+" disabled>";
  4238. 						} else {
  4239. 							if (Helper.param.url && Helper.param.url[j] !== ''){
  4240. 								result+="<a href='"+Helper.param.url[j].replace("@replaceme@",Helper.param.currentItems[i][Helper.param.fields[j]])+"'>"+
  4241. 									Helper.param.currentItems[i][Helper.param.fields[j]]+"</a>";
  4242. 							} else {
  4243. 								result+=Helper.param.currentItems[i][Helper.param.fields[j]];
  4244. 							}
  4245. 						}
  4246. 					result+='</td>';
  4247. 					}
  4248. 				}
  4249. 			}
  4250. 			result+='<td><span class=HelperTextLink itemId="' + i + '" id="Helper:DeleteItem' + i + '">[Del]</span></td></tr>';
  4251. 		}
  4252. 		result+='<tr>';
  4253. 		if (isArrayOnly){
  4254. 			result+='<td align=center><input type='+Helper.param.tags[i]+' class=custominput id=Helper:input0></td>';
  4255. 		}
  4256. 		else {
  4257. 			for (i=0;i<Helper.param.tags.length;i++){
  4258. 				result+='<td align=center><input type='+Helper.param.tags[i]+' class=custominput id=Helper:input'+Helper.param.fields[i]+'></td>';
  4259. 			}
  4260. 		}
  4261. 		result+='<td><span class=HelperTextLink id="Helper:AddItem">[Add]</span></td></tr></table>';
  4262.  
  4263. 		if (Helper.param.showRawEditor) {
  4264. 			result+="<table width=100%><tr><td align=center><textarea cols=70 rows=20 name='Helper:rawEditor'>" +
  4265. 				JSON.stringify(Helper.param.currentItems) + "</textarea></td></tr>"+
  4266. 				"<tr><td align=center><input id='Helper:saveRawEditor' type='button' value='Save' class='custombutton'>"+
  4267. 				"&nbsp;<input id='Helper:resetRawEditor' type='button' value='Reset' class='custombutton'></td></tr>"+
  4268. 				"</tbody></table>";
  4269. 		}
  4270.  
  4271. 		document.getElementById(Helper.param.id).innerHTML = result;
  4272. 		for (i=0;i<Helper.param.currentItems.length;i++)
  4273. 			document.getElementById("Helper:DeleteItem" + i).addEventListener('click', Helper.deleteQuickItem, true);
  4274. 		document.getElementById("Helper:AddItem").addEventListener('click', Helper.addQuickItem, true);
  4275. 		if (Helper.param.showRawEditor) {
  4276. 			document.getElementById("Helper:saveRawEditor").addEventListener('click', Helper.saveRawEditor, true);
  4277. 			document.getElementById("Helper:resetRawEditor").addEventListener('click', Helper.resetRawEditor, true);
  4278. 		}
  4279.  
  4280. 		System.setValueJSON(Helper.param.gmname, Helper.param.currentItems);
  4281. 	},
  4282.  
  4283. 	deleteQuickItem: function(evt) {
  4284. 		// if (!window.confirm('Are you sure you want to delete this link?')) {return;}
  4285. 		var itemId = evt.target.getAttribute("itemId");
  4286. 		Helper.param.currentItems.splice(itemId, 1);
  4287. 		Helper.generateManageTable();
  4288. 	},
  4289.  
  4290. 	addQuickItem: function(evt) {
  4291. 		var isArrayOnly=(Helper.param.fields.length===0);
  4292. 		var newItem={};
  4293. 		if (isArrayOnly) {
  4294. 			newItem=document.getElementById("Helper:input0").value;
  4295. 		} else {
  4296. 			for (var i=0;i<Helper.param.fields.length;i++){
  4297. 				if (Helper.param.tags[i]=="checkbox")
  4298. 					newItem[Helper.param.fields[i]]=document.getElementById("Helper:input"+Helper.param.fields[i]).checked;
  4299. 				else
  4300. 					newItem[Helper.param.fields[i]]=document.getElementById("Helper:input"+Helper.param.fields[i]).value;
  4301. 			}
  4302. 		}
  4303. 		Helper.param.currentItems.push(newItem);
  4304. 		if (Helper.param.sortField) {
  4305. 			Helper.sortAsc=true;
  4306. 			Helper.sortBy=Helper.param.sortField;
  4307. 			Helper.param.currentItems.sort(Helper.stringSort);
  4308. 		}
  4309. 		Helper.generateManageTable();
  4310. 	},
  4311.  
  4312. 	saveRawEditor: function(evt) {
  4313. 		Helper.param.currentItems = JSON.parse(System.findNode("//textarea[@name='Helper:rawEditor']").value);
  4314. 		if (Helper.param.sortField) {
  4315. 			Helper.sortAsc=true;
  4316. 			Helper.sortBy=Helper.param.sortField;
  4317. 			Helper.param.currentItems.sort(Helper.stringSort);
  4318. 		}
  4319. 		Helper.generateManageTable();
  4320. 	},
  4321.  
  4322. 	resetRawEditor: function(evt) {
  4323. 		if (location.search == '?cmd=notepad&subcmd=auctionsearch') {
  4324. 			Helper.param.currentItems = Data.quickSearchList();
  4325. 		}
  4326. 		else Helper.param.currentItems=[];
  4327. 		Helper.generateManageTable();
  4328. 	},
  4329.  
  4330. 	bidNoRefresh: function(evt) {
  4331. 		var inputValue = System.findNode("//input[@id='" + evt.target.getAttribute("linkto") + "']");
  4332. 		var invID = evt.target.getAttribute("invID");
  4333. 		var postData = "cmd=auctionhouse&subcmd=placebid" +
  4334. 				"&auction_id=" + invID +
  4335. 				"&page=" +
  4336. 				"&type=-1" +
  4337. 				"&bid=" + inputValue.value;
  4338.  
  4339. 		GM_xmlhttpRequest({
  4340. 			method: 'POST',
  4341. 			url: System.server + "index.php",
  4342. 			headers: {
  4343. 				"User-Agent" : navigator.userAgent,
  4344. 				"Referer": System.server + "index.php?cmd=auctionhouse&subcmd=type=-1",
  4345. 				"Cookie" : document.cookie,
  4346. 				"Content-Type": "application/x-www-form-urlencoded"
  4347. 			},
  4348. 			data: postData,
  4349. 			onload: function(responseDetails) {
  4350. 				var info = Layout.infoBox(responseDetails.responseText);
  4351. 				var infoElement = evt.target.parentNode;
  4352. 				if (info.search("Bid placed successfully!") != -1) {
  4353. 					infoElement.innerHTML = " <span style='color:green; font-weight:bold;'>" + info + "</span>";
  4354. 				} else {
  4355. 					infoElement.innerHTML = " <span style='color:red; font-weight:bold;'>" + info + "</span>";
  4356. 				}
  4357. 			}
  4358. 		});
  4359. 	},
  4360.  
  4361. 	auctionHouseTogglePreferences: function(evt) {
  4362. 		var prefArea = document.getElementById("Helper:AuctionHousePreferences");
  4363. 		if (prefArea.style.display!="none") {
  4364. 			prefArea.style.visibility="hidden";
  4365. 			prefArea.style.display="none";
  4366. 		} else {
  4367. 			prefArea.style.visibility="visible";
  4368. 			prefArea.style.display="block";
  4369. 		}
  4370. 		if (prefArea.getAttribute("populated")!="done") {
  4371. 			System.xmlhttp('index.php?cmd=auctionhouse&subcmd=preferences', Helper.auctionHouseGetPreferences);
  4372. 		}
  4373. 		return false;
  4374. 	},
  4375.  
  4376. 	auctionHouseGetPreferences: function(responseText) {
  4377. 		var doc=System.createDocument(responseText);
  4378. 		var minLevel = System.findNode("//input[@name='pref_minlevel']", doc).value;
  4379. 		var maxLevel = System.findNode("//input[@name='pref_maxlevel']", doc).value;
  4380. 		var hideGold = System.findNode("//input[@name='pref_hidegold']", doc).checked;
  4381. 		var hideFsp = System.findNode("//input[@name='pref_hidefsp']", doc).checked;
  4382. 		var prefArea = document.createElement("DIV");
  4383.  
  4384. 		System.findNode("//input[@name='pref_minlevel']").value   = minLevel;
  4385. 		System.findNode("//input[@name='pref_maxlevel']").value   = maxLevel;
  4386. 		System.findNode("//input[@name='pref_hidegold']").checked = hideGold;
  4387. 		System.findNode("//input[@name='pref_hidefsp']").checked   = hideFsp;
  4388. 		document.getElementById("Helper:AuctionHousePreferences").setAttribute("populated", "done");
  4389. 	},
  4390.  
  4391. 	auctionHouseSavePreferences: function(evt) {
  4392. 		var minLevel = System.findNode("//input[@name='pref_minlevel']").value;
  4393. 		var maxLevel = System.findNode("//input[@name='pref_maxlevel']").value;
  4394. 		var hideGold = System.findNode("//input[@name='pref_hidegold']").checked;
  4395. 		var hideFsp = System.findNode("//input[@name='pref_hidefsp']").checked;
  4396.  
  4397. 		var submitButton=document.getElementById("Helper:AuctionHouseSavePreferences");
  4398. 		submitButton.disabled=true;
  4399. 		submitButton.value="Saving...";
  4400.  
  4401. 		var postData = "cmd=auctionhouse&subcmd=savepreferences" +
  4402. 				"&pref_minlevel=" + minLevel +
  4403. 				"&pref_maxlevel=" + maxLevel +
  4404. 				(hideGold?"&pref_hidegold=1":"") +
  4405. 				(hideFsp?"&pref_hidefsp=1":"");
  4406.  
  4407. 		GM_xmlhttpRequest({
  4408. 			method: 'POST',
  4409. 			url: System.server + "index.php",
  4410. 			headers: {
  4411. 				"User-Agent" : navigator.userAgent,
  4412. 				"Referer": System.server + "index.php?cmd=auctionhouse&subcmd=preferences",
  4413. 				"Cookie" : document.cookie,
  4414. 				"Content-Type": "application/x-www-form-urlencoded"
  4415. 			},
  4416. 			data: postData,
  4417. 			onload: function(responseDetails) {
  4418. 				Helper.auctionHouseSavePreferencesDone(responseDetails.responseText);
  4419. 			}
  4420. 		});
  4421. 	},
  4422.  
  4423. 	auctionHouseSavePreferencesDone: function(responseText) {
  4424. 		var submitButton=document.getElementById("Helper:AuctionHouseSavePreferences");
  4425. 		submitButton.disabled=false;
  4426. 		submitButton.value="Save";
  4427. 		submitButton.blur();
  4428. 	},
  4429.  
  4430. 	injectAuctionExtraText: function(anItem, itemName, craft, forgeCount, durability) {
  4431. 		var theText=anItem.parentNode.nextSibling.nextSibling;
  4432. 		//Excellent color does not show up well so change Perfect to Green and Excellent takes the yellow color
  4433. 		// to show up better in the AH.
  4434. 		craft = craft.replace(/\#F6ED00/,"#00B600");
  4435. 		craft = craft.replace(/\#F6AE00/,"#F6ED00");
  4436. 		var preText = "<span style='color:blue'>" + craft + "</span>";
  4437. 		if (forgeCount !== 0) {
  4438. 			preText +=  " " + forgeCount + "<img src='" + System.imageServerHTTP + "/hellforge/forgelevel.gif'>";
  4439. 		}
  4440. 		if (durability) preText += durability;
  4441. 		theText.innerHTML = preText + "<br>" + theText.innerHTML;
  4442. 	},
  4443.  
  4444. 	toggleShowExtraLinks: function(evt) {
  4445. 		var showExtraLinksElement = System.findNode("//span[@id='Helper:showExtraLinks']");
  4446. 		if (showExtraLinksElement.textContent == "Show AH and Sell links") {
  4447. 			GM_setValue("showExtraLinks", true);
  4448. 		} else {
  4449. 			GM_setValue("showExtraLinks", false);
  4450. 		}
  4451. 		window.location = window.location;
  4452. 	},
  4453.  
  4454. 	toggleShowQuickDropLinks: function(evt) {
  4455. 		var showQuickDropLinksElement = System.findNode("//span[@id='Helper:showQuickDropLinks']");
  4456. 		if (showQuickDropLinksElement.textContent == "Show Quick Drop links") {
  4457. 			if (window.confirm("Are you sure you want to show the quick drop links?")) GM_setValue("showQuickDropLinks", true);
  4458. 		} else {
  4459. 			GM_setValue("showQuickDropLinks", false);
  4460. 		}
  4461. 		window.location = window.location;
  4462. 	},
  4463.  
  4464. 	injectReportPaint: function() {
  4465. 		var mainTable = System.findNode("//table[@width='600']");
  4466. 		var searchItemRE = /&item=(.*)$/;
  4467. 		var searchSetRE = /&set=(.*)$/;
  4468. 		var searchUserRE = /&user=(.*)$/;
  4469. 		var searchItem = searchItemRE.exec(location);
  4470. 		var searchSet = searchSetRE.exec(location);
  4471. 		var searchUser = searchUserRE.exec(location);
  4472. 		if (searchItem) searchItem = unescape(searchItem[1]);
  4473. 		if (searchSet) {
  4474. 			searchItem = unescape(searchSet[1]);
  4475. 			searchItem=(searchItem.indexOf(' of ')>0)?
  4476. 				searchItem.replace(/^.* of /,''):(searchItem.replace(/ .*$/ig,'')+' ');
  4477. 		}
  4478. 		if (searchUser) searchUser = unescape(searchUser[1]);
  4479. 		var isUser=false, startRow=0, stopRow=mainTable.rows.length, j;
  4480. 		if (searchUser) {
  4481. 			for (var i=0;i<mainTable.rows.length;i++) {
  4482. 				var aRow = mainTable.rows[i];
  4483. 				if (!(aRow.cells[2])) {
  4484. 					if (isUser) stopRow=i;
  4485. 					isUser=(aRow.textContent.replace(/\s*/g,'')==searchUser);
  4486. 					if (isUser) startRow=i;
  4487. 				}
  4488. 			}
  4489. 			var len=mainTable.rows.length;
  4490. 			for (i=0;i<startRow;i++) mainTable.deleteRow(0);
  4491. 			for (i=0;i<len-stopRow;i++) mainTable.deleteRow(stopRow-startRow);
  4492. 		}
  4493. 		if (searchItem) var searchItemArr = searchItem.split('|');
  4494. 		for (i=mainTable.rows.length-1;i>=0;i--) {
  4495. 			aRow = mainTable.rows[i];
  4496. 			if (aRow.cells[2]) { // itemRow
  4497. 				var itemCell = aRow.cells[1];
  4498. 				if (searchItem) {
  4499. 					for (j=0; j<searchItemArr.length; j++) {
  4500. 						if (itemCell.textContent.indexOf(searchItemArr[j].trim())>=0) break;
  4501. 					}
  4502. 					if (j==searchItemArr.length) {
  4503. 						mainTable.deleteRow(i);
  4504. 						continue;
  4505. 					}
  4506. 				}
  4507. 				var recallCell = aRow.cells[2];
  4508. 				var recallToBackpack = "";
  4509. 				if (recallCell.firstChild.nextSibling.innerHTML == 'Backpack') {
  4510. 					recallToBackpack = recallCell.firstChild.nextSibling;
  4511. 					var recallToBackpackHREF = recallToBackpack.getAttribute('href');
  4512. 					var recallToGuildStore = recallToBackpack.nextSibling.nextSibling;
  4513. 					var recallToGuildStoreHREF = recallToGuildStore.getAttribute('href');
  4514. 				} else {
  4515. 					recallToGuildStore = recallCell.firstChild.nextSibling;
  4516. 					recallToGuildStoreHREF = recallToGuildStore.getAttribute('href');
  4517. 				}
  4518. 				if (recallToBackpack) {
  4519. 					recallCell.innerHTML = '<nobr>' + recallCell.innerHTML +
  4520. 						'&nbsp;<span style="cursor:pointer; text-decoration:underline; color:blue;" href="' + recallToBackpackHREF + '">Fast BP</span> |'+
  4521. 						'&nbsp;<span style="cursor:pointer; text-decoration:underline; color:blue;" href="' + recallToGuildStoreHREF + '">Fast GS</span> |'+
  4522. 						'&nbsp;<span style="cursor:pointer; text-decoration:underline; color:blue;" href="' + recallToBackpackHREF + '">Fast Wear</span></nobr>';
  4523. 					var fastBPSpan = recallCell.firstChild.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.nextSibling;
  4524. 					fastBPSpan.addEventListener('click', Helper.recallItem, true);
  4525. 					var fastGSSpan = fastBPSpan.nextSibling.nextSibling;
  4526. 					fastGSSpan.addEventListener('click', Helper.recallItem, true);
  4527. 					var fastWearSpan = fastGSSpan.nextSibling.nextSibling;
  4528. 					fastWearSpan.addEventListener('click', Helper.recallItemNWear, true);
  4529. 				} else {
  4530. 					recallCell.innerHTML = '<nobr>' + recallCell.innerHTML +
  4531. 						'&nbsp;<span style="cursor:pointer; text-decoration:underline; color:blue;" href="' + recallToGuildStoreHREF + '">Fast GS</span></nobr>';
  4532. 					fastGSSpan = recallCell.firstChild.firstChild.nextSibling.nextSibling.nextSibling;
  4533. 					fastGSSpan.addEventListener('click', Helper.recallItem, true);
  4534. 				}
  4535. 			}
  4536. 		}
  4537.  
  4538. 		//Get the list of online members
  4539. 		var memberList = System.getValueJSON("memberlist");
  4540.  
  4541. 		var injectHere, searchString;
  4542. 		if (memberList) {
  4543. 			for (i=0;i<memberList.members.length;i++) {
  4544. 				var member=memberList.members[i];
  4545. 				if (member.status=="Online") {
  4546. 					var player=System.findNode("//b[contains(., '" + member.name + "')]");
  4547. 					if (player) {
  4548. 						player.innerHTML = "<span style='font-size:large; color:green;'>[Online]</span> <a href='" +
  4549. 							System.server + "index.php?cmd=profile&player_id=" + member.id + "'>" + player.innerHTML + "</a>";
  4550. 						player.innerHTML += " [ <a href='index.php?cmd=message&target_player=" + member.name + ">m</a> ]";
  4551. 					}
  4552. 				}
  4553. 				else {
  4554. 					player=System.findNode("//b[contains(., '" + member.name + "')]");
  4555. 					if (player) {
  4556. 						player.innerHTML = "<a href='" +
  4557. 							System.server + "index.php?cmd=profile&player_id=" + member.id + "'>" + player.innerHTML + "</a>";
  4558. 					}
  4559. 				}
  4560. 			}
  4561. 		}
  4562. 	},
  4563.  
  4564. 	recallItem: function(evt) {
  4565. 		var href=evt.target.getAttribute("href");
  4566. 		System.xmlhttp(href, Helper.recallItemReturnMessage, {"target": evt.target, "url": href});
  4567. 	},
  4568.  
  4569. 	recallItemReturnMessage: function(responseText, callback) {
  4570. 		var target = callback.target;
  4571. 		var info = Layout.infoBox(responseText);
  4572. 		var itemCellElement = target.parentNode;
  4573. 		if (info.search("You successfully recalled the item") != -1) {
  4574. 			itemCellElement.innerHTML = "<span style='color:green; font-weight:bold;'>" + info + "</span>";
  4575. 		} else if (info!=="") {
  4576. 			itemCellElement.innerHTML = "<span style='color:red; font-weight:bold;'>" + info + "</span>";
  4577. 		} else {
  4578. 			itemCellElement.innerHTML = "<span style='color:red; font-weight:bold;'>Weird Error: check the Tools>Error Console</span>";
  4579. 			GM_log("Post the previous HTML and the following message to the code.google.com site or to the forum to help us debug this error");
  4580. 			GM_log(callback.url);
  4581. 		}
  4582. 	},
  4583.  
  4584. 	recallItemNWear: function(evt) {
  4585. 		var href=evt.target.getAttribute("href");
  4586. 		System.xmlhttp(href, Helper.recallItemNWearReturnMessage, {"target": evt.target, "url": href});
  4587. 	},
  4588. 	recallItemNWearReturnMessage: function(responseText, callback) {
  4589. 		var target = callback.target;
  4590. 		var info = Layout.infoBox(responseText);
  4591. 		var itemCellElement = target.parentNode;
  4592. 		if (info.search("You successfully") != -1) {
  4593. 			itemCellElement.innerHTML = "<span style='color:green; font-weight:bold;'>Taken</span>";
  4594. 			System.xmlhttp(System.server+'?cmd=trade', Helper.wearRecall, itemCellElement);
  4595. 		} else if (info!=="") {
  4596. 			itemCellElement.innerHTML = "<span style='color:red; font-weight:bold;'>Error</span>";
  4597. 		}
  4598. 	},
  4599. 	wearRecall: function(responseText, callback) {
  4600. 		var doc=System.createDocument(responseText);
  4601. 		var items=System.findNodes('//input[@name="sendItemList[]"]',doc);
  4602. 		if (items) {
  4603. 			var itemId=items[items.length-1].getAttribute('value');
  4604. 			System.xmlhttp(System.server+'?cmd=profile&subcmd=equipitem&inventory_id='+itemId+'&folder_id=0&backpack_page=0',
  4605. 				function(responseText) {
  4606. 					var info = Layout.infoBox(responseText);
  4607. 					if (info==="")
  4608. 						callback.innerHTML += "<br><span style='color:green; font-weight:bold;'>Worn</span>";
  4609. 					else
  4610. 						callback.innerHTML += "<br><span style='color:red; font-weight:bold;'>" + info + "</span>";
  4611. 				});
  4612. 		}
  4613. 	},
  4614.  
  4615. 	injectGuildAddTagsWidgets: function() {
  4616. 		var mainTable = System.findNode("//table[@width='600']");
  4617. 		var itemTable = mainTable.rows[6].cells[0].firstChild.nextSibling;
  4618. 		for (var i=0;i<itemTable.rows.length;i++) {
  4619. 			var aRow = itemTable.rows[i];
  4620. 			if (aRow.cells[2]) { // itemRow
  4621. 				itemId = aRow.cells[0].firstChild.getAttribute("value");
  4622. 				aRow.cells[2].innerHTML += '&nbsp;<span style="cursor:pointer; text-decoration:underline; color:blue;" itemID="' + itemId + '">Fast BP</span>';
  4623. 				itemRecall = aRow.cells[2].firstChild.nextSibling;
  4624. 				itemRecall.addEventListener('click', Helper.recallGuildStoreItem, true);
  4625. 			}
  4626. 		}
  4627. 	},
  4628.  
  4629. 	changeCombatSet: function(responseText, itemIndex) {
  4630. 		var doc=System.createDocument(responseText);
  4631.  
  4632. 		var cbsSelect = System.findNode("//select[@name='combatSetId']", doc);
  4633.  
  4634. 		// find the combat set id value
  4635. 		var allItems = cbsSelect.getElementsByTagName("option");
  4636. 		if (itemIndex >= allItems.length) {return;}
  4637. 		var cbsIndex = allItems[itemIndex].value;
  4638.  
  4639. 		GM_xmlhttpRequest({
  4640. 			method: 'POST',
  4641. 			url: System.server + "index.php",
  4642. 			headers: {
  4643. 				"User-Agent" : navigator.userAgent,
  4644. 				"Content-Type": "application/x-www-form-urlencoded",
  4645. 				"Referer": System.server + "index.php?cmd=profile",
  4646. 				"Cookie" : document.cookie
  4647. 			},
  4648. 			data: "cmd=profile&subcmd=managecombatset&combatSetId="+cbsIndex+"&submit=Use",
  4649. 			onload: function() {
  4650. 				window.location="index.php?cmd=profile";
  4651. 			}
  4652. 		});
  4653. 	},
  4654.  
  4655. 	injectDropItems: function() {
  4656.  
  4657. 		var subPage2Id=System.findNode("//input[@type='hidden' and @name='subcmd2']");
  4658. 		subPage2Id=subPage2Id?subPage2Id.getAttribute("value"):"-";
  4659.  
  4660. 		var mainTable = System.findNode("//table[@width='600']");
  4661. 		var showExtraLinks = GM_getValue("showExtraLinks");
  4662. 		var showQuickDropLinks = GM_getValue("showQuickDropLinks");
  4663. 		var showQuickSendLinks = GM_getValue("showQuickSendLinks");
  4664. 		if (mainTable) {
  4665. 			var insertHere = mainTable.rows[5].cells[0];
  4666. 			insertHere.innerHTML += '[<span style="cursor:pointer; text-decoration:underline; color:blue;" id="Helper:showExtraLinks">' +
  4667. 				(showExtraLinks?'Hide':'Show') + ' AH and Sell links</span>]&nbsp;';
  4668. 			insertHere.innerHTML += '[<span style="cursor:pointer; text-decoration:underline; color:blue;" id="Helper:showQuickDropLinks">' +
  4669. 				(showQuickDropLinks?'Hide':'Show') + ' Quick Drop links</span>]&nbsp;';
  4670.  
  4671. 			if (subPage2Id && subPage2Id == "dostoreitems") {
  4672. 				insertHere.innerHTML += '[<span style="cursor:pointer; text-decoration:underline; color:blue;" id="Helper:selectAllGuildLocked">' +
  4673. 					' Select All Guild Locked</span>]&nbsp;';
  4674. 				document.getElementById("Helper:selectAllGuildLocked").addEventListener('click', Helper.selectAllGuildLocked, true);
  4675. 			}
  4676. 			document.getElementById("Helper:showExtraLinks").addEventListener('click', Helper.toggleShowExtraLinks, true);
  4677. 			document.getElementById("Helper:showQuickDropLinks").addEventListener('click', Helper.toggleShowQuickDropLinks, true);
  4678. 		}
  4679.  
  4680. 		//function to add links to all the items in the drop items list
  4681. 		var itemName, itemInvId, theTextNode, newLink;
  4682. 		var allItems=System.findNodes("//input[@type='checkbox']");
  4683. 		if (allItems) {
  4684. 			for (var i=0; i<allItems.length; i++) {
  4685. 				anItem = allItems[i];
  4686. 				itemInvId = anItem.value;
  4687. 				theTextNode = System.findNode("../../td[3]", anItem);
  4688. 				theImgElement = System.findNode("../../td[2]", anItem).firstChild.firstChild;
  4689. 				itemStats = /ajaxLoadItem\((\d+), (\d+), (\d+), (\d+)/.exec(theImgElement.getAttribute("onmouseover"));
  4690. 				if (itemStats) {
  4691. 					itemId = itemStats[1];
  4692. 					invId = itemStats[2];
  4693. 					type = itemStats[3];
  4694. 					pid = itemStats[4];
  4695. 				}
  4696. 				itemName = theTextNode.textContent.trim().replace("\\","");
  4697. 				theTextNode.textContent = itemName;
  4698. 				var findItems = System.findNodes('//td[@width="90%" and contains(.,"'+itemName+'")]');
  4699. 				var preText = "", postText1 = "", postText2 = "", postText3 = "";
  4700. 				if (showExtraLinks) {
  4701. 					preText = "<span findme='AH'>[<a href='" + System.server + "?cmd=auctionhouse&type=-1&order_by=1&search_text=" +
  4702. 						escape(itemName) +
  4703. 						"'>AH</a>]</span> " +
  4704. 						"<span findme='Sell'>[<a href='" + System.server + "index.php?cmd=auctionhouse&subcmd=create2" +
  4705. 						"&inv_id=" + itemInvId  +
  4706. 						"&item_id=" + itemId +
  4707. 						"&type=" + type +
  4708. 						"&pid=" + pid + "'>" +
  4709. 						"Sell</a>]</span> ";
  4710. 				}
  4711. 				postText1 = ((findItems.length>1)?' [<span findme="checkall" linkto="' +
  4712. 					itemName +
  4713. 					'" style="text-decoration:underline;cursor:pointer">Check all</span>]':'');
  4714. 				if (showQuickDropLinks) {
  4715. 					postText2 = "&nbsp;<span  title='INSTANTLY DROP THE ITEM. NO REFUNDS OR DO-OVERS! Use at own risk.' id='Helper:QuickDrop" +
  4716. 						itemInvId +
  4717. 						"' itemInvId=" +
  4718. 						itemInvId +
  4719. 						" findme='QuickDrop' style='color:red; cursor:pointer; text-decoration:underline;'>[Quick Drop]</span> ";
  4720. 				}
  4721. 				if (showQuickSendLinks) {
  4722. 					postText3 = "&nbsp;<span  title='INSTANTLY SENDS THE ITEM. NO REFUNDS OR DO-OVERS! Use at own risk.' id='Helper:QuickSend" +
  4723. 						itemInvId +
  4724. 						"' itemInvId=" +
  4725. 						itemInvId +
  4726. 						" findme='QuickSend' style='color:blue; cursor:pointer; text-decoration:underline;'>[Quick Send]</span> ";
  4727. 				}
  4728.  
  4729. 				theTextNode.innerHTML = preText +
  4730. 					theTextNode.innerHTML +
  4731. 					postText1 +
  4732. 					postText2 +
  4733. 					postText3;
  4734. 				if (showQuickDropLinks) {
  4735. 					document.getElementById("Helper:QuickDrop"+itemInvId).addEventListener('click', Helper.quickDropItem, true);
  4736. 				}
  4737. 				if (showQuickSendLinks) {
  4738. 					document.getElementById("Helper:QuickSend"+itemInvId).addEventListener('click', Helper.quickSendItem, true);
  4739. 				}
  4740. 			}
  4741. 		}
  4742.  
  4743. 		var checkAllElements = System.findNodes("//span[@findme='checkall']");
  4744. 		if (checkAllElements) {
  4745. 			for (i=0; i<checkAllElements.length; i++) {
  4746. 				checkAllElement = checkAllElements[i];
  4747. 				itemName = checkAllElement.linkto;
  4748. 				checkAllElement.addEventListener('click', Helper.checkAll, true);
  4749. 			}
  4750. 		}
  4751.  
  4752. 		allItems = System.findNodes("//input[@type='checkbox']");
  4753. 		if (allItems) {
  4754. 			for (i=0; i<allItems.length; i++) {
  4755. 				anItem = allItems[i];
  4756. 				theLocation=anItem.parentNode.nextSibling.nextSibling;
  4757. 				theImage=anItem.parentNode.nextSibling.firstChild.firstChild;
  4758. 				System.xmlhttp(Helper.linkFromMouseover(theImage.getAttribute("onmouseover")), Helper.injectDropItemsPaint, theImage);
  4759. 			}
  4760. 		}
  4761.  
  4762. 		Helper.addStatTotalToMouseover();
  4763. 	},
  4764.  
  4765. 	injectMoveItems: function() {
  4766. 		var foldersEnabled = System.findNode("//img[contains(@src,'/folder_on.gif')]");
  4767. 		if (! foldersEnabled) {return;}
  4768. 		var otherFolders = System.findNodes("//td/center/a/img[contains(@src,'/folder.gif')]");
  4769. 		if (! otherFolders) {return;}
  4770. 		var cell=foldersEnabled.parentNode.parentNode.parentNode.parentNode.parentNode.insertRow(-1).insertCell(-1);
  4771. 		cell.colSpan = otherFolders.length + 1;
  4772. 		cell.align='center';
  4773. 		cell.noWrap = true;
  4774. 		var newHtml='Move selected items to: <select name=folder id=selectFolderId class=customselect>';
  4775. 		for (var i=0; i<otherFolders.length; i++) {
  4776. 			newHtml+='<option value='+otherFolders[i].parentNode.getAttribute("href").match(/cmd=profile&subcmd=dropitems&folder_id=(-*\d+)/i)[1]+'>'+
  4777. 				otherFolders[i].parentNode.parentNode.textContent+'</option>';
  4778. 		}
  4779. 		newHtml+='</select> <input type=button class=custombutton id="Helper::moveItems" value=Move>';
  4780. 		cell.innerHTML=newHtml;
  4781. 		document.getElementById("Helper::moveItems").addEventListener('click', Helper.moveItemsToFolder, true);
  4782. 	},
  4783.  
  4784. 	moveItemsToFolder: function() {
  4785. 		var itemsList = System.findNodes('//input[@name="removeIndex[]"]');
  4786. 		var selectElem = document.getElementById('selectFolderId');
  4787. 		var postData = 'cmd=profile&subcmd=sendtofolder&folder_id='+selectElem.options[selectElem.selectedIndex].value;
  4788. 		var haveItems = false;
  4789. 		var postItems = '';
  4790. 		var countItems = 0;
  4791. 		for (var i=0; i<itemsList.length; i++) {
  4792. 			if (itemsList[i].checked) {
  4793. 				countItems++;
  4794. 				postItems+='&folderItem[]='+itemsList[i].value;
  4795. 			}
  4796. 			if (countItems == 12 || (countItems > 0 && i == itemsList.length - 1)) {
  4797. 				// multiple posts since HCS only move the first 12 items to other folder
  4798. 				GM_xmlhttpRequest({
  4799. 					method: 'POST',
  4800. 					url: System.server + "index.php",
  4801. 					headers: {
  4802. 						"User-Agent" : navigator.userAgent,
  4803. 						"Content-Type": "application/x-www-form-urlencoded",
  4804. 						"Referer": document.location,
  4805. 						"Cookie" : document.cookie
  4806. 					},
  4807. 					data: postData+postItems
  4808. 				});
  4809. 				countItems = 0;
  4810. 				postItems = '';
  4811. 				haveItems = true;
  4812. 			}
  4813. 		}
  4814. 		if (haveItems)
  4815. 			setTimeout(function() {window.location=window.location;}, 1000);
  4816. 	},
  4817.  
  4818. 	quickDropItem: function(evt){
  4819. 		var itemInvId = evt.target.getAttribute("itemInvId");
  4820. 		var dropItemHref = System.server + "index.php?cmd=profile&subcmd=dodropitems&removeIndex[]=" + itemInvId;
  4821. 		System.xmlhttp(dropItemHref,
  4822. 			Helper.quickDropItemReturnMessage,
  4823. 			{"target": evt.target, "url": dropItemHref});
  4824. 	},
  4825.  
  4826. 	quickDropItemReturnMessage: function(responseText, callback) {
  4827. 		var target = callback.target;
  4828. 		var info = Layout.infoBox(responseText);
  4829. 		target.style.cursor = 'default';
  4830. 		target.style.textDecoration = 'none';
  4831. 		if (info.search("Items dropped and destroyed.") != -1) {
  4832. 			target.style.color = 'green';
  4833. 			target.style.fontWeight = 'bold';
  4834. 			target.style.fontSize = 'small';
  4835. 			target.innerHTML = "Item Dropped";
  4836. 		} else if (info!=="") {
  4837. 			target.style.color = 'red';
  4838. 			target.style.fontWeight = 'bold';
  4839. 			target.style.fontSize = 'small';
  4840. 			target.innerHTML = "Error: " + info;
  4841. 		} else {
  4842. 			target.style.color = 'red';
  4843. 			target.style.fontSize = 'small';
  4844. 			target.innerHTML = "Weird Error: check the Tools>Error Console";
  4845. 			GM_log("Post the previous HTML and the following message to the code.google.com site or to the forum to help us debug this error");
  4846. 			GM_log(callback.url);
  4847. 		}
  4848. 	},
  4849.  
  4850. 	quickSendItem: function(evt){
  4851. 		var itemInvId = evt.target.getAttribute("itemInvId");
  4852. 		var xcNum = GM_getValue("goldConfirm");
  4853. 		var itemRecipient = GM_getValue("itemRecipient");
  4854. 		var sendItemHref = System.server + "index.php?cmd=trade&subcmd=senditems&xc=" + xcNum + "&target_username=" + itemRecipient + "&sendItemList[]=" + itemInvId;
  4855. 		System.xmlhttp(sendItemHref,
  4856. 			Helper.quickSendItemReturnMessage,
  4857. 			{"target": evt.target, "url": sendItemHref});
  4858. 	},
  4859.  
  4860. 	quickSendItemReturnMessage: function(responseText, callback) {
  4861. 		var target = callback.target;
  4862. 		var info = Layout.infoBox(responseText);
  4863. 		var itemRecipient = GM_getValue("itemRecipient");
  4864. 		target.style.cursor = 'default';
  4865. 		target.style.textDecoration = 'none';
  4866. 		if (info==="Items sent successfully!") {
  4867. 			target.style.color = 'green';
  4868. 			target.style.fontWeight = 'bold';
  4869. 			target.style.fontSize = 'small';
  4870. 			target.innerHTML = "Item sent to " + itemRecipient + "!";
  4871. 		} else if (info!=="") {
  4872. 			target.style.color = 'red';
  4873. 			target.style.fontWeight = 'bold';
  4874. 			target.style.fontSize = 'small';
  4875. 			target.innerHTML = "Error: " + info;
  4876. 		} else {
  4877. 			target.style.color = 'red';
  4878. 			target.style.fontSize = 'small';
  4879. 			target.innerHTML = "Weird Error: check the Tools>Error Console";
  4880. 			GM_log("Post the previous HTML and the following message to the code.google.com site or to the forum to help us debug this error");
  4881. 			GM_log(callback.url);
  4882. 		}
  4883. 	},
  4884.  
  4885. 	selectAllGuildLocked: function(evt) {
  4886. 		var allGuildLockedItems = System.findNodes("//span[@id='guildLocked']");
  4887. 		if (allGuildLockedItems) {
  4888. 		for (var i = 0; i < allGuildLockedItems.length; i++) {
  4889. 			var cbNode = System.findNode("../../td/input[@type='checkbox']", allGuildLockedItems[i]);
  4890. 			cbNode.checked = true;
  4891. 		}
  4892. 		}
  4893. 	},
  4894.  
  4895. 	checkAll: function(evt){
  4896. 		var itemName = evt.target.getAttribute("linkto");
  4897. 		var findItems = System.findNodes("//td[@width='90%' and contains(.,'] "+itemName+" [')]");
  4898. 		for (var i=0; i<findItems.length; i++) {
  4899. 			var item = findItems[i];
  4900. 			var checkboxForItem = item.previousSibling.previousSibling.firstChild;
  4901. 			if (checkboxForItem.checked) {
  4902. 				checkboxForItem.checked = false;
  4903. 			} else {
  4904. 				checkboxForItem.checked = true;
  4905. 			}
  4906.  
  4907. 		}
  4908. 	},
  4909.  
  4910. 	injectDropItemsPaint: function(responseText, callback) {
  4911. 		var textNode = System.findNode("../../../td[3]", callback);
  4912. 		var auctionHouseLink=System.findNode("span[@findme='AH']", textNode);
  4913. 		var sellLink=System.findNode("span[@findme='Sell']", textNode);
  4914. 		var quickDropLink=System.findNode("span[@findme='QuickDrop']", textNode);
  4915. 		var guildLockedRE = /<center>Guild Locked: <font color="#00FF00">/i;
  4916.  
  4917. 		if (guildLockedRE.exec(responseText)) {
  4918.  
  4919. 			if (auctionHouseLink) auctionHouseLink.style.visibility='hidden';
  4920. 			if (sellLink) sellLink.style.visibility='hidden';
  4921. 			if (quickDropLink) quickDropLink.style.visibility='hidden';
  4922. 			var cbNode = System.findNode("../../../td[1]",callback);
  4923. 			textNode.innerHTML += '<span id="guildLocked" visibility="hidden"/>';
  4924.  
  4925. 		}
  4926. 		//<font color='cyan'>Bound (Non-Tradable)</font></b> <font color='orange'>Quest Item </font></center>
  4927. 		var boundItemRE = /Bound \(Non-Tradable\)/i;
  4928. 		if (boundItemRE.exec(responseText)) {
  4929. 			if (auctionHouseLink) auctionHouseLink.style.visibility='hidden';
  4930. 			if (sellLink) sellLink.style.visibility='hidden';
  4931. 			if (quickDropLink) quickDropLink.style.visibility='hidden';
  4932. 		}
  4933. 		if (GM_getValue("disableItemColoring")) {return;}
  4934. 		var fontLineRE=/<center><font color='(#[0-9A-F]{6})' size=2>/i;
  4935. 		var fontLineRX=fontLineRE.exec(responseText);
  4936. 		var color=fontLineRX[1];
  4937. 		if (color=="#FFFFFF") {
  4938. 			var fontLineRE2=/<br>\s*<font color='([a-z]+)'>/i;
  4939. 			var fontLineRX2=fontLineRE2.exec(responseText);
  4940. 			if (fontLineRX2) {
  4941. 				color=fontLineRX2[1];
  4942. 			}
  4943. 		}
  4944. 		if (color=="#40FFFF") color="#00A0A0";
  4945. 		if (color=="orange") color="#FF6000";
  4946. 		if (color=="#00FF00") color="#00B000";
  4947. 		textNode.style.color=color;
  4948. 	},
  4949.  
  4950. 	injectProfile: function() {
  4951. 		var player = System.findNode("//textarea[@id='holdtext']");
  4952. 		var avyImg = System.findNode("//img[contains(@title, 's Avatar')]");
  4953. 		if (!avyImg) {return;}
  4954. 		var playeridRE = document.URL.match(/player_id=(\d+)/);
  4955. 		if (playeridRE) var playerid=playeridRE[1];
  4956. 		var idindex;
  4957.  
  4958. 		Helper.profileInjectGuildRel();
  4959. 		if (GM_getValue("enableBioCompressor")) Helper.compressBio();
  4960.  
  4961. 		if (player) {
  4962. 			if (!playerid) {
  4963. 				playerid = player.innerHTML;
  4964. 				idindex = playerid.indexOf("?ref=") + 5;
  4965. 				playerid = playerid.substr(idindex);
  4966. 			}
  4967.  
  4968. 			var playername = avyImg.getAttribute("title");
  4969. 			avyImg.style.borderStyle="none";
  4970. 			playername = playername.substr(0, playername.indexOf("'s Avatar"));
  4971.  
  4972. 			var avyExtrasDiv = document.createElement("DIV");
  4973. 			avyImg.parentNode.appendChild(avyExtrasDiv);
  4974. 			avyExtrasDiv.align = 'center';
  4975. 			Helper.profileInjectQuickButton(avyExtrasDiv, playerid, playername);
  4976. 			Helper.profileRenderBio(playername);
  4977. 			Helper.buffCost={'count':0,'buffs':{}};
  4978.  
  4979. 			Helper.bioAddEventListener();
  4980.  
  4981. 			var quickBuffLink = System.findNode("//a[contains(@href,'index.php?cmd=quickbuff&t=')]");
  4982. 			if (quickBuffLink) quickBuffLink.setAttribute('href', "javascript:openWindow('index.php?cmd=quickbuff&tid=" + playerid + "', 'fsQuickBuff', 618, 1000, ',scrollbars')");
  4983. 		}
  4984.  
  4985. 		//Needs to be fixed ... the link can be fixed as follows, but the underlying code is still broken.
  4986. 		//var tdInv=System.findNode("//div/strong[.='Inventory']/..");
  4987. 		var tdInv=System.findNode("//td/b[.='Inventory']/..");
  4988. 		if (tdInv) {
  4989. 			tdInv.width="50%";
  4990. 			tdInv.innerHTML+=" | <a href='index.php?cmd=notepad&subcmd=checkwear&playerid="+playerid+"'>Check Items</a>";
  4991. 		}
  4992.  
  4993. 		var isSelfRE=/player_id=/.exec(document.location.search);
  4994. 		if (!isSelfRE) { // self inventory
  4995.  
  4996. 			Helper.profileParseAllyEnemy();
  4997. 			Helper.profileInjectFastWear();
  4998. 			Helper.profileComponents();
  4999.  
  5000. 			// quick wear manager link
  5001. 			var node=System.findNode("//span/a[@href='index.php?cmd=profile&subcmd=togglesection&section_id=2']");
  5002. 			if (node) {
  5003. 				node.parentNode.innerHTML+="&nbsp;[<a href='/index.php?cmd=notepad&subcmd=quickwear'><span style='color:blue;'>Quick&nbsp;Wear</span></a>]";
  5004. 			}
  5005. 			//select all link
  5006. 			var node=System.findNode("//span/a[contains(@href,'cmd=profile&subcmd=dropitems')]");
  5007. 			if (node) {
  5008. 				node.parentNode.innerHTML+="&nbsp;<span id='Helper:profileSelectAll' style='cursor:pointer; text-decoration:underline; font-size:x-small; color:blue;'>[All]</span>";
  5009. 				document.getElementById('Helper:profileSelectAll').addEventListener('click', Helper.profileSelectAll, true);
  5010. 			}
  5011. 			if (GM_getValue("showBPSlotsOnProfile") === true) {
  5012. 				System.xmlhttp("index.php?cmd=world", Helper.injectEmptySlots, 0);
  5013. 			}
  5014.  
  5015. 			//Update the ally/enemy online list, since we are already on the page.
  5016. 			doc = System.findNode("//html");
  5017. 			Helper.parseProfileForWorld(doc.innerHTML, true);
  5018. 		}
  5019.  
  5020. 		Helper.addStatTotalToMouseover();
  5021. 	},
  5022.  
  5023. 	addStatTotalToMouseover: function() {
  5024. 		if (GM_getValue("showStatBonusTotal")) {
  5025. 			profileItems = System.findNodes("//img[contains(@onmouseover,'ajaxLoadItem')]");
  5026. 			if (!profileItems) return;
  5027. 			for (var i=0;i<profileItems.length;i++) {
  5028. 				var mouseOver = profileItems[i].getAttribute("onmouseover");
  5029. 				var reParams=/(\d+),\s*(\d+),\s*(\d+),\s*(\d+),\s*'(.*)'/;
  5030. 				var reResult=reParams.exec(mouseOver);
  5031. 				if (reResult === null) {
  5032. 					return null;
  5033. 				}
  5034. 				var itemId=reResult[1];
  5035. 				var invId=reResult[2];
  5036. 				var type=reResult[3];
  5037. 				var pid=reResult[4];
  5038. 				var finalStr = reResult[5];
  5039. 				//terrasoft.gr/FallenSwordHelper: ajaxLoadItem(7236, 199346003, 1, 1346893, '<br><center><b>[Click to Equip]</b></center>');
  5040. 				var theURL = "fetchitem.php?item_id=" + itemId + "&inv_id=" + invId + "&t="+type + "&p="+pid;
  5041. 				index = itemId+"_"+invId;
  5042. 				profileItems[i].setAttribute("id",index);
  5043. 				profileItems[i].setAttribute("theURL",theURL);
  5044. 				profileItems[i].setAttribute("finalStr",finalStr);
  5045. 				profileItems[i].setAttribute("onmouseover","Tip('<span id=\"mouseovertext"+index+"\"><center><br>&nbsp;&nbsp;Loading Stats...</center><br></span>"+
  5046. 					"<span style=\"display:none; visibility:hidden;\">" + mouseOver.replace(/\'/ig,"\\\'") + "</span>')");
  5047. 				profileItems[i].addEventListener("mouseover",Helper.setProfileItemMouseover,false);
  5048. 			}
  5049. 		}
  5050. 	},
  5051.  
  5052. 	setProfileItemMouseover: function (evt) {
  5053. 		var index = evt.target.getAttribute('id');
  5054. 		var theURL = evt.target.getAttribute('theURL');
  5055. 		var finalStr = evt.target.getAttribute('finalStr');
  5056. 		var mouseoverHTML = document.getElementById("mouseovertext"+index);
  5057. 		if(Helper.savedItemData[index]==undefined) {
  5058. 			System.xmlhttp(theURL,
  5059. 			function(responseText) {
  5060. 				var doc = System.createDocument(responseText);
  5061. 				var bonusTable = System.findNode("//table[tbody/tr/td/center/font[.='Bonuses']]",doc);
  5062. 				var extraText = "";
  5063. 				if (bonusTable) {
  5064. 					var subTotal = 0;
  5065. 					for (var i=2;i<bonusTable.rows.length;i++) {
  5066. 						aRow = bonusTable.rows[i];
  5067. 						bonusValue = parseInt(/(^[-+]?\d+)/.exec(aRow.cells[1].textContent)[1],10);
  5068. 						subTotal += bonusValue;
  5069. 					}
  5070. 					extraText = "<br>Individual item stats subtotal: " + subTotal;
  5071. 				}
  5072. 				mouseoverHTML.innerHTML = responseText+extraText+finalStr;
  5073. 				Helper.savedItemData[index] = responseText+extraText+finalStr;
  5074. 			});
  5075. 		} else {
  5076. 			mouseoverHTML.innerHTML = Helper.savedItemData[index];
  5077. 		}
  5078. 	},
  5079.  
  5080. 	injectEmptySlots: function(responseText) {
  5081. 		var doc = System.createDocument(responseText);
  5082. 		var bpImage = System.findNode("//img[contains(@title,'Manage Backpack')]",doc);
  5083. 		if (bpImage) {
  5084. 			var bpslots = bpImage.parentNode.nextSibling.nextSibling
  5085. 			var node=System.findNode("//span/a[contains(@href,'cmd=profile&subcmd=dropitems')]");
  5086. 			if (bpslots) {
  5087. 				try {
  5088. 					var theText = bpslots.innerHTML.replace("&nbsp;","").replace("&nbsp;","");
  5089. 					var slots = theText.split("/");
  5090. 					var color = (slots[0] == slots[1]) ? "#FF0000" : "blue";
  5091. 					node.innerHTML += "&nbsp;<font color='" + color + "' size='1'>[" + theText + "]</font>&nbsp;";
  5092. 				} catch (err) {
  5093. 					GM_log(err);
  5094. 				}
  5095. 			}
  5096. 		}
  5097.  
  5098. 	},
  5099.  
  5100. 	profileInjectFastWear: function() {
  5101. 		// Fast Wear
  5102. 		var profileInventory = System.findNode("//table[tbody/tr/td/center/a[contains(@href,'subcmd=equipitem')]]");
  5103. 		if (profileInventory) {
  5104. 			var profileInventoryIDRE = /inventory_id=(\d+)/i;
  5105. 			var foldersEnabled = System.findNode("//img[contains(@src,'folder_on.gif')]");
  5106.  
  5107. 			var profileInventoryBox = [];
  5108. 			var profileInventoryBoxItem = [];
  5109. 			var profileInventoryBoxID = [];
  5110. 			for (var i=0;i<12;i++) {
  5111. 				if (foldersEnabled) {
  5112. 					if (profileInventory.rows[2*(i >> 2)]) profileInventoryBox[i]=profileInventory.rows[2*(i >> 2)].cells[i % 4];
  5113. 				} else {
  5114. 					if (profileInventory.rows[i >> 2]) profileInventoryBox[i]=profileInventory.rows[i >> 2].cells[i % 4];
  5115. 				}
  5116. 				if (profileInventoryBox[i]) profileInventoryBoxItem[i] = profileInventoryBox[i].firstChild;
  5117. 				if (profileInventoryBoxItem[i]) {
  5118. 					var itemHREF = profileInventoryBoxItem[i].firstChild.getAttribute("href");
  5119. 					if (itemHREF && profileInventoryIDRE(itemHREF)) profileInventoryBoxID[i] = profileInventoryIDRE(itemHREF)[1];
  5120. 				}
  5121. 			}
  5122.  
  5123. 			var newRow;
  5124.  
  5125. 			for (i=0;i<12;i++) {
  5126. 				if ((i % 4===0) && profileInventoryBoxItem[i] && !foldersEnabled) newRow = profileInventory.insertRow(2*(i >> 2)+1);
  5127. 				if ((i % 4===0) && profileInventoryBoxItem[i] && foldersEnabled) newRow = profileInventory.insertRow(3*(i >> 2)+1);
  5128. 				if (profileInventoryBoxItem[i] && profileInventoryBoxID[i]) {
  5129. 					var itemOnmouseover = profileInventoryBoxItem[i].firstChild.firstChild.getAttribute("onmouseover");
  5130. 					if (itemOnmouseover.indexOf("Equip") != -1) { // check to see if item is equipable.
  5131. 						var output = '<span style="cursor:pointer; text-decoration:underline; color:blue; font-size:x-small;" '+
  5132. 								'id="Helper:equipProfileInventoryItem' + profileInventoryBoxID[i] + '" ' +
  5133. 								'itemID="' + profileInventoryBoxID[i] + '">Wear</span>';
  5134. 						var newCell = newRow.insertCell(i % 4);
  5135. 						newCell.align = 'center';
  5136. 						newCell.innerHTML = output;
  5137. 						document.getElementById('Helper:equipProfileInventoryItem' + profileInventoryBoxID[i]).
  5138. 							addEventListener('click', Helper.equipProfileInventoryItem, true);
  5139. 					}
  5140. 					else {
  5141. 						newCell = newRow.insertCell(i % 4); // dummy cell if we don't put a wear link up.
  5142. 					}
  5143. 				} else if (profileInventoryBoxItem[i] && !profileInventoryBoxID[i]){
  5144. 					newCell = newRow.insertCell(i % 4); // dummy cell if we don't put a wear link up.
  5145. 				}
  5146. 			}
  5147. 		}
  5148. 	},
  5149.  
  5150. 	enableDelComponent: function() {
  5151. 		var nodes=System.findNodes('//a[contains(@href,"cmd=profile&subcmd=destroycomponent&component_id=")]');
  5152. 		if (nodes) {
  5153. 			for (var i=0;i<nodes.length;i++) {
  5154. 				nodes[i].parentNode.innerHTML+='<span id=compDelBtn'+i+' compid='+
  5155. 					nodes[i].getAttribute('href').match(/destroycomponent&component_id=(\d+)/i)[0]+
  5156. 					' style="text-decoration:underline;cursor:pointer;color:#A0CFEC">Del</span>';
  5157. 				document.getElementById('compDelBtn'+i).addEventListener('click',Helper.delComponent,true);
  5158. 			}
  5159. 		}
  5160. 		document.getElementById('compDel').innerHTML='';
  5161. 	},
  5162. 	delComponent: function(evt) {
  5163. 		var id=evt.target.getAttribute('compid');
  5164. 		System.xmlhttp('index.php?cmd=profile&subcmd=destroycomponent&component_id='+id,
  5165. 			function(responseText) {
  5166. 				if (Layout.infoBox(responseText)=='Component destroyed.')
  5167. 					evt.target.parentNode.innerHTML='';
  5168. 				else
  5169. 					evt.target.innerHTML=Layout.infoBox(responseText);
  5170. 			});
  5171. 	},
  5172.  
  5173. 	profileParseAllyEnemy: function() {
  5174. 		// Allies/Enemies count/total function
  5175. 		var alliesTotal = GM_getValue("alliestotal");
  5176. 		var alliesTitle = System.findNode("//div[strong[.='Allies']]");
  5177. 		var alliesTable = alliesTitle.nextSibling.nextSibling;
  5178. 		if (alliesTable) {
  5179. 			var numberOfAllies = 0;
  5180. 			var startIndex = 0;
  5181. 			while (alliesTable.innerHTML.indexOf("/avatars/", startIndex+1) != -1) {
  5182. 				numberOfAllies ++;
  5183. 				startIndex = alliesTable.innerHTML.indexOf("/avatars/",startIndex+1);
  5184. 			}
  5185. 			startIndex = 0;
  5186. 			while (alliesTable.innerHTML.indexOf("/skin/player_default.jpg", startIndex+1) != -1) {
  5187. 				numberOfAllies ++;
  5188. 				startIndex = alliesTable.innerHTML.indexOf("/skin/player_default.jpg",startIndex+1);
  5189. 			}
  5190. 			alliesTitle.innerHTML += "&nbsp<span style='color:blue'>" + numberOfAllies + "</span>";
  5191. 			if (alliesTotal && alliesTotal >= numberOfAllies) {
  5192. 				alliesTitle.innerHTML += "/<span style='color:blue' findme='alliestotal'>" + alliesTotal + "</span>";
  5193. 			}
  5194. 		}
  5195. 		var enemiesTotal = GM_getValue("enemiestotal");
  5196. 		var enemiesTitle = System.findNode("//div[strong[.='Enemies']]");
  5197. 		var enemiesTable = enemiesTitle.nextSibling.nextSibling;
  5198. 		if (enemiesTable) {
  5199. 			var numberOfEnemies = 0;
  5200. 			startIndex = 0;
  5201. 			while (enemiesTable.innerHTML.indexOf("/avatars/", startIndex+1) != -1) {
  5202. 				numberOfEnemies ++;
  5203. 				startIndex = enemiesTable.innerHTML.indexOf("/avatars/",startIndex+1);
  5204. 			}
  5205. 			startIndex = 0;
  5206. 			while (enemiesTable.innerHTML.indexOf("/skin/player_default.jpg", startIndex+1) != -1) {
  5207. 				numberOfEnemies ++;
  5208. 				startIndex = enemiesTable.innerHTML.indexOf("/skin/player_default.jpg",startIndex+1);
  5209. 			}
  5210. 			enemiesTitle.innerHTML += "&nbsp;<span style='color:blue'>" + numberOfEnemies + "</span>";
  5211. 			if (enemiesTotal && enemiesTotal >= numberOfEnemies) {
  5212. 				enemiesTitle.innerHTML += "/<span style='color:blue' findme='enemiestotal'>" + enemiesTotal + "</span>";
  5213. 			}
  5214. 		}
  5215.  
  5216. 		//store a list of allies and enemies for use in coloring
  5217. 		listOfAllies = "";
  5218. 		if (alliesTable) {
  5219. 			var alliesTableActual = alliesTable.firstChild.nextSibling.firstChild.nextSibling;
  5220. 			for (var i=0;i<alliesTableActual.rows.length;i++) {
  5221. 				var aRow = alliesTableActual.rows[i];
  5222. 				for (var j=0;j<alliesTableActual.rows[i].cells.length;j++) {
  5223. 					var aCell = aRow.cells[j];
  5224. 					if (aCell.firstChild.firstChild.nextSibling) {
  5225. 						var allyNameTable = aCell.firstChild.firstChild.nextSibling.nextSibling;
  5226. 						var allyName = allyNameTable.rows[0].cells[1].firstChild.textContent;
  5227. 						listOfAllies += allyName + " ";
  5228. 					}
  5229. 				}
  5230. 			}
  5231. 		}
  5232.  
  5233. 		listOfEnemies = "";
  5234. 		if (enemiesTable) {
  5235. 			var enemiesTableActual = enemiesTable.firstChild.nextSibling.firstChild.nextSibling;
  5236. 			for (i=0;i<enemiesTableActual.rows.length;i++) {
  5237. 				aRow = enemiesTableActual.rows[i];
  5238. 				for (j=0;j<enemiesTableActual.rows[i].cells.length;j++) {
  5239. 					aCell = aRow.cells[j];
  5240. 					if (aCell.firstChild.firstChild.nextSibling) {
  5241. 						var enemyNameTable = aCell.firstChild.firstChild.nextSibling.nextSibling;
  5242. 						var enemyName = enemyNameTable.rows[0].cells[1].firstChild.textContent;
  5243. 						listOfEnemies += enemyName + " ";
  5244. 					}
  5245. 				}
  5246. 			}
  5247. 		}
  5248. 		GM_setValue("listOfAllies", listOfAllies);
  5249. 		GM_setValue("listOfEnemies", listOfEnemies);
  5250. 	},
  5251.  
  5252. 	addClickListener: function(id, listener) {
  5253. 		var node=document.getElementById(id);
  5254. 		if (node) node.addEventListener('click', listener, true);
  5255. 	},
  5256.  
  5257. 	bioAddEventListener: function() {
  5258. 		Helper.addClickListener("Helper:sendBuffMsg", Helper.getBuffsToBuy);
  5259. 		var i=0;
  5260. 		while (true) {
  5261. 			var buff=document.getElementById('Helper:buff'+i);
  5262. 			if (buff) {
  5263. 				buff.addEventListener('click', Helper.toggleBuffsToBuy,true);
  5264. 				i++;
  5265. 			} else
  5266. 				break;
  5267. 		}
  5268. 		Helper.addClickListener('Helper:bioExpander', Helper.expandBio);
  5269. 	},
  5270.  
  5271. 	profileRenderBio: function(playername) {
  5272. 		var bioDiv = System.findNode("//div[strong[.='Biography']]");
  5273. 		var bioCell = bioDiv.nextSibling.nextSibling;
  5274. 		var renderBio=(bioCell && GM_getValue("renderSelfBio")) || (!bioCell && GM_getValue("renderOtherBios"));
  5275. 		GM_setValue("buffsToBuy", "");
  5276. 		if (!renderBio || !bioCell) {return;}
  5277.  
  5278. 		var bioContents = bioCell.innerHTML;
  5279. 		bioContents=bioContents.replace(/\{b\}/g,'`~').replace(/\{\/b\}/g,'~`');
  5280. 		var buffs=bioContents.match(/`~([^~]|~(?!`))*~`/g);
  5281. 		if (buffs) {
  5282. 			for (var i=0;i<buffs.length;i++) {
  5283. 				var fullName=buffs[i].replace(/(`~)|(~`)|(\{b\})|(\{\/b\})/g,'');
  5284. 				var buffName = Helper.removeHTML(fullName);
  5285. 				var cbString =
  5286. 					'<span id="Helper:buff'+i+'" style="color:blue;cursor:pointer">'+
  5287. 					fullName+'</span>';
  5288. 				bioContents=bioContents.replace(buffs[i], cbString);
  5289. 			}
  5290.  
  5291. 			if (bioContents.indexOf("{cmd}") < 0) bioContents+="{cmd}";
  5292.  
  5293. 			bioContents = bioContents.replace("{cmd}",'<input id="Helper:sendBuffMsg" subject="buffMe" href="index.php?cmd=message&target_player=' +
  5294. 				playername +'" class="custombutton" type="submit" value="Ask For Buffs"/>'+
  5295. 				'<span id=buffCost style="color:red"></span>');
  5296. 		}
  5297. 		bioCell.innerHTML = bioContents;
  5298. 	},
  5299.  
  5300. 	profileInjectQuickButton: function(avyrow, playerid, playername) {
  5301. 		var auctiontext = "Go to " + playername + "'s auctions" ;
  5302. 		var ranktext = "Rank " +playername + "" ;
  5303. 		var securetradetext = "Create Secure Trade to " + playername;
  5304.  
  5305. 		var newhtml = avyrow.innerHTML +
  5306. 			"<a " + Layout.quickBuffHref(playerid) + ">" +
  5307. 			"<img alt='Buff " + playername + "' title='Buff " + playername + "' src=" +
  5308. 			System.imageServer + "/skin/realm/icon_action_quickbuff.gif></a>&nbsp;&nbsp;";
  5309. 		if (!GM_getValue("enableMaxGroupSizeToJoin")) {
  5310. 			newhtml += "<a href='" + System.server + "index.php?cmd=guild&subcmd=groups&subcmd2=joinall" +
  5311. 				"');'><img alt='Join All Groups' title='Join All Groups' src=" +
  5312. 				System.imageServer + "/skin/icon_action_join.gif></a>&nbsp;&nbsp;";
  5313. 		} else {
  5314. 			var maxGroupSizeToJoin = GM_getValue("maxGroupSizeToJoin");
  5315. 			newhtml += "<a href='" + System.server + "index.php?cmd=guild&subcmd=groups&subcmd2=joinallgroupsundersize" +
  5316. 				"');'><img alt='Join All Groups' title='Join All Groups < " + maxGroupSizeToJoin + " Members' src=" +
  5317. 				System.imageServer + "/skin/icon_action_join.gif></a>&nbsp;&nbsp;";
  5318. 		}
  5319. 		newhtml += "<a href=" + System.server + "?cmd=auctionhouse&type=-3&tid=" +
  5320. 			playerid + '><img alt="' + auctiontext + '" title="' + auctiontext + '" src="' +
  5321. 			System.imageServer + '/skin/gold_button.gif"></a>&nbsp;&nbsp;' +
  5322. 			"<a href=" + System.server + "index.php?cmd=trade&subcmd=createsecure&target_username=" +
  5323. 			playername + '><img alt="' + securetradetext + '" title="' + securetradetext + '" src=' +
  5324. 			System.imageServerHTTP + "/temple/2.gif></a>&nbsp;&nbsp;" +
  5325. 			"<a href=" + System.server + "?cmd=guild&subcmd=inventory&subcmd2=report&user=" +
  5326. 			playername + '>[SR]</a>&nbsp;&nbsp;';
  5327. 		if (Helper.currentGuildRelationship == "self" && GM_getValue("showAdmin")) {
  5328. 			newhtml +=
  5329. 				"<a href='" + System.server + "index.php?cmd=guild&subcmd=members&subcmd2=changerank&member_id=" +
  5330. 				playerid + '><img alt="' + ranktext + '" title="' + ranktext + '" src=' +
  5331. 				System.imageServerHTTP + "/guilds/" + Helper.guildId + "_mini.jpg></a>";
  5332. 		}
  5333. 		avyrow.innerHTML = newhtml ;
  5334. 	},
  5335.  
  5336. 	profileInjectGuildRel: function() {
  5337. 		var aLink = System.findNode("//a[contains(@href,'cmd=guild&subcmd=view')]");
  5338. 		if (aLink) {
  5339. 			var guildIdResult = /guild_id=([0-9]+)/i.exec(aLink.getAttribute("href"));
  5340. 			if (guildIdResult) Helper.guildId = parseInt(guildIdResult[1], 10);
  5341. 			var warning = document.createElement('span');
  5342. 			var color = "";
  5343. 			var changeAppearance = true;
  5344. 			Helper.currentGuildRelationship = Helper.guildRelationship(aLink.text);
  5345. 			var settings;
  5346. 			switch (Helper.currentGuildRelationship) {
  5347. 				case "self":
  5348. 					settings="guildSelfMessage";
  5349. 					break;
  5350. 				case "friendly":
  5351. 					settings="guildFrndMessage";
  5352. 					break;
  5353. 				case "old":
  5354. 					settings="guildPastMessage";
  5355. 					break;
  5356. 				case "enemy":
  5357. 					settings="guildEnmyMessage";
  5358. 					break;
  5359. 				default:
  5360. 					changeAppearance = false;
  5361. 					break;
  5362. 			}
  5363. 			if (changeAppearance) {
  5364. 				var settingsAry=GM_getValue(settings).split("|");
  5365. 				warning.innerHTML="<br/>" + settingsAry[1];
  5366. 				color = settingsAry[0];
  5367. 				aLink.parentNode.style.color=color;
  5368. 				aLink.style.color=color;
  5369. 				aLink.parentNode.insertBefore(warning, aLink.nextSibling);
  5370. 			}
  5371. 		}
  5372. 	},
  5373.  
  5374. 	profileComponents: function() {
  5375. 		var injectHere = System.findNode("//div[strong[.='Components']]/following-sibling::div[1]");
  5376. 		if (injectHere) {
  5377. 			var componentExtrasDiv = document.createElement("DIV");
  5378. 			injectHere.appendChild(componentExtrasDiv);
  5379. 			componentExtrasDiv.innerHTML+='<div id=compDel align=center>[<span style="text-decoration:underline;cursor:pointer;color:#0000FF">Enable Quick Del</span>]</div>'+
  5380. 				'<div id=compSum align=center>[<span style="text-decoration:underline;cursor:pointer;color:#0000FF">Count Components</span>]</div>'+
  5381. 				'<div align=center><a href="index.php?cmd=notepad&subcmd=quickextract">[<span style="text-decoration:underline;cursor:pointer;color:#0000FF">Quick Extract Components</span>]</a></div>';
  5382. 			document.getElementById('compDel').addEventListener('click', Helper.enableDelComponent, true);
  5383. 			document.getElementById('compSum').addEventListener('click', Helper.countComponent, true);
  5384. 		}
  5385. 	},
  5386.  
  5387. 	countComponent: function() {
  5388. 		var compPage=System.findNodes("//a[contains(@href,'index.php?cmd=profile&component_page=')]");
  5389. 		if (compPage)
  5390. 			Helper.compPage = compPage.length;
  5391. 		else
  5392. 			Helper.compPage = 0;
  5393. 		document.getElementById('compSum').innerHTML='Retrieve page: ';
  5394. 		Helper.componentList={};
  5395. 		System.xmlhttp("index.php?cmd=profile&component_page=0", Helper.retriveComponent, 0);
  5396. 	},
  5397.  
  5398. 	retriveComponent: function(responseText, currentPage) {
  5399. 		var nextPage=currentPage+1;
  5400. 		document.getElementById('compSum').innerHTML+=nextPage+', ';
  5401. 		var doc=System.createDocument(responseText);
  5402. 		var compList = System.findNodes("//a[contains(@href,'cmd=profile&subcmd=destroycomponent&component_id=')]/img",doc);
  5403. 		if (compList) {
  5404. 			for (var i=0;i<compList.length;i++) {
  5405. 				var mouseover=compList[i].getAttribute('onmouseover');
  5406. 				var id=mouseover.match(/ajaxLoadCustom\((\d+).*/)[1];
  5407. 				if (Helper.componentList[id])
  5408. 					Helper.componentList[id].count++;
  5409. 				else {
  5410. 					Helper.componentList[id]={'count':1,'src':compList[i].getAttribute('src'),
  5411. 						'onmouseover':mouseover.replace("<br><center><b>[Click to Destroy]</b></center>","")};
  5412. 				}
  5413. 			}
  5414. 		}
  5415. 		if (currentPage < Helper.compPage - 1) {
  5416. 			System.xmlhttp("index.php?cmd=profile&component_page="+nextPage, Helper.retriveComponent, nextPage);
  5417. 		} else {
  5418. 			var totalCount = System.findNodes("//td[contains(@background,'inventory/1x1mini.gif')]",doc);
  5419. 			if (totalCount) totalCount=totalCount.length; else totalCount=0;
  5420. 			totalCount+=currentPage*50;
  5421. 			var output='Component Summary<br/><table>';
  5422. 			var usedCount=0;
  5423. 			for (id in Helper.componentList) {
  5424. 				var comp=Helper.componentList[id];
  5425. 				output+="<tr><td align=center><img src="+comp.src+" onmouseover=\""+comp.onmouseover+"\"></td><td>"+comp.count+"</td></tr>";
  5426. 				usedCount+=comp.count;
  5427. 			}
  5428. 			output+="<tr><td align=center>Total:</td><td>"+usedCount+" / "+totalCount+"</td></tr></table>";
  5429. 			document.getElementById('compSum').innerHTML=output;
  5430. 		}
  5431. 	},
  5432.  
  5433. 	compressBio: function() {
  5434. 		var bioDiv = System.findNode("//div[strong[.='Biography']]");
  5435. 		var bioCell = bioDiv.nextSibling.nextSibling;
  5436. 		if (bioCell) { //non-self profile
  5437. 			var bioContents = bioCell.innerHTML;
  5438. 			var maxCharactersToShow = GM_getValue("maxCompressedCharacters");
  5439. 			var maxRowsToShow = GM_getValue("maxCompressedLines");
  5440. 			var numberOfLines = bioContents.substr(0,maxCharactersToShow).split(/<br>\n/).length - 1;
  5441. 			if (numberOfLines >= maxRowsToShow) {
  5442. 				var startIndex = 0;
  5443. 				while (maxRowsToShow >= 0) {
  5444. 					maxRowsToShow --;
  5445. 					startIndex = bioContents.indexOf("<br>\n",startIndex+1);
  5446. 				}
  5447. 				maxCharactersToShow = startIndex;
  5448. 			}
  5449. 			if (bioContents.length>maxCharactersToShow) {
  5450. 				//find the end of next HTML tag after the max characters to show.
  5451. 				var breakPoint = bioContents.indexOf("<br>",maxCharactersToShow) + 4;
  5452. 				var bioStart = bioContents.substring(0,breakPoint);
  5453. 				var bioEnd = bioContents.substring(breakPoint,bioContents.length);
  5454. 				var extraOpenHTML = "", extraCloseHTML = "";
  5455. 				var tagList=['b','i','u','span'];
  5456. 				for (var i=0;i<tagList.length;i++){
  5457. 					var closeTagIndex = bioEnd.indexOf("</"+tagList[i]+">");
  5458. 					var openTagIndex = bioEnd.indexOf("<"+tagList[i]+">");
  5459. 					if (closeTagIndex != -1 && openTagIndex > closeTagIndex) {
  5460. 						extraOpenHTML += "<"+tagList[i]+">";
  5461. 						extraCloseHTML += "</"+tagList[i]+">";
  5462. 					}
  5463. 				}
  5464.  
  5465. 				bioCell.innerHTML = bioStart + extraCloseHTML + "<span id='Helper:bioExpander' style='cursor:pointer; text-decoration:underline; color:blue;'>More ...</span>" +
  5466. 					"<span id='Helper:bioHidden' style='display:none; visibility:hidden;'>" + extraOpenHTML + bioEnd + "</span>";
  5467. 			}
  5468. 		}
  5469. 	},
  5470.  
  5471. 	toggleBuffsToBuy: function(evt) {
  5472. 		var buffNameNode=evt.target;
  5473. 		while (buffNameNode.tagName.toLowerCase()!='span') buffNameNode=buffNameNode.parentNode;
  5474. 		var node=buffNameNode;
  5475. 		var selected = node.style.color=='blue';
  5476. 		node.style.color=selected?'yellow':'blue';
  5477.  
  5478. 		var buffName=node.textContent;
  5479. 		if (selected) {
  5480. 			var text='';
  5481. 			// get the whole line from the buff name towards the end (even after the ',', in case of "AL, Lib, Mer: 10k each"
  5482. 			while (node && node.nodeName.toLowerCase()!='br') {
  5483. 				var newtext=node.textContent;
  5484. 				node=node.nextSibling;
  5485. 				text+=newtext;
  5486. 			}
  5487.  
  5488. 			var price=text.replace(/[^a-zA-Z0-9.,+\- ]/g, '').toLowerCase().match(/([+\-]{0,1}[\.\d]+ *k)|([+\-]{0,1}[\.\d]+ *fsp)/);
  5489. 			if (!price) { // some players have prices BEFORE the buff names
  5490. 				node=buffNameNode;
  5491. 				while (node && node.nodeName.toLowerCase()!='br') {
  5492. 					newtext=node.textContent;
  5493. 					node=node.previousSibling;
  5494. 					text=newtext+text;
  5495. 				}
  5496. 				price=text.replace(/[^a-zA-Z0-9.,+\- ]/g, '').toLowerCase().match(/([+\-]{0,1}[\.\d]+ *k)|([+\-]{0,1}[\.\d]+ *fsp)/);
  5497. 			}
  5498. 			var type, cost;
  5499. 			if (price) {
  5500. 				type=price[0].indexOf('k')>0 ? 'k' : 'fsp';
  5501. 				cost=price[0].match(/([+\-]{0,1}[\.\d]+)/)[0];
  5502. 			} else {
  5503. 				type='unknown'; cost='1';
  5504. 			}
  5505. 			Helper.buffCost.buffs[buffName]=[parseFloat(cost),type];
  5506. 			Helper.buffCost.count+=1;
  5507. 		} else {
  5508. 			Helper.buffCost.count-=1;
  5509. 			delete(Helper.buffCost.buffs[buffName]);
  5510. 		}
  5511. 		Helper.updateBuffCost();
  5512. 	},
  5513.  
  5514. 	updateBuffCost: function() {
  5515. 		if (Helper.buffCost.count>0) {
  5516. 			var total={'k':0,'fsp':0,'unknown':0};
  5517. 			var html='This is an estimated cost based on how the script finds the cost associated with buffs from viewing bio.'+
  5518. 				'It can be incorrect, please use with discretion.<br/><hr/>'+
  5519. 				'<table border=0>';
  5520. 			for (buff in Helper.buffCost.buffs) {
  5521. 				total[Helper.buffCost.buffs[buff][1]]+=Helper.buffCost.buffs[buff][0];
  5522. 				html+='<tr><td>'+buff+'</td><td>: '+Helper.buffCost.buffs[buff][0]+Helper.buffCost.buffs[buff][1]+'</td></tr>';
  5523. 			}
  5524. 			var totalText=(total.fsp>0)?(Math.round(total.fsp*100)/100) +' FSP':'';
  5525. 			if (total.fsp > 0 && total.k > 0) totalText+=' and ';
  5526. 			totalText+=(total.k>0)?total.k+' k':'';
  5527. 			if (total.unknown>0) totalText+=' ('+total.unknown+' buff(s) with unknown cost)';
  5528. 			html+='</table><b>Total: '+totalText+'</b>';
  5529. 			document.getElementById('buffCost').innerHTML='<br/><span onmouseover=\'Tip("'+html+'");\'>Estimated Cost: <b>'+totalText+'</b></span>';
  5530. 			GM_setValue("buffCostTotalText", totalText);
  5531. 		} else {
  5532. 			document.getElementById('buffCost').innerHTML='';
  5533. 			GM_setValue("buffCostTotalText", '');
  5534. 		}
  5535. 	},
  5536.  
  5537. 	getBuffsToBuy: function(evt) {
  5538. 		var allSpans = System.findNodes("//span[contains(@id,'Helper:buff')]");
  5539.  
  5540. 		var buffsToBuy = "";
  5541. 		var buffCount = 0;
  5542. 		for (var i=0; i<allSpans.length; i++) {
  5543. 			var aSpan=allSpans[i];
  5544. 			var spanInner = aSpan.innerHTML.replace(/<[a-zA-Z\/][^>]*>/g, "").replace(/[^a-zA-Z0-9 ]/g,'');
  5545.  
  5546. 			if (aSpan.id && aSpan.id.match(/Helper:buff\d*/) != -1 && aSpan.style.color == "yellow") {
  5547. 				buffsToBuy += spanInner.trim() + ", ";
  5548. 				buffCount++;
  5549. 			}
  5550. 		}
  5551. 		buffsToBuy = buffsToBuy.trim();
  5552. 		if (buffsToBuy.lastIndexOf(",") == buffsToBuy.length - 1) {
  5553. 			buffsToBuy = buffsToBuy.substring(0, buffsToBuy.length - 1);
  5554. 		}
  5555. 		GM_setValue("buffsToBuy", buffsToBuy);
  5556. 		var href = evt.target.getAttribute("href");
  5557.  
  5558. 		if (href && buffCount > 0) {
  5559. 			window.location = System.server + href;
  5560. 		} else {
  5561. 			alert("You have not selected any buffs!");
  5562. 			GM_setValue("buffsToBuy", "");
  5563. 			return;
  5564. 		}
  5565. 	},
  5566. 	removeHTML: function(buffName) {
  5567.  
  5568. 		return buffName.replace(/<\/?[^>]+(>|$)/g, "").replace(/[^a-zA-Z 0-9]+/g,"");
  5569. 	},
  5570.  
  5571. 	expandBio: function(evt) {
  5572. 		var bioExpander = document.getElementById('Helper:bioExpander');
  5573. 		bioExpander.style.display = 'none';
  5574. 		bioExpander.style.visibility = 'hidden';
  5575. 		var bioHidden = document.getElementById('Helper:bioHidden');
  5576. 		bioHidden.style.display = 'block';
  5577. 		bioHidden.style.visibility = 'visible';
  5578. 	},
  5579.  
  5580. 	profileSelectAll: function(evt) {
  5581. 		var checkboxItems = System.findNodes("//input[@type='checkbox']");
  5582. 		checkboxItems.forEach(function(e) {e.checked = e.checked? false:true;});
  5583. 	},
  5584.  
  5585. 	equipProfileInventoryItem: function(evt) {
  5586. 		var InventoryItemID=evt.target.getAttribute("itemID");
  5587. 		System.xmlhttp("index.php?cmd=profile&subcmd=equipitem&inventory_id=" + InventoryItemID,
  5588. 			Helper.equipProfileInventoryItemReturnMessage,
  5589. 			{"item": InventoryItemID, "target": evt.target});
  5590. 	},
  5591.  
  5592. 	equipProfileInventoryItemReturnMessage: function(responseText, callback) {
  5593. 		var itemID = callback.item;
  5594. 		var target = callback.target;
  5595. 		var info = Layout.infoBox(responseText);
  5596. 		var itemCellElement = target.parentNode; //System.findNode("//td[@title='" + itemID + "']");
  5597. 		if (!info) {
  5598. 			itemCellElement.innerHTML = "<span style='color:green; font-weight:bold;'>Worn</span>";
  5599. 		} else {
  5600. 			itemCellElement.innerHTML = "<span style='color:red; font-weight:bold;'>Error:" + info + "</span>";
  5601. 		}
  5602. 	},
  5603.  
  5604. 	useProfileInventoryItem: function(evt) {
  5605. 		if (!window.confirm("Are you sure you want to use/extract the item?")) {return;}
  5606. 		var InventoryItemID=evt.target.getAttribute("itemID");
  5607. 		System.xmlhttp("index.php?cmd=profile&subcmd=useitem&inventory_id=" + InventoryItemID,
  5608. 			function(responseText) {
  5609. 				var info = Layout.infoBox(responseText);
  5610. 				if (!info) info = "<font color=red>Error</font>";
  5611. 				evt.target.parentNode.innerHTML = info;
  5612. 			});
  5613. 	},
  5614.  
  5615. 	injectAuctionSearch: function() {
  5616. 		Layout.notebookContent().innerHTML=Helper.makePageHeader('Trade Hub Quick Search','','','')+
  5617. 			'<div>This screen allows you to set up some quick search templates for the Auction House. '+
  5618. 				'The Display on AH column indicates if the quick search will show on the short list on the '+
  5619. 				'Auction House main screen. A maximum of 18 items can show on this list '+
  5620. 				'(It will not show more than 18 even if you have more than 18 flagged). '+
  5621. 				'To edit items, either use the large text area below, '+
  5622. 				'or add a new entry and delete the old one. You can always reset the list to the default values.</div>'+
  5623. 			'<div style="font-size:small;" id="Helper:Auction Search Output">' +
  5624. 			'</div>';
  5625. 		// global parameters for the meta function generateManageTable
  5626. 		Helper.param={};
  5627. 		Helper.param={'id':'Helper:Auction Search Output',
  5628. 			'headers':["Category","Nickname","Quick Search Text","Display on TH?"],
  5629. 			'fields':["category","nickname","searchname","displayOnAH"],
  5630. 			'tags':["textbox","textbox","textbox","checkbox"],
  5631. 			'url':["","","index.php?cmd=auctionhouse&type=-1&search_text=@replaceme@",""],
  5632. 			'currentItems':System.getValueJSON("quickSearchList"),
  5633. 			'gmname':"quickSearchList",
  5634. 			'sortField':"category",
  5635. 			'categoryField':'category',
  5636. 			'showRawEditor':true};
  5637. 		Helper.generateManageTable();
  5638. 	},
  5639.  
  5640. 	linkFromMouseover: function(mouseOver) {
  5641. 		var reParams=/(\d+),\s*(\d+),\s*(\d+),\s*(\d+)/;
  5642. 		var reResult=reParams.exec(mouseOver);
  5643. 		if (reResult === null) {
  5644. 			return null;
  5645. 		}
  5646. 		var itemId=reResult[1];
  5647. 		var invId=reResult[2];
  5648. 		var type=reResult[3];
  5649. 		var pid=reResult[4];
  5650. 		var theUrl = "fetchitem.php?item_id=" + itemId + "&inv_id=" + invId + "&t="+type + "&p="+pid;
  5651. 		theUrl = System.server + theUrl;
  5652. 		return theUrl;
  5653. 	},
  5654.  
  5655. 	linkFromMouseoverCustom: function(mouseOver) {
  5656. 		var reParams =/(\d+),\s*(-?\d+),\s*(\d+),\s*(\d+),\s*\'([a-z0-9]*)\'/i;
  5657. 		var reResult =reParams.exec(mouseOver);
  5658. 		if (reResult === null) {
  5659. 			return null;
  5660. 		}
  5661. 		var itemId   = reResult[1];
  5662. 		var invId    = reResult[2];
  5663. 		var type     = reResult[3];
  5664. 		var pid      = reResult[4];
  5665. 		var vcode    = reResult[5];
  5666. 		var theUrl   = "fetchitem.php?item_id=" + itemId + "&inv_id=" + invId + "&t="+type + "&p=" + pid + "&vcode=" + vcode;
  5667. 		theUrl = System.server + theUrl;
  5668. 		return theUrl;
  5669. 	},
  5670.  
  5671. 	injectInventoryManager: function() {
  5672. 		var content=Layout.notebookContent();
  5673.  
  5674. 		var lastCheck=GM_getValue("lastInventoryCheck");
  5675. 		var now=(new Date()).getTime();
  5676. 		if (!lastCheck) lastCheck=0;
  5677. 		var haveToCheck=((now - lastCheck) > 2*60*1000);
  5678. 		var refreshButton;
  5679. 		if (haveToCheck) {
  5680. 			refreshButton = '<td width="10%" nobr style="font-size:x-small;text-align:right">[ <span id="Helper:InventoryManagerRefresh" style="text-decoration:underline;cursor:pointer">Refresh</span> ]</td>';
  5681. 		} else {
  5682. 			refreshButton = '<td width="10%" nobr style="font-size:x-small;text-align:right">[ Wait '+ Math.round(300 - ((now - lastCheck)/1000)) +'s ]</td>';
  5683. 		}
  5684.  
  5685. 		Helper.inventory=System.getValueJSON("inventory");
  5686. 		var minLvl = GM_getValue("inventoryMinLvl", 1);
  5687. 		var maxLvl = GM_getValue("inventoryMaxLvl", 1000);
  5688.  
  5689. 		var newhtml='<table cellspacing="0" cellpadding="0" border="0" width="100%"><tr style="background-color:#cd9e4b">'+
  5690. 			'<td width="90%" nobr><b>&nbsp;Inventory Manager</b> green = worn, blue = backpack</td>'+
  5691. 			refreshButton+
  5692. 			'<tr><td colspan=2>' +
  5693. 			'<table><tr><td><b>Show Items:</b></td>' +
  5694. 				'<td><table><tr><td>' +
  5695. 				'<div align=right><form id=Helper:inventoryFilterForm subject="inventory" href="index.php?cmd=notepad&subcmd=invmanager" onSubmit="javascript:return false;">' +
  5696. 				'Min lvl:<input value="' + minLvl + '" size=5 name="Helper.inventoryMinLvl" id="Helper.inventoryMinLvl" style=custominput/> ' +
  5697. 				'Max lvl:<input value="' + maxLvl + '" size=5 name="Helper.inventoryMaxLvl" id="Helper.inventoryMaxLvl" style=custominput/> ' +
  5698. 				'<input id="Helper:inventoryFilter" subject="inventory" href="index.php?cmd=notepad&subcmd=invmanager" class="custombutton" type="submit" value="Filter"/>' +
  5699. 				'<input id="Helper:inventoryFilterReset" subject="inventory" href="index.php?cmd=notepad&subcmd=invmanager" class="custombutton" type="button" value="Reset"/></form></div>';
  5700. 		for (var i=0; i<Helper.itemFilters.length; i++) {
  5701. 			newhtml += (i % 5 ===0) ? '</td></tr><tr><td>' : '';
  5702. 			newhtml+='&nbsp;' +Helper.itemFilters[i].type+ ':<input id="'+Helper.itemFilters[i].id+'" type="checkbox" linkto="'+Helper.itemFilters[i].id+'"' +
  5703. 					(GM_getValue(Helper.itemFilters[i].id)?' checked':'') + '/>';
  5704. 		}
  5705. 		newhtml+='</td></tr><tr><td>&nbsp;<span id=GuildInventorySelectAll>[Select All]</span>&nbsp;<span id=GuildInventorySelectNone>[Select None]</span>' +
  5706. 				'</td></tr></table></td></tr></table>' +
  5707. 				'<div style="font-size:small;" id="Helper:InventoryManagerOutput">' +
  5708. 				'</div>';
  5709. 		content.innerHTML=newhtml;
  5710. 		if (haveToCheck)
  5711. 			document.getElementById("Helper:InventoryManagerRefresh").addEventListener('click', Helper.parseProfileStart, true);
  5712. 		Helper.generateInventoryTable("self");
  5713. 		document.getElementById("Helper:inventoryFilterReset").addEventListener('click', Helper.resetLevelFilter, true);
  5714. 		document.getElementById("Helper:inventoryFilterForm").addEventListener('submit', Helper.setLevelFilter, true);
  5715.  
  5716. 		for (i=0; i<Helper.itemFilters.length; i++) {
  5717. 			document.getElementById(Helper.itemFilters[i].id).addEventListener('click', Helper.toggleCheckboxAndRefresh, true);
  5718. 		}
  5719. 		document.getElementById("GuildInventorySelectAll").addEventListener('click', Helper.InventorySelectFilters, true);
  5720. 		document.getElementById("GuildInventorySelectNone").addEventListener('click', Helper.InventorySelectFilters, true);
  5721. 	},
  5722.  
  5723. 	injectGuildInventoryManager: function() {
  5724. 		var content=Layout.notebookContent();
  5725.  
  5726. 		var lastCheck=GM_getValue("lastGuildInventoryCheck");
  5727. 		var now=(new Date()).getTime();
  5728. 		if (!lastCheck) lastCheck=0;
  5729. 		var haveToCheck=((now - lastCheck) > 15*60*1000);
  5730. 		var refreshButton;
  5731. 		if (haveToCheck) {
  5732. 			refreshButton = '<td width="10%" nobr style="font-size:x-small;text-align:right">[ <span id="Helper:GuildInventoryManagerRefresh" style="text-decoration:underline;cursor:pointer">Refresh</span> ]</td>';
  5733. 		} else {
  5734. 			refreshButton = '<td width="10%" nobr style="font-size:x-small;text-align:right">[ Wait '+ Math.round(900 - ((now - lastCheck)/1000)) +'s ]</td>';
  5735. 		}
  5736.  
  5737. 		var guildItemCount = "unknown";
  5738. 		Helper.guildinventory = System.getValueJSON("guildinventory");
  5739. 		if (Helper.guildinventory) {
  5740. 			Helper.guildinventory.items = Helper.guildinventory.items.filter(function (e) {return (e.name);});
  5741. 			guildItemCount = Helper.guildinventory.items.length;
  5742. 		}
  5743. 		var minLvl = GM_getValue("inventoryMinLvl", 1);
  5744. 		var maxLvl = GM_getValue("inventoryMaxLvl", 1000);
  5745.  
  5746. 		var newhtml='<table cellspacing="0" cellpadding="0" border="0" width="100%"><tr style="background-color:#cd9e4b">'+
  5747. 			'<td width="90%" nobr><b>&nbsp;Guild Inventory Manager</b> (takes a while to refresh so only do it if you really need to)</td>'+
  5748. 			refreshButton+
  5749. 			'</tr>' +
  5750. 			'<tr><td colspan=2>' +
  5751. 				'<table><tr><td><b>Show Items:</b></td>' +
  5752. 				'<td><table><tr><td>' +
  5753. 				'<div align=right><form id=Helper:inventoryFilterForm subject="inventory" href="index.php?cmd=notepad&subcmd=guildinvmanager" onSubmit="javascript:return false;">' +
  5754. 				'Min lvl:<input value="' + minLvl + '" size=5 name="Helper.inventoryMinLvl" id="Helper.inventoryMinLvl" style=custominput/> ' +
  5755. 				'Max lvl:<input value="' + maxLvl + '" size=5 name="Helper.inventoryMaxLvl" id="Helper.inventoryMaxLvl" style=custominput/> ' +
  5756. 				'<input id="Helper:inventoryFilter" subject="inventory" href="index.php?cmd=notepad&subcmd=guildinvmanager" class="custombutton" type="submit" value="Filter"/>' +
  5757. 				'<input id="Helper:inventoryFilterReset" subject="inventory" href="index.php?cmd=notepad&subcmd=guildinvmanager" class="custombutton" type="button" value="Reset"/></form></div>';
  5758. 		for (var i=0; i<Helper.itemFilters.length; i++) {
  5759. 			newhtml += (i % 5 === 0) ? '</td></tr><tr><td>' : '';
  5760. 			newhtml+='&nbsp;' +Helper.itemFilters[i].type+ ':<input id="'+Helper.itemFilters[i].id+'" type="checkbox" linkto="'+Helper.itemFilters[i].id+'"' +
  5761. 					(GM_getValue(Helper.itemFilters[i].id)?' checked':'') + '/>';
  5762. 		}
  5763. 		newhtml+='</td></tr><tr><td>&nbsp;<span id=GuildInventorySelectAll>[Select All]</span>&nbsp;<span id=GuildInventorySelectNone>[Select None]</span>' +
  5764. 				'</td></tr></table></td></tr>'+
  5765. 			'<tr><td colspan=2>&nbsp;Guild Item Count:&nbsp;' + guildItemCount + '</td></tr></table>' +
  5766. 			'<div style="font-size:small;" id="Helper:GuildInventoryManagerOutput">' +
  5767. 			'</div>';
  5768. 		content.innerHTML=newhtml;
  5769. 		if (haveToCheck)
  5770. 			document.getElementById("Helper:GuildInventoryManagerRefresh").addEventListener('click', Helper.parseGuildStart, true);
  5771. 		Helper.generateInventoryTable("guild");
  5772. 		document.getElementById("Helper:inventoryFilterReset").addEventListener('click', Helper.resetLevelFilter, true);
  5773. 		document.getElementById("Helper:inventoryFilterForm").addEventListener('submit', Helper.setLevelFilter, true);
  5774.  
  5775. 		for (i=0; i<Helper.itemFilters.length; i++) {
  5776. 			document.getElementById(Helper.itemFilters[i].id).addEventListener('click', Helper.toggleCheckboxAndRefresh, true);
  5777. 		}
  5778. 		document.getElementById("GuildInventorySelectAll").addEventListener('click', Helper.InventorySelectFilters, true);
  5779. 		document.getElementById("GuildInventorySelectNone").addEventListener('click', Helper.InventorySelectFilters, true);
  5780. 	},
  5781.  
  5782. 	InventorySelectFilters: function(evt) {
  5783. 		var checkedValue = (evt.target.id=="GuildInventorySelectAll");
  5784. 		for (var i=0; i<Helper.itemFilters.length; i++) {
  5785. 			GM_setValue(Helper.itemFilters[i].id, checkedValue);
  5786. 		}
  5787. 		if (checkedValue)
  5788. 			window.location=window.location;
  5789. 		else {
  5790. 			for (i=0; i<Helper.itemFilters.length; i++) {
  5791. 				document.getElementById(Helper.itemFilters[i].id).checked = checkedValue;
  5792. 			}
  5793. 		}
  5794. 	},
  5795.  
  5796. 	toggleCheckboxAndRefresh: function(evt) {
  5797. 		GM_setValue(evt.target.id, evt.target.checked);
  5798. 		window.location=window.location;
  5799. 	},
  5800.  
  5801. 	injectOnlinePlayers: function() {
  5802. 		var content=Layout.notebookContent();
  5803.  
  5804. 		var lastCheck=GM_getValue("lastOnlineCheck");
  5805. 		var now=(new Date()).getTime();
  5806. 		if (!lastCheck) lastCheck=0;
  5807. 		var haveToCheck=((now - lastCheck) > 5*60*1000);
  5808. 		var refreshButton;
  5809. 		if (haveToCheck) {
  5810. 			refreshButton = '<td> (takes a while to refresh so only do it if you really need to) </td>'+
  5811. 			'<td width="10%" nobr style="font-size:x-small;text-align:right"><span id="Helper:OnlinePlayersRefresh" style="text-decoration:underline;cursor:pointer">[Refresh]</span></td>';
  5812. 		} else {
  5813. 			refreshButton = '<td width="10%" nobr style="font-size:x-small;text-align:right">[ Wait '+ Math.round(300 - ((now - lastCheck)/1000)) +'s ]</td>';
  5814. 		}
  5815.  
  5816. 		content.innerHTML='<table cellspacing="0" cellpadding="0" border="0" width="100%"><tr style="background-color:#cd9e4b">'+
  5817. 			'<td nobr><b>&nbsp;Online Players</b></td>' +
  5818. 			refreshButton +
  5819. 			'</tr>' +
  5820. 			'</table>' +
  5821. 			'<div style="font-size:small;" id="Helper:OnlinePlayersOutput">' +
  5822. 			'' +
  5823. 			'</div>';
  5824. 		refreshButton = document.getElementById("Helper:OnlinePlayersRefresh");
  5825. 		if (refreshButton)
  5826. 			refreshButton.addEventListener('click', Helper.parseOnlinePlayersStart, true);
  5827.  
  5828. 		GM_addStyle(
  5829. 			'.HelperTableRow1 {background-color:#e7c473;font-size:small}\n' +
  5830. 			'.HelperTableRow1:hover {background-color:white}\n' +
  5831. 			'.HelperTableRow2 {background-color:#e2b960;font-size:small}\n' +
  5832. 			'.HelperTableRow2:hover {background-color:white}');
  5833. 		Helper.onlinePlayers = System.getValueJSON("onlinePlayers");
  5834. 		Helper.sortOnlinePlayersTable();
  5835. 		Helper.generateOnlinePlayersTable();
  5836. 	},
  5837.  
  5838. 	parseOnlinePlayersStart: function() {
  5839. 		// set timer to redisplay the [refresh] button
  5840. 		var now=(new Date()).getTime();
  5841. 		GM_setValue("lastOnlineCheck", now.toString());
  5842.  
  5843. 		var refreshButton = document.getElementById("Helper:OnlinePlayersRefresh");
  5844. 		refreshButton.style.visibility = "hidden";
  5845.  
  5846. 		Helper.onlinePlayers = {players:[]};
  5847. 		var output=document.getElementById('Helper:OnlinePlayersOutput');
  5848. 		output.innerHTML='<br/>Parsing online players ...';
  5849. 		System.xmlhttp('index.php?cmd=onlineplayers&page=1', Helper.parseOnlinePlayersStorePage, {"page":1});
  5850. 	},
  5851.  
  5852. 	parseOnlinePlayersStorePage: function(responseText, callback) {
  5853. 		var doc = System.createDocument(responseText);
  5854. 		var output=document.getElementById('Helper:OnlinePlayersOutput');
  5855. 		var playerRows = System.findNodes("//table/tbody/tr[count(td)=4 and td[2]/a]", doc);
  5856. 		var maxPage = parseInt(System.findNode("//table//td[input[@name='page']]", doc).textContent.replace(/\D/g, ""),10);
  5857. 		output.innerHTML+=callback.page + " ";
  5858. 		if (playerRows){
  5859. 			for (var i=0; i<playerRows.length; i++) {
  5860. 				var guildId;
  5861. 				if (playerRows[i].cells[0].innerHTML.search("href") == -1) guildId = -1;
  5862. 				else guildId = parseInt(playerRows[i].cells[0].firstChild.getAttribute("href").replace(/\D/g,""),10);
  5863. 				var newPlayer = {
  5864. 					guildId: guildId,
  5865. 					id: parseInt(playerRows[i].cells[1].firstChild.getAttribute("href").replace(/\D/g,""),10),
  5866. 					name: playerRows[i].cells[1].textContent,
  5867. 					level: parseInt(playerRows[i].cells[2].textContent,10)
  5868. 				};
  5869. 				Helper.onlinePlayers.players.push(newPlayer);
  5870. 			}
  5871. 		}
  5872. 		if (callback.page<maxPage/*-maxPage+15*/) {
  5873. 			var newPage = (callback.page == 1) ? Math.round(4 * maxPage / 5) : (callback.page+1);
  5874. 			System.xmlhttp('index.php?cmd=onlineplayers&page=' + newPage, Helper.parseOnlinePlayersStorePage, {"page":newPage});
  5875. 		}
  5876. 		else {
  5877. 			Helper.onlinePlayers.players = Helper.onlinePlayers.players.removeDuplicates('name'); //remove duplicate entries.
  5878. 			System.setValueJSON("onlinePlayers", Helper.onlinePlayers);
  5879. 			Helper.sortOnlinePlayersTable();
  5880. 			Helper.generateOnlinePlayersTable();
  5881. 		}
  5882. 	},
  5883.  
  5884. 	generateOnlinePlayersTable: function() {
  5885. 		if (!Helper.onlinePlayers) {return;}
  5886. 		Helper.onlinePlayers.players = Helper.onlinePlayers.players.removeDuplicates('name'); //remove duplicate entries.
  5887. 		var minLvl = GM_getValue("onlinePlayerMinLvl", 1);
  5888. 		var maxLvl = GM_getValue("onlinePlayerMaxLvl", 1000);
  5889. 		var output=document.getElementById("Helper:OnlinePlayersOutput");
  5890. 		var result=
  5891. 			'<div align=right><form id=Helper:onlinePlayerFilterForm subject="onlinePlayer" href="index.php?cmd=notepad&subcmd=onlineplayers" onSubmit="javascript:return false;">' +
  5892. 			'Min lvl:<input value="' + minLvl + '" size=5 name="Helper.onlinePlayerMinLvl" id="Helper.onlinePlayerMinLvl" style=custominput/> ' +
  5893. 			'Max lvl:<input value="' + maxLvl + '" size=5 name="Helper.onlinePlayerMaxLvl" id="Helper.onlinePlayerMaxLvl" style=custominput/> ' +
  5894. 			'<input id="Helper:onlinePlayerFilter" subject="onlinePlayer" href="/index.php?cmd=notepad&subcmd=onlineplayers" class="custombutton" type="submit" value="Filter"/>' +
  5895. 			'<input id="Helper:onlinePlayerFilterReset" subject="onlinePlayer" href="index.php?cmd=notepad&subcmd=onlineplayers" class="custombutton" type="button" value="Reset"/></form></div>' +
  5896. 			'<table id="Helper:OnlinePlayersTable"><tr>' +
  5897. 			'<th align="left" sortkey="guildId" sortType="number">Guild</th>' +
  5898. 			'<th sortkey="name">Name</th>' +
  5899. 			'<th sortkey="level" sortType="number">Level</th></tr>';
  5900. 		var highlightPlayersNearMyLvl = GM_getValue("highlightPlayersNearMyLvl");
  5901. 		var lvlDiffToHighlight = 5;
  5902.  
  5903. 		var player;
  5904. 		for (var i=0; i<Helper.onlinePlayers.players.length;i++) {
  5905. 			player=Helper.onlinePlayers.players[i];
  5906. 			if (player.level >= minLvl && player.level <= maxLvl)
  5907. 				result+='<tr class="HelperTableRow' + (1 + i % 2) +'">' +
  5908. 					'<td><a href="index.php?cmd=guild&amp;subcmd=view&amp;guild_id=' + player.guildId + '">'+
  5909. 						'<img width="16" border="0" height="16" src="' + System.imageServerHTTP + '/guilds/' + player.guildId + '_mini.jpg"></a></td>'+
  5910. 					'<td><a href="index.php?cmd=profile&player_id='+player.id+'">'+ player.name+'</a></td>' +
  5911. 					'<td align="right"' + (highlightPlayersNearMyLvl?(Math.abs(player.level - Helper.characterLevel) <= lvlDiffToHighlight?' style="background-color:#4671C8"':''):'') +
  5912. 						'>' + player.level + '</td>' +
  5913. 					'</tr>';
  5914. 		}
  5915. 		result+='</table>';
  5916. 		output.innerHTML=result;
  5917.  
  5918. 		document.getElementById("Helper:onlinePlayerFilterReset").addEventListener('click', Helper.resetLevelFilter, true);
  5919. 		document.getElementById("Helper:onlinePlayerFilterForm").addEventListener('submit', Helper.setLevelFilter, true);
  5920.  
  5921. 		var theTable=document.getElementById('Helper:OnlinePlayersTable');
  5922. 		for (i=0; i<theTable.rows[0].cells.length; i++) {
  5923. 			var cell=theTable.rows[0].cells[i];
  5924. 			cell.style.textDecoration="underline";
  5925. 			cell.style.cursor="pointer";
  5926. 			cell.addEventListener('click', Helper.sortOnlinePlayersTable, true);
  5927. 		}
  5928. 	},
  5929.  
  5930. 	sortOnlinePlayersTable: function(evt) {
  5931. 		Helper.onlinePlayers=System.getValueJSON("onlinePlayers");
  5932. 		if (!evt) {
  5933. 			var sortCriteria = System.getValueJSON("onlinePlayerSortBy");
  5934. 			if (!sortCriteria) {return;}
  5935. 			var sortType = sortCriteria["sortType"];
  5936. 			Helper.sortBy = sortCriteria["sortBy"];
  5937. 			Helper.sortAsc = sortCriteria["sortAsc"];
  5938. 		} else {
  5939. 			var headerClicked = evt.target.getAttribute("sortKey");
  5940. 			sortType = evt.target.getAttribute("sortType");
  5941. 			if (!sortType) sortType="string";
  5942. 			GM_log(headerClicked);
  5943. 			// GM_log(Helper.sortBy);
  5944. 			GM_log(sortType);
  5945. 			// numberSort
  5946. 			if (Helper.sortAsc==undefined) Helper.sortAsc=true;
  5947. 			if (Helper.sortBy && Helper.sortBy==headerClicked) {
  5948. 				Helper.sortAsc=!Helper.sortAsc;
  5949. 			}
  5950. 			Helper.sortBy=headerClicked;
  5951. 		}
  5952. 		System.setValueJSON("onlinePlayerSortBy", {"sortBy": Helper.sortBy, "sortType": sortType, "sortAsc": Helper.sortAsc});
  5953.  
  5954. 		switch(sortType) {
  5955. 			case "string":
  5956. 				Helper.onlinePlayers.players.sort(Helper.stringSort);
  5957. 				break;
  5958. 			case "number":
  5959. 				Helper.onlinePlayers.players.sort(Helper.numberSort);
  5960. 				break;
  5961. 			default:
  5962. 				break;
  5963. 		}
  5964. 		Helper.generateOnlinePlayersTable();
  5965. 	},
  5966.  
  5967. 	toggleCheckboxAndRefresh: function(evt) {
  5968. 		GM_setValue(evt.target.id, evt.target.checked);
  5969. 		window.location=window.location;
  5970. 	},
  5971.  
  5972. 	parseProfileStart: function(){
  5973. 		var now=(new Date()).getTime();
  5974. 		GM_setValue("lastInventoryCheck", now.toString());
  5975.  
  5976. 		Helper.inventory = new Object;
  5977. 		Helper.inventory.items = new Array();
  5978. 		var output=document.getElementById('Helper:InventoryManagerOutput');
  5979. 		output.innerHTML='<br/>Parsing profile...';
  5980. 		System.xmlhttp('index.php?cmd=profile', Helper.parseProfileDone);
  5981. 	},
  5982.  
  5983. 	parseProfileDone: function(responseText) {
  5984. 		var doc=System.createDocument(responseText);
  5985. 		var output=document.getElementById('Helper:InventoryManagerOutput');
  5986. 		var currentlyWorn=System.findNodes("//a[contains(@href,'subcmd=unequipitem') and contains(img/@src,'/items/')]/img", doc);
  5987. 		for (var i=0; i<currentlyWorn.length; i++) {
  5988. 			var item={"url": Helper.linkFromMouseover(currentlyWorn[i].getAttribute("onmouseover")),
  5989. 				"where":"worn", "index":(i+1)};
  5990. 			if (i===0) output.innerHTML+="<br/>Found worn item ";
  5991. 			output.innerHTML+=(i+1) + " ";
  5992. 			Helper.inventory.items.push(item);
  5993. 		}
  5994. 		var	folderIDs = new Array();
  5995. 		Helper.folderIDs = folderIDs; //clear out the array before starting.
  5996. 		GM_setValue("currentFolder", 1);
  5997. 		var folderLinks = System.findNodes("//a[contains(@href,'index.php?cmd=profile&folder_id=')]", doc);
  5998. 		//if folders are enabled then save the ID's in an array
  5999. 		if (folderLinks) {
  6000. 			for (i=0; i<folderLinks.length;i++) {
  6001. 				folderLink = folderLinks[i];
  6002. 				href = folderLink.getAttribute("href");
  6003. 				var folderID = /folder_id=([-0-9]+)/.exec(href)[1]*1;
  6004. 				folderIDs.push(folderID);
  6005. 				Helper.folderIDs = folderIDs;
  6006. 			}
  6007. 		}
  6008. 		Helper.parseInventoryPage(responseText);
  6009. 	},
  6010.  
  6011. 	parseInventoryPage: function(responseText) {
  6012. 		var doc=System.createDocument(responseText);
  6013. 		var output=document.getElementById('Helper:InventoryManagerOutput');
  6014. 		var backpackItems = System.findNodes("//td[contains(@background,'2x3.gif')]/center/a[contains(@href, 'subcmd=equipitem')]/img", doc);
  6015. 		var pages = System.findNodes("//a[contains(@href,'index.php?cmd=profile&backpack_page=')]", doc);
  6016. 		var pageElement = System.findNode("//a[contains(@href,'backpack_page=')]/font", doc);
  6017. 		var currentPage = 1;
  6018. 		if (pageElement) currentPage = parseInt(System.findNode("//a[contains(@href,'backpack_page=')]/font", doc).textContent,10);
  6019. 		var currentFolder = GM_getValue("currentFolder");
  6020. 		var folderCount = 0, folderID = -1;
  6021. 		if (Helper.folderIDs.length<=1) {
  6022. 			folderCount = 1;
  6023. 			folderID = -1;
  6024. 		} else {
  6025. 			folderCount = Helper.folderIDs.length;
  6026. 			folderID = Helper.folderIDs[currentFolder-1];
  6027. 		}
  6028. 		if (backpackItems) {
  6029. 			output.innerHTML+='<br/>Parsing folder '+currentFolder+', backpack page '+currentPage+'...';
  6030.  
  6031. 			for (var i=0; i<backpackItems.length;i++) {
  6032. 				var theUrl=Helper.linkFromMouseover(backpackItems[i].getAttribute("onmouseover"));
  6033. 				var item={"url": theUrl,
  6034. 					"where":"backpack", "index":(i+1), "page":currentPage};
  6035. 				if (i===0) output.innerHTML+="<br/>Found wearable item ";
  6036. 				output.innerHTML+=(i+1) + " ";
  6037. 				Helper.inventory.items.push(item);
  6038. 			}
  6039. 			} else {
  6040. 				output.innerHTML+='<br/>Parsing folder '+currentFolder+', backpack page '+currentPage+'... Empty';
  6041. 			}
  6042. 		if (currentPage<pages.length || currentFolder<folderCount) {
  6043. 			if (currentPage==pages.length && currentFolder<folderCount) {
  6044. 				currentPage = 0;
  6045. 				folderID = Helper.folderIDs[currentFolder];
  6046. 				GM_setValue("currentFolder", currentFolder+1);
  6047. 			}
  6048. 			System.xmlhttp('index.php?cmd=profile&backpack_page='+(currentPage)+'&folder_id='+(folderID), Helper.parseInventoryPage);
  6049. 		}
  6050. 		else {
  6051. 			output.innerHTML+="<br/>Parsing inventory item ";
  6052. 			Helper.retrieveInventoryItem(0, "self");
  6053. 		}
  6054. 	},
  6055.  
  6056. 	parseGuildStart: function(){
  6057. 		var now=(new Date()).getTime();
  6058. 		GM_setValue("lastGuildInventoryCheck", now.toString());
  6059.  
  6060. 		Helper.guildinventory = new Object;
  6061. 		Helper.guildinventory.items = new Array();
  6062. 		var output=document.getElementById('Helper:GuildInventoryManagerOutput');
  6063. 		output.innerHTML = '<br/>Parsing guild store ...';
  6064. 		System.xmlhttp('index.php?cmd=guild&subcmd=manage&guildstore_page=0', Helper.parseGuildStorePage);
  6065. 	},
  6066.  
  6067. 	parseGuildStorePage: function(responseText) {
  6068. 		var doc=System.createDocument(responseText);
  6069. 		var output=document.getElementById('Helper:GuildInventoryManagerOutput');
  6070. 		var guildstoreItems = System.findNodes("//a[contains(@href,'subcmd2=takeitem')]/img", doc);
  6071. 		var pages = System.findNodes("//a[contains(@href,'cmd=guild&subcmd=manage&guildstore_page')]", doc);
  6072. 		var currentPage = parseInt(System.findNode("//a[contains(@href,'cmd=guild&subcmd=manage&guildstore_page')]/font", doc).textContent,10);
  6073. 		if (guildstoreItems) {
  6074. 			output.innerHTML+='<br/>Parsing guild store page '+currentPage+'...';
  6075.  
  6076. 			for (var i=0; i<guildstoreItems.length;i++) {
  6077. 				var theUrl=Helper.linkFromMouseover(guildstoreItems[i].getAttribute("onmouseover"));
  6078. 				var item={"url": theUrl,
  6079. 					"where":"guildstore", "index":(i+1), "page":currentPage, "worn":false};
  6080. 				if (i===0) output.innerHTML+="<br/>Found guild store item ";
  6081. 				output.innerHTML+=(i+1) + " ";
  6082. 				Helper.guildinventory.items.push(item);
  6083. 			}
  6084. 		} else {
  6085. 			output.innerHTML+='<br/>Parsing guild store page '+currentPage+'... Empty';
  6086. 			currentPage = pages.length; // go to end automatically since the rest of the pages will be empty too.
  6087. 		}
  6088. 		if (currentPage<pages.length) {
  6089. 			System.xmlhttp('index.php?cmd=guild&subcmd=manage&guildstore_page='+(currentPage), Helper.parseGuildStorePage);
  6090. 		}
  6091. 		else {
  6092. 			output.innerHTML+='<br/>Parsing guild report page ...';
  6093. 			System.xmlhttp('index.php?cmd=guild&subcmd=inventory&subcmd2=report', Helper.parseGuildReportPage);
  6094. 		}
  6095. 	},
  6096.  
  6097. 	parseGuildReportPage: function(responseText) {
  6098. 		var doc=System.createDocument(responseText);
  6099. 		var output=document.getElementById('Helper:GuildInventoryManagerOutput');
  6100. 		var guildreportItems = System.findNodes("//img[contains(@src,'items')]", doc);
  6101. 		if (guildreportItems) {
  6102. 			for (var i=0; i<guildreportItems.length;i++) {
  6103. 				var theUrl=Helper.linkFromMouseover(guildreportItems[i].getAttribute("onmouseover"));
  6104. 				var item={"url": theUrl,
  6105. 					"where":"guildreport", "index":(i+1), "worn":false};
  6106. 				if (i===0) output.innerHTML+="<br/>Found guild report item ";
  6107. 				output.innerHTML+=(i+1) + " ";
  6108. 				Helper.guildinventory.items.push(item);
  6109. 			}
  6110. 		}
  6111. 		output.innerHTML+="<br/>Parsing guild inventory item ";
  6112. 		Helper.retrieveInventoryItem(0, "guild");
  6113. 	},
  6114.  
  6115. 	retrieveInventoryItem: function(invIndex, reportType) {
  6116. 		if (reportType == "guild") {
  6117. 			targetInventory = Helper.guildinventory;
  6118. 		} else {
  6119. 			targetInventory = Helper.inventory;
  6120. 		}
  6121. 		if (targetInventory.items[invIndex].url === null) {
  6122. 			invIndex++;
  6123. 		}
  6124. 		System.xmlhttp(targetInventory.items[invIndex].url, Helper.parseInventoryItem, {"invIndex": invIndex, "reportType": reportType});
  6125. 	},
  6126.  
  6127. 	parseInventoryItem: function(responseText, callback) {
  6128. 		if (callback.reportType == "guild") {
  6129. 			targetId = 'Helper:GuildInventoryManagerOutput';
  6130. 			targetInventory = Helper.guildinventory;
  6131. 		} else {
  6132. 			targetId = 'Helper:InventoryManagerOutput';
  6133. 			targetInventory = Helper.inventory;
  6134. 		}
  6135. 		var output=document.getElementById(targetId);
  6136. 		var doc=System.createDocument(responseText);
  6137. 		output.innerHTML+=(callback.invIndex+1) + " ";
  6138.  
  6139. 		var item=targetInventory.items[callback.invIndex];
  6140. 		// item.html=responseText;
  6141.  
  6142. 		var nameNode=System.findNode("//b", doc);
  6143. 		if (!nameNode) GM_log(responseText);
  6144. 		if (nameNode) {
  6145. 			item.name=nameNode.textContent.replace(/\\/g,"");
  6146.  
  6147. 			var itemBonuses=System.findNode("//table[tbody/tr/td/center/font='Bonuses']", doc);
  6148.  
  6149. 			var attackNode=System.findNode("tbody/tr/td[.='Attack:']/../td[2]", itemBonuses);
  6150. 			item.attack=(attackNode)?parseInt(attackNode.textContent,10):0;
  6151.  
  6152. 			var defenseNode=System.findNode("tbody/tr/td[.='Defense:']/../td[2]", itemBonuses);
  6153. 			item.defense=(defenseNode)?parseInt(defenseNode.textContent,10):0;
  6154.  
  6155. 			var armorNode=System.findNode("tbody/tr/td[.='Armor:']/../td[2]", itemBonuses);
  6156. 			item.armor=(armorNode)?parseInt(armorNode.textContent,10):0;
  6157.  
  6158. 			var damageNode=System.findNode("tbody/tr/td[.='Damage:']/../td[2]", itemBonuses);
  6159. 			item.damage=(damageNode)?parseInt(damageNode.textContent,10):0;
  6160.  
  6161. 			var hpNode=System.findNode("tbody/tr/td[.='HP:']/../td[2]", itemBonuses);
  6162. 			item.hp=(hpNode)?parseInt(hpNode.textContent,10):0;
  6163.  
  6164. 			var levelNode=System.findNode("//tr[td='Min Level:']/td[2]", doc);
  6165. 			item.minLevel=(levelNode)?parseInt(levelNode.textContent,10):0;
  6166.  
  6167. 			var itemPartOfSetNode=System.findNode("//font[contains(.,'Set Details')]", doc);
  6168. 			item.partOfSet=(itemPartOfSetNode)?true:false;
  6169.  
  6170. 			var durabilityNode=System.findNode("//tbody/tr/td[nobr/font[.='Durability:']]/../td[2]", doc);
  6171. 			item.durability=(durabilityNode)?durabilityNode.textContent:'0/100';
  6172.  
  6173. 			var forgeCount=0, re=/hellforge\/forgelevel.gif/ig;
  6174. 			while(re.exec(responseText)) {
  6175. 				forgeCount++;
  6176. 			}
  6177. 			item.forgelevel=forgeCount;
  6178.  
  6179. 			item.type = responseText.substr(responseText.indexOf('<br>')+4,responseText.indexOf('-',responseText.indexOf('<br>'))-responseText.indexOf('<br>')-5);
  6180.  
  6181. 			var craft="";
  6182. 			if (responseText.search(/Uncrafted|Very Poor|Poor|Average|Good|Very Good|Excellent|Perfect/) != -1){
  6183. 				var fontLineRE=/<\/b><\/font><br>([^<]+)<font color='(#[0-9A-F]{6})'>([^<]+)<\/font>/;
  6184. 				var fontLineRX=fontLineRE.exec(responseText);
  6185. 				craft = fontLineRX[3];
  6186. 			}
  6187. 			item.craftlevel=craft;
  6188. 		}
  6189.  
  6190. 		if (callback.invIndex<targetInventory.items.length-1) {
  6191. 			Helper.retrieveInventoryItem(callback.invIndex+1, callback.reportType);
  6192. 		}
  6193. 		else {
  6194. 			output.innerHTML+="Parsing done!";
  6195. 			Helper.generateInventoryTable(callback.reportType);
  6196. 		}
  6197. 	},
  6198.  
  6199. 	generateInventoryTable: function(reportType) {
  6200. 		if (reportType == "guild") {
  6201. 			targetId = 'Helper:GuildInventoryManagerOutput';
  6202. 			targetInventory = Helper.guildinventory;
  6203. 			inventoryShell = 'guildinventory';
  6204. 		} else {
  6205. 			targetId = 'Helper:InventoryManagerOutput';
  6206. 			targetInventory = Helper.inventory;
  6207. 			inventoryShell = 'inventory';
  6208. 		}
  6209. 		if (!targetInventory) {return;}
  6210. 		targetInventory.items = targetInventory.items.filter(function (e) {return (e.name);});
  6211.  
  6212. 		var output=document.getElementById(targetId);
  6213. 		var result='<table id="Helper:InventoryTable"><tr>' +
  6214. 			'<th width="180" align="left" sortkey="name" colspan="2">Name</th>' +
  6215. 			'<th sortkey="minLevel">Level</th>' +
  6216. 			'<th align="left" sortkey="where">Where</th>' +
  6217. 			'<th align="left" sortkey="type">Type</th>' +
  6218. 			'<th sortkey="attack">Att</th>' +
  6219. 			'<th sortkey="defense">Def</th>' +
  6220. 			'<th sortkey="armor">Arm</th>' +
  6221. 			'<th sortkey="damage">Dam</th>' +
  6222. 			'<th sortkey="hp">HP</th>' +
  6223. 			'<th sortkey="forgelevel" colspan="2">Forge</th>' +
  6224. 			'<th align="left" sortkey="craftlevel">Craft</th>' +
  6225. 			'<th align="right" sortkey="durability">Dur%</th>' +
  6226. 			'<th width="10"></th>';
  6227. 		var item, color;
  6228.  
  6229. 		var allItems = targetInventory.items;
  6230.  
  6231. 		//apply level filters
  6232. 		var minLvl = GM_getValue("inventoryMinLvl", 1);
  6233. 		var maxLvl = GM_getValue("inventoryMaxLvl", 1000);
  6234. 		allItems=allItems.filter(function(e,i,a) {return (e.minLevel >= minLvl && e.minLevel <= maxLvl);});
  6235.  
  6236. 		var showGloveTypeItems = GM_getValue("showGloveTypeItems");
  6237. 		if (!showGloveTypeItems) {
  6238. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Gloves';});
  6239. 		}
  6240. 		var showHelmetTypeItems = GM_getValue("showHelmetTypeItems");
  6241. 		if (!showHelmetTypeItems) {
  6242. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Helmet';});
  6243. 		}
  6244. 		var showAmuletTypeItems = GM_getValue("showAmuletTypeItems");
  6245. 		if (!showAmuletTypeItems) {
  6246. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Amulet';});
  6247. 		}
  6248. 		var showWeaponTypeItems = GM_getValue("showWeaponTypeItems");
  6249. 		if (!showWeaponTypeItems) {
  6250. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Weapon';});
  6251. 		}
  6252. 		var showAmorTypeItems = GM_getValue("showAmorTypeItems");
  6253. 		if (!showAmorTypeItems) {
  6254. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Armor';});
  6255. 		}
  6256. 		var showShieldTypeItems = GM_getValue("showShieldTypeItems");
  6257. 		if (!showShieldTypeItems) {
  6258. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Shield';});
  6259. 		}
  6260. 		var showRingTypeItems = GM_getValue("showRingTypeItems");
  6261. 		if (!showRingTypeItems) {
  6262. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Ring';});
  6263. 		}
  6264. 		var showBootTypeItems = GM_getValue("showBootTypeItems");
  6265. 		if (!showBootTypeItems) {
  6266. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Boots';});
  6267. 		}
  6268. 		var showRuneTypeItems = GM_getValue("showRuneTypeItems");
  6269. 		if (!showRuneTypeItems) {
  6270. 			allItems=allItems.filter(function(e,i,a) {return e.type != 'Rune';});
  6271. 		}
  6272.  
  6273. 		for (var i=0; i<allItems.length;i++) {
  6274. 			item=allItems[i];
  6275.  
  6276. 			switch (item.where+"") {
  6277. 				case "worn":        color = "green";  whereText = "Worn"; whereTitle="Wearing it";     break;
  6278. 				case "backpack":    color = "blue";   whereText = "BP";   whereTitle="In Backpack";    break;
  6279. 				case "guildstore":  color = "navy";   whereText = "GS";   whereTitle="Guild Store";  break;
  6280. 				case "guildreport": color = "maroon"; whereText = "Rep";  whereTitle="Guild Report"; break;
  6281. 				default: color = "black"; break;
  6282. 			}
  6283.  
  6284. 			result+='<tr style="color:'+ color +'">' +
  6285. 				'<td>' + //'<img src="' + System.imageServerHTTP + '/temple/1.gif" onmouseover="' + item.onmouseover + '">' +
  6286. 				'</td><td><a href="/index.php?cmd=guild&subcmd=inventory&subcmd2=report&item=' + item.name + '">' + item.name + '</a>';
  6287. 			if (item.partOfSet) {
  6288. 				result+=' (<a href="/index.php?cmd=guild&subcmd=inventory&subcmd2=report&set=' +
  6289. 					item.name.replace(/gloves/gi,'').replace(/gauntlets/gi,'').replace(/helmet/gi,'').replace(/helm/gi,'').replace(/amulet/gi,'').replace(/necklace/gi,'').
  6290. 						replace(/weapon/gi,'').replace(/axe/gi,'').replace(/sword/gi,'').replace(/fist/gi,'').replace(/hammer/gi,'').replace(/mace/gi,'').
  6291. 						replace(/armored/gi,'').replace(/armor/gi,'').replace(/plate/gi,'').replace(/shield/gi,'').
  6292. 						replace(/ring/gi,'').replace(/boots/gi,'').replace(/rune/gi,'').
  6293. 						replace(/the/gi,'').replace(/of/gi,'').trim().replace(/  /g,' ').replace(/  /g,' ').replace(/ /g,'|') + '">set</a>)';
  6294. 			}
  6295. 			var craftColor = "";
  6296. 			switch(item.craftlevel) {
  6297. 				case 'Perfect': craftColor = '#00b600'; break;
  6298. 				case 'Excellent': craftColor = '#f6ed00'; break;
  6299. 				case 'Very Good': craftColor = '#f67a00'; break;
  6300. 				case 'Good': craftColor = '#f65d00'; break;
  6301. 				case 'Average': craftColor = '#f64500'; break;
  6302. 				case 'Poor': craftColor = '#f61d00'; break;
  6303. 				case 'Very Poor': craftColor = '#b21500'; break;
  6304. 				case 'Uncrafted': craftColor = '#666666'; break;
  6305. 			}
  6306.  
  6307. 			var durabilityPercent = "";
  6308. 			if (item.durability) {
  6309. 				var durabilityExec = /(.*)\/(.*)/.exec(item.durability);
  6310. 				durabilityPercent = parseInt(100*durabilityExec[1]/durabilityExec[2],10);
  6311. 				var durabilityColor = (durabilityPercent<20)?'red':'gray';
  6312. 			}
  6313. 			result+='</td>' +
  6314. 				'<td align="right">' + item.minLevel + '</td>' +
  6315. 				'<td align="left" title="' + whereTitle + '">' + whereText + '</td>' +
  6316. 				'<td align="left">' + item.type + '</td>' +
  6317. 				'<td align="right">' + item.attack + '</td>' +
  6318. 				'<td align="right">' + item.defense + '</td>' +
  6319. 				'<td align="right">' + item.armor + '</td>' +
  6320. 				'<td align="right">' + item.damage + '</td>' +
  6321. 				'<td align="right">' + item.hp + '</td>' +
  6322. 				'<td align="right">' + item.forgelevel + '</td>' +
  6323. 				'<td>' + ((item.forgelevel>0)? "<img src='" + System.imageServerHTTP + "/hellforge/forgelevel.gif'>":"") + '</td>' +
  6324. 				'<td align="left">' + '<span style="color:' + craftColor + ';">' + item.craftlevel + '</span>' + '</td>' +
  6325. 				'<td align="right">' + '<span style="color:' + durabilityColor + ';">' + durabilityPercent + '</span>' + '</td>' +
  6326. 				'<td></td>' +
  6327. 				'</tr>';
  6328. 		}
  6329. 		result+='</table>';
  6330. 		output.innerHTML=result;
  6331.  
  6332. 		targetInventory.lastUpdate = new Date();
  6333. 		System.setValueJSON(inventoryShell, targetInventory);
  6334.  
  6335. 		var inventoryTable=document.getElementById('Helper:InventoryTable');
  6336. 		for (i=0; i<inventoryTable.rows[0].cells.length; i++) {
  6337. 			var cell=inventoryTable.rows[0].cells[i];
  6338. 			cell.style.textDecoration="underline";
  6339. 			cell.style.cursor="pointer";
  6340. 			cell.addEventListener('click', Helper.sortInventoryTable, true);
  6341. 		}
  6342. 	},
  6343.  
  6344. 	sortInventoryTable: function(evt) {
  6345. 		re=/subcmd=([a-z]+)/;
  6346. 		var subPageIdRE = re.exec(document.location.search);
  6347. 		var subPageId="-";
  6348. 		if (subPageIdRE)
  6349. 			subPageId=subPageIdRE[1];
  6350. 		if (subPageId == "guildinvmanager") {
  6351. 			Helper.guildinventory=System.getValueJSON("guildinventory");
  6352. 			targetInventory = Helper.guildinventory;
  6353. 		} else {
  6354. 			Helper.inventory=System.getValueJSON("inventory");
  6355. 			targetInventory = Helper.inventory;
  6356. 		}
  6357. 		var headerClicked=evt.target.getAttribute("sortKey");
  6358. 		if (Helper.sortAsc==undefined) Helper.sortAsc=true;
  6359. 		if (Helper.sortBy && Helper.sortBy==headerClicked) {
  6360. 			Helper.sortAsc=!Helper.sortAsc;
  6361. 		}
  6362. 		Helper.sortBy="name";
  6363. 		targetInventory.items.sort(Helper.stringSort);
  6364.  
  6365. 		Helper.sortBy=headerClicked;
  6366. 		//GM_log(headerClicked)
  6367. 		if (headerClicked=="minLevel" || headerClicked=="attack" || headerClicked=="defense" ||
  6368. 			headerClicked=="armor" || headerClicked=="damage" || headerClicked=="forgelevel" ||
  6369. 			headerClicked=="hp") {
  6370. 			targetInventory.items.sort(Helper.numberSort);
  6371. 		}
  6372. 		else {
  6373. 			targetInventory.items.sort(Helper.stringSort);
  6374. 		}
  6375. 		if (subPageId == "guildinvmanager") {
  6376. 			Helper.generateInventoryTable("guild");
  6377. 		} else {
  6378. 			Helper.generateInventoryTable("self");
  6379. 		}
  6380. 	},
  6381.  
  6382. 	injectRecipeManager: function() {
  6383. 		var content=Layout.notebookContent();
  6384. 		Helper.recipebook = System.getValueJSON("recipebook");
  6385. 		content.innerHTML='<table cellspacing="0" cellpadding="0" border="0" width="100%"><tr style="background-color:#cd9e4b">'+
  6386. 			'<td width="90%" nobr><b>&nbsp;Recipe Manager</b></td>'+
  6387. 			'<td width="10%" nobr style="font-size:x-small;text-align:right">[<span id="Helper:RecipeManagerRefresh" style="text-decoration:underline;cursor:pointer">Refresh</span>]</td>'+
  6388. 			'</tr>' +
  6389. 			'</table>' +
  6390. 			'<div style="font-size:small;" id="Helper:RecipeManagerOutput">' +
  6391. 			'' +
  6392. 			'</div>';
  6393. 		if (!Helper.recipebook) Helper.parseInventingStart();
  6394. 		document.getElementById("Helper:RecipeManagerRefresh").addEventListener('click', Helper.parseInventingStart, true);
  6395. 		Helper.generateRecipeTable();
  6396. 	},
  6397.  
  6398. 	parseInventingStart: function(){
  6399. 		Helper.recipebook = {};
  6400. 		Helper.recipebook.recipe = [];
  6401. 		var output=document.getElementById('Helper:RecipeManagerOutput');
  6402. 		output.innerHTML='<br/>Parsing inventing screen ...<br/>';
  6403. 		var currentFolder = 1;
  6404. 		GM_setValue("currentFolder", currentFolder);
  6405.  
  6406. 		System.xmlhttp('index.php?cmd=inventing&page=0', Helper.parseInventingPage, {"page": 0});
  6407.  
  6408. 	},
  6409.  
  6410. 	parseInventingPage: function(responseText, callback) {
  6411. 		var doc=System.createDocument(responseText);
  6412.  
  6413. 		var	folderIDs = new Array();
  6414. 		Helper.folderIDs = folderIDs; //clear out the array before starting.
  6415. 		var currentFolder = GM_getValue("currentFolder");
  6416. 		var folderLinks = System.findNodes("//a[contains(@href,'index.php?cmd=inventing&folder_id=')]", doc);
  6417. 		//if folders are enabled then save the ID's in an array
  6418. 		if (folderLinks) {
  6419. 			for (i=0; i<folderLinks.length;i++) {
  6420. 				folderLink = folderLinks[i];
  6421. 				href = folderLink.getAttribute("href");
  6422. 				var folderID = /folder_id=([-0-9]+)/.exec(href)[1]*1;
  6423. 				folderIDs.push(folderID);
  6424. 				Helper.folderIDs = folderIDs;
  6425. 			}
  6426. 		}
  6427. 		folderCount = Helper.folderIDs.length;
  6428. 		folderID = Helper.folderIDs[currentFolder-1];
  6429.  
  6430. 		var output=document.getElementById('Helper:RecipeManagerOutput');
  6431. 		var currentPage = callback.page;
  6432. 		var pages=System.findNode("//select[@name='page']", doc);
  6433. 		if (!pages) {return;}
  6434. 		var recipeRows = System.findNodes("//table[tbody/tr/td[.='Recipe Name']]//tr[td/img]",doc);
  6435.  
  6436. 		var nextPage=currentPage+1;
  6437. 		output.innerHTML += 'Parsing folder '+ currentFolder + ' ... Page ' + nextPage + '... <br/>';
  6438.  
  6439. 		if (recipeRows) {
  6440. 			for (var i=0; i<recipeRows.length;i++) {
  6441. 				aRow = recipeRows[i];
  6442. 				var recipeLink = aRow.cells[1].firstChild.getAttribute("href");
  6443. 				var recipeId = parseInt(recipeLink.match(/recipe_id=(\d+)/i)[1],10);
  6444. 				var recipe={
  6445. 					"img": aRow.cells[0].firstChild.src,
  6446. 					"link": recipeLink,
  6447. 					"name": aRow.cells[1].firstChild.textContent,
  6448. 					"id": recipeId};
  6449. 				output.innerHTML+="Found blueprint: "+ recipe.name + "<br/>";
  6450. 				Helper.recipebook.recipe.push(recipe);
  6451. 			}
  6452. 		}
  6453. 		if ((nextPage<=pages.options.length && currentFolder!=folderCount) || currentFolder<folderCount) {
  6454. 			if (nextPage==pages.options.length && currentFolder<folderCount) {
  6455. 				nextPage = 0;
  6456. 				folderID = Helper.folderIDs[currentFolder];
  6457. 				GM_setValue("currentFolder", currentFolder+1);
  6458. 			}
  6459. 			System.xmlhttp('index.php?cmd=inventing&page='+nextPage+'&folder_id='+(folderID), Helper.parseInventingPage, {"page": nextPage});
  6460. 		}
  6461. 		else {
  6462. 			output.innerHTML+='Finished parsing ... Retrieving individual blueprints...<br/>';
  6463. 			// Helper.generateRecipeTable();
  6464. 			System.xmlhttp('index.php?cmd=inventing&subcmd=viewrecipe&recipe_id=' + Helper.recipebook.recipe[0].id, Helper.parseRecipePage, {"recipeIndex": 0});
  6465. 		}
  6466. 	},
  6467.  
  6468. 	parseRecipeItemOrComponent: function(xpath, doc) {
  6469. 		var resultNodes = System.findNodes(xpath, doc);
  6470. 		var results = [];
  6471. 		if (resultNodes) {
  6472. 			for (var i=0; i<resultNodes.length; i++) {
  6473. 				var resultNode = resultNodes[i];
  6474. 				var mouseOver = resultNode.firstChild.firstChild.getAttribute("onmouseover");
  6475. 				var resultAmounts = resultNode.parentNode.nextSibling.textContent;
  6476. 				var mouseOverRX = mouseOver.match(/ajaxLoadCustom\((\d+),\s*-1,\s*2,\s*\d+,\s*\'([a-z0-9]+)\',\s*\'\'\)/i);
  6477. 				var result = {
  6478. 					img: resultNode.firstChild.firstChild.src,
  6479. 					id: mouseOverRX[1],
  6480. 					verify: mouseOverRX[2],
  6481. 					amountPresent: parseInt(resultAmounts.split("/")[0],10),
  6482. 					amountNeeded: parseInt(resultAmounts.split("/")[1],10)
  6483. 				};
  6484. 				results.push(result);
  6485. 			}
  6486. 		}
  6487. 		return results;
  6488. 	},
  6489.  
  6490. 	parseRecipePage: function(responseText, callback) {
  6491. 		var doc=System.createDocument(responseText);
  6492. 		var output=document.getElementById('Helper:RecipeManagerOutput');
  6493. 		var currentRecipeIndex = callback.recipeIndex;
  6494. 		var recipe = Helper.recipebook.recipe[currentRecipeIndex];
  6495.  
  6496. 		output.innerHTML+='Parsing blueprint ' + recipe.name +'...<br/>';
  6497.  
  6498. 		recipe.credits = System.findNodeInt("//tr[td/img/@title='Credits']/td[1]", doc);
  6499. 		recipe.items = Helper.parseRecipeItemOrComponent("//td[contains(@background,'/inventory/2x3.gif')]", doc);
  6500. 		recipe.components  = Helper.parseRecipeItemOrComponent("//td[contains(@background,'/inventory/1x1mini.gif')]", doc);
  6501. 		recipe.target = Helper.parseRecipeItemOrComponent("//td[contains(@background,'/hellforge/2x3.gif')]", doc)[0];
  6502.  
  6503. 		var nextRecipeIndex = currentRecipeIndex+1;
  6504. 		if (nextRecipeIndex<Helper.recipebook.recipe.length) {
  6505. 			var nextRecipe = Helper.recipebook.recipe[nextRecipeIndex];
  6506. 			System.xmlhttp('index.php?cmd=inventing&subcmd=viewrecipe&recipe_id=' + nextRecipe.id, Helper.parseRecipePage, {"recipeIndex": nextRecipeIndex});
  6507. 		}
  6508. 		else {
  6509. 			output.innerHTML+='Finished parsing ... formatting ...';
  6510. 			Helper.recipebook.lastUpdate = new Date();
  6511. 			System.setValueJSON("recipebook", Helper.recipebook);
  6512. 			Helper.generateRecipeTable();
  6513. 		}
  6514. 	},
  6515.  
  6516. 	generateRecipeTable: function() {
  6517. 		var output=document.getElementById('Helper:RecipeManagerOutput');
  6518. 		var result='<table id="Helper:RecipeTable" width="100%"><tr>' +
  6519. 			'<th align="left" colspan="2" sortkey="name">Name</th>' +
  6520. 			'<th align="left">Items</th>' +
  6521. 			'<th align="left">Components</th>' +
  6522. 			'<th align="left">Target</th>' +
  6523. 			'</tr>';
  6524. 		if (!Helper.recipebook) {return;}
  6525.  
  6526. 		var hideRecipes=[];
  6527. 		if (GM_getValue("hideRecipes")) hideRecipes=GM_getValue("hideRecipeNames").split(",");
  6528.  
  6529. 		var recipe;
  6530. 		var c=0;
  6531. 		for (var i=0; i<Helper.recipebook.recipe.length;i++) {
  6532. 			recipe=Helper.recipebook.recipe[i];
  6533. 			c++;
  6534.  
  6535. 			if (hideRecipes.indexOf(recipe.name) == -1) {
  6536. 				result+='<tr class="HelperTableRow'+(1+c % 2)+'" valign="middle">' +
  6537. 					'<td style="border-bottom:1px solid #CD9E4B;"><a href="' + recipe.link + '"><img border="0" align="middle" src="' + recipe.img + '"/></a></td>' +
  6538. 					'<td style="border-bottom:1px solid #CD9E4B;"><a href="' + recipe.link + '">' + recipe.name + '</a></td>';
  6539. 				result += '<td style="border-bottom:1px solid #CD9E4B;">';
  6540. 				if (recipe.items) {
  6541. 					for (var j=0; j<recipe.items.length; j++) {
  6542. 						result += recipe.items[j].amountPresent  + "/" + recipe.items[j].amountNeeded +
  6543. 							' <img border="0" align="middle" onmouseover="ajaxLoadCustom(' +
  6544. 							recipe.items[j].id + ', -1, 2, ' + Layout.playerId() + ', \'' +
  6545. 							recipe.items[j].verify + '\', \'\');" ' +
  6546. 							'src="' + recipe.items[j].img + '"/><br/>';
  6547. 					}
  6548. 				}
  6549. 				result += '</td>';
  6550. 				result += '<td style="border-bottom:1px solid #CD9E4B;">';
  6551. 				if (recipe.components) {
  6552. 					for (j=0; j<recipe.components.length; j++) {
  6553. 						result += recipe.components[j].amountPresent + "/" + recipe.components[j].amountNeeded +
  6554. 							' <img border="0" align="middle" onmouseover="ajaxLoadCustom(' +
  6555. 							recipe.components[j].id + ', -1, 2, ' + Layout.playerId() + ', \'' +
  6556. 							recipe.components[j].verify + '\', \'\');" ' +
  6557. 							'src="' + recipe.components[j].img + '"/><br/>';
  6558. 					}
  6559. 				}
  6560. 				result += '</td>';
  6561. 				result += '<td style="border-bottom:1px solid #CD9E4B;">';
  6562. 				if (recipe.target) {
  6563. 					result += '<img border="0" align="middle" onmouseover="ajaxLoadCustom(' +
  6564. 						recipe.target.id + ', -1, 2, ' + Layout.playerId() + ', \'' +
  6565. 						recipe.target.verify + '\', \'\');" ' +
  6566. 						'src="' + recipe.target.img + '"/>';
  6567. 				}
  6568. 				result += '</td>';
  6569. 				result += '</tr>';
  6570. 			}
  6571. 		}
  6572. 		result+='</table>';
  6573. 		output.innerHTML=result;
  6574.  
  6575. 		Helper.recipebook.lastUpdate = new Date();
  6576. 		System.setValueJSON("recipebook", Helper.recipebook);
  6577.  
  6578. 		var recipeTable=document.getElementById('Helper:RecipeTable');
  6579. 		for (i=0; i<recipeTable.rows[0].cells.length; i++) {
  6580. 			var cell=recipeTable.rows[0].cells[i];
  6581. 			if (cell.getAttribute("sortkey")) {
  6582. 				cell.style.textDecoration="underline";
  6583. 				cell.style.cursor="pointer";
  6584. 				cell.addEventListener('click', Helper.sortRecipeTable, true);
  6585. 			}
  6586. 		}
  6587. 	},
  6588.  
  6589. 	sortRecipeTable: function(evt) {
  6590. 		Helper.recipebook=System.getValueJSON("recipebook");
  6591. 		var headerClicked = evt.target.getAttribute("sortKey");
  6592. 		var sortType = evt.target.getAttribute("sorttype");
  6593. 		if (!sortType) sortType="string";
  6594. 		sortType = sortType.toLowerCase();
  6595. 		if (Helper.sortAsc==undefined) Helper.sortAsc=true;
  6596. 		if (Helper.sortBy && Helper.sortBy==headerClicked) {
  6597. 			Helper.sortAsc=!Helper.sortAsc;
  6598. 		}
  6599. 		Helper.sortBy=headerClicked;
  6600. 		//GM_log(headerClicked)
  6601. 		switch (sortType) {
  6602. 			case "number":
  6603. 				Helper.recipebook.recipe.sort(Helper.numberSort);
  6604. 				break;
  6605. 			default:
  6606. 				Helper.recipebook.recipe.sort(Helper.stringSort);
  6607. 				break;
  6608. 		}
  6609. 		Helper.generateRecipeTable();
  6610. 	},
  6611.  
  6612. 	injectGroupStats: function() {
  6613. 		var attackTitleElement = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'Attack:')]");
  6614. 		attackValueElement = attackTitleElement.nextSibling;
  6615. 		attackValueElement.innerHTML = "<table><tbody><tr><td style='color:blue;'>" + attackValueElement.innerHTML +
  6616. 			"</td><td>(</td><td title='attackValue'>" + attackValueElement.innerHTML +
  6617. 			"</td><td>)</td></tr></tbody></table>";
  6618. 		var defenseTitleElement = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'Defense:')]");
  6619. 		defenseValueElement = defenseTitleElement.nextSibling;
  6620. 		defenseValueElement.innerHTML = "<table><tbody><tr><td style='color:blue;'>" + defenseValueElement.innerHTML +
  6621. 			"</td><td>(</td><td title='defenseValue'>" + defenseValueElement.innerHTML +
  6622. 			"</td><td>)</td></tr></tbody></table>";
  6623. 		var armorTitleElement = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'Armor:')]");
  6624. 		armorValueElement = armorTitleElement.nextSibling;
  6625. 		armorValueElement.innerHTML = "<table><tbody><tr><td style='color:blue;'>" + armorValueElement.innerHTML +
  6626. 			"</td><td>(</td><td title='armorValue'>" + armorValueElement.innerHTML +
  6627. 			"</td><td>)</td></tr></tbody></table>";
  6628. 		var damageTitleElement = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'Damage:')]");
  6629. 		damageValueElement = damageTitleElement.nextSibling;
  6630. 		damageValueElement.innerHTML = "<table><tbody><tr><td style='color:blue;'>" + damageValueElement.innerHTML +
  6631. 			"</td><td>(</td><td title='damageValue'>" + damageValueElement.innerHTML +
  6632. 			"</td><td>)</td></tr></tbody></table>";
  6633. 		var hpTitleElement = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'HP:')]");
  6634. 		hpValueElement = hpTitleElement.nextSibling;
  6635. 		hpValueElement.innerHTML = "<table><tbody><tr><td style='color:blue;'>" + hpValueElement.innerHTML +
  6636. 			"</td><td>(</td><td title='hpValue'>" + hpValueElement.innerHTML +
  6637. 			"</td><td>)</td></tr></tbody></table>";
  6638. 		System.xmlhttp("index.php?cmd=guild&subcmd=mercs", Helper.parseMercStats);
  6639. 	},
  6640.  
  6641. 	parseMercStats: function(responseText) {
  6642. 		var mercPage=System.createDocument(responseText);
  6643. 		var mercElements = mercPage.getElementsByTagName("IMG");
  6644. 		var totalMercAttack = 0;
  6645. 		var totalMercDefense = 0;
  6646. 		var totalMercArmor = 0;
  6647. 		var totalMercDamage = 0;
  6648. 		var totalMercHP = 0;
  6649. 		for (var i=0; i<mercElements.length; i++) {
  6650. 			merc = mercElements[i];
  6651. 			var mouseoverText = merc.getAttribute("onmouseover");
  6652. 			var src = merc.getAttribute("src");
  6653. 			if (mouseoverText && src.search("/merc/") != -1){
  6654. 				//<td>Attack:</td><td>1919</td>
  6655. 				var attackRE=/<td>Attack:<\/td><td>(\d+)<\/td>/;
  6656. 				var mercAttackValue = attackRE.exec(mouseoverText)[1]*1;
  6657. 				totalMercAttack += mercAttackValue;
  6658. 				var defenseRE=/<td>Defense:<\/td><td>(\d+)<\/td>/;
  6659. 				var mercDefenseValue = defenseRE.exec(mouseoverText)[1]*1;
  6660. 				totalMercDefense += mercDefenseValue;
  6661. 				var armorRE=/<td>Armor:<\/td><td>(\d+)<\/td>/;
  6662. 				var mercArmorValue = armorRE.exec(mouseoverText)[1]*1;
  6663. 				totalMercArmor += mercArmorValue;
  6664. 				var damageRE=/<td>Damage:<\/td><td>(\d+)<\/td>/;
  6665. 				var mercDamageValue = damageRE.exec(mouseoverText)[1]*1;
  6666. 				totalMercDamage += mercDamageValue;
  6667. 				var hpRE=/<td>HP:<\/td><td>(\d+)<\/td>/;
  6668. 				var mercHPValue = hpRE.exec(mouseoverText)[1]*1;
  6669. 				totalMercHP += mercHPValue;
  6670. 			}
  6671. 		}
  6672. 		var attackValue        = System.findNode("//td[@title='attackValue']");
  6673. 		attackNumber           = System.intValue(attackValue.innerHTML);
  6674. 		attackValue.innerHTML  = System.addCommas(attackNumber - Math.round(totalMercAttack*0.2));
  6675. 		var defenseValue       = System.findNode("//td[@title='defenseValue']");
  6676. 		defenseNumber          = System.intValue(defenseValue.innerHTML);
  6677. 		defenseValue.innerHTML = System.addCommas(defenseNumber - Math.round(totalMercDefense*0.2));
  6678. 		var armorValue         = System.findNode("//td[@title='armorValue']");
  6679. 		armorNumber            = System.intValue(armorValue.innerHTML);
  6680. 		armorValue.innerHTML   = System.addCommas(armorNumber - Math.round(totalMercArmor*0.2));
  6681. 		var damageValue        = System.findNode("//td[@title='damageValue']");
  6682. 		damageNumber           = System.intValue(damageValue.innerHTML);
  6683. 		damageValue.innerHTML  = System.addCommas(damageNumber - Math.round(totalMercDamage*0.2));
  6684. 		var hpValue            = System.findNode("//td[@title='hpValue']");
  6685. 		hpNumber               = System.intValue(hpValue.innerHTML);
  6686. 		hpValue.innerHTML      = System.addCommas(hpNumber - Math.round(totalMercHP*0.2));
  6687. 	},
  6688.  
  6689. 	injectGroups: function() {
  6690. 		var subTable = System.findNode("//table[@width='650']/tbody/tr/td/table");
  6691. 		if (!subTable) {return;}
  6692. 		var minGroupLevel = GM_getValue("minGroupLevel");
  6693. 		if (minGroupLevel) {
  6694. 			var textArea = subTable.rows[0].cells[0];
  6695. 			textArea.innerHTML += ' <span style="color:blue">Current Min Level Setting: '+ minGroupLevel +'</span>';
  6696. 		}
  6697.  
  6698. 		allItems = System.findNodes("//tr[td/a/img/@title='View Group Stats']");
  6699. 		var memberList=System.getValueJSON("memberlist");
  6700. 		var onlineIMG = '<img src="' + System.imageServer + '/skin/online.gif" width=10 height="10" title="Online">';
  6701. 		var offlineIMG = '<img src="' + System.imageServer + '/skin/offline.gif" width=10 height="10" title="Offline">';
  6702. 		for (i=0; i<allItems.length; i++) {
  6703. 			var theItem=allItems[i].cells[0];
  6704. 			var foundName=theItem.textContent;
  6705. 			if (memberList) {
  6706. 				var listOfDefenders = "", listOfDefendersHTML = "";
  6707. 				for (j=0; j<memberList.members.length; j++) {
  6708. 					var aMember=memberList.members[j];
  6709. 					// I hate doing two loops, but using a hashtable implementation I found crashed my browser...
  6710. 					if (aMember.name==foundName) {
  6711. 						listOfDefendersHTML = allItems[i].cells[1].innerHTML;
  6712. 						if (listOfDefenders.indexOf("<font") != -1) {
  6713. 						listOfDefenders = listOfDefendersHTML.substring(0, listOfDefendersHTML.indexOf("<font") - 2); //strip off mercs as they don't need buffs
  6714. 						} else {
  6715. 							listOfDefenders = listOfDefendersHTML;
  6716. 						}
  6717. 						listOfDefenders = listOfDefenders.split(","); // quick buff only supports 16
  6718. 						if (listOfDefenders == "[none]") break;
  6719. 						theItem.innerHTML = ((aMember.status == "Online")?onlineIMG:offlineIMG) +
  6720. 							//direct call to player_id is faster link - server doesn't have to do a search.
  6721. 							"&nbsp;<span style='font-size:small;'><a href='index.php?cmd=profile&player_id=" + aMember.id + "'>" +
  6722. 							theItem.innerHTML + "</a></span> [" + aMember.level + "]";
  6723. 						var shortList = new Array();
  6724. 						var modifierWord;
  6725. 						for (var k = 0; k < listOfDefenders.length; k++) {
  6726. 							shortList.push(listOfDefenders[k]);
  6727. 							if (((k + 1) % 16 === 0 && k !== 0) || (k == listOfDefenders.length - 1)) {
  6728. 								modifierWord = Helper.getGroupBuffModifierWord(k);
  6729. 								theItem.innerHTML += "<br><nobr><a href='#' id='buffAll" + k + modifierWord + "'><span style='color:blue; font-size:x-small;' title='Quick buff functionality from HCS only does 16'>"+
  6730. 									"Buff " + modifierWord + " 16</span></a></nobr>";
  6731. 								var buffAllLink = System.findNode("//a[@id='buffAll" + k + modifierWord + "']");
  6732. 								buffAllLink.setAttribute("href","javascript:openWindow('index.php?cmd=quickbuff&t=" + shortList + "', 'fsQuickBuff', 618, 1000, ',scrollbars')");
  6733. 								shortList = new Array();
  6734. 							}
  6735. 						}
  6736.  
  6737. 						break;
  6738. 					}
  6739. 				}
  6740. 			}
  6741.  
  6742. 			var theMembersCell=allItems[i].cells[1];
  6743. 			if (theMembersCell.textContent != "[none]") {
  6744. 				var theMembersArray=theMembersCell.innerHTML.split(",");
  6745. 				var linkMembersArray = new Array();
  6746. 				for (k=0; k<theMembersArray.length; k++) {
  6747. 					var theMember = theMembersArray[k].trim();
  6748. 					var linkMember;
  6749. 					if (theMember.search("<font") == -1) {
  6750. 						if (memberList) {
  6751. 							for (j=0; j<memberList.members.length; j++) {
  6752. 								aMember=memberList.members[j];
  6753. 								// I hate doing two loops, but using a hashtable implementation I found crashed my browser...
  6754. 								if (aMember.name==theMember) {
  6755. 									//direct call to player_id is faster link - server doesn't have to do a search.
  6756. 									linkMember = (k===0?"":" ") + "<a href='index.php?cmd=profile&player_id=" + aMember.id + "'>" + theMember + "</a>";
  6757. 									break;
  6758. 								}
  6759. 							}
  6760. 						}
  6761. 					} else {
  6762. 						linkMember = " " + theMember;
  6763. 					}
  6764. 					linkMembersArray.push(linkMember);
  6765. 				}
  6766. 				theMembersCell.innerHTML = linkMembersArray;
  6767. 			}
  6768.  
  6769. 			var theDateCell=allItems[i].cells[2];
  6770. 			var theDate=theDateCell.firstChild;
  6771. 			var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
  6772. 			var xRE=/([a-zA-Z]+), (\d+) ([a-zA-Z]+) (\d+):(\d+):(\d+) UTC/;
  6773. 			var x=xRE.exec(theDate.innerHTML);
  6774. 			var month = months.indexOf(x[3]);
  6775. 			var curYear = new Date().getFullYear();
  6776. 			var groupDate = new Date();
  6777. 			groupDate.setUTCDate(x[2]);
  6778. 			groupDate.setUTCMonth(month);
  6779. 			groupDate.setUTCFullYear(curYear);
  6780. 			groupDate.setUTCHours(x[4]);
  6781. 			groupDate.setUTCMinutes(x[5]);
  6782. 			theDateCell.innerHTML += '<br><nobr><span style="color:blue; font-size:x-small">Local: '+
  6783. 				groupDate.toString().substr(0,21)+'</span></nobr>';
  6784. 		}
  6785. 		var buttonElement = System.findNode("//td[input[@value='Join All Available Groups']]");
  6786. 		var enableMaxGroupSizeToJoin = GM_getValue("enableMaxGroupSizeToJoin");
  6787. 		if (enableMaxGroupSizeToJoin) {
  6788. 			var maxGroupSizeToJoin = GM_getValue("maxGroupSizeToJoin");
  6789. 			var joinAllInput = buttonElement.firstChild.nextSibling.nextSibling;
  6790. 			joinAllInput.style.display = "none";
  6791. 			joinAllInput.style.visibility = "hidden";
  6792. 			buttonElement.innerHTML += '&nbsp;<input id="joinallgroupsundersize" type="button" value="Join All Groups < ' + maxGroupSizeToJoin + 
  6793. 				' Members" class="custombutton">&nbsp;<input id="fetchgroupstats" type="button" value="Fetch Group Stats" class="custombutton">';
  6794. 			document.getElementById('joinallgroupsundersize').addEventListener('click', Helper.joinAllGroupsUnderSize, true);
  6795. 		} else {
  6796. 			buttonElement.innerHTML += '&nbsp;<input id="fetchgroupstats" type="button" value="Fetch Group Stats" class="custombutton">';
  6797. 		}
  6798. 		document.getElementById('fetchgroupstats').addEventListener('click', Helper.fetchGroupData, true);
  6799.  
  6800. 		re=/subcmd2=([a-z]+)/;
  6801. 		var subPage2IdRE = re.exec(document.location.search);
  6802. 		if (subPage2IdRE && subPage2IdRE[1] == 'joinallgroupsundersize') {
  6803. 			Helper.joinAllGroupsUnderSize();
  6804. 		}
  6805. 	},
  6806.  
  6807. 	joinAllGroupsUnderSize: function(evt) {
  6808. 		var joinButtons = System.findNodes("//img[@title='5 Stamina to join Group']");
  6809. 		for (var i=0; i<joinButtons.length; i++) {
  6810. 			var joinButton = joinButtons[i];
  6811. 			var memberList = joinButton.parentNode.parentNode.previousSibling.previousSibling.previousSibling.previousSibling;
  6812. 			var memberListArrayWithMercs = memberList.innerHTML.split(",");
  6813. 			var memberListArrayWithoutMercs = memberListArrayWithMercs.filter(function(e,i,a) {return e.search('#000099') == -1;});
  6814. 			if (memberListArrayWithoutMercs.length < GM_getValue("maxGroupSizeToJoin")) {
  6815. 				var groupID = /confirmJoin\((\d+)\)/.exec(joinButton.parentNode.getAttribute("href"))[1];
  6816. 				var groupJoinURL = 'index.php?cmd=guild&subcmd=groups&subcmd2=join&group_id=' + groupID;
  6817. 				GM_xmlhttpRequest({
  6818. 					method: 'GET',
  6819. 					url: System.server + groupJoinURL,
  6820. 					headers: {
  6821. 						"User-Agent": navigator.userAgent,
  6822. 						"Referer": document.location
  6823. 					},
  6824. 					onload: function(responseDetails) {
  6825. 						joinButton.style.display = "none";
  6826. 						joinButton.style.visibility = "hidden";
  6827. 					}
  6828. 				});
  6829. 			}
  6830. 		}
  6831. 		//refresh after a slight delay
  6832. 		setTimeout("window.location = '" + System.server + "index.php?cmd=guild&subcmd=groups';",1250);
  6833. 	},
  6834.  
  6835. 	fetchGroupData: function(evt) {
  6836. 		var calcButton = System.findNode("//input[@id='fetchgroupstats']");
  6837. 		calcButton.style.display = "none";
  6838. 		var allItems = System.findNodes("//img[@title='View Group Stats']");
  6839. 		for (var i=0; i<allItems.length; i++) {
  6840. 			System.xmlhttp(allItems[i].parentNode.getAttribute("href"), Helper.parseGroupData, allItems[i].parentNode);
  6841. 		}
  6842. 	},
  6843.  
  6844. 	parseGroupData: function(responseText, linkElement) {
  6845. 		var doc=System.createDocument(responseText);
  6846. 		var allItems = doc.getElementsByTagName("TD");
  6847. 		//<td><font color="#333333">Attack:&nbsp;</font></td>
  6848.  
  6849. 		for (var i=0;i<allItems.length;i++) {
  6850. 			var anItem=allItems[i];
  6851. 			if (anItem.innerHTML == '<font color="#333333">Attack:&nbsp;</font>'){
  6852. 				var attackLocation = anItem.nextSibling;
  6853. 				var attackValue = attackLocation.textContent;
  6854. 			}
  6855. 			if (anItem.innerHTML == '<font color="#333333">Defense:&nbsp;</font>'){
  6856. 				var defenseLocation = anItem.nextSibling;
  6857. 				var defenseValue = defenseLocation.textContent;
  6858. 			}
  6859. 			if (anItem.innerHTML == '<font color="#333333">Armor:&nbsp;</font>'){
  6860. 				var armorLocation = anItem.nextSibling;
  6861. 				var armorValue = armorLocation.textContent;
  6862. 			}
  6863. 			if (anItem.innerHTML == '<font color="#333333">Damage:&nbsp;</font>'){
  6864. 				var damageLocation = anItem.nextSibling;
  6865. 				var damageValue = damageLocation.textContent;
  6866. 			}
  6867. 			if (anItem.innerHTML == '<font color="#333333">HP:&nbsp;</font>'){
  6868. 				var hpLocation = anItem.nextSibling;
  6869. 				var hpValue = hpLocation.textContent;
  6870. 			}
  6871. 		}
  6872. 		extraText = "<table cellpadding='1' style='font-size:x-small; border-top:2px black solid; border-spacing: 1px; border-collapse: collapse;'>";
  6873. 		extraText += "<tr>";
  6874. 		extraText += "<td style='color:brown;'>Attack</td><td align='right'>" + attackValue + "</td>";
  6875. 		extraText += "<td style='color:brown;'>Defense</td><td align='right'>" + defenseValue + "</td></tr>";
  6876. 		extraText += "<tr>";
  6877. 		extraText += "<td style='color:brown;'>Armor</td><td align='right'>" + armorValue + "</td>";
  6878. 		extraText += "<td style='color:brown;'>Damage</td><td align='right'>" + damageValue + "</td></tr>";
  6879. 		extraText += "<tr>";
  6880. 		extraText += "<td style='color:brown;'>HP</td><td align='right'>" + hpValue + "</td>";
  6881. 		extraText += "<td colspan='2'></td></tr>";
  6882. 		extraText += "</table>";
  6883. 		expiresLocation = linkElement.parentNode.previousSibling.previousSibling;
  6884. 		expiresLocation.innerHTML += extraText;
  6885. 	},
  6886.  
  6887. 	addMarketplaceWidgets: function() {
  6888. 		var requestTable = System.findNode("//table[tbody/tr/td/input[@value='Confirm Request']]");
  6889. 		var newRow = requestTable.insertRow(2);
  6890. 		var newCell = newRow.insertCell(0);
  6891. 		newCell.id = "warningfield";
  6892. 		newCell.colSpan = "2";
  6893. 		newCell.align = "center";
  6894.  
  6895. 		document.getElementById('price').addEventListener('keyup', Helper.addMarketplaceWarning, true);
  6896. 		document.getElementById('amount').addEventListener('keyup', Helper.addMarketplaceWarning, true);
  6897. 	},
  6898.  
  6899. 	addMarketplaceWarning: function(evt) {
  6900. 		 var amount = System.findNode("//input[@id='amount']").value;
  6901. 		 var goldPerPoint = System.findNode("//input[@id='price']");
  6902. 		 var warningField = System.findNode("//td[@id='warningfield']");
  6903. 		 var sellPrice = goldPerPoint.value;
  6904. 		 if (sellPrice.search(/^[0-9]*$/) != -1) {
  6905. 			var warningColor = "green";
  6906. 			var warningText = "</b><br>This is probably an offer that will please someone.";
  6907. 			if (sellPrice < 100000) {
  6908. 				warningColor = "brown";
  6909. 				warningText = "</b><br>This is too low ... it just ain't gonna sell.";
  6910. 			} else if (sellPrice > 200000) {
  6911. 				warningColor = "red";
  6912. 				warningText = "</b><br>Hold up there ... this is way to high a price ... you should reconsider.";
  6913. 			}
  6914.  
  6915. 			warningField.innerHTML = "<span style='color:" + warningColor + ";'>You are offering to buy <b>" + amount + "</b> FSP for >> <b>" +
  6916. 				System.addCommas(sellPrice) + warningText + " (Total: " + System.addCommas((amount * sellPrice) + Math.ceil(sellPrice * 0.005)) +  ")</span>";
  6917. 		}
  6918. 	},
  6919.  
  6920. 	injectQuickBuff: function() {
  6921. 		GM_addStyle('.HelperTextLink {color:white;font-size:x-small;cursor:pointer;}\n' +
  6922. 			'.HelperTextLink:hover {text-decoration:underline;}\n');
  6923. 		var playerInput = System.findNode("//input[@name='targetPlayers']");
  6924. 		if (!playerInput) return;
  6925. 		var buffMe = document.createElement("SPAN");
  6926. 		buffMe.innerHTML="[self]";
  6927. 		buffMe.className='HelperTextLink';
  6928. 		buffMe.addEventListener("click", Helper.quickBuffMe, true);
  6929. 		playerInput.parentNode.appendChild(buffMe);
  6930.  
  6931. 		Helper.injectBuffPackArea();
  6932.  
  6933. 		var playerIDRE = /tid=(\d+)/;
  6934. 		var playerID = playerIDRE.exec(location);
  6935. 		if (playerID) {
  6936. 			playerID = playerID[1];
  6937. 			System.xmlhttp("index.php?cmd=profile&player_id=" + playerID, Helper.getPlayerBuffs, false);
  6938. 		}
  6939. 		var playerName = /quickbuff&t=([a-zA-Z0-9]+)/.exec(location);
  6940. 		if (playerName) {
  6941. 			playerName = playerName[1];
  6942. 			System.xmlhttp("index.php?cmd=findplayer&search_active=1&search_username=" + playerName + "&search_show_first=1", Helper.getPlayerBuffs, false);
  6943. 		}
  6944. 		System.xmlhttp("index.php?cmd=profile", Helper.getSustain);
  6945.  
  6946. 		var buffList = Data.buffList();
  6947. 		var skillNodes = System.findNodes("//input[@name='skills[]']");
  6948. 		var buffIndex = new String(window.location).indexOf("&blist=");
  6949. 		var addr;
  6950.  
  6951. 		if (buffIndex != -1) {
  6952. 			addr = new String(window.location).substring(buffIndex + 7);
  6953. 			addr = addr.substring(0, addr.length - 1).split(";");
  6954. 		}
  6955. 		var buffPacksToUse = new Array();
  6956. 		if (skillNodes) {
  6957. 			var targetPlayers = System.findNode("//input[@name='targetPlayers']");
  6958. 			var targetPlayersCount = targetPlayers.value.split(",").length*1;
  6959. 			var newStaminaTotal = 0;
  6960. 			var theBuffPack = System.getValueJSON("buffpack"); // cache it now in case we have a buff pack to find.
  6961. 			for (var i = 0; i < skillNodes.length; i++ ) {
  6962. 				var skillName = skillNodes[i].parentNode.parentNode.textContent.match(/\t([A-Z].*) \[/)[1];
  6963. 				skillNodes[i].setAttribute("skillName", skillName);
  6964. 				for (var k = 0; k < buffList.length; k++) {
  6965. 					if (buffList[k].name == skillName) {
  6966. 						if (addr) {
  6967. 							for (var p = 0; p < addr.length; p++) {
  6968.  
  6969. 								if (addr[p] == k) {
  6970.  
  6971. 									newStaminaTotal += buffList[k].stamina*1;
  6972. 									skillNodes[i].checked = true;
  6973. 								} else if (addr[p] >= 82) {
  6974. 									if (theBuffPack) {
  6975.  
  6976. 										var bpIndex = addr[p] - 82;
  6977. 										var bpButton = document.getElementById("bpSelect" + bpIndex);
  6978.  
  6979. 										if (bpButton) {
  6980. 											var foundMe = false;
  6981. 											for (var indx = 0; indx < buffPacksToUse.length; indx++) {
  6982. 												if (buffPacksToUse[indx] == bpIndex) {
  6983. 													foundMe = true;
  6984. 													break;
  6985. 												}
  6986. 											}
  6987. 											if (!foundMe) {
  6988. 												buffPacksToUse.push(bpIndex);
  6989. 											}
  6990. 											continue;
  6991. 										}
  6992. 									}
  6993. 								}
  6994. 							}
  6995. 						}
  6996. 						skillNodes[i].setAttribute("staminaCost",buffList[k].stamina);
  6997. 						break;
  6998. 					}
  6999. 				}
  7000. 				skillNodes[i].addEventListener("click", Helper.toggleBuffStatus, true);
  7001. 			}
  7002. 		}
  7003. 		var activateButton = System.findNode("//input[@value='Activate Selected Skills']");
  7004. 		activateButton.parentNode.innerHTML += "<br><span style='color:white;'>Stamina to cast selected skills: <span>" +
  7005. 			"<span id='staminaTotal' style='display:none; color:orange;'>" + newStaminaTotal +
  7006. 			"</span>&nbsp;<span id='staminaTotalAll' style='color:orange;'>" + newStaminaTotal * targetPlayersCount + "</span>";
  7007. 		if (buffPacksToUse.length > 0) {
  7008. 			for (i = 0; i < buffPacksToUse.length; i++ ) {
  7009. 				Helper.useBuffPack(buffPacksToUse[i]);
  7010. 			}
  7011. 		}
  7012. 	},
  7013.  
  7014. 	toggleBuffStatus: function(evt) {
  7015. 		var staminaTotal = System.findNode("//span[@id='staminaTotal']");
  7016. 		var staminaTotalAll = System.findNode("//span[@id='staminaTotalAll']");
  7017. 		var targetPlayers = System.findNode("//input[@name='targetPlayers']");
  7018. 		var targetPlayersCount = targetPlayers.value.split(",").length*1;
  7019. 		var newStaminaTotal = 0;
  7020. 		if (evt.target.checked === false) {
  7021. 			evt.target.checked = false;
  7022. 			newStaminaTotal = ((staminaTotal.textContent*1) - (evt.target.getAttribute("staminaCost")*1));
  7023. 			staminaTotal.innerHTML = newStaminaTotal;
  7024. 			staminaTotalAll.innerHTML = newStaminaTotal * targetPlayersCount;
  7025. 		}
  7026. 		else if (evt.target.checked === true) {
  7027. 			evt.target.checked = true;
  7028. 			newStaminaTotal = ((staminaTotal.textContent*1) + (evt.target.getAttribute("staminaCost")*1));
  7029. 			staminaTotal.innerHTML = newStaminaTotal;
  7030. 			staminaTotalAll.innerHTML = newStaminaTotal * targetPlayersCount;
  7031. 		}
  7032. 	},
  7033.  
  7034. 	injectBuffPackArea: function() {
  7035. 		Helper.injectBuffPackList();
  7036. 		Helper.injectBuffPackAddButton();
  7037. 	},
  7038.  
  7039. 	injectBuffPackList: function() {
  7040. 		var injectHere = System.findNode("//input[@value='Activate Selected Skills']/parent::*/parent::*");
  7041. 		var bpArea = document.createElement("SPAN");
  7042. 		bpArea.innerHTML="<br><div align='center'><span style='color:lime; font-size:large;'>Buff Packs</span><table id='bpTable' width='600' style='border:1px solid #A07720;' rules=rows><tbody>" +
  7043. 			"<tr><td style='color:gold; font-weight:bold;'>Nickname</td><td style='color:gold; font-weight:bold;'>Buffs included in the pack</td>" +
  7044. 			"<td><span id=bpSelectAll class='HelperTextLink'>[All]</span>&nbsp;<span id=bpClear class='HelperTextLink'>[Clear]</span></td></tr>" +
  7045. 			"</tbody></table></div>";
  7046. 		bpArea.style.color="white";
  7047. 		injectHere.appendChild(bpArea);
  7048.  
  7049. 		document.getElementById("bpSelectAll").addEventListener("click", function() {Helper.setAllSkills(true);}, false);
  7050. 		document.getElementById("bpClear").addEventListener("click", function() {Helper.setAllSkills(false);}, false);
  7051.  
  7052. 		var theBuffPack = System.getValueJSON("buffpack");
  7053. 		if (!theBuffPack) {return;}
  7054.  
  7055. 		if (!theBuffPack["nickname"]) { //avoid bugs if the new array is not populated yet
  7056. 			theBuffPack["nickname"] = {};
  7057. 		}
  7058. 		if (!theBuffPack["staminaTotal"]) { //avoid bugs if the new array is not populated yet
  7059. 			theBuffPack["staminaTotal"] = {};
  7060. 		}
  7061.  
  7062. 		var bpTable = document.getElementById("bpTable");
  7063. 		for (var i = 0; i < theBuffPack["size"]; i++) {
  7064. 			var myRow = bpTable.insertRow(-1);
  7065. 			var nickname = (theBuffPack["nickname"][i]? theBuffPack["nickname"][i]:"");
  7066. 			var listOfBuffs = theBuffPack["bp"][i];
  7067. 			var staminaTotal = (theBuffPack["staminaTotal"][i]? theBuffPack["staminaTotal"][i]:"");
  7068. 			myRow.innerHTML = "<td>" + nickname + "</td><td style='font-size:x-small;'>" + listOfBuffs + "&nbsp;" + staminaTotal + "&nbsp;" +
  7069. 				"</td><td><span id=bpSelect" + i + " class='HelperTextLink' buffId=" + i + ">[Select]</span> " +
  7070. 				"<span id=bpDelete" + i + " buffId=" + i + " class='HelperTextLink'>[X]</span></td>";
  7071. 			document.getElementById("bpSelect" + i).addEventListener("click", Helper.useBuffPackHandler, true);
  7072. 			document.getElementById("bpDelete" + i).addEventListener("click", Helper.deleteBuffPack, true);
  7073. 		}
  7074. 	},
  7075.  
  7076. 	setAllSkills: function(value) {
  7077. 		var skillNodes = System.findNodes("//input[@name='skills[]']");
  7078. 		if (!skillNodes) {return;}
  7079.  
  7080. 		for (var i = 0; i < skillNodes.length; i++ ) {
  7081. 			skillNodes[i].checked = value;
  7082. 		}
  7083. 		Helper.sumStamCostOfSelectedBuffs();
  7084. 	},
  7085.  
  7086. 	sumStamCostOfSelectedBuffs: function() {
  7087. 		var skillNodes = System.findNodes("//input[@name='skills[]']");
  7088. 		if (!skillNodes) {return;}
  7089.  
  7090. 		staminaRunningTotal = 0;
  7091. 		for (var i = 0; i < skillNodes.length; i++ ) {
  7092. 			if (skillNodes[i].checked) {
  7093. 				staminaRunningTotal += (skillNodes[i].getAttribute("staminaCost")*1);
  7094. 			}
  7095. 		}
  7096.  
  7097. 		var staminaTotal = System.findNode("//span[@id='staminaTotal']");
  7098. 		staminaTotal.innerHTML = staminaRunningTotal;
  7099. 		var staminaTotalAll = System.findNode("//span[@id='staminaTotalAll']");
  7100. 		var targetPlayers = System.findNode("//input[@name='targetPlayers']");
  7101. 		var targetPlayersCount = targetPlayers.value.split(",").length*1;
  7102. 		staminaTotalAll.innerHTML = staminaRunningTotal * targetPlayersCount;
  7103. 	},
  7104.  
  7105. 	useBuffPackHandler: function(evt) {
  7106. 		var bpIndex=evt.target.getAttribute("buffId");
  7107. 		Helper.useBuffPack(bpIndex);
  7108. 	},
  7109.  
  7110. 	useBuffPack: function(bpIndex) {
  7111.  
  7112. 		var theBuffPack = System.getValueJSON("buffpack");
  7113. 		if (!theBuffPack) {return;}
  7114. 		if (bpIndex >= theBuffPack["size"]) {return;}
  7115.  
  7116. 		var buffList = theBuffPack["bp"][bpIndex];
  7117. 		if (!buffList) {return;}
  7118.  
  7119. 		var skillNodes = System.findNodes("//input[@name='skills[]']");
  7120. 		if (!skillNodes) {return;}
  7121.  
  7122. 		for (var i = 0; i < skillNodes.length; i++ ) {
  7123. 			var skillName = skillNodes[i].parentNode.parentNode.textContent.match(/\t([A-Z].*) \[/)[1];
  7124. 			if (buffList.indexOf(skillName) >= 0) {
  7125. 				skillNodes[i].checked = true;
  7126. 			}
  7127. 		}
  7128. 		Helper.sumStamCostOfSelectedBuffs();
  7129. 	},
  7130.  
  7131. 	deleteBuffPack: function(evt) {
  7132.  
  7133. 		if (!window.confirm("Are you sure you want to delete the buff pack?")) {return;}
  7134.  
  7135. 		var bpIndex=parseInt(evt.target.getAttribute("buffId"),10);
  7136. 		var theBuffPack = System.getValueJSON("buffpack");
  7137. 		if (!theBuffPack) {return;}
  7138. 		if (!theBuffPack["size"]) {return;}
  7139.  
  7140. 		theBuffPack["size"] --;
  7141. 		if (theBuffPack["size"] === 0) { // avoid bugs :)
  7142. 			delete theBuffPack["bp"];
  7143. 			delete theBuffPack["nickname"];
  7144. 			delete theBuffPack["staminaTotal"];
  7145. 			theBuffPack["bp"] = {};
  7146. 			theBuffPack["nickname"] = {};
  7147. 			theBuffPack["staminaTotal"] = {};
  7148. 		}
  7149. 		if (!theBuffPack["nickname"]) { //avoid bugs
  7150. 			theBuffPack["nickname"] = {};
  7151. 		}
  7152. 		if (!theBuffPack["staminaTotal"]) { //avoid bugs
  7153. 			theBuffPack["staminaTotal"] = {};
  7154. 		}
  7155. 		for (var i = bpIndex; i < theBuffPack["size"]; i++) {
  7156. 			theBuffPack["bp"][i] = theBuffPack["bp"][i + 1];
  7157. 			//old buff packs won't have the next two values.
  7158. 			theBuffPack["nickname"][i] = (theBuffPack["nickname"][i + 1]? theBuffPack["nickname"][i + 1]:"");
  7159. 			theBuffPack["staminaTotal"][i] = (theBuffPack["staminaTotal"][i + 1]? theBuffPack["staminaTotal"][i + 1]:"");
  7160. 		}
  7161.  
  7162. 		delete theBuffPack["bp"][theBuffPack["size"]];
  7163. 		if (theBuffPack["nickname"][theBuffPack["size"]]) delete theBuffPack["nickname"][theBuffPack["size"]];
  7164. 		if (theBuffPack["staminaTotal"][theBuffPack["size"]]) delete theBuffPack["staminaTotal"][theBuffPack["size"]];
  7165.  
  7166. 		System.setValueJSON("buffpack", theBuffPack);
  7167. 		location.reload(true);
  7168. 	},
  7169.  
  7170. 	injectBuffPackAddButton: function() {
  7171. 		var bpTable = document.getElementById("bpTable");
  7172. 		var myRow = bpTable.insertRow(-1);
  7173. 		myRow.innerHTML = "<td><input size=10 id='newBuffPackNickname' name='newBuffPackNickname' value='nickname'></td>"+
  7174. 			"<td><input size=60 id='newBuffPack' name='newBuffPack' value='full buff names, separated by comma'></td>" +
  7175. 			"<td><span id=bpSave class='HelperTextLink'>[Save]</span><span id=bpAdd class='HelperTextLink'>[add]</span></td>";
  7176.  
  7177. 		// button handlers
  7178. 		document.getElementById("bpAdd").addEventListener("click", Helper.displayAddBuffPack, true);
  7179. 		document.getElementById("bpSave").addEventListener("click", Helper.saveBuffPack, true);
  7180.  
  7181. 		// display [add] only
  7182. 		document.getElementById("newBuffPack").style.visibility = "hidden";
  7183. 		document.getElementById("newBuffPackNickname").style.visibility = "hidden";
  7184. 		document.getElementById("bpAdd").style.visibility = "";
  7185. 		document.getElementById("bpSave").style.visibility = "hidden";
  7186. 	},
  7187.  
  7188. 	displayAddBuffPack: function() {
  7189. 		var skillNodes = System.findNodes("//input[@name='skills[]']");
  7190. 		if (!skillNodes) {return;}
  7191. 		var buffListBox = document.getElementById("newBuffPack");
  7192. 		var buffListText = "";
  7193. 		for (var i = 0; i < skillNodes.length; i++ ) {
  7194. 			var skillName = skillNodes[i].parentNode.parentNode.textContent.match(/\t([A-Z].*) \[/)[1];
  7195. 			if (skillNodes[i].checked === true) {
  7196. 				buffListText += skillName + ",";
  7197. 			}
  7198. 		}
  7199. 		if (buffListText.length > 0) {
  7200. 			buffListText = buffListText.substring(0,buffListText.lastIndexOf(','));
  7201. 			buffListBox.value = buffListText;
  7202. 		}
  7203. 		document.getElementById("newBuffPack").style.visibility = "";
  7204. 		document.getElementById("newBuffPackNickname").style.visibility = "";
  7205. 		document.getElementById("bpAdd").style.visibility = "hidden";
  7206. 		document.getElementById("bpSave").style.visibility = "";
  7207. 	},
  7208.  
  7209. 	saveBuffPack: function() {
  7210. 		if (!document.getElementById("newBuffPack").value) {return;}
  7211. 		if (!document.getElementById("newBuffPackNickname").value) {return;}
  7212.  
  7213. 		var theBuffPack = System.getValueJSON("buffpack");
  7214. 		if (!theBuffPack) {
  7215. 			theBuffPack = {};
  7216. 			theBuffPack["size"] = 0;
  7217. 			theBuffPack["bp"] = {};
  7218. 			theBuffPack["nickname"] = {};
  7219. 			theBuffPack["staminaTotal"] = {};
  7220. 		}
  7221. 		if (!theBuffPack["nickname"]) { //avoid bugs
  7222. 			theBuffPack["nickname"] = {};
  7223. 		}
  7224. 		if (!theBuffPack["staminaTotal"]) { //avoid bugs
  7225. 			theBuffPack["staminaTotal"] = {};
  7226. 		}
  7227. 		theBuffPack["bp"][theBuffPack["size"]] = document.getElementById("newBuffPack").value;
  7228. 		theBuffPack["nickname"][theBuffPack["size"]] = document.getElementById("newBuffPackNickname").value;
  7229. 		var listOfBuffs = theBuffPack["bp"][theBuffPack["size"]];
  7230. 		var buffArray = listOfBuffs.split(",");
  7231. 		var buffList = Data.buffList();
  7232. 		var staminaTotal = 0;
  7233. 		for (var j = 0; j < buffArray.length; j++) {
  7234. 			for (var k = 0; k < buffList.length; k++) {
  7235. 				if (buffArray[j].trim() == buffList[k].name) {
  7236. 					staminaTotal += buffList[k].stamina;
  7237. 					break;
  7238. 				}
  7239. 			}
  7240. 		}
  7241. 		theBuffPack["staminaTotal"][theBuffPack["size"]] = "<span style='color:orange;'>(" + staminaTotal + ")</span>";
  7242.  
  7243. 		//increase the size of the array
  7244. 		theBuffPack["size"] += 1;
  7245.  
  7246. 		// save and reload
  7247. 		System.setValueJSON("buffpack", theBuffPack);
  7248. 		location.reload(true);
  7249. 	},
  7250.  
  7251. 	quickBuffMe: function() {
  7252. 		var playerInput = System.findNode("//input[@name='targetPlayers']");
  7253. 		playerInput.value=GM_getValue("CharacterName");
  7254. 		if (Helper.tmpSelfProfile) {
  7255. 			Helper.getPlayerBuffs(Helper.tmpSelfProfile, true);
  7256. 		}
  7257. 	},
  7258.  
  7259. 	getPlayerBuffs: function(responseText, keepPlayerInput) {
  7260. 		var injectHere = System.findNode("//input[@value='Activate Selected Skills']/parent::*/parent::*");
  7261. 		var resultText = "<table align='center'><tr><td colspan='4' style='color:lime;font-weight:bold'>Buffs already on player:</td></tr>";
  7262.  
  7263. 		if (keepPlayerInput) {
  7264. 			var playerInput = System.findNode("//input[@name='targetPlayers']");
  7265. 			var playerName = playerInput.value;
  7266. 		}
  7267.  
  7268. 		//low level buffs used to get the buff above are not really worth casting.
  7269. 		var buffs = Data.buffList();
  7270. 		var myBuffs = System.findNodes("//font[@size='1']");
  7271. 		for (var i=0;i<myBuffs.length;i++) {
  7272. 			var myBuff=myBuffs[i];
  7273. 			var myBuffName = /([ a-zA-Z]+)\s\[/.exec(myBuff.innerHTML)[1];
  7274. 			var buffFound = false;
  7275. 			for (var j=0;j<buffs.length;j++) {
  7276. 				buffName = buffs[j].name;
  7277. 				if (myBuffName == buffName) {
  7278. 					var onmouseoverText='Tip(\'' +
  7279. 						'<span style=\\\'font-weight:bold; color:#FFF380;\\\'>' + buffName + '</span><br /><br />Stamina: ' +
  7280. 						buffs[j].stamina + '<br>Duration: ' +
  7281. 						buffs[j].duration + '<br>Effect: ' +
  7282. 						buffs[j].buff + '\');';
  7283. 					myBuff.setAttribute("onmouseover", onmouseoverText);
  7284. 					buffFound = true;
  7285. 					break;
  7286. 				}
  7287. 			}
  7288. 			if (!buffFound) GM_log("Buff typo in data file: '" + myBuffName + "'");
  7289. 			var buffLevelRE = /\[(\d+)\]/;
  7290. 			var buffLevel = buffLevelRE.exec(myBuff.innerHTML)[1]*1;
  7291. 			if (buffLevel < 75 &&
  7292. 				myBuff.innerHTML.search("Counter Attack") == -1 && myBuff.innerHTML.search("Quest Finder") == -1 &&
  7293. 				myBuff.innerHTML.search("Death Dealer") == -1 && myBuff.innerHTML.search("Vision") == -1) {
  7294. 				myBuff.style.color = "gray";
  7295. 			}
  7296. 		}
  7297.  
  7298. 		//this could be formatted better ... it looks ugly but my quick attempts at putting it in a table didn't work.
  7299. 		var doc=System.createDocument(responseText);
  7300. 		buffs = System.findNodes("//img[contains(@onmouseover,'tt_setWidth(105)')]", doc);
  7301. 		if (buffs) {
  7302. 			var buffRE, buff, buffName;
  7303. 			for (i=0;i<buffs.length;i++) {
  7304. 				var aBuff=buffs[i];
  7305. 				var onmouseover = aBuff.getAttribute("onmouseover");
  7306. 				if (onmouseover.search("Summon Shield Imp") != -1) {
  7307. 					//tt_setWidth(105); Tip('<center><b>Summon Shield Imp<br>6 HP remaining<br></b> (Level: 150)</b></center>');
  7308. 					//tt_setWidth(105); Tip('<center><b>Summon Shield Imp<br> HP remaining<br></b> (Level: 165)</b></center>');
  7309. 					buffRE = /<b>([ a-zA-Z]+)<br>([0-9]+) HP remaining<br><\/b> \(Level: (\d+)\)/;
  7310. 					buff = buffRE.exec(onmouseover);
  7311. 					if (!buff) {
  7312. 						buffRE = /<b>([ a-zA-Z]+)<br> HP remaining<br><\/b> \(Level: (\d+)\)/;
  7313. 						buff = buffRE.exec(onmouseover);
  7314. 					}
  7315. 					if (!buff) GM_log(onmouseover);
  7316. 					buffName = buff[1];
  7317. 					buffLevel = buff[3];
  7318. 				} else {
  7319. 					buffRE = /<b>([ a-zA-Z]+)<\/b> \(Level: (\d+)\)/;
  7320. 					buff = buffRE.exec(onmouseover);
  7321. 					buffName = buff[1];
  7322. 					buffLevel = buff[2];
  7323. 				}
  7324. 				if (!buffLevel) buffLevel = 0; //For when a shield imp runs out but the buff is still there (0HP)
  7325. 				resultText += ((i % 4 === 0)? "<tr>":"");
  7326. 				resultText += "<td style='color:white; font-size:x-small'>" + buffName + "</td><td style='color:silver; font-size:x-small'>[" + buffLevel + "]</td>";
  7327. 				resultText += ((i % 4 == 3)? "</tr>":"");
  7328. 				var hasThisBuff = System.findNode("//font[contains(.,'" + buffName + "')]");
  7329. 				if (hasThisBuff) {
  7330. 					buffLevelRE = /\[(\d+)\]/;
  7331. 					var myBuffLevel = parseInt(buffLevelRE.exec(hasThisBuff.innerHTML)[1],10);
  7332. 					if (myBuffLevel > 11 ||
  7333. 						buffName == 'Quest Finder') {
  7334. 						hasThisBuff.style.color='lime';
  7335. 						hasThisBuff.innerHTML += " (<font color='#FFFF00'>" + buffLevel + "</font>)";
  7336. 					}
  7337. 				}
  7338. 			}
  7339. 			resultText += ((i % 4 == 3)? "<td></td></tr>":"");
  7340. 		} else {
  7341. 			resultText += "<tr><td colspan='4' style='text-align:center;color:white; font-size:x-small'>[no buffs]</td></tr>";
  7342. 		}
  7343.  
  7344. 		//var playerLevel=Helper.findNodeText("//td[contains(b,'Level:')]/following-sibling::td[1]", doc);
  7345. 		//var playerXP=Helper.findNodeText("//td[contains(b,'XP:')]/following-sibling::td[1]", doc);
  7346. 		resultText += "</table>";
  7347.  
  7348. 		var statistics = System.findNode("//div[strong[contains(.,'Statistics')]]/following-sibling::div[1]/table", doc);
  7349. 		statistics.style.backgroundImage = 'url(' + System.imageServer + '/skin/realm_top_b2.jpg)'; //Color='white';
  7350. 		var staminaCell = statistics.rows[7].cells[1].firstChild.rows[0].cells[0];
  7351. 		var curStamina = System.intValue(staminaCell.textContent.split("/")[0]);
  7352. 		var maxStamina = System.intValue(staminaCell.textContent.split("/")[1]);
  7353. 		staminaCell.textContent += "(" + Math.round((100.0*curStamina)/(1.0*maxStamina)) + "%)";
  7354.  
  7355. 		var lastActivity = System.findNode("//font[contains(.,'Last Activity:')]", doc);
  7356. 		if (lastActivity) {
  7357. 			var newRow = statistics.insertRow(0);
  7358. 			var newCell = newRow.insertCell(0);
  7359. 			newCell.setAttribute('colspan', '4');
  7360. 			newCell.style.textAlign='center';
  7361. 			newCell.innerHTML=lastActivity.innerHTML + '<br/>';
  7362. 		}
  7363.  
  7364. 		resultText += statistics.parentNode.innerHTML;
  7365.  
  7366. 		// injectHere.innerHTML += "<br/><span style='color:lime;font-weight:bold'>Buffs already on player:</span><br/>"
  7367. 		// injectHere.innerHTML += resultText; // "<br/><span style='color:lime;font-weight:bold'>Buffs already on player:</span><br/>"
  7368. 		var newNode = document.createElement("SPAN");
  7369. 		newNode.innerHTML = resultText;
  7370. 		injectHere.appendChild(newNode);
  7371.  
  7372. 		if (keepPlayerInput) {
  7373. 			playerInput = System.findNode("//input[@name='targetPlayers']");
  7374. 			playerInput.value = playerName;
  7375. 		}
  7376. 	},
  7377.  
  7378. 	getSustain: function(responseText) {
  7379. 		var doc=System.createDocument(responseText);
  7380. 		Helper.tmpSelfProfile=responseText;
  7381. 		var sustainText = System.findNode("//a[contains(@onmouseover,'<b>Sustain</b>')]", doc);
  7382. 		if (!sustainText) {return;}
  7383. 		var sustainMouseover = sustainText.parentNode.parentNode.parentNode.nextSibling.nextSibling.firstChild.getAttribute("onmouseover");
  7384. 		var sustainLevelRE = /Level<br>(\d+)%/;
  7385. 		var sustainLevel = sustainLevelRE.exec(sustainMouseover)[1];
  7386. 		var sustainColor = "lime";
  7387. 		if (sustainLevel < 100) sustainColor = "red";
  7388. 		var activateInput = System.findNode("//input[@value='activate']");
  7389. 		var inputTable = activateInput.nextSibling.nextSibling;
  7390. 		var injectHere = inputTable.rows[3].cells[0];
  7391. 		injectHere.align = "center";
  7392. 		injectHere.innerHTML += "&nbsp;<span style='color:orange;'>Sustain:</span> <span style='color:" + sustainColor + ";'>" + sustainLevel + "%</span>";
  7393. 		var furyCasterText = System.findNode("//a[contains(@onmouseover,'<b>Fury Caster</b>')]", doc);
  7394. 		if (!furyCasterText) {return;}
  7395. 		var furyCasterMouseover = furyCasterText.parentNode.parentNode.parentNode.nextSibling.nextSibling.firstChild.getAttribute("onmouseover");
  7396. 		var furyCasterLevelRE = /Level<br>(\d+)%/;
  7397. 		var furyCasterLevel = furyCasterLevelRE.exec(furyCasterMouseover)[1];
  7398. 		var furyCasterColor = "lime";
  7399. 		if (furyCasterLevel < 100) furyCasterColor = "red";
  7400. 		injectHere.innerHTML += "&nbsp;<span style='color:orange;'>Fury Caster:</span> <span style='color:" + furyCasterColor + ";'>" + furyCasterLevel + "%</span>";
  7401. 		var hasBuffMasterBuff = System.findNode("//img[contains(@onmouseover,'Buff Master')]", doc);
  7402. 		if (hasBuffMasterBuff) {
  7403. 			injectHere.innerHTML += "&nbsp;<span style='color:orange;'>Buff Master:</span>	<span style='color:lime;'>On</span>";
  7404. 			var buffMasterTimeToExpire = hasBuffMasterBuff.parentNode.nextSibling.nextSibling.innerHTML;
  7405. 			injectHere.innerHTML += "&nbsp;<span style='color:white; font-size:x-small;'>(" + buffMasterTimeToExpire +")</span>";
  7406. 		}
  7407. 		else {
  7408. 			injectHere.innerHTML += " <span style='color:orange;'>Buff Master:</span> <span style='color:red;'>Off</span>";
  7409. 		}
  7410. 		var hasExtendBuff = System.findNode("//img[contains(@onmouseover,'Extend')]", doc);
  7411. 		if (hasExtendBuff) {
  7412. 			injectHere.innerHTML += "&nbsp;<span style='color:orange;'>Extend:</span>	<span style='color:lime;'>On</span>";
  7413. 			var ExtendTimeToExpire = hasExtendBuff.parentNode.nextSibling.nextSibling.innerHTML;
  7414. 			injectHere.innerHTML += "&nbsp;<span style='color:white; font-size:x-small;'>(" + ExtendTimeToExpire +")</span>";
  7415. 		}
  7416. 		else {
  7417. 			injectHere.innerHTML += " <span style='color:orange;'>Extend:</span> <span style='color:red;'>Off</span>";
  7418. 		}
  7419. 		var canCastCounterAttack = System.findNode("//td/font[contains(.,'Counter Attack')]");
  7420. 		if (canCastCounterAttack) System.xmlhttp("index.php?cmd=settings", Helper.getCounterAttackSetting);
  7421.  
  7422. 		//refresh ally/enemy list while you are here.
  7423. 		Helper.parseProfileForWorld(doc.innerHTML, true);
  7424. 	},
  7425.  
  7426. 	getCounterAttackSetting: function(responseText) {
  7427. 		var doc=System.createDocument(responseText);
  7428. 		var counterAttackTextElement = System.findNode("//input[@name='ca_default']", doc);
  7429. 		if (!counterAttackTextElement) {return;}
  7430. 		var counterAttackValue = counterAttackTextElement.getAttribute("value");
  7431. 		var activateInput = System.findNode("//input[@value='activate']");
  7432. 		var inputTable = activateInput.nextSibling.nextSibling;
  7433. 		var injectHere = inputTable.rows[3].cells[0];
  7434. 		injectHere.innerHTML += "&nbsp;<span style='color:orange;'>Default CA level:</span> <span style='color:white;'>" + counterAttackValue + "</span>";
  7435. 	},
  7436.  
  7437. 	getKillStreak: function(responseText) {
  7438. 		var doc=System.createDocument(responseText);
  7439. 		//Kill&nbsp;Streak:&nbsp;
  7440. 		var killStreakText = System.findNode("//b[contains(.,'Kill')]", doc);
  7441. 		if (killStreakText) {
  7442. 			var killStreakLocation = killStreakText.parentNode.nextSibling;
  7443. 			var playerKillStreakValue = System.intValue(killStreakLocation.textContent);
  7444. 		}
  7445. 		var killStreakElement = System.findNode("//span[@findme='killstreak']");
  7446. 		killStreakElement.innerHTML = System.addCommas(playerKillStreakValue);
  7447. 		GM_setValue("lastKillStreak", playerKillStreakValue);
  7448. 		var deathDealerBuff = System.findNode("//img[contains(@onmouseover,'Death Dealer')]");
  7449. 		var deathDealerRE = /<b>Death Dealer<\/b> \(Level: (\d+)\)/;
  7450. 		var deathDealer = deathDealerRE.exec(deathDealerBuff.getAttribute("onmouseover"));
  7451. 		if (deathDealer) {
  7452. 			var deathDealerLevel = deathDealer[1];
  7453. 			var deathDealerPercentage = (Math.min(Math.round(Math.floor(playerKillStreakValue/5) * deathDealerLevel) * 0.01, 20));
  7454. 		}
  7455. 		var deathDealerPercentageElement = System.findNode("//span[@findme='damagebonus']");
  7456. 		deathDealerPercentageElement.innerHTML = deathDealerPercentage;
  7457. 		GM_setValue("lastDeathDealerPercentage", deathDealerPercentage);
  7458.  
  7459. 		//refresh ally/enemy list while you are here.
  7460. 		Helper.parseProfileForWorld(doc.innerHTML, true);
  7461. 	},
  7462.  
  7463. 	injectCreature: function() {
  7464. 		System.xmlhttp("index.php?cmd=profile", Helper.getCreaturePlayerData,
  7465. 			{"groupExists": false, "groupAttackValue": 0, "groupDefenseValue": 0,
  7466. 				"groupArmorValue": 0, "groupDamageValue": 0, "groupHPValue": 0});
  7467. 		System.xmlhttp("index.php?cmd=guild&subcmd=groups", Helper.checkIfGroupExists);
  7468.  
  7469. 		var creatureName = System.findNode('//td[@align="center"]/font[@size=3]/b');
  7470. 		var doNotKillList=GM_getValue("doNotKillList");
  7471. 		if (creatureName) {
  7472. 			creatureName.innerHTML += ' <a href="http://guide.fallensword.com/index.php?cmd=creatures&search_name=' + creatureName.textContent + '&search_level_min=&search_level_max=&search_class=-1" target="_blank">' +
  7473. 				'<img border=0 title="Search creature in Ultimate FSG" width=10 height=10 src="'+ System.imageServerHTTP + '/temple/1.gif"/></a>' +
  7474. 				' <a href="http://www.fallenswordguide.com/creatures/?search=' + creatureName.textContent + '" target="_blank">' +
  7475. 				'<img border=0 title="Search creature in FSG" width=10 height=10 src="http://www.fallenswordguide.com/favicon.ico"/></a>' +
  7476. 				' <a href="http://wiki.fallensword.com/index.php/Special:Search?search=' + creatureName.textContent + '&go=Go" target="_blank">' +
  7477. 				'<img border=0 title="Search creature in Wiki" width=10 height=10 src="/favicon.ico"/></a>';
  7478. 			var extraText = 'Add to the do not kill list';
  7479. 			if (doNotKillList.indexOf(creatureName.textContent.trim()) != -1) extraText = 'Remove from do not kill list';
  7480. 			creatureName.innerHTML += '&nbsp;<span style="cursor:pointer;text-decoration:underline;color:blue;font-size:x-small;" ' +
  7481. 				'id="addRemoveCreatureToDoNotKillList" creatureName="' + creatureName.textContent.trim() + '">' + extraText + '</span>';
  7482. 			document.getElementById('addRemoveCreatureToDoNotKillList').addEventListener('click', Helper.addRemoveCreatureToDoNotKillList, true);
  7483. 		}
  7484. 	},
  7485.  
  7486. 	addRemoveCreatureToDoNotKillList: function(evt) {
  7487. 		creatureName = evt.target.getAttribute('creatureName');
  7488. 		var doNotKillList = GM_getValue("doNotKillList");
  7489. 		var newDoNotKillList = "";
  7490. 		if (doNotKillList.indexOf(creatureName) != -1) {
  7491. 			newDoNotKillList = doNotKillList.replace(creatureName, "");
  7492. 			newDoNotKillList = newDoNotKillList.replace(",,", ",");
  7493. 			if (newDoNotKillList.charAt(0) == ",") newDoNotKillList = newDoNotKillList.substring(1,newDoNotKillList.length);
  7494. 		} else {
  7495. 			newDoNotKillList = doNotKillList + (doNotKillList.length !== 0?",":"") + creatureName;
  7496. 			newDoNotKillList = newDoNotKillList.replace(",,", ",");
  7497. 		}
  7498. 		GM_setValue("doNotKillList",newDoNotKillList);
  7499. 		window.location = window.location;
  7500. 	},
  7501.  
  7502. 	checkIfGroupExists: function(responseText) {
  7503. 		var doc=System.createDocument(responseText);
  7504. 		var groupExistsIMG = System.findNode("//img[@title='Disband Group (Cancel Attack)']",doc);
  7505. 		if (groupExistsIMG) {
  7506. 			var groupHref = groupExistsIMG.parentNode.parentNode.firstChild.getAttribute("href");
  7507. 			System.xmlhttp(groupHref, Helper.getCreatureGroupData);
  7508. 		}
  7509. 	},
  7510.  
  7511. 	getCreatureGroupData: function(responseText) {
  7512. 		var doc=System.createDocument(responseText);
  7513. 		var groupAttackValue = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'Attack:')]",doc).nextSibling.textContent.replace(/,/,"")*1;
  7514. 		var groupDefenseValue = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'Defense:')]",doc).nextSibling.textContent.replace(/,/,"")*1;
  7515. 		var groupArmorValue = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'Armor:')]",doc).nextSibling.textContent.replace(/,/,"")*1;
  7516. 		var groupDamageValue = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'Damage:')]",doc).nextSibling.textContent.replace(/,/,"")*1;
  7517. 		var groupHPValue = System.findNode("//table[@width='400']/tbody/tr/td[contains(.,'HP:')]",doc).nextSibling.textContent.replace(/,/,"")*1;
  7518. 		System.xmlhttp("index.php?cmd=profile", Helper.getCreaturePlayerData,
  7519. 			{"groupExists": true, "groupAttackValue": groupAttackValue, "groupDefenseValue": groupDefenseValue,
  7520. 				"groupArmorValue": groupArmorValue, "groupDamageValue": groupDamageValue, "groupHPValue": groupHPValue});
  7521. 	},
  7522.  
  7523. 	getCreaturePlayerData: function(responseText, callback) {
  7524. 		//playerdata
  7525. 		var doc=System.createDocument(responseText);
  7526. 		var allItems = doc.getElementsByTagName("B");
  7527. 		for (var i=0;i<allItems.length;i++) {
  7528. 			var anItem=allItems[i];
  7529. 			if (anItem.innerHTML == "Attack:&nbsp;"){
  7530. 				var attackText = anItem;
  7531. 				var attackLocation = attackText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  7532. 				var playerAttackValue = parseInt(attackLocation.textContent,10);
  7533. 				var defenseText = attackText.parentNode.nextSibling.nextSibling.nextSibling.firstChild;
  7534. 				var defenseLocation = defenseText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  7535. 				var playerDefenseValue = parseInt(defenseLocation.textContent,10);
  7536. 				var armorText = defenseText.parentNode.parentNode.nextSibling.nextSibling.firstChild.nextSibling.firstChild;
  7537. 				var armorLocation = armorText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  7538. 				var playerArmorValue = parseInt(armorLocation.textContent,10);
  7539. 				var damageText = armorText.parentNode.nextSibling.nextSibling.nextSibling.firstChild;
  7540. 				var damageLocation = damageText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  7541. 				var playerDamageValue = parseInt(damageLocation.textContent,10);
  7542. 				var hpText = damageText.parentNode.parentNode.nextSibling.nextSibling.firstChild.nextSibling.firstChild;
  7543. 				var hpLocation = hpText.parentNode.nextSibling.firstChild.firstChild.firstChild.firstChild;
  7544. 				var playerHPValue = parseInt(hpLocation.textContent,10);
  7545. 			}
  7546. 			if (anItem.innerHTML == "Kill&nbsp;Streak:&nbsp;"){
  7547. 				var killStreakText = anItem;
  7548. 				var killStreakLocation = killStreakText.parentNode.nextSibling;
  7549. 				var playerKillStreakValue = System.intValue(killStreakLocation.textContent);
  7550. 			}
  7551. 		}
  7552. 		//get buffs here later ... DD, CA, DC, Constitution, etc
  7553. 		allItems = doc.getElementsByTagName("IMG");
  7554. 		var counterAttackLevel = 0, doublerLevel = 0, deathDealerLevel = 0, darkCurseLevel = 0, holyFlameLevel = 0;
  7555. 		var constitutionLevel = 0, sanctuaryLevel = 0, flinchLevel = 0, nightmareVisageLevel = 0, superEliteSlayerLevel = 0;
  7556. 		for (i=0;i<allItems.length;i++) {
  7557. 			anItem=allItems[i];
  7558. 			if (anItem.getAttribute("src").search("/skills/") != -1) {
  7559. 				var onmouseover = anItem.getAttribute("onmouseover");
  7560. 				var counterAttackRE = /<b>Counter Attack<\/b> \(Level: (\d+)\)/;
  7561. 				var counterAttack = counterAttackRE.exec(onmouseover);
  7562. 				if (counterAttack) {
  7563. 					counterAttackLevel = counterAttack[1];
  7564. 					continue;
  7565. 				}
  7566. 				var doublerRE = /<b>Doubler<\/b> \(Level: (\d+)\)/;
  7567. 				var doubler = doublerRE.exec(onmouseover);
  7568. 				if (doubler) {
  7569. 					doublerLevel = doubler[1];
  7570. 					continue;
  7571. 				}
  7572. 				var deathDealerRE = /<b>Death Dealer<\/b> \(Level: (\d+)\)/;
  7573. 				var deathDealer = deathDealerRE.exec(onmouseover);
  7574. 				if (deathDealer) {
  7575. 					deathDealerLevel = deathDealer[1];
  7576. 					continue;
  7577. 				}
  7578. 				var darkCurseRE = /<b>Dark Curse<\/b> \(Level: (\d+)\)/;
  7579. 				var darkCurse = darkCurseRE.exec(onmouseover);
  7580. 				if (darkCurse) {
  7581. 					darkCurseLevel = darkCurse[1];
  7582. 					continue;
  7583. 				}
  7584. 				var holyFlameRE = /<b>Holy Flame<\/b> \(Level: (\d+)\)/;
  7585. 				var holyFlame = holyFlameRE.exec(onmouseover);
  7586. 				if (holyFlame) {
  7587. 					holyFlameLevel = holyFlame[1];
  7588. 					continue;
  7589. 				}
  7590. 				var constitutionRE = /<b>Constitution<\/b> \(Level: (\d+)\)/;
  7591. 				var constitution = constitutionRE.exec(onmouseover);
  7592. 				if (constitution) {
  7593. 					constitutionLevel = constitution[1];
  7594. 					continue;
  7595. 				}
  7596. 				var sanctuaryRE = /<b>Sanctuary<\/b> \(Level: (\d+)\)/;
  7597. 				var sanctuary = sanctuaryRE.exec(onmouseover);
  7598. 				if (sanctuary) {
  7599. 					sanctuaryLevel = sanctuary[1];
  7600. 					continue;
  7601. 				}
  7602. 				var flinchRE = /<b>Flinch<\/b> \(Level: (\d+)\)/;
  7603. 				var flinch = flinchRE.exec(onmouseover);
  7604. 				if (flinch) {
  7605. 					flinchLevel = flinch[1];
  7606. 					continue;
  7607. 				}
  7608. 				var nightmareVisageRE = /<b>Nightmare Visage<\/b> \(Level: (\d+)\)/;
  7609. 				var nightmareVisage = nightmareVisageRE.exec(onmouseover);
  7610. 				if (nightmareVisage) {
  7611. 					nightmareVisageLevel = nightmareVisage[1];
  7612. 					continue;
  7613. 				}
  7614. 				var superEliteSlayerRE = /<b>Super Elite Slayer<\/b> \(Level: (\d+)\)/;
  7615. 				var superEliteSlayer = superEliteSlayerRE.exec(onmouseover);
  7616. 				if (superEliteSlayer) {
  7617. 					superEliteSlayerLevel = superEliteSlayer[1];
  7618. 					continue;
  7619. 				}
  7620. 			}
  7621. 		}
  7622. 		//group data (if appropriate)
  7623. 		var groupAttackValue = 0, groupDefenseValue = 0,  groupArmorValue = 0, groupDamageValue = 0, groupHPValue = 0;
  7624. 		groupExists = callback.groupExists;
  7625. 		if (groupExists) {
  7626. 			groupAttackValue = callback.groupAttackValue;
  7627. 			groupDefenseValue = callback.groupDefenseValue;
  7628. 			groupArmorValue = callback.groupArmorValue;
  7629. 			groupDamageValue = callback.groupDamageValue;
  7630. 			groupHPValue = callback.groupHPValue;
  7631. 		}
  7632. 		//creaturedata
  7633. 		var creatureStatTable = System.findNode("//table[tbody/tr/td[.='Statistics']]");
  7634. 		if (!creatureStatTable) {return;}
  7635. 		var combatEvaluatorBias = GM_getValue("combatEvaluatorBias");
  7636. 		var attackVariable = 1.1053, generalVariable = 1.1053, hpVariable = 1.1;
  7637. 		if (combatEvaluatorBias == 1) {
  7638. 			generalVariable = 1.1;
  7639. 			hpVariable = 1.053;
  7640. 		} else if (combatEvaluatorBias == 2) {
  7641. 			generalVariable = 1.053;
  7642. 			hpVariable = 1;
  7643. 		}
  7644. 		var creatureClass   = creatureStatTable.rows[1].cells[1].textContent;
  7645. 		var creatureLevel   = creatureStatTable.rows[1].cells[3].textContent;
  7646. 		var creatureAttack  = System.intValue(creatureStatTable.rows[2].cells[1].textContent);
  7647. 		var creatureDefense = System.intValue(creatureStatTable.rows[2].cells[3].textContent);
  7648. 		var creatureArmor   = System.intValue(creatureStatTable.rows[3].cells[1].textContent);
  7649. 		var creatureDamage  = System.intValue(creatureStatTable.rows[3].cells[3].textContent);
  7650. 		var creatureHP      = System.intValue(creatureStatTable.rows[4].cells[1].textContent);
  7651. 		var extraNotes = "", holyFlameBonusDamage = 0;
  7652. 		//reduce stats if critter is a SE and player has SES cast on them.
  7653. 		var superEliteSlayerMultiplier = 0;
  7654. 		if (superEliteSlayerLevel > 0) {
  7655. 			superEliteSlayerMultiplier = Math.round(0.002 * superEliteSlayerLevel*100)/100;
  7656. 		}
  7657. 		var creatureName = System.findNode("//td/font[@size='3'][b]").textContent.trim();
  7658. 		if (creatureName.search("Super Elite") != -1) {
  7659. 			creatureAttack -= Math.ceil(creatureAttack * superEliteSlayerMultiplier);
  7660. 			creatureDefense -= Math.ceil(creatureDefense * superEliteSlayerMultiplier);
  7661. 			creatureDefense -= Math.ceil(creatureDefense * superEliteSlayerMultiplier);
  7662. 			creatureArmor -= Math.ceil(creatureArmor * superEliteSlayerMultiplier);
  7663. 			creatureHP -= Math.ceil(creatureHP * superEliteSlayerMultiplier);
  7664. 			extraNotes += (superEliteSlayerLevel > 0? "SES Stat Reduction Multiplier = " + superEliteSlayerMultiplier + "<br>":"");
  7665. 		}
  7666. 		//math section ... analysis
  7667. 		//Holy Flame adds its bonus after the armor of the creature has been taken off.
  7668. 		if (creatureClass == "Undead") {
  7669. 			holyFlameBonusDamage = Math.max(Math.floor((playerDamageValue - creatureArmor) * holyFlameLevel * 0.002),0);
  7670. 			extraNotes += (holyFlameLevel > 0? "HF Bonus Damage = " + holyFlameBonusDamage + "<br>":"");
  7671. 		}
  7672. 		//Death Dealer and Counter Attack both applied at the same time
  7673. 		var deathDealerBonusDamage = Math.floor(playerDamageValue * (Math.min(Math.floor(playerKillStreakValue/5) * 0.01 * deathDealerLevel, 20)/100));
  7674. 		var counterAttackBonusAttack = Math.floor(playerAttackValue * 0.0025 * counterAttackLevel);
  7675. 		var counterAttackBonusDamage = Math.floor(playerDamageValue * 0.0025 * counterAttackLevel);
  7676. 		var extraStaminaPerHit = (counterAttackLevel > 0? Math.ceil((1+(doublerLevel/50))*0.0025*counterAttackLevel) :0);
  7677. 		//playerAttackValue += counterAttackBonusAttack;
  7678. 		//playerDamageValue += deathDealerBonusDamage + counterAttackBonusDamage;
  7679. 		extraNotes += (deathDealerLevel > 0? "DD Bonus Damage = " + deathDealerBonusDamage + "<br>":"");
  7680. 		if (counterAttackLevel > 0) {
  7681. 			extraNotes += "CA Bonus Attack/Damage = " + counterAttackBonusAttack + " / " + counterAttackBonusDamage + "<br>";
  7682. 			extraNotes += "CA Extra Stam Used = " + extraStaminaPerHit + "<br>";
  7683. 		}
  7684. 		//Attack:
  7685. 		extraNotes += (darkCurseLevel > 0? "DC Bonus Attack = " + Math.floor(creatureDefense * darkCurseLevel * 0.002) + "<br>":"");
  7686. 		var nightmareVisageAttackMovedToDefense = Math.floor(playerAttackValue * nightmareVisageLevel * 0.0025);
  7687. 		extraNotes += (nightmareVisageLevel > 0? "NV Attack moved to Defense = " + nightmareVisageAttackMovedToDefense + "<br>":"");
  7688. 		var overallAttackValue = (groupExists?groupAttackValue:playerAttackValue) + counterAttackBonusAttack - nightmareVisageAttackMovedToDefense;
  7689. 		var hitByHowMuch = (overallAttackValue - Math.ceil(attackVariable*(creatureDefense - (creatureDefense * darkCurseLevel * 0.002))));
  7690. 		//Damage:
  7691. 		var overallDamageValue = (groupExists?groupDamageValue:playerDamageValue) + deathDealerBonusDamage + counterAttackBonusDamage + holyFlameBonusDamage;
  7692. 		var damageDone = Math.floor(overallDamageValue - ((generalVariable*creatureArmor) + (hpVariable*creatureHP)));
  7693. 		var numberOfHitsRequired = (hitByHowMuch > 0? Math.ceil((hpVariable*creatureHP)/((overallDamageValue < (generalVariable*creatureArmor))? 1: overallDamageValue - (generalVariable*creatureArmor))):"-");
  7694. 		//Defense:
  7695. 		var overallDefenseValue = (groupExists?groupDefenseValue:playerDefenseValue) + Math.floor(playerDefenseValue * constitutionLevel * 0.001) + nightmareVisageAttackMovedToDefense;
  7696. 		extraNotes += (constitutionLevel > 0? "Constitution Bonus Defense = " + Math.floor(playerDefenseValue * constitutionLevel * 0.001) + "<br>":"");
  7697. 		extraNotes += (flinchLevel > 0? "Flinch Bonus Attack Reduction = " + Math.floor(creatureAttack * flinchLevel * 0.001) + "<br>":"");
  7698. 		var creatureHitByHowMuch = Math.floor((attackVariable*creatureAttack - (creatureAttack * flinchLevel * 0.001)) - overallDefenseValue);
  7699. 		//Armor and HP:
  7700. 		var overallArmorValue = (groupExists?groupArmorValue:playerArmorValue) + Math.floor(playerArmorValue * sanctuaryLevel * 0.001);
  7701. 		extraNotes += (sanctuaryLevel > 0? "Sanc Bonus Armor = " + Math.floor(playerArmorValue * sanctuaryLevel * 0.001) + "<br>":"");
  7702. 		var overallHPValue = (groupExists?groupHPValue:playerHPValue);
  7703. 		var creatureDamageDone = Math.ceil((generalVariable*creatureDamage) - (overallArmorValue + overallHPValue));
  7704. 		var numberOfCreatureHitsTillDead = (creatureHitByHowMuch >= 0? Math.ceil(overallHPValue/(((generalVariable*creatureDamage) < (overallArmorValue))? 1: (generalVariable*creatureDamage) - (overallArmorValue))):"-");
  7705. 		//Analysis:
  7706. 		var playerHits = (numberOfCreatureHitsTillDead=="-"? numberOfHitsRequired:(numberOfHitsRequired=="-"?"-":(numberOfHitsRequired>numberOfCreatureHitsTillDead?"-":numberOfHitsRequired)));
  7707. 		var creatureHits = (numberOfHitsRequired=="-"?numberOfCreatureHitsTillDead:(numberOfCreatureHitsTillDead=="-"?"-":(numberOfCreatureHitsTillDead>numberOfHitsRequired?"-":numberOfCreatureHitsTillDead)));
  7708. 		var fightStatus = "Unknown";
  7709. 		if (playerHits == "-" && creatureHits == "-") {
  7710. 			fightStatus = "Unresolved";
  7711. 		} else if (playerHits == "-") {
  7712. 			fightStatus = "Player dies";
  7713. 		} else if (playerHits == 1) {
  7714. 			fightStatus = "Player 1 hits" + (numberOfCreatureHitsTillDead-numberOfHitsRequired<=1? ", dies on miss":", survives a miss");
  7715. 		} else if (playerHits > 1) {
  7716. 			fightStatus = "Player > 1 hits" + (numberOfCreatureHitsTillDead-numberOfHitsRequired<=1? ", dies on miss":", survives a miss");
  7717. 		}
  7718. 		if (counterAttackLevel > 0 && numberOfHitsRequired == "1") {
  7719. 			var lowestCALevelToStillHit = Math.max(Math.ceil((counterAttackBonusAttack-hitByHowMuch + 1)/playerAttackValue/0.0025), 0);
  7720. 			var lowestCALevelToStillKill = Math.max(Math.ceil((counterAttackBonusDamage-damageDone + 1)/playerDamageValue/0.0025), 0);
  7721. 			var lowestFeasibleCALevel = Math.max(lowestCALevelToStillHit,lowestCALevelToStillKill);
  7722. 			extraNotes += "Lowest CA to still 1-hit this creature = " + lowestFeasibleCALevel + "<br>";
  7723. 			if (lowestFeasibleCALevel !== 0) {
  7724. 				var extraAttackAtLowestFeasibleCALevel = Math.floor(playerAttackValue * 0.0025 * lowestFeasibleCALevel);
  7725. 				var extraDamageAtLowestFeasibleCALevel = Math.floor(playerDamageValue * 0.0025 * lowestFeasibleCALevel);
  7726. 				extraNotes += "Extra CA Att/Dam at this lowered CA level = " + extraAttackAtLowestFeasibleCALevel + " / " + extraDamageAtLowestFeasibleCALevel + "<br>";
  7727. 			}
  7728. 			var extraStaminaPerHitAtLowestFeasibleCALevel = (counterAttackLevel > 0? Math.ceil((1+(doublerLevel/50))*0.0025*lowestFeasibleCALevel) :0);
  7729. 			if (extraStaminaPerHitAtLowestFeasibleCALevel < extraStaminaPerHit) {
  7730. 				extraNotes += "Extra Stam Used at this lowered CA level = " + extraStaminaPerHitAtLowestFeasibleCALevel + "<br>";
  7731. 			}
  7732. 			else {
  7733. 				extraNotes += "No reduction of stam used at the lower CA level<br>";
  7734. 			}
  7735. 		}
  7736. 		if (numberOfHitsRequired == "-" || numberOfHitsRequired != "1") {
  7737. 			lowestCALevelToStillHit = Math.max(Math.ceil((counterAttackBonusAttack-hitByHowMuch + 1)/playerAttackValue/0.0025), 0);
  7738. 			lowestCALevelToStillKill = Math.max(Math.ceil((counterAttackBonusDamage-damageDone + 1)/playerDamageValue/0.0025), 0);
  7739. 			if (lowestCALevelToStillHit >175) {
  7740. 				extraNotes += "Even with CA175 you cannot hit this creature<br>";
  7741. 			} else if (lowestCALevelToStillHit !== 0) {
  7742. 				extraNotes += "You need a minimum of CA" + lowestCALevelToStillHit + " to hit this creature<br>";
  7743. 			}
  7744. 			if (lowestCALevelToStillKill >175) {
  7745. 				extraNotes += "Even with CA175 you cannot 1-hit kill this creature<br>";
  7746. 			} else if (lowestCALevelToStillKill !== 0) {
  7747. 				extraNotes += "You need a minimum of CA" + lowestCALevelToStillKill + " to 1-hit kill this creature<br>";
  7748. 			}
  7749. 		}
  7750.  
  7751. 		//display data
  7752. 		var newRow = creatureStatTable.insertRow(creatureStatTable.rows.length);
  7753. 		var newCell = newRow.insertCell(0);
  7754. 		newCell.colSpan = '4';
  7755. 		newCell.innerHTML = "<table width='100%'><tbody><tr><td bgcolor='#CD9E4B' colspan='4' align='center'>" + (groupExists? "Group ":"") + "Combat Evaluation</td></tr>" +
  7756. 			"<tr><td align='right'><span style='color:#333333'>Will I hit it? </td><td align='left'>" + (hitByHowMuch > 0? "Yes":"No") + "</td>" +
  7757. 				"<td align='right'><span style='color:#333333'>Extra Attack: </td><td align='left'>( " + hitByHowMuch + " )</td></tr>" +
  7758. 			"<tr><td align='right'><span style='color:#333333'># Hits to kill it? </td><td align='left'>" + numberOfHitsRequired + "</td>" +
  7759. 				"<td align='right'><span style='color:#333333'>Extra Damage: </td><td align='left'>( " + damageDone + " )</td></tr>" +
  7760. 			"<tr><td align='right'><span style='color:#333333'>Will I be hit? </td><td align='left'>" + (creatureHitByHowMuch >= 0? "Yes":"No") + "</td>" +
  7761. 				"<td align='right'><span style='color:#333333'>Extra Defense: </td><td align='left'>( " + (-1 * creatureHitByHowMuch) + " )</td></tr>" +
  7762. 			"<tr><td align='right'><span style='color:#333333'># Hits to kill me? </td><td align='left'>" + numberOfCreatureHitsTillDead + "</td>" +
  7763. 				"<td align='right'><span style='color:#333333'>Extra Armor + HP: </td><td align='left'>( " + (-1 * creatureDamageDone) + " )</td></tr>" +
  7764. 			"<tr><td align='right'><span style='color:#333333'># Player Hits? </td><td align='left'>" + playerHits + "</td>" +
  7765. 				"<td align='right'><span style='color:#333333'># Creature Hits? </td><td align='left'>" + creatureHits + "</td></tr>" +
  7766. 			"<tr><td align='right'><span style='color:#333333'>Fight Status: </span></td><td align='left' colspan='3'><span>" + fightStatus + "</span></td></tr>" +
  7767. 			"<tr><td align='right'><span style='color:#333333'>Notes: </span></td><td align='left' colspan='3'><span style='font-size:x-small;'>" +
  7768. 				extraNotes + "</span></td></tr>" +
  7769. 			"<tr><td colspan='4'><span style='font-size:x-small; color:gray'>" +
  7770. 				"*Does include CA, DD, HF, DC, Flinch, Super Elite Slayer, NV, Sanctuary and Constitution (if active) and allow for randomness (1.1053). Does not include Chi Strike or Terrorize (because I haven't done them yet).</span></td></tr>" +
  7771. 			"</tbody></table>";
  7772. 	},
  7773.  
  7774. 	injectBioWidgets: function() {
  7775. 		var textArea = System.findNode("//textarea[@name='bio']");
  7776. 		//textArea.rows=15;
  7777. 		textArea.cols=100;
  7778. 		textArea.id = "biotext";
  7779. 		var textAreaDev = textArea.parentNode;
  7780. 		var bioPreviewHTML = System.convertTextToHtml(textArea.value);
  7781. 		var counterDiv = document.createElement("DIV")
  7782. 		textAreaDev.appendChild(counterDiv);
  7783. 		counterDiv.innerHTML += "<span style='color:blue;'>Character count = </span><span findme='biolength' style='color:blue;'>" +
  7784. 			(textArea.value.length + crCount) + "</span><span style='color:blue;'>/</span><span findme='biototal' style='color:blue;'>255</span>";
  7785.  
  7786. 		var previewDiv = document.createElement("DIV")
  7787. 		textAreaDev.appendChild(previewDiv);
  7788. 		previewDiv.innerHTML = '<table align="center" width="325" border="1"><tbody>' +
  7789. 			'<tr><td style="text-align:center;color:#7D2252;background-color:#CD9E4B">Preview</td></tr>' +
  7790. 			'<tr><td align="left" width="325"><span style="font-size:small;" findme="biopreview">' + bioPreviewHTML +
  7791. 			'</span></td></tr></tbody></table>';
  7792. 		var innerTable = System.findNode("//table[tbody/tr/td/font/b[.='Update your Character Biography']]");
  7793. 		var crCount = 0;
  7794. 		var startIndex = 0;
  7795. 		//Add description text for the new tags
  7796. 		var advancedEditing = System.findNode("//div[h2[.='Advanced Editing:']]");
  7797. 		/* TODO: Add a way to hide the advanced editing 'note' box dynamically.
  7798. 		advancedEditing.addEventListener('mouseover', function(event) {
  7799. 			event.target.style.backgroundColor = "#8EE5EE";
  7800. 		}, false);
  7801. 		advancedEditing.addEventListener('mouseout', function(event) {
  7802. 			event.target.style.backgroundColor = "";
  7803. 		}, false);*/
  7804. 		var advancedEditingDiv = document.createElement("DIV")
  7805. 		advancedEditing.appendChild(advancedEditingDiv);
  7806. 		advancedEditingDiv.style.align = 'left';
  7807. 		advancedEditingDiv.innerHTML += "`~This will allow FSH Script users to select buffs from your bio~`<br/>" +
  7808. 			"You can use the {cmd} tag as well to determine where to put the 'Ask For Buffs' button<br/><br/>" +
  7809. 			"&nbsp;&nbsp;&nbsp;- Note 1: The ` and ~ characters are on the same key on QWERTY keyboards. ` is <b>NOT</b> an apostrophe.<br/>" +
  7810. 			"&nbsp;&nbsp;&nbsp;- Note 2: Inner text will not contain special characters (non-alphanumeric).<br/>" +
  7811. 			"&nbsp;&nbsp;&nbsp;- P.S. Be creative with these! Wrap your buff pack names in them to make buffing even easier!";
  7812. 		var bioEditLinesDiv = document.createElement("DIV")
  7813. 		advancedEditing.appendChild(bioEditLinesDiv);
  7814. 		textArea.rows = GM_getValue("bioEditLines");
  7815. 		bioEditLinesDiv.innerHTML += " Display <input size=2 maxlength=2 id='Helper:linesToShow' type='text' value='" + GM_getValue("bioEditLines") + "'/> Lines"  +
  7816. 		" <input type='button' style='display:none' id='Helper:saveLines' value='Update Rows To Show' class='custombutton'/>";
  7817. 		document.getElementById("Helper:saveLines").addEventListener('click',
  7818. 			function (event) {
  7819. 				var theBox = document.getElementById("Helper:linesToShow");
  7820. 				if (theBox.value.trim().length === 0) {
  7821. 					return;
  7822. 				}
  7823. 				GM_setValue("bioEditLines", theBox.value);
  7824. 				window.location.reload();
  7825. 			}, true);
  7826.  
  7827.  
  7828. 		unsafeWindow.document.getElementById("Helper:linesToShow").onkeypress = function (event) {
  7829. 			event = ( event ) ? event : window.event;
  7830. 			var charkey = String.fromCharCode(( event.which ) ? event.which : event.keyCode);
  7831. 			document.getElementById("Helper:saveLines").style.display = "";
  7832. 			return ((("0123456789").indexOf(charkey) > -1));
  7833. 		};
  7834. 		while (textArea.value.indexOf('\n',startIndex+1) != -1) {
  7835. 			crCount++;
  7836. 			startIndex = textArea.value.indexOf('\n',startIndex+1);
  7837. 		}
  7838.  
  7839. 		document.getElementById('biotext').addEventListener('keyup', Helper.updateBioCharacters, true);
  7840. 		System.xmlhttp("index.php?cmd=points", Helper.getTotalBioCharacters);
  7841. 		//Force the preview area to render
  7842. 		Helper.updateBioCharacters(null);
  7843. 	},
  7844.  
  7845. 	injectShoutboxWidgets: function(textboxname, maxcharacters) {
  7846. 		var textArea = System.findNode("//textarea[@name='" + textboxname + "']");
  7847. 		textArea.setAttribute("findme", "Helper:InputText");
  7848. 		textArea.setAttribute("maxcharacters", maxcharacters);
  7849. 		var textAreaTable = System.findNode("../../../..", textArea);
  7850. 		textAreaTable.insertRow(-1).insertCell(0).setAttribute("id", "Helper:ShoutboxPreview");
  7851. 		textArea.addEventListener('keyup', Helper.updateShoutboxPreview, true);
  7852. 	},
  7853.  
  7854. 	updateShoutboxPreview: function(evt) {
  7855. 		var textArea = System.findNode("//textarea[@findme='Helper:InputText']");
  7856. 		var textContent = textArea.value;
  7857. 		var chars = textContent.length;
  7858. 		var maxchars = parseInt(textArea.getAttribute("maxcharacters"),10);
  7859. 		if (chars>maxchars) {
  7860. 			textContent=textContent.substring(0,maxchars);
  7861. 			textArea.value=textContent;
  7862. 			chars=maxchars;
  7863. 		}
  7864.  
  7865. 		document.getElementById("Helper:ShoutboxPreview").innerHTML = '<table align="center" width="325" border="0"><tbody>' +
  7866. 			'<tr><td style="text-align:center;color:#7D2252;background-color:#CD9E4B">Preview (' + chars + '/' + maxchars + ' characters)</td></tr>' +
  7867. 			'<tr><td width="325"><span style="font-size:x-small;" findme="biopreview">' + textContent +
  7868. 			'</span></td></tr></tbody></table>';
  7869.  
  7870. 	},
  7871.  
  7872. 	updateBioCharacters: function(evt) {
  7873. 		Helper.buffCost={'count':0,'buffs':{}};
  7874. 		var textArea = System.findNode("//textarea[@name='bio']");
  7875. 		var characterCount = System.findNode("//span[@findme='biolength']");
  7876. 		var crCount = 0;
  7877. 		var startIndex = 0;
  7878. 		while (textArea.value.indexOf('\n',startIndex+1) != -1) {
  7879. 			crCount++;
  7880. 			startIndex = textArea.value.indexOf('\n',startIndex+1);
  7881. 		}
  7882. 		characterCount.innerHTML = (textArea.value.length + crCount);
  7883. 		var bioTotal = System.findNode("//span[@findme='biototal']");
  7884. 		//if evt is null, then this is a forced call
  7885. 		//if we don't check this, the HTTP request to get the number of bio character upgrades
  7886. 		//might not have finished before this executes, resulting in red text
  7887. 		if ((characterCount.innerHTML*1) > (bioTotal.innerHTML*1) && evt !== null) {
  7888. 			characterCount.style.color = "red";
  7889. 		} else {
  7890. 			characterCount.style.color = "blue";
  7891. 		}
  7892. 		var previewArea = System.findNode("//span[@findme='biopreview']");
  7893.  
  7894. 		var bioContents = System.convertTextToHtml(textArea.value);
  7895.  
  7896. 		bioContents=bioContents.replace(/\{b\}/g,'`~').replace(/\{\/b\}/g,'~`');
  7897. 		var buffs=bioContents.match(/`~([^~]|~(?!`))*~`/g);
  7898. 		if (buffs) {
  7899. 			for (var i=0;i<buffs.length;i++) {
  7900. 				var fullName=buffs[i].replace(/(`~)|(~`)|(\{b\})|(\{\/b\})/g,'');
  7901. 				var buffName = Helper.removeHTML(fullName);
  7902. 				var cbString =
  7903. 					'<span id="Helper:buff'+i+'" style="color:blue;cursor:pointer">'+
  7904. 					fullName+'</span>';
  7905. 				bioContents=bioContents.replace(buffs[i], cbString);
  7906. 			}
  7907.  
  7908. 			if (bioContents.indexOf("{cmd}") < 0) bioContents+="{cmd}";
  7909.  
  7910. 			bioContents = bioContents.replace("{cmd}",'<input id="Helper:sendBuffMsg" subject="buffMe" href="index.php?cmd=message&target_player=" class="custombutton" type="submit" value="Ask For Buffs"/>' +
  7911. 			'<span id=buffCost style="color:red"></span>');
  7912. 			previewArea.innerHTML = bioContents;
  7913.  
  7914. 			for (i=0;i<buffs.length;i++) {
  7915. 				var buff=document.getElementById('Helper:buff'+i);
  7916. 				if (buff) buff.addEventListener('click', Helper.toggleBuffsToBuy,true);
  7917. 			}
  7918. 		}
  7919.  
  7920. 	},
  7921.  
  7922. 	getTotalBioCharacters: function(responseText) {
  7923. 		var doc=System.createDocument(responseText);
  7924. 		var bioCharactersText = System.findNode("//td[.='+25 Bio Characters']",doc);
  7925. 		var bioCharactersRatio = bioCharactersText.nextSibling.nextSibling.nextSibling.nextSibling;
  7926. 		var bioCharactersValueRE = /(\d+) \/ 75/;
  7927. 		var bioCharactersValue = bioCharactersValueRE.exec(bioCharactersRatio.innerHTML)[1]*1;
  7928. 		var bioTotal = System.findNode("//span[@findme='biototal']");
  7929. 		bioTotal.innerHTML = (bioCharactersValue * 25) + 255;
  7930. 	},
  7931.  
  7932. 	addHistoryWidgets: function() {
  7933. 		var textArea = System.findNode("//textarea[@name='history']");
  7934. 		if (!textArea) {return;}
  7935. 		textArea.value = textArea.value.replace(/<br \/>/ig,"");
  7936. 		var textAreaTable = textArea.parentNode.parentNode.parentNode.parentNode;
  7937. 		var bioPreviewHTML = System.convertTextToHtml(textArea.value);
  7938. 		var newRow = textAreaTable.insertRow(-1);
  7939. 		var newCell = newRow.insertCell(0);
  7940. 		newCell.innerHTML = '<table align="center" width="325" border="1"><tbody>' +
  7941. 			'<tr><td style="text-align:center;color:#7D2252;background-color:#CD9E4B">Preview</td></tr>' +
  7942. 			'<tr><td align="left" width="325"><span style="font-size:small;" findme="biopreview">' + bioPreviewHTML +
  7943. 			'</span></td></tr></tbody></table>';
  7944. 		textArea.id = "historytext";
  7945. 		var innerTable = System.findNode("//table[tbody/tr/td/font/b[.='Edit Guild History']]");
  7946. 		var crCount = 0;
  7947. 		var startIndex = 0;
  7948. 		while (textArea.value.indexOf('\n',startIndex+1) != -1) {
  7949. 			crCount++;
  7950. 			startIndex = textArea.value.indexOf('\n',startIndex+1);
  7951. 		}
  7952. 		innerTable.rows[4].cells[0].innerHTML += "<span style='color:blue;'>Character count = </span><span findme='historylength' style='color:blue;'>" +
  7953. 			(textArea.value.length + crCount) + "</span><span style='color:blue;'>/</span><span findme='historytotal' style='color:blue;'>255</span>";
  7954.  
  7955. 		document.getElementById('historytext').addEventListener('keyup', Helper.updateHistoryCharacters, true);
  7956. 		System.xmlhttp("index.php?cmd=points&subcmd=guildupgrades", Helper.getTotalHistoryCharacters);
  7957. 	},
  7958.  
  7959. 	updateHistoryCharacters: function(evt) {
  7960. 		var textArea = System.findNode("//textarea[@name='history']");
  7961. 		var characterCount = System.findNode("//span[@findme='historylength']");
  7962. 		var crCount = 0;
  7963. 		var startIndex = 0;
  7964. 		while (textArea.value.indexOf('\n',startIndex+1) != -1) {
  7965. 			crCount++;
  7966. 			startIndex = textArea.value.indexOf('\n',startIndex+1);
  7967. 		}
  7968. 		characterCount.innerHTML = (textArea.value.length + crCount);
  7969. 		var bioTotal = System.findNode("//span[@findme='historytotal']");
  7970. 		if ((characterCount.innerHTML*1) > (bioTotal.innerHTML*1)) {
  7971. 			characterCount.style.color = "red";
  7972. 		} else {
  7973. 			characterCount.style.color = "blue";
  7974. 		}
  7975. 		var previewArea = System.findNode("//span[@findme='biopreview']");
  7976. 		var bioPreviewHTML = System.convertTextToHtml(textArea.value);
  7977. 		previewArea.innerHTML = bioPreviewHTML;
  7978. 	},
  7979.  
  7980. 	getTotalHistoryCharacters: function(responseText) {
  7981. 		var doc=System.createDocument(responseText);
  7982. 		var historyCharactersText = System.findNode("//td[.='+20 History Characters']",doc);
  7983. 		var historyCharactersRatio = historyCharactersText.nextSibling.nextSibling.nextSibling.nextSibling;
  7984. 		var historyCharactersValueRE = /(\d+) \/ 250/;
  7985. 		var historyCharactersValue = historyCharactersValueRE.exec(historyCharactersRatio.innerHTML)[1]*1;
  7986. 		var historyTotal = System.findNode("//span[@findme='historytotal']");
  7987. 		historyTotal.innerHTML = (historyCharactersValue * 20) + 255;
  7988. 	},
  7989.  
  7990. 	portalToStartArea: function() {
  7991. 		if (window.confirm('Are you sure you with to use a special portal back to Krul Island?')) {
  7992. 			var krulXCV = GM_getValue("krulXCV");
  7993. 			if (krulXCV) {
  7994. 				System.xmlhttp("index.php?cmd=settings&subcmd=fix&xcv=" + krulXCV, function() {window.location="index.php?cmd=world";});
  7995. 			} else {
  7996. 				window.alert("Please visit the preferences page to cache your Krul Portal link");
  7997. 			}
  7998. 		}
  7999. 	},
  8000.  
  8001. 	storePlayerUpgrades: function() {
  8002. 		var alliesText = System.findNode("//td[.='+1 Max Allies']");
  8003. 		var alliesRatio = alliesText.nextSibling.nextSibling.nextSibling.nextSibling;
  8004. 		if (alliesRatio) {
  8005. 			var alliesValueRE = /(\d+) \/ 115/;
  8006. 			var alliesValue = alliesValueRE.exec(alliesRatio.innerHTML)[1]*1;
  8007. 			GM_setValue("alliestotal",alliesValue+5);
  8008. 		}
  8009. 		var enemiesText = System.findNode("//td[.='+1 Max Enemies']");
  8010. 		var enemiesRatio = enemiesText.nextSibling.nextSibling.nextSibling.nextSibling;
  8011. 		if (enemiesRatio) {		
  8012. 			var enemiesValueRE = /(\d+) \/ 115/;
  8013. 			var enemiesValue = enemiesValueRE.exec(enemiesRatio.innerHTML)[1]*1;
  8014. 			GM_setValue("enemiestotal",enemiesValue+5);
  8015. 		}
  8016. 		var maxAuctionsText = System.findNode("//td[.='+1 Max Auctions']");
  8017. 		var maxAuctionsRatio = maxAuctionsText.nextSibling.nextSibling.nextSibling.nextSibling;
  8018. 		if (maxAuctionsRatio) {
  8019. 			var maxAuctionsValueRE = /(\d+) \/ 100/;
  8020. 			var maxAuctionsValue = maxAuctionsValueRE.exec(maxAuctionsRatio.innerHTML)[1]*1;
  8021. 			GM_setValue("maxAuctions",maxAuctionsValue+2);
  8022. 		}
  8023. 	},
  8024.  
  8025. 	injectTopRated: function() {
  8026. 		var mainTable = System.findNode("//table[tbody/tr/td/font/b[.='Top 250 Players']]");
  8027. 		if (!mainTable) {return;}
  8028. 		var mainTitle = mainTable.rows[0].cells[0];
  8029. 		mainTitle.innerHTML += '&nbsp<input id="findOnlinePlayers" type="button" value="Find Online Players" ' +
  8030. 			'title="Fetch the online status of the top 250 players (warning ... takes a few seconds)." class="custombutton">';
  8031.  
  8032. 		document.getElementById('findOnlinePlayers').addEventListener('click', Helper.findOnlinePlayers, true);
  8033. 	},
  8034.  
  8035. 	findOnlinePlayers: function() {
  8036. 		var findPlayersButton = System.findNode("//input[@id='findOnlinePlayers']");
  8037. 		findPlayersButton.style.display = "none";
  8038. 		var topPlayerTable = System.findNode("//table[@width='500']");
  8039. 		var lowestLevel = topPlayerTable.rows[topPlayerTable.rows.length-4].cells[3].textContent*1;
  8040. 		GM_setValue("lowestLevelInTop250",lowestLevel);
  8041. 		var guildsChecked = "";
  8042. 		for (var i=0; i<topPlayerTable.rows.length; i++) {
  8043. 			var aRow = topPlayerTable.rows[i];
  8044. 			if (aRow.cells[1] && i!==0) {
  8045. 				var playerTable = topPlayerTable.rows[i].cells[1].firstChild;
  8046. 				var playerElement = playerTable.rows[0].cells[0];
  8047. 				var playerGuildHref = playerElement.firstChild.getAttribute("href");
  8048. 				var playerGuildName = playerElement.firstChild.firstChild.getAttribute("title");
  8049. 				//GM_log(guildsChecked.indexOf(playerGuildName));
  8050. 				//if we haven't already checked this guild, then go ahead and check it
  8051. 				if (guildsChecked.search(playerGuildName) == -1) {
  8052. 					//GM_log(i+"::"+playerGuildName + "::" + playerGuildHref + "::" + aRow.innerHTML + "::" + guildsChecked);
  8053. 					System.xmlhttp(playerGuildHref, Helper.parseGuildOnline);
  8054. 					//log current guild as checked.
  8055. 					guildsChecked += ' ' + playerGuildName;
  8056. 				}
  8057. 			}
  8058. 		}
  8059. 	},
  8060.  
  8061. 	parseGuildOnline: function(responseText) {
  8062. 		var topPlayerTable = System.findNode("//table[@width='500']");
  8063. 		var lowestLevel = GM_getValue("lowestLevelInTop250");
  8064. 		var doc=System.createDocument(responseText);
  8065. 		memberTable = System.findNode("//table[tbody/tr/td[.='Rank']]", doc);
  8066. 		for (var i=0; i<memberTable.rows.length; i++) {
  8067. 			aRow = memberTable.rows[i];
  8068. 			if (aRow.cells[1] && i!== 0) {
  8069. 				onlineStatus = aRow.cells[0].innerHTML;
  8070. 				playerName = aRow.cells[1].firstChild.nextSibling.innerHTML;
  8071. 				playerLevel = aRow.cells[2].textContent*1;
  8072. 				if (playerLevel >= lowestLevel) { // don't bother looking if they are a low level
  8073. 					//var playerInTopPlayerList = System.findNode("//a[.='" + playerName +"']", topPlayerTable); // didn't work so had to comprimise.
  8074. 					var playerInTopPlayerList = System.findNode("//a[.='" + playerName +"']");
  8075. 					var inTopPlayerTable = System.findNode("//table[@width='500' and contains(.,'" + playerName +"')]");
  8076. 					if (playerInTopPlayerList && inTopPlayerTable) {
  8077. 						insertHere = playerInTopPlayerList.parentNode;
  8078. 						insertHere.innerHTML += '&nbsp' + onlineStatus;
  8079. 					}
  8080. 				}
  8081. 			}
  8082. 		}
  8083. 	},
  8084.  
  8085. 	injectArena: function() {
  8086. 		arenaTable = System.findNode("//table[@width=620]/tbody/tr/td[contains(.,'Reward')]/table");
  8087. 		var injectHere = System.findNode("//tr[td/input[@value='Setup Combat Moves...']]").previousSibling.previousSibling.firstChild;
  8088. 		var hideMatchesForCompletedMoves = GM_getValue("hideMatchesForCompletedMoves");
  8089. 		injectHere.innerHTML = '<input id="Helper:hideMatchesForCompletedMoves" type="checkbox"' +
  8090. 				(hideMatchesForCompletedMoves?' checked':'') + '/>'+
  8091. 				'<span style="color:blue;">&nbsp;Hide Matches for Completed Moves | Number of active arenas: ' + (arenaTable.rows.length-1) +
  8092. 				'<div align=center><form id=Helper:arenaFilterForm subject="arena" onSubmit="javascript:return false;">' +
  8093. 				'Min lvl:<input value="' + GM_getValue("arenaMinLvl", 1) + '" size=5 name="Helper.arenaMinLvl" id="Helper.arenaMinLvl" style=custominput/> ' +
  8094. 				'Max lvl:<input value="' + GM_getValue("arenaMaxLvl", 1000) + '" size=5 name="Helper.arenaMaxLvl" id="Helper.arenaMaxLvl" style=custominput/> ' +
  8095. 				'<input id="Helper:arenaFilter" subject="arena" class="custombutton" type="submit" value="Filter"/>' +
  8096. 				'<input id="Helper:arenaFilterReset" subject="arena" class="custombutton" type="button" value="Reset"/></form></div>'+
  8097. 				'</span>';
  8098. 		document.getElementById("Helper:hideMatchesForCompletedMoves").addEventListener('click', Helper.hideMatchesForCompletedMoves, true);
  8099. 		document.getElementById("Helper:arenaFilterReset").addEventListener('click', Helper.resetLevelFilter, true);
  8100. 		document.getElementById("Helper:arenaFilterForm").addEventListener('submit', Helper.setLevelFilter, true);
  8101.  
  8102. 		var arenaMoves = System.getValueJSON("arenaMoves");
  8103. 		var hideArenaPrizes = GM_getValue("hideArenaPrizes");
  8104. 		if (hideArenaPrizes) {
  8105. 			var hideArenaPrizesArray = hideArenaPrizes.split(",");
  8106. 		}
  8107. 		var oldArenaMatches = System.getValueJSON("arenaMatches");
  8108. 		if (!oldArenaMatches) {
  8109. 			arenaMatches = new Array();
  8110. 		} else {
  8111. 			while (oldArenaMatches.length>1000)
  8112. 			{
  8113. 				oldArenaMatches.shift();
  8114. 			}
  8115. 			arenaMatches = oldArenaMatches;
  8116. 		}
  8117. 		var matchFound = false;
  8118. 		var minLvl=GM_getValue('arenaMinLvl',1);
  8119. 		var maxLvl=GM_getValue('arenaMaxLvl',1000);
  8120. 		for (var i=1; i<arenaTable.rows.length; i++){
  8121. 			var row = arenaTable.rows[i];
  8122.  
  8123. 			matchFound = false;
  8124. 			aMatch = new Object();
  8125. 			var arenaIDRE = /#\s(\d+)/;
  8126. 			var arenaID = arenaIDRE.exec(row.cells[0].textContent)[1]*1;
  8127. 			if (oldArenaMatches){
  8128. 				for (var k=0; k<oldArenaMatches.length; k++){
  8129. 					if (oldArenaMatches[k].arenaID == arenaID) {
  8130. 						matchFound = true;
  8131. 						break;
  8132. 					}
  8133. 				}
  8134. 			}
  8135. 			if (!matchFound) {
  8136. 				aMatch.arenaID = arenaID;
  8137. 				aMatch.arenaJoinCostHTML = row.cells[2].innerHTML;
  8138. 				aMatch.arenaSpecialsHTML = row.cells[4].innerHTML;
  8139. 				if (row.cells[4].innerHTML.search("/pvp/specials_1.gif") != -1) {
  8140. 					aMatch.arenaSpecials = true;
  8141. 				} else {
  8142. 					aMatch.arenaSpecials = false;
  8143. 				}
  8144. 				aMatch.arenaHellForgeHTML = row.cells[5].innerHTML;
  8145. 				aMatch.arenaEpicHTML = row.cells[6].innerHTML;
  8146. 				aMatch.arenaMaxEquipHTML = row.cells[7].innerHTML;
  8147. 				aMatch.arenaRewardHTML = row.cells[8].innerHTML;
  8148. 				arenaMatches.push(aMatch);
  8149. 			}
  8150.  
  8151. 			var prizeSRC = row.cells[8].firstChild.getAttribute("src");
  8152. 			var maxEquipLevel = row.cells[7].textContent*1;
  8153. 			if (hideMatchesForCompletedMoves && arenaMoves && prizeSRC && prizeSRC.search("/pvp/") != -1) {
  8154. 				for (var j=0; j<arenaMoves.length; j++){
  8155. 					var searchText = System.imageServerHTTP + "/pvp/" + arenaMoves[j].moveID+ ".gif";
  8156. 					if (prizeSRC == searchText && arenaMoves[j].moveCount == 3){
  8157. 						row.style.visibility = "hidden";
  8158. 						row.style.display = "none";
  8159. 						break;
  8160. 					}
  8161. 				}
  8162. 			}
  8163. 			if (prizeSRC && prizeSRC.search("/items/") != -1) {
  8164. 				var prizeImgElement = row.cells[8].firstChild;
  8165. 				var prizeOnmouseover = prizeImgElement.getAttribute("onmouseover");
  8166. 				var itemIdRE = /ajaxLoadCustom\((\d+)/;
  8167. 				var itemId = itemIdRE.exec(prizeOnmouseover)[1];
  8168. 				prizeOnmouseover = prizeOnmouseover.replace(/""/,'"ItemId = '+itemId+'"');
  8169. 				prizeImgElement.setAttribute("onmouseover", prizeOnmouseover);
  8170. 				if (hideArenaPrizes) {
  8171. 					for (k=0; k<hideArenaPrizesArray.length; k++){
  8172. 						var compareStr = System.imageServerHTTP + "/items/" + hideArenaPrizesArray[k] + ".gif";
  8173. 						if (prizeSRC == compareStr) {
  8174. 							row.style.visibility = "hidden";
  8175. 							row.style.display = "none";
  8176. 							break;
  8177. 						}
  8178. 					}
  8179. 				}
  8180. 			}
  8181. 			if (!(maxEquipLevel >= minLvl && maxEquipLevel <= maxLvl)) {
  8182. 				row.style.visibility = "hidden";
  8183. 				row.style.display = "none";
  8184. 			}
  8185.  
  8186. 			if (!matchFound) {
  8187. 				//color new matches since last visit
  8188. 				row.style.backgroundColor = '#F5F298';
  8189. 			}
  8190. 		}
  8191. 		System.setValueJSON("arenaMatches", arenaMatches);
  8192.  
  8193. 		Helper.getArenaTable();
  8194. 		Helper.addEventSortArena();
  8195. 		if (GM_getValue("autoSortArenaList")) {
  8196. 			Helper.sortArenaByHeader("");
  8197. 		}
  8198. 	},
  8199.  
  8200. 	setLevelFilter: function(evt) {
  8201. 		var filterSubject = evt.target.getAttribute("subject");
  8202. 		var href = evt.target.getAttribute("href");
  8203. 		var minLvlSearchText = filterSubject + "MinLvl";
  8204. 		var maxLvlSearchText = filterSubject + "MaxLvl";
  8205. 		var playerMinLvl = document.getElementById("Helper." + minLvlSearchText);
  8206. 		var playerMaxLvl = document.getElementById("Helper." + maxLvlSearchText);
  8207. 		if (playerMinLvl.value === '') playerMinLvl.value = '0';
  8208. 		if (playerMaxLvl.value === '') playerMaxLvl.value = '1000';
  8209. 		if (!isNaN(playerMinLvl.value))
  8210. 			GM_setValue(minLvlSearchText, parseInt(playerMinLvl.value,10));
  8211. 		if (!isNaN(playerMaxLvl.value))
  8212. 			GM_setValue(maxLvlSearchText, parseInt(playerMaxLvl.value,10));
  8213. 		if (href) window.location = System.server + href;
  8214. 		else window.location = window.location;
  8215. 	},
  8216.  
  8217. 	resetLevelFilter: function(evt) {
  8218. 		var filterSubject = evt.target.getAttribute("subject");
  8219. 		var href = evt.target.getAttribute("href");
  8220. 		var minLvlSearchText = filterSubject + "MinLvl";
  8221. 		var maxLvlSearchText = filterSubject + "MaxLvl";
  8222. 		GM_setValue(minLvlSearchText, 1);
  8223. 		document.getElementById("Helper." + minLvlSearchText).value=1;
  8224. 		GM_setValue(maxLvlSearchText, 1000);
  8225. 		document.getElementById("Helper." + maxLvlSearchText).value=1000;
  8226. 		if (href) window.location = System.server + href;
  8227. 		else window.location = window.location;
  8228. 	},
  8229.  
  8230. 	addEventSortArena: function() {
  8231. 		var titleCells=System.findNodes("//td[.='Id']/../td");
  8232. 		for (var i=0; i<titleCells.length; i++) {
  8233. 			var cell=titleCells[i];
  8234. 			cell.innerHTML = cell.innerHTML.replace(/ \[/,"<br>[");
  8235. 			if (cell.innerHTML.search("Max Equip Level") != -1 ||
  8236. 				cell.innerHTML.search("Join Cost") != -1 ||
  8237. 				cell.innerHTML.search("State") != -1 ||
  8238. 				cell.innerHTML.search("Specials") != -1 ||
  8239. 				cell.innerHTML.search("Hell Forge") != -1 ||
  8240. 				cell.innerHTML.search("Epic") != -1 ||
  8241. 				cell.innerHTML.search("Id") != -1){
  8242. 				cell.style.textDecoration="underline";
  8243. 				cell.style.cursor="pointer";
  8244. 				cell.innerHTML=cell.innerHTML.replace(/^&nbsp;/,"");
  8245. 				cell.addEventListener('click', Helper.sortArena, true);
  8246. 			}
  8247. 		}
  8248. 	},
  8249.  
  8250. 	hideMatchesForCompletedMoves: function(evt) {
  8251. 		GM_setValue("hideMatchesForCompletedMoves", evt.target.checked);
  8252. 		window.location=window.location;
  8253. 	},
  8254.  
  8255. 	sortArena: function(evt) {
  8256. 		Helper.sortArenaByHeader(evt.target.textContent.replace(/[ \s]/g,""));
  8257. 	},
  8258.  
  8259. 	getArenaTable: function() {
  8260. 		var list=System.findNode("//td[.='Id']/../..");
  8261.  
  8262. 		Helper.arenaRows = new Array();
  8263. 		for (var i=1; i<list.rows.length; i++){
  8264. 			var theRow=list.rows[i];
  8265. 			Helper.arenaRows[i-1] = {
  8266. 				'ArenaID': theRow.cells[0].textContent,
  8267. 				'Players': theRow.cells[1].textContent,
  8268. 				'JoinCost': theRow.cells[2].textContent.replace(/,/g,"")*1,
  8269. 				'JoinCostHTML': theRow.cells[2].innerHTML,
  8270. 				'State': theRow.cells[3].textContent,
  8271. 				'Specials[?]': (theRow.cells[4].firstChild.getAttribute("src").search("/specials_1.gif") == -1? 1:0),
  8272. 				'SpecialsHTML': theRow.cells[4].innerHTML,
  8273. 				'HellForge[?]': (theRow.cells[5].firstChild.getAttribute("src").search("/specials_1.gif") == -1? 1:0),
  8274. 				'HellForgeHTML': theRow.cells[5].innerHTML,
  8275. 				'Epic[?]': (theRow.cells[6].firstChild.getAttribute("src").search("/specials_1.gif") == -1? 1:0),
  8276. 				'EpicHTML': theRow.cells[6].innerHTML,
  8277. 				'MaxEquipLevel': theRow.cells[7].textContent*1,
  8278. 				'MaxEquipLevelHTML': theRow.cells[7].innerHTML,
  8279. 				'Reward': theRow.cells[8].innerHTML,
  8280. 				'Action': theRow.cells[9].innerHTML,
  8281. 				'Visibility': theRow.style.visibility,
  8282. 				'BackgroundColor': theRow.style.backgroundColor
  8283. 			};
  8284. 		}
  8285. 	},
  8286.  
  8287. 	sortArenaByHeader: function(headerClicked) {
  8288. 		if (headerClicked==="") {
  8289. 			headerClicked = GM_getValue("arenaSortBy");
  8290. 			if (headerClicked == undefined) headerClicked="State";
  8291. 		} else {
  8292. 			GM_setValue("arenaSortBy", headerClicked);
  8293. 		}
  8294. 		if (headerClicked=="Id") headerClicked="ArenaID";
  8295.  
  8296. 		if (Helper.sortAsc==undefined) {
  8297. 			Helper.sortAsc=GM_getValue("arenaSortAsc");
  8298. 			if (Helper.sortAsc==undefined) Helper.sortAsc=false;
  8299. 		} else {
  8300. 			if (Helper.sortBy && Helper.sortBy==headerClicked) {
  8301. 				Helper.sortAsc=!Helper.sortAsc;
  8302. 			}
  8303. 		}
  8304. 		GM_setValue("arenaSortAsc",Helper.sortAsc);
  8305. 		Helper.sortBy=headerClicked;
  8306.  
  8307. 		if (headerClicked=="Member" || headerClicked=="State") {
  8308. 			Helper.arenaRows.sort(Helper.stringSort);
  8309. 		}
  8310. 		else {
  8311. 			Helper.arenaRows.sort(Helper.numberSort);
  8312. 		}
  8313.  
  8314. 		var list=System.findNode("//td[.='Id']/../..");
  8315. 		var result='<tr>' + list.rows[0].innerHTML + '</tr>';
  8316.  
  8317. 		var minLvl=GM_getValue('arenaMinLvl',1);
  8318. 		var maxLvl=GM_getValue('arenaMaxLvl',1000);
  8319. 		for (var i=0; i<Helper.arenaRows.length; i++){
  8320. 			var r = Helper.arenaRows[i];
  8321. 			//var bgColor=((i % 2)==0)?'bgcolor="#e7c473"':'bgcolor="#e2b960"'
  8322. 			var bgColor='bgcolor="'+r.BackgroundColor+'"';
  8323. 			if (r.Action.search("View") != -1) {
  8324. 				bgColor = 'bgcolor="#f5e2b3"';
  8325. 			}
  8326. 			if (r.Visibility!="hidden" && r.MaxEquipLevel >= minLvl && r.MaxEquipLevel <= maxLvl) {
  8327. 				result += '<TR>'+
  8328. 				'<TD '+bgColor+' style="border-bottom:1px solid #CD9E4B;">'+r.ArenaID+'</TD>'+
  8329. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;">'+r.Players+'</TD>'+
  8330. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;">'+r.JoinCostHTML+'</TD>'+
  8331. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;">'+r.State+'</TD>'+
  8332. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;">'+r.SpecialsHTML+'</TD>'+
  8333. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;">'+r.HellForgeHTML+'</TD>'+
  8334. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;">'+r.EpicHTML+'</TD>'+
  8335. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;">'+r.MaxEquipLevelHTML+'</TD>'+
  8336. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;">'+r.Reward+'</TD>'+
  8337. 				'<TD '+bgColor+' align="center" style="border-bottom:1px solid #CD9E4B;"><form method="post" action="index.php">'+r.Action+'</form></TD></TR>';
  8338. 			}
  8339. 		}
  8340. 		//result+='<tr>' + list.rows[list.rows.length-1].innerHTML + '</tr>'
  8341.  
  8342. 		list.innerHTML=result;
  8343.  
  8344. 		Helper.addEventSortArena();
  8345. 	},
  8346.  
  8347. 	storeArenaMoves: function(){
  8348. 		var arenaMoves = System.findNodes("//img[@vspace='4']");
  8349. 		var moves = new Array();
  8350. 		for (var i=1; i<arenaMoves.length; i++) {
  8351. 			arenaMove = arenaMoves[i];
  8352. 			aMove = new Object();
  8353. 			var moveGifNumberRE = /(\d+).gif/;
  8354. 			var moveGifNumber = moveGifNumberRE.exec(arenaMove.getAttribute("src"))[1];
  8355. 			var moveCountRE = /<\/a><br>(\d)\&nbsp;\/\&nbsp;(\d)/;
  8356. 			var moveCount = moveCountRE.exec(arenaMove.parentNode.parentNode.innerHTML);
  8357. 			aMove.moveID = moveGifNumber;
  8358. 			aMove.moveCount = moveCount[2];
  8359. 			aMove.moveHREF = arenaMove.getAttribute("src");
  8360. 			moves.push(aMove);
  8361. 		}
  8362. 		System.setValueJSON("arenaMoves", moves);
  8363. 	},
  8364.  
  8365. 	injectTournament: function() {
  8366. 		var mainTable = System.findNode("//table[tbody/tr/td/a[.='Back to PvP Arena']]");
  8367. 		var joinPage = System.findNode("//b[.='Your Tournament Stats']");
  8368. 		var injectHere = mainTable.rows[4].cells[0];
  8369. 		injectHere.align='center';
  8370.  
  8371. 		var tournamentTitle = System.findNode("//b[contains(.,'Tournament #')]");
  8372. 		var tournamentIDRE = /Tournament #(\d+)/;
  8373. 		var tournamentID = tournamentIDRE.exec(tournamentTitle.innerHTML)[1]*1;
  8374. 		var arenaMatches = System.getValueJSON("arenaMatches");
  8375. 		if (!arenaMatches) {return;}
  8376. 		for (var k=0; k<arenaMatches.length; k++){
  8377. 			if (arenaMatches[k].arenaID == tournamentID && !arenaMatches[k].arenaHTML) {
  8378. 				var tournamentHTML = '<table><tbody>'+
  8379. 					'<tr bgcolor="#CD9E4B"><td>Join Cost</td><td>Specials</td><td>Hell Forge</td><td>Max Equip</td><td>Reward</td></tr>'+
  8380. 					'<tr><td>'+arenaMatches[k].arenaJoinCostHTML+'</td><td>'+arenaMatches[k].arenaSpecialsHTML+
  8381. 						'</td><td>'+arenaMatches[k].arenaHellForgeHTML+'</td><td>'+arenaMatches[k].arenaMaxEquipHTML+
  8382. 						'</td><td>'+arenaMatches[k].arenaRewardHTML+'</td></tr>';
  8383. 				if (arenaMatches[k].arenaSpecials && joinPage) {
  8384. 					tournamentHTML+='<tr><td colspan=5><span id="Helper:combatMoves"></span></td></tr>';
  8385. 					System.xmlhttp("index.php?cmd=arena&subcmd=setup", Helper.getCombatMoves);
  8386. 				}
  8387. 				tournamentHTML+='</tbody></table>';
  8388. 				injectHere.innerHTML = tournamentHTML;
  8389. 				break;
  8390. 			}
  8391. 		}
  8392. 	},
  8393.  
  8394. 	getCombatMoves: function(responseText, callback) {
  8395. 		var doc=System.createDocument(responseText);
  8396. 		var combatMovesTable = System.findNode("//td[table/tbody/tr/td/table/tbody/tr/td/a[@href='index.php?cmd=arena&subcmd=pickmove&slot_id=1']]", doc);
  8397. 		var injectHere = System.findNode("//span[@id='Helper:combatMoves']");
  8398. 		injectHere.innerHTML = combatMovesTable.innerHTML;
  8399. 	},
  8400.  
  8401. 	storeCompletedArenas: function() {
  8402. 		//fix button class and add go to first and last
  8403. 		var prevButton = System.findNode("//input[@value='<']");
  8404. 		var nextButton = System.findNode("//input[@value='>']");
  8405. 		if (prevButton) {
  8406. 			prevButton.setAttribute("class", "custombutton");
  8407. 			var startButton = document.createElement("input");
  8408. 			startButton.setAttribute("type", "button");
  8409. 			startButton.setAttribute("onclick", prevButton.getAttribute("onclick").replace(/\&page=[0-9]*/, "&page=1"));
  8410. 			startButton.setAttribute("class", "custombutton");
  8411. 			startButton.setAttribute("value", "<<");
  8412. 			prevButton.parentNode.insertBefore(startButton,prevButton);
  8413. 		}
  8414. 		if (nextButton) {
  8415. 			nextButton.setAttribute("class", "custombutton");
  8416. 			var lastPageNode=System.findNode("//input[@value='Go']/../preceding-sibling::td");
  8417. 			lastPage = lastPageNode.textContent.replace(/\D/g,"");
  8418. 			var finishButton = document.createElement("input");
  8419. 			finishButton.setAttribute("type", "button");
  8420. 			finishButton.setAttribute("onclick", nextButton.getAttribute("onclick").replace(/\&page=[0-9]*/, "&page=" + lastPage));
  8421. 			finishButton.setAttribute("class", "custombutton");
  8422. 			finishButton.setAttribute("value", ">>");
  8423. 			nextButton.parentNode.insertBefore(finishButton, nextButton.nextSibling);
  8424. 		}
  8425.  
  8426. 		arenaTable = System.findNode("//table[@width=620]/tbody/tr/td[contains(.,'Reward')]/table");
  8427.  
  8428. 		var arenaMoves = System.getValueJSON("arenaMoves");
  8429. 		var oldArenaMatches = System.getValueJSON("arenaMatches");
  8430. 		if (!oldArenaMatches) {
  8431. 			arenaMatches = new Array();
  8432. 		} else {
  8433. 			while (oldArenaMatches.length>1000)
  8434. 			{
  8435. 				oldArenaMatches.shift();
  8436. 			}
  8437. 			arenaMatches = oldArenaMatches;
  8438. 		}
  8439. 		var matchFound = false;
  8440.  
  8441. 		for (var i=1; i<arenaTable.rows.length-1; i++){
  8442. 			var row = arenaTable.rows[i];
  8443. 			matchFound = false;
  8444. 			aMatch = new Object();
  8445. 			var arenaIDRE = /#\s(\d+)/;
  8446. 			var arenaID = arenaIDRE.exec(row.cells[0].textContent)[1]*1;
  8447. 			if (oldArenaMatches){
  8448. 				for (var k=0; k<oldArenaMatches.length; k++){
  8449. 					if (oldArenaMatches[k].arenaID == arenaID) {
  8450. 						matchFound = true;
  8451. 						break;
  8452. 					}
  8453. 				}
  8454. 			}
  8455. 			if (!matchFound) {
  8456. 				aMatch.arenaID = arenaID;
  8457. 				aMatch.arenaJoinCostHTML = row.cells[2].innerHTML;
  8458. 				aMatch.arenaSpecialsHTML = row.cells[4].innerHTML;
  8459. 				if (row.cells[4].innerHTML.search("/pvp/specials_1.gif") != -1) {
  8460. 					aMatch.arenaSpecials = true;
  8461. 				} else {
  8462. 					aMatch.arenaSpecials = false;
  8463. 				}
  8464. 				aMatch.arenaHellForgeHTML = row.cells[5].innerHTML;
  8465. 				aMatch.arenaMaxEquipHTML = row.cells[6].innerHTML;
  8466. 				aMatch.arenaRewardHTML = row.cells[7].innerHTML;
  8467. 				arenaMatches.push(aMatch);
  8468. 			}
  8469. 		}
  8470. 		System.setValueJSON("arenaMatches", arenaMatches);
  8471. 	},
  8472.  
  8473. 	injectRelicList: function(){
  8474. 		var relics = Data.relicList();
  8475. 		var relicImages = System.findNodes("//img[contains(@src,'/relics/')]");
  8476. 		var relicFound = false;
  8477. 		for (var i=0; i<relicImages.length; i++){
  8478. 			var relicImage = relicImages[i];
  8479. 			var relicName = relicImage.parentNode.nextSibling.nextSibling.textContent.trim();
  8480. 			relicFound = false;
  8481. 			for (var j=0; j<relics.length; j++){
  8482. 				var relic = relics[j];
  8483. 				if (relicName == relic.Name.trim()){
  8484. 					var onmouseoverText='Tip(\'' +
  8485. 						'<span style=\\\'font-weight:bold; color:#FFF380;\\\'>' + relic.Name + '</span><br /><br />' +
  8486. 						relic.Realm + '<br><br>' +
  8487. 						relic.Comment + '\');';
  8488. 					relicImage.setAttribute("onmouseover", onmouseoverText);
  8489. 					relicFound = true;
  8490. 					break;
  8491. 				}
  8492. 			}
  8493. 			if (!relicFound) GM_log("Relic:'" + relicName + "' not found in data set");
  8494. 		}
  8495. 	},
  8496.  
  8497. 	injectSettingsGuildData: function(guildType) {
  8498. 		var result='';
  8499. 		result += '<input name="guild' + guildType + '" size="60" value="' + GM_getValue("guild" + guildType) + '">';
  8500. 		result += '<span style="cursor:pointer;text-decoration:none;" id="toggleShowGuild' + guildType + 'Message" linkto="showGuild' +
  8501. 			guildType + 'Message"> &#x00bb;</span>';
  8502. 		result += '<div id="showGuild' + guildType + 'Message" style="visibility:hidden;display:none">';
  8503. 		result += '<input name="guild' + guildType + 'Message" size="60" value="' + GM_getValue("guild" + guildType + "Message") + '">';
  8504. 		result += '</div>';
  8505. 		return result;
  8506. 	},
  8507.  
  8508. 	saveImgLoc: function (evt) {
  8509. 		try {
  8510. 			var imgLocText = System.findNode("//input[@name='local_dir']");
  8511. 			if (imgLocText && imgLocText.value.trim().length > 0) {
  8512. 				GM_setValue("lastImgLoc", imgLocText.value.trim());
  8513. 			}
  8514. 		} catch (err) {
  8515. 			GM_log(err);
  8516. 		}
  8517. 	},
  8518.  
  8519. 	setImgLoc: function (evt) {
  8520. 		try {
  8521. 			var imgLocText = System.findNode("//input[@name='local_dir']");
  8522. 			if (imgLocText) {
  8523. 				imgLocText.value = GM_getValue("lastImgLoc");
  8524. 			}
  8525. 		} catch (err) {
  8526. 			GM_log(err);
  8527. 		}
  8528. 	},
  8529.  
  8530. 	injectSettings: function() {
  8531. 		try {
  8532. 			var exNode = System.findNode("//font[contains(.,'Example:')]");
  8533. 			var saveButton = System.findNode("//input[contains(@value, 'Save Settings')]");
  8534. 			saveButton.addEventListener('click', Helper.saveImgLoc, true);
  8535. 			if (GM_getValue("lastImgLoc")) {
  8536. 				exNode.innerHTML = "Last Location Set:<br><a href='#' id='Helper.lastImgLocLink'>" + GM_getValue("lastImgLoc") + "</a>";
  8537. 				document.getElementById('Helper.lastImgLocLink').addEventListener('click', Helper.setImgLoc, true);
  8538. 			}
  8539. 		} catch (err) {
  8540. 			GM_log(err);
  8541. 		}
  8542. 		var lastCheck=new Date(parseInt(GM_getValue("lastVersionCheck"),10));
  8543. 		var buffs=GM_getValue("huntingBuffs");
  8544. 		var doNotKillList=GM_getValue("doNotKillList");
  8545. 		var hideArenaPrizes=GM_getValue("hideArenaPrizes");
  8546.  
  8547. 		var enableActiveBountyList = GM_getValue("enableActiveBountyList");
  8548. 		var bountyListRefreshTime = GM_getValue("bountyListRefreshTime");
  8549. 		var enableWantedList = GM_getValue("enableWantedList");
  8550. 		var wantedNames = GM_getValue("wantedNames");
  8551. 		var combatEvaluatorBias = GM_getValue("combatEvaluatorBias");
  8552.  
  8553. 		var configData=
  8554. 			'<form><table width="100%" cellspacing="0" cellpadding="5" border="0">' +
  8555. 			'<tr><td colspan="2" height="1" bgcolor="#333333"></td></tr>' +
  8556. 			'<tr><td colspan="2"><b>Fallen Sword Helper configuration</b></td></tr>' +
  8557. 			'<tr><td colspan="2" align=center><input type="button" class="custombutton" value="Check for updates" id="Helper:CheckUpdate"></td></tr>'+
  8558. 			'<tr><td colspan="2" align=center><span style="font-size:xx-small">(Current version: ' + GM_getValue("currentVersion") + ', Last check: ' + lastCheck.toFormatString("dd/MMM/yyyy HH:mm:ss") +
  8559. 			')</span></td></tr>' +
  8560. 			'<tr><td colspan="2" align=center>' +
  8561. 			'<span style="font-weight:bold;">Visit the <a href="http://code.google.com/p/fallenswordhelper/">Fallen Sword Helper web site</a> ' +
  8562. 			'for any suggestions, requests or bug reports</span></td></tr>' +
  8563. 			//General Prefs
  8564. 			'<tr><th colspan="2" align="left">General preferences (apply to most screens)</th></tr>' +
  8565. 			'<tr><td align="right">Enable Guild Info Widgets' + Helper.helpLink('Enable Guild Info Widgets', 'Enabling this option will enable the Guild Info Widgets (coloring on the Guild Info panel)') +
  8566. 				':</td><td><input name="enableGuildInfoWidgets" type="checkbox" value="on"' + (GM_getValue("enableGuildInfoWidgets")?" checked":"") +
  8567. 				'>  Hide Message&gt;<input name="hideGuildInfoMessage" type="checkbox" value="on"' + (GM_getValue("hideGuildInfoMessage")?" checked":"") +
  8568. 				'>  Hide Buff&gt;<input name="hideGuildInfoBuff" type="checkbox" value="on"' + (GM_getValue("hideGuildInfoBuff")?" checked":"") +
  8569. 				'>  Hide ST&gt;<input name="hideGuildInfoSecureTrade" type="checkbox" value="on"' + (GM_getValue("hideGuildInfoSecureTrade")?" checked":"") +
  8570. 				'>  Hide Trade&gt;<input name="hideGuildInfoTrade" type="checkbox" value="on"' + (GM_getValue("hideGuildInfoTrade")?" checked":"") +
  8571. 				'></td></tr>'  +
  8572. 			'<tr><td align="right">Move Guild Info List' + Helper.helpLink('Move Guild Info List', 'This will Move the Guild Info List higher on the bar on the right') +
  8573. 				':</td><td><input name="moveGuildList" type="checkbox" value="on"' + (GM_getValue("moveGuildList")?" checked":"") + '>' +
  8574. 				'</td></tr>' +
  8575. 			'<tr><td align="right">'+Layout.networkIcon()+'Show Online Allies/Enemies' + Helper.helpLink('Show Online Allies/Enemies', 'This will show the allies/enemies online list on the right.') +
  8576. 				':</td><td>Allies<input name="enableAllyOnlineList" type="checkbox" value="on"' + (GM_getValue("enableAllyOnlineList")?" checked":"") +
  8577. 				'> Enemies<input name="enableEnemyOnlineList" type="checkbox" value="on"' + (GM_getValue("enableEnemyOnlineList")?" checked":"") +
  8578. 				'> <input name="allyEnemyOnlineRefreshTime" size="1" value="'+ GM_getValue("allyEnemyOnlineRefreshTime") + '" /> seconds refresh</td></tr>' +
  8579. 			'<tr><td align="right">Hide Top Banner' + Helper.helpLink('Hide Top Banner', 'Pretty simple ... it just hides the top banner') +
  8580. 				':</td><td><input name="hideBanner" type="checkbox" value="on"' + (GM_getValue("hideBanner")?" checked":"") + '></td></tr>' +
  8581. 			'<tr><td align="right">Show ST/Date At Top' + Helper.helpLink('Show ST/Date At Top', 'Adds the current server time on the top banner over the dragon\\\'s head. Does nothing if you hide the top banner. ' +
  8582. 				'Also, if you have the HCS option to hide the Game Stats box, this will not work either.') +
  8583. 				':</td><td><input name="showSTUpTop" type="checkbox" value="on"' + (GM_getValue("showSTUpTop")?" checked":"") + '></td></tr>' +
  8584. 			'<tr><td align="right">Move FS box' + Helper.helpLink('Move FallenSword Box', 'This will move the FS box to the left, under the menu, for better visibility (unless it is already hidden.)') +
  8585. 				':</td><td><input name="moveFSBox" type="checkbox" value="on"' + (GM_getValue("moveFSBox")?" checked":"") + '></td></tr>' +
  8586. 			'<tr><td align="right">"Game Help" Settings Link' + Helper.helpLink('Game Help Settings Link', 'This turns the Game Help text in the lower right box into a link to this settings page. This can be helpful if you use the FS Image Pack.') +
  8587. 				':</td><td><input name="gameHelpLink" type="checkbox" value="on"' + (GM_getValue("gameHelpLink")?" checked":"") + '></td></tr>' +
  8588. 			'<tr><td align="right">Enable Temple Alert' + Helper.helpLink('Enable Temple Alert', 'Puts an alert on the LHS if you  have not prayed at the temple today. Checks once every 60 mins.') +
  8589. 				':</td><td><input name="enableTempleAlert" type="checkbox" value="on"' + (GM_getValue("enableTempleAlert")?" checked":"") + '></td></tr>' +
  8590. 			//Guild Manage
  8591. 			'<tr><th colspan="2" align="left">Guild>Manage preferences</th></tr>' +
  8592. 			'<tr><td colspan="2" align="left">Enter guild names, seperated by commas</td></tr>' +
  8593. 			'<tr><td>Own Guild</td><td>'+ Helper.injectSettingsGuildData("Self") + '</td></tr>' +
  8594. 			'<tr><td>Friendly Guilds</td><td>'+ Helper.injectSettingsGuildData("Frnd") + '</td></tr>' +
  8595. 			'<tr><td>Old Guilds</td><td>'+ Helper.injectSettingsGuildData("Past") + '</td></tr>' +
  8596. 			'<tr><td>Enemy Guilds</td><td>'+ Helper.injectSettingsGuildData("Enmy") + '</td></tr>' +
  8597. 			'<tr><td align="right">Highlight Valid PvP Targets' + Helper.helpLink('Highlight Valid PvP Targets', 'Enabling this option will highlight targets in OTHER guilds that are within your level range to attack for PvP or GvG.') +
  8598. 				':</td><td>PvP: <input name="highlightPlayersNearMyLvl" type="checkbox" value="on"' + (GM_getValue("highlightPlayersNearMyLvl")?" checked":"") +
  8599. 				'> GvG: <input name="highlightGvGPlayersNearMyLvl" type="checkbox" value="on"' + (GM_getValue("highlightGvGPlayersNearMyLvl")?" checked":"") + '" /></td></tr>'  +
  8600. 			'<tr><td align="right">Show rank controls' + Helper.helpLink('Show rank controls', 'Show ranking controls for guild managemenet in member profile page - ' +
  8601. 				'this works for guild founders only') +
  8602. 				':</td><td><input name="showAdmin" type="checkbox" value="on"' + (GM_getValue("showAdmin")?" checked":"") + '></td></tr>' +
  8603. 			'<tr><td align="right">AJAXify rank controls' + Helper.helpLink('AJAXify rank controls', 'Enables guild founders with ranking rights to change rank positions without a screen refresh.') +
  8604. 				':</td><td><input name="ajaxifyRankControls" type="checkbox" value="on"' + (GM_getValue("ajaxifyRankControls")?" checked":"") + '></td></tr>' +
  8605. 			'<tr><td align="right">Show Conflict Details' + Helper.helpLink('Show Conflict Details', 'Inserts detailed conflict information onto your guild\\\'s manage page. Currently displays the target guild as well as the current score.') +
  8606. 				':</td><td><input name="detailedConflictInfo" type="checkbox" value="on"' + (GM_getValue("detailedConflictInfo")?" checked":"") + '></td></tr>' +
  8607. 			//World Screen
  8608. 			'<tr><th colspan="2" align="left">World screen/Hunting preferences</th></tr>' +
  8609. 			'<tr><td align="right">Quick Kill ' + Helper.helpLink('Quick Kill', 'This will kill monsters without opening a new page') +
  8610. 				':</td><td><input name="quickKill" type="checkbox" value="on"' + (GM_getValue("quickKill")?" checked":"") + '>' +
  8611. 				'</td></tr>' +
  8612. 			'<tr><td align="right">Keep Combat Logs' + Helper.helpLink('Keep Combat Logs', 'Save combat logs to a temporary variable. '+
  8613. 				'Press <u>Show logs</u> on the right to display and copy them') +
  8614. 				':</td><td><input name="keepLogs" type="checkbox" value="on"' + (GM_getValue("keepLogs")?" checked":"") + '>' +
  8615. 				'<input type="button" class="custombutton" value="Show Logs" id="Helper:ShowLogs"></td></tr>' +
  8616. 			'<tr><td align="right">Show Combat Log' + Helper.helpLink('Show Combat Log', 'This will show the combat log for each automatic battle below the monster list.') +
  8617. 				':</td><td><input name="showCombatLog" type="checkbox" value="on"' + (GM_getValue("showCombatLog")?" checked":"") + '></td></tr>' +
  8618. 			'<tr><td align="right">Color Special Creatures' + Helper.helpLink('Color Special Creatures', 'Creatures will be colored according to their rarity. ' +
  8619. 				'Champions will be colored green, Elites yellow and Super Elites red.') +
  8620. 				':</td><td><input name="enableCreatureColoring" type="checkbox" value="on"' + (GM_getValue("enableCreatureColoring")?" checked":"") + '></td></td></tr>' +
  8621. 			'<tr><td align="right">'+Layout.networkIcon()+'Show Creature Info' + Helper.helpLink('Show Creature Info', 'This will show the information from the view creature link when you mouseover the link.' +
  8622. 				((System.browserVersion<3)?'<br>Does not work in Firefox 2 - suggest disabling or upgrading to Firefox 3.':'')) +
  8623. 				':</td><td><input name="showCreatureInfo" type="checkbox" value="on"' + (GM_getValue("showCreatureInfo")?" checked":"") + '></td></tr>' +
  8624. 			'<tr><td align="right">Combat Evaluator Bias' + Helper.helpLink('Combat Evaluator Bias', 'This changes the bias of the combat evaluator for the damage and HP evaluation. It will not change the attack bias (1.1053).'+
  8625. 					'<br>Conservative = 1.1053 and 1.1 (Safest)'+
  8626. 					'<br>Semi-Conservative = 1.1 and 1.053'+
  8627. 					'<br>Adventurous = 1.053 and 1 (Bleeding Edge)') +
  8628. 				':</td><td><select name="combatEvaluatorBias"><option value="0"' + (combatEvaluatorBias==0?" SELECTED":"") +
  8629. 					'>Conservative</option><option value="1"' + (combatEvaluatorBias==1?" SELECTED":"") +
  8630. 					'>Semi-Conservative</option><option value="2"' + (combatEvaluatorBias==2?" SELECTED":"") +
  8631. 					'>Adventurous</option></select></td></tr>' +
  8632. 			'<tr><td align="right">Keep Creature Log' + Helper.helpLink('Keep Creature Log', 'This will show the creature log for each creature you see when you travel. This requires Show Creature Info enabled!') +
  8633. 				':</td><td><input name="showMonsterLog" type="checkbox" value="on"' + (GM_getValue("showMonsterLog")?" checked":"") + '>'+
  8634. 				'&nbsp;&nbsp;<input type="button" class="custombutton" value="Show" id="Helper:ShowMonsterLogs"></td></tr>' +
  8635. 			'<tr><td align="right">Hide Krul Portal' + Helper.helpLink('Hide Krul Portal', 'This will hide the Krul portal on the world screen.') +
  8636. 				':</td><td><input name="hideKrulPortal" type="checkbox" value="on"' + (GM_getValue("hideKrulPortal")?" checked":"") + '></td></tr>' +
  8637. 			'<tr><td align="right">Footprints Color' + Helper.helpLink('Footprints Color', 'Changes the color of the footprints, useful if you can\\\'t see them in some maps') +
  8638. 				':</td><td><input name="footprintsColor" size="12" value="'+ GM_getValue("footprintsColor") + '" /><input type="button" class="custombutton" value="Update Color" id="Helper:updateFpColor"><table width="40" height="40" cellspacing="0" cellpadding="0" border="0"><td width="40" height="40" background="' + GM_getValue("currentTile") + '" align="center" style="color:' + GM_getValue("footprintsColor") + ';"><center><table width="40" height="40" cellspacing="0" cellpadding="0" border="0"><tbody><tr><td align="center">**</td></tr></tbody></table></center></td></table></td></tr>' +
  8639. 			'<tr><td align="right">Reset Footprints' + Helper.helpLink('Reset Footprints', 'Resets the footprints variable.') +
  8640. 				':</td><td>Current Size: ' + (!GM_getValue("map") ? 'N/A' : GM_getValue("map").length + ' <input type="button" class="custombutton" value="Reset" id="Helper:ResetFootprints">') + '</td></tr></td></tr>' +
  8641. 			'<tr><td align="right">Show Send Gold' + Helper.helpLink('Show Gold on World Screen', 'This will show an icon below the world map to allow you to quickly send gold to a Friend.') +
  8642. 				':</td><td><input name="sendGoldonWorld" type="checkbox" value="on"' + (GM_getValue("sendGoldonWorld")?" checked":"") + '>'+
  8643. 				'Send <input name="goldAmount" size="5" value="'+ GM_getValue("goldAmount") + '" /> '+
  8644. 				'gold to <input name="goldRecipient" size="10" value="'+ GM_getValue("goldRecipient") + '" />' +
  8645. 				' Current total: <input name="currentGoldSentTotal" size="5" value="'+ GM_getValue("currentGoldSentTotal") + '" />' +
  8646. 				'</td></tr>' +
  8647. 			'<tr><td align="right">Do Not Kill List' + Helper.helpLink('Do Not Kill List', 'List of creatures that will not be killed by quick kill. You must type the full name of each creature, ' +
  8648. 				'separated by commas. Creature name will show up in red color on world screen and will not be killed by keyboard entry (but can still be killed by mouseclick). Quick kill must be '+
  8649. 				'enabled for this function to work.') +
  8650. 				':</td><td colspan="3"><input name="doNotKillList" size="60" value="'+ doNotKillList + '" /></td></tr>' +
  8651. 			'<tr><td align="right">Hunting Buffs' + Helper.helpLink('Hunting Buffs', 'Customize which buffs are designated as hunting buffs. You must type the full name of each buff, ' +
  8652. 				'separated by commas. Use the checkbox to enable/disable them.') +
  8653. 				':</td><td colspan="3"><input name="showHuntingBuffs" type="checkbox" value="on"' + (GM_getValue("showHuntingBuffs")?" checked":"") + '>' +
  8654. 				'<input name="huntingBuffs" size="60" value="'+ buffs + '" /></td></tr>' +
  8655. 			'<tr><td align="right">Enable FS Box Log' + Helper.helpLink('Enable FS Box Log', 'This enables the functionality to keep a log of recent seen FS Box message.') +
  8656. 				':</td><td><input name="fsboxlog" type="checkbox" value="on"' + (GM_getValue("fsboxlog")?" checked":"") + '></td></tr>' +
  8657. 			'<tr><td align="right">Enable Buff Log' + Helper.helpLink('Enable Buff Log', 'This enables the functionality to keep a log of recently casted buffs') +
  8658. 				':</td><td><input name="keepBuffLog" type="checkbox" value="on"' + (GM_getValue("keepBuffLog")?" checked":"") + '></td></tr>' +
  8659. 			'<tr><td align="right">Enable Hunting Mode' + Helper.helpLink('Enable Hunting Mode', 'This disable menu and some visual features to speed up the Helper.') +
  8660. 				':</td><td><input name="huntingMode" type="checkbox" value="on"' + (GM_getValue("huntingMode")?" checked":"") + '></td></tr>' +
  8661. 			'<tr><td align="right">Show FSG icon' + Helper.helpLink('Show FSG icon', 'This will show the FSG icon on the world page that links to the map for the page.') +
  8662. 				':</td><td><input name="showFSGIcon" type="checkbox" value="on"' + (GM_getValue("showFSGIcon")?" checked":"") + '></td></tr>' +
  8663. 			//Log screen prefs
  8664. 			'<tr><th colspan="2" align="left">Log screen preferences</th></tr>' +
  8665. 			'<tr><td align="right">Cleanup Guild Log' + Helper.helpLink('Dim Non Player Guild Log Messages', 'Any log messages not related to the ' +
  8666. 				'current player will be dimmed (e.g. recall messages from guild store)') +
  8667. 				':</td><td><input name="hideNonPlayerGuildLogMessages" type="checkbox" value="on"' + (GM_getValue("hideNonPlayerGuildLogMessages")?" checked":"") + '></td></td></tr>' +
  8668. 			'<tr><td align="right">Use New Guild Log' + Helper.helpLink('Use New Guild Log', 'This will replace the standard guild log with the helper version of the guild log.') +
  8669. 				':</td><td><input name="useNewGuildLog" type="checkbox" value="on"' + (GM_getValue("useNewGuildLog")?" checked":"") + '></td></td></tr>' +
  8670. 			'<tr><td align="right">New Guild Log History' + Helper.helpLink('New Guild Log History (pages)', 'This is the number of pages that the new guild log screen will go back in history.') +
  8671. 				':</td><td><input name="newGuildLogHistoryPages" size="1" value="'+ GM_getValue("newGuildLogHistoryPages") + '" /></td></td></tr>' +
  8672. 			'<tr><td align="right">Enable Log Coloring' + Helper.helpLink('Enable Log Coloring', 'Three logs will be colored if this is enabled, Guild Chat, Guild Log and Player Log. ' +
  8673. 				'It will show any new messages in yellow and anything 20 minutes old ones in brown.') +
  8674. 				':</td><td><input name="enableLogColoring" type="checkbox" value="on"' + (GM_getValue("enableLogColoring")?" checked":"") + '></td></td></tr>' +
  8675. 			'<tr><td align="right">New Log Message Sound' + Helper.helpLink('New Log Message Sound', 'The .wav or .ogg file to play when you have unread log messages. This must be a .wav or .ogg file. This option can be turned on/off on the world page. Only works in Firefox 3.5+') +
  8676. 				':</td><td colspan="3"><input name="defaultMessageSound" size="60" value="'+ GM_getValue("defaultMessageSound") + '" /></td></tr>' +
  8677. 			'<tr><td align="right">Play sound on unread log' + Helper.helpLink('Play sound on unread log', 'Should the above sound play when you have unread log messages? (will work on Firefox 3.5+ only)') +
  8678. 				':</td><td><input name="playNewMessageSound" type="checkbox" value="on"' + (GM_getValue("playNewMessageSound")?" checked":"") + '>' +
  8679. 				' Show speaker on world' + Helper.helpLink('Show speaker on world', 'Should the toggle play sound speaker show on the world map? (This icon is next to the Fallenswordguide and Fallensword wiki icons and will only display on Firefox 3.5+)') +
  8680. 				':<input name="showSpeakerOnWorld" type="checkbox" value="on"' + (GM_getValue("showSpeakerOnWorld")?" checked":"") + '></tr></td>' +
  8681. 			'<tr><td align="right">Enable Chat Parsing' + Helper.helpLink('Enable Chat Parsing', 'If this is checked, your character log will be parsed for chat messages and show the chat message on the screen if you reply to that message.') +
  8682. 				':</td><td><input name="enableChatParsing" type="checkbox" value="on"' + (GM_getValue("enableChatParsing")?" checked":"") + '></td></td></tr>' +
  8683. 			'<tr><td align="right">Add attack link to log' + Helper.helpLink('Add attack link to log', 'If checked, this will add an Attack link to each message in your log.') +
  8684. 				':</td><td><input name="addAttackLinkToLog" type="checkbox" value="on"' + (GM_getValue("addAttackLinkToLog")?" checked":"") + '></td></td></tr>' +
  8685. 			'<tr><td align="right">Enhance Chat Text Entry' + Helper.helpLink('Enhance Chat Text Entry', 'If checked, this will enhance the entry field for entering chat text on the guild chat page.') +
  8686. 				':</td><td><input name="enhanceChatTextEntry" type="checkbox" value="on"' + (GM_getValue("enhanceChatTextEntry")?" checked":"") + '></td></td></tr>' +
  8687. 			//Equipment screen prefs
  8688. 			'<tr><th colspan="2" align="left">Equipment screen preferences</th></tr>' +
  8689. 			'<tr><td align="right">Disable Item Coloring' + Helper.helpLink('Disable Item Coloring', 'Disable the code that colors the item text based on the rarity of the item.') +
  8690. 				':</td><td><input name="disableItemColoring" type="checkbox" value="on"' + (GM_getValue("disableItemColoring")?" checked":"") + '></td></tr>' +
  8691. 			'<tr><td align="right">Show Quick Send Item' + Helper.helpLink('Show Quick Send on Manage Backpack', 'This will show a link beside each item which gives the option to quick send the item to this person') +
  8692. 				':</td><td><input name="showQuickSendLinks" type="checkbox" value="on"' + (GM_getValue("showQuickSendLinks")?" checked":"") + '>'+
  8693. 				'Send Items To <input name="itemRecipient" size="10" value="'+ GM_getValue("itemRecipient") + '" />' +
  8694. 			//Quest prefs
  8695. 			'<tr><th colspan="2" align="left">Quest preferences</th></tr>' +
  8696. 			'<tr><td align="right">Hide Specific Quests' + Helper.helpLink('Hide Specific Quests', 'If enabled, this hides quests whose name matches the list (separated by commas). ' +
  8697. 				'This works on Quest Manager and Quest Book.') +
  8698. 				':</td><td colspan="3"><input name="hideQuests" type="checkbox" value="on"' + (GM_getValue("hideQuests")?" checked":"") + '>' +
  8699. 				'<input name="hideQuestNames" size="60" value="'+ GM_getValue("hideQuestNames") + '" /></td></tr>' +
  8700. 			'<tr><td align="right">Show Incomplete/Not <br>Started Quests' + Helper.helpLink('Show Incomplete/Not Started Quests', 'If checked, the helper will check to see if you have quests that are not started, or are started, not complete and not being tracked.' +
  8701. 				'<br>The helper will only check this when you change worlds, or if when it last checked, there were quests it detected for the current world.') +
  8702. 				':</td><td colspan="3"><input name="checkForQuestsInWorld" type="checkbox" value="on"' + (GM_getValue("checkForQuestsInWorld")?" checked":"") + '>' +
  8703. 				'</td></tr>' +
  8704. 			'<tr><td align="right">Store Last Quest Page' + Helper.helpLink('Store Last Quest Page', 'This will store the page and sort order of each of the three quest selection pages for next time you visit. If you need to reset the links, turn this option off, '+
  8705. 				'click on the link you wish to reset and then turn this option back on again.') +
  8706. 				':</td><td><input name="storeLastQuestPage" type="checkbox" value="on"' + (GM_getValue("storeLastQuestPage")?" checked":"") + '></td></tr>' +
  8707. 			//profile prefs
  8708. 			'<tr><th colspan="2" align="left">Profile preferences</th></tr>' +
  8709. 			'<tr><td align="right">Show BP Slots In Profile' + Helper.helpLink('Show BP Slots In Profile', 'This determines if the backpack counter will be displayed on your profile page') +
  8710. 				':</td><td><input name="showBPSlotsOnProfile" type="checkbox" value="on"' + (GM_getValue("showBPSlotsOnProfile")?" checked":"") + '></td></tr>' +
  8711. 			'<tr><td align="right">Render self bio' + Helper.helpLink('Render self bio', 'This determines if your own bio will render the FSH special bio tags.') +
  8712. 				':</td><td><input name="renderSelfBio" type="checkbox" value="on"' + (GM_getValue("renderSelfBio")?" checked":"") + '></td></tr>' +
  8713. 			'<tr><td align="right">Render other players\' bios' + Helper.helpLink('Render other players bios', 'This determines if other players bios will render the FSH special bio tags.') +
  8714. 				':</td><td><input name="renderOtherBios" type="checkbox" value="on"' + (GM_getValue("renderOtherBios")?" checked":"") + '></td></tr>' +
  8715. 			'<tr><td align="right">Enable Bio Compressor' + Helper.helpLink('Enable Bio Compressor', 'This will compress long bios according to settings and provide a link to expand the compressed section.') +
  8716. 				':</td><td><input name="enableBioCompressor" type="checkbox" value="on"' + (GM_getValue("enableBioCompressor")?" checked":"") +
  8717. 				'> Max Compressed Characters:<input name="maxCompressedCharacters" size="1" value="'+ GM_getValue("maxCompressedCharacters") + '" />'+
  8718. 				' Max Compressed Lines:<input name="maxCompressedLines" size="1" value="'+ GM_getValue("maxCompressedLines") + '" /></td></tr>' +
  8719. 			'<tr><td align="right">Buy Buffs Greeting' + Helper.helpLink('Buy Buffs Greeting', 'This is the default text to open a message with when asking to buy buffs. You can use {playername} to insert the target players name. You can also use' +
  8720. 				' {buffs} to insert the list of buffs. You can use {cost} to insert the total cost of the buffs.') +
  8721. 				':</td><td colspan="3"><input name="buyBuffsGreeting" size="60" value="'+ GM_getValue("buyBuffsGreeting") + '" /></td></tr>' +
  8722. 			'<tr><td align="right">Show Stat Bonus Total' + Helper.helpLink('Show Stat Bonus Total', 'This will show a total of the item stats when you mouseover an item on the profile screen.') +
  8723. 				':</td><td><input name="showStatBonusTotal" type="checkbox" value="on"' + (GM_getValue("showStatBonusTotal")?" checked":"") + '></td></tr>' +
  8724. 			//Arena prefs
  8725. 			'<tr><th colspan="2" align="left">Arena preferences</th></tr>' +
  8726. 			'<tr><td align="right">Auto Sort Arena List' + Helper.helpLink('Auto Sort Arena List', 'This will automatically sort the arena list based on your last preference for sort.') +
  8727. 				':</td><td><input name="autoSortArenaList" type="checkbox" value="on"' + (GM_getValue("autoSortArenaList")?" checked":"") + '></td></tr>' +
  8728. 			'<tr><td align="right">Hide Arena Prizes' + Helper.helpLink('Hide Arena Prizes', 'List of the itemIds of arena prizes that should not display on the arena screen ' +
  8729. 				'separated by commas. To find the itemId you will have to view the source of the page or mouseover the item on the arena page.') +
  8730. 				':</td><td colspan="3"><input name="hideArenaPrizes" size="60" value="'+ hideArenaPrizes + '" /></td></tr>' +
  8731. 			//Bounty hunting prefs
  8732. 			'<tr><th colspan="2" align="left">Bounty hunting preferences</th></tr>' +
  8733. 			'<tr><td align= "right">' + Layout.networkIcon() + 'Show Active Bounties' + Helper.helpLink('Show Active Bounties', 'This will show your active bounties ' +
  8734. 				'on the right hand side') + ':</td><td colspan="3"><input name="enableActiveBountyList" type = "checkbox" value = "on"' + (enableActiveBountyList? " checked":"") + '/>' +
  8735. 				'<input name="bountyListRefreshTime" size="1" value="'+ bountyListRefreshTime + '" /> seconds refresh</td></tr>' +
  8736. 			'<tr><td align= "right">' + Layout.networkIcon() + 'Show Wanted Bounties' + Helper.helpLink('Show Wanted Bounties', 'This will show when someone you want is on the bounty board, the list is ' +
  8737. 				'displayed on the right hand side') + ':</td><td colspan="3"><input name="enableWantedList" type = "checkbox" value = "on"' + (enableWantedList? " checked":"") + '/> Refresh time is same as Active Bounties' +
  8738. 			'<tr><td align= "right">Wanted Names' + Helper.helpLink('Wanted Names', 'The names of the people you want to see on the bounty board separated by commas') + ':</td><td colspan="3">' +
  8739. 				'<input name ="wantedNames" size ="60" value="' + wantedNames + '"/></td></tr>' +
  8740. 			'<tr><td align= "right">' + Layout.networkIcon() + 'Show Attack Helper' + Helper.helpLink('Show Attack Helper', 'This will show extra information on the attack player screen ' +
  8741. 				'about stats and buffs on you and your target') + ':</td><td colspan="3"><input name="enableAttackHelper" type = "checkbox" value = "on"' + (GM_getValue("enableAttackHelper")? " checked":"") + '/>' +
  8742. 			//Auction house prefs
  8743. 			'<tr><th colspan="2" align="left">Auction house preferences</th></tr>' +
  8744. 			'<tr><td align="right">Enable Bulk Sell' + Helper.helpLink('Enable Bulk Sell', 'This enables the functionality for the user to bulk sell items.') +
  8745. 				':</td><td><input name="enableBulkSell" type="checkbox" value="on"' + (GM_getValue("enableBulkSell")?" checked":"") + '></td></tr>' +
  8746. 			'<tr><td align="right">Enable AH Item Widgets' + Helper.helpLink('Enable AH Item Widgets', 'This enables the functionality for looking up the craft and forge of an item.') +
  8747. 				':</td><td><input name="enableAHItemWidgets" type="checkbox" value="on"' + (GM_getValue("enableAHItemWidgets")?" checked":"") + '></td></tr>' +
  8748. 			//Other prefs
  8749. 			'<tr><th colspan="2" align="left">Other preferences</th></tr>' +
  8750. 			'<tr><td align="right">Hide Specific Recipes' + Helper.helpLink('Hide Specific Recipes', 'If enabled, this hides recipes whose name matches the list (separated by commas). ' +
  8751. 				'This works on Recipe Manager') +
  8752. 				':</td><td colspan="3"><input name="hideRecipes" type="checkbox" value="on"' + (GM_getValue("hideRecipes")?" checked":"") + '>' +
  8753. 				'<input name="hideRecipeNames" size="60" value="'+ GM_getValue("hideRecipeNames") + '" /></td></tr>' +
  8754. 			'<tr><td align="right">Hide Relic Offline' + Helper.helpLink('Hide Relic Offline', 'This hides the relic offline defenders checker.') +
  8755. 				':</td><td><input name="hideRelicOffline" type="checkbox" value="on"' + (GM_getValue("hideRelicOffline")?" checked":"") + '></td></tr>' +
  8756. 			'<tr><td align="right">Enter Sends Message' + Helper.helpLink('Enter Sends Message', 'If enabled, will send a message from the Send Message screen if you press enter. You can still insert a new line by holding down shift' +
  8757. 			' when you press enter.') +
  8758. 				':</td><td><input name="enterForSendMessage" type="checkbox" value="on"' + (GM_getValue("enterForSendMessage")?" checked":"") + '></td></tr>' +
  8759. 			'<tr><td align="right">Navigate After Message Sent' + Helper.helpLink('Navigate After Message Sent', 'If enabled, will navigate to the referring page after a successful message is sent. Example: ' +
  8760. 				' if you are on the world screen and hit message on the guild info panel after you send the message, it will return you to the world screen.') +
  8761. 				':</td><td><input name="navigateToLogAfterMsg" type="checkbox" value="on"' + (GM_getValue("navigateToLogAfterMsg")?" checked":"") + '></td></tr>' +
  8762. 			'<tr><td align="right">Disable GS page shift' + Helper.helpLink('Disable GS page shift', 'This will disable the page shift on the manage page to shift to the guild store.') +
  8763. 				':</td><td><input name="disablePageShiftToGuildStore" type="checkbox" value="on"' + (GM_getValue("disablePageShiftToGuildStore")?" checked":"") + '></td></tr>' +
  8764. 			'<tr><td align= "right">Max Group Size to Join' + Helper.helpLink('Max Group Size to Join', 'This will disable HCSs Join All functionality and will only join groups less than a set size. ') +
  8765. 				':</td><td colspan="3"><input name="enableMaxGroupSizeToJoin" type = "checkbox" value = "on"' + (GM_getValue("enableMaxGroupSizeToJoin")? " checked":"") + '/>' +
  8766. 				'Max Size: <input name="maxGroupSizeToJoin" size="1" value="' + GM_getValue("maxGroupSizeToJoin") + '" /></td></tr>' +
  8767. 			'<tr><td align= "right">' + Layout.networkIcon() + 'Enable Titan Log' + Helper.helpLink('Enable Titan Log', 'This will keep a record of guild titan kills while you play. ' +
  8768. 				'You can set the number of minutes to delay before checking again. Setting this to 0 will check every page load, setting it to any other number ' + 
  8769. 				'will mean that it will not refresh until the next page load after that many minutes have elapsed.') + 
  8770. 				':</td><td colspan="3"><input name="enableTitanLog" type = "checkbox" value = "on"' + (GM_getValue("enableTitanLog")? " checked":"") + '/>' +
  8771. 				'<input name="titanLogRefreshTime" size="1" value="'+ GM_getValue("titanLogRefreshTime") + '" /> minutes refresh</td></tr>' +
  8772. 			'<tr><td align="right">Show Gold On Find Player' + Helper.helpLink('Show Gold On Find Player', 'Shows gold on hand on the find player screen.') +
  8773. 				':</td><td><input name="showGoldOnFindPlayer" type="checkbox" value="on"' + (GM_getValue("showGoldOnFindPlayer")?" checked":"") + '></td></tr>' +
  8774. 			//save button
  8775. 			'<tr><td colspan="2" align=center><input type="button" class="custombutton" value="Save" id="Helper:SaveOptions"></td></tr>' +
  8776. 			'<tr><td colspan="2" align=center>' +
  8777. 			'<span style="font-size:xx-small">Fallen Sword Helper was coded by <a href="' + System.server + 'index.php?cmd=profile&player_id=1393340">Coccinella</a>, ' +
  8778. 			'<a href="' + System.server + 'index.php?cmd=profile&player_id=1346893">Tangtop</a>, '+
  8779. 			'<a href="' + System.server + 'index.php?cmd=profile&player_id=2536682">dkwizard</a>, ' +
  8780. 			'<a href="' + System.server + 'index.php?cmd=profile&player_id=1570854">jesiegel</a>,  ' +
  8781. 			'<a href="' + System.server + 'index.php?cmd=profile&player_id=2169401">McBush</a>, and ' +
  8782. 			'<a href="' + System.server + 'index.php?cmd=profile&player_id=2156859">ByteBoy</a> ' +
  8783. 			'with valuable contributions by <a href="' + System.server + 'index.php?cmd=profile&player_id=524660">Nabalac</a>, ' +
  8784. 			'<a href="' + System.server + 'index.php?cmd=profile&player_id=37905">Ananasii</a></td></tr>' +
  8785. 			'</table></form>';
  8786. 		var insertHere = System.findNode("//table[@width='100%' and @cellspacing='0' and @cellpadding='5' and @border='0']");
  8787. 		var newRow=insertHere.insertRow(insertHere.rows.length);
  8788. 		var newCell=newRow.insertCell(0);
  8789. 		newCell.colSpan=3;
  8790. 		newCell.innerHTML=configData;
  8791. 		// insertHere.insertBefore(configData, insertHere);
  8792. 		document.getElementById('Helper:SaveOptions').addEventListener('click', Helper.saveConfig, true);
  8793. 		document.getElementById('Helper:CheckUpdate').addEventListener('click', Helper.checkForUpdate, true);
  8794. 		document.getElementById('Helper:ShowLogs').addEventListener('click', Helper.showLogs, true);
  8795. 		document.getElementById('Helper:ShowMonsterLogs').addEventListener('click', Helper.showMonsterLogs, true);
  8796. 		if (GM_getValue("map")) {document.getElementById('Helper:ResetFootprints').addEventListener('click', Helper.resetFootprints, true);}
  8797. 		document.getElementById('Helper:updateFpColor').addEventListener('click', Helper.updateFpColor, true);
  8798.  
  8799.  
  8800.  
  8801. 		document.getElementById('toggleShowGuildSelfMessage').addEventListener('click', System.toggleVisibilty, true);
  8802. 		document.getElementById('toggleShowGuildFrndMessage').addEventListener('click', System.toggleVisibilty, true);
  8803. 		document.getElementById('toggleShowGuildPastMessage').addEventListener('click', System.toggleVisibilty, true);
  8804. 		document.getElementById('toggleShowGuildEnmyMessage').addEventListener('click', System.toggleVisibilty, true);
  8805.  
  8806. 		var krulButton = System.findNode('//input[@value="Instant Portal back to Krul Island"]');
  8807. 		onClick = krulButton.getAttribute("onclick");
  8808. 		//window.location='index.php?cmd=settings&subcmd=fix&xcv=3264968baaf287c67b0fab314280b163';
  8809. 		krulXCVRE = /xcv=([a-z0-9]+)'/;
  8810. 		krulXCV = krulXCVRE.exec(onClick);
  8811. 		if (krulXCV) GM_setValue("krulXCV",krulXCV[1]);
  8812.  
  8813. 		var minGroupLevelTextField = System.findNode('//input[@name="min_group_level"]');
  8814. 		if (minGroupLevelTextField) {
  8815. 			var minGroupLevel = minGroupLevelTextField.value;
  8816. 			GM_setValue("minGroupLevel",minGroupLevel);
  8817. 		}
  8818. 	},
  8819.  
  8820. 	resetFootprints: function(evt) {
  8821. 		if (window.confirm("Are you sure you want to reset your footprints?")) {
  8822. 			var theMap = System.getValueJSON("map");
  8823. 			if (theMap) {
  8824. 				theMap = {};
  8825. 				theMap["levels"] = {};
  8826. 				System.setValueJSON("map", theMap);
  8827. 			}
  8828. 			window.location.reload();
  8829. 		}
  8830.  
  8831. 	},
  8832.  
  8833. 	updateFpColor: function(evt) {
  8834. 		GM_setValue("footprintsColor", System.findNode("//input[@name='footprintsColor']").value);
  8835. 		window.location.reload();
  8836. 	},
  8837.  
  8838. 	helpLink: function(title, text) {
  8839. 		return ' [ ' +
  8840. 			'<span style="text-decoration:underline;cursor:pointer;" onmouseover="Tip(\'' +
  8841. 			'<span style=\\\'font-weight:bold; color:#FFF380;\\\'>' + title + '</span><br /><br />' +
  8842. 			text + '\');">?</span>' +
  8843. 			' ]';
  8844. 	},
  8845.  
  8846. 	saveConfig: function(evt) {
  8847. 		var oForm=evt.target.form;
  8848.  
  8849. 		//bio compressor validation logic
  8850. 		var maxCompressedCharacters = System.findNode("//input[@name='maxCompressedCharacters']", oForm);
  8851. 		var maxCompressedCharactersValue = maxCompressedCharacters.value*1;
  8852. 		if (isNaN(maxCompressedCharactersValue) || maxCompressedCharactersValue<=50) {
  8853. 			maxCompressedCharacters.value=1500;
  8854. 		}
  8855. 		var maxCompressedLines = System.findNode("//input[@name='maxCompressedLines']", oForm);
  8856. 		var maxCompressedLinesValue = maxCompressedLines.value*1;
  8857. 		if (isNaN(maxCompressedLinesValue) || maxCompressedLinesValue<=1) {
  8858. 			maxCompressedLines.value=25;
  8859. 		}
  8860. 		var newGuildLogHistoryPages = System.findNode("//input[@name='newGuildLogHistoryPages']", oForm);
  8861. 		var newGuildLogHistoryPagesValue = newGuildLogHistoryPages.value*1;
  8862. 		if (isNaN(newGuildLogHistoryPagesValue) || newGuildLogHistoryPagesValue<=1) {
  8863. 			newGuildLogHistoryPages.value=25;
  8864. 		}
  8865. 		var maxGroupSizeToJoin = System.findNode("//input[@name='maxGroupSizeToJoin']", oForm);
  8866. 		var maxGroupSizeToJoinValue = maxGroupSizeToJoin.value*1;
  8867. 		if (isNaN(maxGroupSizeToJoinValue) || maxGroupSizeToJoinValue<=1) {
  8868. 			maxGroupSizeToJoin.value=11;
  8869. 		}
  8870. 		var combatEvaluatorBiasElement = System.findNode("//select[@name='combatEvaluatorBias']", oForm);
  8871. 		var combatEvaluatorBias = combatEvaluatorBiasElement.value;
  8872. 		GM_setValue("combatEvaluatorBias", combatEvaluatorBias);
  8873. 		System.saveValueForm(oForm, "navigateToLogAfterMsg");
  8874. 		System.saveValueForm(oForm, "gameHelpLink");
  8875. 		System.saveValueForm(oForm, "guildSelf");
  8876. 		System.saveValueForm(oForm, "guildFrnd");
  8877. 		System.saveValueForm(oForm, "guildPast");
  8878. 		System.saveValueForm(oForm, "guildEnmy");
  8879. 		System.saveValueForm(oForm, "guildSelfMessage");
  8880. 		System.saveValueForm(oForm, "guildFrndMessage");
  8881. 		System.saveValueForm(oForm, "guildPastMessage");
  8882. 		System.saveValueForm(oForm, "guildEnmyMessage");
  8883.  
  8884. 		System.saveValueForm(oForm, "showAdmin");
  8885. 		System.saveValueForm(oForm, "ajaxifyRankControls");
  8886.  
  8887. 		System.saveValueForm(oForm, "detailedConflictInfo");
  8888. 		System.saveValueForm(oForm, "disableItemColoring");
  8889. 		System.saveValueForm(oForm, "enableLogColoring");
  8890. 		System.saveValueForm(oForm, "enableChatParsing");
  8891. 		System.saveValueForm(oForm, "enableCreatureColoring");
  8892. 		System.saveValueForm(oForm, "hideNonPlayerGuildLogMessages");
  8893. 		System.saveValueForm(oForm, "hideBanner");
  8894. 		System.saveValueForm(oForm, "showSTUpTop");
  8895. 		System.saveValueForm(oForm, "buyBuffsGreeting");
  8896. 		System.saveValueForm(oForm, "renderSelfBio");
  8897. 		System.saveValueForm(oForm, "renderOtherBios");
  8898. 		System.saveValueForm(oForm, "defaultMessageSound");
  8899. 		System.saveValueForm(oForm, "showSpeakerOnWorld");
  8900. 		System.saveValueForm(oForm, "playNewMessageSound");
  8901. 		System.saveValueForm(oForm, "highlightPlayersNearMyLvl");
  8902. 		System.saveValueForm(oForm, "highlightGvGPlayersNearMyLvl");
  8903. 		System.saveValueForm(oForm, "showCombatLog");
  8904. 		System.saveValueForm(oForm, "showMonsterLog");
  8905. 		System.saveValueForm(oForm, "showCreatureInfo");
  8906. 		System.saveValueForm(oForm, "keepLogs");
  8907. 		System.saveValueForm(oForm, "enableGuildInfoWidgets");
  8908. 		System.saveValueForm(oForm, "hideGuildInfoMessage");
  8909. 		System.saveValueForm(oForm, "hideGuildInfoBuff");
  8910. 		System.saveValueForm(oForm, "hideGuildInfoSecureTrade");
  8911. 		System.saveValueForm(oForm, "hideGuildInfoTrade");
  8912. 		System.saveValueForm(oForm, "quickKill");
  8913. 		System.saveValueForm(oForm, "huntingBuffs");
  8914. 		System.saveValueForm(oForm, "showHuntingBuffs");
  8915. 		System.saveValueForm(oForm, "moveGuildList");
  8916. 		System.saveValueForm(oForm, "moveFSBox");
  8917. 		System.saveValueForm(oForm, "hideKrulPortal");
  8918. 		System.saveValueForm(oForm, "hideQuests");
  8919. 		System.saveValueForm(oForm, "hideQuestNames");
  8920. 		System.saveValueForm(oForm, "checkForQuestsInWorld");
  8921. 		System.saveValueForm(oForm, "hideRecipes");
  8922. 		System.saveValueForm(oForm, "hideRecipeNames");
  8923. 		System.saveValueForm(oForm, "footprintsColor");
  8924. 		System.saveValueForm(oForm, "doNotKillList");
  8925. 		System.saveValueForm(oForm, "enableBioCompressor");
  8926. 		System.saveValueForm(oForm, "maxCompressedCharacters");
  8927. 		System.saveValueForm(oForm, "maxCompressedLines");
  8928. 		System.saveValueForm(oForm, "sendGoldonWorld");
  8929. 		System.saveValueForm(oForm, "goldRecipient");
  8930. 		System.saveValueForm(oForm, "goldAmount");
  8931. 		System.saveValueForm(oForm, "keepBuffLog");
  8932. 		System.saveValueForm(oForm, "showQuickSendLinks");
  8933. 		System.saveValueForm(oForm, "itemRecipient");
  8934. 		System.saveValueForm(oForm, "currentGoldSentTotal");
  8935. 		System.saveValueForm(oForm, "hideArenaPrizes");
  8936. 		System.saveValueForm(oForm, "autoSortArenaList");
  8937.  
  8938. 		System.saveValueForm(oForm, "enableAllyOnlineList");
  8939. 		System.saveValueForm(oForm, "enableEnemyOnlineList");
  8940. 		System.saveValueForm(oForm, "allyEnemyOnlineRefreshTime");
  8941.  
  8942. 		System.saveValueForm(oForm, "enableActiveBountyList");
  8943. 		System.saveValueForm(oForm, "bountyListRefreshTime");
  8944. 		System.saveValueForm(oForm, "enableWantedList");
  8945. 		System.saveValueForm(oForm, "wantedNames");
  8946. 		System.saveValueForm(oForm, "enableBulkSell");
  8947. 		System.saveValueForm(oForm, "fsboxlog");
  8948. 		System.saveValueForm(oForm, "huntingMode");
  8949. 		System.saveValueForm(oForm, "enableAttackHelper");
  8950. 		System.saveValueForm(oForm, "hideRelicOffline");
  8951. 		System.saveValueForm(oForm, "enterForSendMessage");
  8952. 		System.saveValueForm(oForm, "showBPSlotsOnProfile");
  8953. 		System.saveValueForm(oForm, "showFSGIcon");
  8954. 		System.saveValueForm(oForm, "storeLastQuestPage");
  8955. 		System.saveValueForm(oForm, "enableAHItemWidgets");
  8956. 		System.saveValueForm(oForm, "addAttackLinkToLog");
  8957. 		System.saveValueForm(oForm, "showStatBonusTotal");
  8958. 		System.saveValueForm(oForm, "newGuildLogHistoryPages");
  8959. 		System.saveValueForm(oForm, "useNewGuildLog");
  8960. 		System.saveValueForm(oForm, "enhanceChatTextEntry");
  8961. 		System.saveValueForm(oForm, "disablePageShiftToGuildStore");
  8962.  
  8963. 		System.saveValueForm(oForm, "enableMaxGroupSizeToJoin");
  8964. 		System.saveValueForm(oForm, "maxGroupSizeToJoin");
  8965.  
  8966. 		System.saveValueForm(oForm, "enableTitanLog");
  8967. 		System.saveValueForm(oForm, "titanLogRefreshTime");
  8968. 		System.saveValueForm(oForm, "enableTempleAlert");
  8969. 		System.saveValueForm(oForm, "showGoldOnFindPlayer");
  8970.  
  8971. 		window.alert("FS Helper Settings Saved");
  8972. 		window.location.reload();
  8973. 		return false;
  8974. 	},
  8975.  
  8976. 	showLogs: function(evt) {
  8977. 		document.location=System.server + "index.php?cmd=notepad&subcmd=showlogs";
  8978. 	},
  8979.  
  8980. 	showMonsterLogs: function(evt) {
  8981. 		document.location=System.server + "index.php?cmd=notepad&subcmd=monsterlog";
  8982. 	},
  8983.  
  8984. 	injectNotepadShowLogs: function() {
  8985. 		var content = Layout.notebookContent();
  8986. 		var combatLog = GM_getValue("CombatLog");
  8987. 		content.innerHTML = '<div align="center"><textarea align="center" cols="80" rows="25" ' +
  8988. 			'readonly style="background-color:white;font-family:Consolas,\"Lucida Console\",\"Courier New\",monospace;" id="Helper:CombatLog">' + combatLog + '</textarea></div>' +
  8989. 			'<br /><br /><table width="100%"><tr>'+
  8990. 			'<td colspan="2" align=center>' +
  8991. 			'<input type="button" class="custombutton" value="Select All" id="Helper:CopyLog"></td>' +
  8992. 			'<td colspan="2" align=center>' +
  8993. 			'<input type="button" class="custombutton" value="Clear" id="Helper:ClearLog"></td>' +
  8994. 			'</tr></table>';
  8995. 		document.getElementById("Helper:CopyLog").addEventListener("click", Helper.notepadCopyLog, true);
  8996. 		document.getElementById("Helper:ClearLog").addEventListener("click", Helper.notepadClearLog, true);
  8997. 	},
  8998.  
  8999. 	notepadCopyLog: function() {
  9000. 		var combatLog=document.getElementById("Helper:CombatLog");
  9001. 		combatLog.focus();
  9002. 		combatLog.select();
  9003. 	},
  9004.  
  9005. 	notepadClearLog: function() {
  9006. 		if (window.confirm("Are you sure you want to clear your log?")) {
  9007. 			var combatLog=document.getElementById("Helper:CombatLog");
  9008. 			GM_setValue("CombatLog", "");
  9009. 			window.location = window.location;
  9010. 		}
  9011. 	},
  9012.  
  9013. 	guildRelationship: function(txt) {
  9014. 		var guildSelf = GM_getValue("guildSelf");
  9015. 		var guildFrnd = GM_getValue("guildFrnd");
  9016. 		var guildPast = GM_getValue("guildPast");
  9017. 		var guildEnmy = GM_getValue("guildEnmy");
  9018. 		if (!guildSelf) {
  9019. 			guildSelf = "";
  9020. 			GM_setValue("guildSelf", guildSelf);
  9021. 		}
  9022. 		if (!guildFrnd) {
  9023. 			guildFrnd = "";
  9024. 			GM_setValue("guildFrnd", guildFrnd);
  9025. 		}
  9026. 		if (!guildPast) {
  9027. 			guildPast = "";
  9028. 			GM_setValue("guildPast", guildPast);
  9029. 		}
  9030. 		if (!guildEnmy) {
  9031. 			guildEnmy = "";
  9032. 			GM_setValue("guildEnmy", guildEnmy);
  9033. 		}
  9034. 		guildSelf = guildSelf.toLowerCase().replace(/\s*,\s*/, ",").replace(/\s\s*/g, " ").split(",");
  9035. 		guildFrnd = guildFrnd.toLowerCase().replace(/\s*,\s*/, ",").replace(/\s\s*/g, " ").split(",");
  9036. 		guildPast = guildPast.toLowerCase().replace(/\s*,\s*/, ",").replace(/\s\s*/g, " ").split(",");
  9037. 		guildEnmy = guildEnmy.toLowerCase().replace(/\s*,\s*/, ",").replace(/\s\s*/g, " ").split(",");
  9038. 		txt = txt.toLowerCase().replace(/\s\s*/g, " ");
  9039. 		if (guildSelf.indexOf(txt) != -1) return "self";
  9040. 		if (guildFrnd.indexOf(txt) != -1) return "friendly";
  9041. 		if (guildPast.indexOf(txt) != -1) return "old";
  9042. 		if (guildEnmy.indexOf(txt) != -1) return "enemy";
  9043. 		return "";
  9044. 	},
  9045.  
  9046. 	displayMiniMap: function() {
  9047. 		var miniMap = document.getElementById("miniMap");
  9048. 		if (!miniMap) {
  9049. 			miniMap = document.createElement("div");
  9050. 			miniMap.style.position = "absolute";
  9051. 			miniMap.style.left = 0;
  9052. 			miniMap.style.top = 0;
  9053. 			miniMap.style.display = 'none';
  9054. 			miniMap.id = "miniMap";
  9055. 			miniMap.style.zIndex = '90';
  9056. 			miniMap.style.filter = "alpha";
  9057. 			miniMap.style.opacity = "0.9";
  9058.  
  9059. 			var objBody = document.getElementsByTagName("body").item(0);
  9060. 			objBody.insertBefore(miniMap, objBody.firstChild);
  9061. 		}
  9062. 		var miniMapName = GM_getValue("miniMapName");
  9063. 		var miniMapSource = GM_getValue("miniMapSource");
  9064. 		if (miniMap.style.display !== "") {
  9065. 			if (miniMapName && Helper.levelName == miniMapName) {
  9066. 				miniMap.innerHTML = miniMapSource;
  9067. 				Helper.addMiniMapExtras(miniMap);
  9068. 			}
  9069. 			else {
  9070. 				System.xmlhttp("index.php?cmd=world&subcmd=map", Helper.loadMiniMap, true);
  9071. 			}
  9072. 		}
  9073. 		else miniMap.style.display = "none";
  9074. 	},
  9075.  
  9076. 	loadMiniMap: function(responseText) {
  9077. 		var size = 20;
  9078. 		var miniMap = document.getElementById("miniMap");
  9079. 		var docu = System.createDocument(responseText);
  9080. 		var doc = '<table cellspacing="0" cellpadding="0" align="center" id=miniMapTable>' + System.findNode("//table", docu).innerHTML + '</table>';
  9081. 		doc = doc.replace(/ background=/g, '><img width=' + size + ' height=' + size + ' src=');
  9082. 		// doc = doc.replace(/<[^>]*>(<center><[^>]*title="You are here")>/g, '$1 width=11 height=11>');
  9083. 		//doc = doc.replace("<center></center>", "");
  9084. 		doc = doc.replace(/<[^>]*title="You are here"[^>]*>/g, '');
  9085. 		doc = doc.replace(/<table [^>]*><tbody><tr><td[^>]*><\/td><\/tr><\/tbody><\/table>/g,'');
  9086. 		doc = doc.replace(/width="40"/g, 'width="' + size + '"').replace(/height="40"/g, 'height="' + size + '"');
  9087. 		miniMap.innerHTML = doc;
  9088. 		Helper.addMiniMapExtras(miniMap);
  9089.  
  9090. 		if (Helper.levelName) {GM_setValue("miniMapName", Helper.levelName);}
  9091. 		GM_setValue("miniMapSource", doc);
  9092. 	},
  9093.  
  9094. 	addMiniMapExtras: function(miniMap) {
  9095. 		Helper.markPlayerOnMiniMap();
  9096. 		Helper.toogleMiniMapPOI();
  9097. 		var last=document.getElementById("miniMapTable").insertRow(-1).insertCell(0);
  9098. 		last.colSpan=document.getElementById("miniMapTable").rows[0].cells.length;
  9099. 		last.innerHTML = "<span style='color:green;font-size:x-small;font-weight:bolder'>"+
  9100. 			"<br/><h1 onmouseover=\"Tip('Click on the player icon and left click drag the path you want to walk. If you walk into a wall or make an error, " +
  9101. 				"close and reopen the mini map and start again. Push N (capital n) to activate the auto-walk and watch the mini map as you walk to your " +
  9102. 				"new location. The screen will refresh when you get there.');\">Auto-Walk</h1></span>";
  9103. 		Helper.miniMapTableEvents();
  9104. 		miniMap.style.display = "";
  9105. 	},
  9106.  
  9107. 	miniMapTableEvents: function(){
  9108. 		Helper.mouse = 0;
  9109. 		Helper.moveList=[Helper.position()];
  9110. 		document.getElementById('miniMap').addEventListener("mouseup", function(e){Helper.mouse = 0},false);
  9111. 		// collect table cells from the drawing_table div element  
  9112. 		var td = document.getElementById('miniMap').getElementsByTagName('td');  
  9113. 		// attach onMouseDown and onMouseOver event for collected table cells  
  9114. 		for (var i=0; i<td.length; i++){
  9115. 			td[i].addEventListener("mousedown", Helper.mousedown, true);
  9116. 			// colorize table cell if left mouse button is pressed  
  9117. 			td[i].addEventListener("mouseover", function (e){if (Helper.mouse == 1) Helper.markPos(this);}, true);
  9118. 		}  
  9119. 	},
  9120.  
  9121. 	mousedown: function (evt){  
  9122. 		// needed for FF to disable dragging 
  9123. 		evt.preventDefault();
  9124. 		// set pressed mouse button 
  9125. 		Helper.mouse = evt.which;
  9126. 		// colorize pixel on mousedown event for TD element
  9127. 		if (this.tagName == 'TD' && Helper.mouse == 1) Helper.markPos(this);
  9128. 	},
  9129.  
  9130. 	markPos: function(td) {
  9131. 		var pos={'X':td.cellIndex,'Y':td.parentNode.rowIndex};
  9132. 		if (!Helper.moveList[0]) return;
  9133. 		var lastPos=Helper.moveList[Helper.moveList.length - 1];
  9134. 		var dx=pos.X-lastPos.X, dy=pos.Y-lastPos.Y;
  9135. 		if (dx>=-1 && dx <=1 && dy>=-1 && dy<=1 && (dx!=0 || dy!=0)) {
  9136. 			Helper.moveList.push(pos);
  9137. 			td.innerHTML='';
  9138. 			td.style.backgroundColor = "red";
  9139. 		}
  9140. 	},
  9141.  
  9142. 	autoMoveMiniMap: function() {
  9143. 		if (Helper.moveList && Helper.moveList.length > 1)
  9144. 			System.xmlhttp("index.php?cmd=world&subcmd=move&x="+Helper.moveList[1].X+"&y="+Helper.moveList[1].Y,
  9145. 				Helper.autoMoveNext, 1);
  9146. 	},
  9147.  
  9148. 	autoMoveNext: function(responseText, id) {
  9149. 		var currentPos = "("+Helper.moveList[id].X+", "+Helper.moveList[id].Y+")";
  9150. 		if (responseText.indexOf(currentPos)<0) {
  9151. 			alert("Cannot move via " + currentPos);
  9152. 			window.location = window.location;
  9153. 		} else {
  9154. 			// update current pos
  9155. 			Helper.markPosOnMiniMap(Helper.moveList[id]);
  9156. 			// move next
  9157. 			var nextId = id+1;
  9158. 			if (nextId < Helper.moveList.length)
  9159. 				System.xmlhttp("index.php?cmd=world&subcmd=move&x="+Helper.moveList[nextId].X+"&y="+Helper.moveList[nextId].Y,
  9160. 					Helper.autoMoveNext, nextId);
  9161. 			else
  9162. 				window.location = window.location;
  9163. 		}
  9164. 	},
  9165.  
  9166. 	toogleMiniMapPOI: function() {
  9167. 		var miniMap = document.getElementById("miniMap");
  9168. 		var miniMapTable = document.getElementById("miniMapTable");
  9169. 		var miniMapCover = document.getElementById("miniMapCover");
  9170. 		if (!miniMapCover) {
  9171. 			miniMapCover = document.createElement("div");
  9172. 			miniMapCover.style.position = "absolute";
  9173. 			miniMapCover.style.left = 0;
  9174. 			miniMapCover.style.top = 0;
  9175. 			miniMapCover.id = "miniMapCover";
  9176. 			miniMapCover.style.zIndex = '100';
  9177. 			miniMapCover.style.filter = "alpha";
  9178. 			miniMapCover.style.opacity = "0.4";
  9179. 			miniMapCover.innerHTML = '<table cellspacing="0" cellpadding="0" align="center">'+
  9180. 				miniMapTable.innerHTML+'</table>';
  9181. 			miniMap.insertBefore(miniMapCover, miniMap.firstChild);
  9182. 		} else {
  9183. 			miniMap.removeChild(miniMapCover);
  9184. 			return;
  9185. 		}
  9186.  
  9187. 		var nodes = System.findNodes("//div[@id='miniMapCover']//td[contains(@onmouseover,'Tip')]");
  9188. 		if (!nodes) return;
  9189. 		for (var i=0; i<nodes.length; i++) {
  9190. 			var tip=nodes[i].getAttribute("onmouseover");
  9191. 			var color=tip.indexOf(': ') > 0 ? 'red' :
  9192. 				tip.indexOf("Tip('Stairway to ") > 0 ? 'green' : 'blue';
  9193. 			nodes[i].innerHTML = '';
  9194. 			nodes[i].style.backgroundColor = color;
  9195. 		}
  9196. 	},
  9197.  
  9198. 	markPlayerOnMiniMap: function() {
  9199. 		var posit = Helper.position();
  9200. 		if (!posit) {return;}
  9201. 		Helper.markPosOnMiniMap(posit);
  9202. 	},
  9203.  
  9204. 	markPosOnMiniMap: function(posit) {
  9205. 		var miniMapTable = document.getElementById("miniMapTable");
  9206. 		if (!miniMapTable) return;
  9207. 		var position = miniMapTable.rows[posit.Y].cells[posit.X];
  9208. 		var background = position.firstChild.src;
  9209. 		position.innerHTML = '<center><img width=16 height=16 src="' + System.imageServer + '/skin/player_tile.gif" title="You are here"></center>';
  9210. 		position.style.backgroundImage = 'url("' + background + '")';
  9211. 		position.style.backgroundPosition = "center";
  9212. 	},
  9213.  
  9214. 	injectQuickLinkManager: function() {
  9215. 		GM_addStyle('.HelperTextLink {color:black;font-size:x-small;cursor:pointer;}\n' +
  9216. 			'.HelperTextLink:hover {text-decoration:underline;}\n');
  9217.  
  9218. 		Layout.notebookContent().innerHTML=Helper.makePageTemplate('Quick Links','','','','quickLinkAreaId');
  9219.  
  9220. 		// global parameters for the meta function generateManageTable
  9221. 		Helper.param={};
  9222. 		Helper.param={'id':'quickLinkAreaId',
  9223. 			'headers':["Name","URL",'New [<span style="cursor:pointer; text-decoration:underline;" title="Open page in a new window">?</span>]'],
  9224. 			'fields':["name","url","newWindow"],
  9225. 			'tags':["textbox","textbox","checkbox"],
  9226. 			'currentItems':System.getValueJSON("quickLinks"),
  9227. 			'gmname':"quickLinks"};
  9228. 		Helper.generateManageTable();
  9229. 	},
  9230.  
  9231. 	movePage: function(dir) {
  9232. 		var dirButton = System.findNode("//input[@value='"+dir+"']");
  9233. 		if (!dirButton) {return;}
  9234. 		var url = dirButton.getAttribute("onClick");
  9235. 		url = url.replace(/^[^']*'/m, "").replace(/\';$/m, "");
  9236. 		window.location = url;
  9237. 	},
  9238.  
  9239. 	toggleSellFromAllBags: function(evt) {
  9240. 		var newValue = !GM_getValue("bulkSellAllBags");
  9241. 		GM_setValue("bulkSellAllBags", newValue);
  9242. 		var theSpan = document.getElementById("Helper:bulkCheck");
  9243. 		theSpan.innerHTML = (newValue === true ? "Selling from all bags" : "Selling only from main folder");
  9244. 	},
  9245.  
  9246. 	injectCreateAuctionTemplate: function() {
  9247. 		if (window.location.search.search("inv_id") == -1) {
  9248. 			if (GM_getValue("enableBulkSell")) {
  9249. 				var row = System.findNode("//html/body/table/tbody/tr[3]/td[2]/table/tbody/tr[3]/td[2]/table/tbody/tr[6]/td");
  9250. 				if (row) {
  9251. 					var sellFromAll = GM_getValue("bulkSellAllBags");
  9252. 					var toggleSellAllHTML = "<span id='Helper:bulkCheck' style='cursor: pointer; text-decoration: underline; color: blue;'>" +
  9253. 					(sellFromAll === true ? "Selling from all bags" : "Selling only from main folder") + " </span>";
  9254. 					row.innerHTML = row.innerHTML.replace("]", " | " + toggleSellAllHTML + " ]");
  9255. 					var bulkCheck = document.getElementById("Helper:bulkCheck")
  9256. 					if (bulkCheck) bulkCheck.addEventListener("click", Helper.toggleSellFromAllBags, true);
  9257. 				}
  9258.  
  9259. 			}
  9260. 			var items = System.findNodes("//a[contains(@href,'index.php?cmd=auctionhouse&subcmd=create2')]");
  9261. 			if (items) {
  9262. 				for (var i = 0; i < items.length; i++) {
  9263. 					var item = items[i];
  9264. 					var itemStats = /ajaxLoadItem\((\d+), (\d+), (\d+), (\d+)/.exec(item.getAttribute("onmouseover"));
  9265. 					if (itemStats) {
  9266. 						itemId = itemStats[1];
  9267. 						invId = itemStats[2];
  9268. 						type = itemStats[3];
  9269. 						pid = itemStats[4];
  9270. 						var itemHref = item.getAttribute("href");
  9271. 						var newHref = itemHref + '&item_id=' + itemId + '&type=' + type + '&pid=' + pid;
  9272. 						item.setAttribute("href",newHref);
  9273. 					}
  9274. 				}
  9275. 			}
  9276. 			return;
  9277. 		}
  9278. 		var auctionTable = System.findNode("//table[tbody/tr/td/a[@href='index.php?cmd=auctionhouse&subcmd=create']]");
  9279. 		if (!auctionTable) {return;}
  9280.     var bidEntryTable = System.findNode("//table[tbody/tr/td/a[@href='index.php?cmd=auctionhouse&subcmd=create']]/tbody/tr[10]/td[1]/table");
  9281. 		itemStats = /inv_id=(\d+)&item_id=(\d+)&type=(\d+)&pid=(\d+)/.exec(window.location.search);
  9282. 		if (itemStats) {
  9283. 			var invId = itemStats[1];
  9284. 			var itemId = itemStats[2];
  9285. 			var type = itemStats[3];
  9286. 			var pid = itemStats[4];
  9287. 			//GM_log();
  9288. 			var newCell = bidEntryTable.rows[0].insertCell(2);
  9289. 			newCell.rowSpan = 5;
  9290. 			newCell.innerHTML = '<img src="' + System.imageServerHTTP + '/items/' + itemId +
  9291. 				'.gif" onmouseover="ajaxLoadItem(' + itemId + ', ' + invId + ', ' + type + ', ' + pid + ', \'\');" border=0>';
  9292. 		}
  9293.  
  9294. 		var newRow = auctionTable.insertRow(10);
  9295. 		newCell = newRow.insertCell(0);
  9296. 		newCell.colSpan = 2;
  9297. 		newCell.align = "center";
  9298. 		var table = System.getValueJSON("auctionTemplate");
  9299. 		if (!table) {
  9300. 			table = [
  9301. 				{auctionLength:6,auctionCurrency:1,auctionMinBid:1,		auctionBuyNow:1,	isDefault:true}
  9302. 			];
  9303. 			System.setValueJSON("auctionTemplate", table);
  9304. 		}
  9305.  
  9306. 		var textResult = "<table cellspacing='0' cellpadding='0' bordercolor='#000000'" +
  9307. 				" border='0' align='center' width='550' style='border-style: solid; border-width: 1px;'>" +
  9308. 				"<tr><td bgcolor='#cd9e4b'><center>Auction Templates</center></td></tr>" +
  9309. 				"<tr><td><table cellspacing='10' cellpadding='0' border='0' width='100%'>" +
  9310. 				"<tr><th bgcolor='#cd9e4b'>Length</th><th bgcolor='#cd9e4b'>Currency</th>"+
  9311. 				"<th bgcolor='#cd9e4b'>Min Bid</th><th bgcolor='#cd9e4b'>Buy Now</th>"+
  9312. 				"<th></th></tr>";
  9313.  
  9314. 		for (i = 0; i < table.length; i++) {
  9315. 			textResult += "<tr align='right'><td>"+Helper.getAuctionLength(table[i].auctionLength)+"</td>"+
  9316. 				"<td>"+(table[i].auctionCurrency==0?"Gold":"FSP")+"</td>"+
  9317. 				"<td>"+System.addCommas(table[i].auctionMinBid)+"</td>"+
  9318. 				"<td>"+System.addCommas(table[i].auctionBuyNow)+"</td>"+
  9319. 				"<td>[<span style='cursor:pointer; text-decoration:underline; color:blue;' "+
  9320. 					"id='Helper:useAuctionTemplate" + i + "' auctionTemplateId=" + i +
  9321. 					" auctionLength=" + table[i].auctionLength +
  9322. 					" auctionCurrency=" + table[i].auctionCurrency +
  9323. 					" auctionMinBid=" + table[i].auctionMinBid +
  9324. 					" auctionBuyNow=" + table[i].auctionBuyNow +
  9325. 					">apply</span>]";
  9326. 				textResult += " [<span style='cursor:pointer; text-decoration:underline; color:blue;' "+
  9327. 					"id='Helper:delAuctionTemplate" + i + "' auctionTemplateId=" + i +">del</span>]";
  9328. 			textResult += "</td></tr>";
  9329. 		}
  9330. 		if (table.length<=10) {
  9331. 			textResult += "<tr align='right'>"+
  9332. 				"<td><select id='Helper:auctionLength'><option value='0' selected>1 Hour</option><option value='1' >2 Hours</option>"+
  9333. 					"<option value='2' >4 Hours</option><option value='3' >8 Hours</option><option value='4' >12 Hours</option>"+
  9334. 					"<option value='5' >24 Hours</option><option value='6' >48 Hours</option></select></td>"+
  9335. 				"<td><select id='Helper:auctionCurrency'><option value='0' >Gold</option><option value='1' selected>FSP</option></select></td>"+
  9336. 				"<td><input type='text' class='custominput' size='6' id='Helper:minBid'/></td>"+
  9337. 				"<td><input type='text' class='custominput' size='6' id='Helper:buyNow'/></td>"+
  9338. 				"<td>[<span style='cursor:pointer; text-decoration:underline; color:blue;' "+
  9339. 					"id='Helper:saveAuctionTemplate'>save new template</span>]</td></tr>";
  9340.  
  9341. 		}
  9342. 		textResult += "</table></td></tr></table>";
  9343.  
  9344. 		newCell.innerHTML = textResult;
  9345.  
  9346. 		if (table.length<=10) document.getElementById("Helper:saveAuctionTemplate").addEventListener("click", Helper.saveAuctionTemplate, true);
  9347. 		for (i = 0; i < table.length; i++) {
  9348. 			document.getElementById("Helper:useAuctionTemplate" + i).addEventListener("click", Helper.useAuctionTemplate, true);
  9349. 			document.getElementById("Helper:delAuctionTemplate" + i).addEventListener("click", Helper.delAuctionTemplate, true);
  9350. 		}
  9351. 	},
  9352.  
  9353. 	getAuctionLength: function(auctionLength) {
  9354. 		if (auctionLength == 1) return '2 Hours';
  9355. 		else if (auctionLength == 2) return '4 Hours';
  9356. 		else if (auctionLength == 3) return '8 Hours';
  9357. 		else if (auctionLength == 4) return '12 Hours';
  9358. 		else if (auctionLength == 5) return '24 Hours';
  9359. 		else if (auctionLength == 6) return '48 Hours';
  9360. 		else return '1 Hour';
  9361. 	},
  9362.  
  9363. 	useAuctionTemplate: function(evt) {
  9364. 		var newAuctionLength = evt.target.getAttribute("auctionLength");
  9365. 		var newAuctionCurrency = evt.target.getAttribute("auctionCurrency");
  9366. 		var newAuctionMinBid = evt.target.getAttribute("auctionMinBid");
  9367. 		var newAuctionBuyNow = evt.target.getAttribute("auctionBuyNow");
  9368.  
  9369. 		var auctionLength = System.findNode("//select[@name='auction_length']");
  9370. 		var auctionCurrency = System.findNode("//select[@name='currency']");
  9371. 		var auctionMinBid = System.findNode("//input[@name='minbid']");
  9372. 		var auctionBuyNow = System.findNode("//input[@name='buynow']");
  9373.  
  9374. 		auctionLength.selectedIndex = newAuctionLength;
  9375. 		auctionCurrency.selectedIndex = newAuctionCurrency;
  9376. 		auctionMinBid.value = newAuctionMinBid;
  9377. 		auctionBuyNow.value = newAuctionBuyNow;
  9378.  
  9379. 		var enableBulkSell = GM_getValue("enableBulkSell");
  9380. 		if (enableBulkSell) {
  9381. 			var bulkSellAuctionLength = System.findNode("//select[@id='Helper:bulkSellAuctionLength']");
  9382. 			var bulkSellAuctionCurrency = System.findNode("//select[@id='Helper:bulkSellAuctionCurrency']");
  9383. 			var bulkSellAuctionMinBid = System.findNode("//input[@id='Helper:bulkSellMinBid']");
  9384. 			var bulkSellAuctionBuyNow = System.findNode("//input[@id='Helper:bulkSellBuyNow']");
  9385.  
  9386. 			bulkSellAuctionLength.selectedIndex = newAuctionLength;
  9387. 			bulkSellAuctionCurrency.selectedIndex = newAuctionCurrency;
  9388. 			bulkSellAuctionMinBid.value = newAuctionMinBid;
  9389. 			bulkSellAuctionBuyNow.value = newAuctionBuyNow;
  9390. 		}
  9391. 	},
  9392.  
  9393. 	saveAuctionTemplate: function(evt) {
  9394. 		var auctionLength = document.getElementById("Helper:auctionLength").value;
  9395. 		var auctionCurrency = document.getElementById("Helper:auctionCurrency").value;
  9396. 		var auctionMinBid = document.getElementById("Helper:minBid").value;
  9397. 		var auctionBuyNow = document.getElementById("Helper:buyNow").value;
  9398. 		if (!auctionMinBid) {return;}
  9399. 		var table = System.getValueJSON("auctionTemplate");
  9400. 		var theTemplate = {
  9401. 			auctionLength: auctionLength,
  9402. 			auctionCurrency: auctionCurrency,
  9403. 			auctionMinBid: auctionMinBid,
  9404. 			auctionBuyNow: auctionBuyNow,
  9405. 			isDefault: false
  9406. 		};
  9407. 		table.push(theTemplate);
  9408. 		System.setValueJSON("auctionTemplate", table);
  9409. 		window.location = window.location;
  9410. 	},
  9411.  
  9412. 	delAuctionTemplate: function(evt) {
  9413. 		var auctionTemplateId = evt.target.getAttribute("auctionTemplateId");
  9414. 		var table = System.getValueJSON("auctionTemplate");
  9415. 		table.splice(auctionTemplateId,1);
  9416. 		System.setValueJSON("auctionTemplate", table);
  9417. 		window.location = window.location;
  9418. 	},
  9419.  
  9420. 	injectMessageTemplate: function() {
  9421. 		if (GM_getValue("navigateToLogAfterMsg")) {
  9422.  
  9423. 			if (document.referrer.indexOf("?cmd=message") == -1) {
  9424. 				GM_setValue("msgReferringPage", document.referrer);
  9425. 			}
  9426. 			var messageSent = System.findNode("//center[contains(.,'Message sent to target player!')]");
  9427. 			if (messageSent) {
  9428. 				if (GM_getValue("msgReferringPage")) {
  9429. 					window.location = GM_getValue("msgReferringPage");
  9430. 					return;
  9431. 				} else {
  9432. 					window.location = "http://www.fallensword.com/index.php?cmd=log";
  9433. 					return;
  9434. 				}
  9435. 			}
  9436. 		}
  9437. 		//will only insert if we have a buff list (when button on profile is clicked)
  9438. 		Helper.insertBuffsInMsg();
  9439. 		var injectHere = System.findNode("//div[@class='innerContentPage']");
  9440. 		var table = System.getValueJSON("quickMsg");
  9441.  
  9442. 		var targetPlayer = System.findNode("//input[@name='target_player']").value;
  9443.  
  9444. 		if (location.search.indexOf("&replyTo") != -1) {
  9445. 			var newDev = document.createElement("div")
  9446. 			injectHere.appendChild(newDev);
  9447. 			var msg = location.search.match(/=%27(.*)%27/)[1].replace(/_/g, " ");
  9448. 			newDev.innerHTML = '<b>Replying To</b> [<a tabindex="-1" href="#" onmouseover="Tip(\'The message that was sent to you that you are replying to\');">?</a>]: ' + msg;
  9449. 		}
  9450.  
  9451. 		var textResult = "<br><table cellspacing='0' cellpadding='0' bordercolor='#000000'" +
  9452. 				" border='0' align='center' width='550' style='border-style: solid; border-width: 1px;'>" +
  9453. 				"<tr><td bgcolor='#cd9e4b'><center>Quick Message</center></td></tr>" +
  9454. 				"<tr><td><table cellspacing='10' cellpadding='0' border='0' width='100%'>";
  9455.  
  9456. 		for (var i = 0; i < table.length; i++) {
  9457. 			textResult += "<tr><td>Msg " + (i+1) + " [<a onmouseover=\"Tip('Click on the message to append the template');\" href='#'>" +
  9458. 				"<font color='white'>?</font></a>]:&nbsp;&nbsp;&nbsp;&nbsp;</td><td><span id='Helper.quickMsg" + i + "' quickMsgId=" + i + ">" +
  9459. 				table[i].replace(/{playername}/g, targetPlayer) + "</span></td></tr>";
  9460. 		}
  9461. 		textResult += "<tr><td valign=top colspan=2>Edit Templates: </td></tr>" +
  9462. 			"<tr><td align=center colspan=2 id=quickMsgTemplAreaId>&nbsp;</td></tr>" +
  9463. 			"</table></td></tr></table>";
  9464.  
  9465. 		var newNode = document.createElement("span");
  9466. 		newNode.id = "spanQuickMsg";
  9467. 		newNode.align = "center";
  9468. 		newNode.innerHTML = textResult;
  9469. 		injectHere.appendChild(newNode);
  9470.  
  9471. 		for (i = 0; i < table.length; i++) {
  9472. 			document.getElementById("Helper.quickMsg" + i).addEventListener("click", Helper.useQuickMsg, true);
  9473. 		}
  9474. 		if (GM_getValue("enterForSendMessage")) {
  9475. 			document.getElementsByName("msg")[0].addEventListener('keypress', function(evt) {
  9476. 				var r = evt.charCode;
  9477. 				var s = evt.keyCode;
  9478. 				if (r === 0 & s == 13 & !evt.shiftKey) {
  9479. 					var button = System.findNode("//input[@value='Send Message']");
  9480. 					if (button) {
  9481. 						evt.preventDefault();
  9482. 						evt.stopPropagation();
  9483. 						button.click();
  9484. 					}
  9485. 				}
  9486. 			}, true);
  9487. 		}
  9488.  
  9489. 		Helper.param={};
  9490. 		Helper.param={'id':'quickMsgTemplAreaId',
  9491. 			'headers':["Quick Message"],
  9492. 			'fields':[],
  9493. 			'tags':["textbox"],
  9494. 			'currentItems':System.getValueJSON("quickMsg"),
  9495. 			'gmname':"quickMsg"};
  9496. 		Helper.generateManageTable();
  9497. 	},
  9498.  
  9499. 	saveQuickMsg: function() {
  9500. 		var quickMsg = document.getElementById("Helper.quickMsgFullText").value;
  9501. 		try {
  9502. 			JSON.parse(quickMsg);
  9503. 		} catch (err) {
  9504. 			alert("Not a valid template");
  9505. 			return;
  9506. 		}
  9507. 		GM_setValue("quickMsg", quickMsg);
  9508. 		var injectHere = System.findNode("//input[@value='Send Message']/../../../../../../../../..");
  9509. 		injectHere.removeChild(document.getElementById("spanQuickMsg"));
  9510. 		Helper.injectMessageTemplate();
  9511. 	},
  9512.  
  9513. 	useQuickMsg: function(evt) {
  9514. 		var targetPlayer = System.findNode("//input[@name='target_player']").value;
  9515. 		var quickMsgId = evt.target.getAttribute("quickMsgId");
  9516. 		System.findNode("//textarea[@name='msg']").value +=
  9517. 			System.getValueJSON("quickMsg")[quickMsgId].replace(/{playername}/g, targetPlayer) + "\n";
  9518. 	},
  9519.  
  9520. 	insertBuffsInMsg: function() {
  9521. 		var buffsToBuy = GM_getValue("buffsToBuy");
  9522. 		if (buffsToBuy && buffsToBuy.trim().length > 0) {
  9523. 			var targetPlayer = System.findNode("//input[@name='target_player']").value;
  9524. 			var greetingText = GM_getValue("buyBuffsGreeting").trim();
  9525. 			var hasBuffTag = greetingText.indexOf("{buffs}") != -1;
  9526. 			var hasCostTag = greetingText.indexOf("{cost}") != -1;
  9527. 			greetingText = greetingText.replace(/{playername}/g, targetPlayer);
  9528. 			if (!hasBuffTag) {
  9529. 				System.findNode("//textarea[@name='msg']").value =  greetingText + " " + GM_getValue("buffsToBuy");
  9530. 			} else {
  9531. 				if (!hasCostTag) {
  9532. 					System.findNode("//textarea[@name='msg']").value =  greetingText.replace(/{buffs}/g, "`~" + GM_getValue("buffsToBuy") + "~`");
  9533. 				} else {
  9534. 					System.findNode("//textarea[@name='msg']").value =  greetingText.replace(/{buffs}/g, "`~" + GM_getValue("buffsToBuy") + "~`").replace(/{cost}/g, GM_getValue("buffCostTotalText"));
  9535. 				}
  9536. 			}
  9537. 			GM_setValue("buffsToBuy", "");
  9538. 		}
  9539. 	},
  9540.  
  9541. 	injectMailbox: function() {
  9542. 		var items = System.findNodes("//a[contains(@href,'temp_id')]");
  9543. 		if (items) {
  9544. 			for (var i = 0; i < items.length; i++) {
  9545. 				var item = items[i];
  9546. 				var itemHref = item.getAttribute('href');
  9547. 				var itemTable = item.parentNode.parentNode.parentNode.parentNode.parentNode;
  9548. 				itemTable.innerHTML += '<br><span style="cursor:pointer; text-decoration:underline; color:blue; font-size:x-small;" '+
  9549. 					'id="Helper:recallMailboxItem' + i + '" ' +
  9550. 					'itemHref="' + itemHref + '">Fast Take</span>';
  9551. 				document.getElementById('Helper:recallMailboxItem' + i).addEventListener('click', Helper.recallMailboxItem, true);
  9552. 			}
  9553. 			var titleTable = System.findNode("//table[tbody/tr/td/font/b[.='Item Mailbox']]");
  9554. 			if (!titleTable) titleTable = System.findNode("//table[tbody/tr/td/font/b[.='Guild Mailbox']]");
  9555. 			titleTable.rows[4].cells[0].align = 'center';
  9556. 			titleTable.rows[4].cells[0].innerHTML = '<span id="Helper:recallAllMailbox" '+
  9557. 				'style="cursor:pointer; text-decoration:underline; color:blue; font-size:x-small;">Take All</span>';
  9558. 			document.getElementById('Helper:recallAllMailbox').addEventListener('click', Helper.recallAllMailbox, true);
  9559. 		}
  9560. 	},
  9561.  
  9562. 	recallAllMailbox: function(evt) {
  9563. 		var mailItems = System.findNodes("//span[contains(@id,'Helper:recallMailboxItem')]");
  9564. 		for (var i = 0; i < mailItems.length; i++) {
  9565. 			var mailItem = mailItems[i];
  9566. 			var mailboxItemHref = mailItem.getAttribute("itemHref");
  9567. 			System.xmlhttp(mailboxItemHref,
  9568. 				Helper.recallMailboxReturnMessage,
  9569. 				{"target": mailItem});
  9570. 		}
  9571. 	},
  9572.  
  9573. 	recallMailboxItem: function(evt) {
  9574. 		var mailboxItemHref = evt.target.getAttribute("itemHref");
  9575. 		System.xmlhttp(mailboxItemHref,Helper.recallMailboxReturnMessage,{"target": evt.target, "url": mailboxItemHref});
  9576. 	},
  9577.  
  9578. 	recallMailboxReturnMessage: function(responseText, callback) {
  9579. 		var target = callback.target;
  9580. 		var info = Layout.infoBox(responseText);
  9581. 		target.style.cursor = 'default';
  9582. 		target.style.textDecoration = 'none';
  9583. 		if (info.search("Item was transferred to your backpack") != -1) {
  9584. 			target.style.color = 'green';
  9585. 			target.style.fontWeight = 'bold';
  9586. 			target.style.fontSize = 'small';
  9587. 			target.innerHTML = "Taken";
  9588. 		} else if (info.search("Item was transferred to the guild store!") != -1) {
  9589. 			target.style.color = 'green';
  9590. 			target.style.fontWeight = 'bold';
  9591. 			target.style.fontSize = 'small';
  9592. 			target.innerHTML = "Taken";
  9593. 		} else if (info!=="") {
  9594. 			target.style.color = 'red';
  9595. 			target.style.fontWeight = 'bold';
  9596. 			target.style.fontSize = 'small';
  9597. 			target.innerHTML = "Error: " + info;
  9598. 		} else {
  9599. 			target.style.color = 'red';
  9600. 			target.style.fontSize = 'small';
  9601. 			target.innerHTML = "Weird Error: check the Tools>Error Console";
  9602. 			GM_log("Post the previous HTML and the following message to the code.google.com site or to the forum to help us debug this error");
  9603. 			GM_log(callback.url);
  9604. 		}
  9605. 	},
  9606.  
  9607. 	injectAuctionQuickCancel: function() {
  9608. 		if (location.search == '?cmd=auctionhouse' != -1 && location.search == '&type=-2' != -1) {
  9609. 			var cancelButtons = System.findNodes("//img[@title='Cancel Auction']");
  9610. 			if (cancelButtons) {
  9611. 				for (var i = 0; i < cancelButtons.length; i++) {
  9612. 					var cancelButton = cancelButtons[i];
  9613. 					var cancelButtonHref = cancelButton.parentNode.getAttribute('href');
  9614. 					var cancelButtonCellElement = cancelButton.parentNode.parentNode.parentNode;
  9615. 					cancelButtonCellElement.style.textAlign = 'center';
  9616. 					cancelButtonCellElement.innerHTML += '<br><br><span style="cursor:pointer; text-decoration:underline; color:blue; font-size:x-small;" '+
  9617. 						'id="Helper:cancelAuctionItem' + i + '" ' +
  9618. 						'cancelButtonHref="' + cancelButtonHref + '">Fast Cancel</span>';
  9619. 					document.getElementById('Helper:cancelAuctionItem' + i).addEventListener('click', Helper.cancelAuctionItem, true);
  9620. 				}
  9621. 				var buttonCell = System.findNode("//input[contains(@value,'My Auctions')]/..");
  9622. 				var insertCancelAllHere = buttonCell;
  9623. 				var insertCancelAllBlock = document.createElement("SPAN");
  9624. 				insertCancelAllBlock.innerHTML = "Cancel All";
  9625. 				insertCancelAllBlock.style.cursor = "pointer";
  9626. 				insertCancelAllBlock.style.textDecoration = "underline";
  9627. 				insertCancelAllBlock.style.color = "blue";
  9628. 				insertCancelAllBlock.style.fontSize = "x-small";
  9629. 				insertCancelAllHere.innerHTML += "&nbsp;";
  9630. 				insertCancelAllHere.appendChild(insertCancelAllBlock);
  9631. 				insertCancelAllBlock.addEventListener('click', Helper.cancelAllAuction, true);
  9632. 			}
  9633. 		}
  9634. 	},
  9635.  
  9636. 	cancelAllAuction: function(evt) {
  9637. 		var auctionItems = System.findNodes("//span[contains(@id,'Helper:cancelAuctionItem')]");
  9638. 		for (var i = 0; i < auctionItems.length; i++) {
  9639. 			var auctionItem = auctionItems[i];
  9640. 			var cancelButtonHref = auctionItem.getAttribute("cancelButtonHref");
  9641. 			System.xmlhttp(cancelButtonHref,
  9642. 				Helper.cancelAuctionReturnMessage,
  9643. 				{"target": auctionItem, "url": cancelButtonHref});
  9644. 		}
  9645. 	},
  9646.  
  9647. 	cancelAuctionItem: function(evt) {
  9648. 		var cancelButtonHref = evt.target.getAttribute("cancelButtonHref");
  9649. 		System.xmlhttp(cancelButtonHref,
  9650. 			Helper.cancelAuctionReturnMessage,
  9651. 			{"target": evt.target, "url": cancelButtonHref});
  9652. 	},
  9653.  
  9654. 	cancelAuctionReturnMessage: function(responseText, callback) {
  9655. 		var target = callback.target;
  9656. 		var info = Layout.infoBox(responseText);
  9657. 		target.style.cursor = 'default';
  9658. 		target.style.textDecoration = 'none';
  9659. 		if (info.search("You cancelled your auction") != -1) {
  9660. 			target.style.color = 'green';
  9661. 			target.style.fontWeight = 'bold';
  9662. 			target.style.fontSize = 'small';
  9663. 			target.innerHTML = "Cancelled";
  9664. 		} else if (info!=="") {
  9665. 			target.style.color = 'red';
  9666. 			target.style.fontWeight = 'bold';
  9667. 			target.style.fontSize = 'small';
  9668. 			target.innerHTML = "Error: " + info;
  9669. 		} else {
  9670. 			target.style.color = 'red';
  9671. 			target.style.fontSize = 'small';
  9672. 			target.innerHTML = "Weird Error: check the Tools>Error Console";
  9673. 			GM_log("Post the previous HTML and the following message to the code.google.com site or to the forum to help us debug this error");
  9674. 			GM_log(callback.url);
  9675. 		}
  9676. 	},
  9677.  
  9678. 	injectPoints: function() {
  9679. 		Helper.currentFSP = System.findNode("//tr[td/a/img[contains(@src,'/skin/icon_points.gif')]]/td[4]").textContent.replace(/,/g,"")*1;
  9680.  
  9681. 		var stamForFSPElement = System.findNode("//td[@width='60%' and contains(.,'+25 Current Stamina')]/../td[4]");
  9682. 		var stamForFSPInjectHere = System.findNode("//td[@width='60%' and contains(.,'+25 Current Stamina')]");
  9683. 		var stamFSPTextField = System.findNode("table/tbody/tr/td/input[@name='quantity']", stamForFSPElement);
  9684. 		stamFSPTextField.type='current';
  9685. 		stamFSPTextField.addEventListener('keyup', Helper.updateStamCount, true);
  9686. 		stamForFSPInjectHere.innerHTML += ' <span style="color:blue" id="totalStam" type="current"><span>';
  9687.  
  9688. 		stamForFSPElement = System.findNode("//td[@width='60%' and contains(.,'+10 Maximum Stamina')]/../td[4]");
  9689. 		stamForFSPInjectHere = System.findNode("//td[@width='60%' and contains(.,'+10 Maximum Stamina')]");
  9690. 		stamFSPTextField = System.findNode("table/tbody/tr/td/input[@name='quantity']", stamForFSPElement);
  9691. 		stamFSPTextField.type='maximum';
  9692. 		stamFSPTextField.addEventListener('keyup', Helper.updateStamCount, true);
  9693. 		stamForFSPInjectHere.innerHTML += ' <span style="color:blue" id="totalStam" type="maximum"><span>';
  9694.  
  9695. 		var goldForFSPElement = System.findNode("//td[@width='60%' and contains(.,'+50,000')]/../td[4]");
  9696. 		goldForFSPElement.innerHTML = '<a href="' + System.server + '?cmd=marketplace">Sell at Marketplace</a>';
  9697. 	},
  9698.  
  9699. 	updateStamCount: function(evt) {
  9700. 		var FSPvalue = evt.target.value*1;
  9701. 		var type = evt.target.getAttribute("type");
  9702. 		var injectHere = System.findNode("//span[@id='totalStam' and @type='"+type+"']");
  9703. 		//cap the value if the user goes over his current FSP
  9704. 		var color = 'red';
  9705. 		var extraStam = Helper.currentFSP*(type=='current'?25:10);
  9706. 		if (FSPvalue <= Helper.currentFSP) {
  9707. 			extraStam = FSPvalue*(type=='current'?25:10);
  9708. 			color = 'blue';
  9709. 		}
  9710. 		injectHere.style.color = color;
  9711. 		injectHere.innerHTML = '(+' + extraStam + ' stamina)';
  9712. 	},
  9713.  
  9714. 	injectTitan: function() {
  9715. 		System.xmlhttp("index.php?cmd=guild&subcmd=scouttower", Helper.getScoutTowerDetails);
  9716. 	},
  9717.  
  9718. 	getScoutTowerDetails: function(responseText) {
  9719. 		var doc=System.createDocument(responseText);
  9720. 		var scoutTowerTable = System.findNode("//table[tbody/tr/td/img[contains(@src,'/skin/scouttower_header.jpg')]]", doc);
  9721. 		if (scoutTowerTable) {
  9722. 			var titanTable = System.findNode("//table[tbody/tr/td/img[contains(@src,'/skin/titankilllog_banner.jpg')]]");
  9723. 			var newRow = titanTable.insertRow(0);
  9724. 			var newCell = newRow.insertCell(0);
  9725. 			newCell.align = "center";
  9726. 			newCell.innerHTML = scoutTowerTable.rows[1].cells[0].innerHTML + "<br><br>" ;
  9727. 			newRow = titanTable.insertRow(1);
  9728. 			newCell = newRow.insertCell(0);
  9729. 			newCell.innerHTML = scoutTowerTable.rows[8].cells[0].innerHTML;
  9730. 		}
  9731. 		Helper.injectScouttowerBuffLinks();
  9732. 	},
  9733.  
  9734. 	injectScouttower: function() {
  9735. 		Helper.injectScouttowerBuffLinks();
  9736. 		Helper.parseScoutTower();
  9737. 	},
  9738.  
  9739. 	injectScouttowerBuffLinks: function() {
  9740. 		var titanTables = System.findNodes("//table[tbody/tr/td/font[.='Guild Member']]");
  9741. 		if (titanTables) {
  9742. 			for (var i = 0; i < titanTables.length; i++) {
  9743. 				titanTable = titanTables[i];
  9744. 				var shortList = new Array();
  9745. 				if (titanTable.rows.length <= 1) continue;
  9746. 				for (var j = 1; j < titanTable.rows.length; j++) {
  9747. 					if (titanTable.rows[j].cells[1]) {
  9748. 						var firstCell = titanTable.rows[j].cells[0];
  9749. 						var playerID = /player_id=(\d+)/.exec(firstCell.innerHTML)[1];
  9750. 						shortList.push(firstCell.textContent);
  9751. 						firstCell.innerHTML += " <a style='color:blue;font-size:10px;' " +
  9752. 							Layout.quickBuffHref(playerID) + ">[b]</a>";
  9753. 					}
  9754. 				}
  9755. 				titanTable.rows[0].cells[0].innerHTML += " <a style='color:blue;font-size:10px;'>all</a>";
  9756. 				var buffAllLink = titanTable.rows[0].cells[0].firstChild.nextSibling.nextSibling;
  9757. 				buffAllLink.setAttribute("href","javascript:openWindow('index.php?cmd=quickbuff&t=" + shortList + "', 'fsQuickBuff', 618, 1000, ',scrollbars')");
  9758. 			}
  9759. 		}
  9760. 	},
  9761.  
  9762. 	injectQuestTracker: function() {
  9763. 		var injectHere = System.findNode("//td[font/b[.='Quest Details']]");
  9764. 		var tracking = false;
  9765. 		tracking = Helper.isQuestBeingTracked(location.search);
  9766. 		var questName = System.findNode("//font[@size='2' and contains(.,'\"')]", injectHere);
  9767. 		if (questName) {
  9768. 			questName = questName.innerHTML;
  9769. 			questName = questName.match(/"(.*)"/);
  9770. 			if (questName && questName.length > 1) {
  9771. 				questName = questName[1];
  9772. 				injectHere.innerHTML += '&nbsp;<a href="http://guide.fallensword.com/index.php?cmd=quests&search_name=' + questName.replace(/ /g,'+') + '&search_level_min=&search_level_max=" target="_blank">' +
  9773. 					'<img border=0 title="Search quest in Ultimate FSG" src="'+ System.imageServerHTTP + '/temple/1.gif"/></a>';
  9774. 				if (GM_getValue("showFSGIcon")) {
  9775. 					injectHere.innerHTML += '&nbsp;<a href="http://www.fallenswordguide.com/quests/index.php?realm=0&search=' + questName.replace(/ /g,'+') +
  9776. 						'" target="_blank"><img border=0 title="Search for this quest on the Fallensword Guide" src="http://www.fallenswordguide.com/favicon.ico"/></a>';
  9777. 				}
  9778. 				injectHere.innerHTML += '&nbsp;<a href="http://wiki.fallensword.com/index.php/' + questName.replace(/ /g,'_') +
  9779. 					'" target="_blank"><img border=0 title="Search for this quest on the Fallensword Wiki" src=' + System.imageServer + '/skin/fs_wiki.gif /></a>';
  9780. 			}
  9781.  
  9782. 		}
  9783.  
  9784. 		if (tracking === true) {
  9785.  
  9786. 			injectHere.innerHTML += '<br><input id="dontTrackThisQuest" data="' + location.search + '" type="button" value="Stop Tracking Quest" title="Tracks quest progress." class="custombutton">';
  9787. 			document.getElementById("dontTrackThisQuest").addEventListener("click", Helper.dontTrackThisQuest, true);
  9788.  
  9789. 		} else {
  9790. 			injectHere.innerHTML += '<br><input id="trackThisQuest" type="button" value="Track Quest" title="Tracks quest progress." class="custombutton">';
  9791. 			document.getElementById("trackThisQuest").addEventListener("click", Helper.trackThisQuest, true);
  9792. 		}
  9793. 	},
  9794.  
  9795. 	trackThisQuest: function(evt) {
  9796.  
  9797. 		var currentTrackedQuest = GM_getValue("questBeingTracked").split(";");
  9798. 		if (currentTrackedQuest.length > 0 && currentTrackedQuest[0].trim().length > 0) {
  9799. 			GM_setValue("questBeingTracked", GM_getValue("questBeingTracked") + ";" + location.search);
  9800. 		} else {
  9801. 		GM_setValue("questBeingTracked", location.search);
  9802. 		}
  9803. 		window.location = window.location;
  9804. 	},
  9805.  
  9806. 	dontTrackThisQuest: function(evt) {
  9807. 		var questNotToTrack = evt.target.getAttribute("data");
  9808. 		var currentTrackedQuest = GM_getValue("questBeingTracked").split(";");
  9809. 		if (currentTrackedQuest.length > 0) {
  9810. 			var newTracked = "";
  9811. 			for (var i = 0; i < currentTrackedQuest.length; i++) {
  9812. 				if (currentTrackedQuest[i] != questNotToTrack) {
  9813. 					if (newTracked.trim().length > 0) {
  9814. 						newTracked += ";";
  9815. 					}
  9816. 					newTracked += currentTrackedQuest[i];
  9817.  
  9818. 				}
  9819. 			}
  9820. 			GM_setValue("questBeingTracked", newTracked);
  9821. 		} else {
  9822. 		GM_setValue("questBeingTracked", "");
  9823. 		}
  9824.  
  9825. 		window.location = window.location;
  9826. 	},
  9827.  
  9828. 	getQuestInfo: function(responseText, callback) {
  9829. 		var idx = callback.data;
  9830. 		var doc=System.createDocument(responseText);
  9831. 		var questInfoLink = System.findNode("//a[@id='qiLink" + idx + "']");
  9832. 		var questNameNode = System.findNode("//font[b[.='Quest Details']]/following-sibling::font[1]", doc);
  9833. 		if (questNameNode) {
  9834. 			questInfoLink.innerHTML = questNameNode.innerHTML.replace (/"/g, "");
  9835. 		} else {
  9836. 			questInfoLink.innerHTML = "Unnamed Quest";
  9837. 		}
  9838. 		var questInfoElement = System.findNode("//span[@findme='questinfo" + idx + "']");
  9839. 		var trackingHTMLElement = System.findNode("//font[@color='#003300']", doc);
  9840. 		if (trackingHTMLElement) {
  9841. 			questInfoElement.innerHTML = trackingHTMLElement.innerHTML;
  9842. 		} else {
  9843. 			questInfoElement.innerHTML = 'None';
  9844. 		}
  9845. 		document.getElementById("dontTrackThisQuest" + idx).addEventListener("click", Helper.dontTrackThisQuest, true);
  9846. 	},
  9847.  
  9848. 	prepareBountyData: function() {
  9849. 		enableActiveBountyList = GM_getValue("enableActiveBountyList");
  9850. 		enableWantedList = GM_getValue("enableWantedList");
  9851. 		if (enableWantedList || enableActiveBountyList) {
  9852. 			var mainTable = System.findNode("//table[tbody/tr/td[contains(@background,'/skin/sidebar_bg.gif')]]");
  9853. 			if (mainTable && mainTable.rows[1]) {
  9854. 				var injectHere = mainTable.rows[1].cells[2].firstChild.nextSibling.rows[2].cells[0].firstChild.nextSibling;
  9855. 				if (enableWantedList) {
  9856. 					if (!injectHere)
  9857. 						return;
  9858. 					var info = injectHere.insertRow(0);
  9859. 					var cell = info.insertCell(0);
  9860. 					cell.innerHTML="<span id='Helper:WantedListPlaceholder'></span>";
  9861. 				}
  9862. 				if (enableActiveBountyList) {
  9863. 					if (injectHere) {
  9864. 						info = injectHere.insertRow(0);
  9865. 						cell = info.insertCell(0);
  9866. 						cell.innerHTML="<span id='Helper:BountyListPlaceholder'></span>";
  9867. 					}
  9868. 				}
  9869. 				Helper.retrieveBountyInfo(enableActiveBountyList, enableWantedList);
  9870. 			}
  9871. 		}
  9872. 	},
  9873.  
  9874. 	retrieveBountyInfo: function(enableActiveBountyList, enableWantedList) {
  9875. 		var bountyList = System.getValueJSON("bountylist");
  9876. 		var wantedList = System.getValueJSON("wantedList");
  9877. 		var bountyListRefreshTime = GM_getValue("bountyListRefreshTime");
  9878. 		var bwNeedsRefresh = GM_getValue("bwNeedsRefresh");
  9879.  
  9880. 		bountyListRefreshTime *= 1000;
  9881. 		if (!bwNeedsRefresh) {
  9882. 			if (bountyList) {
  9883. 				if ((new Date()).getTime() - bountyList.lastUpdate.getTime() > bountyListRefreshTime) bwNeedsRefresh = true; // invalidate cache
  9884. 			}
  9885. 			if (wantedList && !bwNeedsRefresh) {
  9886. 				if ((new Date()).getTime() - wantedList.lastUpdate.getTime() > bountyListRefreshTime) bwNeedsRefresh = true; // invalidate cache
  9887. 			}
  9888. 		}
  9889.  
  9890. 		if (!bountyList || !wantedList || bwNeedsRefresh && (enableActiveBountyList || enableWantedList)) {
  9891. 			System.xmlhttp("index.php?cmd=bounty", Helper.parseBountyPageForWorld);
  9892. 		} else {
  9893. 			if (enableWantedList) {
  9894. 				wantedList.isRefreshed = false;
  9895. 				Helper.injectWantedList(wantedList);
  9896. //alert("wantedList.isRefreshed = "+ wantedList.isRefreshed);
  9897. 			}
  9898. 			if (enableActiveBountyList) {
  9899. 				bountyList.isRefreshed = false;
  9900. //alert("bountyList.isRefreshed = " + bountyList.isRefreshed);
  9901. 				Helper.injectBountyList(bountyList);
  9902. 			}
  9903. 		}
  9904. 	},
  9905.  
  9906. 	parseBountyPageForWorld: function(details) {
  9907. 		var doc=System.createDocument(details);
  9908. 		var  enableActiveBountyList = GM_getValue("enableActiveBountyList");
  9909. 		var  enableWantedList = GM_getValue("enableWantedList");
  9910. 		GM_setValue("bwNeedsRefresh", false);
  9911.  
  9912. 		if (enableWantedList) {
  9913. 			var activeTable = System.findNode("//table[@width = '630' and @cellpadding = '3']", doc);
  9914. 			var wantedNames = GM_getValue("wantedNames");
  9915. 			var wantedArray = wantedNames.split(",");
  9916. 			var wantedList = {};
  9917. 			wantedList.bounty = [];
  9918. 			wantedList.isRefreshed = true;
  9919. 			wantedList.lastUpdate = new Date();
  9920. 			wantedList.wantedBounties = false;
  9921.  
  9922. 			if (activeTable) {
  9923. 				for (var i = 1; i < activeTable.rows.length - 2; i+=2) {
  9924. 					for (var j = 0; j < wantedArray.length; j++) {
  9925. 						var target = activeTable.rows[i].cells[0].firstChild.firstChild.firstChild.textContent;
  9926. 						if (target == wantedArray[j].trim()) {
  9927. 							wantedList.wantedBounties = true;
  9928. 							bounty = {};
  9929. 							bounty.target = target;
  9930. 							bounty.link = activeTable.rows[i].cells[0].firstChild.firstChild.getAttribute("href");
  9931. 							bounty.lvl = activeTable.rows[i].cells[0].firstChild.firstChild.nextSibling.textContent.replace(/\[/, "").replace(/\]/, "");
  9932.  
  9933. 							bounty.offerer = activeTable.rows[i].cells[1].firstChild.firstChild.firstChild.textContent;
  9934.  
  9935. 							bounty.reward = activeTable.rows[i].cells[2].textContent;
  9936. 							bounty.rewardType = activeTable.rows[i].cells[2].firstChild.firstChild.firstChild.firstChild.nextSibling.firstChild.title;
  9937.  
  9938. 							bounty.rKills = activeTable.rows[i].cells[3].textContent;
  9939.  
  9940. 							bounty.xpLoss = activeTable.rows[i].cells[4].textContent;
  9941.  
  9942. 							bounty.posted = activeTable.rows[i].cells[5].textContent;
  9943.  
  9944. 							bounty.tickets = activeTable.rows[i].cells[6].textContent;
  9945.  
  9946. 							if (activeTable.rows[i].cells[7].textContent.trim() == "[active]") {
  9947. 								bounty.active = true;
  9948. 								bounty.accept = "";
  9949. 							}
  9950. 							else {
  9951. 								bounty.active = false;
  9952. 								bounty.accept = activeTable.rows[i].cells[7].firstChild.firstChild.getAttribute("onclick");
  9953. 							}
  9954. 							wantedList.bounty.push(bounty);
  9955. 						}
  9956. 					}
  9957. 				}
  9958. 			}
  9959. 			Helper.injectWantedList(wantedList);
  9960. 		}
  9961. 		if (enableActiveBountyList) {
  9962. 			activeTable = System.findNode("//table[@width = 620]", doc);
  9963. 			var bountyList = {};
  9964. 			bountyList.bounty = [];
  9965. 			bountyList.isRefreshed = true;
  9966. 			bountyList.lastUpdate = new Date();
  9967.  
  9968. 			if (activeTable) {
  9969. 				if (!(/No bounties active/).test(activeTable.rows[1].cells[0].innerHTML)) {
  9970. 					bountyList.activeBounties = true;
  9971. 					for (i = 1; i < activeTable.rows.length - 2; i+=2) {
  9972. 						bounty = {};
  9973. 						bounty.target = activeTable.rows[i].cells[0].firstChild.firstChild.firstChild.textContent;
  9974. 						bounty.link = activeTable.rows[i].cells[0].firstChild.firstChild.getAttribute("href");
  9975. 						bounty.lvl = activeTable.rows[i].cells[0].firstChild.firstChild.nextSibling.textContent.replace(/\[/, "").replace(/\]/, "");
  9976. 						bounty.reward = activeTable.rows[i].cells[2].textContent;
  9977. 						bounty.rewardType = activeTable.rows[i].cells[2].firstChild.firstChild.firstChild.firstChild.nextSibling.firstChild.title;
  9978. 						bounty.posted = activeTable.rows[i].cells[3].textContent;
  9979. 						bounty.xpLoss = activeTable.rows[i].cells[4].textContent;
  9980. 						bounty.progress = activeTable.rows[i].cells[5].textContent;
  9981.  
  9982. 						bountyList.bounty.push(bounty);
  9983. 					}
  9984. 				}
  9985. 				else {
  9986. 					bountyList.activeBounties = false;
  9987. 				}
  9988. 			}
  9989. 			Helper.injectBountyList(bountyList);
  9990. 		}
  9991. 	},
  9992.  
  9993. 	injectBountyList: function(bountyList) {
  9994. 		System.setValueJSON("bountylist", bountyList);
  9995. 		var injectHere = document.getElementById("Helper:BountyListPlaceholder");
  9996. 		var displayList = document.createElement("TABLE");
  9997. 		displayList.style.border = "1px solid #c5ad73";
  9998. 		displayList.style.backgroundColor = (bountyList.isRefreshed)?"#6a5938":"#4a3918";
  9999. 		displayList.cellPadding = 1;
  10000. 		displayList.width = 125;
  10001.  
  10002. 		var aRow=displayList.insertRow(0); //bountyList.rows.length
  10003. 		var aCell=aRow.insertCell(0);
  10004. 		var output = "<ol style='color:#FFF380;font-size:10px;list-style-type:decimal;margin-left:1px;margin-top:1px;margin-bottom:1px;padding-left:20px;'>"+
  10005. 			"Active Bounties <span id='Helper:resetBountyList' style='color:blue; font-size:8px; cursor:pointer; text-decoration:underline;'>Reset</span>";
  10006.  
  10007. 		if (bountyList.activeBounties === false) {
  10008. 			output += "</ol> \f <ol style='color:orange;font-size:10px;list-style-type:decimal;margin-left:1px;margin-top:1px;margin-bottom:1px;padding-left:10px;'>" +
  10009. 				"[No Active bounties]</ol>";
  10010. 		}
  10011. 		else {
  10012. 			for (var i = 0; i < bountyList.bounty.length; i++) {
  10013. 				var mouseOverText = "\"tt_setWidth(205);";
  10014. 				mouseOverText += "Tip('<div style=\\'text-align:center;width:205px;\\'>Level:  " + bountyList.bounty[i].lvl +
  10015. 				"<br/>Reward: " + bountyList.bounty[i].reward + " " +bountyList.bounty[i].rewardType +
  10016. 				"<br/>XP Loss Remaining: " + bountyList.bounty[i].xpLoss +
  10017. 				"<br/>Progress:  " + bountyList.bounty[i].progress;
  10018. 				mouseOverText += "</div>');\"";
  10019.  
  10020. //				output += " href='" + bountyList.bounty[i].link + "'>" + bountyList.bounty[i].target +"</a></li>";
  10021. 				output += "<li style='padding-bottom:0px;'>";
  10022. 				output += "<a style='color:red;font-size:10px;'";
  10023. 				output += "href='" + System.server + "index.php?cmd=attackplayer&target_username=" + bountyList.bounty[i].target + "'>[a]</a>&nbsp;";
  10024.  
  10025. 				output += "<a style='color:#A0CFEC;font-size:10px;'";
  10026. 				output += "href='" + System.server + "index.php?cmd=message&target_player=" + bountyList.bounty[i].target + "'>[m]";
  10027. 				output += "</a> &nbsp;<a onmouseover=" + mouseOverText;
  10028. 				output += "style='color:";
  10029. 				output += "#FFF380";
  10030. 				output += ";font-size:10px;'";
  10031. 				output += " href='" + bountyList.bounty[i].link + "'>" + bountyList.bounty[i].target +"</a></li>";
  10032. 			}
  10033. 		}
  10034.  
  10035. 		aCell.innerHTML = output;
  10036. 		var breaker=document.createElement("BR");
  10037. 		injectHere.parentNode.insertBefore(breaker, injectHere.nextSibling);
  10038. 		injectHere.parentNode.insertBefore(displayList, injectHere.nextSibling);
  10039. 		var test = document.getElementById('Helper:resetBountyList').addEventListener('click', Helper.resetBountyList, true);
  10040. 	},
  10041.  
  10042. 	resetBountyList: function(event) {
  10043. 		System.setValueJSON("bountylist", null);
  10044. 		window.location = window.location;
  10045. 	},
  10046.  
  10047. 	injectWantedList: function(wantedList) {
  10048. 		System.setValueJSON("wantedList", wantedList);
  10049. 		var injectHere = document.getElementById("Helper:WantedListPlaceholder");
  10050. 		var displayList = document.createElement("TABLE");
  10051. 		displayList.style.border = "1px solid #c5ad73";
  10052. 		displayList.style.backgroundColor = (wantedList.isRefreshed)?"#6a5938":"#4a3918";
  10053. 		displayList.cellPadding = 1;
  10054. 		displayList.width = 125;
  10055.  
  10056. 		var aRow=displayList.insertRow(0);
  10057. 		var aCell=aRow.insertCell(0);
  10058. 		var output = "<ol style='color:#FFF380;font-size:10px;list-style-type:decimal;margin-left:1px;margin-top:1px;margin-bottom:1px;padding-left:12px;'>"+
  10059. 			"Wanted Bounties <span id='Helper:resetWantedList' style='color:blue; font-size:8px; cursor:pointer; text-decoration:underline;'>Reset</span><br>";
  10060.  
  10061. 		if (wantedList.wantedBounties === false) {
  10062. 			output += "</ol> \f <ol style='color:orange;font-size:10px;list-style-type:decimal;margin-left:1px;margin-top:1px;margin-bottom:1px;padding-left:7px;'>" +
  10063. 				"[No wanted bounties]</ol>";
  10064. 		}
  10065. 		else {
  10066. 			for (var i = 0; i < wantedList.bounty.length; i++) {
  10067. 				var mouseOverText = "\"tt_setWidth(205);";
  10068. 				mouseOverText += "Tip('<div style=\\'text-align:center;width:205px;\\'>Target Level:  " + wantedList.bounty[i].lvl +
  10069. 					"<br/>Offerer: "+ wantedList.bounty[i].offerer +
  10070. 					"<br/>Reward: " + wantedList.bounty[i].reward + " " +wantedList.bounty[i].rewardType +
  10071. 					"<br/>Req. Kills: " + wantedList.bounty[i].rKills +
  10072. 					"<br/>XP Loss Remaining: " + wantedList.bounty[i].xpLoss +
  10073. 					"<br/>Posted: " + wantedList.bounty[i].posted +
  10074. 					"<br/>Tickets Req.:  " + wantedList.bounty[i].tickets;
  10075. 				mouseOverText += "</div>');\"";
  10076.  
  10077. 				output += "<li style='padding-bottom:0px;margin-left:5px;'>";
  10078. 				output += "<a style= 'font-size:10px;";
  10079. 				if (wantedList.bounty[i].accept)
  10080. 					output += "color:rgb(0,255,0); cursor:pointer; text-decoration:underline blink;' title = 'Accept Bounty' 'onclick=\"" + wantedList.bounty[i].accept + "\"'>[a]</a>&nbsp;";
  10081. 				else
  10082. 					output += "color:red;' href='" + System.server + "index.php?cmd=attackplayer&target_username=" + wantedList.bounty[i].target + "'>[a]</a>&nbsp;";
  10083. 				output += "<a style='color:#A0CFEC;font-size:10px;'";
  10084. 				output += "href='" + System.server + "index.php?cmd=message&target_player=" + wantedList.bounty[i].target + "'>[m]";
  10085. 				output += "</a> &nbsp;<a onmouseover=" + mouseOverText;
  10086. 				output += "style='color:";
  10087. 				output += "#FFF380";
  10088. 				output += ";font-size:10px;'";
  10089. 				output += " href='" + wantedList.bounty[i].link + "'>" + wantedList.bounty[i].target +"</a></li>";
  10090. 			}
  10091. 		}
  10092.  
  10093. 		aCell.innerHTML = output;
  10094. 		var breaker=document.createElement("BR");
  10095. 		injectHere.parentNode.insertBefore(breaker, injectHere.nextSibling);
  10096. 		injectHere.parentNode.insertBefore(displayList, injectHere.nextSibling);
  10097. 		document.getElementById('Helper:resetWantedList').addEventListener('click', Helper.resetWantedList, true);
  10098. 	},
  10099.  
  10100. 	resetWantedList: function(event) {
  10101. 		System.setValueJSON("wantedList", null);
  10102. 		window.location = window.location;
  10103. 	},
  10104.  
  10105. 	prepareAllyEnemyList: function() {
  10106. 		if (GM_getValue("enableAllyOnlineList") || GM_getValue("enableEnemyOnlineList")) {
  10107. 			var rightColumnTable = System.findNode("//td[@id='rightColumn']/table");
  10108. 			if (rightColumnTable) {
  10109. 				var info = rightColumnTable.insertRow(2);
  10110. 				var cell = info.insertCell(0);
  10111. 				cell.innerHTML="<span id='Helper:AllyEnemyListPlaceholder'></span>";
  10112. 				Helper.retrieveAllyEnemyData(false);
  10113. 			}
  10114. 		}
  10115. 	},
  10116.  
  10117. 	retrieveAllyEnemyData: function(refreshAllyEnemyDataOnly) {
  10118. 		var contactList = System.getValueJSON("contactList");
  10119. 		var allyEnemyOnlineRefreshTime = GM_getValue("allyEnemyOnlineRefreshTime");
  10120. 		allyEnemyOnlineRefreshTime *= 1000;
  10121. 		if (contactList) {
  10122. 			if ((new Date()).getTime() - contactList.lastUpdate.getTime() > allyEnemyOnlineRefreshTime) contactList = null; // invalidate cache
  10123. 		}
  10124.  
  10125. 		if (!contactList || refreshAllyEnemyDataOnly) {
  10126. 			System.xmlhttp("index.php?cmd=profile", Helper.parseProfileForWorld, refreshAllyEnemyDataOnly);
  10127. 		} else {
  10128. 			contactList = System.getValueJSON("contactList");
  10129. 			contactList.isRefreshed = false;
  10130. 			Helper.injectAllyEnemyList(contactList);
  10131. 		}
  10132. 	},
  10133.  
  10134. 	parseProfileForWorld: function(details, refreshAllyEnemyDataOnly) {
  10135. 		var doc=System.createDocument(details);
  10136. 		var alliesTable = System.findNode("//div[strong[.='Allies']]/following-sibling::div[1]/table[1]",doc);
  10137. 		var enemiesTable = System.findNode("//div[strong[.='Enemies']]/following-sibling::div[1]/table[1]",doc);
  10138. 		var contactList = System.getValueJSON("contactList");
  10139. 		if (!contactList) {
  10140. 			contactList = {};
  10141. 			contactList.contacts = [];
  10142. 		}
  10143. 		contactList.contacts.forEach(function(e) {e.status="Deleted";});
  10144. 		if (alliesTable && enemiesTable) {
  10145. 			var alliesDetails=alliesTable.getElementsByTagName("TABLE");
  10146.  
  10147. 			for (i=0;i<alliesDetails.length;i++) {
  10148. 				var aTable = alliesDetails[i];
  10149. 				var contactLink   = aTable.rows[0].cells[1].firstChild;
  10150. 				var contactId     = System.intValue((/[0-9]+$/).exec(contactLink.getAttribute("href"))[0]);
  10151. 				var contactName   = contactLink.textContent;
  10152. 				var contactStatus = aTable.rows[0].cells[0].firstChild.title;
  10153.  
  10154. 				var aContact;
  10155.  
  10156. 				// find contact in contact list, to modify data instead of replacing it
  10157.  
  10158. 				var findContacts = contactList.contacts.filter(function (e) {return e.id==contactId;});
  10159. 				if (findContacts.length>0) {
  10160. 					aContact = findContacts[0];
  10161. 				}
  10162. 				else { // contact was not found, must be new
  10163. 					aContact = {};
  10164. 					// You can still modify an object, even if you have added it to something else
  10165. 					contactList.contacts.push(aContact);
  10166. 					aContact.firstSeen = new Date();
  10167. 					aContact.status = "Offline"; // new players are supposed to be offline
  10168. 				}
  10169.  
  10170. 				if (aContact.status == "Offline" && contactStatus=="Online") {
  10171. 					aContact.loggedInAt = new Date();
  10172. 				}
  10173.  
  10174. 				if (!aContact.loggedInAt) {
  10175. 					aContact.loggedInAt = new Date();
  10176. 				}
  10177.  
  10178. 				aContact.status = contactStatus;
  10179. 				aContact.id     = contactId;
  10180. 				aContact.name   = contactName;
  10181. 				aContact.type   = "Ally";
  10182. 			}
  10183. 			var enemiesDetails=enemiesTable.getElementsByTagName("TABLE");
  10184.  
  10185. 			for (i=0;i<enemiesDetails.length;i++) {
  10186. 				aTable = enemiesDetails[i];
  10187. 				contactLink   = aTable.rows[0].cells[1].firstChild;
  10188. 				contactId     = System.intValue((/[0-9]+$/).exec(contactLink.getAttribute("href"))[0]);
  10189. 				contactName   = contactLink.textContent;
  10190. 				contactStatus = aTable.rows[0].cells[0].firstChild.title;
  10191.  
  10192. 				aContact;
  10193.  
  10194. 				// find contact in contact list, to modify data instead of replacing it
  10195.  
  10196. 				findContacts = contactList.contacts.filter(function (e) {return e.id==contactId;});
  10197. 				if (findContacts.length>0) {
  10198. 					aContact = findContacts[0];
  10199. 				}
  10200. 				else { // contact was not found, must be new
  10201. 					aContact = {};
  10202. 					// You can still modify an object, even if you have added it to something else
  10203. 					contactList.contacts.push(aContact);
  10204. 					aContact.firstSeen = new Date();
  10205. 					aContact.status = "Offline"; // new players are supposed to be offline
  10206. 				}
  10207.  
  10208. 				if (aContact.status == "Offline" && contactStatus=="Online") {
  10209. 					aContact.loggedInAt = new Date();
  10210. 				}
  10211.  
  10212. 				if (!aContact.loggedInAt) {
  10213. 					aContact.loggedInAt = new Date();
  10214. 				}
  10215.  
  10216. 				aContact.status = contactStatus;
  10217. 				aContact.id     = contactId;
  10218. 				aContact.name   = contactName;
  10219. 				aContact.type   = "Enemy";
  10220. 			}
  10221. 			// remove not existing players
  10222. 			contactList.contacts = contactList.contacts.filter(function(e) {return e.status!="Deleted";});
  10223. 			// damn, I love javascript array functions :)
  10224.  
  10225. 			contactList.lastUpdate = new Date();
  10226. 			contactList.isRefreshed = true;
  10227. 			System.setValueJSON("contactList", contactList);
  10228. 			if (!refreshAllyEnemyDataOnly) Helper.injectAllyEnemyList(contactList);
  10229. 		}
  10230. 	},
  10231.  
  10232. 	injectAllyEnemyList: function(contactList) {
  10233. 		enableAllyOnlineList = GM_getValue("enableAllyOnlineList");
  10234. 		enableEnemyOnlineList = GM_getValue("enableEnemyOnlineList");
  10235. 		if (!enableAllyOnlineList && !enableEnemyOnlineList) {return;}
  10236. 		var onlineAlliesEnemies = contactList.contacts.filter(function (e) {return (e.status=="Online");});
  10237. 		if (!enableAllyOnlineList) onlineAlliesEnemies = onlineAlliesEnemies.filter(function (e) {return (e.type!="Ally");});
  10238. 		if (!enableEnemyOnlineList) onlineAlliesEnemies = onlineAlliesEnemies.filter(function (e) {return (e.type!="Enemy");});
  10239. 		if (onlineAlliesEnemies.length === 0) {return;}
  10240. 		var playerId = Layout.playerId();
  10241. 		var injectHere = document.getElementById("Helper:AllyEnemyListPlaceholder");
  10242. 		var displayList = document.createElement("TABLE");
  10243. 		displayList.style.border = "1px solid #c5ad73";
  10244. 		displayList.style.backgroundColor = (contactList.isRefreshed)?"#6a5938":"#4a3918";
  10245. 		displayList.cellPadding = 3;
  10246. 		displayList.width = 125;
  10247.  
  10248. 		var aRow=displayList.insertRow(displayList.rows.length);
  10249. 		var aCell=aRow.insertCell(0);
  10250. 		output = '<center><font color="white"><b>Allies/Enemies</b></font><br/><font color="white" size=1><i><b>Online Contacts</b> <span id="Helper:resetAllyEnemyList" style="color:blue; font-size:8px; cursor:pointer; text-decoration:underline;">Reset</span></i></font></center>'+
  10251. 		'<table width="110" cellpadding="0" cellspacing="0"><tbody>'+
  10252. 			'<tr><td colspan="2" height="5"></td></tr>';
  10253.  
  10254. 		for (var i=0;i<onlineAlliesEnemies.length;i++) {
  10255. 			var contact=onlineAlliesEnemies[i];
  10256. 			var contactColor = "";
  10257. 			if (((new Date()) - contact.loggedInAt) < 30000) { // just logged in
  10258. 				contactColor = "orange";
  10259. 			}
  10260. 			else if (contact.type == "Ally") {
  10261. 				contactColor = "DodgerBlue";
  10262. 			}
  10263. 			else if (contact.type == "Enemy") {
  10264. 				contactColor = "red";
  10265. 			}
  10266. 			else {
  10267. 				contactColor = "white";
  10268. 			}
  10269. 			output +=
  10270. 				'<tr>'+
  10271. 					'<td align="left">'+
  10272. 						'<span style="color:' + contactColor + '; font-size:x-small; visibility:hidden;">+</span>'+
  10273. 						'<a style="color:' + contactColor + '; font-size:x-small;" href="index.php?cmd=profile&player_id=' + contact.id + '">' + contact.name + '</a>'+
  10274. 					'</td>'+
  10275. 					'<td align="right"><span style="color:#FFFF00; font-size:x-small;">'+
  10276. 						'<a href="index.php?cmd=message&target_player=' + contact.name + '" onmouseover="tt_setWidth(100); Tip(\'Send Message\')"><font color="#FFFF00">M</font></a>'+
  10277. 						'&nbsp;<a href="javascript:openWindow(\'index.php?cmd=quickbuff&t=' + contact.name + '\', \'fsQuickBuff\', 618, 1000, \',scrollbars\');" onmouseover="tt_setWidth(100); Tip(\'Quick Buff\')"><font color="#FFFF00">B</font></a>'+
  10278. 						'&nbsp;<a href="index.php?cmd=trade&subcmd=createsecure&target_username=' + contact.name + '" onmouseover="tt_setWidth(100); Tip(\'Secure Trade\')"><font color="#FFFF00">S</font></a>'+
  10279. 						'&nbsp;<a href="index.php?cmd=trade&target_player=' + contact.name + '" onmouseover="tt_setWidth(100); Tip(\'Send to Player\')"><font color="#FFFF00">T</font></a>'+
  10280. 					'</span></td>'+
  10281. 				'</tr>';
  10282. 		}
  10283. 		output += '</tbody></table>';
  10284.  
  10285.  
  10286. 		aCell.innerHTML = output;
  10287. 		injectHere.parentNode.align = 'center';
  10288. 		injectHere.parentNode.width = '120';
  10289.  
  10290. 		var breaker=document.createElement("BR");
  10291. 		injectHere.parentNode.insertBefore(breaker, injectHere.nextSibling);
  10292. 		injectHere.parentNode.insertBefore(displayList, injectHere.nextSibling);
  10293. 		document.getElementById('Helper:resetAllyEnemyList').addEventListener('click', Helper.resetAllyEnemyList, true);
  10294. 	},
  10295.  
  10296. 	resetAllyEnemyList: function(evt) {
  10297. 		GM_setValue("contactList","");
  10298. 		window.location = window.location;
  10299. 	},
  10300.  
  10301. 	injectCreateAuctionBulkSell: function() {
  10302. 		if (window.location.search.search("inv_id") == -1) {return;}
  10303. 		var enableBulkSell = GM_getValue("enableBulkSell");
  10304. 		if (!enableBulkSell) {return;}
  10305.  
  10306. 		var auctionTable = System.findNode("//table[tbody/tr/td/a[@href='index.php?cmd=auctionhouse&subcmd=create']]");
  10307. 		if (!auctionTable) {return;}
  10308.  
  10309. 		var newRow = auctionTable.insertRow(11);
  10310. 		var newCell = newRow.insertCell(0);
  10311. 		newCell.innerHTML = "&nbsp;";
  10312. 		newRow = auctionTable.insertRow(12);
  10313. 		newCell = newRow.insertCell(0);
  10314. 		newCell.colSpan = 2;
  10315. 		newCell.align = "center";
  10316.  
  10317. 		var textResult = "<table cellspacing='0' cellpadding='0' bordercolor='#000000'" +
  10318. 				" border='0' align='center' width='550' style='border-style: solid; border-width: 1px;'>" +
  10319. 				"<tr><td bgcolor='#cd9e4b'><center>Bulk Auction List</center></td></tr>" +
  10320. 				"<tr><td align='center'><table cellspacing='10' cellpadding='0' border='0' width='100%' style='border-style: solid; border-width: 1px;'>" +
  10321. 				"<tr><th bgcolor='#cd9e4b'>Length</th><th bgcolor='#cd9e4b'>Currency</th>"+
  10322. 				"<th bgcolor='#cd9e4b'>Min Bid</th><th bgcolor='#cd9e4b'>Buy Now</th>"+
  10323. 				"<th></th></tr>";
  10324.  
  10325. 			textResult += "<tr align='right'>"+
  10326. 				"<td><select id='Helper:bulkSellAuctionLength'><option value='0' selected>1 Hour</option><option value='1' >2 Hours</option>"+
  10327. 					"<option value='2' >4 Hours</option><option value='3' >8 Hours</option><option value='4' >12 Hours</option>"+
  10328. 					"<option value='5' >24 Hours</option><option value='6' >48 Hours</option></select></td>"+
  10329. 				"<td><select id='Helper:bulkSellAuctionCurrency'><option value='0' >Gold</option><option value='1' selected>FSP</option></select></td>"+
  10330. 				"<td><input type='text' class='custominput' size='6' id='Helper:bulkSellMinBid'/></td>"+
  10331. 				"<td><input type='text' class='custominput' size='6' id='Helper:bulkSellBuyNow'/></td>"+
  10332. 				"<td>[<span style='cursor:pointer; text-decoration:underline; color:blue;' "+
  10333. 					"id='Helper:bulkListAll'>bulk list all</span>]</td></tr>";
  10334.  
  10335. 		textResult += "</table></td></tr>";
  10336.  
  10337. 		textResult += "<tr><td align='center'><table id='Helper:CreateAuctionBulkSellTable' cellspacing='10' cellpadding='0' border='0' width='100%'";
  10338.  
  10339. 		textResult += "</table></td></tr>";
  10340.  
  10341. 		textResult += "</table>";
  10342.  
  10343. 		newCell.innerHTML = textResult;
  10344.  
  10345. 		var itemStats = /inv_id=(\d+)&item_id=(\d+)/.exec(window.location.search);
  10346. 		var invID = itemStats[1];
  10347. 		var itemID = itemStats[2];
  10348. 		var xmlhttpAddress;
  10349.  
  10350. 		if (GM_getValue("bulkSellAllBags")) {
  10351. 			xmlhttpAddress = "index.php?cmd=guild&subcmd=inventory&subcmd2=storeitems";
  10352. 		} else {
  10353. 			xmlhttpAddress = "index.php?cmd=auctionhouse&subcmd=create";
  10354. 		}
  10355. 		System.xmlhttp(xmlhttpAddress, Helper.processAuctionBulkSellItems, {"itemID":itemID,"invID":invID});
  10356. 		document.getElementById('Helper:bulkListAll').addEventListener('click', Helper.bulkListAll, true);
  10357. 	},
  10358.  
  10359. 	processAuctionBulkSellItems: function(responseText, callback) {
  10360. 		var originalItemID = callback.itemID;
  10361. 		var originalInvID = callback.invID;
  10362.  
  10363. 		var bulkSellTable = System.findNode("//table[@id='Helper:CreateAuctionBulkSellTable']");
  10364.  
  10365. 		var doc=System.createDocument(responseText);
  10366. 		var bulkAuctionItemIMGs = System.findNodes("//img[contains(@src,'items/"+originalItemID+".gif')]", doc);
  10367. 		if (!bulkAuctionItemIMGs) {return;}
  10368. 		var maxAuctions = GM_getValue("maxAuctions");
  10369. 		if (!maxAuctions) maxAuctions = 2;
  10370.  
  10371. 		for (var i=0;i<bulkAuctionItemIMGs.length;i++) {
  10372. 			var bulkItemIMG = bulkAuctionItemIMGs[i];
  10373. 			if (!GM_getValue("bulkSellAllBags")) {
  10374. 				bulkItemIMG = bulkItemIMG.parentNode;
  10375. 			}
  10376. 			var bulkItemMouseover = bulkItemIMG.getAttribute("onmouseover");
  10377. 			var itemStats = /ajaxLoadItem\((\d+), (\d+), (\d+), (\d+)/.exec(bulkItemMouseover);
  10378. 			var itemId = itemStats[1];
  10379. 			var invId = itemStats[2];
  10380. 			var type = itemStats[3];
  10381. 			var pid = itemStats[4];
  10382. 			if ((i % 3 === 0)) newRow = bulkSellTable.insertRow(-1);
  10383. 			//var newRow = bulkSellTable.insertRow(-1);
  10384. 			var newCell = newRow.insertCell(-1);
  10385. 			newCell.style.vAlign = "middle";
  10386. 			newCell.innerHTML = '<img src="'+System.imageServerHTTP+'/items/'+itemId+'.gif" border=0 ' +
  10387. 				'onmouseover="ajaxLoadItem('+itemId+', '+invId+', '+type+', '+pid+', \'\');">';
  10388. 			newCell = newRow.insertCell(-1);
  10389. 			newCell.style.vAlign = "middle";
  10390. 			newCell.innerHTML = '<span id="Helper:bulkListSingle'+invId+'" itemInvId="'+invId+'" style="cursor:pointer; text-decoration:underline; color:blue;">auction single</span>';
  10391. 			document.getElementById('Helper:bulkListSingle'+invId).addEventListener('click', Helper.bulkListSingle, true);
  10392. 			if ((i+2) > maxAuctions && (i+1) != bulkAuctionItemIMGs.length) {
  10393. 				var newRow = bulkSellTable.insertRow(-1);
  10394. 				newCell = newRow.insertCell(0);
  10395. 				newCell.colSpan = 4;
  10396. 				var newText = "You only have " + maxAuctions + " auction slots.";
  10397. 				if (maxAuctions == 2) {
  10398. 					newText += " Check the updates page to add more (or to fix this number if you think it is wrong)";
  10399. 				}
  10400. 				newCell.innerHTML = newText;
  10401. 				break;
  10402. 			}
  10403. 		}
  10404. 	},
  10405.  
  10406. 	bulkListAll: function() {
  10407. 		var bulkSellAuctionLength = System.findNode("//select[@id='Helper:bulkSellAuctionLength']");
  10408. 		var bulkSellAuctionCurrency = System.findNode("//select[@id='Helper:bulkSellAuctionCurrency']");
  10409. 		var bulkSellAuctionMinBid = System.findNode("//input[@id='Helper:bulkSellMinBid']");
  10410. 		var bulkSellAuctionBuyNow = System.findNode("//input[@id='Helper:bulkSellBuyNow']");
  10411.  
  10412. 		var potentialAuctions = System.findNodes("//span[contains(@id,'Helper:bulkListSingle')]");
  10413. 		for (var i=0;i<potentialAuctions.length;i++) {
  10414. 			var potentialAuction = potentialAuctions[i];
  10415. 			var invID = /Helper:bulkListSingle(\d+)/.exec(potentialAuction.getAttribute("id"))[1];
  10416. 			var bulkSellHref = System.server + "index.php?cmd=auctionhouse&subcmd=docreate&inv_id=" + invID +
  10417. 				"&auction_length=" + bulkSellAuctionLength.value + "&currency=" + bulkSellAuctionCurrency.value +
  10418. 				"&minbid=" + bulkSellAuctionMinBid.value + "&buynow=" + bulkSellAuctionBuyNow.value;
  10419. 			System.xmlhttp(bulkSellHref,
  10420. 				Helper.bulkListSingleReturnMessage,
  10421. 				{"target": potentialAuction});
  10422. 		}
  10423. 	},
  10424.  
  10425. 	bulkListSingle: function(evt) {
  10426. 		var itemInvId = evt.target.getAttribute("itemInvId");
  10427. 		var bulkSellAuctionLength = System.findNode("//select[@id='Helper:bulkSellAuctionLength']");
  10428. 		var bulkSellAuctionCurrency = System.findNode("//select[@id='Helper:bulkSellAuctionCurrency']");
  10429. 		var bulkSellAuctionMinBid = System.findNode("//input[@id='Helper:bulkSellMinBid']");
  10430. 		var bulkSellAuctionBuyNow = System.findNode("//input[@id='Helper:bulkSellBuyNow']");
  10431.  
  10432. 		var bulkSellHref = System.server + "index.php?cmd=auctionhouse&subcmd=docreate&inv_id=" + itemInvId +
  10433. 			"&auction_length=" + bulkSellAuctionLength.value + "&currency=" + bulkSellAuctionCurrency.value +
  10434. 			"&minbid=" + bulkSellAuctionMinBid.value + "&buynow=" + bulkSellAuctionBuyNow.value;
  10435. 		System.xmlhttp(bulkSellHref,
  10436. 			Helper.bulkListSingleReturnMessage,
  10437. 			{"target": evt.target, "url": bulkSellHref});
  10438. 	},
  10439.  
  10440. 	bulkListSingleReturnMessage: function(responseText, callback) {
  10441. 		var target = callback.target;
  10442. 		var info = Layout.infoBox(responseText);
  10443. 		if (info.search("Auction placed successfully!") != -1) {
  10444. 			target.style.color = 'green';
  10445. 			target.style.fontWeight = 'bold';
  10446. 			target.style.fontSize = 'small';
  10447. 			target.innerHTML = "Auction Listed";
  10448. 		} else if (info!=="") {
  10449. 			target.style.color = 'red';
  10450. 			target.style.fontWeight = 'bold';
  10451. 			target.style.fontSize = 'small';
  10452. 			target.innerHTML = "Error: " + info;
  10453. 		} else {
  10454. 			target.style.color = 'red';
  10455. 			target.style.fontSize = 'small';
  10456. 			target.innerHTML = "Weird Error: check the Tools>Error Console";
  10457. 			GM_log("Post the previous HTML and the following message to the code.google.com site or to the forum to help us debug this error");
  10458. 			GM_log(callback.url);
  10459. 		}
  10460. 	},
  10461.  
  10462. 	toggleCheckAllItems: function(evt) {
  10463. 		var allItems=System.findNodes("//input[@type='checkbox']");
  10464. 		if (allItems) {
  10465. 			for (var i=0; i<allItems.length; i++) {
  10466. 				var checkboxForItem = allItems[i];
  10467. 				if (checkboxForItem.style.visibility == "hidden")
  10468. 					checkboxForItem.checked = false;
  10469. 				else {
  10470. 					if (checkboxForItem.checked) {
  10471. 						checkboxForItem.checked = false;
  10472. 					} else {
  10473. 						checkboxForItem.checked = true;
  10474. 					}
  10475. 				}
  10476. 			}
  10477. 		}
  10478. 	},
  10479.  
  10480. 	toggleCheckAllPlants: function(evt) {
  10481. 		var plantRE = new RegExp(evt.target.getAttribute("plantRE"));
  10482. 		var allItems = System.findNodes("//input[@type='checkbox']");
  10483. 		if (allItems) {
  10484. 			for (var i = 0; i < allItems.length; i++){
  10485. 				var theImgNode = allItems[i].parentNode.parentNode.previousSibling.firstChild.firstChild.firstChild;
  10486. 				System.xmlhttp(Helper.linkFromMouseover(theImgNode.getAttribute("onmouseover")),
  10487. 					function (responseText, callBack) {
  10488. 						var checkbox = callBack.parentNode.parentNode.parentNode.nextSibling.firstChild.firstChild;
  10489.  
  10490. 						if (plantRE.exec(responseText)) {
  10491. 							if (checkbox.checked)
  10492. 								checkbox.checked = false;
  10493. 							else
  10494. 								checkbox.checked = true;
  10495. 						}
  10496. 					},
  10497. 					theImgNode);
  10498.  
  10499. 			}
  10500. 		}
  10501. 	},
  10502.  
  10503. 	injectStandardTrade: function() {
  10504. 		var mainTable = System.findNodes("//table[@width='300']");
  10505. 		if (mainTable[2]) {
  10506. 			var td=mainTable[2].parentNode;
  10507. 			td.innerHTML = '<form method="post" action="index.php" name="sendItemForm">'+
  10508. 				td.innerHTML.replace('<form method="post" action="index.php" name="sendItemForm"></form>','')+
  10509. 				'</form>'; // fixing HCS coding style (<table><form><tr>  --> <form><table><tr>)
  10510. 			mainTable = System.findNodes("//table[@width='300']");
  10511. 			var newRow = mainTable[2].insertRow(mainTable[2].rows.length - 1);
  10512. 			var newCellAll = newRow.insertCell(0);
  10513. 			newCellAll.colSpan = 3;
  10514. 			Helper.makeSelectAllInTrade(newCellAll);
  10515. 		}
  10516. 	},
  10517.  
  10518. 	injectSecureTrade: function() {
  10519. 		var mainTable = System.findNode("//table[@width='300']");
  10520. 		if (mainTable) {
  10521. 			var td=mainTable.parentNode;
  10522. 			td.innerHTML = '<form method="post" action="index.php" name="createOffer" onsubmit="if(confirm(\'Are you sure you wish send this offer?\')) return true; else return false;">'+
  10523. 				td.innerHTML.replace('<form method="post" action="index.php" name="createOffer" onsubmit="if(confirm(\'Are you sure you wish send this offer?\')) return true; else return false;"></form>','')+
  10524. 				'</form>'; // fixing HCS coding style (<table><form><tr>  --> <form><table><tr>)
  10525. 			mainTable = System.findNode("//table[@width='300']");
  10526. 			var newRow = mainTable.insertRow(mainTable.rows.length - 5);
  10527. 			var newCellAll = newRow.insertCell(0);
  10528. 			newCellAll.colSpan = 3;
  10529. 			Helper.makeSelectAllInTrade(newCellAll);
  10530. 		}
  10531. 	},
  10532.  
  10533. 	makeSelectAllInTrade: function(injectHere) { // currently reuse FSH code, this should be changed to SS2H code which is cleaner
  10534. 		injectHere.innerHTML += 'Check: &ensp<span style="cursor:pointer; text-decoration:underline;" id="Helper:checkAllItems">' +
  10535. 			'All Items</span> &ensp ' +
  10536.  
  10537. 			'<span plantRE="Heffle|Trinettle|Blood Bloom|Jademare|DarkShade" style="cursor:pointer; text-decoration:underline;"' +
  10538. 			'id="Helper:checkAllPlants">All Plants</span> &ensp ' +
  10539.  
  10540. 			'<span plantRE="Heffle" style="cursor:pointer; text-decoration:underline;" id="Helper:checkAllHeffle">' +
  10541. 			'Heffle</span> &ensp ' +
  10542.  
  10543. 			'<span plantRE="Trinettle" style="cursor:pointer; text-decoration:underline;" id="Helper:checkAllTrinettle">' +
  10544. 			'Trinettle</span>\f &emsp &emsp &ensp &ensp' +
  10545.  
  10546. 			'<span plantRE="Blood Bloom" style="cursor:pointer; text-decoration:underline;" id="Helper:checkAllBloom">' +
  10547. 			'Blood Bloom</span> &ensp' +
  10548.  
  10549. 			'<span plantRE="Jademare" style="cursor:pointer; text-decoration:underline;" id="Helper:checkAllJade">' +
  10550. 			'Jademare</span> &ensp ' +
  10551.  
  10552. 			'<span plantRE="Dark Shade" style="cursor:pointer; text-decoration:underline;" id="Helper:checkAllShade">' +
  10553. 			'Dark Shade</span>' +
  10554.  
  10555. 			'<br/>From folders: <span id="Helper:getFolder">retrieving ...</span>';
  10556.  
  10557. 		document.getElementById("Helper:checkAllItems").addEventListener('click', Helper.toggleCheckAllItems, true);
  10558. 		document.getElementById("Helper:checkAllPlants").addEventListener('click', Helper.toggleCheckAllPlants, true);
  10559. 		document.getElementById("Helper:checkAllHeffle").addEventListener('click', Helper.toggleCheckAllPlants, true);
  10560. 		document.getElementById("Helper:checkAllTrinettle").addEventListener('click', Helper.toggleCheckAllPlants, true);
  10561. 		document.getElementById("Helper:checkAllBloom").addEventListener('click', Helper.toggleCheckAllPlants, true);
  10562. 		document.getElementById("Helper:checkAllJade").addEventListener('click', Helper.toggleCheckAllPlants, true);
  10563. 		document.getElementById("Helper:checkAllShade").addEventListener('click', Helper.toggleCheckAllPlants, true);
  10564.  
  10565. 		System.xmlhttp("index.php?cmd=profile&subcmd=dropitems&fromworld=1", Helper.getFolderName2Trade, true);
  10566. 	},
  10567.  
  10568. 	getFolderName2Trade: function(responseText) {
  10569. 		var doc=System.createDocument(responseText);
  10570. 		var otherFolders = System.findNodes("//td/center/a/img[contains(@src,'/folder.gif')]",doc);
  10571. 		var newHtml='<span id="Folder-2" fid=-2 style="cursor:pointer; text-decoration:underline;">All</span> '+
  10572. 			'<span id="Folder-1" fid=-1 style="cursor:pointer; text-decoration:underline;">Main</span> ';
  10573. 		for (var i=0; i<otherFolders.length; i++) {
  10574. 			//GM_log(otherFolders[i].parentNode.getAttribute("href").match(/cmd=profile&subcmd=dropitems&folder_id=(\d+)/i)[1]);
  10575. 			newHtml+='<span id="Folder'+i+'" fid='+
  10576. 				otherFolders[i].parentNode.getAttribute("href").match(/cmd=profile&subcmd=dropitems&folder_id=(-*\d+)/i)[1]+
  10577. 				' style="cursor:pointer; text-decoration:underline;">'+
  10578. 				otherFolders[i].parentNode.parentNode.textContent+'</span> ';
  10579. 		}
  10580. 		document.getElementById("Helper:getFolder").innerHTML=newHtml;
  10581. 		for (var i=-2; i<otherFolders.length; i++) {
  10582. 			document.getElementById("Folder"+i).addEventListener('click', Helper.getFolderContent2Trade, true);
  10583. 		}
  10584. 	},
  10585.  
  10586. 	getFolderContent2Trade: function(evt) {
  10587. 		var fid=evt.target.getAttribute('fid');
  10588. 		if (fid==-2)
  10589. 			window.location.reload();
  10590. 		else
  10591. 			System.xmlhttp('index.php?cmd=profile&subcmd=dropitems&folder_id='+fid, function(responseText) {
  10592. 				var table=System.findNode('//td[@colspan=3 or @colspan=2]/table[@cellspacing=8]');
  10593. 				var newHtml = '<table cellspacing="8" cellpadding="0" border="0" align="center"><tbody><tr>';
  10594. 				var doc=System.createDocument(responseText);
  10595. 				Helper.itemList = {};
  10596. 				Helper.retrieveItemInfor(doc);
  10597. 				var counter = 0;
  10598. 				for (var key in Helper.itemList) {
  10599. 					newHtml+='<td align="center"><table cellspacing="0" cellpadding="0" border="0"><tbody><tr>'+
  10600. 						'<td background="http://72.29.91.222/inventory/2x3.gif" width="60" height="90">'+
  10601. 						Helper.itemList[key].html.match(/(<center><img [^>]*><\/center>)/)[1]+
  10602. 						'</td></tr><tr><td align="center"><input type="checkbox" name="sendItemList[]" value="'+Helper.itemList[key].id+'"></td></tr></tbody></table></td>';
  10603. 					counter++;
  10604. 					if (counter % 6 == 0) newHtml+='</tr><tr>';
  10605. 				}
  10606. 				newHtml+='</tr></tbody></table>';
  10607. 				table.innerHTML = newHtml;
  10608. 			});
  10609. 	},
  10610.  
  10611. 	makePageHeader: function(title, comment, spanId, button) {
  10612. 		return '<table width=100%><tr style="background-color:#CD9E4B">'+
  10613. 			'<td width="90%" nobr><b>&nbsp;'+title+'</b>'+
  10614. 			(comment===''?'':'&nbsp;('+comment+')')+
  10615. 			'<td width="10%" nobr style="font-size:x-small;text-align:right">'+
  10616. 			(spanId?'[<span style="text-decoration:underline;cursor:pointer;" id="'+spanId+'">'+button+'</span>]':'')+
  10617. 			'</td></tr></table>';
  10618. 	},
  10619. 	makePageHeaderTwo: function(title, comment, spanId, button, spanId2, button2) {
  10620. 		return '<table width=100%><tr style="background-color:#CD9E4B">'+
  10621. 			'<td width="90%" nobr><b>&nbsp;'+title+'</b>'+
  10622. 			(comment===''?'':'&nbsp;('+comment+')')+
  10623. 			'<td width="10%" nobr style="font-size:x-small;text-align:right">'+
  10624. 			(spanId?'[<span style="text-decoration:underline;cursor:pointer;" id="'+spanId+'">'+button+'</span>]':'')+
  10625. 			(spanId2?'[<span style="text-decoration:underline;cursor:pointer;" id="'+spanId2+'">'+button2+'</span>]':'')+
  10626. 			'</td></tr></table>';
  10627. 	},
  10628. 	makePageTemplate: function(title, comment, spanId, button, divId) {
  10629. 		return Helper.makePageHeader(title, comment, spanId, button)+
  10630. 			'<div style="font-size:small;" id="'+divId+'"></div>';
  10631. 	},
  10632.  
  10633. 	injectAttackPlayer: function() {
  10634. 		var b = System.findNode("//input[contains(@value, 'Activate!')]");
  10635. 		if (b !== null) {
  10636. 			var oldOnclick = b.getAttribute("onClick");
  10637. 			b.setAttribute("onClick", "if (confirm('Are you sure you want to activate PvP Prestige?')) { " + oldOnclick + "}");
  10638. 		}
  10639. 		if (!GM_getValue("enableAttackHelper")) {return;}
  10640. 		//inject current stats, buffs and equipment
  10641. 		var attackPlayerTable = System.findNode("//table[tbody/tr/td/font/b[.='Attack Player (PvP)']]");
  10642. 		if (!attackPlayerTable) {return;}
  10643. 		var targetPlayer = /target_username=([a-zA-Z0-9]+)/.exec(location.search);
  10644. 		if (targetPlayer) {
  10645. 			var output = "<center><table width='550' cellspacing='0' cellpadding='0' bordercolor='#000000' border='0' style='border-style: solid; border-width: 1px;'><tbody>";
  10646. 			output += "<tr style='text-align:center;' bgcolor='#cd9e4b'><td width='275' style='border-style: solid; border-width: 1px;'>Attacker</td><td width='275' style='border-style: solid; border-width: 1px;'>Defender</td></tr>";
  10647. 			output += "<tr style='text-align:center;'><td style='border-style: solid; border-width: 1px;'><span id='Helper:attackPlayerSelfStatData'><font color='green'>Gathering your stats ...</font></span></td>"+
  10648. 				"<td style='border-style: solid; border-width: 1px;'><span id='Helper:attackPlayerDefenderStatData'><font color='green'>Gathering defender stats ...</font></span></td></tr>";
  10649. 			output += "<tr style='text-align:center;'><td style='border-style: solid; border-width: 1px;'><span id='Helper:attackPlayerSelfBuffData'><font color='green'>Gathering your buffs ...</font></span></td>" +
  10650. 				"<td style='border-style: solid; border-width: 1px;'><span id='Helper:attackPlayerDefenderBuffData'><font color='green'>Gathering defender buffs ...</font></span></td></tr>";
  10651. 			output += "</tbody></table><center>";
  10652.  
  10653. 			attackPlayerTable.rows[4].cells[0].innerHTML = output;
  10654. 			//System.xmlhttp("index.php?cmd=profile", Helper.getSelfProfileStatsAndBuffs);
  10655. 			System.xmlhttp("index.php?cmd=profile", Helper.getProfileStatsAndBuffs, {"anchor1":"attackPlayerSelfStatData","anchor2":"attackPlayerSelfBuffData"});
  10656. 			System.xmlhttp("index.php?cmd=findplayer&search_active=1&search_username="+targetPlayer[1]+"&search_show_first=1", Helper.getProfileStatsAndBuffs, {"anchor1":"attackPlayerDefenderStatData","anchor2":"attackPlayerDefenderBuffData"});
  10657. 			//insert blank row
  10658. 			var newRow = attackPlayerTable.insertRow(5);
  10659. 			var newCell = newRow.insertCell(0);
  10660. 			newCell.innerHTML = "&nbsp;";
  10661. 		}
  10662. 	},
  10663.  
  10664. 	getProfileStatsAndBuffs: function(responseText, callback) {
  10665. 		var doc = System.createDocument(responseText);
  10666. 		//stats
  10667. 		var vlTextElement = System.findNode("//td[b[contains(.,'VL')]]", doc);
  10668. 		var vlValueElement = vlTextElement.nextSibling;
  10669. 		var pvpTextElement = System.findNode("//td[b[contains(.,'PvP')]]", doc);
  10670. 		var pvpValueElement = pvpTextElement.nextSibling;
  10671. 		var attackTextElement = System.findNode("//td[b[contains(.,'Attack:')]]", doc);
  10672. 		var attackValueElement = attackTextElement.nextSibling;
  10673. 		var defenseTextElement = System.findNode("//td[b[contains(.,'Defense:')]]", doc);
  10674. 		var defenseValueElement = defenseTextElement.nextSibling;
  10675. 		var armorTextElement = System.findNode("//td[b[contains(.,'Armor:')]]", doc);
  10676. 		var armorValueElement = armorTextElement.nextSibling;
  10677. 		var damageTextElement = System.findNode("//td[b[contains(.,'Damage:')]]", doc);
  10678. 		var damageValueElement = damageTextElement.nextSibling;
  10679. 		var hpTextElement = System.findNode("//td[b[contains(.,'HP:')]]", doc);
  10680. 		var hpValueElement = hpTextElement.nextSibling;
  10681. 		var goldTextElement = System.findNode("//td[b[contains(.,'Gold:')]]", doc);
  10682. 		var goldValueElement = goldTextElement.nextSibling;
  10683. 		var output = "<table width='100%'><tbody>";
  10684. 		output += "<tr><td width='25%' style='text-align:right;'>" + vlTextElement.innerHTML + "</td><td width='25%' style='text-align:left;'>" + vlValueElement.innerHTML + "</td>" +
  10685. 			"<td width='25%' style='text-align:right;'>" + pvpTextElement.innerHTML + "</td><td width='25%' style='text-align:left;'>" + pvpValueElement.innerHTML + "</td></tr>";
  10686. 		output += "<tr><td width='25%' style='text-align:right;'>" + attackTextElement.innerHTML + "</td><td width='25%' style='text-align:left;'>" + attackValueElement.innerHTML + "</td>" +
  10687. 			"<td width='25%' style='text-align:right;'>" + defenseTextElement.innerHTML + "</td><td width='25%' style='text-align:left;'>" + defenseValueElement.innerHTML + "</td></tr>";
  10688. 		output += "<tr><td width='25%' style='text-align:right;'>" + armorTextElement.innerHTML + "</td><td width='25%' style='text-align:left;'>" + armorValueElement.innerHTML + "</td>" +
  10689. 			"<td width='25%' style='text-align:right;'>" + damageTextElement.innerHTML + "</td><td width='25%' style='text-align:left;'>" + damageValueElement.innerHTML + "</td></tr>";
  10690. 		output += "<tr><td width='25%' style='text-align:right;'>" + hpTextElement.innerHTML + "</td><td width='25%' style='text-align:left;'>" + hpValueElement.innerHTML + "</td>" +
  10691. 			"<td width='25%' style='text-align:right;'>" + goldTextElement.innerHTML + "</td><td width='25%' style='text-align:left;'>" + goldValueElement.innerHTML + "</td></tr>";
  10692. 		output += "</tbody></table>";
  10693. 		var anchor1 = callback.anchor1;
  10694. 		var injectHere = System.findNode("//span[@id='Helper:"+anchor1+"']");
  10695. 		injectHere.innerHTML = output;
  10696. 		//buffs
  10697. 		var activeBuffsTitleRow = System.findNode("//div[strong[.='Active Buffs']]", doc);
  10698. 		//fix to cover bad HTML by HCS.
  10699. 		if (!activeBuffsTitleRow) activeBuffsTitleRow = System.findNode("//div[b/b/strong[.='Active Buffs']]", doc);
  10700. 		var activeBuffsElement = activeBuffsTitleRow.nextSibling.nextSibling;
  10701. 		var anchor2 = callback.anchor2;
  10702. 		injectHere = System.findNode("//span[@id='Helper:"+anchor2+"']");
  10703. 		injectHere.innerHTML = activeBuffsElement.innerHTML;
  10704. 	},
  10705.  
  10706. 	injectScavenging: function() {
  10707. 		var injectHere=System.findNode("//b[contains(.,'Multiple Scavenging Results')]/..");
  10708. 		if (injectHere) { // multi scavenging
  10709. 			var victories=System.findNodes("//td[contains(.,'victorious')]");
  10710. 			if (victories) injectHere.innerHTML+="<br/>Victories: "+victories.length;
  10711. 			var defeats=System.findNodes("//td[contains(.,'defeated')]");
  10712. 			if (defeats) injectHere.innerHTML+=", Defeated: "+defeats.length;
  10713. 			var gains=System.findNodes("//td[contains(.,'Item Gained')]/b");
  10714. 			if (gains) {
  10715. 				injectHere.innerHTML+="<br/>"+gains.length+" item(s): ";
  10716. 				var gainHash={};
  10717. 				for (var i=0;i<gains.length;i++) {
  10718. 					if (gainHash[gains[i].textContent])
  10719. 						gainHash[gains[i].textContent]++;
  10720. 					else
  10721. 						gainHash[gains[i].textContent]=1;
  10722. 				}
  10723. 				for (var item in gainHash) {
  10724. 					injectHere.innerHTML+=gainHash[item]+" "+item+"(s), ";
  10725. 				}
  10726. 			}
  10727. 		}
  10728. 		System.xmlhttp("index.php?cmd=world", Helper.getBpCountFromWorld);
  10729. 	},
  10730.  
  10731. 	getBpCountFromWorld: function(responseText) {
  10732. 		// backpack counter
  10733. 		var doc=System.createDocument(responseText);
  10734. 		var bp=System.findNode("//td[a/img[contains(@src,'_manageitems.gif')]]",doc);
  10735. 		var injectHere=document.getElementById("reportDiv");
  10736. 		if (!injectHere) injectHere=System.findNode("//b[contains(.,'Multiple Scavenging Results')]/..");
  10737. 		injectHere.appendChild(bp);
  10738. 	},
  10739.  
  10740. 	getGroupBuffModifierWord: function(defenderIdx) {
  10741. 		var modifierWord = "";
  10742. 		switch (Math.ceil(( defenderIdx+1) / 16)) {
  10743. 			case 1:
  10744. 				modifierWord = "first";
  10745. 				break;
  10746. 			case 2:
  10747. 				modifierWord = "second";
  10748. 				break;
  10749. 			case 3:
  10750. 				modifierWord = "third";
  10751. 				break;
  10752. 			case 4:
  10753. 				modifierWord = "fourth";
  10754. 				break;
  10755. 			case 5:
  10756. 				modifierWord = "fifth";
  10757. 				break;
  10758. 			case 6:
  10759. 				modifierWord = "sixth";
  10760. 				break;
  10761. 			case 7:
  10762. 				modifierWord = "seventh";
  10763. 				break;
  10764. 			case 8:
  10765. 				modifierWord = "eighth";
  10766. 				break;
  10767. 			case 9:
  10768. 				modifierWord = "ninth";
  10769. 				break;
  10770. 			case 10:
  10771. 				modifierWord = "tenth";
  10772. 				break;
  10773. 			case 11:
  10774. 				modifierWord = "eleventh";
  10775. 				break;
  10776. 			case 12:
  10777. 				modifierWord = "twelfth";
  10778. 				break;
  10779. 			case 13:
  10780. 				modifierWord = "thirteenth";
  10781. 				break;
  10782. 			case 14:
  10783. 				modifierWord = "fourteenth";
  10784. 				break;
  10785. 			default:
  10786. 				modifierWord = "";
  10787. 				break;
  10788. 		}
  10789. 		return modifierWord;
  10790. 	},
  10791.  
  10792. 	injectJoinAllLink: function() {
  10793. 		var attackGroupLink = System.findNode("//td[a/font[.='A new guild attack group has been formed.']]");
  10794. 		if (attackGroupLink) {
  10795. 			if (!GM_getValue("enableMaxGroupSizeToJoin")) {
  10796. 				attackGroupLink.innerHTML += " <nobr><a href='index.php?cmd=guild&subcmd=groups&subcmd2=joinall'>"+
  10797. 					"<span style='color:yellow; font-size:x-small;'>[Join All]</span></a></nobr>";
  10798. 			} else {
  10799. 				var maxGroupSizeToJoin = GM_getValue("maxGroupSizeToJoin");
  10800. 				attackGroupLink.innerHTML += " <nobr><a href='index.php?cmd=guild&subcmd=groups&subcmd2=joinallgroupsundersize'>"+
  10801. 					"<span style='color:yellow; font-size:x-small;'>[Join < " + maxGroupSizeToJoin + "]</span></a></nobr>";
  10802. 			}
  10803. 		}
  10804. 	},
  10805.  
  10806. 	changeGuildLogHREF: function() {
  10807. 		if (!GM_getValue("useNewGuildLog")) return;
  10808. 		var guildLogNodes = System.findNodes('//a[@href="index.php?cmd=guild&subcmd=log"]');
  10809. 		if (guildLogNodes) {
  10810. 			for (i=0;i<guildLogNodes.length;i++) {
  10811. 				guildLogNode = guildLogNodes[i];
  10812. 				guildLogNode.setAttribute("href", "index.php?cmd=notepad&subcmd=newguildlog");
  10813. 			}
  10814. 			//hide the lhs box
  10815. 			if (location.search == "?cmd=notepad&subcmd=newguildlog" && guildLogNode.textContent == "You have unread guild log messages.") {
  10816. 				messageBox = guildLogNode.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode;
  10817. 				if (messageBox) {
  10818. 					messageBox.style.display = "none";
  10819. 					messageBox.style.visibility = "hidden";
  10820. 					//hide the empty row before it too (can't do after in case there is no after row)
  10821. 					messageBox.previousSibling.style.display = "none";
  10822. 					messageBox.previousSibling.style.visibility = "hidden";
  10823. 				}
  10824. 			}
  10825. 		}
  10826. 	},
  10827.  
  10828. 	injectGuildRanks: function() {
  10829. 		//update the guild member list and insert a list of members next to each rank
  10830. 		System.xmlhttp("index.php?cmd=guild&subcmd=manage", Helper.parseGuildForWorld, true);
  10831.  
  10832. 		var rankNameTable = System.findNode("//table[tbody/tr/td[.='Rank Name']]");
  10833. 		if (!rankNameTable) return;
  10834. 		var memberList = System.getValueJSON("memberlist");
  10835. 		if (memberList) {
  10836. 			for (i=0;i<memberList.members.length;i++) {
  10837. 				var member=memberList.members[i];
  10838. 				if (member.name.trim() == Helper.characterName.trim()) {
  10839. 					Helper.characterRank = member.rank;
  10840. 					break;
  10841. 				}
  10842. 			}
  10843. 			for (i=0;i<rankNameTable.rows.length;i++) {
  10844. 				aRow = rankNameTable.rows[i];
  10845. 				if (aRow.cells[1]) {
  10846. 					rankName = aRow.cells[0].textContent;
  10847. 					if (rankName.trim() == Helper.characterRank.trim()) {
  10848. 						Helper.characterRow = i;
  10849. 						break;
  10850. 					}
  10851. 				}
  10852. 			}
  10853. 		}
  10854.  
  10855. 		//gather rank info
  10856. 		var newRankElement = System.findNode("//td[a[@href='index.php?cmd=guild&subcmd=ranks&subcmd2=add']]");
  10857. 		newRankElement.innerHTML += '&nbsp;<input id="getrankweightings" type="button" value="Get Rank Weightings" class="custombutton">';
  10858.  
  10859. 		document.getElementById('getrankweightings').addEventListener('click', Helper.fetchRankData, true);
  10860.  
  10861. 		if (GM_getValue("ajaxifyRankControls")) {
  10862. 			//up buttons
  10863. 			var upButtons = System.findNodes("//input[@value='Up']");
  10864. 			for (i=0;i<upButtons.length;i++) {
  10865. 				upButton = upButtons[i];
  10866. 				onclickText = upButton.getAttribute("onclick");
  10867. 				onclickHREF = /window.location=\'(.*)\';/.exec(onclickText)[1];
  10868. 				upButton.setAttribute("onclickhref", onclickHREF);
  10869. 				upButton.setAttribute("onclick", "");
  10870. 				upButton.addEventListener('click', Helper.moveRankUpOneSlotOnScreen, true);
  10871. 			}
  10872. 			//down buttons
  10873. 			var downButtons = System.findNodes("//input[@value='Down']");
  10874. 			for (i=0;i<downButtons.length;i++) {
  10875. 				downButton = downButtons[i];
  10876. 				onclickText = downButton.getAttribute("onclick");
  10877. 				onclickHREF = /window.location=\'(.*)\';/.exec(onclickText)[1];
  10878. 				downButton.setAttribute("onclickhref", onclickHREF);
  10879. 				downButton.setAttribute("onclick", "");
  10880. 				downButton.addEventListener('click', Helper.moveRankDownOneSlotOnScreen, true);
  10881. 			}
  10882. 		}
  10883. 	},
  10884.  
  10885. 	moveRankUpOneSlotOnScreen: function(evt) {
  10886. 		onclickHREF = evt.target.getAttribute("onclickhref");
  10887. 		thisRankRow = evt.target.parentNode.parentNode;
  10888. 		prevRow = thisRankRow.previousSibling;
  10889. 		nextRow1 = thisRankRow.nextSibling;
  10890. 		nextRow2 = nextRow1.nextSibling;
  10891. 		parentTable = thisRankRow.parentNode;
  10892. 		thisRankRowNum = thisRankRow.rowIndex;
  10893. 		previousRankRowNum = parseInt(thisRankRowNum - 4, 10);
  10894. 		if (previousRankRowNum <= 1 || Helper.characterRow > thisRankRowNum) return;
  10895. 		injectRow = parentTable.rows[previousRankRowNum - 1];
  10896. 		parentTable.insertBefore(prevRow, injectRow);
  10897. 		parentTable.insertBefore(thisRankRow, injectRow);
  10898. 		parentTable.insertBefore(nextRow1, injectRow);
  10899. 		parentTable.insertBefore(nextRow2, injectRow);
  10900. 		System.xmlhttp(onclickHREF);
  10901. 		window.scrollBy(0,-57);
  10902. 	},
  10903.  
  10904. 	moveRankDownOneSlotOnScreen: function(evt) {
  10905. 		onclickHREF = evt.target.getAttribute("onclickhref");
  10906. 		thisRankRow = evt.target.parentNode.parentNode;
  10907. 		prevRow = thisRankRow.previousSibling;
  10908. 		nextRow1 = thisRankRow.nextSibling;
  10909. 		nextRow2 = nextRow1.nextSibling;
  10910. 		parentTable = thisRankRow.parentNode;
  10911. 		thisRankRowNum = thisRankRow.rowIndex;
  10912. 		previousRankRowNum = parseInt(thisRankRowNum + 8, 10);
  10913. 		if (previousRankRowNum - 1 > parentTable.rows.length || Helper.characterRow > thisRankRowNum) return;
  10914. 		injectRow = parentTable.rows[previousRankRowNum - 1];
  10915. 		parentTable.insertBefore(prevRow, injectRow);
  10916. 		parentTable.insertBefore(thisRankRow, injectRow);
  10917. 		parentTable.insertBefore(nextRow1, injectRow);
  10918. 		parentTable.insertBefore(nextRow2, injectRow);
  10919. 		System.xmlhttp(onclickHREF);
  10920. 		window.scrollBy(0,57);
  10921. 	},
  10922.  
  10923. 	fetchRankData: function(evt) {
  10924. 		var calcButton = System.findNode("//input[@id='getrankweightings']");
  10925. 		calcButton.style.display = "none";
  10926. 		var allItems = System.findNodes("//input[@value='Edit']");
  10927. 		for (var i=0; i<allItems.length; i++) {
  10928. 			anItem = allItems[i];
  10929. 			var targetNode = anItem.parentNode.previousSibling;
  10930. 			var href = /window\.location='(.*)';/.exec(anItem.getAttribute("onclick"))[1];
  10931. 			System.xmlhttp(href, Helper.parseRankData, targetNode);
  10932. 		}
  10933. 	},
  10934.  
  10935. 	parseRankData: function(responseText, linkElement) {
  10936. 		var doc=System.createDocument(responseText);
  10937. 		var checkBoxes = System.findNodes("//input[@type='checkbox']",doc);
  10938. 		var count = 0;
  10939. 		for (var i=0;i<checkBoxes.length;i++) {
  10940. 			var checkbox=checkBoxes[i];
  10941. 			if (checkbox.checked) {
  10942. 				//terrasoft.gr/FallenSwordHelper: Can Un-Tag Items
  10943. 				var privName = checkbox.nextSibling.textContent.trim();
  10944. 				if (privName == 'Bank Withdraw' ||
  10945. 					privName == 'Build/Upgrade/Demolish Structures' ||
  10946. 					privName == 'Can Un-Tag Items') {
  10947. 					count += 5;
  10948. 				} else if (privName == 'Can Mass Messages') {
  10949. 					count += 0.5;
  10950. 				} else if (privName == 'Take Items' ||
  10951. 					privName == 'Can Tag Items' ||
  10952. 					privName == 'Can Recall Tagged Items' ||
  10953. 					privName == 'Can Tag Items') {
  10954. 					count += 0.2;
  10955. 				} else if (privName == 'Store Items' ||
  10956. 					privName == 'Can View Advisor') {
  10957. 					count += 0.1;
  10958. 				} else {
  10959. 					count++;
  10960. 				}
  10961. 			}
  10962. 		}
  10963. 		var taxRate = System.findNode("//input[@name='rank_tax']",doc);
  10964.  
  10965. 		linkElement.innerHTML = "<span style='color:blue;'>(" + Math.round(10*count)/10 + ") Tax:(" + taxRate.value + "%)</span> " + linkElement.innerHTML;
  10966. 	},
  10967.  
  10968. 	injectGuildRanksMembers: function(memberList) {
  10969. 		//first build up a relationship from rank to names
  10970. 		Helper.sortAsc = true;
  10971. 		Helper.sortBy = "rank".trim();
  10972. 		memberList.members.sort(Helper.stringSort);
  10973. 		var rankList = {};
  10974. 		rankList.rank = [];
  10975. 		var tempList = [];
  10976. 		var prevRank = memberList.members[0].rank.replace(/Profile Unavailable/ig,"");
  10977. 		var curRank = "";
  10978. 		for (i=0;i<memberList.members.length;i++) {
  10979. 			var member=memberList.members[i];
  10980. 			curRank = member.rank.replace(/Profile Unavailable/ig,"");
  10981. 			if (curRank != prevRank) {
  10982. 				aRank = {};
  10983. 				aRank.rank = prevRank;
  10984. 				aRank.names = tempList;
  10985. 				rankList.rank.push(aRank);
  10986. 				tempList = [];
  10987. 				//last name on the list, so add it to the list of names
  10988. 				if (i == memberList.members.length-1) {
  10989. 					aRank = {};
  10990. 					aRank.rank = curRank;
  10991. 					tempList.push(" " + member.name);
  10992. 					aRank.names = tempList;
  10993. 					rankList.rank.push(aRank);
  10994. 					tempList = [];
  10995. 				}
  10996. 			} else if (curRank == prevRank && i == memberList.members.length-1) {
  10997. 				aRank = {};
  10998. 				aRank.rank = prevRank;
  10999. 				tempList.push(" " + member.name);
  11000. 				aRank.names = tempList;
  11001. 				rankList.rank.push(aRank);
  11002. 				tempList = [];
  11003. 			}
  11004. 			tempList.push(" " + member.name);
  11005. 			prevRank = member.rank.replace(/Profile Unavailable/ig,"");
  11006. 		}
  11007. 		//then for each of the ranks, find the rank on screen and append the names next to it.
  11008. 		var rankNameTable = System.findNode("//table[tbody/tr/td[.='Rank Name']]");
  11009. 		for (i=0;i<rankNameTable.rows.length;i++) {
  11010. 			aRow = rankNameTable.rows[i];
  11011. 			if (aRow.cells[1]) {
  11012. 				rankName = aRow.cells[0].textContent;
  11013. 				for (j=0;j<rankList.rank.length;j++) {
  11014. 					rankListName = rankList.rank[j].rank;
  11015. 					if (rankName == rankListName) {
  11016. 						aRow.cells[0].innerHTML += " <span style='color:blue;'>- " + rankList.rank[j].names + "</span>";
  11017. 						break;
  11018. 					}
  11019. 				}
  11020. 			}
  11021. 		}
  11022. 	},
  11023.  
  11024. 	injectNewGuildLog: function(){
  11025. 		var content=Layout.notebookContent();
  11026.  
  11027. 		//store the time zone for use in processing date/times
  11028. 		var gmtOffsetMinutes = (new Date()).getTimezoneOffset();
  11029. 		Helper.gmtOffsetMilli = gmtOffsetMinutes*60*1000;
  11030.  
  11031. 		//find the time the guild log was stored last
  11032. 		Helper.storedGuildLog = System.getValueJSON("storedGuildLog");
  11033. 		if (Helper.storedGuildLog) {
  11034. 			var lastMessageIndex = Helper.storedGuildLog.logMessage.length;
  11035. 			Helper.lastStoredGuildLogMessage = Helper.storedGuildLog.logMessage[0].logMessage;
  11036. 			Helper.lastStoredGuildLogMessagePostTime = Helper.storedGuildLog.logMessage[0].postDateAsLocalMilli;
  11037. 		}
  11038.  
  11039.  
  11040. 		Helper.newStoredGuildLog = {logMessage:[]};
  11041.  
  11042. 		var newhtml='<table cellspacing="0" cellpadding="0" border="0" width="100%">' +
  11043. 			'<tr style="background-color:#cd9e4b"><td width="80%" nobr><b>&nbsp;Guild Log Version 3</b></td><td><a href="index.php?cmd=guild&subcmd=log"><span style="color:blue;">Old Guild Log</span></a></td></tr>' +
  11044. 			'<tr><td colspan=2>' +
  11045. 				'<table><tbody><tr><td><b>Filters:</b></td>' +
  11046. 				'<td><table><tbody><tr><td>';
  11047. 		for (var i=0; i<Helper.guildLogFilters.length; i++) {
  11048. 			var guildLogFilterID = Helper.guildLogFilters[i].id;
  11049. 			Helper[guildLogFilterID] = GM_getValue(guildLogFilterID);
  11050. 			newhtml += (i % 5 ===0) ? '</td></tr><tr><td>' : '';
  11051. 			newhtml+='&nbsp;' +Helper.guildLogFilters[i].type+ 's:<input id="'+guildLogFilterID+'" type="checkbox" linkto="'+guildLogFilterID+'"' +
  11052. 					(Helper[guildLogFilterID]?' checked':'') + '/>';
  11053. 		}
  11054. 		newhtml += '</td></tr><tr><td>&nbsp;<span id=GuildLogSelectAll>[Select All]</span>&nbsp;<span id=GuildLogSelectNone>[Select None]</span>' +
  11055. 				'</td></tr></tbody></table></td></tr>'+
  11056. 			'<tr><td colspan=2><span style="color:blue;" id="Helper:NewGuildLogLoadingMessage">Loading Page 1 ...</span></td></tr>' +
  11057. 			'</tbody></table>';
  11058. 		newhtml += '<table width="100%" cellspacing="0" cellpadding="2" border="0" id="Helper:GuildLogInjectTable"><tbody>' +
  11059. 			'<tr><td width="16" bgcolor="#cd9e4b"></td><td width="20%" bgcolor="#cd9e4b">Date</td><td width="80%" bgcolor="#cd9e4b">Message</td></tr>' +
  11060. 			'</tbody></table>';
  11061. 		content.innerHTML=newhtml;
  11062.  
  11063. 		var guildLogInjectTable = document.getElementById("Helper:GuildLogInjectTable");
  11064. 		var loadingMessageInjectHere = document.getElementById("Helper:NewGuildLogLoadingMessage");
  11065.  
  11066. 		for (i=0; i<Helper.guildLogFilters.length; i++) {
  11067. 			document.getElementById(Helper.guildLogFilters[i].id).addEventListener('click', Helper.toggleGuildLogFilterVisibility, true);
  11068. 		}
  11069. 		document.getElementById("GuildLogSelectAll").addEventListener('click', Helper.guildLogSelectFilters, true);
  11070. 		document.getElementById("GuildLogSelectNone").addEventListener('click', Helper.guildLogSelectFilters, true);
  11071.  
  11072. 		var oldMaxPagesToFetch = GM_getValue("oldNewGuildLogHistoryPages");
  11073. 		oldMaxPagesToFetch? parseInt(oldMaxPagesToFetch,10):oldMaxPagesToFetch = 100; 
  11074. 		var maxPagesToFetch = parseInt(GM_getValue("newGuildLogHistoryPages") - 1,10);
  11075. 		GM_setValue("oldNewGuildLogHistoryPages", maxPagesToFetch);
  11076. 		var completeReload = false;
  11077. 		if (maxPagesToFetch > oldMaxPagesToFetch) completeReload = true;
  11078. 		//fetch guild log page and apply filters
  11079. 		System.xmlhttp('index.php?cmd=guild&subcmd=log', Helper.parseGuildLogPage, 
  11080. 			{"guildLogInjectTable": guildLogInjectTable, "pageNumber": 0, "loadingMessageInjectHere": loadingMessageInjectHere, "maxPagesToFetch": maxPagesToFetch, "completeReload": completeReload});
  11081. 	},
  11082.  
  11083. 	toggleGuildLogFilterVisibility: function(evt) {
  11084. 		var filterID = evt.target.id;
  11085. 		var filterChecked = evt.target.checked;
  11086. 		var logRows = System.findNodes("//tr[@id='GuildLogFilter:" + filterID + "']");
  11087. 		if (logRows) {
  11088. 			for (i=0;i<logRows.length;i++) {
  11089. 				logRow = logRows[i];
  11090. 				if (filterChecked) {
  11091. 					logRow.style.display = "";
  11092. 					logRow.style.visibility = "visible";
  11093. 				} else {
  11094. 					logRow.style.display = "none";
  11095. 					logRow.style.visibility = "hidden";
  11096. 				}
  11097. 			}
  11098. 		}
  11099. 		GM_setValue(filterID,filterChecked);
  11100. 		Helper[filterID] = filterChecked;
  11101. 	},
  11102.  
  11103. 	guildLogSelectFilters: function(evt) {
  11104. 		var checkedValue = (evt.target.id=="GuildLogSelectAll");
  11105. 		for (var i=0; i<Helper.guildLogFilters.length; i++) {
  11106. 			GM_setValue(Helper.guildLogFilters[i].id, checkedValue);
  11107. 			document.getElementById(Helper.guildLogFilters[i].id).checked = checkedValue;
  11108. 		}
  11109. 		var logRows = System.findNodes("//tr[contains(@id,'GuildLogFilter:')]");
  11110. 		if (logRows) {
  11111. 			for (i=0;i<logRows.length;i++) {
  11112. 				logRow = logRows[i];
  11113. 				rowID = logRow.getAttribute("id");
  11114. 				if (checkedValue) {
  11115. 					logRow.style.display = "";
  11116. 					logRow.style.visibility = "visible";
  11117. 				} else if (rowID != "GuildLogFilter:Unknown") {
  11118. 					logRow.style.display = "none";
  11119. 					logRow.style.visibility = "hidden";
  11120. 				}
  11121. 			}
  11122. 		}
  11123.  
  11124. 	},
  11125.  
  11126. 	parseGuildLogPage: function(responseText, callback) {
  11127. 		var pageNumber = callback.pageNumber;
  11128. 		var maxPagesToFetch = callback.maxPagesToFetch;
  11129. 		var completeReload = callback.completeReload;
  11130. 		var guildLogInjectTable = callback.guildLogInjectTable;
  11131. 		var loadingMessageInjectHere = callback.loadingMessageInjectHere;
  11132. 		var doc=System.createDocument(responseText);
  11133.  
  11134. 		var logTable = System.findNode("//table[@border='0' and @cellpadding='2' and @width='100%']",doc);
  11135.  
  11136. 		//if the whole first page is new, then likely that the stored log needs to be refreshed, so go ahead and do so
  11137. 		if (pageNumber == 0) {
  11138. 			var lastRowInTable = logTable.rows[logTable.rows.length-4];
  11139. 			var lastRowCellContents = lastRowInTable.cells[1].innerHTML;
  11140. 			lastRowPostDateAsDate = System.parseDate(lastRowCellContents);
  11141. 			lastRowPostDateAsLocalMilli = lastRowPostDateAsDate.getTime() - Helper.gmtOffsetMilli;
  11142. 			if (lastRowPostDateAsLocalMilli > Helper.lastStoredGuildLogMessagePostTime) completeReload = true;
  11143. 		} else {
  11144. 			completeReload = false;
  11145. 		}
  11146.  
  11147. 		var enableLogColoring = GM_getValue("enableLogColoring");
  11148. 		if (enableLogColoring) {
  11149. 			var lastCheckScreen = "lastGuildLogCheck";
  11150. 			var localLastCheckMilli=GM_getValue(lastCheckScreen);
  11151. 			if (!localLastCheckMilli) localLastCheckMilli=(new Date()).getTime();
  11152. 			var localDateMilli = (new Date()).getTime();
  11153. 		}
  11154.  
  11155. 		for (i=1;i<logTable.rows.length;i+=4) {
  11156. 			aRow = logTable.rows[i];
  11157.  
  11158. 			var cellContents = aRow.cells[1].innerHTML;
  11159. 			postDateAsDate = System.parseDate(cellContents);
  11160. 			postDateAsLocalMilli = postDateAsDate.getTime() - Helper.gmtOffsetMilli;
  11161.  
  11162. 			//if the post date is the same as last one in the stored list and the message is the same, then break out
  11163. 			//and start appending the stored values instead of parsing.
  11164. 			var stopProcessingLogPages = false;
  11165. 			if (postDateAsLocalMilli == Helper.lastStoredGuildLogMessagePostTime && aRow.innerHTML == Helper.lastStoredGuildLogMessage && !completeReload) {
  11166. 				stopProcessingLogPages = true;
  11167. 				break;
  11168. 			}
  11169. 			var displayRow = true;
  11170. 			var rowTypeID = "GuildLogFilter:Unknown";
  11171. 			//if recall message, check to see if showRecallMessages is checked.
  11172. 			if (aRow.innerHTML.search("recalled the item") != -1 ||
  11173. 				aRow.innerHTML.search("took the item") != -1 ||
  11174. 				aRow.innerHTML.search("stored the item") != -1) {
  11175. 				if (!Helper.showRecallMessages) {
  11176. 					displayRow = false;
  11177. 				}
  11178. 				rowTypeID = "GuildLogFilter:showRecallMessages";
  11179. 			}
  11180. 			//Tag/Untag (showTaggingMessages)
  11181. 			else if (aRow.innerHTML.search("has added flags to some of guild's stored items costing a total of") != -1 ||
  11182. 				aRow.innerHTML.search("has removed flags to the guild's stored items.") != -1) {
  11183. 				if (!Helper.showTaggingMessages) {
  11184. 					displayRow = false;
  11185. 				}
  11186. 				rowTypeID = "GuildLogFilter:showTaggingMessages";
  11187. 			}
  11188. 			//Relic messages (showRelicMessages)
  11189. 			else if (aRow.innerHTML.search("relic. This relic now has an empower level of") != -1 ||
  11190. 				aRow.innerHTML.search("relic. The relic empower level has been reset to zero.") != -1 ||
  11191. 				aRow.innerHTML.search("captured the relic") != -1 ||
  11192. 				aRow.innerHTML.search("captured your relic") != -1 ||
  11193. 				aRow.innerHTML.search("has captured the undefended relic") != -1 ||
  11194. 				aRow.innerHTML.search("attempted to capture your relic") != -1) {
  11195. 				if (!Helper.showRelicMessages) {
  11196. 					displayRow = false;
  11197. 				}
  11198. 				rowTypeID = "GuildLogFilter:showRelicMessages";
  11199. 			}
  11200. 			//Mercenary messages (showMercenaryMessages)
  11201. 			else if (aRow.innerHTML.search("disbanded a mercenary.") != -1 ||
  11202. 				aRow.innerHTML.search("hired the mercenary") != -1) {
  11203. 				if (!Helper.showMercenaryMessages) {
  11204. 					displayRow = false;
  11205. 				}
  11206. 				rowTypeID = "GuildLogFilter:showMercenaryMessages";
  11207. 			}
  11208. 			//Group Combat messages (showGroupCombatMessages)
  11209. 			else if (aRow.innerHTML.search(/A group from your guild was (.*) in combat./) != -1) {
  11210. 				if (!Helper.showGroupCombatMessages) {
  11211. 					displayRow = false;
  11212. 				}
  11213. 				rowTypeID = "GuildLogFilter:showGroupCombatMessages";
  11214. 			}
  11215. 			//Donation messages (showDonationMessages)
  11216. 			else if (aRow.innerHTML.search(/deposited ([,0-9]+) FallenSword Points into the guild./) != -1 ||
  11217. 				aRow.innerHTML.search(/deposited ([,0-9]+) gold into the guild bank/) != -1) {
  11218. 				if (!Helper.showDonationMessages) {
  11219. 					displayRow = false;
  11220. 				}
  11221. 				rowTypeID = "GuildLogFilter:showDonationMessages";
  11222. 			}
  11223. 			//Ranking messages (showRankingMessages)
  11224. 			else if (aRow.innerHTML.search("has added a new rank entitled") != -1 ||
  11225. 				aRow.innerHTML.search("has been assigned the rank") != -1) {
  11226. 				if (!Helper.showRankingMessages) {
  11227. 					displayRow = false;
  11228. 				}
  11229. 				rowTypeID = "GuildLogFilter:showRankingMessages";
  11230. 			}
  11231. 			//GvG messages (showGvGMessages)
  11232. 			else if (aRow.innerHTML.search("resulted in a draw. Your GvG rating and Guild RP was unaffected.") != -1 ||
  11233. 				aRow.innerHTML.search(/resulted in (.*) with a final score of/) != -1 ||
  11234. 				aRow.innerHTML.search("has just initiated a conflict with the guild") != -1 ||
  11235. 				aRow.innerHTML.search("has initiated a conflict with your guild") != -1 ||
  11236. 				aRow.innerHTML.search("is participating in the conflict against the guild") != -1) {
  11237. 				if (!Helper.showGvGMessages) {
  11238. 					displayRow = false;
  11239. 				}
  11240. 				rowTypeID = "GuildLogFilter:showGvGMessages";
  11241. 			}
  11242.  
  11243. 			//display the row or effectively hide it
  11244. 			newRow = aRow.cloneNode(true);
  11245. 			if (!displayRow) {
  11246. 				newRow.style.display = "none";
  11247. 				newRow.style.visibility = "hidden";
  11248. 			}
  11249. 			newRow.id = rowTypeID
  11250. 			guildLogInjectTable.appendChild(newRow);
  11251. 			postAge = (localDateMilli - postDateAsLocalMilli)/(1000*60);
  11252. 			if (enableLogColoring && postDateAsLocalMilli > localLastCheckMilli) {
  11253. 				newRow.style.backgroundColor = "#F5F298";
  11254. 			}
  11255. 			else if (enableLogColoring && postAge > 20 && postDateAsLocalMilli <= localLastCheckMilli) {
  11256. 				newRow.style.backgroundColor = "#CD9E4B";
  11257. 			}
  11258. 			var newLogMessage = {
  11259. 				postDateAsLocalMilli: postDateAsLocalMilli,
  11260. 				rowTypeID: rowTypeID,
  11261. 				logMessage: newRow.innerHTML,
  11262. 			};
  11263. 			Helper.newStoredGuildLog.logMessage.push(newLogMessage);
  11264. 			//create following spacer row
  11265. 			var spacerRow = document.createElement("TR");
  11266. 			if (!displayRow) {
  11267. 				spacerRow.style.display = "none";
  11268. 				spacerRow.style.visibility = "hidden";
  11269. 			}
  11270. 			spacerRow.id = rowTypeID
  11271. 			guildLogInjectTable.appendChild(spacerRow);
  11272. 			spacerRow.innerHTML = '<td height="1" bgcolor="#634229" colspan="3"></td>'
  11273. 			newLogMessage = {
  11274. 				postDateAsLocalMilli: postDateAsLocalMilli,
  11275. 				rowTypeID: rowTypeID,
  11276. 				logMessage: spacerRow.innerHTML,
  11277. 			};
  11278. 			Helper.newStoredGuildLog.logMessage.push(newLogMessage);
  11279. 		}
  11280.  
  11281. 		if (stopProcessingLogPages) {
  11282. 			loadingMessageInjectHere.innerHTML = 'Processing stored logs ...';
  11283. 			for (i=0;i<Helper.storedGuildLog.logMessage.length;i++) {
  11284. 				var logMessageArrayItem = Helper.storedGuildLog.logMessage[i];
  11285. 				var newRow = document.createElement("TR");
  11286. 				var displayRow = true;
  11287. 				for (var j=0; j<Helper.guildLogFilters.length; j++) {
  11288. 					var guildLogFilterID = Helper.guildLogFilters[j].id;
  11289. 					var rowTypeID = "GuildLogFilter:" + guildLogFilterID;
  11290. 					if (logMessageArrayItem.rowTypeID == rowTypeID) {
  11291. 						displayRow = Helper[guildLogFilterID];
  11292. 						break;
  11293. 					}
  11294. 				}
  11295. 				newRow.style.display = "";
  11296. 				newRow.style.visibility = "";
  11297. 				if (!displayRow) {
  11298. 					newRow.style.display = "none";
  11299. 					newRow.style.visibility = "hidden";
  11300. 				}
  11301. 				newRow.id = logMessageArrayItem.rowTypeID
  11302. 				guildLogInjectTable.appendChild(newRow);
  11303. 				newRow.innerHTML = logMessageArrayItem.logMessage;
  11304. 				postAge = (localDateMilli - logMessageArrayItem.postDateAsLocalMilli)/(1000*60);
  11305. 				if (enableLogColoring && newRow.cells[2] && logMessageArrayItem.postDateAsLocalMilli > localLastCheckMilli) {
  11306. 					newRow.style.backgroundColor = "#F5F298";
  11307. 				}
  11308. 				else if (enableLogColoring && newRow.cells[2] && postAge > 20 && logMessageArrayItem.postDateAsLocalMilli <= localLastCheckMilli) {
  11309. 					newRow.style.backgroundColor = "#CD9E4B";
  11310. 				}
  11311. 				var newLogMessage = {
  11312. 					postDateAsLocalMilli: logMessageArrayItem.postDateAsLocalMilli,
  11313. 					rowTypeID: logMessageArrayItem.rowTypeID,
  11314. 					logMessage: logMessageArrayItem.logMessage,
  11315. 				};
  11316. 				Helper.newStoredGuildLog.logMessage.push(newLogMessage);
  11317. 			}
  11318. 		}
  11319.  
  11320. 		var page = System.findNode("//select[@name='page']/..", doc);
  11321. 		var curPage = parseInt(System.findNode("//select[@name='page']", doc).value,10);
  11322. 		var maxPage = page.innerHTML.match(/of&nbsp;(\d*)/)[1];
  11323.  
  11324. 		//fetch the next page (if necessary)
  11325. 		if (pageNumber < maxPage && pageNumber < maxPagesToFetch && !stopProcessingLogPages) {
  11326. 			var nextPage = parseInt(pageNumber+1,10);
  11327. 			loadingMessageInjectHere.innerHTML = 'Loading Page ' + (nextPage + 1) + " of " + Math.floor(maxPagesToFetch+1,maxPage) + "...";
  11328. 			System.xmlhttp('index.php?cmd=guild&subcmd=log&subcmd2=&page=' + nextPage + '&search_text=', Helper.parseGuildLogPage, 
  11329. 				{"guildLogInjectTable": guildLogInjectTable, "pageNumber": nextPage, "loadingMessageInjectHere": loadingMessageInjectHere, "maxPagesToFetch": maxPagesToFetch, "completeReload": completeReload});
  11330. 		} else {
  11331. 			loadingMessageInjectHere.innerHTML = 'Loading Complete.';
  11332. 			//Helper.addLogColoring("GuildLog", 1);
  11333. 			Helper.addGuildLogWidgets();
  11334. 			System.setValueJSON("storedGuildLog", Helper.newStoredGuildLog);
  11335. 			now=(new Date()).getTime();
  11336. 			GM_setValue("lastGuildLogCheck", now.toString());
  11337. 		}
  11338. 	},
  11339.  
  11340. 	injectCheckWearingItem: function() {
  11341. 		Layout.notebookContent().innerHTML=Helper.makePageTemplate("Check Wearing Items for Best Damage", "", "", "", "checkwear");
  11342.  
  11343. 		document.getElementById("checkwear").innerHTML+="Getting profile ...<br/>";
  11344. 		var playerid=/&playerid=(\d+)/.exec(window.location)[1];
  11345. 		Helper.wearingItems={};
  11346. 		Helper.wearingItems.playerid=playerid;
  11347. 		System.xmlhttp("index.php?cmd=profile&player_id="+playerid, Helper.getWearingItems);
  11348. 	},
  11349.  
  11350. 	getWearingItems: function(responseText) {
  11351. 		var doc=System.createDocument(responseText);
  11352. 		var items=System.findNodes("//img[contains(@onmouseover,'ajaxLoadItem') and contains(@src,'/items/')]",doc);
  11353. 		for (var i=0; i<items.length; i++) {
  11354. 			if (!(items[i].parentNode.getAttribute("href")) || items[i].parentNode.getAttribute("href").indexOf("subcmd=unequipitem&")>0) {
  11355. 				var item=items[i], type, onmo=item.getAttribute("onmouseover");
  11356. 				if (item.parentNode.getAttribute("href")) item=item.parentNode;
  11357. 				if (item.parentNode.width != 60) item=item.parentNode.parentNode.parentNode.parentNode;
  11358. 				type = item.parentNode.cellIndex + item.parentNode.parentNode.rowIndex*3;
  11359. 				Helper.wearingItems[type]=onmo;
  11360. 			}
  11361. 		}
  11362. 		Helper.wearingItems.name=System.findNode("//td[@width=666]/table/tbody/tr/td[@colspan=2]/font/b",doc);
  11363. 		if (Helper.wearingItems.name) 
  11364. 			Helper.wearingItems.name = Helper.wearingItems.name.textContent;
  11365. 		else
  11366. 			Helper.wearingItems.name = System.findNode("//td[@colspan=3]/center/table[@width=500]/tbody/tr/td/font/b",doc).textContent;
  11367. 		Helper.wearingItems.lvl=System.findNode("//b[contains(.,'Level:')]",doc).parentNode.nextSibling.textContent;
  11368. 		document.getElementById("checkwear").innerHTML+="Getting items from "+Helper.wearingItems.name+"'s profile ... <br/>";
  11369. 		Helper.getEachWearingItem(0);
  11370. 	},
  11371.  
  11372. 	getEachWearingItem: function(type) {
  11373. 		if (Helper.wearingItems[type]) {
  11374. 			System.xmlhttp(Helper.linkFromMouseover(Helper.wearingItems[type]), function(responseText) {
  11375. 					var name=responseText.match(/<b>([^<]*)<\/b>/)[1];
  11376. 					var mo=Helper.wearingItems[type].replace("'<br><center><b>[Click to Unequip]</b></center>'","''");
  11377. 					Helper.wearingItems[type]={"mo":mo};
  11378. 					Helper.wearingItems[type].wear=name;
  11379. 					Helper.wearingItems[type].fullSet=responseText.match(/>Set Details \((\d)\/\1\)</)!=null;
  11380. 					document.getElementById("checkwear").innerHTML+=" comparing "+name+" ...<br/>";
  11381. 					var stype=[2,0,7,4,1,5,6,3,8][type];
  11382. 					var url="http://guide.fallensword.com/index.php?cmd=items&index=0&search_name=&search_level_min=&"+
  11383. 						"search_level_max="+Helper.wearingItems.lvl+
  11384. 						"&search_type="+stype+"&search_rarity=-1&sort_by=1&sort_by=5";
  11385. 					GM_xmlhttpRequest({
  11386. 						method: 'GET',
  11387. 						url: url,
  11388. 						headers: {
  11389. 							"User-Agent": navigator.userAgent,
  11390. 							"Referer": document.location
  11391. 						},
  11392. 						onload: function(responseDetails) {
  11393. 							var doc=System.createDocument(responseDetails.responseText);
  11394. 							var nodes = System.findNodes("//a[contains(@href,'index.php?cmd=items&subcmd=view')]",doc);
  11395. 							Helper.wearingItems[type].suggest="";
  11396. 							Helper.wearingItems[type].best=nodes[0].textContent;
  11397. 							for (var i=0; i<5; i++) {
  11398. 								Helper.wearingItems[type].suggest+=
  11399. 									"<span onmouseover=\"Tip('"+nodes[i].parentNode.parentNode.textContent+"');\">"+
  11400. 										nodes[i].textContent+"</span>"+
  11401. 									" <span style='font-size:xx-small'>[<a href='/index.php?cmd=guild&subcmd=inventory&subcmd2=report&item="+nodes[i].textContent+"'>GS</a>] "+
  11402. 									"[<a href='/index.php?cmd=auctionhouse&type=-1&search_text="+nodes[i].textContent+"'>AH</a>] "+
  11403. 									"[<a href='"+nodes[i].getAttribute("href").replace(/http:\/\/(.*)\//,"http://guide.fallensword.com/")+"'>UFG</a>]</span>, ";
  11404. 							}
  11405. 							Helper.getEachWearingItem(type+1);
  11406. 						}
  11407. 					});
  11408. 				});
  11409. 		} else {
  11410. 			if (type < 8)
  11411. 				Helper.getEachWearingItem(type+1);
  11412. 			else
  11413. 				Helper.showCheckWearingResult();
  11414. 		}
  11415. 	},
  11416.  
  11417. 	showCheckWearingResult: function() {
  11418. 		var content=document.getElementById("checkwear");
  11419. 		var pos2type=["Glove", "Helm", "Amulet", "Weapon", "Armor", "Shield", "Ring", "Boot", "Rune"];
  11420. 		var newHtml, color;
  11421. 		newHtml='<h3><a href="/index.php?cmd=profile&player_id='+Helper.wearingItems.playerid+'">'+Helper.wearingItems.name+'</a>\'s Setup Analysis</h3>'+
  11422. 			"Please note that:<br/>"+
  11423. 			"<ul><li>Analysis based on availability of items in the Ultimate Fallensword Guide</li>"+
  11424. 			"<li>Item sorted by damage stat in no-forge, no-craft condition</li>"+
  11425. 			"<li>Set bonus, other stats are not considered</li></ul>"+
  11426. 			"Please use at your own risk ^_^<p/>"+
  11427. 			"Tooltip format: Name  	Level  	Type 	Rarity 	Attack  	Defense  	Armor  	Damage  	HP<p/>"+
  11428. 			"<table width=100% cellspacing=2>";
  11429. 		for (var type=0; type<9; type++) {
  11430. 			newHtml+="<tr><th align=left>"+pos2type[type]+"</th>";
  11431. 			if (Helper.wearingItems[type]) {
  11432. 				if (Helper.wearingItems[type].wear == Helper.wearingItems[type].best ||  Helper.wearingItems[type].fullSet) {
  11433. 					color="green";
  11434. 				} else {
  11435. 					color="yellow";
  11436. 					GM_log(Helper.wearingItems[type].suggest);
  11437. 					Helper.wearingItems[type].suggest=Helper.wearingItems[type].suggest.replace(">"+Helper.wearingItems[type].wear+"<", 
  11438. 						"><font color=yellow>"+Helper.wearingItems[type].wear+"</font><");
  11439. 					GM_log(Helper.wearingItems[type].suggest);
  11440. 				}
  11441. 				newHtml+="<td><span style='color:"+color+"' onmouseover=\""+Helper.wearingItems[type].mo+"\">"+Helper.wearingItems[type].wear+"</span>"+
  11442. 					(Helper.wearingItems[type].fullSet?" (<span style='color:blue'>Full Set</span>)":"")+"</td></tr>"+
  11443. 					"<tr><td align=right>Suggested</td><td>"+Helper.wearingItems[type].suggest+"</td></tr>";
  11444. 			} else
  11445. 				newHtml+="<td><span style='color:red'>NOTHING</span></td></tr>";
  11446. 		}
  11447. 		content.innerHTML=newHtml+"</table>";
  11448. 	},
  11449.  
  11450. 	addChatTextArea: function() {
  11451. 		if (!GM_getValue("enhanceChatTextEntry")) return;
  11452. 		var messageCell = System.findNode("//td[table/tbody/tr/td/input[@value='Send As Mass']]");
  11453. 		var chatConfirm=System.findNode("//input[@name='xc']");
  11454. 		result = '<form name="dochat" action="index.php" method="post">';
  11455. 		result += '<table border="0"><tbody><tr><td rowspan="2">';
  11456. 		result += '<input type="hidden" value="guild" name="cmd"/>';
  11457. 		result += '<input type="hidden" value="dochat" name="subcmd"/>';
  11458. 		result += '<input type="hidden" value="' + chatConfirm.value + '" name="xc"/>';
  11459. 		result += '<textarea align="center" cols="60" rows="2" name="msg" id="Helper:ChatTextArea"></textarea>';
  11460. 		result += '</td><td>';
  11461. 		result += '<input class="custominput" type="submit" value="Send" name="submit"/>';
  11462. 		result += '</td><tr><td>';
  11463. 		result += '<input class="custominput" type="submit" value="Send As Mass" name="submit" ' +
  11464. 			'onClick="window.confirm(\'Are you sure you want to send a mass message?\')"/>';
  11465. 		result += '</td></tr></tbody></table>';
  11466. 		result += '</form>';
  11467. 		messageCell.innerHTML = result;
  11468.  
  11469. 		document.getElementById('Helper:ChatTextArea').addEventListener('keyup', function(evt) {if (evt.keyCode == 13) evt.target.form.submit()}, true);
  11470. 	},
  11471.  
  11472. 	updateTitanLogs: function() {
  11473. 		if (!GM_getValue("enableTitanLog")) return;
  11474. 		//need timer function
  11475. 		var titanLogRefreshTime = GM_getValue("titanLogRefreshTime");
  11476. 		var titanLog = System.getValueJSON("titanLog");
  11477. 		if (titanLog && titanLog.lastUpdate) {
  11478. 			if ((new Date()).getTime() - titanLog.lastUpdate.getTime() > (titanLogRefreshTime * 60 * 1000)) {
  11479. 				//bring up the scout tower page and parse it
  11480. 				//index.php?cmd=guild&subcmd=scouttower
  11481. 				System.xmlhttp("index.php?cmd=guild&subcmd=scouttower", Helper.parseScoutTower);
  11482. 			}
  11483. 		}
  11484. 	},
  11485.  
  11486. 	parseScoutTower: function(responseText) {
  11487. 		if (responseText) {
  11488. 			var doc = System.createDocument(responseText);
  11489. 			var titanTable = System.findNode("//table[tbody/tr/td/font[.='Titan']]", doc);
  11490. 		} else {	
  11491. 			var titanTable = System.findNode("//table[tbody/tr/td/font[.='Titan']]");
  11492. 		}
  11493. 		var titanLog = System.getValueJSON("titanLog");
  11494. 		if (!titanLog) titanLog = {}, titanLog.titans = [];
  11495. 		if (titanTable) {
  11496. 			var titanName = "", titanRealm = "", titanHP = "";
  11497. 			for (var i=1; i<titanTable.rows.length; i++) { //ignore title row
  11498. 				var titan = {};
  11499. 				var aRow = titanTable.rows[i];
  11500. 				if (aRow.cells[3]) { // titan row
  11501. 					titan.name = aRow.cells[0].firstChild.getAttribute('title');
  11502. 					titan.realm = aRow.cells[1].textContent;
  11503. 					titanHP = /(\d+)\/(\d+)/.exec(aRow.cells[2].textContent);
  11504. 					titan.currentHP = titanHP[1]*1;
  11505. 					titan.maxHP = titanHP[2]*1;
  11506. 					titan.firstRow = aRow.innerHTML;
  11507. 					titan.nextRow = titanTable.rows[i+1].innerHTML;
  11508.  
  11509. 					//if the titan is already in the array, then update the record
  11510. 					var titanFoundInLog = false;
  11511. 					for (var j=0; j<titanLog.titans.length; j++) {
  11512. 						if (titan.name == titanLog.titans[j].name && titan.realm == titanLog.titans[j].realm && titan.maxHP == titanLog.titans[j].maxHP) {
  11513. 							if (titan.currentHP < titanLog.titans[j].currentHP) titanLog.titans.splice(j,1,titan);
  11514. 							titanFoundInLog = true;
  11515. 							break;
  11516. 						}
  11517. 					}
  11518.  
  11519. 					//if not already in the array, then add the titan to the array
  11520. 					if (!titanFoundInLog) {
  11521. 						titanLog.titans.push(titan);
  11522. 					}
  11523. 				}
  11524. 			}
  11525. 			//if there are more than 20 titans in the log, then purge the oldest ones
  11526. 			if (titanLog.titans.length > 15) {
  11527. 				titanLog.titans.splice(0, titanLog.titans.length - 15);
  11528. 			}
  11529.  
  11530. 			//save the titanLog
  11531. 			titanLog.lastUpdate = new Date();
  11532. 			System.setValueJSON("titanLog", titanLog);
  11533.  
  11534. 			//if on the scout tower screen, show the log
  11535. 			if (location.search == "?cmd=guild&subcmd=scouttower") {
  11536. 				var newRow = titanTable.insertRow(-1);
  11537. 				newRow.innerHTML = '<td bgcolor="#cd9e4b" style="height: 1px;" colspan="4">Killed Titan History</td>';
  11538. 				for (var j=titanLog.titans.length-1; j>=0; j--) {
  11539. 					var titanLogTitan = {};
  11540. 					titanLogTitan.name = titanLog.titans[j].name;
  11541. 					titanLogTitan.realm = titanLog.titans[j].realm;
  11542. 					titanLogTitan.maxHP = titanLog.titans[j].maxHP;
  11543. 					//if the titan is already on the screen, then don't display it again
  11544. 					var displayTitan = true;
  11545. 					for (var i=1; i<titanTable.rows.length; i++) {
  11546. 						var aRow = titanTable.rows[i];
  11547. 						if (aRow.cells[3]) { // titan row
  11548. 							var scoutTowerTitan = {};
  11549. 							scoutTowerTitan.name = aRow.cells[0].firstChild.getAttribute('title');
  11550. 							scoutTowerTitan.realm = aRow.cells[1].textContent;
  11551. 							titanHP = /(\d+)\/(\d+)/.exec(aRow.cells[2].textContent);
  11552. 							scoutTowerTitan.maxHP = titanHP[2]*1;
  11553. 							if (titanLogTitan.name == scoutTowerTitan.name && titanLogTitan.realm == scoutTowerTitan.realm 
  11554. 								&& titanLogTitan.maxHP == scoutTowerTitan.maxHP) {
  11555. 								displayTitan = false;
  11556. 								break;
  11557. 							}
  11558. 						}
  11559. 					}
  11560. 					if (displayTitan) {
  11561. 						var newRow = titanTable.insertRow(-1);
  11562. 						newRow.innerHTML = titanLog.titans[j].firstRow;
  11563. 						newRow = titanTable.insertRow(-1);
  11564. 						newRow.innerHTML = titanLog.titans[j].nextRow;
  11565. 						newRow = titanTable.insertRow(-1);
  11566. 						newRow.innerHTML = '<td height="2" colspan="3"></td>';
  11567. 						newRow = titanTable.insertRow(-1);
  11568. 						newRow.innerHTML = '<td bgcolor="#cd9e4b" style="height: 1px;" colspan="4"></td>';
  11569. 						newRow = titanTable.insertRow(-1);
  11570. 						newRow.innerHTML = '<td height="2" colspan="3"></td>';
  11571. 					}
  11572. 				}
  11573. 			}
  11574. 		}
  11575.  
  11576.  
  11577. 	},
  11578.  
  11579. 	injectHomePageTwoLink: function() {
  11580. 		var viewNewsArchiveLink = System.findNode("//a[@href='index.php?cmd=&subcmd=viewarchive']");
  11581. 		if (viewNewsArchiveLink) {
  11582. 			viewNewsArchiveLink.parentNode.innerHTML += '&nbsp;<a href="index.php?cmd=&subcmd=viewarchive&subcmd2=&page=2&search_text=">View Archive Page 2</a>'
  11583. 		}
  11584. 	},
  11585.  
  11586. 	injectNotepad: function() {
  11587. 		var textAreaNode = System.findNode("//textarea[@name='notes']");
  11588. 		textAreaNode.cols = 115;
  11589. 		textAreaNode.rows = 30;
  11590. 	},
  11591.  
  11592. 	injectTempleAlert: function() {
  11593. 		//Checks to see if the temple is open for business.
  11594. 		if (!GM_getValue("enableTempleAlert")) return;
  11595. 		//need timer function
  11596. 		var templeAlertLastUpdate = System.getValueJSON("templeAlertLastUpdate");
  11597. 		if (templeAlertLastUpdate) {
  11598. 			if ((new Date()).getTime() - templeAlertLastUpdate.getTime() > (60 * 60 * 1000)) {
  11599. 				//bring up the temple page and parse it
  11600. 				System.xmlhttp("index.php?cmd=temple", Helper.parseTemplePage);
  11601. 			}
  11602. 		} else {
  11603. 			System.xmlhttp("index.php?cmd=temple", Helper.parseTemplePage);
  11604. 		}
  11605. 	},
  11606.  
  11607. 	parseTemplePage: function(responseText) {
  11608. 		var doc = System.createDocument(responseText);
  11609. 		//if need to pray is set then put an alert in the LHS sidebar
  11610. 		var needToPray = System.findNode("//input[@value='Pray to Osverin']", doc);
  11611. 		if (needToPray) {
  11612. 			var logoutRow = System.findNode("//tr[td/a[@href='javascript:confirmLogout();']]");
  11613. 			var LHSSidebarTable = logoutRow.parentNode.parentNode;
  11614. 			var newRow=LHSSidebarTable.insertRow(logoutRow.rowIndex+1);
  11615. 			var newCell=newRow.insertCell(0);
  11616. 			newCell.height = 10;
  11617. 			newCell.align = 'center';
  11618. 			newCell.innerHTML = '<table width="125" cellpadding="3" border="0" bgcolor="#4a3918" style="border: 1px solid rgb(198, 173, 115);"><tbody>' +
  11619. 				'<tr><td align="center"><a href="index.php?cmd=temple"><font color="#ffffff">You feel disconnected from the gods.</font></a></td></tr>' +
  11620. 				'</tbody></table>';
  11621. 			var newRow=LHSSidebarTable.insertRow(logoutRow.rowIndex+1);
  11622. 			var newCell=newRow.insertCell(0);
  11623. 			newCell.height = 10;
  11624. 		}
  11625. 		System.setValueJSON("templeAlertLastUpdate", new Date());
  11626. 	},
  11627.  
  11628. 	injectFindPlayer: function() {
  11629. 		var findPlayerButton = System.findNode("//input[@value='Find Player']");
  11630. 		findPlayerButton.parentNode.innerHTML += "&nbsp;<a href='index.php?cmd=findplayer&search_active=1&search_username=&search_level_min=" + 
  11631. 			(Helper.characterLevel - 5) + "&search_level_max=" + (Helper.characterLevel + 5) + 
  11632. 			"&search_in_guild=0'><span style='color:blue;'>Get PvP targets</span></a>";
  11633. 		if (!GM_getValue("showGoldOnFindPlayer")) return;
  11634. 		var findPlayerTable = System.findNode("//table[tbody/tr/td[.='Guild']]");
  11635. 		for (var i=0; i<findPlayerTable.rows.length; i++) {
  11636. 			var aRow = findPlayerTable.rows[i];
  11637. 			if (i == 0) {
  11638. 				var newCell = aRow.insertCell(4);
  11639. 				newCell.style.backgroundColor = '#CD9E4B';
  11640. 				newCell.style.fontSize = '12px';
  11641. 				newCell.align = 'right';
  11642. 				newCell.innerHTML = 'PvP';
  11643. 				var newCell = aRow.insertCell(5);
  11644. 				newCell.style.backgroundColor = '#CD9E4B';
  11645. 				newCell.innerHTML = '&nbsp;';
  11646. 				var newCell = aRow.insertCell(6);
  11647. 				newCell.style.backgroundColor = '#CD9E4B';
  11648. 				newCell.style.fontSize = '12px';
  11649. 				newCell.align = 'right';
  11650. 				newCell.innerHTML = 'Gold';
  11651. 			}
  11652. 			if (i != 0 && aRow.cells[1]) {
  11653. 				var playerHREF = aRow.cells[0].firstChild.nextSibling.getAttribute("href");
  11654. 					var newCell = aRow.insertCell(4);
  11655. 					newCell.style.fontSize = '12px';
  11656. 					newCell.align = 'right';
  11657. 					newCell.innerHTML = '<span style="color:green;" id="PvP' + playerHREF + '">?</span>';
  11658. 					System.xmlhttp(playerHREF, Helper.findPlayerParseProfile, {"href": playerHREF});
  11659. 					var newCell = aRow.insertCell(5);
  11660. 					newCell.innerHTML = '&nbsp;';
  11661. 					var newCell = aRow.insertCell(6);
  11662. 					newCell.style.fontSize = '12px';
  11663. 					newCell.align = 'right';
  11664. 					newCell.innerHTML = '<span style="color:blue;" id="Gold' + playerHREF + '">?</span>';
  11665. 					System.xmlhttp(playerHREF, Helper.findPlayerParseProfile, {"href": playerHREF});
  11666. 			} else if (!aRow.cells[1]) {
  11667. 				aRow.cells[0].colSpan = 8;
  11668. 			}
  11669. 		}
  11670. 	},
  11671.  
  11672. 	findPlayerParseProfile: function(responseText, callback) {
  11673. 		var doc = System.createDocument(responseText);
  11674. 		var statisticsTable = System.findNode("//div[strong[contains(.,'Statistics')]]/following-sibling::div[1]/table", doc);
  11675. 		var pvpElement = System.findNode("./tbody/tr/td[b[contains(.,'PvP')]]", statisticsTable);
  11676. 		var pvpValue = pvpElement.nextSibling;
  11677. 		document.getElementById("PvP" + callback.href).innerHTML = pvpValue.textContent;
  11678. 		var goldElement = System.findNode("./tbody/tr/td[b[contains(.,'Gold:')]]", statisticsTable);
  11679. 		var goldValue = goldElement.nextSibling;
  11680. 		document.getElementById("Gold" + callback.href).innerHTML = goldValue.textContent;
  11681. 	}
  11682. };
  11683.  
  11684. Helper.onPageLoad(null);