a try at turns (they really don't work atm)

This commit is contained in:
Lily Tsuru 2024-04-02 20:47:55 -04:00
parent dcc6310dd4
commit 09ce4f309e
4 changed files with 87 additions and 30 deletions

View file

@ -12,6 +12,7 @@ import * as fastifyWebsocket from '@fastify/websocket';
import { WebSocket } from 'ws'; import { WebSocket } from 'ws';
import Queue from 'mnemonist/queue.js'; import Queue from 'mnemonist/queue.js';
import { kMaxUserNameLength } from '@socketcomputer/shared';
// for the maximum socket.io experience // for the maximum socket.io experience
const kCanvasJpegQuality = 0.25; const kCanvasJpegQuality = 0.25;
@ -29,7 +30,6 @@ class VMUser {
this.connection.on('message', async (data, isBinary) => { this.connection.on('message', async (data, isBinary) => {
if (!isBinary) this.connection.close(1000); if (!isBinary) this.connection.close(1000);
await this.vm.OnWSMessage(this, data as Buffer); await this.vm.OnWSMessage(this, data as Buffer);
}); });
@ -91,6 +91,14 @@ class TurnQueue extends EventEmitter {
if (this.queue.size == 1) this.nextTurn(); 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() { private turnInterval() {
this.turnTime--; this.turnTime--;
if (this.turnTime < 1) { if (this.turnTime < 1) {
@ -107,15 +115,19 @@ class TurnQueue extends EventEmitter {
this.interval = setInterval(() => this.turnInterval(), 1000); 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 // removes the front of the quuee
let arr = this.queue.toArray().slice(1); let arr = this.queue.toArray();
let arr2: Array<userAndTime> = arr.map((u, index) => { let arr2: Array<userAndTime> = arr.map((u, index) => {
let time = this.turnTime * 1000;
if(index != 0) {
time = this.turnTime * 1000 + ((index - 1) * (kTurnTimeSeconds * 1000))
}
return { return {
user: u, user: u,
time: this.turnTime * 1000 + (index - 1) * (kTurnTimeSeconds * 1000) time: time
}; };
}, this); }, this);
@ -148,6 +160,20 @@ class VirtualMachine extends EventEmitter {
console.log(`[VM] about to expire!`); console.log(`[VM] about to expire!`);
}); });
this.queue.on('turnQueue', (arr: Array<userAndTime>) => {
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) => { this.vm.on('statechange', async (state: VMState) => {
if (state == VMState.Started) { if (state == VMState.Started) {
@ -160,13 +186,12 @@ class VirtualMachine extends EventEmitter {
}); });
this.queue.on('turnQueue', (arr: Array<userAndTime>) => { this.queue.on('turnQueue', (arr: Array<userAndTime>) => {
// TODO! SERIALIZE TURN QUEUE!
console.log("Turn queue", arr); console.log("Turn queue", arr);
for (let entry of arr) { for (let entry of arr) {
entry.user.SendMessage((encoder: Shared.MessageEncoder) => { entry.user.SendMessage((encoder: Shared.MessageEncoder) => {
// painnnnnnnnnnnnnnnnnnn fuck i should just make a dynamic buffer system lol // 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 ? // pain ?
encoder.SetTurnSrvMessage( encoder.SetTurnSrvMessage(
@ -216,11 +241,10 @@ class VirtualMachine extends EventEmitter {
} }
async RemUser(user: VMUser) { async RemUser(user: VMUser) {
// TODO: erase from turn queue (once we have it) wired up
console.log(user.username, 'left.'); console.log(user.username, 'left.');
this.users.splice(this.users.indexOf(user), 1); this.users.splice(this.users.indexOf(user), 1);
this.queue.TryRemove(user);
// bye-bye! // bye-bye!
await this.BroadcastMessage((encoder: Shared.MessageEncoder) => { await this.BroadcastMessage((encoder: Shared.MessageEncoder) => {
@ -232,9 +256,11 @@ class VirtualMachine extends EventEmitter {
async OnWSMessage(user: VMUser, message: Buffer) { async OnWSMessage(user: VMUser, message: Buffer) {
try { 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) { } catch (err) {
// get out // get out
console.log("FUCK!", err);
user.connection.close(); user.connection.close();
return; return;
} }

View file

@ -22,17 +22,17 @@ html, body {
#xp-window { #xp-window {
/*cursor: none; /* let windows do that ;) */ /*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%; background-size: 100% 100%;
width: 690px; width: 690px;
height: 460px; height: 460px; */
margin: auto; margin: auto;
text-align: center; text-align: center;
} }
.xp-image, .xp-image img, .xp-image canvas { .xp-image, .xp-image img, .xp-image canvas {
width: 500px; /*width: 500px;
height: 375px; height: 375px;*/
display: inline-block; display: inline-block;
} }

View file

@ -9,12 +9,16 @@
</head> </head>
<body> <body>
<p style="text-align: center; font-size: 12px; color: #999;">Click the screen to request a turn and control the computer!</p> <p style="text-align: center; font-size: 12px; color: #999;">Click the screen to request a turn and control the computer!</p>
<div id="xp-window"> <div id="xp-window">
<canvas id="xp-canvas" width="800" height="600"></canvas>
<!-- maybe for nostalgia i can unfuck this but I don't care to
<div class="xp-image"> <div class="xp-image">
<canvas id="xp-canvas" width="800" height="600"></canvas> <canvas id="xp-canvas" width="800" height="600"></canvas>
</div> </div>
-->
</div> </div>
<div style="height: 15px;" class="turn-timer"></div> <div style="height: 15px;" class="turn-timer"></div>
<div class="user-count-wrapper"> <div class="user-count-wrapper">

View file

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