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 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<userAndTime> = 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<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) => {
if (state == VMState.Started) {
@ -160,13 +186,12 @@ class VirtualMachine extends EventEmitter {
});
this.queue.on('turnQueue', (arr: Array<userAndTime>) => {
// 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;
}

View file

@ -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;
}

View file

@ -9,12 +9,16 @@
</head>
<body>
<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">
<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">
<canvas id="xp-canvas" width="800" height="600"></canvas>
</div>
-->
</div>
<div style="height: 15px;" class="turn-timer"></div>
<div class="user-count-wrapper">

View file

@ -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<user>();
private userList = new Array<UserRecord>();
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<void> {
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();
})