您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Helps with solving the detective school puzzles in Kingdom of Loathing
当前为
// ==UserScript== // @name KoL Detective Helper // @namespace kol.interface.unfinished // @description Helps with solving the detective school puzzles in Kingdom of Loathing // @include https://*kingdomofloathing.com/wham.php* // @grant GM_setValue // @grant GM_getValue // @version 1.0.1 // ==/UserScript== // Version 1.0.1 // - highlight active row better // Version 1.0 var titleKey; var places; var person; var people; var jobs; var personPlaceJob = {}; var personSays = {}; function getTitle() { var t = document.evaluate( '//b[contains(.,"Who killed ")]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (t.singleNodeValue) { var title = t.singleNodeValue.innerHTML; // console.log('title is '+title); titleKey = title; var tt = document.evaluate( '//td[contains(.,"You have been on this case for ")]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (tt.singleNodeValue) { var re = tt.singleNodeValue.innerHTML.match(/You have been on this case for ([0-9][0-9]*) minute/); if (re) { var mins = re[1]; // console.log('minutes is '+mins); if (mins!=0) getTruthAndLies(); } } } } function gatherLocations() { var rc = []; var locs = document.evaluate( '//a[contains(@href,"wham.php?visit=")]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null); for (var i=0;i<locs.snapshotLength;i++) { var loc = locs.snapshotItem(i); var aloc = loc.firstChild.firstChild.innerHTML; rc[rc.length] = aloc; // console.log('location: '+aloc); } return rc; } function gatherPeople() { var rc = []; for (var p in personPlaceJob) { rc[rc.length] = p; } return rc; } function gatherJobs() { var rc = []; for (var p in personPlaceJob) { rc[rc.length] = personPlaceJob[p].job; } return rc; } // ------------------------------------------------- function gatherPerson() { var p = document.evaluate( '//input[@value="Accuse!"]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (p.singleNodeValue) { p = document.evaluate( './/b', p.singleNodeValue.parentNode.parentNode, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (p.singleNodeValue) { person = p.singleNodeValue.innerHTML; var role = String(p.singleNodeValue.nextSibling.nextSibling.nextSibling.nodeValue).trim(); var loc = String(p.singleNodeValue.nextSibling.nextSibling.nextSibling.nextSibling.innerHTML).trim().replace(")","").replace("(",""); //console.log(person+', '+role+' is at '+loc); var peep = personPlaceJob[person]; if (peep) { peep.job = role; peep.place = loc; } else { personPlaceJob[person] = { job:role, place:loc }; } console.log('Person: '+person); var assocs = gatherAnswer(person); } } } function gatherAnswer(person) { var a = document.evaluate( '//td[@colspan="2" and @width="500"]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null); if (a.singleNodeValue) { var t = a.singleNodeValue.innerHTML; var p,l,j; var accused = checkAccused(t); console.log('accused? ' + accused); for (var i in people) { var re = new RegExp('\\b'+people[i]+'\\b'); if (re.test(t)) { p = people[i]; //console.log('Talking about person '+p); } } for (var i in places) { var re = new RegExp('\\b'+places[i]+'\\b'); if (re.test(t)) { if (!l || l.length<places[i].length) { l = places[i]; } //console.log('Talking about location '+l); } } // console.log('looking for jobs'); for (var i in jobs) { var re = new RegExp('\\b'+jobs[i]+'\\b'); var w = t.search(re); if (w>=3 && t.substr(w-3,3).toLowerCase()!="ex-") { if (!j || j.length<jobs[i].length) { j = jobs[i]; } // console.log('Talking about job '+j); } } var map = personSays[person]; if (!map) { map = new Object(); personSays[person] = map; } if (p && l) { console.log(p + ' -> ' + l); map[p+'.place'] = l; } if (p && j) { console.log(p + ' -> ' + j); map[p+'.job'] = j; } if (l && j) { console.log(l + ' -> ' + j); map[l] = j; } if (accused) { if (p) map.accused = p; else if (j) map.accused = j; else map.accused = 'n/a'; } } } function checkAccused(text) { var re = /("Do you have any thoughts on who did it\?" you ask.|"Help me out here," you say\. "You know all the people in this house. Who's the most likely killer\?"|"Who do you think is the most likely to be the killer\?" you ask\.|"Who do you think the killer is\?" you ask.|"Does anyone else here seem particularly suspicious to you\?" you ask\.|"If you had to guess," you ask, "who would you say did it\?")/; return re.test(text); } // ------------------------------------------------- function saveTruthAndLies() { GM_setValue('truth',JSON.stringify(personPlaceJob)); GM_setValue('lies',JSON.stringify(personSays)); // var i = 1; // // console.log('Truth:'); // for (var p in personPlaceJob) { // console.log(i+'. '+p+': '+personPlaceJob[p].job+', '+personPlaceJob[p].place); // i = i+1; // } // // console.log('Lies:'); // i = 1; // for (var p in personSays) { // var ps = personSays[p]; // var s = ''; // for (var rel in ps) { // if (s) // s += ', '; // s += rel+':'+ps[rel]; // } // console.log(i+'. '+p+' says '+s); // i = i+1; // } } function getTruthAndLies() { var t = GM_getValue('truth',''); if (t) { personPlaceJob = JSON.parse(t); } var lies = GM_getValue('lies',''); if (lies) { personSays = JSON.parse(lies); } } function abbreviateName(name) { var re = /^([A-Z])[a-zA-Z]* ([A-Z])/; var m = name.match(re); if (m) return m[1]+m[2]; return name; } function display() { var tbl = document.createElement('table'); tbl.setAttribute('style','width:95%;font-size:9pt;border-collapse:collapse;border:1px solid black;'); tbl.setAttribute('cellpadding','3'); tbl.setAttribute('cellspacing','2'); // headers var c,r = tbl.insertRow(); r.setAttribute('style','border:1px solid black;'); c = r.insertCell(); c.appendChild(document.createTextNode('Perp')); for (var ppl in people) { var name = abbreviateName(people[ppl]); c = r.insertCell(); c.appendChild(document.createTextNode(name)); // c = r.insertCell(); // c.appendChild(document.createTextNode(name)); } for (var loc in places) { c = r.insertCell(); c.appendChild(document.createTextNode(places[loc])); } c = r.insertCell(); c.appendChild(document.createTextNode('Acc')); for (var p in personSays) { r = tbl.insertRow(); var rattrib = "border:1px solid black;"; c = r.insertCell(); if (p==person) { var b = document.createElement('b'); b.appendChild(document.createTextNode(p)); c.appendChild(b); rattrib = rattrib + "background-color:rgb(250,230,230);"; } else { c.appendChild(document.createTextNode(p)); } r.setAttribute('style',rattrib); c.appendChild(document.createElement('br')); if (personPlaceJob[p] && personPlaceJob[p].place) { var b = document.createElement('div'); b.setAttribute('style','font-size:smaller;'); if (personPlaceJob[p].job) { b.appendChild(document.createTextNode(personPlaceJob[p].job)); b.appendChild(document.createElement('br')); } b.appendChild(document.createTextNode(personPlaceJob[p].place)); c.appendChild(b); } for (var ppl in people) { c = r.insertCell(); var place = personSays[p][people[ppl]+'.place']; if (place) { var d = document.createElement('div'); // check truth if (personPlaceJob[people[ppl]] && personPlaceJob[people[ppl]].place) { // we know this association if (personPlaceJob[people[ppl]].place==place) { d.setAttribute('style','color:green;border-bottom:1px solid black;'); } else { d.setAttribute('style','color:red;border-bottom:1px solid black;'); } } else { d.setAttribute('style','color:gray;border-bottom:1px solid black;'); } d.appendChild(document.createTextNode(place)); c.appendChild(d); } else { c.appendChild(document.createElement('br')); } //c = r.insertCell(); //c.appendChild(document.createElement('br')); var job = personSays[p][people[ppl]+'.job']; if (job) { var d = document.createElement('div'); // check truth if (personPlaceJob[people[ppl]] && personPlaceJob[people[ppl]].job) { if (personPlaceJob[people[ppl]] && personPlaceJob[people[ppl]].job==job) { d.setAttribute('style','color:green;border-top:1px solid black;'); } else { d.setAttribute('style','color:red;border-top:1px solid black;'); } } else { d.setAttribute('style','color:gray;border-top:1px solid black;'); } d.appendChild(document.createTextNode(job)); c.appendChild(d); } else { c.appendChild(document.createElement('br')); } } for (var loc in places) { c = r.insertCell(); var job = personSays[p][places[loc]]; if (job) { var d = document.createElement('div'); d.setAttribute('style','color:gray;'); // check truth for (var others in personPlaceJob) { var other = personPlaceJob[others]; if (other.job==job && other.place) { if (other.place==places[loc]) { d.setAttribute('style','color:green;'); } else { d.setAttribute('style','color:red;'); } break; } else if (other.place==places[loc] && other.job) { if (other.job==job) { d.setAttribute('style','color:green;'); } else { d.setAttribute('style','color:red;'); } break; } } d.appendChild(document.createTextNode(job)); c.appendChild(d); } } c = r.insertCell(); if (personSays[p].accused) { c.appendChild(document.createTextNode(personSays[p].accused)); } } document.body.appendChild(tbl); } // ------------------------------------------------- getTitle(); places = gatherLocations(); people = gatherPeople(); jobs = gatherJobs(); gatherPerson(); saveTruthAndLies(); display();