antimarty fortune cookie script

Kingdom of Loathing fortune cookie tracker

目前为 2014-08-10 提交的版本。查看 最新版本

  1. // antimarty's fortune cookie script, based in part on:
  2. // csemaj's KoL Script
  3. // Copyright (c) 2007, James Cammarata
  4. // Based on code written by Byung Kim (Tard) http://kol.dashida.com and OneTonTomato's scripts
  5. // toggle preference code from lukifer's mrscript
  6. // http://www.noblesse-oblige.org/lukifer/scripts/
  7. // script update code based on DrEvi1's hatrack helper, which credits Picklish
  8. // fixes for lag combatting inventory screens by Firvagor
  9. // now using Charon's account options tab code
  10. // Released under the GPL license
  11. // http://www.gnu.org/copyleft/gpl.html
  12. //
  13. // ==UserScript==
  14. // @name antimarty fortune cookie script
  15. // @namespace antimarty
  16. // @include *kingdomofloathing.com/*.php*
  17. // @include *127.0.0.1:600*/*.php*
  18. // @include localhost:18481/*.php*
  19. // @version 0.5.7
  20. // @grant GM_getValue
  21. // @grant GM_setValue
  22. // @grant GM_xmlhttpRequest
  23. //
  24. // @description Kingdom of Loathing fortune cookie tracker
  25. // ==/UserScript==
  26.  
  27. // released versions:
  28. // Version 0.5.7 - clan speakeasy, new topmenu frame rearrangement, gm grant stuff, move to Greasy Fork
  29. // Version 0.5.5 - kolhs semis; red fox; bram the stoker
  30. // Version 0.5.4 - new undersea SRs
  31. // Version 0.5.3 - new giant castle SRs, fix oxygenarian detection
  32. // Version 0.5.2 - updated for new level 8 and level 9 semis, and typo for friars
  33. // Version 0.5.1 - new hidden temple semi rare
  34. // Version 0.5.0 - add last location info to char pane if no popups
  35. // Version 0.4.9 - bug fix for deep fat friars' adventure name
  36. // Version 0.4.8 - bug fix for auto-attack combat macros, change version check
  37. // Version 0.4.7 - add disable popups option as FF4 workaround
  38. // Version 0.4.6 - bug fix for noncombat semis
  39. // Version 0.4.5 - Show initial bracket for new ascension, bug fix for puttied/faxed/arrow'd SR monsters
  40. // Version 0.4.4 - ascii, kge fights from fax/putty/camera/arrowing aren't semis; support new options page
  41. // Version 0.4.3 - add elf alley semi
  42. // Version 0.4.2 - add the pixel stopwatch
  43. // Version 0.4.1, use the turnsplayed native counter
  44. // Version 0.4.0, display a predicted cookie window if no cookie eaten
  45. // Version 0.3.9, support for billiards room semi
  46. // Version 0.3.8, sanity check numbers when user loads charsheet
  47. // Version 0.3.7, misc bug fixes
  48. // Version 0.3.6, fixes (courtesy Firvagor) for crimbo anti-lag changes to inventory screens; clear counter after semi-rare
  49. // Version 0.3.5, filter impossible cookie values; check for updates automatically
  50. // Version 0.3.4, support for hobopolis adventures
  51. // Version 0.3.3, bugfixes encore
  52. // Version 0.3.2, bugfixes
  53. // Version 0.3.1, bugfixes
  54. // Version 0.3.0, remember most recent semi-rare. Re-fix bugs re-introduced in 0.2.6
  55. // for unascended chars and compact mode, thanks to bad version control.
  56. // Version 0.2.6, reduced overhead, and bug fixes
  57. // Version 0.2.5, compact mode support and support for unascended chars
  58. // Version 0.2.3, improved sanity checker
  59. // Version 0.2.0, includes sanity checker
  60. // Version 0.1.1, bugfixes
  61. // Version 0.1.0 initial beta
  62.  
  63. // Known bugs:
  64. // doesn't work in the kolmafia relay browser if you have this option set:
  65. // [] Force results to reload inline for [use] links
  66. // ... because the results page never reloads, so greasemonkey scripts don't run
  67. // may not save data correctly if Firefox doesn't exit cleanly (Greasemonkey issue)
  68.  
  69. // basic logic to do this without retrieving character pane data:
  70. // - store an internal counter for adventures used
  71. // - look at the adventures remaining
  72. // - every time the pane is refreshed:
  73. // - if the remaining adventures decreases, decrease the counter by that amount
  74. // - if stays the same, do nothing
  75. // - if increases, do nothing
  76. // warn when hit zero
  77. //
  78. // read char sheet as a sanity check when the counter doesn't seem to be
  79. // decrementing normally
  80.  
  81. // (temporarily?) unused, with move to Greasy Fork
  82. /* var currentVersion = "0.5.7";
  83. var scriptSite = "http://userscripts.org/scripts/show/13180"
  84. // this is autogenerated by userscripts.org from Userscript @ comments above, use to reduce bandwidth on version check
  85. var scriptURL = "http://userscripts.org/scripts/source/13180.meta.js";
  86. */
  87. ////////////////////////////////////////////////////////////////////////////////
  88. // Based on a function taken from OneTonTomato's UpUp skill script
  89. function GM_get(target, callback) {
  90. GM_xmlhttpRequest({
  91. method: 'GET',
  92. url: target,
  93. onload:function(details) {
  94. if( typeof callback=='function' ){
  95. callback(details.responseText);
  96. }
  97. }
  98. });
  99. }
  100.  
  101. // Check version number of script on the web
  102. function CheckScriptVersion(data)
  103. {
  104. // alert("inside version check");
  105. // Preemptively set error, in case request fails...
  106. GM_setValue("webVersion", "Error")
  107.  
  108. var m = data.match(/@version\s*([0-9.]+)/);
  109. if (m) {
  110. GM_setValue("webVersion", m[1]);
  111. }
  112. }
  113.  
  114. ////////////////////////////////////////////////////////////////////////////////
  115. // parse the char pane for the player name
  116. // revised version! now taken directly from kolpreviousnadventures to handle compact mode
  117. function getPlayerNameFromCharpane() {
  118. var username = document.getElementsByTagName("b");
  119. if (!username || username.length < 1) return false;
  120. username = username[0];
  121. if (!username) return false;
  122. username = username.firstChild;
  123. if (!username) return false;
  124. // in full mode the link is <a><b>Name</b></a>
  125. // in compact mode it's <b><a>Name</a></b>
  126. // so have to handle this, and also can use it to tell
  127. // whether it's in compact mode or not.
  128. var fullmode = true;
  129. while (username && username.nodeType == 1)
  130. {
  131. username = username.firstChild;
  132. fullmode = false;
  133. }
  134. if (!username) return false;
  135. username = username.nodeValue;
  136. if (!username) return false;
  137. username = username.toLowerCase();
  138. // alert("found username " + username + ", fullmode: " + fullmode);
  139. return {'username': username, 'fullmode': fullmode};
  140. }
  141.  
  142. ////////////////////////////////////////////////////////////////////////////////
  143. // parse the char sheet (not the sidepane) for the player name
  144. function getPlayerNameFromCharsheet(data) {
  145. // it's an href with syntax something like
  146. // showplayer.php?who=PlayerID">PlayerName</a>
  147. var playerName = /showplayer\.php\?who\=\d+\">([^<]+)<\/a/i.exec(data); // sometimes this fails, don't know why
  148. if(playerName)
  149. return playerName[1].toLowerCase();
  150. else
  151. return null;
  152. }
  153.  
  154. ////////////////////////////////////////////////////////////////////////////////
  155. // parse the char sheet (not pane) for the total adventure count
  156. // taken from the csemaj cookie script
  157. // the "(this run)" only appears if you have ascended
  158. function getTurnsPlayed(data) {
  159. var turncount = "0";
  160. if(data.indexOf("Turns Played (this run)") >= 0) {
  161. // alert("parsing datasheet for turns for an ascended char");
  162. turncount = /Turns Played \(this run\)[^>]*>(<[^>]+>)*([\d,]+)/i.exec(data)[2];
  163. }
  164. else {
  165. // alert("parsing datasheet for turns for an UNascended char");
  166. turncount = /Turns Played[^>]*>(<[^>]+>)*([\d,]+)/i.exec(data)[2];
  167. }
  168. // alert("found turncount=" + turncount);
  169. return parseInt(turncount.replace(',',''),10);
  170. }
  171.  
  172. function getDaysPlayed(data) {
  173. var dayCount = 0;
  174. if(data.indexOf("Days Played (this run)") >= 0) {
  175. // alert("parsing datasheet for days for an ascended char");
  176. dayCount = /Days Played \(this run\)[^>]*>(<[^>]+>)*([\d,]+)/i.exec(data)[2];
  177. }
  178. else {
  179. // alert("parsing datasheet for days for an UNascended char");
  180. dayCount = /Days Played[^>]*>(<[^>]+>)*([\d,]+)/i.exec(data)[2];
  181. }
  182. // alert("found dayCount=" + dayCount);
  183. return parseInt(dayCount.replace(',',''),10);
  184. }
  185.  
  186. // parse the charpane info for the password hash (use as a session ID)
  187. function getPwdHash(data){
  188. var pwdHash = /pwdhash \= \"(.*?)\"/i.exec(data)[1]; // the .*? is the non-greedy version of .*
  189.  
  190. // alert("got pwdHash: " + pwdHash);
  191. return pwdHash;
  192. }
  193.  
  194. // parse the charpane info for the turnsplayed counter
  195. // updates at the end of the adventure, not during the fight
  196. function getTurnsplayedVar(data){
  197. var turnsplayed = /turnsthisrun \= (\d+)/i.exec(data)[1];
  198.  
  199. return parseInt(turnsplayed);
  200. }
  201.  
  202. ////////////////////////////////////////////////////////////////////////////////
  203. // parse the main page for the name of the (noncombat) adventure - assuming
  204. // it's the next bolded thing after "Adventure Results:"
  205. function getAdventureName(data) {
  206. var adventureName = "";
  207. if ( data.indexOf( "Adventure Results:" ) != -1 ) { // kol mafia can put up stuff that requires this check
  208. adventureName = /Results:<\/b>.*?<b>(.*?)<\/b>/i.exec(data)[1];
  209. }
  210. // the hobopolis rares are choice adventures, not normal noncombats
  211. else if(document.location.pathname.indexOf("choice.php") != -1) {
  212. // look for adventure name as something in bold on blue background
  213. adventureName = /bgcolor=\"blue\"><b>(.*?)<\/b>/i.exec(data)[1];
  214. }
  215. // check for known broken adventures
  216. if(adventureName == "") {
  217. if(data.indexOf( "There once was a bleary-eyed cyclops" ) != -1 ){
  218. adventureName = "The Bleary-Eyed Cyclops";
  219. }
  220. }
  221.  
  222. // alert("got adventure name: " + adventureName);
  223. return adventureName;
  224. }
  225.  
  226. ////////////////////////////////////////////////////////////////////////////////
  227. // parse the main page for the name of the adventure
  228. function getMonsterName(data) {
  229. var monsterName = /id=\"monname\"> *(.*?)<\/span>/i.exec(data);
  230. if(monsterName)
  231. monsterName = monsterName[1].toLowerCase();
  232. else
  233. return {'monsterName': "", 'fromPutty': false};
  234. // don't count monsters from putty/fax/camera/arrowing
  235. var fromPutty = data.indexOf("You put the copied monster on the ground") != -1 ? true : false;
  236. if(!fromPutty)
  237. fromPutty = data.indexOf("You gaze at the photocopy") != -1 ? true : false;
  238. if(!fromPutty)
  239. fromPutty = data.indexOf("You reach down to open up the camera") != -1 ? true : false;
  240. if(!fromPutty)
  241. fromPutty = data.indexOf("hear a wolf whistle from behind you") != -1 ? true : false;
  242. if(!fromPutty)
  243. fromPutty = data.indexOf("You play back the recording") != -1 ? true : false;
  244. if(!fromPutty)
  245. fromPutty = data.indexOf("%%") != -1 ? true : false; // some sort of error we see a lot with copied monsters
  246. // alert("got monster name: *" + monsterName + "*; from putty = " + fromPutty);
  247. return {'monsterName': monsterName, 'fromPutty': fromPutty};
  248. }
  249.  
  250. // process a noncombat result for semi-rareness
  251. var semis =
  252. {
  253. noncombats: {
  254. "Play Misty For Me" : "the Haunted Kitchen",
  255. "Like the Sunglasses, But Less Comfortable" : "the Haunted Library",
  256. "The Pilsbury Doughjerk" : "the Haunted Pantry",
  257. "The Bleary-Eyed Cyclops" : "the Limerick Dungeon", // I don't see the title appear when I get this adv.
  258. "In the Still of the Alley" : "the Sleazy Back Alley",
  259. "Natural Selection" : "the Goatlet",
  260. "Not Quite as Cold as Ice" : "the Lair of the Ninja Snowmen",
  261. "Prior to Always" : "a Battlefield",
  262. "How Does He Smell?" : "the Batrat and Ratbat Burrow",
  263. "All The Rave" : "the Castle Top Floor",
  264. "Le Chauve-Souris du Parfum" : "Guano Junction",
  265. "Hands On" : "the Harem",
  266. "You Can Top Our Desserts, But You Can't Beat Our Meats" : "the Laboratory",
  267. "Rokay, Raggy!" : "the Menagerie Level 2",
  268. "A Menacing Phantom" : "the Misspelled Cemetery",
  269. "Lunchboxing" : "the Outskirts of Cobb's Knob",
  270. "Filth, Filth, and More Filth" : "South of the Border",
  271. "It's The Only Way To Be Sure" : "the Deep Fat Friars",
  272. "It's the Only Way to be Sure" : "Pandamonium slums",
  273. "Two Sizes Too Small" : "the Hidden City",
  274. "Some Bricks Do, In Fact, Hang in the Air" : "the Inexplicable Door",
  275. "Blaaargh! Blaaargh!" : "the Spooky Forest",
  276. "Monty of County Crisco" : "Whitey's Grove",
  277. "The Latest Sorcerous Developments" : "the Hippy Camp (pre-war)",
  278. "Sand in the Vaseline" : "the Orcish Frat House (pre-war)",
  279. "Yo Ho Ho and a Bottle of Whatever This Is" : "the Obligatory Pirate's Cove",
  280. "A Tight Squeeze" : "BurnBarrel Blvd.",
  281. "Cold Comfort" : "Exposure Esplanade",
  282. "Juicy!" : "the Heap",
  283. "Flowers for You" : "the Ancient Hobo Burial Ground",
  284. "Maybe It's a Sexy Snake!" : "the Purple Light District",
  285. "What a Tosser" : "Elf Alley",
  286. "A Shark's Chum" : "The Haunted Billiards Room",
  287. "The Time This Fire" : "Vanya's Castle Chapel",
  288. "Oh, <i>There</i> Have it Gone" : "A-Boo Peek",
  289. "Synecdoche, Twin Peak" : "Twin Peak",
  290. "It's a Gas Gas Gas" : "Oil Peak",
  291. "Fit and Finish" : "the Castle Basement",
  292. "Ahead of the Game" : "the Castle Ground Floor",
  293. "Razor, Scooter" : "the Dive Bar",
  294. "Deeps Impact" : "the Briny Deeps",
  295. "The Haggling" : "the Brinier Deepers",
  296. "Camera On, James" : "the Wreck of the Edgar Fitzsimmons",
  297. "Dragon the Line" : "Madness Reef",
  298. "A Drawer of Chests" : "the Mer-Kin Outpost",
  299. "Through the Locking Glass" : "the Hallowed Halls",
  300. "Clay Is Great, But Leather Is Bether" : "Ye Olde Medievale Villagee",
  301. "Where There's Smoke...": "The Copperhead Club",
  302. "Methinks the Protesters Doth Protest Too Little": "A Mob of Zeppelin Protesters",
  303. // fake ones for testing
  304. // "A Dash of Boulder" : "the Dungeons of Doom - Boulder",
  305. // "Meat Score!" : "the Treasury - Meat Score",
  306. },
  307. combats: { // use lowercase
  308. "some bad ascii art" : "the Valley Beyond The Orc Chasm",
  309. "a knob goblin elite guard captain" : "the Cobb's Knob Kitchens",
  310. "a knob goblin embezzler" : "the Treasury",
  311. "a c. h. u. m. chieftain" : "a Maze of Sewer Tunnels",
  312. "baa'baa'bu'ran" : "the Hidden Temple",
  313. "a 7-foot dwarf foreman" : "Itznotyerzitz Mine",
  314. "a moister oyster" : "An Octopus's Garden",
  315. "françois verte, art teacher" : "Art Class", // some encoding issue with this one
  316. "x-fingered shop teacher" : "Shop Class", // need to resolve the X (1-11)
  317. "mrs. k, the chemistry teacher" : "Chemistry class",
  318. "the red fox" : "The Red Zeppelin",
  319. "bram the stoker" : "The Haunted Boiler Room",
  320. "a full-length mirror" : "The Haunted Storage Room",
  321. // fake ones for testing
  322. // "a knob goblin elite guardsman" : "the Treasury",
  323. // "a swarm of killer bees" : "the Dungeons of Doom",
  324. },
  325. };
  326.  
  327. function clearCounters(playerName) {
  328. GM_setValue(playerName+"_lastSemiTurn",-1);
  329. GM_setValue(playerName+"_lastSemiLocation","");
  330. GM_setValue(playerName+"_luckyTurn1", -1);
  331. GM_setValue(playerName+"_luckyTurn2", -1);
  332. GM_setValue(playerName+"_luckyTurn3", -1);
  333. }
  334.  
  335. function checkForNoncombatSemi(data) {
  336. theAdv = getAdventureName(document.body.innerHTML);
  337. // alert("in checkForNoncombatSemi(), adv name = " + theAdv);
  338. // alert("semis.noncombats[theAdv] = " + semis.noncombats[theAdv]);
  339. if(semis.noncombats[theAdv] != undefined) {
  340. var playerName = GM_getValue("currentPlayer");
  341. var turncount = GM_getValue(playerName+"_turncount", 0);
  342. // var turncount = getTurnsplayedVar(top.frames[0].document);
  343.  
  344. // alert("Found semirare adv \'" + theAdv + "\' in area " + semis.noncombats[theAdv] + " on tuncount " + turncount + " for player " + playerName);
  345. // found a semi, clear counters
  346. // this might backfire if using the counter as a generic countdown for other purposes, e.g. wossname tracking
  347. clearCounters(playerName);
  348.  
  349. GM_setValue(playerName+"_lastSemiTurn",turncount+1); // the turncount var isn't updated yet
  350. GM_setValue(playerName+"_allowBracket",true);
  351. GM_setValue(playerName+"_lastSemiLocation",semis.noncombats[theAdv]);
  352.  
  353. // trigger char pane refresh with the new info
  354. top.frames[0].location.reload();
  355. }
  356. }
  357.  
  358. function checkForCombatSemi(data) {
  359. var monster = getMonsterName(document.body.innerHTML);
  360. theAdv = monster.monsterName;
  361.  
  362. if(monster.fromPutty == false && semis.combats[theAdv] != undefined) {
  363. var playerName = GM_getValue("currentPlayer");
  364. var turncount = GM_getValue(playerName+"_turncount", 0);
  365. // var turncount = getTurnsplayedVar(top.frames[0].document);
  366.  
  367. // alert("Found semi rare adv \'" + theAdv + "\' in area " + semis.combats[theAdv] + " - for player " + playerName + " on turn " + turncount );
  368. // found a semi, clear counters
  369. // this might backfire if using the counter as a generic countdown for other purposes, e.g. wossname tracking
  370. clearCounters(playerName);
  371.  
  372. GM_setValue(playerName+"_lastSemiTurn",turncount+1); // the turncount var isn't updated yet
  373. GM_setValue(playerName+"_allowBracket",true);
  374. GM_setValue(playerName+"_lastSemiLocation",semis.combats[theAdv]);
  375.  
  376. // trigger char pane refresh with the new info
  377. top.frames[0].location.reload();
  378. }
  379. }
  380.  
  381. ////////////////////////////////////////////////////////////////////////////////
  382. // callback function to process the main charsheet as a sanity check after
  383. // something questionable was spotted, or just on a new session
  384. // **** mostly deprecated ****
  385. function sanityCheckCharsheet(data) {
  386. // alert("entering sanity check");
  387. var playerName = getPlayerNameFromCharsheet(data);
  388. GM_setValue("currentPlayer", playerName);
  389. var turncount = getTurnsPlayed(data); // total turns played
  390. if(isNaN(turncount) ) {
  391. // alert("sanityCheckCharsheet - unable to parse either turncount (" + turncount + ") or remaining adv count (" + remainingAdventureCount + "), aborting");
  392. return; // hopefully will try again with more success, can't continue
  393. }
  394.  
  395. GM_setValue(playerName+"_turncount", turncount); // I'll try to keep this up to date
  396.  
  397. // if the previous turncount makes no sense, zero it. After ascending would be an example
  398. var lastSemiTurn = GM_getValue(playerName+"_lastSemiTurn",-1);
  399. if( lastSemiTurn > turncount+1) {
  400. GM_setValue(playerName+"_lastSemiTurn",-1);
  401. GM_setValue(playerName+"_lastSemiLocation","");
  402. }
  403. var prevDayCount = GM_getValue(playerName+"_dayCount",-1);
  404.  
  405. var dayCount = getDaysPlayed(data);
  406. if(!isNaN(dayCount)) {
  407. if(dayCount < prevDayCount) { // must have ascended
  408. GM_setValue(playerName+"_lastSemiTurn",-1);
  409. GM_setValue(playerName+"_lastSemiLocation","");
  410. }
  411. GM_setValue(playerName+"_dayCount",dayCount);
  412. }
  413.  
  414. // set a flag is we are oxy, since it affects the cookie spacing
  415. if( data.match("Oxygenarian"))
  416. GM_setValue(playerName+"_isOxy", true);
  417. else
  418. GM_setValue(playerName+"_isOxy", false);
  419. }
  420.  
  421. ////////////////////////////////////////////////////////////////////////////////
  422. // watch for the lucky numbers result on the main page
  423. function processMain(doc) {
  424. var countdown1 = -1;
  425. var countdown2 = -1;
  426. var countdown3 = -1;
  427. var pos = -1;
  428.  
  429. // alert("in processMain()");
  430. ///////NEW STUFF (Firvagor) - changed the if line to use the div instead of the body, since the results, and a hidden field is made inside the div so infinite looping doesn't occur//////////
  431. //if the hidden field is found, don't do anything
  432. if (doc.getElementById("cookiedone")!=null){return;}
  433.  
  434. var playerName = GM_getValue( "currentPlayer");
  435. var divElement = doc.getElementById("effdiv");
  436. var bqElement = doc.getElementsByTagName("blockquote");
  437. // if(bqElement[0])
  438. // alert("processMain: speakeasy quote = " + bqElement[0]);
  439.  
  440. if ( divElement ) {
  441. // alert("found divElement");
  442.  
  443. doc.getElementById("effdiv").innerHTML += "<input type='hidden' id='cookiedone' name='completed' value='yes'>";
  444. if((pos = doc.getElementById("effdiv").innerHTML.indexOf( "Lucky numbers:" )) != -1 ) {
  445.  
  446. // alert("found lucky numbers");
  447. // need to parse the text, format is "Lucky numbers: ###, ###, ###"
  448. var cookieText = doc.getElementById("effdiv").innerHTML.substring(pos, pos+30);
  449.  
  450. // first one starts after the colon, next two after commas
  451. pos = cookieText.indexOf(":");
  452. cookieText = cookieText.substring(pos+1);
  453. countdown1 = parseInt(cookieText);
  454.  
  455. pos = cookieText.indexOf(",");
  456. cookieText = cookieText.substring(pos+1);
  457. countdown2 = parseInt(cookieText);
  458.  
  459. pos = cookieText.indexOf(",");
  460. cookieText = cookieText.substring(pos+1);
  461. countdown3 = parseInt(cookieText);
  462.  
  463. // elegantly sort them
  464. {
  465. var temp;
  466. if(countdown1 > countdown2) {
  467. temp = countdown1; countdown1 = countdown2; countdown2 = temp;
  468. }
  469. if(countdown2 > countdown3) {
  470. temp = countdown2; countdown2 = countdown3; countdown3 = temp;
  471. }
  472. if(countdown1 > countdown2) {
  473. temp = countdown1; countdown1 = countdown2; countdown2 = temp;
  474. }
  475. }
  476. // alert("processMain: cookie cookieText=" + cookieText + ", lucky numbers are " + countdown1 + ", " + countdown2 + ", " + countdown3);
  477. }
  478. }
  479. // speakeasy drink; format is "burp-speak the number <b>30</b>"
  480. // doesn't work, is there really an effdiv for this? didn't see it in the text
  481. // try a blockquote instead... doesn't sound too reliable
  482. // else if((pos = doc.getElementById("effdiv").innerHTML.indexOf( "burp-speak the number" )) != -1 ) {
  483. if(bqElement[0] && (pos = bqElement[0].innerHTML.indexOf( "burp-speak the number" )) != -1 ) {
  484. // alert("processing speakeasy");
  485. bqElement[0].innerHTML += "<input type='hidden' id='cookiedone' name='completed' value='yes'>";
  486. var cookieText = bqElement[0].innerHTML.substring(pos, pos+30);
  487.  
  488. // just one number, bolded
  489. pos = cookieText.indexOf("<b>");
  490. cookieText = cookieText.substring(pos+3);
  491. countdown1 = parseInt(cookieText);
  492. countdown2 = -1;
  493. countdown3 = -1;
  494. // alert("processMain: speakeasy cookieText=" + cookieText + ", lucky numbers are " + countdown1 + ", " + countdown2 + ", " + countdown3);
  495. }
  496.  
  497. if(countdown1>=0 || countdown2>=0 || countdown3>=0) {
  498. // filter out nonsense values:
  499. // - too high ( > 200 since last semi, 120 for oxy)
  500. // - too low ( < 160 since last semi, or < 100 if oxy)
  501. // the filters only apply if you found a semi recently; otherwise the counter starts
  502. // after a would-be semi, or ascension, with your first adventure.php location
  503. // adventure, but it's too much trouble to keep track
  504. GM_setValue(playerName+"_allowSanityCheck", false); // lock out the other pane from panicking
  505. // must call processCharsheet now, to clear this
  506. var allowBracket = GM_getValue(playerName+"_allowBracket",false);
  507. GM_setValue(playerName+"_allowBracket",false); // no reason to put up reminder after this
  508.  
  509. var turncount = GM_getValue(playerName+"_turncount", 0);
  510. var lastSemiTurn = GM_getValue(playerName+"_lastSemiTurn",-1);
  511. var wasOxy = GM_getValue(playerName+"_isOxy", false);
  512. GM_setValue(playerName+"_isOxy", false); // ate a cookie, must not be oxy
  513. var minCount = 160; var maxCount = 200;
  514. if( wasOxy ) {
  515. minCount = 100; maxCount = 120;
  516. }
  517. if(turncount < 70) { // newly ascended
  518. minCount = 70; maxCount = 80; lastSemiTurn = 0;
  519. }
  520. var turnsSinceSemi = turncount - lastSemiTurn;
  521.  
  522. // alert("filtering lucky numbers for " + playerName + " based on turncount=" + turncount + ", lastSemiTurn=" + lastSemiTurn + ", wasOxy=" + wasOxy + ", turnsSinceSemi = " + turnsSinceSemi );
  523. // eliminate counters that are too high on an absolute basis, then try to
  524. // eliminate ones too high and low based on last semi
  525. if(countdown1 > maxCount) countdown1 = -1;
  526. if(countdown2 > maxCount) countdown2 = -1;
  527. if(countdown3 > maxCount) countdown3 = -1;
  528. if(lastSemiTurn != -1 && turnsSinceSemi <= maxCount && allowBracket) {
  529. if( countdown1 + turnsSinceSemi > maxCount ) countdown1 = -1;
  530. if( countdown2 + turnsSinceSemi > maxCount ) countdown2 = -1;
  531. if( countdown3 + turnsSinceSemi > maxCount ) countdown3 = -1;
  532. }
  533. if(lastSemiTurn != -1) {
  534. if( countdown1 + turnsSinceSemi < minCount ) countdown1 = -1;
  535. if( countdown2 + turnsSinceSemi < minCount ) countdown2 = -1;
  536. if( countdown3 + turnsSinceSemi < minCount ) countdown3 = -1;
  537. }
  538. // now to compare them vs existing numbers
  539. // if there is no match, stick them in as the current numbers
  540. // if there is a match, use that and zero the other two
  541. var oldLuckyTurn1 = GM_getValue(playerName+"_luckyTurn1",-1);
  542. var oldLuckyTurn2 = GM_getValue(playerName+"_luckyTurn2",-1);
  543. var oldLuckyTurn3 = GM_getValue(playerName+"_luckyTurn3",-1);
  544. var oldCountdown1 = oldLuckyTurn1 != -1 ? oldLuckyTurn1 - turncount : -1;
  545. var oldCountdown2 = oldLuckyTurn2 != -1 ? oldLuckyTurn2 - turncount : -1;
  546. var oldCountdown3 = oldLuckyTurn3 != -1 ? oldLuckyTurn3 - turncount : -1;
  547.  
  548. var noPopups = GM_getValue("noPopups", false);
  549. // need to watch out for -1 matching -1 since we reset values above
  550. // check for self-match in new cookie values first
  551. if(countdown1 != -1 && (countdown1==countdown2 || countdown1 == countdown3)) {
  552. if(!noPopups) alert(countdown1 + " turns until a semi-rare!");
  553. countdown2 = -1;
  554. countdown3 = -1;
  555. }
  556. else if(countdown2 != -1 && countdown2 == countdown3) {
  557. if(!noPopups) alert(countdown2 + " turns until a semi-rare!");
  558. countdown1 = -1;
  559. countdown3 = -1;
  560. }
  561. else if (countdown1 != -1 && (countdown1 == oldCountdown1 || countdown1 == oldCountdown2 || countdown1 == oldCountdown3 || countdown2 == -1 && countdown3 == -1)) {
  562. if(!noPopups) alert(countdown1 + " turns until a semi-rare!");
  563. countdown2 = -1;
  564. countdown3 = -1;
  565. }
  566. else if (countdown2 != -1 && (countdown2 == oldCountdown1 || countdown2 == oldCountdown2 || countdown2 == oldCountdown3 || countdown1 == -1 && countdown3 == -1)) {
  567. if(!noPopups) alert(countdown2 + " turns until a semi-rare!");
  568. countdown1 = -1;
  569. countdown3 = -1;
  570. }
  571. else if (countdown3 != -1 && (countdown3 == oldCountdown1 || countdown3 == oldCountdown2 || countdown3 == oldCountdown3 || countdown1 == -1 && countdown2 == -1)) {
  572. if(!noPopups) alert(countdown3 + " turns until a semi-rare!");
  573. countdown1 = -1;
  574. countdown2 = -1;
  575. }
  576. GM_setValue(playerName+"_luckyTurn1",countdown1 != -1 ? countdown1 + turncount : -1);
  577. GM_setValue(playerName+"_luckyTurn2",countdown2 != -1 ? countdown2 + turncount : -1);
  578. GM_setValue(playerName+"_luckyTurn3",countdown3 != -1 ? countdown3 + turncount : -1);
  579.  
  580. // load and parse the main charsheet to set the behind the scene variables that
  581. // convert the cookie countdown into actual adventure number for each cookie
  582. // GM_get(baseURL + charSheet, processCharsheet);
  583.  
  584. // trigger char pane refresh with the new info
  585. top.frames[0].location.reload();
  586. }
  587. }
  588.  
  589. ////////////////////////////////////////////////////////////////////////////////
  590. function manualCookieEntry() {
  591. var playerName = getPlayerNameFromCharpane().username;
  592. // alert("player name: " + playerName);
  593. GM_setValue("currentPlayer", playerName); // store for other functions that need to know who's playing
  594. var noPopups = GM_getValue("noPopups", false);
  595. if(noPopups) return; // need to figure out some way to enter values without using a popup
  596. var turncount = GM_getValue(playerName+"_turncount", -1);
  597. var luckyTurn1 = GM_getValue(playerName+"_luckyTurn1", -1);
  598. var luckyTurn2 = GM_getValue(playerName+"_luckyTurn2", -1);
  599. var luckyTurn3 = GM_getValue(playerName+"_luckyTurn3", -1);
  600. var oldCountdown1 = luckyTurn1 > 0 ? luckyTurn1 - turncount : -1;
  601. var oldCountdown2 = luckyTurn2 > 0 ? luckyTurn2 - turncount : -1;
  602. var oldCountdown3 = luckyTurn3 > 0 ? luckyTurn3 - turncount : -1;
  603.  
  604. var countdown1 = -1;
  605. var countdown2 = -1;
  606. var countdown3 = -1;
  607. var displayText = "";
  608. if(oldCountdown1 > -1)
  609. displayText += oldCountdown1;
  610. if(oldCountdown2 > -1) {
  611. if(displayText != "") displayText += ", ";
  612. displayText += oldCountdown2;
  613. }
  614. if(oldCountdown3 > -1) {
  615. if(displayText != "") displayText += ", ";
  616. displayText += oldCountdown3;
  617. }
  618.  
  619. var lastSemiTurn = GM_getValue(playerName+"_lastSemiTurn",-1);
  620. var lastSemiLocation = GM_getValue(playerName+"_lastSemiLocation","");
  621. var promptText = "";
  622. if(lastSemiTurn > -1 && turncount >= lastSemiTurn ) {
  623. promptText = "Last semirare found " + (turncount - lastSemiTurn) + " turns ago, at " + lastSemiLocation + ".\n\n";
  624. }
  625. else {
  626. promptText = "Last semirare unknown.\n\n"
  627. }
  628. cookieText = prompt(promptText + "Enter 1-3 new cookie vals (-1 to clear)\n", displayText);
  629.  
  630. if(cookieText) { // will be null if user cancels
  631. countdown1 = parseInt(cookieText);
  632. var pos = cookieText.indexOf(",");
  633. if(pos > 0) {
  634. cookieText = cookieText.substring(pos+1);
  635. countdown2 = parseInt(cookieText);
  636. pos = cookieText.indexOf(",");
  637. if(pos > 0) {
  638. cookieText = cookieText.substring(pos+1);
  639. countdown3 = parseInt(cookieText);
  640. }
  641. }
  642. // alert("manual text entry, got values " + countdown1 + ", " + countdown2 + ", " + countdown3);
  643. GM_setValue(playerName+"_luckyTurn1",countdown1+turncount);
  644. GM_setValue(playerName+"_luckyTurn2",countdown2+turncount);
  645. GM_setValue(playerName+"_luckyTurn3",countdown3+turncount);
  646. GM_setValue(playerName+"_needSanityCheck", false); // just in case we were in the middle of something
  647. GM_setValue(playerName+"_allowBracket",false); // no reason to put up reminder after this
  648.  
  649. // load and parse the main charsheet to set the behind the scene variables that
  650. // convert the cookie countdown into actual adventure number for each cookie
  651. // GM_get(baseURL + charSheet, processCharsheet);
  652. // trigger char pane refresh with the new info
  653. top.frames[0].location.reload();
  654.  
  655. }
  656. }
  657.  
  658. ////////////////////////////////////////////////////////////////////////////////
  659. // this function must be called when we are in the char sidepane
  660. function getPlayerLevel(data) {
  661. var playerLevel = /Level (\d+)/i.exec(data); // full mode
  662. if( !playerLevel)
  663. playerLevel = /Lvl\. (\d+)/i.exec(data); // compact mode
  664. if( playerLevel)
  665. return parseInt(playerLevel[1],10);
  666.  
  667. // normal level checks fail if astral spirit
  668. if(data.indexOf("Astral Spirit") != -1)
  669. return 0; // astral spirit
  670. else
  671. return -1; // error
  672. }
  673.  
  674. ////////////////////////////////////////////////////////////////////////////////
  675. // this function must be called when we are in the char sidepane
  676. function updateCharacterPane() {
  677. var a = getPlayerNameFromCharpane();
  678. var playerName = a.username;
  679. var fullmode = a.fullmode;
  680. if( playerName == null ) // not sure why we sometimes see this, but doesn't seem to be at critical times
  681. return;
  682.  
  683. GM_setValue("currentPlayer", playerName); // store for other functions that need to know who's playing
  684. // if astral plane, need to reset counters
  685. // getPlayerLevel() returns 0 for astral plane
  686. var playerLevel = getPlayerLevel(document.documentElement.innerHTML);
  687. if(playerLevel == 0) {
  688. // clear the counters, no point in doing anything else
  689. clearCounters(playerName);
  690. return;
  691. }
  692.  
  693. // check the session ID to see if we are still in the same session
  694. // if a new session, check if an update is available
  695. var pwdHash = getPwdHash(document.documentElement.innerHTML);
  696. var oldPwdHash = GM_getValue(playerName + "_pwdHash", 0);
  697. if(pwdHash != oldPwdHash) {
  698. // new session
  699. GM_setValue(playerName + "_pwdHash", pwdHash);
  700. // run sanity check on new session, make sure we haven't missed anything
  701. // alert("calling sanity check");
  702. GM_get(baseURL + charSheet, sanityCheckCharsheet);
  703. // check for a new version of script if none seen already (asynch call, will run in parallel)
  704. // (temporarily?) removed for use with greasy fork
  705. /* var webVer = GM_getValue("webVersion", "Error");
  706. if(webVer == "Error" || webVer <= currentVersion) {
  707. // alert("calling version check");
  708. GM_get(scriptURL, CheckScriptVersion);
  709. }
  710. */
  711. }
  712.  
  713. // new native counter!
  714. var turncount = getTurnsplayedVar(document.documentElement.innerHTML);
  715. var oldTurncount = GM_getValue(playerName+"_turncount", 0);
  716. GM_setValue(playerName+"_turncount", turncount);
  717.  
  718. var lastSemiTurn = GM_getValue(playerName+"_lastSemiTurn",-1);
  719. var lastSemiLocation = GM_getValue(playerName+"_lastSemiLocation","");
  720. if(lastSemiTurn > turncount + 1) { // turncount var lags behind when fighting, so can have an off-by-1 issue
  721. // could happen if ascended
  722. lastSemiTurn = -1;
  723. GM_setValue(playerName+"_lastSemiTurn",-1);
  724. GM_setValue(playerName+"_lastSemiLocation","");
  725. }
  726.  
  727. var luckyTurn1 = GM_getValue(playerName+"_luckyTurn1", -1);
  728. var luckyTurn2 = GM_getValue(playerName+"_luckyTurn2", -1);
  729. var luckyTurn3 = GM_getValue(playerName+"_luckyTurn3", -1);
  730.  
  731. // if anything hit zero, warn the user
  732. var noPopups = GM_getValue("noPopups", false);
  733. var atSemi = false;
  734. if( turncount == luckyTurn1 || turncount == luckyTurn2 || turncount == luckyTurn3) {
  735. atSemi = true;
  736. if(!noPopups && turncount != oldTurncount) {
  737. var alertText = "Fortune cookie countdown hit zero!";
  738. if(lastSemiTurn > -1 && turncount >= lastSemiTurn) {
  739. alertText += "\n\nLast semirare found " + (turncount - lastSemiTurn) + " turns ago, at " + lastSemiLocation + ".";
  740. }
  741. else {
  742. alertText += "\n\nLast semirare unknown.";
  743. }
  744. confirm(alertText);
  745. }
  746. }
  747. var displayText = "";
  748. if(luckyTurn1 >= turncount)
  749. displayText += luckyTurn1 - turncount;
  750. if(luckyTurn2 >= turncount) {
  751. if(displayText != "") displayText += ", ";
  752. displayText += luckyTurn2 - turncount;
  753. }
  754. if(luckyTurn3 >= turncount) {
  755. if(displayText != "") displayText += ", ";
  756. displayText += luckyTurn3 - turncount;
  757. }
  758. if(atSemi && noPopups)
  759. displayText += " (last SR: " + (lastSemiLocation == "" ? "unknown" : lastSemiLocation) + ")";
  760. if(atSemi && fullmode) { // shows the html literally in compact mode
  761. displayText = "<font color=\"red\"><b>" + displayText + "</b></font>";
  762. }
  763.  
  764. // display turn var to figure out exactly how it works
  765. // displayText += " (tp=" + turnsplayedVar+")";
  766. var hideIfZeros = GM_getValue("hideIfZeros", false);
  767.  
  768. if(displayText != ""
  769. || hideIfZeros == false ) {
  770. // display an FC bracket if no cookie eaten, and have found a semi recently
  771. var isOxy = GM_getValue(playerName+"_isOxy", false);
  772. var turnsSinceSemi = turncount - lastSemiTurn;
  773. var minCount = 160; var maxCount = 200;
  774. if( isOxy ) {
  775. minCount = 100; maxCount = 120;
  776. }
  777. if(displayText == "" && lastSemiTurn != -1 && turnsSinceSemi <= maxCount ) {
  778. displayText = "[" + Math.max(0, minCount - turnsSinceSemi) + "...";
  779. displayText += Math.max(0, maxCount - turnsSinceSemi) + "]";
  780. } else if (displayText == "" && turncount < 70) { // default just-ascended bracket
  781. displayText = "[" + Math.max(0, 70 - turncount) + "...";
  782. displayText += Math.max(0, 80 - turncount) + "]";
  783. }
  784. if(fullmode) {
  785. var newElement = document.createElement("FONT");
  786. newElement.innerHTML = "<b>"
  787. + "<font size=2>Cookie Count: "
  788. + displayText
  789. + "</font></b><br><br>"; ;
  790. newElement.setAttribute("onmouseover", 'this.style.opacity="0.5"');
  791. newElement.setAttribute("onmouseout", 'this.style.opacity="1"');
  792. newElement.setAttribute("id", 'fortuneCookieCounter');
  793. newElement.addEventListener("click", manualCookieEntry, true);
  794. newElement.align = "center";
  795. var elements = document.getElementsByTagName( "FONT" );
  796. for ( var i = 0; i < elements.length; ++i ){
  797. if ( elements[i].innerHTML.indexOf( "Last Adventure" ) != -1 ){
  798. // insert our before this one
  799. elements[i].parentNode.insertBefore(newElement,elements[i]);
  800. break;
  801. }
  802. }
  803. }
  804. else { // compact mode - different layout, make a table row and two data element
  805. var newTR = document.createElement('tr');
  806.  
  807. var newElement = document.createElement("td");
  808. newElement.appendChild(document.createTextNode("Cookie:"));
  809. newElement.align = "right";
  810. newTR.appendChild(newElement);
  811. newElement = document.createElement("td");
  812. newElement.setAttribute("onmouseover", 'this.style.opacity="0.5"');
  813. newElement.setAttribute("onmouseout", 'this.style.opacity="1"');
  814. newElement.setAttribute("id", 'fortuneCookieCounter');
  815. newElement.addEventListener("click", manualCookieEntry, true);
  816. newElement.align = "left";
  817. newElement.style.fontWeight = "bold";
  818. newElement.appendChild(document.createTextNode(displayText));
  819. newTR.appendChild(newElement);
  820. var elements = document.getElementsByTagName( "TR" );
  821. var done = false;
  822. // if the last adventures script is running, insert before, else append to table
  823. for ( var i = 1; i < elements.length; ++i ){
  824. // normally "Adv", might be "Last Adventures" if that script is running
  825. if ( elements[i].innerHTML.indexOf( "Last Adventures" ) != -1 ){
  826. // insert ours before this one - experiment, back up one more
  827. elements[i].parentNode.insertBefore(newTR,elements[i-1]);
  828. done = true;
  829. break;
  830. }
  831. }
  832. if(!done) { // normal, no last adv script
  833. for ( var i = 0; i < elements.length; ++i ){
  834. if ( elements[i].innerHTML.indexOf( "Adv" ) != -1 ){
  835. // insert ours at end of the table in compact mode
  836. elements[i].parentNode.appendChild(newTR);
  837. break;
  838. }
  839. }
  840. }
  841. }
  842. }
  843. }
  844.  
  845. ////////////////////////////////////////////////////////////////////////////////
  846. // set preferences
  847. // code stolen from mr script
  848. // not set on a per-player basis, would need to add code to parse account pane for char name
  849. function toggleHideCountdown() {
  850. // alert("in toggleHideCountdown()");
  851.  
  852. var hideIfZeros = GM_getValue("hideIfZeros", false);
  853. hideIfZeros = !hideIfZeros;
  854. GM_setValue("hideIfZeros", hideIfZeros);
  855. // trigger char pane refresh with the new info
  856. top.frames[0].location.reload();
  857. var msg = document.getElementById('cookiecountertoggle');
  858. msg.innerHTML = (hideIfZeros ? "Hiding" : "Showing") + " Inactive Counter - Click to Change";
  859. }
  860.  
  861. function togglePopups() {
  862. // alert("in toggleHideCountdown()");
  863.  
  864. var noPopups = GM_getValue("noPopups", false);
  865. noPopups = !noPopups;
  866. GM_setValue("noPopups", noPopups);
  867. // trigger char pane refresh with the new info
  868. var msg = document.getElementById('cookiepopups');
  869. msg.innerHTML = (noPopups ? "Popups Disabled " : "Using Popups") + " (disable for FF4) - Click to Change";
  870. top.frames[0].location.reload();
  871. }
  872.  
  873. // --------------------------------------------
  874. // ---------- account menu option -------------
  875. // --------------------------------------------
  876.  
  877. // Charon's code
  878. function buildPrefs() {
  879. if (!document.querySelector('#privacy'))
  880. return;
  881. if (!document.querySelector('#scripts')) {
  882. //scripts tab is not built, do it here
  883. var scripts = document.querySelector('ul').appendChild(document.createElement('li'));
  884. scripts.id = 'scripts';
  885. var a = scripts.appendChild(document.createElement('a'));
  886. a.href = '#';
  887. var img = a.appendChild(document.createElement('img'));
  888. img.src = 'http://images.kingdomofloathing.com/itemimages/cmonkey1.gif';
  889. img.align = 'absmiddle';
  890. img.border = '0';
  891. img.style.paddingRight = '10px';
  892. a.appendChild(document.createTextNode('Scripts'));
  893. a.addEventListener('click', function (e) {
  894. //make our new tab active when clicked, clear out the #guts div and add our settings to it
  895. e.stopPropagation();
  896. document.querySelector('.active').className = '';
  897. document.querySelector('#scripts').className = 'active';
  898. document.querySelector('#guts').innerHTML = '<div class="scaffold"></div>';
  899. document.querySelector('#guts').appendChild(getSettings());
  900. }, false);
  901. } else {
  902. //script tab already exists
  903. document.querySelector('#scripts').firstChild.addEventListener('click', function (e) {
  904. //some other script is doing the activation work, just add our settings
  905. e.stopPropagation();
  906. document.querySelector('#guts').appendChild(getSettings());
  907. }, false);
  908. }
  909. }
  910.  
  911. function getSettings() {
  912. //build our settings and return them for appending
  913. var guts = document.body.appendChild(document.createElement('div'));
  914. guts.id = 'cookieprefs';
  915. var subhead = guts.appendChild(document.createElement('div'));
  916. subhead.className = 'subhead';
  917. subhead.textContent = 'Fortune Cookie Counter';
  918. var section = guts.appendChild(document.createElement('div'));
  919. section.className = 'indent';
  920. //call function in main script to actually make the settings
  921. section.appendChild(buildSettings());
  922. return guts;
  923. }
  924.  
  925. function buildSettings() {
  926. var prefLink = document.createElement('a');
  927. var hideIfZeros = GM_getValue("hideIfZeros", false);
  928.  
  929. prefLink.setAttribute('href','javascript:void(0)');
  930. prefLink.setAttribute('id','cookiecountertoggle');
  931. prefLink.innerHTML = (hideIfZeros ? "Hiding" : "Showing") + " Inactive Counter - Click to Change";
  932. prefLink.addEventListener("click", toggleHideCountdown, true);
  933.  
  934. var prefAnchor = document.createElement('a');
  935. prefAnchor.setAttribute('name','opt'); prefAnchor.innerHTML = " ";
  936. var pDiddy = document.createElement('p');
  937. with(pDiddy)
  938. { appendChild(prefAnchor);
  939. appendChild(prefLink);
  940. }
  941.  
  942. prefLink = document.createElement('a');
  943. var noPopups = GM_getValue("noPopups", false);
  944.  
  945. prefLink.setAttribute('href','javascript:void(0)');
  946. prefLink.setAttribute('id','cookiepopups');
  947. prefLink.innerHTML = (noPopups ? "Popups Disabled " : "Using Popups") + " (disable for FF4) - Click to Change";
  948. prefLink.addEventListener("click", togglePopups, true);
  949.  
  950. prefAnchor = document.createElement('p');
  951. prefAnchor.setAttribute('name','opt'); prefAnchor.innerHTML = " ";
  952. with(pDiddy)
  953. { appendChild(prefAnchor);
  954. appendChild(prefLink);
  955. }
  956. // add a link to update, if an update is available
  957. // (temporarily?) removed for use with Greasy Fork
  958. /* var webVer = GM_getValue("webVersion");
  959. if (webVer != "Error" && webVer > currentVersion) { // this is actually a text string comparison, not numerical
  960. var newElement = document.createElement('p');
  961. newElement.style.fontSize = "x-small";
  962. newElement.appendChild(document.createTextNode("New cookie script version " + webVer + " available: "));
  963.  
  964. var hrefElement = document.createElement('a');
  965. hrefElement.setAttribute('href', scriptSite);
  966. hrefElement.setAttribute('target', "_blank");
  967. hrefElement.appendChild(document.createTextNode("here"));
  968. newElement.appendChild(hrefElement);
  969. pDiddy.appendChild(newElement);
  970. }
  971. */
  972. return pDiddy;
  973. }
  974.  
  975. ////////////////////////////////////////////////////////////////////////////////
  976. // main prog, just call the proper routine if we are on a pane we care about
  977. var nodeBody = document.getElementsByTagName("body").item(0);
  978. var textBody = "";
  979. var baseURL = "";
  980. var charSheet = "charsheet.php";
  981. var playerName = GM_getValue( "currentPlayer");
  982.  
  983. if (nodeBody) {
  984. if (nodeBody.textContent) {
  985. textBody = nodeBody.textContent;
  986. }
  987. else if (nodeBody.text) {
  988. textBody = nodeBody.text;
  989. }
  990. baseURL = nodeBody.baseURI.substring(0,nodeBody.baseURI.lastIndexOf('/')+1);
  991. }
  992.  
  993. // do normal page processing independently of whether started sanity check
  994. if ( document.location.pathname.indexOf("charpane.php") != -1 ) {
  995. //////NEW STUFF (Firvagor) - since the charpane refreshes every time something is used, if the results section is found, run main function using manually located mainpane (can only use indexing for some reason)/////
  996. if (top.frames[2].document.getElementById("effdiv")!=null) // was frames[1] until aug 2014 topmenu update
  997. processMain(top.frames[2].document);
  998. updateCharacterPane();
  999. }
  1000. else if ( document.location.pathname.indexOf("inventory.php") != -1
  1001. || document.location.pathname.indexOf("clan_viplounge.php")!= -1){
  1002. //alert("calling processMain() for " + document.location.pathname);
  1003. //////NEW STUFF (Firvagor) - passes in current document instead of nothing, just to define the frame used/////
  1004. GM_setValue(playerName+"_fighting",0);
  1005. processMain(document);
  1006. }
  1007. else if ( document.location.pathname.indexOf("charsheet.php") != -1){
  1008. // alert("calling sanityCheckCharsheet() for " + document.location.pathname);
  1009. GM_setValue(playerName+"_fighting",0);
  1010. sanityCheckCharsheet(document.body.innerHTML);
  1011. }
  1012. else if ( document.location.pathname.indexOf("account.php") != -1 ) {
  1013. // alert("calling set prefs for " + document.location.pathname);
  1014. GM_setValue(playerName+"_fighting",0);
  1015. buildPrefs();
  1016. // setPrefs();
  1017. }
  1018. else if ( document.location.pathname.indexOf("adventure.php") != -1
  1019. || document.location.pathname.indexOf("choice.php") != -1) {
  1020. // adventure.php should trap all "normal" noncombats
  1021. // choice noncombats are in choice.php - now needed for hobopolis
  1022. // for the fortune cookie combat rares, need to process fight.php
  1023. GM_setValue(playerName+"_fighting",0);
  1024. checkForNoncombatSemi(document.body.innerHTML);
  1025. }
  1026. else if ( document.location.pathname.indexOf("fight.php") != -1 ) {
  1027. // see if we are actively fighting (no asynch calls allowed while fighting!)
  1028. var fighting = GM_getValue(playerName+"_fighting",0)
  1029. // alert("prefight check - page = " + document.location.pathname + ", fighting = " + fighting);
  1030. {
  1031. if( fighting == 0) {
  1032. // just started a fight, see if it's a combat semi (orc chasm, kitchens, treasury)
  1033. checkForCombatSemi(document.body.innerHTML);
  1034. }
  1035. // alert("incrementing fighting from " + fighting);
  1036. fighting = fighting + 1; // also count rounds, prevents doing things twice in same fight
  1037. // fighting, but maybe we're done, look for adventure again tag
  1038. // I forget why we look at paragraphs here!
  1039. // var paragraphs = document.getElementsByTagName( "p" );
  1040. // for ( var i = 0; i < paragraphs.length; ++i ) {
  1041. // if ( paragraphs[i].innerHTML.indexOf( "Adventure Again (" ) != -1
  1042. // || paragraphs[i].innerHTML.indexOf("Go back to Your Inventory") != -1) {
  1043. if ( document.body.innerHTML.indexOf( "Adventure Again (" ) != -1
  1044. || document.body.innerHTML.indexOf("Go back to Your Inventory") != -1) {
  1045. fighting = 0;
  1046. // break;
  1047. }
  1048. // }
  1049. }
  1050. GM_setValue(playerName+"_fighting",fighting);
  1051. // alert("post fight - fighting = " + fighting);
  1052.  
  1053. }
  1054. else {
  1055. // alert("ignoring " + document.location.pathname);
  1056. }
  1057.  
  1058. // do sanity check (load charsheet asynchronously) if requested - not while fighting
  1059. if(GM_getValue(playerName+"_needSanityCheck",false) == true
  1060. && GM_getValue(playerName+"_allowSanityCheck",false) == true ) {
  1061. // alert("need sanity check flag detected!");
  1062. // no sanity check allowed if fighting
  1063. if( GM_getValue(playerName+"_fighting",0) == 0) {
  1064. // alert("calling sanity check");
  1065. GM_setValue(playerName+"_needSanityCheck", false);
  1066. // alert("calling sanity check");
  1067. GM_get(baseURL + charSheet, sanityCheckCharsheet);
  1068. }
  1069. }