您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
GPS for fields
// ==UserScript== // @name BvS Quickfield // @namespace http://userscripts.org/users/dtkarlsson // @description GPS for fields // @include http*://*animecubed.com/billy/bvs/villagefields* // @include http*://*animecubedgaming.com/billy/bvs/villagefields* // @licence MIT; http://www.opensource.org/licenses/mit-license.php // @copyright 2009, Daniel Karlsson // @version 1.0.4 // @history 1.0.4 New domain - animecubedgaming.com - Channel28 // @history 1.0.3 Now https compatible (Updated by Channel28) // @history 1.0.2 Fixed various issues (Updated by Sena) // @history 1.0.1 Added grant permissions (Updated by Channel28) // @history 1.0.0 Changed to a more console-y design // @history 1.0.0 Simplified field reordering // @history 1.0.0 Script now calculates field difficulty range // @history 1.0.0 Minor tweaks here and there // @history 0.3.0 Added key reordering by drag and drop // @history 0.2.0 Change from GM_set/getValue to DOM Storage API // @history 0.2.0 Redesigned the UI // @grant GM_log // @grant GM_addStyle // ==/UserScript== /* DOM Storage wrapper class Constructor: var store = new DOMStorage({"session"|"local"}, [<namespace>]); Set item: store.setItem(<key>, <value>); Get item: store.getItem(<key>[, <default value>]); Remove item: store.removeItem(<key>); Get all keys in namespace as array: var array = store.keys(); */ function DOMStorage(type, namespace) { var my = this; if (typeof(type) != "string") type = "session"; switch (type) { case "local": my.storage = localStorage; break; case "session": my.storage = sessionStorage; break; default: my.storage = sessionStorage; } if (!namespace || typeof(namespace) != "string") namespace = "Greasemonkey"; my.ns = namespace + "."; my.setItem = function(key, val) { try { my.storage.setItem(encodeURIComponent(my.ns + key), val); } catch (e) { GM_log(e); } }, my.getItem = function(key, def) { try { var val = my.storage.getItem(encodeURIComponent(my.ns + key)); if (val) return val; else return def; } catch (e) { return def; } } my.removeItem = function(key) { try { // Kludge, avoid Firefox crash my.storage.setItem(encodeURIComponent(my.ns + key), null); } catch (e) { GM_log(e); } } my.keys = function() { // Return array of all keys in this namespace var arr = []; var i = 0; do { try { if (i>my.storage.length) { throw 'error'; } var key = decodeURIComponent(my.storage.key(i)); if (key.indexOf(my.ns) == 0) arr.push(key.slice(my.ns.length)); } catch (e) { break; } i++; } while (true); return arr; } } var DS = new DOMStorage("local", "BvSQuickfield"); const KEYDIFF = { simple: 0, training: 0, aquafield: 0, dimlylit: 5, crumbling: 5, dealersroom: 5, blaring: 10, hairy: 10, parkinglot: 10, pulsating: 15, worst: 15, core: 15, hidden: 20, forbidden: 20, holyground: 20, darkside: 20, raging: 25, passionate: 25, melody: 25, cursed: 40, filthy: 40, noodleshop: 40, chosen: 60, hopeless: 60, nothingness: 60, brilliant: 65, delicious: 65, dancefloor: 65, beautiful: 70, passedover: 70, touchstone: 70, corrupted: 80, despaired: 80, paradise: 80, sickened: 100, imprisoned: 100, fallenangel: 100, merciless: 130, grieving: 130, furnace: 130 }; function Field() { var my = this; my.keys = []; my.notes = ""; my.unpack = function(str) { if (!str || typeof(str) != "string") return false; // Restore from string "<key>|<key>|<key>|<notes>" var match = str.match(/(.*)\|(.*)\|(.*)\|(.*)/); if (match) { var field = new Field(); my.keys = []; my.keys[0] = match[1]; my.keys[1] = match[2]; my.keys[2] = match[3]; my.notes = match[4]; return true; } return false; } my.pack = function() { // Return string "<key>|<key>|<key>|<notes>" return my.keys.join("|") + "|" + my.notes; } my.difficulty = function() { return KEYDIFF[keyStyle(my.keys[0])] + KEYDIFF[keyStyle(my.keys[1])] + KEYDIFF[keyStyle(my.keys[2])]; } } function FieldList() { var my = this; my.fields = []; my.load = function(store) { my.fields = []; var keys = store.keys(); for (var i in keys) { if (/field(\d+)/.test(keys[i])) { var index = parseInt(RegExp.lastParen); var field = new Field(); if (field.unpack(store.getItem(keys[i]))) my.fields[index] = field; else store.removeItem(keys[i]); } else store.removeItem(keys[i]); } } my.save = function(store) { var keys = store.keys(); for (var i in keys) store.removeItem(keys[i]); var i = 0; for (var j in my.fields) { store.setItem("field" + i, my.fields[j].pack()); i++; } } } var FIELDLIST = new FieldList(); FIELDLIST.load(DS); // Event handlers // Update Add button and difficulty hint function updateDifficulty() { var f = new Field(); f.keys = getField(); var dnode = document.evaluate("//form/table/tbody/tr/td[@colspan='2'][contains(text(), 'Stamina')]", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; if (dnode) { var d = f.difficulty(); var sta = dnode.textContent.replace(/Stamina.*/, "Stamina"); dnode.textContent = sta + ", Difficulty: " + d + " - " + (d + 5) + ")"; } var button = document.getElementById("addfield"); if (button) button.textContent = "Add " + f.keys.join(" - "); } function buttonClick(event) { var id = event.target.getAttribute("id"); if (/remove(\d+)/.test(id)) { var index = parseInt(RegExp.lastParen); removeField(index); } else if (/setfield(\d+)/.test(id)) { var index = parseInt(RegExp.lastParen); setField(FIELDLIST.fields[index].keys); updateDifficulty(); } else if (/addfield/.test(id)) { addField(); } } var dragging = null; var hover = null; var prevHover = null; function mousedownEvent(event) { // Find td with class = "key" var cl = event.target.getAttribute("class"); if (!/key/.test(cl)) return; // Get parent tr dragging = event.target.parentNode; event.preventDefault(); window.addEventListener('mouseup', mouseupEvent, true); window.addEventListener('mousemove', moveEvent, true); } function moveEvent(event) { if (!dragging) return; event.preventDefault(); var cl = event.target.getAttribute("class"); if (!/key/.test(cl)) { window.removeEventListener('mouseup', mouseupEvent, true); window.removeEventListener('mousemove', moveEvent, true); dragging = null; hover = null; prevHover = null; } hover = event.target.parentNode; var r1 = parseInt(dragging.id.replace(/row/, "")); var r2 = parseInt(hover.id.replace(/row/, "")); if (r1 != r2) { var f = FIELDLIST.fields[r1]; FIELDLIST.fields[r1] = FIELDLIST.fields[r2]; FIELDLIST.fields[r2] = f; FIELDLIST.save(DS); updateTable(); dragging = hover; } } function mouseupEvent(event) { if (!dragging) return; window.removeEventListener('mouseup', mouseupEvent, true); window.removeEventListener('mousemove', moveEvent, true); dragging = null; hover = null; prevHover = null; } // UI // Return currently selected item from dropdown function getSelectedItem(xpath) { var dropdown = document.evaluate(xpath, document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; return dropdown.options[dropdown.selectedIndex].text; } // Current field keys function getField() { var keys = []; keys[0] = getSelectedItem("//select[@name='key_1']"); keys[1] = getSelectedItem("//select[@name='key_2']"); keys[2] = getSelectedItem("//select[@name='key_3']"); return keys; } // Set field keys function setField(keys) { for (var i = 0; i < 3; i++) { var dropdown = document.evaluate("//select[@name='key_" + (i + 1) + "']", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; for (var j in dropdown.options) if (dropdown.options[j].text == keys[i]) { dropdown.selectedIndex = j break; } } uselessCrap(keys, "cd "); } // Add a field to DB function addField(keys) { if (!keys) keys = getField(); var notes = prompt("Notes for " + keys.join(" - "), "-"); if (notes) { var field = new Field(); field.keys = keys; field.notes = notes; FIELDLIST.fields.push(field); FIELDLIST.save(DS); updateTable(); uselessCrap(keys, "mkdir -p "); } } // Change field notes function changeNotes(index) { var notes = prompt("Notes for " + FIELDLIST.fields[index].keys.join(" - "), FIELDLIST.fields[index].notes); if (notes) { FIELDLIST.fields[index].notes = notes; FIELDLIST.save(DS); updateTable(); } } // Remove a field from DB function removeField(index) { if (FIELDLIST.fields[index] && confirm("Remove field " + FIELDLIST.fields[index].keys.join(" - ") + "?")) { var keys = FIELDLIST.fields[index].keys; FIELDLIST.fields.splice(index, 1); FIELDLIST.save(DS); updateTable(); uselessCrap(keys, "rm -rf "); } } // Create the UI table function createTable() { var addtable = document.getElementById("quickfield"); if (!addtable) { addtable = document.createElement("table"); addtable.setAttribute("id", "quickfield"); addtable.innerHTML = '<caption><span id="cli">//Quickfield</span>' + '<span class="blink">_</span></caption>' + '<col width="auto"/><col/><col/><col/>' + '<col/><col width="auto"/><thead><tr><td/><td>Key 1</td><td>Key 2</td>' + '<td>Key 3</td><td>Notes</td><td/></tr></thead><tfoot><tr><td colspan="6">' + '<div id="addfield">Add Field</div></td></tr></tfoot><tbody/>'; } var form = document.evaluate("//form[@name='field']", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; form.parentNode.appendChild(addtable); document.getElementById("addfield").addEventListener('click', buttonClick, false); updateTable(); } // Helper: create TD with class=cls and style=sty function tableData(html, cls, sty) { var td = document.createElement("td"); td.innerHTML = html; if (cls) td.setAttribute("class", cls); if (sty) td.setAttribute("style", sty); return td; } // Helper: remove non-alpha characters and convert to lower case function keyStyle(key) { if (key) { return key.replace(/\W/g, "").toLowerCase(); } return ""; } // Create a div with class="button" and attach eventlistener function createButton(text, id, onclick) { var div = document.createElement("div"); div.appendChild(document.createTextNode(text)); div.setAttribute("class", "button"); div.setAttribute("id", id); div.addEventListener('click', onclick, false); return div; } // Create a field row function tableRow(n, key1, key2, key3, notes) { n = parseInt(n); var tr = document.createElement("tr"); tr.setAttribute("id", "row" + n); var td = document.createElement("td"); var b = createButton("X", "remove" + n, buttonClick); b.setAttribute("title", "Remove Field"); td.appendChild(b); tr.appendChild(td); tr.appendChild(tableData(key1, "key " + keyStyle(key1))); tr.appendChild(tableData(key2, "key " + keyStyle(key2))); tr.appendChild(tableData(key3, "key " + keyStyle(key3))); td = document.createElement("td"); td.setAttribute("class", "notes"); td.appendChild(document.createTextNode(notes)); td.addEventListener('mousedown', function(event) {changeNotes(n);}, false); tr.appendChild(td); td = document.createElement("td"); b = createButton("Set", "setfield" + n, buttonClick); b.setAttribute("title", "Set Field"); td.appendChild(b); tr.appendChild(td); return tr; } // Updates UI table, creates and removes rows if needed function updateTable() { var tbody = document.getElementById("quickfield").getElementsByTagName("tbody")[0]; tbody.innerHTML = ""; var i; for (i in FIELDLIST.fields) { var tr = document.getElementById("row" + i); if (tr) { // Row exists, update content var tds = tr.getElementsByTagName("td"); for (var k = 0; k < 3; k++) { tds[k + 1].textContent = FIELDLIST.fields[i].keys[k]; tds[k + 1].setAttribute("class", "key " + keyStyle(FIELDLIST.fields[i].keys[k])); } tds[4].textContent = FIELDLIST.fields[i].notes; tds[4].setAttribute("title", "Difficulty: " + FIELDLIST.fields[i].difficulty() + " - " + (FIELDLIST.fields[i] + 5)); } else { // Create new row tr = tableRow(i, FIELDLIST.fields[i].keys[0], FIELDLIST.fields[i].keys[1], FIELDLIST.fields[i].keys[2], FIELDLIST.fields[i].notes); tr.getElementsByTagName("td")[4].setAttribute("title", "Difficulty: " + FIELDLIST.fields[i].difficulty() + " - " + (FIELDLIST.fields[i].difficulty() + 5)); tbody.appendChild(tr); } } // Remove remaining rows do { var tr = document.getElementById("row" + (++i)); if (tr) tr.parentNode.removeChild(tr); } while (tr); } var tehStuff = {}; function uselessCrap(keys, pre) { if (tehStuff.timer) clearTimeout(tehStuff.timer); tehStuff.i = 0; tehStuff.str = pre; if (keys) { tehStuff.str += keys.join("/").replace(/\s/g, "_").toLowerCase().replace(/[^a-z_\/]/g, ""); } tehStuff.el = document.getElementById("cli"); tehStuff.timer = setTimeout(moarCrap, 50); } function moarCrap() { if (tehStuff.i > tehStuff.str.length) { tehStuff.timer = null; } else { tehStuff.el.textContent = "# " + tehStuff.str.substr(0, tehStuff.i++); tehStuff.timer = setTimeout(moarCrap, 50); } } GM_addStyle("table#quickfield {width: 100%; background-color: black; color: rgb(33%, 100%, 0%); border-collapse: collapse; font-size: 12px;}"); GM_addStyle("#quickfield thead {font-weight: bold;}"); GM_addStyle("#quickfield caption {background-color: black; font-size: 18px; font-weight: bold; margin-top: 6px;}"); GM_addStyle("#quickfield td {border: 1px solid black; text-align: center;}"); GM_addStyle("#quickfield input {width: auto;}"); GM_addStyle("#quickfield td.key {font-variant: small-caps; cursor: move;}"); GM_addStyle("#quickfield td.notes {color: rgb(100%, 66%, 0%); cursor: pointer;}"); GM_addStyle("#addfield {border: 1px solid rgb(25%, 75%, 0%); background-color: black; color: rgb(25%, 75%, 0%); cursor: pointer;}"); GM_addStyle("#addfield:hover {border: 1px solid rgb(33%, 100%, 0%); background-color: rgb(16%, 50%, 0%); color: rgb(33%, 100%, 0%);}"); GM_addStyle("div.button {border: 1px solid rgb(25%, 75%, 0%); background-color: black; color: rgb(25%, 75%, 0%); cursor: pointer;}"); GM_addStyle("div.button:hover {border: 1px solid rgb(33%, 100%, 0%); background-color: rgb(16%, 50%, 0%); color: rgb(33%, 100%, 0%);}"); GM_addStyle("span.blink {text-decoration: blink;}"); // YA RLY // tier 1 key style GM_addStyle(".simple {color: #FFFFFF; background-color: #006600;}"); GM_addStyle(".training {color: #FFFFFF; background-color: #006666;}"); GM_addStyle(".aquafield {color: #FFFFFF; background-color: #006600;}"); // tier 2 key style GM_addStyle(".dimlylit {color: #FFFFFF; background-color: #006666;}"); GM_addStyle(".crumbling {color: #FFFFFF; background-color: #006600;}"); GM_addStyle(".dealersroom {color: #FFFFFF; background-color: #006666;}"); // tier 3 key style GM_addStyle(".blaring {color: #FFFFFF; background-color: #660000;}"); GM_addStyle(".hairy {color: #FFFFFF; background-color: #660000;}"); GM_addStyle(".parkinglot {color: #FFFFFF; background-color: #660000;}"); // tier 4 key style GM_addStyle(".pulsating {color: #FFFFFF; background-color: #666600;}"); GM_addStyle(".worst {color: #FFFFFF; background-color: #663300;}"); GM_addStyle(".core {color: #FFFFFF; background-color: #666666;}"); // tier 5 key style GM_addStyle(".hidden {color: #000000; background-color: #CCCC00;}"); GM_addStyle(".forbidden {color: #000000; background-color: #CCCC00;}"); GM_addStyle(".holyground {color: #000000; background-color: #CCCC00;}"); // tier 6 key style GM_addStyle(".raging {color: #000000; background-color: #CC0000;}"); GM_addStyle(".passionate {color: #000000; background-color: #CC0000;}"); GM_addStyle(".melody {color: #000000; background-color: #CC0000;}"); // tier 7 key style GM_addStyle(".cursed {color: #FFFFFF; background-color: #006666;}"); GM_addStyle(".filthy {color: #FFFFFF; background-color: #006666;}"); GM_addStyle(".noodleshop {color: #FFFFFF; background-color: #006666;}"); // tier 8 key style GM_addStyle(".chosen {color: #FFFFFF; background-color: #000000;}"); GM_addStyle(".hopeless {color: #FFFFFF; background-color: #000000;}"); GM_addStyle(".nothingness {color: #FFFFFF; background-color: #000000;}"); // tier 9 key style GM_addStyle(".brilliant {color: #FFFFCC; background-color: #666600;}"); GM_addStyle(".delicious {color: #FFFFCC; background-color: #666600;}"); GM_addStyle(".dancefloor {color: #FFFFCC; background-color: #666600;}"); // tier 10 key style GM_addStyle(".beautiful {color: #FFCCCC; background-color: #660000;}"); GM_addStyle(".passedover {color: #FFCCCC; background-color: #660000;}"); GM_addStyle(".touchstone {color: #FFCCCC; background-color: #660000;}"); // tier 11 key style GM_addStyle(".corrupted {color: #660000; background-color: #FF5555;}"); GM_addStyle(".despaired {color: #660000; background-color: #FF5555;}"); GM_addStyle(".paradise {color: #660000; background-color: #FF5555;}"); // tier 12 key style GM_addStyle(".sickened {color: #222222; background-color: #DDDDDD;}"); GM_addStyle(".imprisoned {color: #222222; background-color: #DDDDDD;}"); GM_addStyle(".fallenangel {color: #222222; background-color: #DDDDDD;}"); createTable(); document.getElementById("quickfield").addEventListener('mousedown', mousedownEvent, true); for (var i = 1; i < 4; i++) { var input = document.evaluate("//select[@name='key_" + i + "']", document, null, XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; if (input) input.addEventListener('change', updateDifficulty, false); } updateDifficulty();