summaryrefslogtreecommitdiff
path: root/server/src/server.ts
diff options
context:
space:
mode:
authorElizabeth Hunt <elizabeth.hunt@simponic.xyz>2023-08-23 19:44:59 -0600
committerElizabeth Hunt <elizabeth.hunt@simponic.xyz>2023-08-23 19:44:59 -0600
commitdec7b614d895a1b507137e4a96a8999ff63aa179 (patch)
tree827437755bf9674db51818ee59d919c74a4ea2fc /server/src/server.ts
parentd64ffb5016119e54f0e20d05ae8ac9c96955d9d5 (diff)
downloadjumpstorm-dec7b614d895a1b507137e4a96a8999ff63aa179.tar.gz
jumpstorm-dec7b614d895a1b507137e4a96a8999ff63aa179.zip
holy fuck we actually got somewhere
Diffstat (limited to 'server/src/server.ts')
-rw-r--r--server/src/server.ts162
1 files changed, 116 insertions, 46 deletions
diff --git a/server/src/server.ts b/server/src/server.ts
index 713d3ed..b3eb1ea 100644
--- a/server/src/server.ts
+++ b/server/src/server.ts
@@ -1,109 +1,179 @@
import { Game } from "@engine/Game";
-import { Floor, Player } from "@engine/entities";
+import { EntityNames, Player } from "@engine/entities";
+import { WallBounds, Physics, Collision, NetworkUpdate } from "@engine/systems";
import {
- WallBounds,
- Physics,
- Collision,
- NetworkUpdate,
- MessageQueueProvider,
- MessagePublisher,
-} from "@engine/systems";
+ type MessageQueueProvider,
+ type MessagePublisher,
+ MessageType,
+ type MessageProcessor,
+ type Message,
+} from "@engine/network";
+import { stringify, parse } from "@engine/utils";
import { Grid } from "@engine/structures";
import { Miscellaneous } from "@engine/config";
import { Server } from "bun";
+const SERVER_PORT = 8080;
+const SERVER_TICK_RATE = (1 / 100) * 1000;
+const GAME_TOPIC = "game";
+
+type SessionData = { sessionId: string };
+
+interface ServerMessage extends Message {
+ sessionData: SessionData;
+}
+
class ServerSocketMessageReceiver implements MessageQueueProvider {
- private messages: any[];
+ private messages: ServerMessage[];
constructor() {
this.messages = [];
}
- addMessage(message: any) {
+ public addMessage(message: ServerMessage) {
this.messages.push(message);
}
- getNewMessages() {
+ public getNewMessages() {
return this.messages;
}
- clearMessages() {
+ public clearMessages() {
this.messages = [];
}
}
+class ServerMessageProcessor implements MessageProcessor {
+ constructor() {}
+
+ public process(_message: ServerMessage) {}
+}
+
class ServerSocketMessagePublisher implements MessagePublisher {
- private server: Server;
- private messages: any[];
+ private server?: Server;
+ private messages: Message[];
+
+ constructor(server?: Server) {
+ if (server) {
+ this.server = server;
+ }
- constructor(server: Server) {
- this.server = server;
this.messages = [];
}
- addMessage(_message: any) {}
+ public setServer(server: Server) {
+ this.server = server;
+ }
+
+ public addMessage(message: Message) {
+ this.messages.push(message);
+ }
- publish() {}
+ public publish() {
+ this.messages.forEach(
+ (message) => this.server?.publish(GAME_TOPIC, stringify(message)),
+ );
+
+ this.messages = [];
+ }
}
const game = new Game();
const messageReceiver = new ServerSocketMessageReceiver();
+const messagePublisher = new ServerSocketMessagePublisher();
+const messageProcessor = new ServerMessageProcessor();
+const sessionControllableEntities: Map<string, Set<string>> = new Map();
-const server = Bun.serve<{ sessionId: string }>({
- port: 8080,
- fetch: async (req, server): Promise<string> => {
- const sessionId = crypto.randomUUID();
-
- server.upgrade(req, {
- headers: {
- "Set-Cookie": `SessionId=${sessionId}`,
- },
- data: {
- sessionId,
- },
- });
-
- return sessionId;
+const server = Bun.serve<SessionData>({
+ port: SERVER_PORT,
+ fetch: async (req, server): Promise<Response> => {
+ const url = new URL(req.url);
+
+ const headers = new Headers();
+ headers.set("Access-Control-Allow-Origin", "*");
+
+ if (url.pathname == "/assign") {
+ const sessionId = crypto.randomUUID();
+ headers.set("Set-Cookie", `SessionId=${sessionId};`);
+
+ return new Response(sessionId, { headers });
+ }
+
+ const cookie = req.headers.get("cookie");
+ if (!cookie) {
+ return new Response("No session", { headers, status: 401 });
+ }
+
+ const sessionId = cookie.split(";").at(0)!.split("SessionId=").at(1);
+
+ if (url.pathname == "/game") {
+ headers.set(
+ "Set-Cookie",
+ `SessionId=${sessionId}; HttpOnly; SameSite=Strict;`,
+ );
+ server.upgrade(req, {
+ headers,
+ data: {
+ sessionId,
+ },
+ });
+
+ return new Response("upgraded", { headers });
+ }
+ if (url.pathname == "/me") {
+ return new Response(sessionId, { headers });
+ }
+
+ return new Response("Not found", { headers, status: 404 });
},
websocket: {
open(ws) {
const { sessionId } = ws.data;
if (sessionControllableEntities.has(sessionId)) {
+ // no need to add player
return;
}
- const player = new Player();
+ const player = new Player(sessionId);
game.addEntity(player);
-
sessionControllableEntities.set(sessionId, new Set(player.id));
+
+ messagePublisher.addMessage({
+ type: MessageType.NEW_ENTITY,
+ body: {
+ entityName: EntityNames.Player,
+ args: { playerId: sessionId },
+ },
+ });
+
+ ws.subscribe(GAME_TOPIC);
},
message(ws, message) {
- console.log(JSON.parse(message));
- messageReceiver.addMessage(message);
+ if (typeof message == "string") {
+ const receivedMessage = parse<ServerMessage>(message);
+ receivedMessage.sessionData = ws.data;
+
+ messageReceiver.addMessage(receivedMessage);
+ }
},
- close(ws) {},
+ close(_ws) {},
},
});
-const messagePublisher = new ServerSocketMessagePublisher(server);
+messagePublisher.setServer(server);
[
new Physics(),
new Collision(new Grid()),
new WallBounds(Miscellaneous.WIDTH),
- new NetworkUpdate(messageReceiver, messagePublisher),
+ new NetworkUpdate(messageReceiver, messagePublisher, messageProcessor),
].forEach((system) => game.addSystem(system));
-[new Floor(160), new Player()].forEach((entity) => game.addEntity(entity));
-
game.start();
-
setInterval(() => {
game.doGameLoop(performance.now());
-}, Miscellaneous.SERVER_TICK_RATE);
-
-const sessionControllableEntities: Map<string, Set<string>> = new Map();
+}, SERVER_TICK_RATE);
console.log(`Listening on ${server.hostname}:${server.port}`);