Commit Graph

9 Commits

Author SHA1 Message Date
Evan 5e7317a818 Update socket rate limiting (#3447)
## Description:

On replays, there can be a burst of traffic from hashes, so instead just
have a 2MB limit per client for the entire game. Also the winner message
can be 100s of kb on a large game with many players, so now we don't
need to put a special case for that.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
2026-03-16 20:26:56 -07:00
evanpelle f6167d2d94 allow 3 send winner msgs, in case a client reconnects 2026-03-14 11:30:12 -07:00
Evan 5fb7f75f3d Server-side WebSocket message rate limiting & size enforcement (#3424)
## Description:

* Adds ClientMsgRateLimiter — a per-client token-bucket rate limiter
that gates all incoming WebSocket messages. Returns "ok", "limit"
(drop), or "kick" based on the violation type.

* Intent messages are capped at 500 bytes each (they are stored in turn
history for the game duration, so oversized intents
accumulate in server RAM). Violations kick the client.

* Winner messages bypass the byte rate limit (they include stats for all
players and can be 100s of KB) but are strictly capped at one per client
— a second winner message kicks the client.

* All other messages go through the standard per-second (10/s) and
per-minute (150/min) rate limits. Violations drop the message; byte
budget exhaustion kicks the client.

* WebSocket maxPayload set to 2 MB on game workers.
Invalid (unparseable) messages now immediately kick the client rather
than being silently dropped.
Unit tests added for all rate limiting behaviors.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
2026-03-13 21:15:10 -07:00
Josh Harris 05af154b58 feat(server): add health api endpoint for increased observability (#3264)
## Description:

Adds an additional API endpoint to the server for health, using the
master lobby service as the health metric. The master lobby service is
considered healthy if the lobby service has started (i.e. it had enough
ready workers to start), and the current amount of ready workers is more
than half of the desired number.

This means that we won't show as healthy until all the workers start,
and then we will continue to show as healthy even if a few workers
crash, as long as at least more than half are still running. Any less
than that, and the service becomes unhealthy.

This also is set to "no cache" in the nginx config. This is to ensure
that any checks of the server health show the true value, and cannot
show false/stale data served by nginx, cloudflare, or anything else.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

jish
2026-02-21 16:52:47 -06:00
Himansu Rawal 8aa3e26e70 feat: Prevent GameServer from restarting after ending by introducin… (#2923)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #(issue number)
#2919 


In GameManager.tick(), when a game becomes active but hasn't started, a
setTimeout for game.start() is scheduled with a 2-second delay. If the
game finishes or is cancelled within those 2 seconds, game.end() is
called, which clears the existing interval. However:

1.The 2-second timeout still fires. game.start() executes.
2. A NEW setInterval is created for turn execution.
3.Since the game is already ending/finished, it's removed from
GameManager.games, but the interval continues to run forever in the
background


## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

codimo
2026-01-20 19:54:57 -08:00
Himansu Rawal e1d31ef1ee fix: replace setInterval with recursive setTimeout in Master.ts to pr… (#2869)
If this PR fixes an issue, link it below. If not, delete these two
lines.
Resolves #2868 

## Description:

This PR addresses a critical memory leak in the Master server process
(causing ~30GB RAM usage).

The issue was caused by `setInterval` calling `fetchLobbies()` every
100ms. When `fetchLobbies` took longer than 100ms to complete (due to
network latency or load), requests would pile up indefinitely, creating
a massive queue of pending Promises and open sockets.

I have refactored the polling logic into a generic `startPolling`
utility (in `src/server/PollingLoop.ts`) that uses a recursive
`setTimeout` pattern. This ensures that the next `fetchLobbies` call is
only scheduled *after* the previous one has completed (successfully or
failed), preventing any request pile-up.

## Please complete the following:

- [x] I have added screenshots for all UI updates (N/A - backend only)
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file (N/A - no user facing text)
- [x] I have added relevant tests to the test directory
(`tests/PollingLoop.test.ts`)
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

codimo
2026-01-14 09:50:43 -08:00
evanpelle 584fa9fb5d add support for custom colors (#2103)
## Description:

Added a colors tab in territory patterns modal so players can select
their color.

Refactored the PrivilegeChecker, removed custom flag checks since we no
longer support custom flags.

<img width="479" height="345" alt="Screenshot 2025-09-27 at 5 01 17 PM"
src="https://github.com/user-attachments/assets/ad96da65-f0eb-4731-a861-e6e5fcb4566a"
/>
## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
2025-10-09 20:47:20 -07:00
evanpelle 00668dd924 Remove role based perms, fetch cosmetics.json from api (#1640)
## Description:

* Fetch cosmetics.json from api
* Remove all role based perms, we are only using flares now
* Created Priviledge refresher which periodically polls /cosmetics.json
endpoint.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I have read and accepted the CLA agreement (only required once).

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
2025-08-04 16:48:41 -07:00
Aotumuri 4dd6c9bac3 custom flag (2) (#1303)
## Description:

This PR implements the permission check logic.

Other related parts will be handled in a separate UI update.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
- [x] I understand that submitting code with bugs that could have been
caught through manual testing blocks releases and new features for all
contributors
2025-07-03 00:24:52 +00:00