game-server/index.js

86 lines
2.2 KiB
JavaScript
Raw Normal View History

2025-08-25 14:33:52 -07:00
import express from "express";
import http from "http";
import { WebSocketServer } from "ws";
import cors from "cors";
import pkg from "pg";
const { Pool } = pkg;
const app = express();
const PORT = 3000;
// Setup Postgres connection pool
const pool = new Pool({
connectionString: process.env.DATABASE_URL || "neverleavetheconnectionstringhereforproduction",
});
app.use(cors());
// HTTP GET /games/:id → return game info from DB
app.get("/games/:id", async (req, res) => {
const gameId = req.params.id;
try {
const result = await pool.query("SELECT info FROM items WHERE id = $1", [gameId]);
if (result.rows.length === 0) {
return res.redirect(302, "https://engine.battlesnake.com");
// return res.status(404).json({ error: "Game not found" });
}
res.json(result.rows[0].info); // send back the JSONB field
} catch (err) {
console.error(err);
res.status(500).json({ error: "Database error" });
}
});
// Create HTTP server and attach WebSocket server
const server = http.createServer(app);
const wss = new WebSocketServer({ server });
// Helper to match the path pattern
function matchGameEventsPath(url) {
if (!url) return null;
const match = url.match(/^\/games\/([^\/]+)\/events$/);
return match ? match[1] : null;
}
wss.on("connection", async (ws, req) => {
const gameId = matchGameEventsPath(req.url);
if (!gameId) {
ws.close();
return;
}
console.log(`WS client connected for game: ${gameId}`);
try {
// Grab frames array from DB
const result = await pool.query("SELECT frames FROM items WHERE id = $1", [gameId]);
if (result.rows.length === 0) {
ws.send(JSON.stringify({ error: "Game not found" }));
ws.close();
return;
}
const frames = result.rows[0].frames || [];
// Stream frames one by one with delay
frames.forEach((frame, i) => {
setTimeout(() => {
if (ws.readyState === ws.OPEN) {
ws.send(JSON.stringify(frame));
}
}, i * 5); // staggered delay
});
} catch (err) {
console.error(err);
ws.send(JSON.stringify({ error: "Database error" }));
ws.close();
}
});
server.listen(PORT, "0.0.0.0", () => {
console.log(`Server running at http://localhost:${PORT} (HTTP + WebSocket)`);
});