A validate pass alone does not unstick SteamCMD when it lands in state 0x6
with BytesToDownload=0 and a TargetBuildID newer than buildid: Steam never
schedules a depot fetch. Verified manually that deleting appmanifest_298740.acf
forces a clean reconciliation and a full re-validate that actually downloads
the missing depot. The handler now retries with the manifest removed when the
first pass leaves a pending target.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Steam was reaching state 0x6 with BytesToDownload=0, a known stuck-mid-update
pattern that resolves when SteamCMD is told to validate. Also stop relying on
the "Success!" stdout marker, which is missing in many real successes — compare
the buildid in appmanifest before and after instead.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The mmmaxwwwell SE image calls steamcmd with +login before +force_install_dir,
which Steam rejects ("Please use force_install_dir before logon!"), so container
restarts never actually update the game. The new handler runs SteamCMD in a
sibling one-shot container with the correct argument order, mounting the same
volumes as the live container, then leaves the server stopped for the operator
to start. The version cache is invalidated after a successful update so the UI
shows the new build immediately.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reads the SteamCMD appmanifest_298740.acf via SSH and exposes
buildid + LastUpdated through a new /api/servers/:id/version endpoint.
The overview tab now renders a "Server Version" card and surfaces a
pending update hint when TargetBuildID differs from the installed build.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bisher: 7d JWT im localStorage. Jeder 403 loggte den User aus — auch "Insufficient
permissions"-Responses fuer Background-Requests — wodurch User sich effektiv taeglich
neu einloggen mussten.
Backend:
- Neue refresh_tokens Tabelle (SHA256-gehasht, mit Rotation + Revoke)
- /auth/refresh tauscht Refresh-Token gegen frischen Access-Token (rotiert beide)
- /auth/logout revoked den Refresh-Token
- Access-Token-TTL auf 15m; Guest-Refresh 7d, Discord-Refresh 90d
- Daily cleanup-Job fuer abgelaufene/revoked Tokens
Frontend:
- api.js refreshed bei 401 automatisch (single-flight) und retryt die Anfrage
- 403 wird nicht mehr als Session-Ablauf behandelt
- Discord-Callback + Guest-Login liefern beide Tokens
- App.jsx synced React-State per gsm_token_refreshed CustomEvent
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Unreachable cards now show a disabled 'Starten' button so moderator cards
stay the same height as reachable ones
- Dashboard hides unreachable servers by default; a toggle button (bottom
of header area, only visible when unreachable count > 0) flips the view
and persists the preference in localStorage
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Use real SE dedicated log patterns:
- Join: 'OnConnectedClient <Name> attempt'
- Leave: 'User left <Name>' (successful) / 'User left [<steamid>]' (failed attempt)
Unresolved leaves pop the oldest pending entry so failed connection attempts
don't stick in the player list.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Integrates Space Engineers dedicated server (docker+wine on 192.168.2.78) into GSM:
- config.json entry with docker runtime and log-based player detection
- getSpaceEngineersPlayers() parses docker logs for connect/disconnect events
- Extends type-check sites in rcon, autoshutdown, discordBot, servers routes
- Frontend ServerCard/ServerDetail logo + address wiring
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Switched Minecraft server from All the Mods 10 to Biohazard: Project Genesis
(Beta 0.4.5, MC 1.20.1 + Forge 47.4.0). Updated server name, Discord bot
display, frontend modpack link, and documentation.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add findSteamCmd() helper that searches common locations
- Provide path hints per server type as fallback
- Remove hardcoded paths, more robust for different setups
- Check /usr/games/steamcmd, ~/steamcmd/, ~/Steam/ etc.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Create generic SteamCMD handler factory for reusable update logic
- Check build IDs via appmanifest files and Steam API
- Support V Rising (1829350), Palworld (2394010), Zomboid (380870), tModLoader (1281930)
- Show update button for all supported server types in UI
- Minecraft, OpenTTD, Hytale marked as manual-update-only
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Container status 'created' means it was never started yet (e.g. after
docker create during update), so it should show as offline.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replaced emoji icons with actual server logos from gsm.zeasy.dev
as embed thumbnails for a more professional look.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Superadmins can now send custom update messages to Discord directly from
the Dashboard via a new modal with server type selection, title template,
description, and color picker.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed detection pattern from "hat das Spiel verlassen" to "ist weg"
to match actual Terraria server log format.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add getTerrariaPlayers function in ssh.js for PM2 log parsing
- Support German and English join/leave messages
- Update rcon.js to use Terraria log parsing
- Add Terraria to player fetch conditions in servers.js
- Update autoshutdown.js and discordBot.js for Terraria support
- Update config path to tModLoader directory
- Add global error handlers in server.js
- Update CLAUDE.md with deployment rules and Terraria info
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add hytale to serverDisplay config with icon 🏰 and color
- Fix fetchServerStatuses to get players for Hytale (no RCON)
- Enables player join/leave alerts for Hytale
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add server.type === 'hytale' check to player count API routes,
matching the fix in autoshutdown.js.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Hytale uses log parsing instead of RCON, so add explicit check for
server.type === 'hytale' to enable player count checking.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Join: [World|*] Player 'Name' joined world ... (UUID)
- Leave: [PlayerSystems] Removing player 'Name (Name)' from world ... (UUID)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add getHytalePlayers function to ssh.js that parses server logs
- Track player joins via [Universe|P] Adding player pattern
- Track disconnects via Removing player pattern
- Integrate with rcon.js getPlayers and getPlayerList functions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace regex-based tokenization with character-by-character parsing
to completely avoid issues with numbers in CSS class names.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add missing "hytale" entry to SERVER_JOBS in prometheus.js
- Fix config editor regex bug that was corrupting CSS class names (e.g. text-cyan-400 becoming text-cyan-<span>400</span>)
- Use placeholder tokens to prevent numbers regex from matching inside already-replaced spans
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add Node Exporter target for Hytale server (10.0.30.204:9100)
- Add Hytale config read/write functions to ssh.js
- Add GET/PUT /hytale/config API routes
- Create HytaleConfigEditor.jsx with JSON syntax highlighting
- Add Hytale config tab to ServerDetail.jsx
- Add stopCmd and port to Hytale server config
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add tmux runtime support to ssh.js (status, start, stop, logs, uptime)
- Add Hytale server configuration to config.json
- Add Hytale server info and logo to frontend (ServerCard, ServerDetail)
- Add Hytale emoji to Discord notification mapping
- Update documentation with Hytale server details
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Changed logs state initialization from empty string to null to properly
distinguish between "not yet loaded" and "loaded but empty" states.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The number regex was applied after the boolean regex, causing it to
match "400" in CSS class names like "text-orange-400" and corrupt
the HTML output. Now uses placeholder tokens to mark numbers before
adding any HTML tags.
Affected editors: Palworld, Zomboid, OpenTTD
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adds POST /api/servers/discord/send-update endpoint that allows
superadmins to send announcements to all Discord guild update channels.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Database files should not be in version control as they contain
production data that gets overwritten on each deployment.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add ConfirmModal component for stop/restart confirmations
- Add start/stop/restart buttons to ServerCard (moderator/admin only)
- Add confirmation dialogs to ServerDetail for stop/restart actions
- Add btn-sm CSS class for smaller buttons
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add isGuest flag to UserContext
- Block guests from navigating to /server/:id route
- Make ServerCards non-clickable for guests
- Add rejectGuest middleware to backend
- Protect server detail endpoints (/:id, /metrics/history, /whitelist)
Guests can now only view the dashboard overview without accessing
individual server details.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Gray out unreachable servers with 50% opacity
- Disable click interaction for unreachable servers
- Show "Nicht erreichbar" badge
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Deploy backend to /opt/gameserver-monitor/backend/ (not root)
- Deploy frontend to /opt/gameserver-monitor/frontend/dist/
- Run PM2 restart from backend directory with --update-env
- Add proper PM2 process check before restart
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>