您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Modding utility/menu for paper.io
- // ==UserScript==
- // @name paper2hack
- // @description Modding utility/menu for paper.io
- // @version 0.1.22
- // @author Pablo Gracia
- // @match https://paper-io.com
- // @match https://paper-io.com/teams/
- // @match https://paperio.site
- // @match https://paper-io.com/battleroyale/
- // @match https://paperanimals.io
- // @match https://amogus.io
- // @require https://cdn.jsdelivr.net/npm/tweakpane@3.1.4/dist/tweakpane.min.js
- // @license GPL-3.0-only
- // @icon https://paper-io.com/favicon.ico
- // @grant none
- // @namespace https://gf.qytechs.cn/users/1204224
- // ==/UserScript==
- adblock = () => false //this detects if adblock is on, we make it always return false so that the impostor skin loads
- window.addEventListener('load', function () {
- "use strict";
- const VERSION = "beta 0.1.21"
- let newApi
- let finish = false; // Start booting
- // New api loads too slow!!
- // Maybe plan in only supporting the old api? just an opinion
- (async() => {
- console.log("[paper2hack] Waiting for api");
- while(!window.hasOwnProperty("paperio2api")) // paperio2api was first defined!
- if (window.hasOwnProperty("paper2")) {newApi = false;return;} // paper2 was first defined!
- await new Promise(resolve => setTimeout(resolve, 1000)); // Wait!!
- console.log("[paper2hack] api defined!");
- })();
- window.api = {
- /**
- * Gets the configuration
- * @returns the configuration
- */
- config: function () {
- if (newApi) {
- return paperio2api.config;
- } else {
- return paper2.currentConfig;
- }
- },
- /**
- * Gets the game
- * @returns the game
- */
- game: function () {
- if (newApi) {
- return paperio2api.game
- } else {
- return paper2.game
- }
- },
- /**
- * Gets the player
- * @returns the player
- */
- player: function () {
- return this.game().player;
- },
- /**
- * Search an unit by the name
- * If no unit is found, it will return `null`
- * If an unit is found, it will return that unit
- * If multiple names are used
- * The first one will be returned
- * @param {*} name The name to be searched for
- * @returns The unit if found, null if not
- */
- searchForUnit: function (name) {
- for (let i = 0; i < this.game().units.length; i++) {
- if (this.game().units[i].name.toLowerCase() == name.toLowerCase()) {return this.game().units[i];}
- }
- return null;
- },
- /**
- * Create a message, that will appear above the specified unit.
- * @param {*} unit The unit
- * @param {*} text The text
- * @param {*} hexColor The color, in hex, for example : `#FF00FF`
- */
- addMessage: function (unit, text, hexColor) {
- unit.addLabel({
- "unit": undefined, // Assign to the unit
- "text": text,
- "color": hexColor
- })
- },
- /**
- * Kills the unit, by the other unit
- * @param {*} unitToKill The unit that will be killed
- * @param {*} unitToGetKill The unit that'll get the kill stat for
- */
- kill: function (unitToKill, unitToGetKill) {
- if (unitToGetKill == undefined) {unitToGetKill = this.player()}
- this.game().kill(unitToKill, unitToGetKill)
- },
- /**
- * Returns the resource located at the resource array (`a0_0x344c`)
- * This is only intended for reverse engineering
- * @param {number} res the resource, starting at `196`
- * @returns the resource, as a `string` can also be undefined
- */
- getResource: function (res) {
- return a0_0x2cc6(res);
- }
- }
- let ETC = {
- "newMessage":function (message) {
- let newMessage = document.createElement("p");
- document.querySelectorAll("#message")[1].appendChild(newMessage);
- newMessage.innerText = message;
- // Return the new message, if you need it
- return newMessage;
- },
- "reset": function () { alert("Cannot be done with tweakpane!\nTry clearing site data.") },
- "zoomScroll": false,
- "debugging": false,
- "map": false,
- "despawnK": false,
- "speed": api.config().unitSpeed,
- "skin": "",
- "skinUnlock": () => {
- try {
- shop.btnsData.forEach(item => {
- if (item.codeName) {
- unlockSkin(item.codeName)
- }
- })
- console.log("[paper2hack] skins unlocked!")
- } catch (e) {
- console.log("[paper2hack] Error unlocking skins!", e)
- }
- },
- "_skins": [],
- "pause": function () {
- if (!newApi) {
- // Toggle between paused and unpaused
- // This is not possible in the new api (I believe)
- api.game().paused = !paper2.game.paused;
- if (api.game().paused) {
- console.log("[paper2hack] Paused");
- } else {
- console.log("[paper2hack] Unpaused");
- }
- // Return so the unit speed doesn't change
- return;
- }
- if (api.config().unitSpeed !== 0) {
- api.config().unitSpeed = 0
- console.log("[paper2hack] Paused")
- } else {
- api.config().unitSpeed = 90
- console.log("[paper2hack] Unpaused")
- }
- return;
- },
- "despawnOthers": function () {
- // Array where we store the units to kill
- let unitkills = [];
- for (let i = 0; i < api.game().units.length; i++) {
- if (api.game().units[i].isPlayer) {continue;} // Ignore if we get the player unit
- unitkills.push(api.game().units[i]);
- }
- // Iterate through the units that we're going to kill
- unitkills.forEach((obj) => {
- api.kill(obj, obj);
- })
- },
- "help": function () {
- alert(`
- paper2hack ${VERSION} written by stretch07 and contributors.\n\n
- https://github.com/stretch07/paper2hack \n
- Issues? https://github.com/stretch07/paper2hack/issues
- If you encounter any issues with paper2hack, refresh the page, hit the 'Reset' button, or uninstall/reinstall the mod. As a last resort, try clearing site data.
- `)
- },
- "keysList": function () {
- alert(`Keyboard shortcuts:\n- Space: Pause/play\n- K: Despawn all other players`)
- },
- "openGithub": function () {
- window.open("https://github.com/stretch07/paper2hack", '_blank').focus();
- }
- }
- function scrollE(e) {
- if (e.deltaY > 0) {
- if (api.config().maxScale > 0.45) {
- api.config().maxScale -= 0.2
- }
- } else if (e.deltaY < 0) {
- if (api.config().maxScale < 4.5) {
- api.config().maxScale += 0.2
- }
- }
- }
- let pane = new Tweakpane.Pane({ title: "paper2hack"})
- let mods = pane.addFolder({ title: "Mods" })
- mods.addInput(ETC, "speed", { min: 5, max: 500, count: 5 }).on("change", ev => {
- api.config().unitSpeed = ev.value;
- })
- mods.addInput(ETC, "skin", {
- label: "Skin",
- // Yeah unreadable i know
- // Got this with a simple js trick ;)
- options: {"No skin":"skin_00","Orange":"skin_20","Burger":"skin_19","Matrix":"skin_49","Green Goblin":"skin_48","Squid Game":"skin_47","Venom":"skin_46","Money Heist":"skin_45","Doge":"skin_44","Baby Yoda":"skin_43","Chess Queen":"skin_42","Impostor":"skin_41","Cyber Punk":"skin_40","Stay safe":"skin_39","Sanitizer":"skin_38","Doctor":"skin_37","COVID-19":"skin_36","Geralt":"skin_35","Batman":"skin_30","Joker":"skin_29","Pennywise":"skin_28","Reaper":"skin_27","Captain America":"skin_26","Thanos":"skin_25","Cupid":"skin_24","Snowman":"skin_23","Present":"skin_22","Christmas":"skin_21","Ladybug":"skin_18","Tank":"skin_17","Duck":"skin_16","Cake":"skin_15","Cash":"skin_14","Sushi":"skin_13","Bat":"skin_12","Heart":"skin_11","Rainbow":"skin_10","Nyan cat":"skin_01","Watermelon":"skin_02","Ghost":"skin_03","Pizza":"skin_04","Minion":"skin_05","Freddy":"skin_06","Spiderman":"skin_07","Teletubby":"skin_08","Unicorn":"skin_09","Eye":"eye", "Frankenstein":"Frank", "Santa":"santa", "Rudolph":"rudolf"}
- }).on("change", ev => {
- if (newApi && finish) {window.alert("Cannot do this in this version!");}
- // Oh boy! No player No skin!
- if (!api.game() || !api.player()) {return;}
- let id = ev.value;
- // The skin manager uses the codeName to get the skin itself
- let codeName;
- let secret = true;
- shop.btnsData.forEach(s => {
- if (s.useId == id) {
- codeName = s.codeName;
- // There is no skins with the same code name, so we can return!
- return;
- }
- })
- // Edge cases since these skins don't have use ids
- if (id == "eye") {codeName = id;}
- else if (id == "Frank") {codeName = id;}
- else if (id == "santa") {codeName = id;}
- else if (id == "rudolf") {codeName = id;}
- else { secret = false; }
- // The skin manager treats the default skin as undefined
- // if we don't do this it will create an error and will not change the skin
- if (codeName == "default") {codeName = undefined;}
- // Get the skin from the code name
- let skin = api.game().skinManager.getPlayerSkin(codeName);
- // And set it to the player!
- api.player().setSkin(skin);
- if (secret) {return;}
- shop.chosenSkin = id;
- Cookies.set('skin', id);
- })
- mods.addInput(ETC, "debugging", { label: "Debug" }).on("change", ev => {
- api.game().debug = ev.value
- api.game().debugGraph = ev.value
- })
- mods.addInput(ETC, "map", { label: "Map"}).on("change", ev => {
- api.game().debugView = ev.value;
- })
- mods.addButton({ title: "Pause/Play" }).on("click", ETC.pause)
- if (!newApi) {
- mods.addButton({ title: "Unlock skins", }).on("click", ETC.skinUnlock)
- }
- mods.addButton({ title: "I give up" }).on("click",() => {
- api.kill(api.player());
- })
- mods.addButton({ title: "Despawn others" }).on("click", ETC.despawnOthers)
- mods.addInput(ETC, "despawnK", { label: "Despawn Others on K" })
- // keyboard shortcuts
- // pause: Spacebar
- // kill everyone: K
- document.addEventListener("keydown", ev => {
- if (!api.player()) {return;} //If not in game, return
- if (event.key === 'k') {
- if (!ETC.despawnK) return;
- ETC.despawnOthers()
- }
- if (event.key === " ") {
- ETC.pause()
- }
- })
- mods.addInput(ETC, "zoomScroll", { label: "Scroll to Zoom" }).on("change", ev => {
- if (ev.value === true) {
- window.addEventListener("wheel", scrollE)
- } else {
- window.removeEventListener("wheel", scrollE)
- }
- })
- mods.addButton({ title: "Reset" }).on('click', ETC.reset);
- let about = pane.addFolder({ title: "About", expanded: false });
- about.addButton({ title: "Help" }).on("click", ETC.help);
- about.addButton({ title: "Keyboard Shortcuts" }).on("click", ETC.keysList);
- about.addButton({ title: "GitHub" }).on("click", ETC.openGithub);
- /*Last things*/
- if (!localStorage.getItem('paper2hack')) {
- this.localStorage.setItem('paper2hack', JSON.stringify({}))
- }
- pane.importPreset(JSON.parse(localStorage.getItem("paper2hack")))
- pane.on("change", e => {
- localStorage.setItem("paper2hack", JSON.stringify(pane.exportPreset()))
- })
- document.querySelector(".tp-dfwv").style.zIndex = "50"; //Make sure the menu shows up over some GUI
- finish = true; // Ended booting
- let messages = this.document.querySelectorAll("#message p");
- messages.forEach((msg)=>{msg.remove();}) //Remove all messages
- ETC.newMessage(`paper2hack ${VERSION}`);
- let checkinstallmessage = ETC.newMessage('');
- checkinstallmessage.innerHTML = `<a style="color: white" href="https://github.com/stretch07/paper2hack">check/install update</a>`;
- ETC.newMessage(`have fun hacking!`);
- }, false);
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址