您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A save outfit feature for Goatlings. Written before the current save outfit feature was implemented. Merely proof of concept, now.
// ==UserScript== // @name Goatlings: Save Outfit // @version 0.1.3 // @description A save outfit feature for Goatlings. Written before the current save outfit feature was implemented. Merely proof of concept, now. // @author Felix G. "Automalix" // @namespace https://gf.qytechs.cn/en/users/322117-automalix // @match http://www.goatlings.com/habuddy* // @grant none // ==/UserScript== /*It is not recommended to run this script, as there is official implementation of what it achieves, but you can do so without breaking site functionality.*/ (function(){ const setStoredValue = function(key, value) { if (value == null || value === undefined) localStorage.removeItem(key) else { if (typeof value != "number" && typeof value != "string") value = JSON.stringify(value) localStorage.setItem(key, value) } }, getStoredValue = function(key, safety) { let value = localStorage.getItem(key); if (value != null) { if (typeof value == "string") { try {return JSON.parse(value)} catch (ex) {console.log(ex)} } return value; } return safety; }, clothing = new Map(), DOM = { saveOutfit: document.querySelector(`input[onclick="save_outfit()"]`), itemArea: document.querySelector("#item_area_ajax"), closetItems: document.querySelector("#item_area_ajax").childNodes, hairButton: document.querySelector(`input[value="Hair"]`), facesButton: document.querySelector(`input[value="Faces"]`), hatsButton: document.querySelector(`input[value="Hats"]`), bodyButton: document.querySelector(`input[value="Body"]`), basesButton: document.querySelector(`input[value="Bases"]`), accessoriesButton: document.querySelector(`input[value="Accessories"]`), backgroundsButton: document.querySelector(`input[value="Backgrounds"]`), outfitsButton: document.querySelector(`input[onclick="load_outfits()"]`), reset: document.querySelector(`input[value="Reset"]`), }, Outfit = function(outfit){ //constructor for new Outfits this.outfit = outfit; }; let a = ["hair", "faces", "hats", "body", "bases", "accessories", "backgrounds"], // 0-6; closet = "hair"; //the page loads on the hair tab so we can assume this to be true const savedOutfits = getStoredValue("Saved Outfits", {}); //DOM.reset.insertAdjacentHTML('afterend', ` <input class="button" type="button" value="Archive My Outfit">`) //DOM.saveOutfit = document.querySelector('input[value="Archive My Outfit"]'); DOM.saveOutfit.onclick = null; const saveList = function (){ let [index, saveClothes] = [0, clothing] if(Object.keys(savedOutfits).length > 0) index = Object.keys(savedOutfits).length; savedOutfits[index] = new Outfit(JSON.stringify([...saveClothes])); setStoredValue("Saved Outfits", savedOutfits) } DOM.saveOutfit.addEventListener("click", saveList) DOM.outfitsButton.addEventListener("click", function(){ const outfitImageLoadObserver = new MutationObserver( function(){ let savedOutfitsArr = [], val = []; for(let value in savedOutfits){ savedOutfitsArr.push(`<li class="my-saved-outfits"><button class="button" id="${value}">Put On Outfit ${Number(value) + 1}</button></li>`) val.push(value); } DOM.itemArea.firstChild.insertAdjacentHTML('afterend', /*`<div id="testOutput" style="text-align:center; margin:10px;"> <button>Print Outfit Object to Console</button> </div>`+*/ `<div id="testDelete" style="text-align:center; margin:10px;"> <button class="button" >Delete All Saved Outfits</button> </div> <div id="outfitHolderDiv" style="text-align:center; margin-bottom:10px;"> <ul style="list-style:none; margin:0; padding:0; color:white"> ${savedOutfitsArr} </ul> </div>`) //document.querySelector("#testOutput").addEventListener("click", function(){console.log(savedOutfits)}) document.querySelector("#testDelete").addEventListener("click", function(){ localStorage.removeItem("Saved Outfits"); document.querySelector("#outfitHolderDiv").remove() }) for(let value of document.querySelectorAll(`.my-saved-outfits`)){ value.addEventListener("click", function(event){ DOM.reset.click(); putOnOutfit(event.originalTarget.id); }) } outfitImageLoadObserver.disconnect(); }) outfitImageLoadObserver.observe(DOM.itemArea, {childList: true}) }) const putOnOutfit = function(num){ if(Object.keys(savedOutfits).length > 0){ let ourClothes = JSON.parse(savedOutfits[num].outfit); ourClothes.map(function(value, index){ setTimeout( function(value){ clothingClicker(value) }, index * 1000, value) }) } }, clothingClicker = function(itemArr){ let [itemID, page] = [itemArr[0], itemArr[1]]; const pageSwitch = function(location){ document.querySelector(`input[value="${location.charAt(0).toUpperCase() + location.slice(1)}"]`).click() } const clickOn = function(){ try {document.querySelector(`#${itemID}`).firstChild.click()} catch(ex){} itemObserver.disconnect(); } pageSwitch(page) const itemObserver = new MutationObserver(clickOn) itemObserver.observe(DOM.itemArea, {subtree: true, childList: true}); //console.log(itemID, page); }, clothesSaver = function(itemID, closetPage){ if (clothing.has(itemID)) clothing.delete(itemID) else clothing.set(itemID, closetPage) }, closetObserverInit = function(){ const closetItemObserver = new MutationObserver(function(event){ let ID = event[0].target.id; clothesSaver(ID, closet); //console.log(clothing) }); for(let value of DOM.closetItems) { if(typeof value == "object") { closetItemObserver.observe(value, {childList: true, attributes: true, characterData: true}) } } }, pageChecker = function(element){ let page = element.value; closet = page.toLowerCase(); }; closetObserverInit(); const itemAjaxObserver = new MutationObserver(closetObserverInit); itemAjaxObserver.observe(DOM.itemArea, {childList: true, attributes: true, characterData: true}) DOM.hairButton.addEventListener("click", function(){pageChecker(this)}) DOM.facesButton.addEventListener("click", function(){pageChecker(this)}) DOM.hatsButton.addEventListener("click", function(){pageChecker(this)}) DOM.bodyButton.addEventListener("click", function(){pageChecker(this)}) DOM.basesButton.addEventListener("click", function(){pageChecker(this)}) DOM.accessoriesButton.addEventListener("click", function(){pageChecker(this)}) DOM.backgroundsButton.addEventListener("click", function(){pageChecker(this)}) DOM.reset.addEventListener("click", function(){clothing.clear()}) })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址