diff --git a/client/src/components/LandingPage.tsx b/client/src/components/LandingPage.tsx
index 81b5ff6..7cdf947 100644
--- a/client/src/components/LandingPage.tsx
+++ b/client/src/components/LandingPage.tsx
@@ -47,8 +47,7 @@ function GameTile({
let navigate = useNavigate();
const routeChange = () =>{
- let path = `game/${gameId}`;
- navigate(path);
+ navigate(gameId);
}
return
@@ -272,7 +272,7 @@ function LevelAppBar({isLoading, levelId, worldId, levelTitle}) {
return
-
+
{gameInfo.data?.worlds.nodes[worldId].title && `World: ${gameInfo.data?.worlds.nodes[worldId].title}`}
@@ -282,10 +282,10 @@ function LevelAppBar({isLoading, levelId, worldId, levelTitle}) {
{levelTitle}
diff --git a/client/src/components/Welcome.tsx b/client/src/components/Welcome.tsx
index 0c66c5b..0382b6b 100644
--- a/client/src/components/Welcome.tsx
+++ b/client/src/components/Welcome.tsx
@@ -39,7 +39,7 @@ function LevelIcon({ worldId, levelId, position }) {
// TODO: relative positioning?
return (
-
+
)
@@ -76,13 +76,13 @@ function Welcome() {
for (let i = 1; i <= gameInfo.data.worldSize[id]; i++) {
svgElements.push(
)
}
svgElements.push(
-
+
,
- // loader: () => redirect("/game/adam")
},
{
- path: "/game/:gameId",
+ path: "/g/:owner/:repo",
element:
,
errorElement:
,
children: [
{
- path: "/game/:gameId",
+ path: "/g/:owner/:repo",
element:
,
},
{
- path: "/game/:gameId/world/:worldId/level/:levelId",
+ path: "/g/:owner/:repo/world/:worldId/level/:levelId",
element:
,
},
],
diff --git a/package.json b/package.json
index 4f6fac5..a1c99c5 100644
--- a/package.json
+++ b/package.json
@@ -66,10 +66,10 @@
"start": "concurrently -n server,client -c blue,green \"npm run start_server\" \"npm run start_client\"",
"start_server": "cd server && lake build && NODE_ENV=development nodemon -e mjs --exec \"node ./index.mjs\"",
"start_client": "NODE_ENV=development webpack-dev-server --hot",
- "build": "npm run build_server && npm run build_client",
- "build_server": "server/build.sh",
- "build_client": "NODE_ENV=production webpack",
+ "build": "NODE_ENV=production webpack",
"production": "NODE_ENV=production node server/index.mjs",
+ "build_robo": "rm -rf ./Robo && git clone https://github.com/hhu-adam/Robo && docker build ./Robo --file ./Robo/Dockerfile --tag github-hhu-adam:Robo && rm -rf ./Robo",
+ "build_nng": "rm -rf ./NNG4 && git clone https://github.com/hhu-adam/NNG4 && docker build ./NNG4 --file ./NNG4/Dockerfile --tag github-hhu-adam:NNG4 && rm -rf ./NNG4",
"update_lean": "./UPDATE_LEAN.sh"
},
"eslintConfig": {
diff --git a/server/build.sh b/server/build.sh
deleted file mode 100755
index 7825db7..0000000
--- a/server/build.sh
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/usr/bin/env sh
-
-# Operate in the directory where this file is located
-cd $(dirname $0)
-
-# Build Adam
-( rm -rf adam
- git clone https://github.com/hhu-adam/Robo adam/
- cd adam
- docker rmi adam:latest || true
- docker build \
- --rm -f Dockerfile -t adam:latest .
-)
-
-# Build NNG
-( rm -rf nng
- git clone https://github.com/hhu-adam/NNG4 nng/
- cd nng
- docker rmi nng:latest || true
- docker build \
- --rm -f Dockerfile -t nng:latest .
-)
diff --git a/server/index.mjs b/server/index.mjs
index b63602e..22ce928 100644
--- a/server/index.mjs
+++ b/server/index.mjs
@@ -9,14 +9,20 @@ import os from 'os';
import anonymize from 'ip-anonymize';
import { importTrigger, importStatus } from './import.mjs'
+/** Preloaded games. The keys refer to the docker tags of the virtual machines.
+ * The number `queueLength` determines how many instances of the docker container
+ * get started before any user shows up to have them up and running immediately.
+ * The values `name`, `module`, and `dir` are just used for development where we
+ * use a project directory instead of a docker container.
+*/
const games = {
- adam: {
+ "github-hhu-adam:Robo": {
name: "Adam",
module: "Adam",
dir: "../../../../Robo",
queueLength: 5
},
- nng: {
+ "github-hhu-adam:NNG4": {
name: "NNG",
module: "NNG",
dir: "../../../../NNG4",
@@ -50,17 +56,18 @@ const isDevelopment = environment === 'development'
/** We keep queues of started Lean Server processes to be ready when a user arrives */
const queue = {}
-const queueLength = 5
-function startServerProcess(gameId) {
- const serverProcess = isDevelopment
- ? cp.spawn("./gameserver",
- ["--server", games[gameId].dir, games[gameId].module, games[gameId].name],
+function startServerProcess(tag) {
+ let serverProcess
+ if (isDevelopment && games[tag]?.dir) {
+ serverProcess = cp.spawn("./gameserver",
+ ["--server", games[tag].dir, games[tag].module, games[tag].name],
{ cwd: "./build/bin/" })
- : cp.spawn("docker",
- ["run", "--runtime=runsc", "--network=none", "--rm", "-i", `${gameId}:latest`,
- "./gameserver", "--server", "/game/", games[gameId].module, games[gameId].name],
+ } else {
+ serverProcess = cp.spawn("docker",
+ ["run", "--runtime=runsc", "--network=none", "--rm", "-i", `${tag}`],
{ cwd: "." })
+ }
serverProcess.on('error', error =>
console.error(`Launching Lean Server failed: ${error}`)
);
@@ -73,32 +80,35 @@ function startServerProcess(gameId) {
}
/** start Lean Server processes to refill the queue */
-function fillQueue(gameId) {
- while (queue[gameId].length < games[gameId].queueLength) {
- const serverProcess = startServerProcess(gameId)
- queue[gameId].push(serverProcess)
+function fillQueue(tag) {
+ while (queue[tag].length < games[tag].queueLength) {
+ const serverProcess = startServerProcess(tag)
+ queue[tag].push(serverProcess)
}
}
-for (let gameId in games) {
- queue[gameId] = []
- fillQueue(gameId)
+if (!isDevelopment) { // Don't use queue in development
+ for (let tag in games) {
+ queue[tag] = []
+ fillQueue(tag)
+ }
}
-const urlRegEx = new RegExp("^/websocket/(.*)$")
+const urlRegEx = /^\/websocket\/g\/([\w.-]+)\/([\w.-]+)$/
wss.addListener("connection", function(ws, req) {
const reRes = urlRegEx.exec(req.url)
if (!reRes) { console.error(`Connection refused because of invalid URL: ${req.url}`); return; }
- const gameId = reRes[1]
- if (!games[gameId]) { console.error(`Unknown game: ${gameId}`); return; }
+ const owner = reRes[1]
+ const repo = reRes[2]
+ const tag = `github-${owner}:${repo}`
let ps;
- if (isDevelopment) { // Don't use queue in development
- ps = startServerProcess(gameId)
+ if (!queue[tag] || queue[tag].length == 0) {
+ ps = startServerProcess(tag)
} else {
- ps = queue[gameId].shift() // Pick the first Lean process; it's likely to be ready immediately
- fillQueue(gameId)
+ ps = queue[tag].shift() // Pick the first Lean process; it's likely to be ready immediately
+ fillQueue(tag)
}
socketCounter += 1;