您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
allows multiple ppl to work on a mod in realtime.
// ==UserScript== // @name shared modding sessions (SMS) // @namespace http://tampermonkey.net/ // @version 1.0.0 // @description allows multiple ppl to work on a mod in realtime. // @author plxyer-x // @match https://starblast.io/modding.html // @icon https://starblast.io/static/img/icon64.png // @license fuck is that? // @grant none // ==/UserScript== (function() { 'use strict'; let terminal = window.$("#terminal").terminal(); class ModdingSHSession { constructor (server, token, terminal, nonSecure = false) { this.server = server; this.token = token; this.nonSecure = nonSecure; this.terminal = terminal; this.stopped = false; this.started = false; this.pending_commands = []; } static parse (string, terminal) { let args = string.split(" ").map(e => e.trim()).filter(e => e); let nonSecure = false; if (args.includes("-n") || args.includes("--non-secure")) { nonSecure = true; let idx = args.indexOf("-n"); if (idx === -1) idx = args.indexOf("--non-secure"); args.splice(idx, 1); } return new this(args[0], args[1], terminal, nonSecure); } endSession () { if (!this.stopped) { this.started = true; this.stopped = true; this.terminal.echo("Ending session..."); } } closeSocket () { this.ws.close(); setTimeout(function () { if (!this.closed) { this.closed = true; this.terminal.set_prompt("> "); } }.bind(this), 5000); } connect () { try { let ws = this.ws = new WebSocket(`ws${this.nonSecure ? "" : "s"}://${this.server}/`); ws.onopen = function () { if (this.stopped) return this.closeSocket(); ws.send(JSON.stringify({ name: "join", token: this.token })); }.bind(this); ws.onmessage = function (data) { if (this.stopped) return this.closeSocket(); try { let packet = JSON.parse(data.data); if (packet.message && !Array.isArray(packet.message)) packet.message = [packet.message]; switch (packet.name) { case "session_start": this.started = true; this.user = packet.username || "guest"; if (packet.server) this.server = packet.server; this.prompt = `${this.user}@${this.server}`; for (let i of this.pending_commands) this.execute(i); this.pending_commands = []; this.terminal.set_prompt(this.prompt + "# "); this.terminal.echo(`[msh://${this.prompt}]: Session connected successfully.`); this.terminal.echo(`Type 'logout' to end the session.`); break; case "session_end": if (packet.error) { let message = packet.message; if (!message) { if (!this.started) message = "Failed to establish connection (ERR_CONNECTION_REFUSED)"; else message = "Server closes connection unexpectedly." } this.terminal.error(message); } else this.terminal.echo("Session finished."); this.endSession(); break; case "command": this.terminal.echo(`${this.prompt}# ${packet.command}`); break; case "message": for (let m of packet.message) this.terminal.echo(m); break; case "error": for (let e of packet.message) this.terminal.error(e); break; } } catch {} }.bind(this); ws.onclose = function () { if (!this.closed && inSession === this) { this.terminal.set_prompt("> "); } this.closed = true; if (!this.stopped) { this.terminal.echo("Session connection removed."); this.endSession(); } }.bind(this); ws.onerror = function () { this.terminal.error("Failed to connect: Cannot resolve host."); this.endSession(); this.close(); }.bind(this); } catch (e) { this.terminal.error("Failed to connect: Cannot resolve host."); this.endSession(); } } execute (command) { if (!this.started) this.pending_commands.push(command); else this.ws.send(JSON.stringify({ name: "execute", command })); } close () { if (!this.closed) { this.closeSocket(); this.endSession(); } } } let old_interpreter = terminal.export_view().interpreters.top().interpreter; let inSession = null; let getSession = function () { if (!inSession || inSession.closed) { return null; } return inSession; } terminal.set_interpreter(function (input, termInstance) { let args = (input || "").trim().split(" ").map(e => e.trim()); let command = args[0] || ""; let session = getSession(); if (session) { if (command === "logout") { session.close(); } else session.execute(input); } else { if (command === "msh") { inSession = ModdingSHSession.parse(args.slice(1).join(" "), terminal); if (!inSession.server) { terminal.echo(` [flags] <server> [token]\nConnect to shared modding sessions (SMS).\nAvailable flags:\n\t -n, --non-secure: Server is using non-secure WebSocket (ws://)`) inSession = null; } else { terminal.echo("Connecting to Modding session..."); inSession.connect(); } } else old_interpreter.call(this, input, termInstance); } }) })();