a try at turns (they really don't work atm)
This commit is contained in:
parent
dcc6310dd4
commit
09ce4f309e
4 changed files with 87 additions and 30 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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">
|
||||||
|
@ -28,7 +32,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<center><iframe src="https://xat.com/embed/chat.php#id=213019806&gn=computernewb" width="650" height="486" frameborder="0" scrolling="no"></iframe><br><small><a target="_BLANK" href="https://xat.com/web_gear/chat/embed.php?id=213019806&GroupName=computernewb">Get computernewb chat group</a> | <a target="_BLANK" href="https://xat.com/computernewb"> Go to computernewb website</a></small><br></center>
|
<center><iframe src="https://xat.com/embed/chat.php#id=213019806&gn=computernewb" width="650" height="486" frameborder="0" scrolling="no"></iframe><br><small><a target="_BLANK" href="https://xat.com/web_gear/chat/embed.php?id=213019806&GroupName=computernewb">Get computernewb chat group</a> | <a target="_BLANK" href="https://xat.com/computernewb"> Go to computernewb website</a></small><br></center>
|
||||||
|
|
||||||
|
|
||||||
<p style="margin-top: 30px; text-align: center; font-size: 11px; color: #666;"><small>Not</small> Powered by <a href="http://socket.io">Socket.IO (Don't use this!!)</a></p>
|
<p style="margin-top: 30px; text-align: center; font-size: 11px; color: #666;"><small>Not</small> Powered by <a href="http://socket.io">Socket.IO (Don't use this!!)</a></p>
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
@ -49,12 +58,17 @@ class client {
|
||||||
this.drawRects((message as Shared.DisplayRectMessage));
|
this.drawRects((message as Shared.DisplayRectMessage));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
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:
|
|
||||||
this.remUser((message as Shared.RemUserMessage));
|
case Shared.MessageType.RemUser:
|
||||||
break;
|
this.remUser((message as Shared.RemUserMessage));
|
||||||
|
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}`);
|
||||||
|
@ -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();
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue