From c0e1f9c830bdaf08e599f6a68fdf82a6b0a887a2 Mon Sep 17 00:00:00 2001 From: Elijah R Date: Sun, 23 Jun 2024 18:45:14 -0400 Subject: [PATCH] format with prettier --- .prettierrc | 1 + client.js | 402 ++++++++++----------- index.js | 969 +++++++++++++++++++++++++++------------------------ package.json | 9 +- 4 files changed, 728 insertions(+), 653 deletions(-) create mode 100644 .prettierrc diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.prettierrc @@ -0,0 +1 @@ +{} diff --git a/client.js b/client.js index 762c423..fadbbfb 100644 --- a/client.js +++ b/client.js @@ -1,259 +1,267 @@ // Small single-file CollabVM client library, in semi-modern Javascript -import * as ws from 'ws'; +import * as ws from "ws"; const guacutils = { - parse: (string) => { - let pos = -1; - let sections = []; + parse: (string) => { + let pos = -1; + let sections = []; - for(;;) { - let len=string.indexOf('.', pos + 1); + for (;;) { + let len = string.indexOf(".", pos + 1); - if(len === -1) - break; + if (len === -1) break; - pos=parseInt(string.slice(pos + 1, len)) + len + 1 - sections.push(string.slice(len + 1, pos) - .replace(/'/g, "'") - .replace(/"/g, '"') - .replace(///g, '/') - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(/&/g, '&') - ); + pos = parseInt(string.slice(pos + 1, len)) + len + 1; + sections.push( + string + .slice(len + 1, pos) + .replace(/'/g, "'") + .replace(/"/g, '"') + .replace(///g, "/") + .replace(/</g, "<") + .replace(/>/g, ">") + .replace(/&/g, "&"), + ); - if(string.slice(pos, pos + 1) === ';') - break; - } - - return sections; - }, - - encode: (cypher) =>{ - let command = ''; - - for(var i = 0; i < cypher.length; i++) { - let current = cypher[i]; - command += current.length + '.' + current; - command += ( i < cypher.length - 1 ? ',' : ';'); - } - return command; + if (string.slice(pos, pos + 1) === ";") break; } + + return sections; + }, + + encode: (cypher) => { + let command = ""; + + for (var i = 0; i < cypher.length; i++) { + let current = cypher[i]; + command += current.length + "." + current; + command += i < cypher.length - 1 ? "," : ";"; + } + return command; + }, }; const ConnectionState = Object.freeze({ - CLOSED: 0, - CONNECTING: 1, - CONNECTED: 2 + CLOSED: 0, + CONNECTING: 1, + CONNECTED: 2, }); // System chat messages have a nil username. function IsSystemChatInstruction(inst) { - return inst[1] == ''; + return inst[1] == ""; } class UserData { - #_name; - #_rank; + #_name; + #_rank; - constructor(name, rank) { - this._name = name; - this._rank = rank; - } + constructor(name, rank) { + this._name = name; + this._rank = rank; + } - GetName() { return this._name; } - GetRank() { return this._rank; } + GetName() { + return this._name; + } + GetRank() { + return this._rank; + } - UpdateRank(new_rank) { this._rank = new_rank; } + UpdateRank(new_rank) { + this._rank = new_rank; + } } export default class CollabVMClient { + constructor() { + this._state = ConnectionState.CLOSED; + this._users = []; + } - constructor() { - this._state = ConnectionState.CLOSED; - this._users = []; - } + GetState() { + return this._state; + } - GetState() { return this._state; } + Connect(uri) { + this._ws = new ws.WebSocket(uri, "guacamole", { + origin: "https://computernewb.com", + }); + this._ws.onopen = this.OnWebSocketOpen.bind(this); + this._ws.onclose = this.OnWebSocketClose.bind(this); + this._ws.onerror = this.OnWebSocketError.bind(this); + this._ws.onmessage = this.OnWebSocketMessage.bind(this); + this._state = ConnectionState.CONNECTING; + } - Connect(uri) { - this._ws = new ws.WebSocket(uri, 'guacamole', { - origin: "https://computernewb.com" - }); - this._ws.onopen = this.OnWebSocketOpen.bind(this); - this._ws.onclose = this.OnWebSocketClose.bind(this); - this._ws.onerror = this.OnWebSocketError.bind(this) - this._ws.onmessage = this.OnWebSocketMessage.bind(this); - this._state = ConnectionState.CONNECTING; - } + OnWebSocketOpen() { + this._state = ConnectionState.CONNECTED; + this.OnOpen(); + } - OnWebSocketOpen() { - this._state = ConnectionState.CONNECTED; - this.OnOpen(); - } + OnWebSocketClose() { + this._state = ConnectionState.CLOSED; + this.OnClose(arguments); + } - OnWebSocketClose() { - this._state = ConnectionState.CLOSED; - this.OnClose(arguments); - } + OnWebSocketError() { + // fire the close handler + this._state = ConnectionState.CLOSED; + this.OnClose(arguments); + } - OnWebSocketError() { - // fire the close handler - this._state = ConnectionState.CLOSED; - this.OnClose(arguments); - } + Close() { + this._state = ConnectionState.CLOSED; + this._ws.close(); + } - Close() { - this._state = ConnectionState.CLOSED; - this._ws.close(); - } + OnWebSocketMessage(ev) { + // cvm server should never send binary data + if (typeof ev.data !== "string") return; - OnWebSocketMessage(ev) { - // cvm server should never send binary data - if(typeof(ev.data) !== "string") - return; + let message = guacutils.parse(ev.data); + if (message.length === 0) return; - let message = guacutils.parse(ev.data); - if(message.length === 0) - return; + // Hardcoded, we need to keep this to be alive + if (message[0] === "nop") { + this.SendGuacamoleMessage("nop"); + return; + } - // Hardcoded, we need to keep this to be alive - if(message[0] === "nop") { - this.SendGuacamoleMessage("nop"); - return; - } + //if(message[0] === "chat") { - //if(message[0] === "chat") { - - // console.log(`FUCK (${message.length}) ${message[1]} ${message[2]}`) - //} + // console.log(`FUCK (${message.length}) ${message[1]} ${message[2]}`) + //} - if(message[0] === "chat" && message.length === 3 && !IsSystemChatInstruction(message)) { - if(message[1] != this._username) { - //console.log(`FUCK 2 (${message.length}) ${message[1]} ${message[2]}`) - this.OnChat(message[1], message[2]); - return; - } - } + if ( + message[0] === "chat" && + message.length === 3 && + !IsSystemChatInstruction(message) + ) { + if (message[1] != this._username) { + //console.log(`FUCK 2 (${message.length}) ${message[1]} ${message[2]}`) + this.OnChat(message[1], message[2]); + return; + } + } - if(message[0] === "adduser") { - this.OnAddUser(message.slice(2), parseInt(message[1])); - return; - } + if (message[0] === "adduser") { + this.OnAddUser(message.slice(2), parseInt(message[1])); + return; + } - if(message[0] === "remuser") - this.OnRemUser(message.slice(2), parseInt(message[1])); + if (message[0] === "remuser") + this.OnRemUser(message.slice(2), parseInt(message[1])); - // Handle renames - if(message[0] === "rename") { - if(message.length === 5) { - if(message[1] == '1') { - this._username = message[3]; - } - } - } + // Handle renames + if (message[0] === "rename") { + if (message.length === 5) { + if (message[1] == "1") { + this._username = message[3]; + } + } + } - this.OnGuacamoleMessage(message); - } + this.OnGuacamoleMessage(message); + } - OnAddUser(users, count) { - //console.log(users); - for(var i = 0; i < count * 2; i += 2) { - let name = users[i]; - let rank = users[i + 1]; + OnAddUser(users, count) { + //console.log(users); + for (var i = 0; i < count * 2; i += 2) { + let name = users[i]; + let rank = users[i + 1]; - //console.log(`[${this.GetVM()}] user ${name} rank ${rank}`) + //console.log(`[${this.GetVM()}] user ${name} rank ${rank}`) - let existingUser = this._users.find(elem => elem.GetName() == name); - if(existingUser === undefined) { - //console.log(`[${this.GetVM()}] New user ${name} rank ${rank}`) - this._users.push(new UserData(name, rank)); - } else { - // Handle admin/mod rank update - if(existingUser.GetRank() != rank) { - //console.log(`[${this.GetVM()}] updating ${name} to rank ${rank}`) - existingUser.UpdateRank(rank); - } - } - } - this.OnAddUser_Bot(this.GetUserCount()); - } + let existingUser = this._users.find((elem) => elem.GetName() == name); + if (existingUser === undefined) { + //console.log(`[${this.GetVM()}] New user ${name} rank ${rank}`) + this._users.push(new UserData(name, rank)); + } else { + // Handle admin/mod rank update + if (existingUser.GetRank() != rank) { + //console.log(`[${this.GetVM()}] updating ${name} to rank ${rank}`) + existingUser.UpdateRank(rank); + } + } + } + this.OnAddUser_Bot(this.GetUserCount()); + } - OnRemUser(users, count) { - for(var i = 0; i < count; i++) { - let saveUserTemp = this.GetUser(users[i]); - this._users = this._users.filter(user => user.GetName() != users[i]); - } + OnRemUser(users, count) { + for (var i = 0; i < count; i++) { + let saveUserTemp = this.GetUser(users[i]); + this._users = this._users.filter((user) => user.GetName() != users[i]); + } - this.OnRemUser_Bot(this.GetUserCount()); - } + this.OnRemUser_Bot(this.GetUserCount()); + } - // This subtracts bots, including ourselves - GetUserCount() { - const KnownBots = [ - this.GetUsername(), - //"General Darian" - // logger bots - "Specialized Egg", - "Emperor Kevin" - ]; + // This subtracts bots, including ourselves + GetUserCount() { + const KnownBots = [ + this.GetUsername(), + //"General Darian" + // logger bots + "Specialized Egg", + "Emperor Kevin", + ]; - var len = this._users.length; + var len = this._users.length; - // subtract known bots - for(var i = len - 1; i != 0; --i) { - // ? - if(this._users[i] === undefined) - return; + // subtract known bots + for (var i = len - 1; i != 0; --i) { + // ? + if (this._users[i] === undefined) return; - var name = this._users[i].GetName(); - if(KnownBots.find(elem => name == elem) !== undefined) { - //console.log("found blacklisted username", name) - len--; - } - } + var name = this._users[i].GetName(); + if (KnownBots.find((elem) => name == elem) !== undefined) { + //console.log("found blacklisted username", name) + len--; + } + } - return len; - } + return len; + } + GetUserCountFull() { + return this._users.length; + } - GetUserCountFull() { - return this._users.length; - } + GetUsers() { + this._users; + } - GetUsers() { - this._users; - } + GetUser(username) { + let existingUser = this._users.find((elem) => elem.GetName() == username); - GetUser(username) { - let existingUser = this._users.find(elem => elem.GetName() == username); + // Apparently this can fail somehow..? + if (existingUser === undefined) return null; - // Apparently this can fail somehow..? - if(existingUser === undefined) - return null; - - return existingUser; - } + return existingUser; + } - GetUsername() { return this._username; } + GetUsername() { + return this._username; + } - Rename(name) { - this._username = name; - this.SendGuacamoleMessage("rename", name); - } + Rename(name) { + this._username = name; + this.SendGuacamoleMessage("rename", name); + } - GetVM() { return this._vm; } - - ConnectToVM(vm) { - this._vm = vm; - this.SendGuacamoleMessage("connect", vm); - } + GetVM() { + return this._vm; + } - SendGuacamoleMessage() { - if(this._state !== ConnectionState.CONNECTED) - return; + ConnectToVM(vm) { + this._vm = vm; + this.SendGuacamoleMessage("connect", vm); + } - this._ws.send(guacutils.encode(Array.prototype.slice.call(arguments))); - } + SendGuacamoleMessage() { + if (this._state !== ConnectionState.CONNECTED) return; + this._ws.send(guacutils.encode(Array.prototype.slice.call(arguments))); + } } diff --git a/index.js b/index.js index 88f025a..1212142 100644 --- a/index.js +++ b/index.js @@ -1,120 +1,119 @@ -import CollabVMClient from './client.js'; -import {BANNED_ISO, ISO_DIRECTORIES, INSTALLBOT_VMS, BOT_PREFIX, ADMIN_TOKEN, kGeneralLimitBaseSeconds, kRebootLimitBaseSeconds} from './config.js'; +import CollabVMClient from "./client.js"; +import { + BANNED_ISO, + ISO_DIRECTORIES, + INSTALLBOT_VMS, + BOT_PREFIX, + ADMIN_TOKEN, + kGeneralLimitBaseSeconds, + kRebootLimitBaseSeconds, +} from "./config.js"; function Log() { - // console.log(`[AnyOSBot] [${new Date()}]`, [...arguments].join(' ')) - console.log('[AnyOSBot]', [...arguments].join(' ')) + // console.log(`[AnyOSBot] [${new Date()}]`, [...arguments].join(' ')) + console.log("[AnyOSBot]", [...arguments].join(" ")); } - // you people SUCK man (dynamic edition, with less bugs!) // and it actually probably works without hanging or negative seconds this time. class RateLimit { - constructor(time, factor, ident) { - this._ident = ident; - this._timeBase = time; - this._msUntil = 0; - this._n = 1; - this._factor = factor; - } + constructor(time, factor, ident) { + this._ident = ident; + this._timeBase = time; + this._msUntil = 0; + this._n = 1; + this._factor = factor; + } - GetTime() { - return this._msUntil; - } + GetTime() { + return this._msUntil; + } - IsLimited() { - return this._limited; - } + IsLimited() { + return this._limited; + } - GetMs() { - let ret = Math.floor( - ((this._n * (1/5)) * this._timeBase) * this._factor - ); + GetMs() { + let ret = Math.floor(this._n * (1 / 5) * this._timeBase * this._factor); - // Make sure it's at least time base - if(ret < 1000) - ret = this._timeBase; + // Make sure it's at least time base + if (ret < 1000) ret = this._timeBase; - // Clean out fractional milliseconds - if((ret % 1000) != 0) - ret -= (ret % 1000); + // Clean out fractional milliseconds + if (ret % 1000 != 0) ret -= ret % 1000; + //Log(`Debug: Ratelimit returns ${ret} (where N = ${this._n})`); + return ret; + } - //Log(`Debug: Ratelimit returns ${ret} (where N = ${this._n})`); - return ret; - } + SetUserCount(count) { + if (count == 0) count = 1; + this._n = count; - SetUserCount(count) { - if(count == 0) - count = 1; - this._n = count; + //Log(`Debug: Ratelimit \"${this._ident}\" count set to ${count}, algo says time will be: ${this.GetMs()} (${this.GetMs() / 1000} seconds)`); + } - //Log(`Debug: Ratelimit \"${this._ident}\" count set to ${count}, algo says time will be: ${this.GetMs()} (${this.GetMs() / 1000} seconds)`); - } + StartLimit() { + // TODO: this might work for the dyna ratelimit? + if (this._limited) return; - StartLimit() { - // TODO: this might work for the dyna ratelimit? - if(this._limited) - return; + let self = this; + self._msUntil = this.GetMs(); + Log( + `Ratelimit \"${this._ident}\" started, will be done in ${self._msUntil} ms (${self._msUntil / 1000} seconds)`, + ); + self._limited = true; - let self = this; - self._msUntil = this.GetMs(); - Log(`Ratelimit \"${this._ident}\" started, will be done in ${self._msUntil} ms (${self._msUntil / 1000} seconds)`); - self._limited = true; + this._siHandle = setInterval(() => { + self._msUntil -= 1000; + if (self._msUntil <= 0) { + Log(`Ratelimit \"${self._ident}\" is done.`); + clearInterval(self._siHandle); + self._limited = false; + return; + } + }, 1000); + } - this._siHandle = setInterval(() => { - self._msUntil -= 1000; - if(self._msUntil <= 0) { - Log(`Ratelimit \"${self._ident}\" is done.`) - clearInterval(self._siHandle); - self._limited = false; - return; - } - }, 1000); - } - - ToString() { - const time = Math.floor(this.GetTime() / 1000); - let second_or_seconds = () => { - if(time > 1 || time === 0) - return "seconds"; - return "second"; - }; - return `${time} ${second_or_seconds()}`; - } + ToString() { + const time = Math.floor(this.GetTime() / 1000); + let second_or_seconds = () => { + if (time > 1 || time === 0) return "seconds"; + return "second"; + }; + return `${time} ${second_or_seconds()}`; + } } - class HelperBot extends CollabVMClient { - constructor(wsUri, vmId, ide2, floppy) { - super(); + constructor(wsUri, vmId, ide2, floppy) { + super(); - this._wsUri = wsUri; - this._vmId = vmId; - this._ide2 = ide2; - this._hasFloppy = floppy; + this._wsUri = wsUri; + this._vmId = vmId; + this._ide2 = ide2; + this._hasFloppy = floppy; + } - } + DoConn() { + Log(`[${this._vmId}]`, `Connecting to ${this._wsUri}`); + this.Connect(this._wsUri); + } - DoConn() { - Log(`[${this._vmId}]`, `Connecting to ${this._wsUri}`); - this.Connect(this._wsUri); - } + OnOpen() { + Log(`[${this._vmId}]`, `Bot connected to CollabVM server`); + this.CreateRateLimits(); - OnOpen() { - Log(`[${this._vmId}]`, `Bot connected to CollabVM server`); - this.CreateRateLimits(); + // This dummy rename is required for some dumb reason.. + this.Rename("fucker google"); + this.ConnectToVM(this._vmId); + } - // This dummy rename is required for some dumb reason.. - this.Rename("fucker google"); - this.ConnectToVM(this._vmId); - } + OnClose(ev) { + //console.log(arguments) + // reconnect lol - OnClose(ev) { - //console.log(arguments) - // reconnect lol - - /* the right way doesnt work thanks to something + /* the right way doesnt work thanks to something Log(`[${this._vmId}]`, `Connection closed, reconnecting in 5 seconds`); let self = this; @@ -123,314 +122,364 @@ class HelperBot extends CollabVMClient { self.DoConn(); }, 1000 * 5) */ - - Log(`[${this._vmId}]`, `Connection closed, exiting process`); - process.exit(0); + Log(`[${this._vmId}]`, `Connection closed, exiting process`); + process.exit(0); - // The bot should probably give up after some attempts - } + // The bot should probably give up after some attempts + } - Chat(message) { - this.SendGuacamoleMessage("chat", message); - } + Chat(message) { + this.SendGuacamoleMessage("chat", message); + } + OnAddUser_Bot(count) { + this.GeneralCmdLimit.SetUserCount(count); + this.RebootLimit.SetUserCount(count); + } - OnAddUser_Bot(count) { - this.GeneralCmdLimit.SetUserCount(count); - this.RebootLimit.SetUserCount(count); - } + OnRemUser_Bot(count) { + this.GeneralCmdLimit.SetUserCount(count); + this.RebootLimit.SetUserCount(count); + } - OnRemUser_Bot(count) { - this.GeneralCmdLimit.SetUserCount(count); - this.RebootLimit.SetUserCount(count); - } + UserCanBypass(username) { + let existingUser = this.GetUser(username); - UserCanBypass(username) { - let existingUser = this.GetUser(username); + // Apparently this can fail somehow..? + if (existingUser == null) return false; - // Apparently this can fail somehow..? - if(existingUser == null) - return false; + let rank = existingUser.GetRank(); + return rank == 2 || rank == 3; + } - let rank = existingUser.GetRank(); - return rank == 2 || rank == 3; - } + SendMonitorCommand(cmd) { + this.SendGuacamoleMessage("admin", "5", this.GetVM(), cmd); + } + ConcatPath(isodir, otherPath) { + let isopath = ISO_DIRECTORIES[isodir]; + if (isopath === undefined) { + // imo crashing and being restarted by systemd is better than not knowing why shit was coming out as undefined + // gotta love javascript + throw new Error(`Undefined iso directory ${isodir}`); + } + return `${isopath}/${otherPath}`; + } - SendMonitorCommand(cmd) { - this.SendGuacamoleMessage("admin", "5", this.GetVM(), cmd); - } + // QEMU Abstractions - ConcatPath(isodir, otherPath) { - let isopath = ISO_DIRECTORIES[isodir]; - if (isopath === undefined) { - // imo crashing and being restarted by systemd is better than not knowing why shit was coming out as undefined - // gotta love javascript - throw new Error(`Undefined iso directory ${isodir}`); - } - return `${isopath}/${otherPath}`; - } + QemuEjectDevice(devname) { + this.SendMonitorCommand(`eject ${devname}`); + } - // QEMU Abstractions + QemuChangeDevice(devname, source, opts) { + this.SendMonitorCommand(`change ${devname} "${source}" ${opts}`); + } - QemuEjectDevice(devname) { - this.SendMonitorCommand(`eject ${devname}`); - } + QemuEjectCd() { + if (this._ide2) this.QemuEjectDevice("ide2-cd0"); + else this.QemuEjectDevice("vm.cd"); + } - QemuChangeDevice(devname, source, opts) { - this.SendMonitorCommand(`change ${devname} "${source}" ${opts}`); - } + QemuEjectFloppy() { + if (this._hasFloppy) this.QemuEjectDevice("vm.floppy"); + } - QemuEjectCd() { - if(this._ide2) - this.QemuEjectDevice("ide2-cd0"); - else - this.QemuEjectDevice("vm.cd"); - } + QemuChangeCd(source, opts) { + if (this._ide2) this.QemuChangeDevice("ide2-cd0", source, opts); + else this.QemuChangeDevice("vm.cd", source, opts); + } - QemuEjectFloppy() { - if(this._hasFloppy) - this.QemuEjectDevice("vm.floppy"); - } + QemuChangeFloppy(source) { + if (this._hasFloppy) + this.QemuChangeDevice("vm.floppy", source, "raw read-only"); + } - QemuChangeCd(source, opts) { - if(this._ide2) - this.QemuChangeDevice("ide2-cd0", source, opts); - else - this.QemuChangeDevice("vm.cd", source, opts); - } + OnChat(username, message) { + //console.log(`${username}> ${message}`); - QemuChangeFloppy(source) { - if(this._hasFloppy) - this.QemuChangeDevice("vm.floppy" , source, "raw read-only"); - } + if (username == this.GetUsername()) return; + if (message[0] === BOT_PREFIX) { + this.HandleCommands(username, message); + } + } - OnChat(username, message) { - //console.log(`${username}> ${message}`); + HandleCommands(username, message) { + { + let user = this.GetUser(username); + if (user == null) { + Log(`[${this._vmId}]`, `I don't know about user \"${username}\" `); + process.exit(0); + return; + } - if(username == this.GetUsername()) - return; + // This should disallow unregistered users, + // please don't fuck the rank up to where I can't do this + if (!(user.GetRank() >= 1)) { + return; + } + } - if(message[0] === BOT_PREFIX) { - this.HandleCommands(username, message); - } - } + // Little code fragment to make rate limiting + // more portable. + const DoLimit = (limit) => { + //console.log(`[AnyOSBot] [${this._vmId}] ${this.GetUserCount()} users online (${this.GetUserCountFull()} actual)`) - HandleCommands(username, message) { - { - let user = this.GetUser(username); - if(user == null) { - Log(`[${this._vmId}]`, `I don't know about user \"${username}\" `); - process.exit(0); - return; - } + //if(this._vmId !== 'vm0b0t') { + // + if (limit.IsLimited() && !this.UserCanBypass(username)) { + this.Chat( + `You may not use commands yet. Please wait ${limit.ToString()}.`, + ); + return false; + } + //} - // This should disallow unregistered users, - // please don't fuck the rank up to where I can't do this - if(!(user.GetRank() >= 1)) { - return; - } - } + //console.log(`[AnyOSBot] [${this._vmId}] ${new Date()} ${username} executed command ${command}`) - // Little code fragment to make rate limiting - // more portable. - const DoLimit = (limit) => { - //console.log(`[AnyOSBot] [${this._vmId}] ${this.GetUserCount()} users online (${this.GetUserCountFull()} actual)`) + //Log(`[${this._vmId}]`, `${username} executed \"!${command}\"`); + Log(`[${this._vmId}]`, `${username} executed \"${message}\"`); + if (!this.UserCanBypass(username)) { + limit.StartLimit(); + } + return true; + }; - //if(this._vmId !== 'vm0b0t') { - // - if(limit.IsLimited() && !this.UserCanBypass(username)) { - this.Chat(`You may not use commands yet. Please wait ${limit.ToString()}.`); - return false; - } - //} + // generate a help HTML string for the help + const generateHelp = (arr) => { + let str = "

AnyOSInstallBot Help:

"; + return str; + }; - //console.log(`[AnyOSBot] [${this._vmId}] ${new Date()} ${username} executed command ${command}`) + const generateList = (title, arr) => { + let str = `

${title}

"; + return str; + }; - //Log(`[${this._vmId}]`, `${username} executed \"!${command}\"`); - Log(`[${this._vmId}]`, `${username} executed \"${message}\"`); + let command = ""; - if(!this.UserCanBypass(username)) { - limit.StartLimit(); - } - return true; - } + if (message.indexOf(" ") !== -1) + command = message.slice(1, message.indexOf(" ")); + else command = message.slice(1); - // generate a help HTML string for the help - const generateHelp = (arr) => { - let str = "

AnyOSInstallBot Help:

"; - return str; - } + switch (command) { + case "help": + if (!DoLimit(this.GeneralCmdLimit)) return; + this.SendGuacamoleMessage( + "admin", + "21", + generateHelp([ + { + command: "certerror", + help: "Provides information on the CollabNet SSL certificate", + }, + { command: "network", help: "Provides network driver information" }, + { + command: "cd [path]", + help: "Change CD image to Computernewb ISO image (see computernewb.com/isos)", + }, + { + command: "lilycd [path]", + help: "Change CD image to Lily ISO image (see computernewb.com/~lily/ISOs)", + }, + { + command: "crustycd [path]", + help: "Change CD image to CrustyWindows ISO image (see crustywindo.ws/collection)", + }, + { + command: "flp [path]", + help: "Change Floppy image to Dartz IMG/flp image", + usesFloppy: true, + }, + { + command: "lilyflp [path]", + help: "Change Floppy image to Lily IMG/flp image", + usesFloppy: true, + }, + { + command: "httpcd [URL]", + help: "Change CD image to HTTP server ISO file. Whitelisted domains only (see computernewb.com/CHOCOLATEMAN/domains.txt for a list)", + }, + { + command: "eject [cd/flp]", + help: "Ejects media from the specified drive.", + }, + { + command: "reboot", + help: "Reboot the VM. Has a larger cooldown, so don't be a retard with it.", + }, + { + command: "bootset [string of c,a,d,n]", + help: "Change the VM's boot order", + }, + ]), + ); + return; + break; - const generateList = (title, arr) => { - let str = `

