-
-
Notifications
You must be signed in to change notification settings - Fork 35
Expand file tree
/
Copy pathCHANGELOG
More file actions
418 lines (347 loc) · 35.8 KB
/
Copy pathCHANGELOG
File metadata and controls
418 lines (347 loc) · 35.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
-- update - 2026.09.10
- fix(updaters): Decouple CounterStrikeSharp from auto-enabling MetaMod updates. If MetaMod is disabled (`INSTALL_METAMOD=0`) while CSS is active (`INSTALL_CSS=1`), the egg now logs a warning instead of forcing `INSTALL_METAMOD=1` and overwriting custom/pinned MetaMod builds. If MetaMod is present in `game/csgo/addons/metamod`, it is loaded into `gameinfo.gi` without triggering the auto-updater.
-- update - 2026.08.06
- security(centralized): Update soak window. A new version is recorded as pending and only installs once it has stayed on the branch, byte for byte unchanged, for `UPDATE_SOAK_SECONDS` (default 12h), leaving time to pull a bad release before it reaches any host. Keyed on SHA-256, not the version header, so a swapped body cannot inherit an elapsed timer. `--update` is the only bypass, on purpose: a marker inside the file would be set by whoever published it
- feat(doctor): Reports the pending version and the time left on its window
- fix(doctor): Stale-daemon detection compares the version the daemon logged at startup, not file timestamps. mtime lied both ways: a self-update keeps the download's mtime, any edit bumps it
- fix(centralized): A self-update verifies the daemon came back on the new script, retries once, then reports it loudly. The restart's exit code was trusted, so a daemon on old code stayed silent until `--doctor`
- fix(installer): The installer fetches through a cache-busting URL, so an install right after a release stages the current script
- fix(centralized): `--update` bypasses the raw.githubusercontent edge cache too. Busting is opt-in per command (`--update`, `--test`, `--doctor`); the cron check keeps a cacheable URL
- refactor(updaters): Release fetch, JSON guard, version compare and the up-to-date logging were copy-pasted across all four addon updaters. Now shared via `fetch_release`, `needs_update` and `run_updater`; ModSharp drops its hand-rolled API call for `github_release_json`. Same behaviour, ~180 fewer lines
- refactor(centralized): The update-check rate limit is stamped once instead of at eight early returns, where missing one disabled it silently
- test: New suites for the soak window, the shared updater helpers and the daemon version read. `--test` runs all of them
- chore(test): Suites moved to `misc/tests/`. `--test` on a host running an older script fails until it self-updates; `--doctor` is unaffected
-- update - 2026.08.04
- feat(test): New daemon-side units for the push lock (dead-owner and pid-less locks stolen, live owner waited out), the duplicate worker guard, the daemon instance lock and the symlinked lock directory scan
- fix(daemon): Only one worker per server is started now - a reconcile sweep and a real docker event both fire on a restart, and the second worker overwrote the first one's registry entry, so whichever finished first unregistered the other and its status stopped being refreshed (the egg then fell back to SteamCMD mid-push)
- fix(centralized): `--test` and `--doctor` bypass the raw.githubusercontent edge cache (a timestamp query), so a self-test or a branch check right after a push no longer runs against a file that is minutes old. Self-update keeps the plain URL: it runs from cron on every host and unique URLs would bypass the CDN entirely
- fix(doctor): The broken-symlink check no longer counts VPK links pointing at another mount (e.g. a separate community-addons mount) - those resolve only inside the container, so healthy servers were reported as having broken symlinks
- fix(daemon): VPK links whose source a CS2 update removed are pruned from the volumes on both the push and the verify path - the egg skips its own broken-link cleanup while the daemon is authoritative, so they piled up over updates and showed as "broken VPK symlink(s)" in `--doctor` [#58]
- feat(daemon): Starting `--daemon` while one is already running now reports on it (pid, uptime, script version, pushes in flight) instead of failing, and points at `--daemon restart`
- feat(daemon): New `--daemon restart` waits for in-flight pushes to finish (up to 5 min), then cycles the systemd service and verifies it came back up
- fix(daemon): Daemon mode takes a host-wide instance lock and refuses to start next to a running daemon - a hand-started second instance wiped the running daemon's worker registry and both then fought over the same push locks [#58]
- fix(daemon): A push lock whose owner is gone is now stolen instead of waited out - a worker killed by a service restart (or any lock left by a script older than 1.0.53, which carried no owner pid) used to park every later worker for that server on "queued", so the server waited for game files forever and never fell back to SteamCMD [#58]
- fix(doctor): The orphaned-lock cleanup never ran on Debian/Ubuntu - `/var/lock` is a symlink to `/run/lock` there and `find` does not descend into it without `-H`, so weeks-old locks survived every doctor run while the summary still reported "Everything looks healthy" [#58]
- fix(daemon): Push workers now handle SIGTERM/SIGINT/SIGHUP, so a daemon restart no longer leaks the per-container lock directory (bash skips the EXIT trap when a signal kills the shell) [#58]
- fix(daemon): The wait for a free worker pool slot is capped at 1h and reports failed - it was the last unbounded wait, and the status refresher kept it invisible to both the egg and the doctor [#58]
- fix(doctor): Stuck-status detection now measures time spent in the state (the worker's enqueue stamp) instead of the refreshed timestamp, which is bumped every 3s for as long as the worker lives - a server blocked on a busy lock was reported as a healthy "push in progress" [#58]
-- update - 2026.07.23
- feat(daemon): One-way status file protocol replaces the delete-and-wait marker handshake - the daemon writes `egg/.daemon-status` (queued/updating/verifying/pushing/done/failed + timestamp + queue position) and the egg only reads it, so the boot race that could trigger a full ~33GB SteamCMD redownload on loaded hosts can no longer happen (#56)
- feat(daemon): Boot acknowledgement - the egg accepts done/failed only if written after its own boot, so a restart during a CS2 update waits for a fresh verify instead of starting on files mid-replacement
- feat(daemon): Central update lock - server restarts while steamcmd rewrites the shared CS2_DIR now show "Central CS2 update in progress" and wait for it to finish; verify/push and the update can never see each other's half-written trees
- feat(daemon): Queue visibility - on a saturated worker pool the server console shows a live queue position instead of silently timing out into a SteamCMD fallback
- feat(daemon): Startup/reconnect reconcile - the daemon sweeps all running servers after a restart or a dropped docker event stream, so boots whose event was missed still get verified and acknowledged
- feat(daemon): Script version is logged at daemon startup, so journalctl shows exactly which version is running
- feat(centralized): New `--test` flag downloads the boot-handshake protocol test suite from GitHub (same branch as self-update), runs it and cleans up - quick sanity check for support and prerelease testing
- feat(centralized): New `--doctor` flag - full health check (script/service/cron paths, daemon state vs on-disk version, dependencies, kernel, disk space, per-server status files, orphaned locks, update source) with safe auto-fixes (daemon restart on stale code, orphaned lock cleanup, duplicate crontab entry removal); troubleshooting docs now lead with it
- fix(daemon): A crashed push worker now flips the status to failed - the egg falls back to SteamCMD immediately instead of hanging on a dead push
- fix(daemon): A worker no longer gives up when the per-container push lock is busy (e.g. cron is pushing the same volume) - it waits for the lock while keeping the egg's status fresh
- fix(centralized): VPK verify got stricter - hardlink mode now requires inode identity and copy mode checks mtime in addition to size, so an update that changed a VPK's content but not its size is re-pushed instead of leaving the server on stale files
- fix(centralized): Wings restart error path produced a garbage HTTP code on curl failure (`\n` was never expanded), making the failure log misleading
- feat(egg): Faster dead-daemon detection - a stale status file (no refresh for 20s) triggers the SteamCMD fallback in ~20s instead of 30+
- feat(egg): Sanity check on daemon handoff - if the daemon reports ready but not a single VPK is readable (e.g. dangling symlinks after a failed mount), the egg falls back to SteamCMD instead of starting a crashing server (KL-DMN-04)
- fix(egg): Legacy grace period - the compat marker lands instantly while the worker's first status write takes ~1-2s, so the bare marker only counts after ~5s without a status file; prevents a false "host script outdated" warning and keeps the boot acknowledgement authoritative on new-script hosts
- feat(egg): Broken VPK symlinks (leftovers of a lost daemon setup) are cleaned before the SteamCMD fallback runs, so SteamCMD rebuilds into a clean tree
- feat(egg): Standalone servers (no daemon on the host) skip most of the boot wait - with an established install and zero daemon evidence the egg proceeds after ~5s instead of the full window
- feat(centralized): Self-update survives a deleted testing branch - a confirmed 404 on the configured branch (e.g. dev after merge) switches the script back to main automatically
- fix(centralized): CS2_DIR permissions preserve exec bits (u=rwX,go=rX) instead of blanket 755 that marked every game file executable
- fix(centralized): Wings restart API calls got connect/max timeouts, so a hanging Wings can't stall the update run
- fix(centralized): Script re-execs itself with sudo when started as a normal user, instead of failing halfway with confusing permission errors
- feat(centralized): New `--update` flag self-updates the script immediately from the configured branch (daemon restarts automatically), without running a CS2 update
- fix(daemon): Worker cleanup trap could abort on the push path (locals already gone when it fired), leaking the per-container lock and a pool slot - servers then waited on "queued" forever
- feat(daemon): Push locks record their owner pid, so `--doctor` removes a dead-owner lock instantly instead of waiting for the 2h age rule
- fix(daemon): Volume file ownership now follows the volume's actual owner (numeric uid:gid) instead of a hardcoded pterodactyl:pterodactyl - on Pelican hosts pushed files (e.g. gameinfo.gi) stayed root-owned and in-container addon updaters failed with Permission denied until a second restart [#56]
- feat(test): The centralized script is now sourceable, so `--test` also unit-tests daemon-side pieces: dynamic volume-owner detection everywhere, and the status writers (atomicity + terminal state never resurrected) on Linux hosts
- fix(updaters): GitHub API rate limiting (shared node IP) is now detected and reported clearly - the addon update check is skipped for that boot and the installed version keeps running, instead of feeding the error response into the parser
- fix(sync): Legacy cfg sync counter was stuck at 0 (pipe subshell), the "Synced N config file(s)" message never appeared
- fix(install): SteamCMD extract no longer spams the console with the full file listing
- docs(error-codes): New KL-DMN-03 (daemon reported failed push) and KL-DMN-04 (ready but no readable VPK) entries; stable anchors for every code (log links now jump to the right section) and retired notes on KL-DMN-01/02
- docs(vpk-sync): New "Boot Handshake" section documenting the status file protocol; legacy marker files remain supported until 2026-10-01
-- update - 2026.07.21
- fix(centralized): Auto-restart works on Pelican Panel - the Wings config is now looked up at `/etc/pelican/config.yml` too, and a new `WINGS_CONFIG` setting points at a custom `--config` path if Wings runs from somewhere else (#55)
-- update - 2026.07.11
- feat(daemon): Worker pool for file pushes - heavy pushes now run on parallel workers (new MAX_WORKERS setting, default 8) while symlink mounts stay instant, so mass-starting dozens of servers no longer stalls the event loop and falls back to SteamCMD downloads (#51)
- feat(daemon): Push heartbeat - a server boot now keeps waiting while a daemon push is actively running instead of giving up after 30s, so SteamCMD can never write the same game tree concurrently with a long push
- feat(installer): MAX_WORKERS is asked in the install wizard and preserved across reinstalls and script self-updates
- feat(installer): CS2_EGG_BRANCH override installs from any branch (e.g. dev) and points self-update at the same branch, so testers can run prereleases without being pulled back to stable
- feat(cleanup): New delete_parent_dir rule option removes whole leaf bundle folders, and default rules now clean SwiftlyS2 crash data after a week: loose .dmp files and <uuid>/ bundles in crashreport/ (keyed on minidump age since SwiftlyS2 regenerates crashinfo.json every boot) plus prevention/incident.\*.log files
- feat(config): Cleanup rule migration now merges by rule name, so new default rules reach existing servers on config bump while your customized and custom rules stay untouched
- fix(swiftlys2): Version file is only bumped after a successful copy - a failed copy (full disk, IO error) now retries on next boot instead of silently keeping a corrupted install forever
- fix(updaters): MetaMod and CounterStrikeSharp copy failures now log an error and skip the version bump instead of reporting success
- fix(updaters): GitHub release-info requests got proper timeouts - an unreachable api.github.com no longer hangs server boot for minutes
- fix(config): Config migration keeps the freshly generated config when the settings merge fails instead of overwriting it with an empty file (user settings were silently lost)
- fix(logging): Warning-level messages were dropped when console_level was set to WARNING due to a missing priority mapping
- fix(centralized): Update run no longer dies mid-flight when no server container is running
- fix(centralized): A failed push on one volume no longer aborts the whole run - healthy servers still get their files and restart
- fix(centralized): Cron push and daemon self-heal now share the same per-container lock, so the two can never write one volume at the same time
- fix(centralized): Self-update stages the new script next to the installed one, making the final replace an atomic rename - a crash mid-update can no longer leave a half-written script behind
- fix(centralized): Config validation reports every error at once, not just the first one
- fix(entrypoint): SRCDS_VALIDATE handled safely when unset; steamclient.so copy skipped when SteamCMD never produced it
- fix(installer): Script download is staged and syntax-checked before replacing the live script, so a dropped connection can't leave a truncated script for cron to execute
- refactor(centralized): Removed the live-tail display and the no-op post-update health check + rollback (~170 lines); SteamCMD error hints (0x202 disk space etc.) moved into the spinner's failure output
- refactor(centralized): Shared helpers for container matching and volume lookup, deduplicated simulate/real update flow, byte formatting via numfmt
- refactor(docker): Removed dead code - unused check_version() and check_filesystem(), redundant config version pre-pass, macOS stat branch, unused INTERNAL_IP + iproute2 package, unreachable updater availability guards, log priority cache
- refactor(update): ModSharp updater is invoked like the other updaters (direct function call instead of a bash subprocess)
-- update - 2026.04.21
- feat(cleanup): Cleanup is fully customizable now: add, disable, or retarget rules per directory, pattern, and age right in `cleanup.json`. No code edit needed.
- feat(centralized): New `--validate` flag runs a one-shot SteamCMD file check without changing your saved config.
- feat(installer): Daemon installer re-asks if you mistype yes/no instead of quietly aborting.
- feat(logging): Cleaner log output: level tag in a fixed column (`INFO`, `OK`, `WARN`, `ERROR`, `DEBUG`), message colored per severity.
- feat(logging): Every fatal error now prints a short code with a docs link. Skim the new error reference instead of scrolling the log.
- feat(logging): Your Steam account token is automatically hidden from every log line, not just the startup command.
- fix(daemon): First-boot race fixed: the egg no longer accidentally triggers a full SteamCMD download while the daemon is still pushing game files.
- fix(daemon): If the central daemon goes down, servers recover cleanly on the next restart and rebuild from SteamCMD instead of crashing on missing files.
- fix(daemon): Wait-for-daemon messages only appear when the wait actually lasts longer than a couple of seconds, fast starts stay quiet.
- fix(centralized): Permissions on pushed game files are correct again (files stay at 644, not marked as executable). Prevents Pterodactyl's file manager from flagging them as anomalies.
- fix(centralized): SteamCMD-only directories (`Steam/`, `steamapps/`) are no longer pushed into server volumes, they served no runtime purpose and were getting deleted each boot.
- fix(entrypoint): `VALIDATE_INSTALL=1` always shows the "may wipe configs" warning and waits 5 seconds before running, giving you time to stop the server and cancel.
- fix(entrypoint): SteamCMD failures no longer print the same error line twice.
- fix(cleanup): Core dump files at the container root are now cleaned up alongside the ones in the game binary directory.
- docs(error-codes): New reference page (`docs/advanced/error-codes.md`) lists every egg error code with symptom, cause, and fix.
- docs(cleanup): New guide (`docs/features/cleanup.md`) with custom rule examples: longer demo retention, per-plugin log sweeps, and how to disable a rule without losing it.
-- update - 2026.04.15
- fix(update_helper): Local SteamCMD installs were misdetected as daemon-managed → updates silently disabled and steamcmd dir deleted on restart. Detection rewritten to mount + heartbeat marker (10min TTL).
- feat(centralized): Daemon writes .daemon-managed marker before sync and on every container start event - reliable signal for all push methods (symlink/hardlink/copy).
-- update - 2026.04.14
- feat: Pelican panel support
- feat(modsharp): admins.jsonc preserved across updates (backup + restore alongside core.json)
- feat(centralized): Installer script (install-cs2-update.sh) - guided wizard, systemd daemon setup, cron registration, auto troubleshoot
- feat(centralized): AUTO_RESTART_SERVERS default changed to true
- feat(centralized): UPDATE_CHECK_INTERVAL default changed to \* (every cron run, rate-limited by script)
- feat(metamod): Switched to GitHub releases, always uses prerelease channel (CS2 builds)
- feat(metamod): GitHub mirror fallback (ghproxy.net, gh.llkk.cc) for restricted regions. This is for Asian community with love who reported their issue!
- feat(updater): All GitHub downloads automatically try mirrors on failure (1 attempt per source).
- feat(cleanup): steamcmd, steamapps, Steam directories removed when game files are externally managed (saves ~200MB+)
- refactor(update_helper): SteamCMD auto-removed from container when daemon VPKs confirmed accessible
- deprecation(sync): SYNC_LOCATION support marked for removal 2026-10-01
- docs(vpk-sync): Rewritten around installer script, storage savings table, push methods, lock behavior
- docs(readme): Added Centralized Update & VPK Sync section with installer one-liner
-- update - 2026.02.12
- fix(gdb): Replaced background gdbserver --attach with Valve's native GAME_DEBUGGER env var
- fix(gdb): Suspend/breakpoints now work without SYS_PTRACE Docker capability
- fix(gdb): gdbserver launches cs2 as parent process instead of attaching externally
-- update - 2026.02.05
- fix: Update ModSharp directory paths for consistency in backup and restore operations
-- update - 2025.12.19
- feat(cleanup): Enhance core dump deletion to include numbered core files
-- update - 2025.12.16
- feat(cleanup): Core dump cleanup added (~2.2 GB disk space freed per restart)
- feat(egg): Startup detection changed to "Source2Init OK" for better ModSharp compatibility
- refactor(modsharp): ModSharp updater optimized from 297 to 158 lines (-46.8% code reduction)
- refactor(modsharp): Direct GitHub API integration for multiple asset downloads (core + extensions)
- refactor(modsharp): Uses common handle_download_and_extract() utility for consistency
- refactor(modsharp): Removed duplicate get_latest_modsharp_release() function
- refactor(modsharp): Removed unnecessary install_modsharp() wrapper function
- refactor(modsharp): Fixed extraction paths (core → /game/, extensions → /game/sharp/shared/)
- refactor(modsharp): Config backup/restore centralized (core.json preservation)
- optimise(updater): TEMP_DIR centralized in updater_common.sh (DRY principle applied)
- optimise(updater): Removed redundant TEMP_DIR declarations from all updater scripts
-- update - 2025.11.28
- feat(updater): Added PRERELEASE egg variable to allow downloading prerelease/beta versions from GitHub
- feat(updater): New centralized get_github_release() function in updater_common.sh
- fix(swiftlys2): Update now properly overwrites bin/ and gamedata/ directories (was using cp -rn which never updated existing files)
- feat(cleanup): Added SwiftlyS2 logs cleanup (/game/csgo/addons/swiftlys2/logs/\*.log)
- optimise(docker): Removed unused packages from Dockerfile (cron, mawk)
-- update - 2025.11.20
- feat(centralized): Multi-registry support for container detection (Docker Hub + GHCR)
- feat(centralized): SERVER_IMAGE now accepts multiple images separated by spaces or commas
- feat(centralized): Container list display before restart for better visibility
- fix(centralized): Container restart iteration failing after first container with set -e
- upgrade(modsharp): Updated .NET runtime from 9.0.0 to 10.0.0
-- update - 2025.11.19
- feat(entrypoint): Added GDB remote debugging support with automatic process attachment
- feat(egg): Added GDB_DEBUG_PORT variable for IDA Pro and GDB client integration
- feat(entrypoint): Automatic CS2 process detection and gdbserver initialization on specified port
- docs: Added comprehensive GDB debugging documentation with IDA Pro setup guide
- docs: Documented server lock behavior and remote debugging workflow
-- update - 2025.11.14
- feat(centralized): Wings API integration for seamless Pterodactyl server restarts
- feat(centralized): Automatic SSL/non-SSL detection from Wings configuration
- feat(centralized): --simulate flag to test restart logic without downloading CS2 updates
- feat(centralized): Only restarts running servers (stopped servers remain stopped intentionally)
- feat(build): GitHub Container Registry (ghcr.io) publishing support with unlimited pulls
- feat(build): -g/--ghcr flag for GitHub Container Registry, -a/--all for both registries
- feat(build): Pre-build validation for shell script syntax and source dependencies
- feat(egg): Hidden PREFIX_TEXT variable to customize log prefix text (default: KitsuneLab)
- feat(entrypoint): Automatic crash detection with troubleshooting guide for common issues
- refactor(build): Changed -P flag to -d/--dockerhub for explicit registry selection
- refactor(build): Replaced emoji symbols with simple text symbols for consistency
- refactor(egg): Default Docker image changed to GitHub Container Registry (ghcr.io/k4ryuu/cs2-egg)
- optimise(build): Credential caching for GHCR (no repeated authentication needed)
- optimise(build): Logging output compacted and cleaner structured
- optimise(config): Config templates use $CONFIG_VERSION variable instead of hardcoded versions
- optimise(config): Migration checks version once and logs once (removed CONFIG_CHANGES tracking)
- optimise(config): Centralized smart_merge function eliminates 150 lines of duplicated code
- optimise(cleanup): Platform detection cached at startup (50% fewer uname system calls)
- optimise(filter): Exact pattern matching uses O(1) hash lookup instead of iteration
- optimise(filter): Separated blocking and masking patterns for faster processing
- optimise(logging): Log level priority cached and reused (20% faster log message filtering)
- optimise(update_helper): Auto-cleanup obsolete configs (auto-restart.json, webhook.json) on new egg detection
- remove(config): Removed unused logging config fields (file_level, colors.enabled, colors.use_emoji)
- fix(config): Bumped config version to 1.0.1 to trigger migration for updated logging.json structure
- fix(config): Migration preserves only fields that exist in new template (deleted fields stay deleted)
- fix(logging): Console log level from logging.json now properly applied (was always INFO regardless of config)
- docs: Updated VPK sync documentation with Wings API details and simulate mode usage
- docs: Added Docker registry comparison (Docker Hub vs GitHub pull rate limits)
- docs: Installation guide updated with registry selection and pull limit details
- docs: Added hidden variables documentation (PREFIX_TEXT, ALLOW_TOKENLESS) to configuration guide
-- update - 2025.11.13
- feat(centralized): Automatic self-update from GitHub with validation and rollback (enabled by default)
- feat(centralized): Preserves user configuration during self-update (paths, settings auto-transferred)
- feat(centralized): Input validation for paths and configurations (security hardening)
- feat(centralized): Lock file mechanism to prevent concurrent execution (cron-safe)
- feat(centralized): Optional validate flag for faster updates (disabled by default)
- feat(centralized): Versioned backup system (keeps last 3 versions for rollback)
- feat(centralized): Automatic SteamCMD dependency installation (i386 + 32-bit libraries)
- feat(centralized): Multi-distro support with fallback logic (Ubuntu 18.04+, Debian 10+)
- feat(centralized): Intelligent SteamCMD error detection with contextual help (0x202 and more later)
- feat(centralized): Health check system validates prerequisites before installation
- feat(centralized): Spinner animation for blocking operations (package install, container restarts)
- feat(centralized): Version-based update detection (replaces hash comparison for config independence)
- refactor(centralized): Uses SteamCMD native version checking (removed Steam API dependency)
- refactor(centralized): Uses Docker native commands for server restarts (removed Pterodactyl API)
- refactor(centralized): Finds all containers matching image name regardless of tag/branch
- refactor(centralized): Comprehensive error handling with detailed output on failures
- optimise(centralized): Reduced verbose logging (replaced repetitive messages with comments)
- remove(centralized): No longer requires curl, jq, or Pterodactyl API credentials (simpler setup)
- fix(centralized): Nested command substitution causing corrupted version files and duplicate logs
- fix(centralized): Argument list overflow from corrupted version file
- fix(centralized): Argument list overflow when restarting many servers
- fix(centralized): Dependency installation return logic causing premature exit on success
- fix(centralized): apt-get update failures silently ignored after i386 architecture addition
- fix(centralized): Hash comparison falsely detecting updates due to user config differences
-- update - 2025.11.12
- feat: Multi-framework support with independent boolean toggles per addon
- feat: Added ModSharp as standalone addon with .NET 9 runtime auto-installation
- feat: Migrated to SwiftlyS2 v2 (standalone, no MetaMod dependency)
- feat: Smart Docker image cleanup in build script (only removes replaced images)
- feat: Centralized gameinfo.gi management preserving all configured addons
- feat: MetaMod load order enforcement (always first after LowViolence)
- feat: SwiftlyS2 load order enforcement (always last before Game csgo for ModSharp compatibility)
- feat: ModSharp + SwiftlyS2 compatibility via automatic load order management
- feat: Added ALLOW_TOKENLESS hidden variable for RequireLoginForDedicatedServers patching
- refactor: Code restructure with centralized updater functions (~320 lines eliminated)
- refactor: Standardized logging and version management across all updaters
- upgrade: Enhanced addon selection with descriptive standalone options
- upgrade: All scripts now read-only (555 permissions) for security
- upgrade: MetaMod auto-enabled with warning when CSS is selected
- remove: Obsolete per-addon AUTOUPDATE variables and old Swiftly v1 option
- remove: ADDON_SELECTION dropdown (deprecated, backwards compatible until next patch)
- fix: Version file operations and duplicate migration messages
- fix: Multiple addons now coexist properly in gameinfo.gi SearchPaths
- fix: VPK sync now excludes gameinfo.gi to preserve addon configurations
-- update - 2025.11.07
- feat: Introduced organized /egg/ directory structure for all egg-related files
- feat: Implemented FTP-editable JSON configuration system with 5 config files
- feat: Added config version migration system with automatic backup and smart merge
- feat: Replaced environment variables with JSON configs for auto-restart, webhook, filter, cleanup, and logging
- feat: Implemented API-based version checking via api.steamcmd.net (non-blocking, fast)
- feat: Added Pterodactyl API integration for automatic server restart
- feat: Introduced daily log rotation with triple limits (size, count, age)
- feat: Created automatic legacy file migration system (update_helper.sh)
- refactor: Moved auto-restart configuration from ~10 environment variables to single JSON file
- refactor: Consolidated all configs into /egg/configs/ directory (FTP accessible)
- refactor: Complete rewrite of docker/utils/config.sh with version management
- refactor: Simplified Pterodactyl egg variables from ~20 to ~8 (60% reduction)
- refactor: Switched add-on selection values to descriptive labels (more readable Panel UI)
- refactor: Unified update control under AUTO_UPDATE (replaces UPDATE_AUTO_RESTART)
- upgrade: Enhanced auto-restart system with client API token support
- optimise: Replaced unbuffer (expect) with stdbuf for console piping (~1.2MB compressed saving)
- optimise: Switched awk dependency from gawk to mawk to reduce image size (~3-4MB compressed saving)
- remove: Deleted redundant steamcmd_version_check.sh (merged into version.sh)
- remove: Removed 12+ legacy environment variables (migrated to JSON configs)
- remove: Removed expect package from Docker image (no longer needed after stdbuf switch)
- security: API tokens now user-configurable via FTP (not environment)
- security: Removed default API token values from egg to prevent extraction
- security: Implemented per-user API token system (not shared across servers)
- security: Added automatic GSLT token masking in logs
- docs: Updated 15+ documentation pages for new configuration system
- docs: Created comprehensive troubleshooting guide with new scenarios
- docs: Created detailed configuration files reference documentation
- fix: Fixed entrypoint.sh syntax error with sed regex escaping
-- update - 2025.04.29
- feat: Replaced separate toggles for MetaMod and CounterStrikeSharp with a unified "Server Add-ons" dropdown
- feat: Added support for Swiftly as a server add-on option
- feat: Server add-ons now offer four options as None, Metamod Only, Metamod + CounterStrikeSharp, Metamod + Swiftly
-- update - 2025.03.27
- feat: Added support for the new CounterStrikeSharp versioning schema
- feat: Added support for with-runtime and without runtime installs
-- update - 2024.11.28
- feat: Added SteamCMD installed, which useful for centralized file systems or to repair user deletions
- fix: Update validated the game files forcefully
- fix: Udpdate broke after a SteamCMD function update
- fix: Egg log file was not used properly by the logger
- upgrade: Steam version checker to prevent caching
-- update - 2024.11.21 - Optimisation Update
- feat: Junk cleaner now shows the freed space, duration and overall counter
- feat: Message filter now supports @prefix for exact pattern matching
- feat: Message filter now displays detailed pattern load statistics on startup
- feat: Patterns can now have replacement values for masking sensitive data
- optimise: Update system now has centralized download and extract handling
- optimise: Changed to startup only log cleanup for better performance
- optimise: Junk cleaner now uses a better way to find and eliminate the files
- optimise: Removed some redundant validations
- optimise: Message filter now processes patterns only once during initialization
- optimise: Pattern matching now uses hash maps for faster lookups
- optimise: Message filter now has early return for empty messages
- optimise: Added retry mechanism for downloads with proper error handling
- optimise: Version checking is now centralized and more efficient
- optimise: Improved file operations with less I/O usage
- optimise: Replaced awk with sed for better performance
- optimise: Muted unnecessary file operation outputs
- optimise: Junk cleaner wont show the exact deleted files except in debug mode for less I/O operations
- optimise: Steam token masking is now integrated into the pattern system
- fix: Metamod gameinfo update issues
- fix: All values have now a default value to prevent issues by missing variables
- fix: Added proper error handling and signal management
-- update - 2024.11.18
- feat: Added option to save egg logs to a file with a 48-hour rotation
- feat: Added option to change the log level for console and file log messages
- upgrade: Allowed the countdown command to be empty
- remove: Removed some redundant code
-- update - 2024.11.17
- feat: Add environment default value setter to ensure required variables are maintained
- chore: Auto-Restart game version checker now uses different file
- chore: Changed max slot number to 64
- chore: Changed Auto-Restart API KEY to match the correct length
- fix: Auto-Restart now initialize game version to file if not present
- fix: Prevent Auto-Restart from validating during countdown if an update is in progress
- remove: Unused source include in this version of the egg
-- update - 2024.11.16
- fix: The Steam token mask removed other matching patterns aswell from being visible
- fix: Removed maxplayers_override from startup as its deprecated
-- update - 2024.11.15
- feat: Added Auto-Restart feature to automatically restart the server if it has a newer version
- feat: The console now censures the Steam Token of the user for security reasons (sending logs, screenshots, etc.)
- upgrade: Changed MetaMod auto-updater to use GitHub aswell due to some users had issues calling alliedmods.net
- refactor: The full script has been refactored for easier maintanaibility
- chore: Changed some of the variable rules to use boolean
- chore: Changed some of the variables naming and descriptions for better understanding
-- update - 2024.10.02
- fix: Round backup cleaner removed some other files
-- update - 2024.08.20
- fix: Server shutdown was handled like Segmentation fault
- fix: Server shown crash state and no answer dialog instead of kicking users
-- update - 2024.07.28
- feat: Added console filter to block unwanted messages (import the egg again to have it)
- feat: Added preview mode for console filter to show what messages you block exactly (import the egg again to have it)
- chore: Fix some spelling and grammar mistakes
-- update - 2024.07.24
- fix: Junk cleaner was not working at all
-- update - 2024.07.01
- feat: Added Dev branch support with tag `dev` (import the egg again to have it)
- feat: Added proper names for the images (import the egg again to have it)
- fix: Removed redundant codes at logging and coloring sections
- fix: Removed debug message leftovers at metamod updater
- fix: Removed error upon server shutdown and added a good message instead
- fix: Re-phrased some messages for better understanding
- fix: Removed cleanup messages with 0 files for less spam
-- update - 2024.06.20
- upgrade: Metamod version finder logic
- fix: Metamod updater not working correctly
- fix: Changed updaters to start the server even if the download fails
-- update - 2024.06.15
- fix: Variable name miss-matches
- fix: MetaMod files are not overwritten correctly
-- update - 2024.06.14
- fix: Issues where you was unable to disable the scripts