您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Definable is a modular ModMenu for Drawaria.Online
当前为
- // ==UserScript==
- // @name Definable ModMenu
- // @namespace Definable
- // @version 0.1.2
- // @description Definable is a modular ModMenu for Drawaria.Online
- // @homepage https://drawaria.online/profile/?uid=63196790-c7da-11ec-8266-c399f90709b7
- // @author ≺ᴄᴜʙᴇ³≻
- // @match https://drawaria.online/
- // @match https://drawaria.online/test
- // @match https://drawaria.online/room/*
- // @icon https://i.ibb.co/8Xb1gXg/Andrew-T-Austin-brightly-lit-tesseract-hypercube.png
- // @grant none
- // @license GNU GPLv3
- // @run-at document-end
- // ==/UserScript==
- (() => {
- String.prototype.toFunction = function () {
- return new Function("(" + this + ")()");
- };
- String.prototype.__invokeAsFunction = function (...args) {
- new Function("(" + this + ")()")();
- };
- Function.prototype.callAsWorker = function (...args) {
- return new Promise((resolve, reject) => {
- const code = `self.onmessage = e => self.postMessage((${this.toString()}).call(null, ...e.data));`,
- blob = new Blob([code], { type: "text/javascript" }),
- worker = new Worker((window.URL ?? window.webkitURL).createObjectURL(blob));
- worker.onmessage = (e) => (resolve(e.data), worker.terminate());
- worker.onerror = (e) => (reject(e.message), worker.terminate());
- worker.postMessage(args);
- });
- };
- const originalElementPrototypeAppend = Element.prototype.append;
- Element.prototype.append = function (...elements) {
- elements = elements.filter((appendingElement) => {
- if (appendingElement instanceof HTMLElement) return true;
- return false;
- });
- originalElementPrototypeAppend.apply(this, elements);
- return this;
- };
- // Function.toString().replace(/^\s*\/\/.+$/gm, "").split("\n").filter((s) => s).map((s) => s.trim()).join("");
- })();
- (async function ($name) {
- "use strict";
- const cache = {
- storage: await caches.open($name),
- /**
- * @param {string} url
- * @param {string} scriptContent
- */
- saveScript: function (url, scriptContent) {
- this.storage.put(url, new Response(scriptContent, { headers: { "Content-Type": "application/javascript" } }));
- },
- /**
- * @param {string} url
- * @param {object} json
- */
- saveObject: function (url, json) {
- this.storage.put(url, new Response(JSON.stringify(json), { headers: { "Content-Type": "application/json" } }));
- },
- /**
- * @param {string} url
- * @returns {Promise<string>}
- */
- loadScript: async function (url) {
- const response = (await this.storage.match(url)) || (await fetch(url));
- return await response.text();
- },
- /**
- * @param {string} url
- * @returns {Promise<object>}
- */
- loadObject: async function (url) {
- const response = (await this.storage.match(url)) || (await fetch(url));
- return await response.json();
- },
- };
- const UI = {
- /**
- * Returns the first element that is a descendant of node that matches selectors.
- * @param {string} selectors
- * @param {ParentNode} parentElement
- * @returns {Element|null}
- */
- querySelect: (selectors, parentElement = document) => parentElement.querySelector(selectors),
- /**
- * Returns all element descendants of node that match selectors.
- * @param {string} selectors
- * @param {ParentNode} parentElement
- * @returns {NodeListOf<Element>}
- */
- querySelectAll: (selectors, parentElement = document) => parentElement.querySelectorAll(selectors),
- /**
- * Create Element and assign properties to it.
- * @param {string} tagName
- * @param {object} properties
- * @returns {Element}
- */
- createElement: (tagName, properties = {}) => {
- /** @type {Element} */
- const element = Object.assign(document.createElement(tagName), properties);
- if (properties.title) {
- try {
- element.setAttribute("data-toggle", "tooltip");
- element.setAttribute("data-html", "true");
- jQuery(element).tooltip({ boundary: "window" });
- } catch (error) {}
- }
- return element;
- },
- /**
- * Assign attributes to element.
- * @param {Element} element
- * @param {object} attributes
- */
- setAttributes: (element, attributes) => Object.entries(attributes).forEach(([k, v]) => element.setAttribute(k, v)),
- /**
- * Assign styles to element.
- * @param {Element} element
- * @param {object} styles
- */
- setStyles: (element, styles) => Object.assign(element.style, styles),
- /**
- * @param {string} name
- * @returns {HTMLDivElement}
- */
- createContainer: function (name = "div") {
- return this.createElement(name, { className: "container" });
- },
- /**
- * @returns {HTMLDivElement}
- */
- createRow: function () {
- return this.createElement("div", { className: "row" });
- },
- /**
- * @param {string} name
- * @returns {HTMLElement}
- */
- createIcon: function (name) {
- return this.createElement("i", { className: `fas fa-${name}` });
- },
- /**
- * @param {string} type
- * @param {object} properties
- * @returns {HTMLInputElement}
- */
- createInput: function (type, properties = {}) {
- const input = this.createElement("input", { ...{ className: "form-control" }, ...properties, ...{ type: type } });
- if (!input.id) input.id = uid(8);
- return input;
- },
- /**
- * @param {HTMLInputElement} input
- * @param {object} properties
- * @returns {HTMLLabelElement}
- */
- createLabelFor: function (input, properties = {}) {
- const label = this.createElement("label", { ...{ className: "btn btn-sm btn-outline-secondary" }, ...properties, ...{ htmlFor: input.id } });
- label.appendChild(input);
- input.hidden = true;
- if (input.type === "checkbox" || input.type === "radio") {
- input.addEventListener("input", function () {
- label.classList[input.checked ? "add" : "remove"]("active");
- });
- }
- return label;
- },
- /**
- * @param {string} className
- * @returns {HTMLElement & { show: Function, hide: Function }}
- */
- createSpinner: function (className = "text-secondary") {
- const spinner = this.createElement("div", { className: [className, "spinner-border spinner-border-sm"].join(" ") });
- spinner.show = function () {
- spinner.classList.remove("d-none");
- };
- spinner.hide = function () {
- spinner.classList.add("d-none");
- };
- spinner.hide();
- return spinner;
- },
- /**
- * @param {HTMLInputElement} input
- * @param {HTMLLabelElement|HTMLInputElement|HTMLButtonElement|HTMLElement} addon
- * @returns {HTMLDivElement}
- */
- createGroup: function (input, addon) {
- const group = this.createElement("div", { className: "input-group input-group-sm" });
- const groupAppend = this.createElement("div", { className: "input-group-append" });
- if (!(addon instanceof HTMLInputElement || addon instanceof HTMLButtonElement)) {
- addon.classList.add("input-group-text");
- }
- groupAppend.appendChild(addon);
- group.appendChild(input);
- group.appendChild(groupAppend);
- return group;
- },
- /**
- * @param {Array<HTMLLabelElement|HTMLInputElement|HTMLButtonElement|HTMLElement>} inputs
- * @returns {HTMLDivElement}
- */
- createInputGroup: function (...inputs) {
- const group = this.createElement("div", { className: "input-group input-group-sm" });
- let previousElementSibling = inputs[0];
- let appendGroup = this.createElement("div", { className: "input-group-append" });
- for (let index = 0; index < inputs.length; index++) {
- const input = inputs[index];
- if (input instanceof HTMLInputElement) {
- if (!(previousElementSibling instanceof HTMLInputElement)) {
- group.appendChild(appendGroup);
- appendGroup = this.createElement("div", { className: "input-group-append" });
- }
- input.hidden = false;
- group.appendChild(input);
- } else {
- input.classList.add("input-group-text");
- appendGroup.appendChild(input);
- if (index + 1 === inputs.length) {
- group.appendChild(appendGroup);
- }
- }
- previousElementSibling = input;
- }
- return group;
- },
- };
- const DrawariaOnlineMessageTypes = {
- /**
- * @param {string} message
- * @returns {string}
- */
- chatmsg: function (message) {
- // 42["chatmsg","a"]
- const data = ["chatmsg", message];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- passturn: function () {
- // 42["passturn"]
- const data = ["passturn"];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @returns {string}
- */
- pgdrawvote: function (playerid) {
- // 42["pgdrawvote",2,0]
- const data = ["pgdrawvote", playerid, 0];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- pgswtichroom: function () {
- // 42["pgswtichroom"]
- const data = ["pgswtichroom"];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- playerafk: function () {
- // 42["playerafk"]
- const data = ["playerafk"];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- playerrated: function () {
- // 42["playerrated"]
- const data = ["playerrated"];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} gestureid
- * @returns {string}
- */
- sendgesture: function (gestureid) {
- // 42["sendgesture",16]
- const data = ["sendgesture", gestureid];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- sendvote: function () {
- // 42["sendvote"]
- const data = ["sendvote"];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @returns {string}
- */
- sendvotekick: function (playerid) {
- // 42["sendvotekick",93]
- const data = ["sendvotekick", playerid];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} wordid
- * @returns {string}
- */
- wordselected: function (wordid) {
- // 42["wordselected",0]
- const data = ["sendvotekick", wordid];
- return `${42}${JSON.stringify(data)}`;
- },
- clientcmd: {
- /**
- * @param {number|string} itemid
- * @param {boolean} isactive
- * @returns {string}
- */
- activateitem: function (itemid, isactive) {
- const data = ["clientcmd", 12, [itemid, isactive]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} itemid
- * @returns {string}
- */
- buyitem: function (itemid) {
- const data = ["clientcmd", 11, [itemid]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} itemid
- * @param {"zindex"|"shared"} target
- * @param {any} value
- * @returns {string}
- */
- canvasobj_changeattr: function (itemid, target, value) {
- const data = ["clientcmd", 234, [itemid, target, value]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- canvasobj_getobjects: function () {
- const data = ["clientcmd", 233];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} itemid
- * @returns {string}
- */
- canvasobj_remove: function (itemid) {
- let data = ["clientcmd", 232, [itemid]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} itemid
- * @param {number|string} positionX
- * @param {number|string} positionY
- * @param {number|string} speed
- * @returns {string}
- */
- canvasobj_setposition: function (itemid, positionX, positionY, speed) {
- const data = ["clientcmd", 230, [itemid, 100 / positionX, 100 / positionY, { movespeed: speed }]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} itemid
- * @param {number|string} rotation
- * @returns {string}
- */
- canvasobj_setrotation: function (itemid, rotation) {
- const data = ["clientcmd", 231, [itemid, rotation]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {any} value
- * @returns {string}
- */
- customvoting_setvote: function (value) {
- const data = ["clientcmd", 301, [value]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {any} value
- * @returns {string}
- */
- getfpid: function (value) {
- const data = ["clientcmd", 901, [value]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- getinventory: function () {
- const data = ["clientcmd", 10, [true]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- getspawnsstate: function () {
- const data = ["clientcmd", 102];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} positionX
- * @param {number|string} positionY
- * @returns {string}
- */
- moveavatar: function (positionX, positionY) {
- const data = ["clientcmd", 103, [1e4 * Math.floor(positionX * 0.01 * 1e4) + Math.floor(positionY * 0.01 * 1e4), false]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- setavatarprop: function () {
- const data = ["clientcmd", 115];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} flagid
- * @param {boolean} isactive
- * @returns {string}
- */
- setstatusflag: function (flagid, isactive) {
- const data = ["clientcmd", 3, [flagid, isactive]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {number|string} tokenid
- * @returns {string}
- */
- settoken: function (playerid, tokenid) {
- const data = ["clientcmd", 2, [playerid, tokenid]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {any} value
- * @returns {string}
- */
- snapchatmessage: function (playerid, value) {
- const data = ["clientcmd", 330, [playerid, value]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- spawnavatar: function () {
- const data = ["clientcmd", 101];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- startrollbackvoting: function () {
- const data = ["clientcmd", 320];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- trackforwardvoting: function () {
- const data = ["clientcmd", 321];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} trackid
- * @returns {string}
- */
- votetrack: function (trackid) {
- const data = ["clientcmd", 1, [trackid]];
- return `${42}${JSON.stringify(data)}`;
- },
- },
- /**
- * @param {string} roomID
- * @param {string} name
- * @param {string} uid
- * @param {string} wt
- * @returns {string}
- */
- startplay: function (roomID, name = undefined, uid = undefined, wt = undefined) {
- const data = `${420}${JSON.stringify(["startplay", name, 2, "en", roomID, null, [null, "https://drawaria.online/", 1000, 1000, [null, uid, wt], null]])}`;
- return data;
- },
- clientnotify: {
- /**
- * @param {number|string} playerid
- * @returns {string}
- */
- requestcanvas: function (playerid) {
- const data = ["clientnotify", playerid, 10001];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {string} base64
- * @returns {string}
- */
- respondcanvas: function (playerid, base64) {
- const data = ["clientnotify", playerid, 10002, [base64]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {number|string} imageid
- * @returns {string}
- */
- galleryupload: function (playerid, imageid) {
- const data = ["clientnotify", playerid, 11, [imageid]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {any} type
- * @returns {string}
- */
- warning: function (playerid, type) {
- const data = ["clientnotify", playerid, 100, [type]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {string} targetname
- * @param {boolean} mute
- * @returns {string}
- */
- mute: function (playerid, targetname, mute = false) {
- const data = ["clientnotify", playerid, 1, [mute, targetname]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {string} targetname
- * @param {boolean} hide
- * @returns {string}
- */
- hide: function (playerid, targetname, hide = false) {
- const data = ["clientnotify", playerid, 3, [hide, targetname]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {string} reason
- * @param {string} targetname
- * @returns {string}
- */
- report: function (playerid, reason, targetname) {
- const data = ["clientnotify", playerid, 2, [targetname, reason]];
- return `${42}${JSON.stringify(data)}`;
- },
- },
- drawcmd: {
- /**
- * @param {number|string} playerid
- * @param {number|string} x1
- * @param {number|string} y1
- * @param {number|string} x2
- * @param {number|string} y2
- * @param {number|string} size
- * @param {number|string} color
- * @param {boolean} ispixel
- * @returns {string}
- */
- line: function (x1, y1, x2, y2, color, size = 4, ispixel = true, playerid = 0) {
- const data = ["drawcmd", 0, [x1 * 0.001, y1 * 0.001, x2 * 0.001, y2 * 0.001, false, -size, color, playerid, ispixel]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @param {number|string} x1
- * @param {number|string} y1
- * @param {number|string} x2
- * @param {number|string} y2
- * @param {number|string} size
- * @param {number|string} color
- * @returns {string}
- */
- erase: function (x1, y1, x2, y2, color, size, ispixel = true, playerid = 0) {
- const data = ["drawcmd", 1, [x1 * 0.01, y1 * 0.01, x2 * 0.01, y2 * 0.01, false, -size, color, playerid, ispixel]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} x
- * @param {number|string} y
- * @param {number|string} color
- * @param {number|string} tolerance
- * @param {number|string} r
- * @param {number|string} g
- * @param {number|string} b
- * @param {number|string} a
- * @returns {string}
- */
- flood: function (x, y, color, tolerance, r, g, b, a) {
- // 42["drawcmd",2,[x, y,color,{"0":r,"1":g,"2":b,"3":a},size]]
- const data = ["drawcmd", 2, [x * 0.01, y * 0.01, color, { 0: r, 1: g, 2: b, 3: a }, tolerance]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @param {number|string} playerid
- * @returns {string}
- */
- undo: function (playerid) {
- // 42["drawcmd",3,[playerid]]
- const data = ["drawcmd", 3, [playerid]];
- return `${42}${JSON.stringify(data)}`;
- },
- /**
- * @returns {string}
- */
- clear: function () {
- // 42["drawcmd",4,[]]
- const data = ["drawcmd", 4, []];
- return `${42}${JSON.stringify(data)}`;
- },
- },
- };
- /**
- * @param {string} message
- * @param {string} styles
- */
- const log = (message, styles = "color:#5090C1", application = undefined) => console.log("%c" + [`[${application ?? $name}]`, message].join(" "), styles);
- /**
- * Generate radnow UID
- * @param {number} size
- * @returns {string}
- */
- const uid = (size = 8) => {
- const MASK = 0x3d;
- const LETTERS = "abcdefghijklmnopqrstuvwxyz";
- const NUMBERS = "1234567890";
- const SPECIALS = "-_";
- const charset = `${NUMBERS}${LETTERS}${LETTERS.toUpperCase()}${SPECIALS}`.split("");
- const bytes = new Uint8Array(size);
- crypto.getRandomValues(bytes);
- return bytes.reduce((acc, byte) => `${acc}${charset[byte & MASK]}`, "");
- };
- /**
- * @param {number[]} byteArray
- * @returns {string}
- */
- const toHexString = (byteArray) => {
- return byteArray.map((byte) => byte.toString(16).padStart(2, "0")).join("");
- };
- /**
- * @param {string} key
- * @param {string} value
- */
- const setCookie = (key, value) => {
- if (window.Cookie) Cookies.set(key, value);
- document.cookie = `${key}=${value}; Secure; Path=/; SameSite=None; Partitioned;`;
- };
- /**
- * @param {(index:number,value:*)=>{}} callbackOnDelete
- * @param {(index:number,value:*)=>{}} callbackOnSet
- * @returns {Array<*>}
- */
- const makeObservableArray = (callbackOnDelete, callbackOnSet) => {
- if (!("Proxy" in window)) {
- console.warn("Your browser doesn't support Proxies.");
- return;
- }
- // a proxy for our array
- const proxy = new Proxy([], {
- deleteProperty: function (target, property) {
- (callbackOnDelete ?? ___)(property, target[property]);
- delete target[property];
- return true;
- },
- set: function (target, property, value, receiver) {
- target[property] = value;
- (callbackOnSet ?? ___)(property, value);
- return true;
- },
- });
- Object.defineProperty(proxy, "isProxy", {
- value: true,
- writable: false,
- });
- return proxy;
- };
- /**
- * @param {string} message
- * @returns {Array<any>|object}
- */
- const tryParseJSON = (message) => {
- try {
- return JSON.parse(message);
- } catch (error) {
- return [];
- }
- };
- const clearScripts = (remove = true) => {
- try {
- let array = document.querySelectorAll('script[src]:not([data-codemaid="ignore"])');
- array.forEach((script) => {
- if (script.src != "") document.head.appendChild(script);
- });
- } catch (error) {
- console.error(error);
- }
- try {
- let unifiedScript = DefinableCore.UI.createElement("script");
- let scripts = document.querySelectorAll('script:not([src]):not([data-codemaid="ignore"])');
- let unifiedScriptContent = "";
- scripts.forEach((script) => {
- let content = script.textContent; //.replaceAll(/\s/g, '');
- unifiedScriptContent += `try{${content}}catch(e){console.warn(e);}`;
- script.remove();
- });
- unifiedScript.textContent = unifiedScriptContent;
- if (!remove) document.head.appendChild(unifiedScript);
- } catch (error) {
- console.error(error);
- }
- };
- const clearStyles = (remove = false) => {
- try {
- let unifiedStyles = DefinableCore.UI.createElement("style");
- unifiedStyles.textContet = "";
- let styles = document.querySelectorAll('style:not([data-codemaid="ignore"])');
- styles.forEach((style) => {
- unifiedStyles.textContent += style.textContent;
- style.remove();
- });
- if (!remove) document.head.appendChild(unifiedStyles);
- } catch (error) {
- console.error(error);
- }
- };
- const clearEmbeds = () => {
- try {
- let array = document.querySelectorAll("iframe");
- array.forEach((iframe) => {
- iframe.remove();
- });
- } catch (error) {
- console.error(error);
- }
- };
- class Player {
- /** @type {Array<Player>} */
- static instances = [];
- static get noConflict() {
- return Player.instances[0] ?? new Player(uid(12));
- }
- /**
- * @param {string|undefined} inviteLink
- * @returns {URL}
- */
- static getSocketServerURL(inviteLink) {
- if (typeof inviteLink === "undefined") return `wss://sv3.drawaria.online/socket.io/?sid1=undefined&hostname=drawaria.online&EIO=3&transport=websocket`;
- const roomID = this.getRoomID(inviteLink);
- const [_voidable, serverPrefix] = roomID.split(".");
- return new URL(`wss://${typeof serverPrefix === "undefined" ? "" : "sv".concat(serverPrefix, ".")}drawaria.online/socket.io/?sid1=undefined&hostname=drawaria.online&EIO=3&transport=websocket`);
- }
- /**
- * @param {string|undefined} inviteLink
- * @returns {string}
- */
- static getRoomID(inviteLink) {
- const inviteURL = new URL(inviteLink);
- return inviteURL.pathname.slice(6);
- }
- static parseMessage = DrawariaOnlineMessageTypes;
- /** @type {string} */
- name;
- /** @type {string} */
- uid;
- /** @type {string} */
- wt;
- /** @type {string} */
- roomID;
- /** @type {WebSocket} */
- socket;
- /** @type {Map<string, Function[]>} */
- events;
- /**
- * @param {string} name
- */
- constructor(name = undefined) {
- this.name = name;
- this.uid = "_";
- this.wt = undefined;
- this.roomID = undefined;
- this.events = new Map();
- Player.instances.push(this);
- }
- /**
- * @param {string} inviteLink
- */
- connect = (inviteLink) => {
- if (this.isConnected) return;
- this.#createNewConnection(inviteLink);
- };
- disconnect = () => {
- this.send("41");
- if (this.isConnected) this.socket.close();
- };
- reconnect = () => {
- if (!this.isConnected) {
- this.connect(`https://drawaria.online/room/${this.roomID}`);
- return;
- }
- this.send("41");
- this.send("40");
- };
- /**
- * @param {string} inviteLink
- */
- enterRoom = (inviteLink = undefined) => {
- this.roomID = Player.getRoomID(inviteLink ?? document.querySelector("#invurl").value);
- this.reconnect();
- };
- nextRoom = () => {
- this.send(Player.parseMessage.pgswtichroom());
- };
- leaveRoom = () => {
- this.send("41");
- };
- /**
- * @param {string} payload
- */
- send = (payload) => {
- if (this.isConnected) this.socket.send(payload);
- else debug(`send failed! Connection is closed`);
- };
- /**
- * @returns {boolean}
- */
- get isConnected() {
- return typeof this.socket !== "undefined" && this.socket instanceof WebSocket && (this.socket.readyState === WebSocket.OPEN || this.socket.readyState === WebSocket.CONNECTING);
- }
- #sendHeartbeat = () => {
- if (this.isConnected) this.socket.send(2);
- };
- /**
- * @param {string} inviteLink
- */
- #createNewConnection = (inviteLink) => {
- this.socket = new WebSocket(Player.getSocketServerURL(inviteLink));
- this.roomID = Player.getRoomID(inviteLink);
- this.socket.addEventListener("open", this.#startHeartbeat);
- this.socket.addEventListener("message", this.#handleMessage);
- };
- #startHeartbeat = () => {
- this.heartbeatInterval = setInterval(this.#sendHeartbeat, 25000);
- };
- #handleMessage = (rawMessage) => {
- const [eventType, eventName, eventData] = this.#parseMessageEvent(rawMessage);
- switch (eventType) {
- case "40":
- this.send(Player.parseMessage.startplay(this.roomID, this.name, this.uid, this.wt));
- break;
- case "430":
- break;
- case "42":
- this.__invokeEvent(eventName, eventData);
- break;
- default:
- }
- };
- /**
- * @param {MessageEvent} messageEvent
- * @returns {[string, string, Array<any>|object]}
- */
- #parseMessageEvent = (messageEvent) => {
- const rawData = String(messageEvent.data);
- const messageType = (rawData.match(/^\d+/i) ?? [""])[0];
- const messageData = messageType.length === rawData.length ? [] : tryParseJSON(rawData.slice(messageType.length));
- return [messageType, Array.isArray(messageData) ? messageData.shift() : "", messageData];
- };
- /**
- * @param {DrawariaOnlineEvents} event
- * @param {Function} callback
- */
- addEventListener = (event, callback, id = undefined) => {
- if (!this.hasEventListener(event)) {
- this.events.set(event, []);
- }
- callback.id = id ?? this.addEventListener.caller.name ?? uid(8);
- try {
- this.events.get(event).push(callback);
- } catch (error) {
- debug(`addEventListener returned error \"${error}\"`, "color:firebrick");
- }
- };
- /**
- * @param {DrawariaOnlineEvents} event
- * @param {*} data
- */
- __invokeEvent = (event, data) => {
- if (this.hasEventListener(event)) {
- const listeners = this.events.get(event);
- listeners.forEach((listener) => listener(data));
- }
- };
- /**
- * @param {DrawariaOnlineEvents} name
- * @returns {boolean}
- */
- hasEventListener = (name) => {
- return this.events.has(name);
- };
- }
- class DefinableCore {
- static UI = UI;
- static Player = Player;
- constructor(moduleName, moduleIcon = "code") {
- this.name = moduleName;
- this.__initializeHead(moduleIcon);
- this.__initializeBody();
- }
- __initializeHead(moduleIcon) {
- const input = this.UI.createInput("checkbox");
- this.label = this.UI.createLabelFor(input, { title: this.name });
- const icon = this.UI.createIcon(moduleIcon);
- this.label.appendChild(icon);
- }
- __initializeBody() {
- const submoduleSelectionContainer = this.UI.createElement("nav", { className: "row" });
- const wrapper = this.UI.createElement("div");
- this.wrapper = wrapper;
- this.__contaier = this.UI.createElement("div");
- this.__contaier.appendChild(this.UI.createElement("b", { textContent: this.name }));
- // this.wrapper.appendChild(submoduleSelectionContainer);
- this.__contaier.appendChild(submoduleSelectionContainer);
- this.wrapper.appendChild(this.__contaier);
- const input = this.UI.querySelect("&>input", this.label);
- input.addEventListener("input", function () {
- wrapper.classList[input.checked ? "remove" : "add"]("d-none");
- });
- wrapper.classList.add("d-none");
- }
- createRow() {
- const row = this.UI.createRow();
- this.__contaier.appendChild(row);
- return row;
- }
- /**
- * @param {DefinableCore} submodule
- */
- registerModule(submodule) {
- // const submoduleSelectionContainer = this.UI.querySelect("&>nav", this.wrapper);
- const submoduleSelectionContainer = this.UI.querySelect("&>nav", this.__contaier);
- submoduleSelectionContainer.appendChild(submodule.label);
- this.wrapper.appendChild(submodule.wrapper);
- }
- get UI() {
- return DefinableCore.UI;
- }
- get Player() {
- return DefinableCore.Player;
- }
- }
- window.addEventListener("definable:core:init", function () {
- const ui = DefinableCore.UI;
- const definable = new DefinableCore("Definable", "code");
- const chatbox = ui.querySelect("#chatbox_messages");
- /** @type {HTMLElement} */
- const devider = chatbox.previousElementSibling;
- devider.before(definable.wrapper);
- definable.wrapper.before(devider.cloneNode(false));
- setTimeout(() => {
- window.dispatchEvent(new CustomEvent("definable:init", { detail: { main: definable, core: DefinableCore } }));
- definable.wrapper.classList.remove("d-none");
- definable.wrapper.classList.add("container");
- definable.wrapper.id = "definable";
- }, 500);
- });
- setTimeout(() => {
- window.dispatchEvent(new CustomEvent("definable:core:init"));
- clearEmbeds();
- clearScripts();
- clearStyles();
- document.head.appendChild(
- UI.createElement("style", { id: "definableStyles", textContent: ["#definable .row { gap: 0.125rem; margin-bottom: 0.125rem; }", "#definable label { margin: 0; }"].join("\n") })
- );
- // console.clear();
- }, 500);
- function launchScriptManager() {
- const ui = DefinableCore.UI;
- const container = ui.createContainer();
- {
- const row = ui.createRow();
- const scriptSourceLinkInput = ui.createInput("text", { className: "form-control" });
- const requestSourceInput = ui.createInput("button");
- const requestSourceLabel = ui.createLabelFor(requestSourceInput);
- const group = ui.createGroup(scriptSourceLinkInput, requestSourceLabel);
- const spinnerIcon = ui.createSpinner("");
- const defaultIcon = ui.createIcon("external-link-alt");
- requestSourceLabel.appendChild(defaultIcon);
- requestSourceLabel.appendChild(spinnerIcon);
- requestSourceInput.addEventListener("click", function () {
- defaultIcon.classList.add("d-none");
- spinnerIcon.show();
- if (!scriptSourceLinkInput.value.startsWith("http")) {
- log("Not a valid Link: ".concat(scriptSourceLinkInput.value), "color: firebrick;");
- spinnerIcon.hide();
- defaultIcon.classList.remove("d-none");
- return;
- }
- const requestSourceLink = new URL(scriptSourceLinkInput.value);
- log("Requesting Module: ".concat(requestSourceLink), "color: rebeccapurple;");
- fetch(requestSourceLink).then(async (response) => {
- const copy = response.clone();
- const content = await copy.text();
- if (copy.status === 200 && content) {
- cache.saveScript(requestSourceLink, content);
- log("Module installed!", "color: forestgreen;");
- spinnerIcon.hide();
- defaultIcon.classList.remove("d-none");
- scriptSourceLinkInput.value = "";
- }
- });
- });
- row.appendChild(group);
- container.appendChild(row);
- }
- DefinableCore.UI.querySelect("#login-leftcol").appendChild(container);
- }
- })("definable");