From 09ce4f309ecc03c2c18a4e58e418ee1558264e83 Mon Sep 17 00:00:00 2001 From: modeco80 Date: Tue, 2 Apr 2024 20:47:55 -0400 Subject: [PATCH] a try at turns (they really don't work atm) --- backend/src/SocketComputerServer.ts | 44 +++++++++++++++++----- webapp/src/css/main.css | 8 ++-- webapp/src/index.html | 8 +++- webapp/src/index.ts | 57 +++++++++++++++++++++-------- 4 files changed, 87 insertions(+), 30 deletions(-) diff --git a/backend/src/SocketComputerServer.ts b/backend/src/SocketComputerServer.ts index 8d2d432..a176669 100644 --- a/backend/src/SocketComputerServer.ts +++ b/backend/src/SocketComputerServer.ts @@ -12,6 +12,7 @@ import * as fastifyWebsocket from '@fastify/websocket'; import { WebSocket } from 'ws'; import Queue from 'mnemonist/queue.js'; +import { kMaxUserNameLength } from '@socketcomputer/shared'; // for the maximum socket.io experience const kCanvasJpegQuality = 0.25; @@ -29,7 +30,6 @@ class VMUser { this.connection.on('message', async (data, isBinary) => { if (!isBinary) this.connection.close(1000); - await this.vm.OnWSMessage(this, data as Buffer); }); @@ -91,6 +91,14 @@ class TurnQueue extends EventEmitter { if (this.queue.size == 1) this.nextTurn(); } + public TryRemove(user: VMUser) { + if (this.queue.toArray().indexOf(user) !== -1) { + let hadTurn = (this.CurrentUser() === user); + this.queue = Queue.from(this.queue.toArray().filter(u => u !== user)); + if (hadTurn) this.nextTurn(); + } + } + private turnInterval() { this.turnTime--; if (this.turnTime < 1) { @@ -107,15 +115,19 @@ class TurnQueue extends EventEmitter { this.interval = setInterval(() => this.turnInterval(), 1000); } - if (this.queue.size == 1) this.emit('turnQueue', [{ user: this.CurrentUser(), time: kTurnTimeSeconds * 1000 }]); + //if (this.queue.size == 1) this.emit('turnQueue', [{ user: this.CurrentUser(), time: this.turnTime * 1000 }]); // removes the front of the quuee - let arr = this.queue.toArray().slice(1); + let arr = this.queue.toArray(); let arr2: Array = arr.map((u, index) => { + let time = this.turnTime * 1000; + if(index != 0) { + time = this.turnTime * 1000 + ((index - 1) * (kTurnTimeSeconds * 1000)) + } return { user: u, - time: this.turnTime * 1000 + (index - 1) * (kTurnTimeSeconds * 1000) + time: time }; }, this); @@ -148,6 +160,20 @@ class VirtualMachine extends EventEmitter { console.log(`[VM] about to expire!`); }); + this.queue.on('turnQueue', (arr: Array) => { + for(let user of arr) { + user.user.SendMessage((encoder: Shared.MessageEncoder) => { + let n = 16 + (arr.length * (2+kMaxUserNameLength)); + console.log(n) + encoder.Init(n); + encoder.SetTurnSrvMessage(user.time, arr.map((item) => { + return item.user.username; + })); + return encoder.Finish(); + }) + } + }); + this.vm.on('statechange', async (state: VMState) => { if (state == VMState.Started) { @@ -160,13 +186,12 @@ class VirtualMachine extends EventEmitter { }); this.queue.on('turnQueue', (arr: Array) => { - // TODO! SERIALIZE TURN QUEUE! console.log("Turn queue", arr); for (let entry of arr) { entry.user.SendMessage((encoder: Shared.MessageEncoder) => { // painnnnnnnnnnnnnnnnnnn fuck i should just make a dynamic buffer system lol - encoder.Init(4 + arr.length * Shared.kMaxUserNameLength); + encoder.Init(64+ arr.length * (Shared.kMaxUserNameLength)); // pain ? encoder.SetTurnSrvMessage( @@ -216,11 +241,10 @@ class VirtualMachine extends EventEmitter { } async RemUser(user: VMUser) { - // TODO: erase from turn queue (once we have it) wired up - console.log(user.username, 'left.'); this.users.splice(this.users.indexOf(user), 1); + this.queue.TryRemove(user); // bye-bye! await this.BroadcastMessage((encoder: Shared.MessageEncoder) => { @@ -232,9 +256,11 @@ class VirtualMachine extends EventEmitter { async OnWSMessage(user: VMUser, message: Buffer) { try { - this.OnDecodedMessage(user, await Shared.MessageDecoder.ReadMessage(message, false)); + let messageBuffer = message.buffer.slice(message.byteOffset); + this.OnDecodedMessage(user, await Shared.MessageDecoder.ReadMessage(messageBuffer, false)); } catch (err) { // get out + console.log("FUCK!", err); user.connection.close(); return; } diff --git a/webapp/src/css/main.css b/webapp/src/css/main.css index b570366..e65478c 100644 --- a/webapp/src/css/main.css +++ b/webapp/src/css/main.css @@ -22,17 +22,17 @@ html, body { #xp-window { /*cursor: none; /* let windows do that ;) */ - background: url(../../static/macbook.png) no-repeat center; +/* background: url(../../static/macbook.png) no-repeat center; background-size: 100% 100%; width: 690px; - height: 460px; + height: 460px; */ margin: auto; text-align: center; } .xp-image, .xp-image img, .xp-image canvas { - width: 500px; - height: 375px; + /*width: 500px; + height: 375px;*/ display: inline-block; } diff --git a/webapp/src/index.html b/webapp/src/index.html index a6b93cd..2a34a15 100644 --- a/webapp/src/index.html +++ b/webapp/src/index.html @@ -9,12 +9,16 @@

Click the screen to request a turn and control the computer!

+
+ + +
@@ -28,7 +32,7 @@


Get computernewb chat group | Go to computernewb website
- +

Not Powered by Socket.IO (Don't use this!!)

diff --git a/webapp/src/index.ts b/webapp/src/index.ts index 6a54bce..b7643f8 100644 --- a/webapp/src/index.ts +++ b/webapp/src/index.ts @@ -1,16 +1,15 @@ import * as Shared from '@socketcomputer/shared'; -type user = { +type UserRecord = { username: string - queuePos: number }; // client for -class client { +class SocketClient { private websocket: WebSocket = null; private url = ""; - private userList = new Array(); + private userList = new Array(); private canvas:HTMLCanvasElement = null; private canvasCtx : CanvasRenderingContext2D = null; @@ -31,6 +30,16 @@ class client { private onWsOpen() { console.log("client WS OPEN!!"); + + let self = this; + + this.canvas.addEventListener('click', async () => { + await self.SendMessage((enc: Shared.MessageEncoder) => { + enc.Init(4); + enc.SetTurnMessage(); + return enc.Finish(); + }); + }) } private async onWsMessage(e: MessageEvent) { @@ -49,12 +58,17 @@ class client { this.drawRects((message as Shared.DisplayRectMessage)); break; - case Shared.MessageType.AddUser: - this.addUser((message as Shared.AddUserMessage)); - break; - case Shared.MessageType.RemUser: - this.remUser((message as Shared.RemUserMessage)); - break; + case Shared.MessageType.AddUser: + this.addUser((message as Shared.AddUserMessage)); + break; + + case Shared.MessageType.RemUser: + this.remUser((message as Shared.RemUserMessage)); + break; + + case Shared.MessageType.Turn: + this.turnQueueUpdate((message as Shared.TurnServerMessage)); + break; default: console.log(`Unhandled message type ${message.type}`); @@ -66,14 +80,24 @@ class client { } private onWsClose() { - // backoff? - console.log("FUCK YOU FUCKING FUCKER GOOGLE."); + // backoff + reconnect? this.websocket.removeEventListener("open", this.onWsOpen); this.websocket.removeEventListener("message", this.onWsMessage); this.websocket.removeEventListener("close", this.onWsClose); this.websocket = null; } + async SendMessage(messageGenerator: (encoder: Shared.MessageEncoder) => ArrayBuffer) { + await this.SendBuffer(messageGenerator(new Shared.MessageEncoder())); + } + + async SendBuffer(buffer: ArrayBuffer): Promise { + return new Promise((res, rej) => { + this.websocket.send(buffer); + res(); + }); + } + private resizeDisplay(message: Shared.DisplaySizeMessage) { console.log("resizes to", message.width, message.height) this.canvas.width = message.width; @@ -87,8 +111,7 @@ class client { private addUser(message: Shared.AddUserMessage) { this.userList.push({ - username: message.user, - queuePos: -1 + username: message.user }); this.updateUserCount(); @@ -105,6 +128,10 @@ class client { this.updateUserCount(); } + private turnQueueUpdate(message: Shared.TurnServerMessage) { + console.log("turn queue", message.time, "queue", message.turnQueue); + } + private drawRects(message: Shared.DisplayRectMessage) { let blob = new Blob([message.data]); createImageBitmap(blob) @@ -119,6 +146,6 @@ class client { let globalclient = null; document.addEventListener("DOMContentLoaded", async () => { - globalclient = new client("ws://127.0.0.1:4050", document.getElementById("xp-canvas") as HTMLCanvasElement); + globalclient = new SocketClient("ws://127.0.0.1:4050", document.getElementById("xp-canvas") as HTMLCanvasElement); globalclient.connect(); })