format with prettier
This commit is contained in:
parent
5fd343c87b
commit
c0e1f9c830
4 changed files with 728 additions and 653 deletions
1
.prettierrc
Normal file
1
.prettierrc
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{}
|
402
client.js
402
client.js
|
@ -1,259 +1,267 @@
|
||||||
// Small single-file CollabVM client library, in semi-modern Javascript
|
// Small single-file CollabVM client library, in semi-modern Javascript
|
||||||
import * as ws from 'ws';
|
import * as ws from "ws";
|
||||||
|
|
||||||
const guacutils = {
|
const guacutils = {
|
||||||
parse: (string) => {
|
parse: (string) => {
|
||||||
let pos = -1;
|
let pos = -1;
|
||||||
let sections = [];
|
let sections = [];
|
||||||
|
|
||||||
for(;;) {
|
for (;;) {
|
||||||
let len=string.indexOf('.', pos + 1);
|
let len = string.indexOf(".", pos + 1);
|
||||||
|
|
||||||
if(len === -1)
|
if (len === -1) break;
|
||||||
break;
|
|
||||||
|
|
||||||
pos=parseInt(string.slice(pos + 1, len)) + len + 1
|
pos = parseInt(string.slice(pos + 1, len)) + len + 1;
|
||||||
sections.push(string.slice(len + 1, pos)
|
sections.push(
|
||||||
.replace(/'/g, "'")
|
string
|
||||||
.replace(/"/g, '"')
|
.slice(len + 1, pos)
|
||||||
.replace(///g, '/')
|
.replace(/'/g, "'")
|
||||||
.replace(/</g, '<')
|
.replace(/"/g, '"')
|
||||||
.replace(/>/g, '>')
|
.replace(///g, "/")
|
||||||
.replace(/&/g, '&')
|
.replace(/</g, "<")
|
||||||
);
|
.replace(/>/g, ">")
|
||||||
|
.replace(/&/g, "&"),
|
||||||
|
);
|
||||||
|
|
||||||
if(string.slice(pos, pos + 1) === ';')
|
if (string.slice(pos, pos + 1) === ";") break;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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({
|
const ConnectionState = Object.freeze({
|
||||||
CLOSED: 0,
|
CLOSED: 0,
|
||||||
CONNECTING: 1,
|
CONNECTING: 1,
|
||||||
CONNECTED: 2
|
CONNECTED: 2,
|
||||||
});
|
});
|
||||||
|
|
||||||
// System chat messages have a nil username.
|
// System chat messages have a nil username.
|
||||||
function IsSystemChatInstruction(inst) {
|
function IsSystemChatInstruction(inst) {
|
||||||
return inst[1] == '';
|
return inst[1] == "";
|
||||||
}
|
}
|
||||||
|
|
||||||
class UserData {
|
class UserData {
|
||||||
#_name;
|
#_name;
|
||||||
#_rank;
|
#_rank;
|
||||||
|
|
||||||
constructor(name, rank) {
|
constructor(name, rank) {
|
||||||
this._name = name;
|
this._name = name;
|
||||||
this._rank = rank;
|
this._rank = rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
GetName() { return this._name; }
|
GetName() {
|
||||||
GetRank() { return this._rank; }
|
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 {
|
export default class CollabVMClient {
|
||||||
|
constructor() {
|
||||||
|
this._state = ConnectionState.CLOSED;
|
||||||
|
this._users = [];
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
GetState() {
|
||||||
this._state = ConnectionState.CLOSED;
|
return this._state;
|
||||||
this._users = [];
|
}
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
OnWebSocketOpen() {
|
||||||
this._ws = new ws.WebSocket(uri, 'guacamole', {
|
this._state = ConnectionState.CONNECTED;
|
||||||
origin: "https://computernewb.com"
|
this.OnOpen();
|
||||||
});
|
}
|
||||||
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() {
|
OnWebSocketClose() {
|
||||||
this._state = ConnectionState.CONNECTED;
|
this._state = ConnectionState.CLOSED;
|
||||||
this.OnOpen();
|
this.OnClose(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
OnWebSocketClose() {
|
OnWebSocketError() {
|
||||||
this._state = ConnectionState.CLOSED;
|
// fire the close handler
|
||||||
this.OnClose(arguments);
|
this._state = ConnectionState.CLOSED;
|
||||||
}
|
this.OnClose(arguments);
|
||||||
|
}
|
||||||
|
|
||||||
OnWebSocketError() {
|
Close() {
|
||||||
// fire the close handler
|
this._state = ConnectionState.CLOSED;
|
||||||
this._state = ConnectionState.CLOSED;
|
this._ws.close();
|
||||||
this.OnClose(arguments);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
Close() {
|
OnWebSocketMessage(ev) {
|
||||||
this._state = ConnectionState.CLOSED;
|
// cvm server should never send binary data
|
||||||
this._ws.close();
|
if (typeof ev.data !== "string") return;
|
||||||
}
|
|
||||||
|
|
||||||
OnWebSocketMessage(ev) {
|
let message = guacutils.parse(ev.data);
|
||||||
// cvm server should never send binary data
|
if (message.length === 0) return;
|
||||||
if(typeof(ev.data) !== "string")
|
|
||||||
return;
|
|
||||||
|
|
||||||
let message = guacutils.parse(ev.data);
|
// Hardcoded, we need to keep this to be alive
|
||||||
if(message.length === 0)
|
if (message[0] === "nop") {
|
||||||
return;
|
this.SendGuacamoleMessage("nop");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Hardcoded, we need to keep this to be alive
|
//if(message[0] === "chat") {
|
||||||
if(message[0] === "nop") {
|
|
||||||
this.SendGuacamoleMessage("nop");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//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[0] === "adduser") {
|
||||||
if(message[1] != this._username) {
|
this.OnAddUser(message.slice(2), parseInt(message[1]));
|
||||||
//console.log(`FUCK 2 (${message.length}) ${message[1]} ${message[2]}`)
|
return;
|
||||||
this.OnChat(message[1], message[2]);
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message[0] === "adduser") {
|
if (message[0] === "remuser")
|
||||||
this.OnAddUser(message.slice(2), parseInt(message[1]));
|
this.OnRemUser(message.slice(2), parseInt(message[1]));
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(message[0] === "remuser")
|
// Handle renames
|
||||||
this.OnRemUser(message.slice(2), parseInt(message[1]));
|
if (message[0] === "rename") {
|
||||||
|
if (message.length === 5) {
|
||||||
|
if (message[1] == "1") {
|
||||||
|
this._username = message[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handle renames
|
this.OnGuacamoleMessage(message);
|
||||||
if(message[0] === "rename") {
|
}
|
||||||
if(message.length === 5) {
|
|
||||||
if(message[1] == '1') {
|
|
||||||
this._username = message[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(`[${this.GetVM()}] user ${name} rank ${rank}`)
|
||||||
//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}`)
|
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);
|
OnRemUser(users, count) {
|
||||||
if(existingUser === undefined) {
|
for (var i = 0; i < count; i++) {
|
||||||
//console.log(`[${this.GetVM()}] New user ${name} rank ${rank}`)
|
let saveUserTemp = this.GetUser(users[i]);
|
||||||
this._users.push(new UserData(name, rank));
|
this._users = this._users.filter((user) => user.GetName() != users[i]);
|
||||||
} 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) {
|
this.OnRemUser_Bot(this.GetUserCount());
|
||||||
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 subtracts bots, including ourselves
|
||||||
}
|
GetUserCount() {
|
||||||
|
const KnownBots = [
|
||||||
|
this.GetUsername(),
|
||||||
|
//"General Darian"
|
||||||
|
// logger bots
|
||||||
|
"Specialized Egg",
|
||||||
|
"Emperor Kevin",
|
||||||
|
];
|
||||||
|
|
||||||
// This subtracts bots, including ourselves
|
var len = this._users.length;
|
||||||
GetUserCount() {
|
|
||||||
const KnownBots = [
|
|
||||||
this.GetUsername(),
|
|
||||||
//"General Darian"
|
|
||||||
// logger bots
|
|
||||||
"Specialized Egg",
|
|
||||||
"Emperor Kevin"
|
|
||||||
];
|
|
||||||
|
|
||||||
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
|
var name = this._users[i].GetName();
|
||||||
for(var i = len - 1; i != 0; --i) {
|
if (KnownBots.find((elem) => name == elem) !== undefined) {
|
||||||
// ?
|
//console.log("found blacklisted username", name)
|
||||||
if(this._users[i] === undefined)
|
len--;
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var name = this._users[i].GetName();
|
return len;
|
||||||
if(KnownBots.find(elem => name == elem) !== undefined) {
|
}
|
||||||
//console.log("found blacklisted username", name)
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return len;
|
GetUserCountFull() {
|
||||||
}
|
return this._users.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetUsers() {
|
||||||
|
this._users;
|
||||||
|
}
|
||||||
|
|
||||||
GetUserCountFull() {
|
GetUser(username) {
|
||||||
return this._users.length;
|
let existingUser = this._users.find((elem) => elem.GetName() == username);
|
||||||
}
|
|
||||||
|
|
||||||
GetUsers() {
|
// Apparently this can fail somehow..?
|
||||||
this._users;
|
if (existingUser === undefined) return null;
|
||||||
}
|
|
||||||
|
|
||||||
GetUser(username) {
|
return existingUser;
|
||||||
let existingUser = this._users.find(elem => elem.GetName() == username);
|
}
|
||||||
|
|
||||||
// Apparently this can fail somehow..?
|
GetUsername() {
|
||||||
if(existingUser === undefined)
|
return this._username;
|
||||||
return null;
|
}
|
||||||
|
|
||||||
return existingUser;
|
Rename(name) {
|
||||||
}
|
this._username = name;
|
||||||
|
this.SendGuacamoleMessage("rename", name);
|
||||||
|
}
|
||||||
|
|
||||||
GetUsername() { return this._username; }
|
GetVM() {
|
||||||
|
return this._vm;
|
||||||
|
}
|
||||||
|
|
||||||
Rename(name) {
|
ConnectToVM(vm) {
|
||||||
this._username = name;
|
this._vm = vm;
|
||||||
this.SendGuacamoleMessage("rename", name);
|
this.SendGuacamoleMessage("connect", vm);
|
||||||
}
|
}
|
||||||
|
|
||||||
GetVM() { return this._vm; }
|
SendGuacamoleMessage() {
|
||||||
|
if (this._state !== ConnectionState.CONNECTED) return;
|
||||||
ConnectToVM(vm) {
|
|
||||||
this._vm = vm;
|
|
||||||
this.SendGuacamoleMessage("connect", vm);
|
|
||||||
}
|
|
||||||
|
|
||||||
SendGuacamoleMessage() {
|
|
||||||
if(this._state !== ConnectionState.CONNECTED)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this._ws.send(guacutils.encode(Array.prototype.slice.call(arguments)));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
this._ws.send(guacutils.encode(Array.prototype.slice.call(arguments)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "AnyOSInstallBot",
|
"name": "anyosinstallbot",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Helper bot to insert media into AnyOS VMs",
|
"description": "Helper bot to insert media into AnyOS VMs",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
@ -8,5 +8,12 @@
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ws": "^8.3.0"
|
"ws": "^8.3.0"
|
||||||
|
},
|
||||||
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
|
||||||
|
"scripts": {
|
||||||
|
"format": "prettier *.js -w"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"prettier": "^3.3.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue