Recipe Counter

Counts known recipes and tracks missing recipes in your crafting discovery pages in Kingdom of Loathing.

  1. // ==UserScript==
  2. // @name Recipe Counter
  3. // @namespace kol.interface.unfinished
  4. // @description Counts known recipes and tracks missing recipes in your crafting discovery pages in Kingdom of Loathing.
  5. // @include https://*kingdomofloathing.com/craft.php*
  6. // @include https://*.kingdomofloathing.com/account.php
  7. // @include http://kol.coldfront.net/thekolwiki/index.php/Cocktailcrafting_Discoveries*
  8. // @include http://kol.coldfront.net/thekolwiki/index.php/Cooking_Discoveries*
  9. // @include http://kol.coldfront.net/thekolwiki/index.php/Meat-Pasting_Discoveries*
  10. // @include http://kol.coldfront.net/thekolwiki/index.php/Meatsmithing_Discoveries*
  11. // @include http://kol.coldfront.net/thekolwiki/index.php/Miscellaneous_Discoveries*
  12. // @version 3.989
  13. // @grant GM_setValue
  14. // @grant GM_getValue
  15. // @grant GM_xmlhttpRequest
  16. // ==/UserScript==
  17.  
  18. //Version 3.989
  19. // - Murderbots
  20. //Version 3.988
  21. // - Robortender
  22. //Version 3.987
  23. // - more eldritch essentials
  24. //Version 3.986
  25. // - eldritch essentials
  26. //Version 3.985
  27. // - fix thanksgetting
  28. //Version 3.984
  29. // - thanksgetting
  30. //Version 3.983
  31. // - change to data uri for images used
  32. //Version 3.982
  33. // - fix overzealous use of https
  34. //Version 3.981
  35. // - change to https
  36. //Version 3.98
  37. // - spurious smithing, gunpasting, hi-yo silver
  38. //Version 3.97
  39. // - patent medicines
  40. //Version 3.96
  41. // - perfect cocktails
  42. //Version 3.95
  43. // - guncraft
  44. //Version 3.94
  45. // - heavy metallurgy
  46. //Version 3.93
  47. // - velvetry
  48. //Version 3.92
  49. // - retro-electrical
  50. //Version 3.91
  51. // - add baking, and retire jewelry, moving recipes to meat-pasting
  52. //Version 3.90
  53. // - cool winery
  54. //Version 3.89
  55. // - add Crimbo stuff
  56. //Version 3.88
  57. // - add Post-Apocalyptica
  58. //Version 3.87
  59. // - add @grant, switch GM_log to console.log, remove auto-update
  60. //Version 3.86
  61. // - spookyraven stuff, crash-site stuff, June/2014 familiar stuff
  62. //Version 3.85
  63. // - sugar cubans
  64. //Version 3.84
  65. // - spring break beach stuff
  66. //Version 3.83
  67. // - V11 stuff
  68. //Version 3.82
  69. // - added lynrd stuff
  70. //Version 3.81
  71. // - add Sugar Scale Structures to miscellaneous
  72. //Version 3.80
  73. // - add Smiths-ing to cocktails, cooking, meatpasting, meatsmithing
  74. // - add Weapons: Swords to meatpasting, Loathsome Smithery to meatsmithing
  75. //Version 3.79
  76. // - added tin-kering to miscellaneous
  77. //Version 3.78
  78. // - added cluster stuff to miscellanous, cooking, cocktails
  79. //Version 3.77
  80. // - added Aquatic Jewelry
  81. // - added Sea Leatherworking
  82. //Version 3.76
  83. // - added Cosmic Potions to miscellaneous
  84. // - added Papier-Mache to cooking
  85. //Version 3.75
  86. // - added Oil Rigging to miscellaneous
  87. //Version 3.74
  88. // - added 'tonstruction and Wax Wear to miscellaneous
  89. //Version 3.73
  90. // - added Papier Mache to miscellaneous
  91. //Version 3.72
  92. // - added Hot Daubery to miscellaneous
  93. //Version 3.71
  94. // - added category Confectionery to meatsmithing and cocktailcrafting
  95. // - added Peppermints to meatpasting and miscellaneous
  96. //Version 3.70
  97. // - added category Confectionery to cooking
  98. //Version 3.69
  99. // - added categories: Confectionery to jewelry and meat-pasting,
  100. // and Festive Crimbo Cocktails to cocktailcrafting.
  101. //Version 3.68
  102. // - added sticky paper and rough stuff category to meatpasting discoveries
  103. //Version 3.674
  104. // - fix suddenly re-broken Humpy Dumplings
  105. //Version 3.673
  106. // - added honey stuff
  107. //Version 3.672
  108. // - added knob cake
  109. //Version 3.671
  110. // - more Amazing Ideas
  111. //Version 3.67
  112. // - added new recipe sections from April 2011 IOTM
  113. //Version 3.665
  114. // - fix https/http issue in auto-update
  115. //Version 3.66
  116. // - fix weirdness with vial of jus de larmes, due to it's italicization
  117. // - update shared account-menu tab code
  118. //Version 3.65
  119. // - incorporate Charon the Hand's code for a shared account menu tab
  120. //Version 3.64
  121. // - fix account menu so it works with the new account menu update
  122. //Version 3.63
  123. // - added an account menu entry to update recipe lists manually.
  124. //Version 3.62
  125. // - more robust when an auto-check fails or is incomplete
  126. //Version 3.61
  127. // - added Paperclip Paraphernalia
  128. //Version 3.6
  129. // - improved new discovery detection, based on md5 sums of the wiki table
  130. // text rather than last edit date of the page.
  131. //Version 3.5
  132. // - fix to work around kol's fuzzy matching system which would sometimes
  133. // cause the script to wrongly report info in the mouse-over text and
  134. // miscolour the item text after clicking on a missing recipe.
  135. //Version 3.4
  136. // - now checks and lets you know if wiki discovery pages (list of recipes)
  137. // has been updated so you can revisit it to refresh the recipes list.
  138. //Version 3.3
  139. // - sped up missing ingredient checking considerably and
  140. // it also retrieves the item counts, but only if you have
  141. // (ever) enabled chat (you do not need to be in chat).
  142. // Slower route is used when chat commands cannot be used.
  143. //Version 3.2
  144. // - added auto-update checking
  145. //Version 3.1.1
  146. // - updated Cooking recipe sections with Popsicles.
  147. //Version 3.1
  148. // - added ability to check inventory for ingredients of missing recipes.
  149. // Click on the item name and it looks through through your inventory, changing
  150. // the colour the item to either gray or black depending on whether you have
  151. // all the ingredients. Mouseover text shows which ingredient is missing if
  152. // just one.
  153. //Version 3.0.1
  154. // - added Smoked Pottery to miscellaneous
  155. //Version 3.0
  156. // - added crafting links for missing recipes, which take you to the appropriate
  157. // crafting page, with the selection boxes filled if you have the items.
  158. // - script state is now persistent, with counts and any displayed missing recipes
  159. // not disappearing if you actually craft something.
  160. // - The "show missing" button is now a toggle instead of a one-time button, and
  161. // so can be applied by default as you switch discovery pages.
  162. //Version 2.0
  163. // - added gathering and display of missing recipes
  164. //Version 1.3
  165. // - add sub-counts for sections
  166. //Version 1.2
  167. // - add miscellaneous discoveries
  168. //Version 1.1
  169.  
  170. // current page title if at a kol discoveries page
  171. var knownPage='';
  172.  
  173. var pageLinks={'Meat-Pasting Discoveries:':'craft.php?mode=combine',
  174. 'Cocktailcrafting Discoveries:':'craft.php?mode=cocktail',
  175. 'Meatsmithing Discoveries:':'craft.php?mode=smith',
  176. 'Cooking Discoveries:':'craft.php?mode=cook',
  177. 'Miscellaneous Discoveries:':'craft.php?mode=discoveries'};
  178.  
  179. function doPage() {
  180. // find table root of area interested in
  181. var node,root;
  182. var listing = document.getElementsByTagName('b');
  183. for (var i=0;i<listing.length;i++) {
  184. var node = listing[i];
  185. if (node.firstChild && pageLinks[node.firstChild.data]) {
  186. root = node.parentNode;
  187. knownPage = node.firstChild.data; // ugh
  188. while (root && root.tagName!='TABLE')
  189. root = root.parentNode;
  190. break;
  191. }
  192. }
  193. if (root) {
  194. GM_setValue('missinga','');
  195. GM_setValue('missingb','');
  196. // count
  197. var count = document.evaluate('.//img[contains(@onclick,"descitem")]',root,null,
  198. XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null).snapshotLength;
  199. node.firstChild.data = node.firstChild.data.substr(0,node.firstChild.data.length-1)+
  200. ' ('+count+' known):';
  201. addButton(node);
  202. addSubcounts(root);
  203. if (GM_getValue('showmissing',''))
  204. showMissing();
  205. } else {
  206. // direct crafting page?
  207. var a = document.getElementById('a');
  208. var b = document.getElementById('b');
  209. if (a && b) {
  210. var ma = GM_getValue('missinga');
  211. var mb = GM_getValue('missingb');
  212. if (ma) {
  213. selectOption(a,ma);
  214. selectOption(b,mb);
  215. GM_setValue('missinga','');
  216. GM_setValue('missingb','');
  217. }
  218. }
  219. }
  220. }
  221.  
  222. function selectOption(sbox,txt) {
  223. for (var i=0;i<sbox.options.length;i++) {
  224. if (sbox.options[i].text.indexOf(txt)==0 &&
  225. sbox.options[i].text.replace(/\s*\([0-9]+\)\s*/,'')==txt) {
  226. sbox.selectedIndex = i;
  227. return;
  228. }
  229. }
  230. }
  231.  
  232. function addButton(node) {
  233. var v = document.createElement('a');
  234. v.setAttribute('href','#');
  235. v.setAttribute('id','showmissingbutton');
  236. v.setAttribute('style','font-size:x-small;color:white;vertical-align:middle;');
  237. fixupButton(v);
  238. v.addEventListener('click',bHandler,false);
  239. var p = knownPage.replace(/:.*$/,'').replace(/ /g,'_');
  240. v.setAttribute('discoveries_page',p);
  241. node.parentNode.appendChild(document.createTextNode('\u00a0\u00a0\u00a0'));
  242. node.parentNode.appendChild(v);
  243.  
  244. if (GM_getValue(p+'_oldmd5',0)!=GM_getValue(p+'_newmd5',-1)) {
  245. node.parentNode.appendChild(document.createTextNode('\u00a0\u00a0\u00a0'));
  246. v = document.createElement('a');
  247. v.setAttribute('href','http://kol.coldfront.net/thekolwiki/index.php/'+p);
  248. v.setAttribute('style','font-size:x-small;color:yellow;vertical-align:middle;');
  249. v.setAttribute('title','Updated discoveries list detected!');
  250. v.setAttribute('id','recipecountdisoveriesnotice');
  251. v.setAttribute('target','_blank');
  252. v.appendChild(document.createTextNode('Click to update discoveries list'));
  253. node.parentNode.appendChild(v);
  254. } else {
  255. v = document.getElementById('recipecountdiscoveriesnotice');
  256. if (v) {
  257. v.parentNode.removeChild(v);
  258. }
  259. }
  260. }
  261.  
  262. function fixupButton(v) {
  263. if (GM_getValue('showmissing','')) {
  264. v.setAttribute('title','Click to hide all missing recipes on this page.');
  265. if (v.firstChild)
  266. v.replaceChild(document.createTextNode('[Hide Missing]'),v.firstChild);
  267. else
  268. v.appendChild(document.createTextNode('[Hide Missing]'));
  269. } else {
  270. v.setAttribute('title','Click to display all missing recipes on this page.');
  271. if (v.firstChild)
  272. v.replaceChild(document.createTextNode('[Show Missing]'),v.firstChild);
  273. else
  274. v.appendChild(document.createTextNode('[Show Missing]'));
  275. }
  276. }
  277.  
  278. function showMissing() {
  279. var v = document.getElementById('showmissingbutton');
  280. if (GM_getValue('showmissing','')) {
  281. if (!missing()) {
  282. var page = v.getAttribute('discoveries_page');
  283. var pages = page.replace(/_/g,' ');
  284. var goWiki = document.createElement('a');
  285. goWiki.setAttribute('title','Click to go to the full list of '+pages+' recipes on the KoL wiki.');
  286. goWiki.setAttribute('target','_blank');
  287. goWiki.setAttribute('style','font-size:x-small;color:white;vertical-align:middle;');
  288. goWiki.setAttribute('href','http://kol.coldfront.net/thekolwiki/index.php/'+page);
  289. goWiki.appendChild(document.createTextNode('[Load all '+pages+']'));
  290. v.parentNode.appendChild(goWiki);
  291. }
  292. } else {
  293. var xx = document.getElementsByClassName('showmissingaddition');
  294. for (var i=xx.length-1;i>=0;i--) {
  295. var x = xx[i];
  296. x.parentNode.removeChild(x);
  297. }
  298. }
  299. fixupButton(v);
  300. }
  301.  
  302. function bHandler(e) {
  303. var b = GM_getValue('showmissing','');
  304. GM_setValue('showmissing', (b ? '' : 'true'));
  305. showMissing();
  306. }
  307.  
  308. function addSubcounts(root) {
  309. var tbls = document.evaluate( './/table', root, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
  310. for (var i=tbls.snapshotLength-1;i>=0;i--) {
  311. var tbl = tbls.snapshotItem(i);
  312. var id = tbl.getAttribute('id');
  313. if (id && id.indexOf('table_')==0) {
  314. // found one
  315.  
  316. var count=0;
  317. var listing = tbl.getElementsByTagName('img');
  318. for (var j=0;j<listing.length;j++) {
  319. var imgnode = listing[j];
  320. var click;
  321. if (click=imgnode.getAttribute('onclick')) {
  322. if (click.indexOf('descitem')==0) {
  323. count++;
  324. }
  325. }
  326. }
  327.  
  328. // count the images
  329. if (tbl.previousSibling) {
  330. var hdr = tbl.previousSibling.previousSibling;
  331. if (hdr && hdr.tagName=='CENTER' && hdr.firstChild) {
  332. var f = document.createElement('font');
  333. f.setAttribute('style','font-size:x-small;');
  334. f.appendChild(document.createTextNode(' ('+count+' recipe'+((count==1)? '' : 's')+')'));
  335. hdr.firstChild.appendChild(f);
  336. }
  337. }
  338. }
  339. }
  340. }
  341.  
  342. var rlists = [{title:'Cocktailcrafting Discoveries',
  343. sections:['Amazing Ideas','Confectionery','Clustercocktails','Cool Winery','Distillations','Eldritch Essentials','Evil Fruity Girl Drinks',
  344. 'Eww','Extra-Fruity Girl Drinks',
  345. 'Fancy Garnishes','Festive Crimbo Cocktails','Fruity Girl Drinks','Hilarious Jokes','Infused Wines',
  346. 'Miscellaneous','Miscellaneous Boozery','Mushroom Wines','Perfect Cocktails','Post-Apocalyptica', 'Premium Cocktails','Schnapps',
  347. 'Robortender Recipes','Simple Cocktails','Smiths-ing','Specialty Beers','Tiny Plastic Sword Drinks',
  348. 'Underwater Cocktails']},
  349. {title:'Cooking Discoveries',
  350. sections:['Advanced Sauceror Potions','Amazing Ideas','Baking','Brownies','Casseroles','Clusterbaking','Confectionery',
  351. 'Confections','Dirty Exploits','Eldritch Essentials','Evil Noodle Dishes','Evil Sauceror Potions','Familiar',
  352. 'High-Pressure Potions','Kabobs','Key Limes','Miscellaneous','Miscellaneous Cookery', 'Miscellaneous Potions',
  353. 'Nemesis Quest Slimes','Noodle Dishes','Papier-Mache','Patent Medicines','Pies','Pizzas','Popsicles','Pork Gem Potions','Post-Apocalyptica',
  354. 'Quest Items','Sauceror Potions','Secret Sauces','Smiths-ing','Space Foods','Stir-Fries','Tempura','Tex-Mex',
  355. 'Tex-Mex-Italian','Thanksgarden Creations','Transmutations']},
  356. {title:'Meat-Pasting Discoveries',
  357. sections:['Amazing Ideas','Aquatic Jewelry','Campground Items','Clusterbombs','Confectionery','Decoys','Elemental Jewelry','Expensive Pork Elf Jewelry',
  358. 'Familiars','Gear','Genetic Engineering','Guncraft','Gunpasting','Hi-Yo Silver','Hilarious Jokes','Horrifying Jewelry','Miscellaneous',
  359. 'Miscellaneous Jewelry','Murderbot Technology','Parts','Parts for Campground Items',
  360. 'Parts for Familiars','Peppermints','Pork Elf Jewelry','Post-Apocalyptica','Primordial Soup','Quest Items','Rainbow Pearl Jewelry','Retro-Electrical','Rough Stuff',
  361. 'Smiths-ing','Spacetime Bending','Usable Items','Vampire Pearl Jewelry','Weapons: Swords']},
  362. {title:'Meatsmithing Discoveries',
  363. sections:['Armor: Accessories','Armor: Advanced Accessories','Armor: Advanced Hats',
  364. 'Armor: Advanced Pants','Armor: Advanced Shields', 'Armor: Advanced Shirts', 'Armor: Hats',
  365. 'Armor: Pants','Armor: Shields','Armor: Shirts','Campground Items', 'Confectionery','Depleted Grimacite', 'Gear','Ghast Irony',
  366. 'Ingredients','Loathsome Smithery','Miscellaneous Smithery','Post-Apocalyptica','Quest Weapons','Sea Leatherworking','Slimy Things',
  367. 'Smiths-ing','Spacetime Bending','Spurious Smithing','Weapons: Advanced Crossbows',
  368. 'Weapons: Advanced Staves','Weapons: Advanced Swords','Weapons: Clubs',
  369. 'Weapons: Crossbows','Weapons: Miscellaneous','Weapons: Staves',
  370. 'Weapons: Swords','Weapons: Utensils','Weapons: Whips']},
  371. {title:'Miscellaneous Discoveries',
  372. sections:["'tonstruction",'BRICKO Beasts','BRICKO Bits','Balloon Bendings','Clingfilm Creations',
  373. 'Cold Comforts','Cosmic Potions','Duct Tape Designs','Eldritch Essentials','Heavy Metallurgy','Honey Stuff','Hot Daubery','Mummy Wrapping Manufacturings',
  374. 'Oil Rigging','Palm-Frond Preparations','Paperclip Paraphernalia','Papier-Mache','Peppermints','Plaiddery','Smoked Pottery',
  375. 'Snailmail Structures','Spacetime Bending','Spooky Bark Surprises','Sugar Cubans','Sugar Scale Structures','Tin-kering',
  376. 'Turtlemail Treasures','Velvetry','Wax Wear','Wumpus Hair Weavings']}];
  377.  
  378. // locate all missing recipes
  379. function missing() {
  380. var s = knownPage;
  381. //console.log('knownPage='+s);
  382. if (!s) {
  383. return;
  384. }
  385. for (var i=0;i<rlists.length;i++) {
  386. if (s.indexOf(rlists[i].title)>=0) {
  387. var r = missingInPage(retrieveCopy(rlists[i].title));
  388. if (!r)
  389. return false;
  390. insertMissing(r);
  391. return true;
  392. }
  393. }
  394. }
  395.  
  396. // set by missingInPage and used by insertMissing
  397. var secMap = {};
  398.  
  399. // uses the secMap and the given list of missing recipes to create fake versions
  400. function insertMissing(r) {
  401. for (var s in r) {
  402. var tbl = secMap[s];
  403. var lastr = null;
  404. if (tbl && tbl.rows.length>0 && tbl.rows[tbl.rows.length-1].cells.length<3) {
  405. lastr = tbl.rows[tbl.rows.length-1];
  406. }
  407. for (var e in r[s]) {
  408. if (r[s][e]) {
  409. for (var j=0;j<r[s][e].length;j++) {
  410. if (lastr) {
  411. createMissing(lastr,e,r[s][e][j]);
  412. lastr = null;
  413. } else {
  414. // TBD: what if tbl is null?
  415. if (!tbl) {
  416. if (secMap['last_table']) {
  417. tbl = insertMissingTable(secMap['last_table'].nextSibling,s);
  418. } else {
  419. var root = document.evaluate( '//td[contains(text(),"You haven\'t made any discoveries in this field yet")]/text()', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE,null);
  420. tbl = insertMissingTable(root.singleNodeValue.nextSibling,s);
  421. }
  422. secMap[s] = tbl;
  423. }
  424. lastr = tbl.insertRow(-1);
  425. lastr.setAttribute('class','showmissingaddition');
  426. createMissing(lastr,e,r[s][e][j]);
  427. }
  428. // console.log('missing in '+s+': '+e+' = '+r[s][e][j]);
  429. }
  430. }
  431. }
  432. }
  433. }
  434.  
  435. // creates a table for a section s
  436. function insertMissingTable(root,s) {
  437. var c = document.createElement('center');
  438. var tbl = document.createElement('table');
  439. var b = document.createElement('b');
  440. var br1 = document.createElement('br');
  441. var br2 = document.createElement('br');
  442. c.setAttribute('class','showmissingaddition');
  443. tbl.setAttribute('class','showmissingaddition');
  444. br1.setAttribute('class','showmissingaddition');
  445. br2.setAttribute('class','showmissingaddition');
  446. b.innerHTML = s;
  447. b.setAttribute('style','color:red;');
  448. c.appendChild(b);
  449. root.parentNode.insertBefore(br1,root);
  450. root.parentNode.insertBefore(c,root);
  451. root.parentNode.insertBefore(br2,root);
  452. root.parentNode.insertBefore(tbl,root);
  453. return tbl;
  454. }
  455.  
  456.  
  457. // locate missing recipes in the current kol discoveries page, given a list of recipes
  458. function missingInPage(r) {
  459. if (!r) {
  460. alert('You need to visit the KoL Wiki discoveries pages (http://kol.coldfront.net/thekolwiki/index.php/Discoveries) to initialize the recipe list. Visit each of the 6 pages of Recipes on the wiki, then re-open a recipe page in the game and try again.');
  461. return;
  462. }
  463. secMap = {};
  464. var tbls = document.evaluate( '//table', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
  465. for (var i=0;i<tbls.snapshotLength;i++) {
  466. var tbl = tbls.snapshotItem(i);
  467. var id = (tbl) ? tbl.getAttribute('id') : null;
  468. if (id && id.indexOf('table_')==0) {
  469. // found one
  470. // figure out which section this represents
  471. var sec = tbl.previousSibling;
  472. while (sec && sec.tagName!='CENTER')
  473. sec = sec.previousSibling;
  474. if (sec) {
  475. sec = sec.firstChild.firstChild.innerHTML;
  476. }
  477. var es = document.evaluate( './/td', tbl, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
  478. for (var j=0;j<es.snapshotLength;j+=2) {
  479. var e = es.snapshotItem(j);
  480. var f = es.snapshotItem(j+1);
  481. var item = (f.firstChild.firstChild.nodeType==3) ? f.firstChild.firstChild.data : f.firstChild.firstChild.innerHTML;
  482. if (!item) continue;
  483. var itemr = f.firstChild.nextSibling;
  484. if (itemr.tagName!='FONT') itemr = itemr.nextSibling;
  485. var components = '';
  486. for (var k=0;k<itemr.childNodes.length;k++) {
  487. if (itemr.childNodes[k].nodeType==3) {
  488. components += itemr.childNodes[k].data;
  489. } else if (itemr.childNodes[k].tagName=='I') {
  490. components += '<i>'+itemr.childNodes[k].innerHTML+'</i>';
  491. }
  492. }
  493. components = components.replace(/\([0-9]+\)/g,'').replace(/\+[\s]*$/,'').replace(/ /g,' ').replace(/\s\s+/,' ').replace(/ *$/,'').replace(/^ */,'');
  494. // check that we have a section
  495. if (sec) {
  496. if (r && r[sec] && r[sec][item]) {
  497. var hi = hasRecipe(r[sec][item],components);
  498. if (hi>=0) {
  499. r[sec][item].splice(hi,1);
  500. }
  501. }
  502. } else if (r) {
  503. for (var s in r) {
  504. if (r[s][item]) {
  505. var hi = hasRecipe(r[s][item],components);
  506. if (hi>=0) {
  507. r[s][item].splice(hi,1);
  508. sec = s;
  509. break;
  510. }
  511. }
  512. }
  513. }
  514. }
  515. secMap[sec] = tbl; // store for later
  516. secMap['last_table'] = tbl;
  517. }
  518. }
  519. return r;
  520. }
  521.  
  522. // check the given list for a recipe combination, and return the index or -1
  523. function hasRecipe(clist,c) {
  524. if (!clist)
  525. return -1;
  526. var c2 = c.match(/(^[^+]*)\+(.*$)/);
  527. if (c2) {
  528. c2 = c2[2] +' + '+c2[1];
  529. c2 = c2.replace(/\+[\s]*$/,'').replace(/ /g,' ').replace(/ *$/,'').replace(/^ */,'');
  530. }
  531. for (var i=0;i<clist.length;i++) {
  532. if (clist[i] == c || (c2 && clist[i] == c2)) {
  533. return i;
  534. }
  535. }
  536. return -1;
  537. }
  538.  
  539. // creates a new entry for a missing title+components, and
  540. // attaches the resulting td's to the given tr
  541. function createMissing(tr,title,components) {
  542. var td1 = tr.insertCell(-1);
  543. var td2 = tr.insertCell(-1);
  544. td1.setAttribute('class','showmissingaddition');
  545. td2.setAttribute('class','showmissingaddition');
  546. td1.setAttribute('valign','center');
  547. td2.setAttribute('valign','top');
  548. var i = document.createElement('img');
  549. i.setAttribute('class','hand');
  550. i.setAttribute('src','data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAABEklEQVRIie2WyxHDMAhE0xR10Q6NUAK1UALHzYl8haXIljOZyR5laR6flfAFX9LlJ8DuDhGBiMDMzgGLCIjoBiYiMPNacGb6ukZEcPd1YACIiO+AH5WlVtVmgMwMZm5+nwZnpqr6VgUAMLMnH1QmLMFmBmZuHnztdyURKQ3YBGe5VBVE1Mysp4go21GC82BloK1AIuLpulV7S3BlIGbeLHUGKyKbAZbgyhiVqVJmNnTNyh6v6u0meO/jMBJwWepeSdPxI9l9BO7J3eHuYGYQ0W09H5BlYOCe9aMJM5gpsLt3+5Qmmp3LTfDorF0ynXqZpPMPzXhUp8/j1Cx0N3iPpsGqOvVwHAIe/SE4FLxXf/BpugJUkH7bCBPJ3QAAAABJRU5ErkJggg==');
  551. td1.appendChild(i);
  552. var b = document.createElement('b');
  553. b.setAttribute('style','color:red;');
  554. b.innerHTML = title;
  555. td2.appendChild(b);
  556. var f = document.createElement('font');
  557. f.setAttribute('size','1');
  558. f.setAttribute('color','red');
  559.  
  560. if (knownPage!='Miscellaneous Discoveries:') {
  561. var f2 = document.createElement('font');
  562. f2.setAttribute('size','2');
  563. f2.setAttribute('color','red');
  564. var ia = document.createElement('a');
  565. ia.appendChild(document.createTextNode('make?'));
  566. ia.setAttribute('title','Click to go the crafting page for this missing recipe');
  567. ia.setAttribute('href','#');
  568. ia.setAttribute('missinga',components.replace(/\s*\+.*/,''));
  569. ia.setAttribute('missingb',((components.indexOf('+')>0) ? components.replace(/[^+]*\+\s*/,'') : ''));
  570. ia.addEventListener('click',missingButtonHandler,false);
  571. f2.appendChild(document.createTextNode('\u00A0['));
  572. f2.appendChild(ia);
  573. f2.appendChild(document.createTextNode(']'));
  574. f.appendChild(f2);
  575.  
  576. b.setAttribute('missinga',components.replace(/\s*\+.*/,''));
  577. b.setAttribute('missingb',((components.indexOf('+')>0) ? components.replace(/[^+]*\+\s*/,'') : ''));
  578. b.setAttribute('title','click to check for ingredients');
  579. b.addEventListener('click',checkIngredientsHandler,false);
  580. }
  581. f.appendChild(document.createElement('br'));
  582. f.appendChild(document.createTextNode(components));
  583. td2.appendChild(f);
  584. }
  585.  
  586. function missingButtonHandler() {
  587. GM_setValue('missinga',this.getAttribute('missinga').replace(/<[^>]+>/g,''));
  588. GM_setValue('missingb',this.getAttribute('missingb').replace(/<[^>]+>/g,''));
  589. window.location.href = pageLinks[knownPage];
  590. }
  591.  
  592. // return a new copy of the master recipes
  593. function retrieveCopy(page) {
  594. var r = JSON.parse(GM_getValue('recipes','{}'));
  595. return r[page];
  596. }
  597.  
  598. // scrape data from a kol wiki page
  599. function gather(m5) {
  600. var recipes = JSON.parse(GM_getValue('recipes','{}'));
  601.  
  602. var s = window.location.pathname.replace(/_/g,' ');
  603. //console.log('Gathering...'+s);
  604. for (var i=0;i<rlists.length;i++) {
  605. if (s.indexOf(rlists[i].title)>=0) {
  606. gatherRecipes(rlists[i],recipes);
  607. var p = rlists[i].title.replace(/:.*$/,'').replace(/ /g,'_');
  608. GM_setValue(p+'_oldmd5',m5);
  609. GM_setValue(p+'_newmd5',m5);
  610. }
  611. }
  612. GM_setValue('recipes',JSON.stringify(recipes));
  613. }
  614.  
  615. // scrape data from a specific kol wiki page
  616. function gatherRecipes(rlist,recipes) {
  617. var s = {};
  618. for (var i=0;i<rlist.sections.length;i++) {
  619. var r = gatherRecipesSection(rlist.sections[i]);
  620. s[rlist.sections[i]] = r;
  621. }
  622. recipes[rlist.title] = s;
  623. // var p = rlist.title.replace(/:.*$/,'').replace(/ /g,'_')+'_last';
  624. // GM_setValue(p,(new Date()).toUTCString());
  625. //console.log('setting '+p+' to '+GM_getValue(p));
  626. }
  627.  
  628. // scrapte data for the given section of a kol wiki page
  629. function gatherRecipesSection(section) {
  630. var r = {};
  631. var sec = document.evaluate( '//span[@class="mw-headline"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  632. //var sec = document.evaluate( '//span[text()="'+section+'"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  633. // console.log('gathering for section '+section);
  634. var rx = new RegExp('','');
  635. for (var j=0;j<sec.snapshotLength;j++) {
  636. var sn = sec.snapshotItem(j).innerHTML;
  637. if (sn.replace(/^ */,'').replace(/ *$/,'')==section) {
  638. var hp = sec.snapshotItem(j).parentNode;
  639. if (hp && hp.tagName=='H2') {
  640. hp = hp.nextSibling.nextSibling;
  641. while (hp && hp.tagName!='H2') {
  642. var i;
  643. var tbls = document.evaluate( './/td', hp, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);
  644. for (i=0;i<tbls.snapshotLength-1;i+=2) {
  645. var e = tbls.snapshotItem(i);
  646. var f = tbls.snapshotItem(i+1);
  647. var n = f.firstChild.firstChild.innerHTML;
  648. var c = '';
  649. for (var k=0;k<f.firstChild.nextSibling.nextSibling.childNodes.length;k++) {
  650. var s = f.firstChild.nextSibling.nextSibling.childNodes[k];
  651. if (s.innerHTML)
  652. c += s.innerHTML;
  653. else if (s.nodeType==3)
  654. c += s.data;
  655. else if (c)
  656. c += ' + ';
  657. }
  658. c = c.replace(/\+[\s]*$/,'').replace(/ /g,' ').replace(/ *$/,'').replace(/^ */,'');
  659. if (c) {
  660. // console.log('found recipe for '+n+', consisting of: '+c);
  661. if (r[n]) r[n][r[n].length] = c;
  662. else r[n] = [c];
  663. }
  664. }
  665. if (i>0)
  666. return r;
  667. hp = hp.nextSibling;
  668. }
  669. }
  670. }
  671. }
  672. return r;
  673. }
  674.  
  675. // called when the confused image is clicked on.
  676. function checkIngredientsHandler(e) {
  677. this.removeEventListener('click',checkIngredientsHandler,false);
  678. checkIngredientsFast(this,this.getAttribute('missinga'),this.getAttribute('missingb'));
  679. }
  680.  
  681. // utility function, stolen from other scripts
  682. function GM_get(dest, callback)
  683. { GM_xmlhttpRequest({
  684. method: 'GET',
  685. url: dest,
  686. //onerror:function(error) { console.log("GM_get Error: " + error); },
  687. onload:function(details) {
  688. if( typeof(callback)=='function' ){
  689. callback(details.responseText);
  690. } } }); }
  691.  
  692. // if chat not enabled use the slow route
  693. function checkIngredientsSlow(item,ing1,ing2) {
  694. //item.setAttribute('style','color:pink;');
  695. //item.setAttribute('title','checking...');
  696. var r1b = false;
  697. var r2b = false;
  698. GM_get('http://'+window.location.host+'/inventory.php?which=1',function(response){
  699. if(response!=''){
  700. var r1 = new RegExp('<b[^>]*>'+ing1+'</b>','gm');
  701. var r2 = new RegExp('<b[^>]*>'+ing2+'</b>','gm');
  702. if (!r1b) r1b = r1.test(response);
  703. if (!r2b) r2b = r2.test(response);
  704. if (r1b && r2b) {
  705. item.setAttribute('style','color:black;');
  706. item.addEventListener('click',checkIngredientsHandler,false);
  707. item.setAttribute('title','Ingredients found in inventory at last check. Click to check again.');
  708. } else {
  709. GM_get('http://'+window.location.host+'/inventory.php?which=2',function(response){
  710. if(response!=''){
  711. if (!r1b) r1b = r1.test(response);
  712. if (!r2b) r2b = r2.test(response);
  713. if (r1b && r2b) {
  714. item.setAttribute('style','color:black;');
  715. item.addEventListener('click',checkIngredientsHandler,false);
  716. item.setAttribute('title','Ingredients found in inventory at last check. Click to check again.');
  717. } else {
  718. GM_get('http://'+window.location.host+'/inventory.php?which=3',function(response){
  719. if(response!=''){
  720. if (!r1b) r1b = r1.test(response);
  721. if (!r2b) r2b = r2.test(response);
  722. if (r1b && r2b) {
  723. item.setAttribute('style','color:black;');
  724. item.setAttribute('title','Ingredients found in inventory at last check. Click to check again.');
  725. } else {
  726. item.setAttribute('style','color:gray;');
  727. if (r1b)
  728. item.setAttribute('title','Ingredient '+ing2+' not found in inventory. Click to check again.');
  729. else if (r2b)
  730. item.setAttribute('title','Ingredient '+ing1+' not found in inventory. Click to check again.');
  731. else
  732. item.setAttribute('title','Ingredients not found in inventory. Click to check again.');
  733. }
  734. item.addEventListener('click',checkIngredientsHandler,false);
  735. }});
  736. }
  737. }});
  738. }
  739. }});
  740. }
  741.  
  742. // faster checking but requires chat is enabled
  743. function checkIngredientsFast(item,ing1,ing2) {
  744. item.setAttribute('style','color:pink;');
  745. item.setAttribute('title','checking...');
  746. if (ing1.match(/<[^>]+>/) || ing2.match(/<[^>]+>/))
  747. return checkIngredientsSlow(item,ing1,ing2);
  748. var pd = findPwdhash();
  749. if (!pd) {
  750. console.log('cound not find pwd or playerid');
  751. return;
  752. }
  753. //console.log('pwd='+pd.pwd);
  754. //console.log('pid='+pd.pid);
  755. GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/count '+encodeURI(ing1),
  756. function(response) {
  757. if(response!='') {
  758. //console.log('response: '+response);
  759. var r1 = response.match(/(<[^>]*>)*You have ([0-9]*) ([^<]*)\./);
  760. GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/count '+encodeURI(ing2),
  761. function(response) {
  762. if(response!='') {
  763. var r2 = response.match(/(<[^>]*>)*You have ([0-9]*) ([^<]*)\./);
  764. if (r1 && r2) {
  765. verifyItems(item,ing1,ing2,pd,r1,r2);
  766. } else {
  767. setItemState(item,r1,r2,ing1,ing2);
  768. }
  769. }});
  770. } else {
  771. checkIngredientsSlow(item,ing1,ing2);
  772. }});
  773. }
  774.  
  775. function setItemState(item,r1,r2,ing1,ing2) {
  776. if (r1 && r2) {
  777. item.setAttribute('style','color:black;');
  778. item.setAttribute('title','Found '+r1[2]+' '+r1[3]+' and '+r2[2]+' '+r2[3]+' at last check. Click to check again.');
  779. } else {
  780. item.setAttribute('style','color:gray;');
  781. if (r1)
  782. item.setAttribute('title','Found '+r1[2]+' '+r1[3]+' but no '+ing2+' in your inventory. Click to check again.');
  783. else if (r2)
  784. item.setAttribute('title','Found '+r2[2]+' '+r2[3]+' but no '+ing1+' in your inventory. Click to check again.');
  785. else
  786. item.setAttribute('title','Neither ingredient is in your inventory. Click to check again.');
  787. }
  788. item.addEventListener('click',checkIngredientsHandler,false);
  789. }
  790.  
  791. function verifyItems(item,ing1,ing2,pd,r1,r2) {
  792. GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/examine '+encodeURI(ing1),
  793. function(response) {
  794. var r3 = response.match(/^<[^>]*>Examining: ([^<]*)/);
  795. if (r3) r3 = (r3[1]==ing1) ? r3 : null;
  796. GM_get('http://'+window.location.host+'/submitnewchat.php?playerid='+pd.pid+'&pwd='+pd.pwd+'&graf=/examine '+encodeURI(ing2),
  797. function(response) {
  798. var r4 = response.match(/^<[^>]*>Examining: ([^<]*)/);
  799. if (r4) r4 = (r4[1]==ing2) ? r4 : null;
  800. setItemState(item,(r3) ? r1 : null,(r4) ? r2 : null,ing1,ing2);
  801. });
  802. });
  803. }
  804.  
  805. function checkDiscoveries() {
  806. for (p in pageLinks) {
  807. var purl = p.replace(/:.*$/,'').replace(/ /g,'_');
  808. GM_xmlhttpRequest({
  809. method: 'GET',
  810. url: 'http://kol.coldfront.net/thekolwiki/index.php/'+purl,
  811. onload: function(details) {
  812. var q = this.url.replace(/[^/]*\//g,'');
  813. if (details.responseText) {
  814. var mdf = getPageMD5(details.responseText);
  815. //console.log('new md5 for '+q+': '+mdf);
  816. GM_setValue(q+'_newmd5',mdf);
  817. }
  818. }
  819. });
  820. }
  821. }
  822.  
  823. function getPageMD5(raw) {
  824. var text = '';
  825. var j,i = raw.indexOf('<table>');
  826. while(raw && i>=0) {
  827. raw = raw.substr(i+7);
  828. j = raw.indexOf('</table>');
  829. if (j<0)
  830. break; // bad parse?
  831. text = text + raw.substr(0,j);
  832. raw = raw.substr(j);
  833. i = raw.indexOf('<table>');
  834. }
  835. text = text.replace(/<[^>]*>/g,'');
  836. text = text.replace(/[\s\n]+/g,'');
  837. var m = MD5(text);
  838. //console.log('md5 of '+text);
  839. return m;
  840. }
  841.  
  842. function findPwdhash() {
  843. var somef=window.parent.frames;
  844. var goo = null;
  845. for(var j=0;j<somef.length;j++) {
  846. if (somef[j].name=="charpane") {
  847. goo=somef[j];
  848. var page = goo.document.documentElement.innerHTML;
  849. var pwdh = page.match(/pwdhash\s*=\s*\"([a-f0-9]+)\"/);
  850. if (pwdh) {
  851. var plid = page.match(/playerid\s*=\s*([a-f0-9]+)/);
  852. if (plid) {
  853. return {pwd:pwdh[1],pid:plid[1]};
  854. }
  855. }
  856. }
  857. }
  858. }
  859.  
  860.  
  861. /**
  862. *
  863. * MD5 (Message-Digest Algorithm)
  864. * http://www.webtoolkit.info/
  865. *
  866. **/
  867. var MD5 = function (string) {
  868. function RotateLeft(lValue, iShiftBits) {
  869. return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
  870. }
  871. function AddUnsigned(lX,lY) {
  872. var lX4,lY4,lX8,lY8,lResult;
  873. lX8 = (lX & 0x80000000);
  874. lY8 = (lY & 0x80000000);
  875. lX4 = (lX & 0x40000000);
  876. lY4 = (lY & 0x40000000);
  877. lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
  878. if (lX4 & lY4) {
  879. return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
  880. }
  881. if (lX4 | lY4) {
  882. if (lResult & 0x40000000) {
  883. return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
  884. } else {
  885. return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
  886. }
  887. } else {
  888. return (lResult ^ lX8 ^ lY8);
  889. }
  890. }
  891. function F(x,y,z) { return (x & y) | ((~x) & z); }
  892. function G(x,y,z) { return (x & z) | (y & (~z)); }
  893. function H(x,y,z) { return (x ^ y ^ z); }
  894. function I(x,y,z) { return (y ^ (x | (~z))); }
  895. function FF(a,b,c,d,x,s,ac) {
  896. a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
  897. return AddUnsigned(RotateLeft(a, s), b);
  898. };
  899. function GG(a,b,c,d,x,s,ac) {
  900. a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
  901. return AddUnsigned(RotateLeft(a, s), b);
  902. };
  903. function HH(a,b,c,d,x,s,ac) {
  904. a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
  905. return AddUnsigned(RotateLeft(a, s), b);
  906. };
  907. function II(a,b,c,d,x,s,ac) {
  908. a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
  909. return AddUnsigned(RotateLeft(a, s), b);
  910. };
  911. function ConvertToWordArray(string) {
  912. var lWordCount;
  913. var lMessageLength = string.length;
  914. var lNumberOfWords_temp1=lMessageLength + 8;
  915. var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
  916. var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
  917. var lWordArray=Array(lNumberOfWords-1);
  918. var lBytePosition = 0;
  919. var lByteCount = 0;
  920. while ( lByteCount < lMessageLength ) {
  921. lWordCount = (lByteCount-(lByteCount % 4))/4;
  922. lBytePosition = (lByteCount % 4)*8;
  923. lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
  924. lByteCount++;
  925. }
  926. lWordCount = (lByteCount-(lByteCount % 4))/4;
  927. lBytePosition = (lByteCount % 4)*8;
  928. lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
  929. lWordArray[lNumberOfWords-2] = lMessageLength<<3;
  930. lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
  931. return lWordArray;
  932. };
  933. function WordToHex(lValue) {
  934. var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
  935. for (lCount = 0;lCount<=3;lCount++) {
  936. lByte = (lValue>>>(lCount*8)) & 255;
  937. WordToHexValue_temp = "0" + lByte.toString(16);
  938. WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
  939. }
  940. return WordToHexValue;
  941. };
  942. function Utf8Encode(string) {
  943. string = string.replace(/\r\n/g,"\n");
  944. var utftext = "";
  945. for (var n = 0; n < string.length; n++) {
  946. var c = string.charCodeAt(n);
  947. if (c < 128) {
  948. utftext += String.fromCharCode(c);
  949. }
  950. else if((c > 127) && (c < 2048)) {
  951. utftext += String.fromCharCode((c >> 6) | 192);
  952. utftext += String.fromCharCode((c & 63) | 128);
  953. }
  954. else {
  955. utftext += String.fromCharCode((c >> 12) | 224);
  956. utftext += String.fromCharCode(((c >> 6) & 63) | 128);
  957. utftext += String.fromCharCode((c & 63) | 128);
  958. }
  959. }
  960. return utftext;
  961. };
  962. var x=Array();
  963. var k,AA,BB,CC,DD,a,b,c,d;
  964. var S11=7, S12=12, S13=17, S14=22;
  965. var S21=5, S22=9 , S23=14, S24=20;
  966. var S31=4, S32=11, S33=16, S34=23;
  967. var S41=6, S42=10, S43=15, S44=21;
  968. string = Utf8Encode(string);
  969. x = ConvertToWordArray(string);
  970. a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
  971. for (k=0;k<x.length;k+=16) {
  972. AA=a; BB=b; CC=c; DD=d;
  973. a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
  974. d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
  975. c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
  976. b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
  977. a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
  978. d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
  979. c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
  980. b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
  981. a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
  982. d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
  983. c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
  984. b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
  985. a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
  986. d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
  987. c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
  988. b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
  989. a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
  990. d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
  991. c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
  992. b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
  993. a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
  994. d=GG(d,a,b,c,x[k+10],S22,0x2441453);
  995. c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
  996. b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
  997. a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
  998. d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
  999. c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
  1000. b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
  1001. a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
  1002. d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
  1003. c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
  1004. b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
  1005. a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
  1006. d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
  1007. c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
  1008. b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
  1009. a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
  1010. d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
  1011. c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
  1012. b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
  1013. a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
  1014. d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
  1015. c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
  1016. b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
  1017. a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
  1018. d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
  1019. c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
  1020. b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
  1021. a=II(a,b,c,d,x[k+0], S41,0xF4292244);
  1022. d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
  1023. c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
  1024. b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
  1025. a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
  1026. d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
  1027. c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
  1028. b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
  1029. a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
  1030. d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
  1031. c=II(c,d,a,b,x[k+6], S43,0xA3014314);
  1032. b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
  1033. a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
  1034. d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
  1035. c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
  1036. b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
  1037. a=AddUnsigned(a,AA);
  1038. b=AddUnsigned(b,BB);
  1039. c=AddUnsigned(c,CC);
  1040. d=AddUnsigned(d,DD);
  1041. }
  1042. var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
  1043. return temp.toLowerCase();
  1044. }
  1045.  
  1046. // --------------------------------------------
  1047. // ---------- account menu option -------------
  1048. // --------------------------------------------
  1049.  
  1050.  
  1051. // Charon's code
  1052. function buildPrefs() {
  1053. if (!document.querySelector('#privacy'))
  1054. return;
  1055. if (!document.querySelector('#scripts')) {
  1056. //scripts tab is not built, do it here
  1057. var scripts = document.querySelector('ul').appendChild(document.createElement('li'));
  1058. scripts.id = 'scripts';
  1059. var a = scripts.appendChild(document.createElement('a'));
  1060. a.href = '#';
  1061. var img = a.appendChild(document.createElement('img'));
  1062. img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAACOElEQVRIibWXu9HsIAyFCQkpgCbUiFpRO2qFBiiAAkgVEjo8N7gjxvZi7/P3jGZfhs96HbEBH1y9dxARiAilFPTeMcZ4a4/wCZSZkVKCiICZQURg5r8Dt9YQY0QIASGEt2Efg5l5Qt1U9W/B27Yh54wQAnLOM9wxxrfz+xa41oqcM1QVtVZs2wZVnfkVEdRafws2M4jINFWFmYGZp+f+2lr7DdjMZusQEcYY6L1DVQ8e+30i8huwt0wpBTlnpJRmjpl5fkdECCG8HO6n4FLKbCERQe/94Z7WGkRktti2bd+DVRUpJZRSlhv23iEiyDkfCu0rsFdyjHEWkKoeFCvGiBjjhKkqYoxP+/sSrKrIOUNEZtF4OB3MzLPQiGhGZ69sV2Ffgkspc7GHkIhQa0UI4dDD/j6EgJTSAe5FaGbPwWOMqVBnc8l0jx3mv6nqUlZXOX8A+9OvNNnz6q3jHnlPr9a5nb0+gPd6vDdXJM/x2XLOMw376XU3TA5gM7sMMYDp6Qp89dBXI/QAvgqX5+gODOAyIk/BrbXbMD0D77vhbER0X1yrzR185VFKCWZ2C77N8eqp9yp0V7mttbn2XGArIbkUkPPk2bYNInJQpjNYRJbQlwRkde3FfwVOKU1ddxgz347Il8DMjBjjHBir4tqr2k/GYu/9Abb6HGN8qNyPwWZ2mdO76v3aY5fBO/PRue/Xrw8CZjbDSkTLHKeUDlHxI/BXYOB/a7mouDf+R83MMMaYk8sr/5UD/j/2nAi155cMxQAAAABJRU5ErkJggg==';
  1063. img.align = 'absmiddle';
  1064. img.border = '0';
  1065. img.style.paddingRight = '10px';
  1066. a.appendChild(document.createTextNode('Scripts'));
  1067. a.addEventListener('click', function (e) {
  1068. //make our new tab active when clicked, clear out the #guts div and add our settings to it
  1069. e.stopPropagation();
  1070. document.querySelector('.active').className = '';
  1071. document.querySelector('#scripts').className = 'active';
  1072. document.querySelector('#guts').innerHTML = '<div class="scaffold"></div>';
  1073. document.querySelector('#guts').appendChild(getSettings());
  1074. }, false);
  1075. } else {
  1076. //script tab already exists
  1077. document.querySelector('#scripts').firstChild.addEventListener('click', function (e) {
  1078. //some other script is doing the activation work, just add our settings
  1079. e.stopPropagation();
  1080. document.querySelector('#guts').appendChild(getSettings());
  1081. }, false);
  1082. }
  1083. }
  1084.  
  1085. function getSettings() {
  1086. //build our settings and return them for appending
  1087. var contents = document.createElement('div');
  1088. contents.id = 'recipecounterprefs';
  1089. var fieldset = contents.appendChild(document.createElement('fieldset'));
  1090. fieldset.setAttribute('style', 'width:33%; margin-top:20px');
  1091. var legend = fieldset.appendChild(document.createElement('legend'));
  1092. legend.className = 'subhead';
  1093. legend.textContent = 'Recipe Counter';
  1094. var section = fieldset.appendChild(document.createElement('div'));
  1095. section.className = 'indent';
  1096. section.appendChild(buildSettings());
  1097. return contents;
  1098. }
  1099.  
  1100. function buildSettings() {
  1101. //var ul = document.createElement('ul');
  1102. //var li = document.createElement('li');
  1103. var ar = document.createElement('a');
  1104. ar.setAttribute('href','#');
  1105. ar.appendChild(document.createTextNode('Update all recipe lists'));
  1106. ar.addEventListener('click',openAll,false);
  1107. ar.setAttribute('title','Note that this opens up 6 new windows.');
  1108. //li.appendChild(ar);
  1109. //ul.appendChild(li);
  1110. return ar;
  1111. }
  1112.  
  1113. function openAll() {
  1114. window.open('http://kol.coldfront.net/thekolwiki/index.php/Cocktailcrafting_Discoveries','Cocktailcrafting Discoveries');
  1115. window.open('http://kol.coldfront.net/thekolwiki/index.php/Cooking_Discoveries','Cooking Discoveries');
  1116. window.open('http://kol.coldfront.net/thekolwiki/index.php/Meat-Pasting_Discoveries','Meat-Pasting Discoveries');
  1117. window.open('http://kol.coldfront.net/thekolwiki/index.php/Meatsmithing_Discoveries','Meatsmithing Discoveries');
  1118. window.open('http://kol.coldfront.net/thekolwiki/index.php/Miscellaneous_Discoveries','Miscellaneous Discoveries');
  1119. }
  1120.  
  1121. if (window.location.href.indexOf('http://kol.coldfront.net/thekolwiki/index.php/')>=0) {
  1122. gather(getPageMD5(document.body.innerHTML));
  1123. } else if (window.location.pathname.indexOf('/account.php')==0) {
  1124. buildPrefs();
  1125. } else {
  1126. checkDiscoveries();
  1127. doPage();
  1128. }

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址