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);
}
})
})();