mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:50:43 +00:00
use structed logging
This commit is contained in:
@@ -70,11 +70,14 @@
|
||||
* BUG: island don't check if inscribed, just try to remove it DONE 8/31/2024
|
||||
* if completely surrounded by same enemy, lose island DONE 8/31/2024
|
||||
* BUG: fix boat leaves trail DONE 9/1/2024
|
||||
* end game when no players left (or after 1 hour or so?)
|
||||
* use better favicon
|
||||
* BUG: tiles get left behind during conquer
|
||||
* end game when no players left (or after 1 hour or so?) DONE 9/1/2024
|
||||
* add structured logging DONE 9/1/2024
|
||||
* make attack execution stream tiles to pq
|
||||
* Create exit to menu button
|
||||
* use better favicon
|
||||
* center map on game start
|
||||
* Make fake humans
|
||||
* BUG: tiles get left behind during conquer
|
||||
* Load terrain dataImage in background
|
||||
* BUG: shore tiles left behind during conquer
|
||||
* BUG: when sending boat to TerraNullius, only takes one tile
|
||||
|
||||
Generated
+187
-5
@@ -15,6 +15,8 @@
|
||||
"colord": "^2.9.3",
|
||||
"crypto": "^1.0.1",
|
||||
"express": "^4.19.2",
|
||||
"google-auth-library": "^9.14.0",
|
||||
"googleapis": "^143.0.0",
|
||||
"jimp": "^0.22.12",
|
||||
"msgpack5": "^6.0.2",
|
||||
"node-addon-api": "^8.1.0",
|
||||
@@ -33,7 +35,7 @@
|
||||
"@types/chai": "^4.3.17",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/mocha": "^10.0.7",
|
||||
"@types/node": "^22.4.1",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/sinon": "^17.0.3",
|
||||
"@types/ws": "^8.5.11",
|
||||
"babel-jest": "^29.7.0",
|
||||
@@ -4138,9 +4140,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "22.4.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.4.1.tgz",
|
||||
"integrity": "sha512-1tbpb9325+gPnKK0dMm+/LMriX0vKxf6RnB0SZUqfyVkQ4fMgUSySqhxE/y8Jvs4NyF1yHzTfG9KlnkIODxPKg==",
|
||||
"version": "22.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.2.tgz",
|
||||
"integrity": "sha512-acJsPTEqYqulZS/Yp/S3GgeE6GZ0qYODUR8aVr/DkhHQ8l9nd4j5x1/ZJy9/gHrRlFMqkO6i0I3E27Alu4jjPg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"undici-types": "~6.19.2"
|
||||
@@ -4984,6 +4986,15 @@
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/bignumber.js": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
|
||||
"integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/binary-base64-loader": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/binary-base64-loader/-/binary-base64-loader-1.0.0.tgz",
|
||||
@@ -5204,6 +5215,12 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer-equal-constant-time": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
|
||||
"integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
@@ -6210,6 +6227,15 @@
|
||||
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
||||
},
|
||||
"node_modules/ecdsa-sig-formatter": {
|
||||
"version": "1.0.11",
|
||||
"resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
|
||||
"integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
@@ -6635,6 +6661,12 @@
|
||||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/external-editor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
|
||||
@@ -6922,6 +6954,48 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/gaxios": {
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
|
||||
"integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
"https-proxy-agent": "^7.0.1",
|
||||
"is-stream": "^2.0.0",
|
||||
"node-fetch": "^2.6.9",
|
||||
"uuid": "^9.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/gaxios/node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/gcp-metadata": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
|
||||
"integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"gaxios": "^6.0.0",
|
||||
"json-bigint": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/gensync": {
|
||||
"version": "1.0.0-beta.2",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
|
||||
@@ -7068,6 +7142,66 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/google-auth-library": {
|
||||
"version": "9.14.0",
|
||||
"resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.14.0.tgz",
|
||||
"integrity": "sha512-Y/eq+RWVs55Io/anIsm24sDS8X79Tq948zVLGaa7+KlJYYqaGwp1YI37w48nzrNi12RgnzMrQD4NzdmCowT90g==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"base64-js": "^1.3.0",
|
||||
"ecdsa-sig-formatter": "^1.0.11",
|
||||
"gaxios": "^6.1.1",
|
||||
"gcp-metadata": "^6.1.0",
|
||||
"gtoken": "^7.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/googleapis": {
|
||||
"version": "143.0.0",
|
||||
"resolved": "https://registry.npmjs.org/googleapis/-/googleapis-143.0.0.tgz",
|
||||
"integrity": "sha512-hGeNM9d9cDQAV/dm8FvdkismWIDCJRV9v11UTLq4nRPP+s/2jPuHQnpI7dR+sWmL0o3XURW0K3a3THKyDRnWVg==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"google-auth-library": "^9.0.0",
|
||||
"googleapis-common": "^7.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/googleapis-common": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/googleapis-common/-/googleapis-common-7.2.0.tgz",
|
||||
"integrity": "sha512-/fhDZEJZvOV3X5jmD+fKxMqma5q2Q9nZNSF3kn1F18tpxmA86BcTxAGBQdM0N89Z3bEaIs+HVznSmFJEAmMTjA==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"extend": "^3.0.2",
|
||||
"gaxios": "^6.0.3",
|
||||
"google-auth-library": "^9.7.0",
|
||||
"qs": "^6.7.0",
|
||||
"url-template": "^2.0.8",
|
||||
"uuid": "^9.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/googleapis-common/node_modules/uuid": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
||||
"funding": [
|
||||
"https://github.com/sponsors/broofa",
|
||||
"https://github.com/sponsors/ctavan"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
@@ -7084,6 +7218,19 @@
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
"integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="
|
||||
},
|
||||
"node_modules/gtoken": {
|
||||
"version": "7.1.0",
|
||||
"resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
|
||||
"integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"gaxios": "^6.0.0",
|
||||
"jws": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/handle-thing": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz",
|
||||
@@ -7817,7 +7964,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
@@ -8904,6 +9050,15 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/json-bigint": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
|
||||
"integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bignumber.js": "^9.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/json-parse-even-better-errors": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
|
||||
@@ -8934,6 +9089,27 @@
|
||||
"integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/jwa": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
|
||||
"integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-equal-constant-time": "1.0.1",
|
||||
"ecdsa-sig-formatter": "1.0.11",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/jws": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jws/-/jws-4.0.0.tgz",
|
||||
"integrity": "sha512-KDncfTmOZoOMTFG4mBlG0qUIOlc03fmzH+ru6RgYVZhPkyiy/92Owlt/8UEN+a4TXR1FQetfIpJE8ApdvdVxTg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"jwa": "^2.0.0",
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/kind-of": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||
@@ -12535,6 +12711,12 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/url-template": {
|
||||
"version": "2.0.8",
|
||||
"resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
|
||||
"integrity": "sha512-XdVKMF4SJ0nP/O7XIPB0JwAEuT9lDIYnNsK8yGVe43y0AWoKeJNdv3ZNWh7ksJ6KqQFjOO6ox/VEitLnaVNufw==",
|
||||
"license": "BSD"
|
||||
},
|
||||
"node_modules/utif2": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/utif2/-/utif2-4.1.0.tgz",
|
||||
|
||||
+3
-1
@@ -17,7 +17,7 @@
|
||||
"@types/chai": "^4.3.17",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/mocha": "^10.0.7",
|
||||
"@types/node": "^22.4.1",
|
||||
"@types/node": "^22.5.2",
|
||||
"@types/sinon": "^17.0.3",
|
||||
"@types/ws": "^8.5.11",
|
||||
"babel-jest": "^29.7.0",
|
||||
@@ -56,6 +56,8 @@
|
||||
"colord": "^2.9.3",
|
||||
"crypto": "^1.0.1",
|
||||
"express": "^4.19.2",
|
||||
"google-auth-library": "^9.14.0",
|
||||
"googleapis": "^143.0.0",
|
||||
"jimp": "^0.22.12",
|
||||
"msgpack5": "^6.0.2",
|
||||
"node-addon-api": "^8.1.0",
|
||||
|
||||
+54
-15
@@ -27,6 +27,8 @@ class Client {
|
||||
|
||||
private random = new PseudoRandom(1234)
|
||||
|
||||
private ip: Promise<string | null> = null
|
||||
|
||||
constructor() {
|
||||
this.lobbiesContainer = document.getElementById('lobbies-container');
|
||||
}
|
||||
@@ -35,6 +37,7 @@ class Client {
|
||||
setFavicon()
|
||||
this.terrainMap = loadTerrainMap()
|
||||
this.startLobbyPolling()
|
||||
this.ip = getClientIP()
|
||||
setupUsernameCallback((username) => {
|
||||
console.log('Username updated:', username);
|
||||
if (this.game != null) {
|
||||
@@ -100,7 +103,7 @@ class Client {
|
||||
}
|
||||
}
|
||||
|
||||
private joinLobby(lobby: Lobby) {
|
||||
private async joinLobby(lobby: Lobby) {
|
||||
const lobbyButton = document.getElementById('lobby-button');
|
||||
if (lobbyButton) {
|
||||
this.isLobbyHighlighted = !this.isLobbyHighlighted;
|
||||
@@ -115,21 +118,26 @@ class Client {
|
||||
if (this.game != null) {
|
||||
return;
|
||||
}
|
||||
this.terrainMap.then(tm => {
|
||||
this.game = createClientGame(getUsername(), new PseudoRandom(Date.now()).nextID(), lobby.id, getConfig(), tm);
|
||||
this.game.join();
|
||||
const g = this.game;
|
||||
window.addEventListener('beforeunload', function (event) {
|
||||
console.log('Browser is closing');
|
||||
g.stop();
|
||||
});
|
||||
})
|
||||
const [terrainMap, clientIP] = await Promise.all([
|
||||
this.terrainMap,
|
||||
this.ip
|
||||
]);
|
||||
console.log(`got ip ${clientIP}`)
|
||||
this.game = createClientGame(
|
||||
getUsername(),
|
||||
new PseudoRandom(Date.now()).nextID(), // TODO this can cause dup ids
|
||||
clientIP,
|
||||
lobby.id,
|
||||
getConfig(),
|
||||
terrainMap
|
||||
);
|
||||
this.game.join();
|
||||
const g = this.game;
|
||||
window.addEventListener('beforeunload', function (event) {
|
||||
console.log('Browser is closing');
|
||||
g.stop();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
function getUsername(): string {
|
||||
@@ -154,6 +162,37 @@ function setupUsernameCallback(callback: (username: string) => void): void {
|
||||
}
|
||||
|
||||
|
||||
async function getClientIP(timeoutMs: number = 1000): Promise<string | null> {
|
||||
const controller = new AbortController();
|
||||
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
||||
|
||||
try {
|
||||
const response: Response = await fetch('https://api.ipify.org?format=json', {
|
||||
signal: controller.signal
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data: {ip: string} = await response.json();
|
||||
return data.ip;
|
||||
} catch (error) {
|
||||
if (error instanceof Error) {
|
||||
if (error.name === 'AbortError') {
|
||||
console.error('Request timed out');
|
||||
} else {
|
||||
console.error('Error fetching IP:', error.message);
|
||||
}
|
||||
} else {
|
||||
console.error('An unknown error occurred');
|
||||
}
|
||||
return null;
|
||||
} finally {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Initialize the client when the DOM is loaded
|
||||
|
||||
@@ -12,7 +12,7 @@ import {TerrainRenderer} from "./graphics/TerrainRenderer";
|
||||
|
||||
|
||||
|
||||
export function createClientGame(name: string, clientID: ClientID, gameID: GameID, config: Config, terrainMap: TerrainMap): ClientGame {
|
||||
export function createClientGame(name: string, clientID: ClientID, ip: string | null, gameID: GameID, config: Config, terrainMap: TerrainMap): ClientGame {
|
||||
let eventBus = new EventBus()
|
||||
let game = createGame(terrainMap, eventBus, config)
|
||||
let terrainRenderer = new TerrainRenderer(game)
|
||||
@@ -21,6 +21,7 @@ export function createClientGame(name: string, clientID: ClientID, gameID: GameI
|
||||
return new ClientGame(
|
||||
name,
|
||||
clientID,
|
||||
ip,
|
||||
gameID,
|
||||
eventBus,
|
||||
game,
|
||||
@@ -47,6 +48,7 @@ export class ClientGame {
|
||||
constructor(
|
||||
public playerName: string,
|
||||
private id: ClientID,
|
||||
private clientIP: string | null,
|
||||
private gameID: GameID,
|
||||
private eventBus: EventBus,
|
||||
private gs: Game,
|
||||
@@ -67,6 +69,7 @@ export class ClientGame {
|
||||
type: "join",
|
||||
gameID: this.gameID,
|
||||
clientID: this.id,
|
||||
clientIP: this.clientIP,
|
||||
lastTurn: this.turns.length
|
||||
})
|
||||
)
|
||||
|
||||
+2
-2
@@ -114,9 +114,9 @@ export const ClientIntentMessageSchema = ClientBaseMessageSchema.extend({
|
||||
export const ClientJoinMessageSchema = ClientBaseMessageSchema.extend({
|
||||
type: z.literal('join'),
|
||||
clientID: z.string(),
|
||||
clientIP: z.string().nullable(),
|
||||
gameID: z.string(),
|
||||
// The last turn the client saw.
|
||||
lastTurn: z.number()
|
||||
lastTurn: z.number() // The last turn the client saw.
|
||||
})
|
||||
|
||||
export const ClientLeaveMessageSchema = ClientBaseMessageSchema.extend({
|
||||
|
||||
@@ -3,5 +3,9 @@ import {ClientID} from '../core/Schemas';
|
||||
|
||||
|
||||
export class Client {
|
||||
constructor(public readonly id: ClientID, public readonly ws: WebSocket) { }
|
||||
constructor(
|
||||
public readonly id: ClientID,
|
||||
public readonly ip: string | null,
|
||||
public readonly ws: WebSocket
|
||||
) { }
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import {ClientMessage, ClientMessageSchema, Intent, ServerStartGameMessage, Serv
|
||||
import {Config} from "../core/configuration/Config";
|
||||
import {Client} from "./Client";
|
||||
import WebSocket from 'ws';
|
||||
import {slog} from "./StructuredLog";
|
||||
|
||||
|
||||
export enum GamePhase {
|
||||
@@ -30,6 +31,12 @@ export class GameServer {
|
||||
|
||||
public addClient(client: Client, lastTurn: number) {
|
||||
console.log(`game ${this.id} adding client ${client.id}`)
|
||||
slog('client_joined_game', `client ${client.id} (re)joining game ${this.id}`, {
|
||||
clientID: client.id,
|
||||
clientIP: client.ip,
|
||||
gameID: this.id,
|
||||
isRejoin: lastTurn > 0
|
||||
})
|
||||
// Remove stale client if this is a reconnect
|
||||
this.clients = this.clients.filter(c => c.id != client.id)
|
||||
this.clients.push(client)
|
||||
|
||||
@@ -8,6 +8,7 @@ import {Client} from './Client';
|
||||
import {ClientMessage, ClientMessageSchema} from '../core/Schemas';
|
||||
import {GamePhase} from './GameServer';
|
||||
import {getConfig} from '../core/configuration/Config';
|
||||
import {LogSeverity, slog} from './StructuredLog';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@@ -31,11 +32,10 @@ app.get('/lobbies', (req, res) => {
|
||||
wss.on('connection', (ws) => {
|
||||
|
||||
ws.on('message', (message: string) => {
|
||||
console.log(`got message ${message}`)
|
||||
const clientMsg: ClientMessage = ClientMessageSchema.parse(JSON.parse(message))
|
||||
slog('websocket_msg', 'server received websocket message', clientMsg, LogSeverity.DEBUG)
|
||||
if (clientMsg.type == "join") {
|
||||
console.log('got join request')
|
||||
gm.addClient(new Client(clientMsg.clientID, ws), clientMsg.gameID, clientMsg.lastTurn)
|
||||
gm.addClient(new Client(clientMsg.clientID, clientMsg.clientIP, ws), clientMsg.gameID, clientMsg.lastTurn)
|
||||
}
|
||||
// TODO: send error message
|
||||
})
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
export enum LogSeverity {
|
||||
DEBUG = 'DEBUG',
|
||||
INFO = 'INFO',
|
||||
WARN = 'WARN',
|
||||
ERROR = 'ERROR',
|
||||
FATAL = 'FATAL'
|
||||
}
|
||||
|
||||
export function slog(eventType: string, description, data: any, severity = LogSeverity.INFO): void {
|
||||
const logEntry = {
|
||||
eventType: eventType,
|
||||
description: description,
|
||||
severity: severity,
|
||||
data: data
|
||||
};
|
||||
if (process.env.GAME_ENV == 'dev') {
|
||||
console.log(description)
|
||||
} else {
|
||||
console.log(JSON.stringify(logEntry));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user