${title}

"; - return str; - } + case "network": + if (!DoLimit(this.GeneralCmdLimit)) return; + switch (this._vmId) { + case "vm7": + this.SendGuacamoleMessage( + "admin", + "21", + generateList("VirtIO Network Setup Instructions (Windows):", [ + 'Run "!cd driver/virtio-win-0.1.225.iso" to insert the VirtIO driver CD into the VM.', + 'Run "devmgmt.msc" in the VM, look for the "Ethernet Controller" device, and update its driver.', + "When asked for a path, put in D:\\NetKVM\\{OS}\\x86 (or on a 64-bit OS, D:\\NetKVM\\{OS}\\amd64)", + "After that, see the !certerror command.", + ]), + ); + break; + case "vm8": + this.SendGuacamoleMessage( + "admin", + "21", + generateList("RTL8139 Network Setup Instructions (Windows):", [ + 'Run "!cd Driver/VM8 Network Drivers.iso" to insert the RTL8139 network driver CD into the VM.', + 'Run "devmgmt.msc" in the VM, look for the "Ethernet Controller" device, and update its driver.', + "When asked for a path, put in D:\\(name of OS)\\. For example, on Windows NT 4, put in D:\\WINNT4\\ (click browse and select the OS if you can't figure it out)", + "After that, you should be online. This step should NOT be required on Windows 2000, XP, Vista, or 7. This step should not be required on ANY Linux distro unless its really shit.", + ]), + ); + break; + default: + this.chat("This VM should already have internet."); + break; + } + break; + case "certerror": + if (!DoLimit(this.GeneralCmdLimit)) return; - let command = ''; + //if(this._vmId == 'vm0b0t') { + // this.SendGuacamoleMessage("admin", "21", "

fuck off retard why are you trying to get collabnet on vm0

"); + // return; + //} - if(message.indexOf(' ') !== -1) - command = message.slice(1, message.indexOf(' ')); - else - command = message.slice(1); + this.SendGuacamoleMessage( + "admin", + "21", + generateList("CollabNet Setup Instructions:", [ + "Follow the instructions on http://192.168.1.1 to install the certificate.", + ]), + ); + break; - switch(command) { - case 'help': - if(!DoLimit(this.GeneralCmdLimit)) - return; - this.SendGuacamoleMessage("admin", "21", generateHelp([ - { command: "certerror", help: "Provides information on the CollabNet SSL certificate" }, - { command: "network", help: "Provides network driver information" }, - { command: "cd [path]", help: "Change CD image to Computernewb ISO image (see computernewb.com/isos)" }, - { command: "lilycd [path]", help: "Change CD image to Lily ISO image (see computernewb.com/~lily/ISOs)" }, - { command: "crustycd [path]", help: "Change CD image to CrustyWindows ISO image (see crustywindo.ws/collection)" }, - { command: "flp [path]", help: "Change Floppy image to Dartz IMG/flp image", usesFloppy: true }, - { command: "lilyflp [path]", help: "Change Floppy image to Lily IMG/flp image", usesFloppy: true }, - { command: "httpcd [URL]", help: "Change CD image to HTTP server ISO file. Whitelisted domains only (see computernewb.com/CHOCOLATEMAN/domains.txt for a list)" }, - { command: "eject [cd/flp]", help: "Ejects media from the specified drive." }, - { command: "reboot", help: "Reboot the VM. Has a larger cooldown, so don't be a retard with it." }, - { command: "bootset [string of c,a,d,n]", help: "Change the VM's boot order" }, - ])); - return; - break; + // this is gigantic holy fuck + case "cd": + case "lilycd": + case "crustycd": + case "flp": + case "lilyflp": + case "httpcd": + case "httpflp": + { + if (!DoLimit(this.GeneralCmdLimit)) return; - case 'network': - if(!DoLimit(this.GeneralCmdLimit)) - return; + let arg = message.slice(message.indexOf(" ") + 1); + let ext = arg.slice(arg.lastIndexOf(".") + 1); + if (arg.indexOf("..") !== -1) return; + for (var ii = 0; ii < BANNED_ISO.length; ii++) { + if (BANNED_ISO[ii].test(arg)) { + this.Chat("That ISO is currently blacklisted."); + return; + } + } - switch(this._vmId) { - case "vm7": - this.SendGuacamoleMessage("admin", "21", generateList("VirtIO Network Setup Instructions (Windows):", [ - "Run \"!cd driver/virtio-win-0.1.225.iso\" to insert the VirtIO driver CD into the VM.", - "Run \"devmgmt.msc\" in the VM, look for the \"Ethernet Controller\" device, and update its driver.", - "When asked for a path, put in D:\\NetKVM\\{OS}\\x86 (or on a 64-bit OS, D:\\NetKVM\\{OS}\\amd64)", - "After that, see the !certerror command." - ])); - break; - case "vm8": - this.SendGuacamoleMessage("admin", "21", generateList("RTL8139 Network Setup Instructions (Windows):", [ - "Run \"!cd Driver/VM8 Network Drivers.iso\" to insert the RTL8139 network driver CD into the VM.", - "Run \"devmgmt.msc\" in the VM, look for the \"Ethernet Controller\" device, and update its driver.", - "When asked for a path, put in D:\\(name of OS)\\. For example, on Windows NT 4, put in D:\\WINNT4\\ (click browse and select the OS if you can't figure it out)", - "After that, you should be online. This step should NOT be required on Windows 2000, XP, Vista, or 7. This step should not be required on ANY Linux distro unless its really shit." - ])); - break; - default: - this.chat("This VM should already have internet."); - break; - } - - break; + switch (command) { + case "cd": + case "lilycd": + case "crustycd": + if ( + arg.indexOf("http://") !== -1 || + arg.indexOf("https://") != -1 + ) { + this.Chat( + "Use the http versions of these commands, if the iso is locally hosted you can try !command Path/iso.iso (case-sensitive)", + ); + return; + } - case 'certerror': - if(!DoLimit(this.GeneralCmdLimit)) - return; + if (ext.toLowerCase() === "iso") { + // repetitive but whatever it works + if (command === "lilycd") + this.QemuChangeCd(this.ConcatPath("lily", arg), ""); + else if (command == "crustycd") + this.QemuChangeCd(this.ConcatPath("crustywin", arg), ""); + else if (command == "cd") + this.QemuChangeCd(this.ConcatPath("computernewb", arg), ""); - //if(this._vmId == 'vm0b0t') { - // this.SendGuacamoleMessage("admin", "21", "

fuck off retard why are you trying to get collabnet on vm0

"); - // return; - //} + //this.QemuChangeCd(this.ConcatPath(command === 'lilycd' && 'lily' || command === "crustycd" && 'crustywin' || 'computernewb', arg), ""); + } + break; - this.SendGuacamoleMessage("admin", "21", generateList("CollabNet Setup Instructions:", [ - "Follow the instructions on http://192.168.1.1 to install the certificate." - ])); - break; + case "flp": + case "lilyflp": + if ( + arg.indexOf("http://") !== -1 || + arg.indexOf("https://") != -1 + ) { + this.Chat("Use the http versions of these commands"); + return; + } - // this is gigantic holy fuck - case 'cd': - case 'lilycd': - case 'crustycd': - case 'flp': - case 'lilyflp': - case 'httpcd': - case 'httpflp': { - if(!DoLimit(this.GeneralCmdLimit)) - return; + if (!this._hasFloppy) { + this.Chat("This VM does not have a floppy drive."); + return; + } - let arg = message.slice(message.indexOf(' ')+1); - let ext = arg.slice(arg.lastIndexOf('.') + 1); - if(arg.indexOf('..') !== -1) - return; - for (var ii = 0; ii < BANNED_ISO.length; ii++) { - if (BANNED_ISO[ii].test(arg)) { - this.Chat("That ISO is currently blacklisted."); - return; - } - } + if (ext.toLowerCase() === "iso") { + this.Chat("dumbass, use !cd or !lilycd"); + return; + } - switch(command) { - case 'cd': - case 'lilycd': - case 'crustycd': - if(arg.indexOf('http://') !== -1 || arg.indexOf('https://') != -1) { - this.Chat("Use the http versions of these commands, if the iso is locally hosted you can try !command Path/iso.iso (case-sensitive)") - return; - } + if (ext.toLowerCase() === "img" || ext.toLowerCase() === "ima") { + this.QemuChangeFloppy( + this.ConcatPath( + command === "lilyflp" ? "lily" : "computernewb", + arg, + ), + ); + } + break; - if(ext.toLowerCase() === "iso") { - // repetitive but whatever it works - if(command === 'lilycd') - this.QemuChangeCd(this.ConcatPath('lily', arg), ""); - else if (command == 'crustycd') - this.QemuChangeCd(this.ConcatPath('crustywin', arg), ""); - else if (command == 'cd') - this.QemuChangeCd(this.ConcatPath('computernewb', arg), ""); + case "httpcd": + //this.Chat("Disabled due to retards, sorry! Try !cd, !lilycd or !crustycd for some local isos."); + //return; - //this.QemuChangeCd(this.ConcatPath(command === 'lilycd' && 'lily' || command === "crustycd" && 'crustywin' || 'computernewb', arg), ""); - } - break; + // whitelisted domains + const whitelist = [ + "http://kernel.org", + "https://kernel.org", + "http://distro.ibiblio.org", + "https://distro.ibiblio.org", + "https://dl.collabsysos.xyz", + "https://egg.l5.ca", + "https://download.manjaro.org", + "https://ubuntu.osuosl.org/", + "https://mirror.kku.ac.th/", + "https://cdimage.debian.org", + "https://archive.elijahr.dev/Games/pcgc.iso", + ]; - case 'flp': - case 'lilyflp': - if(arg.indexOf('http://') !== -1 || arg.indexOf('https://') != -1) { - this.Chat("Use the http versions of these commands") - return; - } - - - if(!this._hasFloppy) { - this.Chat("This VM does not have a floppy drive."); - return; - } - - if(ext.toLowerCase() === "iso") { - this.Chat("dumbass, use !cd or !lilycd"); - return; - } - - if(ext.toLowerCase() === "img" || ext.toLowerCase() === "ima") { - this.QemuChangeFloppy(this.ConcatPath(command === 'lilyflp' ? 'lily' : 'computernewb', arg)); - } - break; - - case 'httpcd': - //this.Chat("Disabled due to retards, sorry! Try !cd, !lilycd or !crustycd for some local isos."); - //return; - - // whitelisted domains - const whitelist = ['http://kernel.org', 'https://kernel.org', 'http://distro.ibiblio.org', - 'https://distro.ibiblio.org', 'https://dl.collabsysos.xyz', 'https://egg.l5.ca', - 'https://download.manjaro.org', 'https://ubuntu.osuosl.org/', 'https://mirror.kku.ac.th/', - 'https://cdimage.debian.org', 'https://archive.elijahr.dev/Games/pcgc.iso' ]; - - /*var is_founded = false; // this might not be elegant sorry - Hilda + /*var is_founded = false; // this might not be elegant sorry - Hilda for (var piss in whitelist) { //console.log(`${arg.indexOf(whitelist[piss])}`); if (arg.startsWith(whitelist[piss]) === true) { // no archive.org/cock.iso?ignore=validurl @@ -438,146 +487,156 @@ class HelperBot extends CollabVMClient { break; } }*/ - - // Yeah I knew it, thanks modeco! - Hilda - let is_founded = (() => whitelist.find(e => arg.startsWith(e)) !== undefined)(); - if(is_founded === false) - { - //this.Chat("This is sparta!"); - return; - } - /* + // Yeah I knew it, thanks modeco! - Hilda + let is_founded = (() => + whitelist.find((e) => arg.startsWith(e)) !== undefined)(); + if (is_founded === false) { + //this.Chat("This is sparta!"); + return; + } + + /* if(arg.indexOf('~dartz/isos') !== -1 || arg.indexOf('~lily/ISOs') !== -1) { this.Chat('Use the non-http versions of these commands for local images, please.'); return; } */ - /*if(arg.indexOf('crustywindo.ws') !== -1) { // make this an else if or bundle in previous if if latter is added back + /*if(arg.indexOf('crustywindo.ws') !== -1) { // make this an else if or bundle in previous if if latter is added back this.Chat("Use the !crustycd command for the bootleg collection, please."); return; }*/ // wait im retarded whitelist - if(ext.toLowerCase() === "iso") - this.QemuChangeCd(arg, ""); - break; + if (ext.toLowerCase() === "iso") this.QemuChangeCd(arg, ""); + break; - case 'httpflp': - //this.Chat("Disabled due to retards; sorry!"); - //return; + case "httpflp": + //this.Chat("Disabled due to retards; sorry!"); + //return; - if(arg.indexOf('~dartz/isos') !== -1 || arg.indexOf('~lily/ISOs') !== -1) { - this.Chat('Use the non-http versions of these commands for local images, please.'); - return; - } + if ( + arg.indexOf("~dartz/isos") !== -1 || + arg.indexOf("~lily/ISOs") !== -1 + ) { + this.Chat( + "Use the non-http versions of these commands for local images, please.", + ); + return; + } - if(!this._hasFloppy) { - this.Chat("This VM does not have a floppy drive."); - return; - } + if (!this._hasFloppy) { + this.Chat("This VM does not have a floppy drive."); + return; + } - if(ext.toLowerCase() == "img" || ext.toLowerCase() == "ima") - this.QemuChangeFloppy(arg); - break; - } - // bleh - this.Chat("Tried to put media into specified device."); - } break; + if (ext.toLowerCase() == "img" || ext.toLowerCase() == "ima") + this.QemuChangeFloppy(arg); + break; + } + // bleh + this.Chat("Tried to put media into specified device."); + } + break; - case 'eject': { - if(!DoLimit(this.GeneralCmdLimit)) - return; + case "eject": + { + if (!DoLimit(this.GeneralCmdLimit)) return; - let arg = message.slice(message.indexOf(' ')+1); + let arg = message.slice(message.indexOf(" ") + 1); - //this.Chat("sorry, severe autism not allowed right now"); - //return; + //this.Chat("sorry, severe autism not allowed right now"); + //return; - switch(arg) { - case 'cd': - this.QemuEjectCd(); - break; - case 'flp': - this.QemuEjectFloppy(); - break; - } - } break; + switch (arg) { + case "cd": + this.QemuEjectCd(); + break; + case "flp": + this.QemuEjectFloppy(); + break; + } + } + break; + case "reboot": + if (!DoLimit(this.RebootLimit)) return; - case 'reboot': - if(!DoLimit(this.RebootLimit)) - return; - - // this.Chat("hold on fellas"); - // return; - this.SendMonitorCommand("system_reset"); - break; + // this.Chat("hold on fellas"); + // return; + this.SendMonitorCommand("system_reset"); + break; - case 'bootset': - if(!DoLimit(this.GeneralCmdLimit)) - return; + case "bootset": + if (!DoLimit(this.GeneralCmdLimit)) return; - //this.Chat("sorry, severe autism not allowed right now"); - //return; - this.SendMonitorCommand(`boot_set ${message.slice(message.indexOf(' ')+1)}`); - break; + //this.Chat("sorry, severe autism not allowed right now"); + //return; + this.SendMonitorCommand( + `boot_set ${message.slice(message.indexOf(" ") + 1)}`, + ); + break; - default: - this.Chat(`Unknown command ${command}. See !help?`); - break; - } - } + default: + this.Chat(`Unknown command ${command}. See !help?`); + break; + } + } - CreateRateLimits() { - // Instanciate rate limit classes - // TODO: Should these be shared? idk + CreateRateLimits() { + // Instanciate rate limit classes + // TODO: Should these be shared? idk - //if (vmId == 'vm0b0t') - // this.GeneralCmdLimit = new RateLimit(25 * 1000); - //else - this.GeneralCmdLimit = new RateLimit(kGeneralLimitBaseSeconds * 1000, 2, `General commands/${this._vmId}`); + //if (vmId == 'vm0b0t') + // this.GeneralCmdLimit = new RateLimit(25 * 1000); + //else + this.GeneralCmdLimit = new RateLimit( + kGeneralLimitBaseSeconds * 1000, + 2, + `General commands/${this._vmId}`, + ); - //this.EjectLimit = new RateLimit(30 * 1000); - this.RebootLimit = new RateLimit(kRebootLimitBaseSeconds * 1000, 3, `!reboot/${this._vmId}`); - } + //this.EjectLimit = new RateLimit(30 * 1000); + this.RebootLimit = new RateLimit( + kRebootLimitBaseSeconds * 1000, + 3, + `!reboot/${this._vmId}`, + ); + } - OnGuacamoleMessage(message) { - if(message[0] == "connect") { - if(message[1] == '0') { - Log(`[${this._vmId}]`, `Failed to connect to VM`); - this.Close(); - return; - } + OnGuacamoleMessage(message) { + if (message[0] == "connect") { + if (message[1] == "0") { + Log(`[${this._vmId}]`, `Failed to connect to VM`); + this.Close(); + return; + } - //console.log(message); - Log(`[${this._vmId}]`, `Connected to VM`); + //console.log(message); + Log(`[${this._vmId}]`, `Connected to VM`); + // I'm fucking lazy + this.SendGuacamoleMessage("login", ADMIN_TOKEN); + this.CreateRateLimits(); + } - // I'm fucking lazy - this.SendGuacamoleMessage("login", ADMIN_TOKEN); - this.CreateRateLimits(); - } + // 5.admin,1.2,44.unknown command: 'aaaaa' ; + if (message[0] == "admin" && message[1] == "2") { + if (message[2].indexOf("Could not open") !== -1) { + this.Chat( + "Could not open selected CD or floppy image. Please check the filename", + ); + } -// 5.admin,1.2,44.unknown command: 'aaaaa' ; - if(message[0] == "admin" && message[1] == "2") { - if(message[2].indexOf("Could not open") !== -1) { - this.Chat("Could not open selected CD or floppy image. Please check the filename"); - } - - - if(message[2].indexOf("boot device list now set to") !== -1) { - this.Chat("Successfully set boot order."); - } - //console.log(`Admin response: ${message[2]}`); - } - } + if (message[2].indexOf("boot device list now set to") !== -1) { + this.Chat("Successfully set boot order."); + } + //console.log(`Admin response: ${message[2]}`); + } + } } - -for(let vm of INSTALLBOT_VMS) { - // initalize this bot instance - new HelperBot(vm.uri, vm.id, vm.usesIde2, vm.hasFloppy) - .DoConn(); +for (let vm of INSTALLBOT_VMS) { + // initalize this bot instance + new HelperBot(vm.uri, vm.id, vm.usesIde2, vm.hasFloppy).DoConn(); } - diff --git a/package.json b/package.json index 45e7ddc..45ba980 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "AnyOSInstallBot", + "name": "anyosinstallbot", "version": "1.0.0", "description": "Helper bot to insert media into AnyOS VMs", "main": "index.js", @@ -8,5 +8,12 @@ "type": "module", "dependencies": { "ws": "^8.3.0" + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e", + "scripts": { + "format": "prettier *.js -w" + }, + "devDependencies": { + "prettier": "^3.3.2" } }