您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Adds pet leveling info to your own profile page
当前为
// ==UserScript== // @name GazelleGames pet leveling info // @namespace v3rrrr82xk1c96vvo1c6 // @match https://gazellegames.net/user.php?id=* // @grant GM.getValue // @grant GM.setValue // @grant GM.deleteValue // @version 1.3.1 // @description Adds pet leveling info to your own profile page // @run-at document-start // @inject-into content // @license MIT // ==/UserScript== (async function () { "use strict"; const theirUserID = new URLSearchParams(location.search).get("id"); const ownUserID = await GM.getValue("you").then((yourID) => { // Own ID is cached if (yourID) { return yourID; } // Not cached, get it from page once it's loaded return new Promise((resolve) => { window.addEventListener("DOMContentLoaded", () => { yourID = new URLSearchParams(document.body.querySelector("#nav_userinfo a.username").search).get("id"); GM.setValue("you", yourID); resolve(yourID); }); }); }); // Only runs on your own user page if (theirUserID !== ownUserID) { return; } let apiKey = await GM.getValue("apiKey"); if (!apiKey) { if (!(apiKey = prompt("Please enter an API key with the 'Items' permission to use this script."))) { return; } GM.setValue("apiKey", apiKey); } const endpoint = `https://${location.host}/api.php?request=items&include_info=true&type=users_equipped`; const options = { method: "GET", mode: "same-origin", credentials: "omit", redirect: "error", referrerPolicy: "no-referrer", headers: { "X-API-Key": apiKey } }; const equipment = await (await fetch(endpoint, options)).json(); if (equipment.status !== "success") { if (equipment.status === 401) { GM.deleteValue("apiKey"); } return; } function toInt(value) { return (typeof value === "number") ? value : parseInt(value, 10); } const pets = []; for (const equip of equipment.response) { const type = equip.item.equipType; if (type && String(type) === "18" && equip.experience && equip.experience > 0) { pets.push({ name: equip.item.name, xp: toInt(equip.experience), lv: toInt(equip.level), id: String(equip.itemid), slot: toInt(equip.slotid) }); } } if (!pets.length) return; // Sort by slot ID for consistent ordering. pets.sort((first, second) => first.slot - second.slot); // Build our HTML structure. // CSS classes copied from the "Personal" box const box = document.createElement("div"); const innerBox = document.createElement("div"); const list = document.createElement("ul"); const heading = document.createElement("div"); box.className = "box_personal_history"; innerBox.className = "box"; heading.className = "head colhead_dark"; list.className = "stats nobullet"; list.style.lineHeight = "1.5"; heading.append("Pet Leveling"); innerBox.append(heading, list); box.append(innerBox); function totalXP(lv) { return Math.ceil((lv * lv * 625) / 9); } function xpToTimeString(xp) { const days = Math.floor(xp / 24); const hours = xp % 24; let timeString = ""; if (days) { const s = (days === 1) ? "" : "s"; timeString = `${days} day${s}`; } if (hours) { if (timeString) { timeString += " "; } const s = (hours === 1) ? "" : "s"; timeString += `${hours} hour${s}`; } else if (!timeString) { timeString = "0 hours"; // ??? } return timeString; } const listItems = []; for (let i = 0, last = pets.length - 1; i <= last; ++i) { const pet = pets[i]; const liItem = document.createElement("li"); const liLevelInput = document.createElement("li"); const liTimeOutput = document.createElement("li"); const shopLink = document.createElement("a"); // Indent the level/time lines liLevelInput.style.paddingLeft = "10px"; liTimeOutput.style.paddingLeft = "10px"; shopLink.style.fontWeight = "bold"; shopLink.href = `/shop.php?ItemID=${pet.id}`; shopLink.referrerPolicy = "no-referrer"; shopLink.title = "Shop for this pet"; const nextLevel = pet.lv + 1; const targetLevelInput = document.createElement("input"); targetLevelInput.type = "number"; targetLevelInput.required = true; targetLevelInput.inputmode = "numeric"; targetLevelInput.style.width = "3em"; targetLevelInput.min = nextLevel; targetLevelInput.max = Math.max(999, nextLevel); targetLevelInput.value = nextLevel; const displayTimeDifference = (toLevel) => { const missingXP = totalXP(toLevel) - pet.xp; liTimeOutput.textContent = xpToTimeString(missingXP); }; // Display initial info displayTimeDifference(nextLevel); // When the user types anything, update if it's valid. targetLevelInput.addEventListener("input", function () { if (this.checkValidity()) { displayTimeDifference(parseInt(this.value, 10)); } }); // When the user commits a new value, complain if it's invalid. // No idea why setTimeout is needed tbh targetLevelInput.addEventListener("change", function () { setTimeout(() => { if (!this.reportValidity()) { liTimeOutput.textContent = ""; } }); }); shopLink.append(pet.name); liItem.append(shopLink); liLevelInput.append(`Level ${pet.lv} → `, targetLevelInput); listItems.push(liItem, liLevelInput, liTimeOutput); // Space between the equipped pets if (i !== last) { const spacer = document.createElement("li"); spacer.style.marginTop = "10px"; listItems.push(spacer); } } list.append(...listItems); // Try to insert our UI function insert() { const target = document.getElementsByName("user_info")[0]; target?.after(box); return Boolean(target); } if (!insert()) { window.addEventListener("DOMContentLoaded", insert); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址