您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Version 0.1.7 - The [], spring break monsters
- // antimarty's monster manuel helper - pop up monster info for the monster you are fighting
- //
- // Released under the GPL license
- // http://www.gnu.org/copyleft/gpl.html
- //
- // ==UserScript==
- // @name monster manuel
- // @namespace antimarty
- // @include *kingdomofloathing.com/fight.php*
- // @include *127.0.0.1:600*/fight.php*
- // @include *localhost:*/fight.php*
- // @include *kingdomofloathing.com/questlog.php.php*
- // @include *127.0.0.1:600*/questlog.php*
- // @include *localhost:*/questlog.php*
- // @version 0.1.7
- // @grant GM_getValue
- // @grant GM_setValue
- // @grant GM_xmlhttpRequest
- //
- // @description Version 0.1.7 - The [], spring break monsters
- //
- // ==/UserScript==
- // released versions:
- // Version 0.0.1 - first try
- // Version 0.0.2 - fixes for special case monster names
- // Version 0.0.3 - more fixes, add update link, general cleanup
- // Version 0.0.4 - fernswarthy monster fixes
- // Version 0.0.5 - slime tube and hobo monsters, haunted sorority monsters
- // Version 0.0.6 - redo popup for non-mafia
- // Version 0.0.7 - clean up some minor error handling stuff
- // Version 0.0.8 - crimbo 2012 - taco elves and crimbokutown workers
- // Version 0.0.9 - "The" Cray-kin, other jar of psychoses stuff, game inform monsters
- // Version 0.1.0 - "The" Sierpinski Brothers, "The" Server, mafia wants a password
- // Version 0.1.1 - password bug fix
- // Version 0.1.2 - mostly undo the password bug fix, and a few things like angry angry bugbears
- // Version 0.1.3 - add custom monster entry, then remove it. Plus more names-from-images.
- // Version 0.1.4 - dreadsylvania monsters, fixes for GM/Firefox updates
- // Version 0.1.5 - add junksprites, halloween monsters
- // Known bugs:
- // - shows all factoids for multiple monsters with the same name
- /* var currentVersion = "0.1.6";
- var scriptSite = "http://userscripts.org/scripts/show/150102"
- // this is a small file autogenerated by userscripts.org from Userscript @ comments above, use to reduce bandwidth on version check
- var scriptURL = "http://userscripts.org/scripts/source/150102.meta.js";
- */
- ////////////////////////////////////////////////////////////////////////////////
- // Based on a function taken from OneTonTomato's UpUp skill script
- function GM_get(target, callback) {
- GM_xmlhttpRequest({
- method: 'GET',
- url: target,
- onload:function(details) {
- if( typeof callback=='function' ){
- callback(details.responseText);
- }
- }
- });
- }
- // Check for an updated script version
- function CheckScriptVersion(data)
- {
- // Preemptively set error, in case request fails...
- GM_setValue("webVersion", "Error")
- var m = data.match(/@version\s*([0-9.]+)/);
- if (m)
- {
- GM_setValue("webVersion", m[1]);
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // parse the char pane for the player name
- // revised version! now taken directly from kolpreviousnadventures to handle compact mode
- function getPlayerNameFromCharpane() {
- var failed = {'username': "", 'fullmode': true};
- if (!top.frames || !top.frames[0]) return failed;
- var username = top.frames[0].document.getElementsByTagName("b");
- if (!username || username.length < 1) return failed;
- username = username[0];
- if (!username) return failed;
- username = username.firstChild;
- if (!username) return failed;
- // in full mode the link is <a><b>Name</b></a>
- // in compact mode it's <b><a>Name</a></b>
- // so have to handle this, and also can use it to tell
- // whether it's in compact mode or not.
- var fullmode = true;
- while (username && username.nodeType == 1)
- {
- username = username.firstChild;
- fullmode = false;
- }
- if (!username) return failed;
- username = username.nodeValue;
- if (!username) return failed;
- username = username.toLowerCase();
- // alert("found username " + username + ", fullmode: " + fullmode);
- return {'username': username, 'fullmode': fullmode};
- }
- // don't strip "The" (and maybe other stuff tbd) from the names of these
- var invariableMonsterNames = [
- "El Diablo",
- "five skeleton invaders", // this one shares an image name with procedural stuff
- "The Avatar of Sneaky Pete",
- "The Bat in the Spats",
- "The Beefhemoth",
- "The Big Wisniewski",
- "The Clownlord Beelzebozo",
- "The Cray-Kin",
- "The Frattlesnake",
- "The Free Man",
- "the ghost of Phil Bunion",
- "the gunk",
- "The Landscaper",
- "The Large-Bellied Snitch",
- "The Man",
- "The Sierpinski brothers",
- "The Server",
- "The Snake With Like Ten Heads",
- "The Terrible Pinch",
- "The Thing with No Name",
- "The Thorax",
- "The Unkillable Skeleton"];
- // for monsters with name generators, or easier to look at the image names
- var monsterImages = {
- "sororghost": "sexy sorority ghost",
- "sororeton": "sexy sorority skeleton",
- "sororpire": "sexy sorority vampire",
- "sororwolf": "sexy sorority werewolf",
- "sororbie": "sexy sorority zombie",
- "coldhobo": "Cold hobo",
- "hothobo": "Hot hobo",
- "nhobo": "Normal hobo",
- "slhobo": "Sleaze hobo",
- "spookyhobo": "Spooky hobo",
- "stenchhobo": "Stench hobo",
- "elfhobo": "Hobelf",
- "animelf1": "tiny-screwing animelf",
- "animelf2": "plastic-extruding animelf",
- "animelf3": "circuit-soldering animelf",
- "animelf4": "quality control animelf",
- "animelf5": "toy assembling animelf",
- "beergolem": "X Bottles of Beer on a Golem",
- "stonegolem": "X Stone Golem",
- "dimhorror":" X-dimensional horror",
- "hydra": "X-headed Hydra",
- "earbeast": "Beast with X Ears",
- "eyebeast": "Beast with X Eyes",
- "fernghost": "Ghost of Fernswarthy's Grandfather",
- "tacoelf_sign": "sign-twirling Crimbo elf",
- "tacoelf_taco": "taco-clad Crimbo elf",
- "tacoelf_cart": "tacobuilding elf",
- "bigskeleton": "procedurally-generated skeleton",
- "faq_miniboss": "Video Game Miniboss",
- "faq_boss": "Video Game Boss",
- "faq_": "Video Game Minion", // no convenient way to tell strong vs. weak vs. moderate
- "bb_caveman": "angry cavebugbear", // and all the very very very... angry ones, too
- "dvhotbear": "hot bugbear",
- "dvcoldbear": "cold bugbear",
- "dvspookybear": "spooky bugbear",
- "dvsleazebear": "sleaze bugbear",
- "dvstenchbear": "stench bugbear",
- "dvhotghost": "hot ghost",
- "dvcoldghost": "cold ghost",
- "dvspookyghost": "spooky ghost",
- "dvsleazeghost": "sleaze ghost",
- "dvstenchghost": "stench ghost",
- "dvhotskel": "hot skeleton",
- "dvcoldskel": "cold skeleton",
- "dvspookyskel": "spooky skeleton",
- "dvsleazeskel": "sleaze skeleton",
- "dvstenchskel": "stench skeleton",
- "dvhotvamp": "hot vampire",
- "dvcoldvamp": "cold vampire",
- "dvspookyvamp": "spooky vampire",
- "dvsleazevamp": "sleaze vampire",
- "dvstenchvamp": "stench vampire",
- "dvhotwolf": "hot werewolf",
- "dvcoldwolf": "cold werewolf",
- "dvspookywolf": "spooky werewolf",
- "dvsleazewolf": "sleaze werewolf",
- "dvstenchwolf": "stench werewolf",
- "dvhotzom": "hot zombie",
- "dvcoldzom": "cold zombie",
- "dvspookyzom": "spooky zombie",
- "dvsleazezom": "sleaze zombie",
- "dvstenchzom": "stench zombie",
- "shopteacher": "X-fingered Shop Teacher",
- "js_bender": "junksprite bender",
- "js_melter": "junksprite melter",
- "js_sharpener": "junksprite sharpener",
- "vandalkid": "vandal kid",
- "paulblart": "suburban security civilian",
- // sloppy seconds sundae, spring break sunken party
- "ssd_cocktail": "Sloppy Seconds Cocktail",
- "ssd_sundae": "Sloppy Seconds Sundae",
- "ssd_burger": "Sloppy Seconds Burger",
- "fun-gal": "Fun-Guy Playmate",
- "srpainting": "ancestral Spookyraven portrait"
- };
- ////////////////////////////////////////////////////////////////////////////////
- // get monster name (monster manuel version)
- function getMonsterName(data) {
- var monsterName = /id=\"monname\"> *(.*?)<\/span>/i.exec(data);
- if(monsterName)
- monsterName = monsterName[1];
- else
- return "";
- var imageName = /adventureimages\/(.*?)\.gif/i.exec(data);
- if(imageName)
- imageName = imageName[1];
- else
- return "";
- // alert("initially found monster name: " + monsterName + " (image name: " + imageName + ")");
- // strip off leading articles, etc from monster names as seen during fight
- // maybe make this a list of prefixes, it's getting pretty long
- if(invariableMonsterNames.indexOf(monsterName) == -1) {
- if( monsterName.substring(0,2).toLowerCase()=="a ")
- monsterName = monsterName.substring(2,monsterName.length);
- else if( monsterName.substring(0,3).toLowerCase()=="an ")
- monsterName = monsterName.substring(3,monsterName.length);
- else if( monsterName.substring(0,5).toLowerCase()=="some ")
- monsterName = monsterName.substring(5,monsterName.length);
- else if( monsterName.substring(0,4).toLowerCase()=="the ")
- monsterName = monsterName.substring(4,monsterName.length);
- else if( monsterName.substring(0,3).toLowerCase()=="el ")
- monsterName = monsterName.substring(3,monsterName.length);
- else if( monsterName.substring(0,3).toLowerCase()=="la ")
- monsterName = monsterName.substring(3,monsterName.length);
- // translate special cases
- if(monsterName.indexOf("'s butt") != -1)
- monsterName = "[somebody else's butt]";
- else if(monsterName.substring(0,6).toLowerCase()=="shadow" && monsterName.indexOf("Black Bubbles")==-1 && imageName.indexOf("faq_")==-1)
- monsterName = "(shadow opponent)";
- // all slime tube monsters are... "Slime Tube monster", ignore names, just check for the image
- else if(/slime[1-5]/i.exec(imageName) != null )
- monsterName = "Slime Tube monster";
- // more monsters-from-images
- // keep trailing numbers for anime elves (different monsters), strip otherwise (different images for same mob)
- else if(/animelf[1-5]/i.exec(imageName) != null )
- monsterName = monsterImages[imageName];
- else {
- var stripped = /(.*?)[0-9]+/i.exec(imageName);
- if(stripped != null) imageName=stripped[1];
- if(monsterImages[imageName] != undefined)
- monsterName = monsterImages[imageName];
- else if(imageName.substring(0,4).toLowerCase()=="faq_") // video game minions, how to tell strong vs. weak?
- monsterName = monsterImages["faq_"];
- }
- }
- // alert("returning monster name: " + monsterName + " (image name: " + imageName + ")");
- return monsterName;
- }
- // from one ton tomato's mallsearch script
- function getParent(el, pTagName) {
- if (el == null) {
- return null;
- } else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase()) { // Gecko bug, supposed to be uppercase
- return el;
- } else {
- return getParent(el.parentNode, pTagName);
- }
- }
- // fill my popup window with a reduced version of manuels facts, for our monster only
- function processManual(data){
- var myDocument = document.createElement('div');
- myDocument.innerHTML = data;
- // could just get monsterName directly, this is a relic from earlier versions
- var monsterName = /\&monster=(.+)/i.exec(decodeURIComponent(manuelURL));
- if(monsterName) monsterName = monsterName[1];
- // alert("monster name = " + monsterName);
- // first find the table with our monster; find its parent; use that to find all the monster tables
- if(monsterName) {
- // strip out the javascript href change that loads the game main page
- var allscripts = myDocument.getElementsByTagName("script");
- allscripts[0].parentNode.removeChild(allscripts[0]);
- var allElements = myDocument.getElementsByTagName("font");
- var parentNode = 0;
- var monsterTables =0;
- var i;
- for(i=0; i < allElements.length; i++) {
- if(allElements[i].innerHTML.indexOf(monsterName) != -1) {
- parentNode = getParent(allElements[i], "table");
- parentNode = getParent(parentNode, "p");
- monsterTables = parentNode.getElementsByTagName("table");
- break;
- }
- }
- // now delete all that parent's children, except our keeper monster
- // monsterTables is a live list, so as we delete items in the doc, list items disappear...
- if(monsterTables) {
- for(i=0; i < monsterTables.length; ) {
- // use the <font></font> tags to eliminate false matches in random text. Harem guards
- // is an example. (why did I change this?)
- // if(monsterTables[i].innerHTML.indexOf(">" + monsterName + "</font>") > -1) {
- if(monsterTables[i].innerHTML.indexOf(">" + monsterName + "<") >= 0
- || monsterName=="Video Game Minion" && monsterTables[i].innerHTML.indexOf(">" + monsterName)>= 0) {
- // our monster, skip it
- i++;
- }
- else {
- // not our monster, delete it (next target monster table will be at same index)
- // there is also an <a> node in front of each monster
- monsterTables[i].parentNode.removeChild(monsterTables[i].previousSibling);
- monsterTables[i].parentNode.removeChild(monsterTables[i]);
- }
- }
- }
- // delete some junk stuff - other quests header info, back to campsite footer, etc
- if(parentNode.parentNode) {
- parentNode.parentNode.removeChild(parentNode.parentNode.firstChild);
- parentNode.parentNode.removeChild(parentNode.parentNode.firstChild);
- parentNode.parentNode.removeChild(parentNode.parentNode.firstChild);
- parentNode.parentNode.removeChild(parentNode.parentNode.lastChild);
- parentNode.parentNode.removeChild(parentNode.parentNode.lastChild);
- }
- /* // if new script version available, add a link
- var webVer = GM_getValue("webVersion", "Error");
- if (webVer != "Error" && webVer > currentVersion) { // this is actually a text string comparison, not numerical
- var newElement = document.createElement('p');
- newElement.style.fontSize = "x-small";
- newElement.appendChild(document.createTextNode("New Monster Manuel script version " + webVer + " available: "));
- var hrefElement = document.createElement('a');
- hrefElement.setAttribute('href', scriptSite);
- hrefElement.setAttribute('target', "_blank");
- hrefElement.appendChild(document.createTextNode("here"));
- newElement.appendChild(hrefElement);
- parentNode.parentNode.appendChild(newElement);
- }
- */
- // and finally fill our window
- myWindow.document.documentElement.innerHTML = myDocument.innerHTML;
- myWindow.document.close();
- }
- }
- // pop up an empty window for our factoid, and call something to fill it
- // to do: figure out how to size this appropriately
- var myWindow;
- function manuelPopup()
- {
- myWindow = window.open(baseURL,'manuel','height=400,width=500,scrollbars=yes');
- GM_get(baseURL + manuelURL, processManual);
- }
- // parse the charpane info for the password hash (use as a session ID)
- function getPwdHash(data){
- var pwdHash = /pwdhash \= \"(.*?)\"/i.exec(data); // the .*? is the non-greedy version of .*
- if(pwdHash)
- pwdHash = pwdHash[1];
- else
- pwdHash = "";
- return pwdHash;
- }
- ////////////////////////////////////////////////////////////////////////////////
- function monsterNameEntry() {
- var monsterName = prompt("Enter Monster Name to research:\n", "");
- var firstChar = monsterName.toLowerCase().charAt(0) ;
- if(firstChar < 'a' || firstChar > 'z') firstChar = '-';
- manuelURL = "questlog.php?which=6&vl=" + firstChar + "&monster="+monsterName;
- manuelPopup();
- }
- ////////////////////////////////////////////////////////////////////////////////
- // currently unused - not really helpful to search unless can cross first-letter sections
- function processQuestPage() {
- var entries = document.getElementsByTagName("b");
- var i;
- for(i=0; i < entries.length; i++) {
- if(entries[i].innerHTML == "Other") {
- // append our item here
- var newElement = entries[i].parentNode.parentNode.appendChild(document.createElement('b'));
- newElement.setAttribute("onmouseover", 'this.style.opacity="0.5"');
- newElement.setAttribute("onmouseout", 'this.style.opacity="1"');
- newElement.innerHTML = " Search";
- newElement.addEventListener("click", monsterNameEntry);
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- function processFight() {
- var playerName = getPlayerNameFromCharpane().username;
- var pwdHash = "";
- // once per login, check if a new version is available
- // why all this top level stuff sometimes fails at each level, who knows
- if(playerName && top && top.frames[0] && top.frames[0].document && top.frames[0].document.documentElement) {
- pwdHash = getPwdHash(top.frames[0].document.documentElement.innerHTML);
- var oldPwdHash = GM_getValue(playerName + "_pwdHash", 0);
- if(pwdHash != oldPwdHash) {
- // new session
- GM_setValue(playerName + "_pwdHash", pwdHash);
- /* // check for a new version of script if none seen already
- var webVer = GM_getValue("webVersion", "Error");
- if(webVer == "Error" || webVer <= currentVersion)
- GM_get(scriptURL, CheckScriptVersion);
- */
- }
- // clear any lingering flag that was set with empty player name by old script versions
- GM_setValue("_hasManuel", false);
- }
- var monsterName = getMonsterName(document.body.innerHTML);
- var firstChar = monsterName.toLowerCase().charAt(0) ;
- if(firstChar < 'a' || firstChar > 'z') firstChar = '-';
- // apparently mafia now wants a password
- // yay, that change got reverted, and was causing problems anyway
- // manuelURL = "questlog.php?which=6&vl=" + firstChar + "&pwd=" + pwdHash + "&monster="+monsterName;
- manuelURL = "questlog.php?which=6&vl=" + firstChar + "&monster="+monsterName;
- // find the monster's HTML element on the page; add our link
- var monsterSpan = document.getElementById("monname");
- var monsterTable = getParent(monsterSpan, "table");
- if(monsterSpan && monsterTable) {
- var newElement = document.createElement("FONT");
- // make sure we have a factoid to popup - signalled by the attack/defense/hp display
- // or by monster manuel saying something
- if(monsterTable.innerHTML.indexOf("Enemy's Attack Power") != -1
- || document.body.innerHTML.indexOf("Monster Manuel") != -1 ){
- if(playerName != "")
- GM_setValue(playerName+"_hasManuel", true); // current monster has factoids, ergo player has manuel
- newElement.innerHTML = "<font size=2> (<u>factoids</u>)</font>"; ;
- newElement.setAttribute("onmouseover", 'this.style.opacity="0.5"');
- newElement.setAttribute("onmouseout", 'this.style.opacity="1"');
- newElement.setAttribute("id", 'manuel');
- newElement.addEventListener("click", manuelPopup, true);
- // always insert a factoid link if there are factoids
- monsterSpan.parentNode.insertBefore(newElement, monsterSpan.nextSibling);
- } else {
- newElement.innerHTML = "<font size=2> (no factoids)</font>"; ;
- newElement.setAttribute("onmouseout", 'this.style.opacity="0.5"');
- newElement.setAttribute("id", 'manuel');
- // no factoids, only insert the link if we know the player has manuel
- if(GM_getValue(playerName+"_hasManuel", false) == true )
- monsterSpan.parentNode.insertBefore(newElement, monsterSpan.nextSibling);
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- // main prog, just call the proper routine if we are on a pane we care about
- var nodeBody = document.getElementsByTagName("body").item(0);
- var baseURL = "";
- var manuelURL = "";
- if (nodeBody) {
- baseURL = nodeBody.baseURI.substring(0,nodeBody.baseURI.lastIndexOf('/')+1);
- }
- // our popup gets named after the originating window, which is fight.php, so don't process it
- if(window.name != "manuel" && document.location.pathname.indexOf("fight.php") != -1 ) {
- processFight();
- }
- else if(document.location.pathname.indexOf("questlog.php") != -1 ) {
- // deprecated until I can figure out how to search across different first letters
- // processQuestPage();
- }
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址