您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Idle-Pixel plugin framework
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/441206/1025986/IdlePixel%2B.js
// ==UserScript== // @name IdlePixel+ // @namespace com.anwinity.idlepixel // @version 0.0.1 // @description Idle-Pixel plugin framework // @author Anwinity // @match https://idle-pixel.com/play.php* // @grant none // ==/UserScript== (function() { 'use strict'; class IdlePixelPlusPlugin { constructor(id, name, opts) { if(typeof id !== "string" || typeof name !== "string") { throw new TypeError("IdlePixelPlusPlugin constructor takes the following arguments: (id:string, name:string, opts?:object)"); } this.id = id; this.name = name; this.opts = opts || {}; } onLogin() { } onMessageReceived(data) { } onVariableSet(key, valueBefore, valueAfter) { } onChat(data) { } onPanelChanged(panelBefore, panelAfter) { } } class IdlePixelPlus { constructor() { this.version = "0.0.1"; this.plugins = {}; this.debug = false; } init() { const self = this; // hook into websocket messages const original_open_websocket = window.open_websocket; window.open_websocket = function() { original_open_websocket.apply(this, arguments); const original_onmessage = window.websocket.websocket.onmessage; window.websocket.websocket.onmessage = function(event) { original_onmessage.apply(window.websocket.websocket, arguments); self.onMessageReceived(event.data); } } // hook into Items.set, which is where var_ values are set const original_items_set = Items.set; Items.set = function(key, value) { let valueBefore = window["var_"+key]; original_items_set.apply(this, arguments); let valueAfter = window["var_"+key]; self.onVariableSet(key, valueBefore, valueAfter); } // hook into switch_panels, which is called when the main panel is changed. This is also used for custom panels. const original_switch_panels = window.switch_panels; window.switch_panels = function(id) { let panelBefore = Globals.currentPanel; if(panelBefore && panelBefore.startsWith("panel-")) { panelBefore = panelBefore.substring("panel-".length); } self.hideCustomPanels(); original_switch_panels.apply(this, arguments); let panelAfter = Globals.currentPanel; if(panelAfter && panelAfter.startsWith("panel-")) { panelAfter = panelAfter.substring("panel-".length); } self.onPanelChanged(panelBefore, panelAfter); } console.log("IdlePixelPlus initialized"); } registerPlugin(plugin) { if(!(plugin instanceof IdlePixelPlusPlugin)) { throw new TypeError("IdlePixelPlus.registerPlugin takes the following arguments: (plugin:IdlePixelPlusPlugin)"); } if(plugin.id in this.plugins) { throw new Error(`IdlePixelPlusPlugin with id "${plugin.id}" is already registered. Make sure your plugin id is unique!`); } // TODO: easy config system // TODO: custom panels this.plugins[plugin.id] = plugin; console.log(`IdlePixelPlus registered plugin "${plugin.id}" (${plugin.name})`); } forEachPlugin(f) { if(typeof f !== "function") { throw new TypeError("IdlePixelPlus.forEachPlugin takes the following arguments: (f:function)"); } Object.values(this.plugins).forEach(plugin => { try { f(plugin); } catch(err) { console.error(`Error occurred while executing function for plugin "${plugin.id}."`); console.error(err); } }); } setPanel(panel) { if(typeof panel !== "string") { throw new TypeError("IdlePixelPlus.setPanel takes the following arguments: (panel:string)"); } window.switch_panels(panel); } sendMessage(message) { if(typeof message !== "string") { throw new TypeError("IdlePixelPlus.sendMessage takes the following arguments: (message:string)"); } if(window.websocket && window.websocket.websocket && window.websocket.websocket.readyState==1) { window.websocket.websocket.send(message); } } hideCustomPanels() { this.forEachPlugin((plugin) => { if(plugin.opts.panel) { let panels = plugin.opts.panel; if(!Array.isArray(panels)) { panels = [panels]; } panels.forEach(panel => { if(panel.id) { const el = document.getElementById(`panel-${panel.id}`); if(el) { el.style.display = "none"; } } }); } }); } onMessageReceived(data) { if(this.debug) { console.log(`IP+ onMessageReceived: ${data}`); } if(data) { this.forEachPlugin((plugin) => { if(typeof plugin.onMessageReceived === "function") { plugin.onMessageReceived(data); } }); if(data.startsWith("VALID_LOGIN")) { this.onLogin(); } else if(data.startsWith("CHAT=")) { const split = data.substring("CHAT=".length).split("~"); const chatData = { username: split[0], tag: null, sigil: null, level: split[3], message: split[4] }; // CHAT=anwinity~none~none~1565~test // TODO: none and none, probably for tag and sigil } } } onLogin() { if(this.debug) { console.log(`IP+ onLogin`); } this.forEachPlugin((plugin) => { if(typeof plugin.onLogin === "function") { plugin.onLogin(); } }); } onVariableSet(key, valueBefore, valueAfter) { if(this.debug) { console.log(`IP+ onVariableSet "${key}": "${valueBefore}" -> "${valueAfter}"`); } this.forEachPlugin((plugin) => { if(typeof plugin.onVariableSet === "function") { plugin.onVariableSet(key, valueBefore, valueAfter); } }); } onChat(data) { if(this.debug) { console.log(`IP+ onChat`, data); } this.forEachPlugin((plugin) => { if(typeof plugin.onChat === "function") { plugin.onChat(data); } }); } onPanelChanged(panelBefore, panelAfter) { if(this.debug) { console.log(`IP+ onPanelChanged "${panelBefore}" -> "${panelAfter}"`); } this.forEachPlugin((plugin) => { if(typeof plugin.onPanelChanged === "function") { plugin.onPanelChanged(panelBefore, panelAfter); } }); } } // Add to window and init window.IdlePixelPlusPlugin = IdlePixelPlusPlugin; window.IdlePixelPlus = new IdlePixelPlus(); window.IdlePixelPlus.init(); })();