From 3829a4a83d800e81a8bb3a5fe2cd7cde13079259 Mon Sep 17 00:00:00 2001 From: Frank Harris Date: Mon, 8 Jun 2026 16:09:54 -0500 Subject: [PATCH] worshop work --- .../SERVER_CONTENT_WORKSHOP_PHASE1.md | 19 +++---- .../workshop/generic_steam_workshop_linux.sh | 19 ++++--- .../generic_steam_workshop_windows_cygwin.sh | 19 ++++--- .../addonsmanager/server_content_helpers.php | 15 +++--- .../tests/workshop_helpers_test.php | 21 ++++---- README.md | 12 +++++ docs/AGENT_COMMUNICATION.md | 28 ++++++++++ docs/ARCHITECTURE.md | 45 ++++++++++++++++ docs/COMMAND_FLOW.md | 27 ++++++++++ docs/PANEL_ARCHITECTURE.md | 26 +++++++++ docs/REPOSITORY_STRUCTURE.md | 27 ++++++++++ docs/UPDATE_POLICY.md | 28 ++++++++++ docs/agents/LINUX_AGENT.md | 9 ++-- docs/agents/WINDOWS_AGENT.md | 9 ++-- docs/architecture/AI_GSP_ARCHITECTURE.md | 2 + docs/architecture/API_REFERENCE.md | 9 ++-- docs/architecture/LIBRARY_REFERENCE.md | 2 + docs/architecture/MODULE_DEPENDENCIES.md | 2 + docs/architecture/PANEL_AGENT_COMMANDS.md | 7 ++- docs/architecture/PANEL_AGENT_FLOW.md | 3 +- docs/architecture/REPOSITORY_OVERVIEW.md | 2 + docs/architecture/RPC_STATUS_REPAIR_REPORT.md | 2 + docs/decisions/0001-screen-vs-tmux.md | 2 + docs/decisions/0002-status-detection.md | 2 + docs/decisions/0003-companion-programs.md | 2 + docs/decisions/0004-workshop-system.md | 12 +++-- docs/decisions/0005-control-path-layout.md | 2 + docs/decisions/0006-installers.md | 2 + docs/decisions/COMPANION_PROGRAMS_DESIGN.md | 2 + docs/decisions/README.md | 2 + docs/decisions/SCHEDULER_ACTIONS_DESIGN.md | 2 + docs/decisions/STEAM_WORKSHOP_DESIGN.md | 29 +++++----- docs/development/CODEX_GUIDE.md | 2 + .../GSP_PLATFORM_IMPROVEMENT_REPORT.md | 2 + docs/features/COMPANION_PROGRAMS.md | 2 + docs/features/COMPETITOR_COMPARISON.md | 2 + docs/features/FILE_EDITOR.md | 2 + docs/features/FTP_SYSTEM.md | 2 + docs/features/INSTALLERS.md | 2 + docs/features/LOGGING_SYSTEM.md | 2 + docs/features/PROVISIONING.md | 2 + docs/features/RCON_SYSTEM.md | 2 + docs/features/SCHEDULER_ACTIONS.md | 2 + docs/features/SCHEDULER_SYSTEM.md | 2 + docs/features/STATUS_SYSTEM.md | 2 + docs/features/USER_API.md | 2 + .../WORKSHOP_PHASE1_IMPLEMENTATION.md | 18 ++++--- docs/features/WORKSHOP_SYSTEM.md | 53 +++++++++++++------ docs/features/XML_SYSTEM.md | 4 +- docs/games/README.md | 2 + docs/modules/GAMEMANAGER.md | 2 + docs/modules/MODULE_INDEX.md | 2 + docs/modules/PANEL_UPDATE.md | 2 + docs/modules/SCHEDULER.md | 2 + docs/modules/SERVER_CONTENT_MANAGER.md | 20 ++++--- docs/modules/TS3Admin.md | 2 + docs/modules/UPDATE.md | 2 + docs/modules/administration.md | 2 + docs/modules/backup-restore.md | 2 + docs/modules/billing.md | 2 + docs/modules/circular.md | 2 + docs/modules/config_games.md | 2 + docs/modules/cron.md | 2 + docs/modules/dashboard.md | 2 + docs/modules/dsi.md | 2 + docs/modules/editconfigfiles.md | 2 + docs/modules/faq.md | 2 + docs/modules/fast_download.md | 2 + docs/modules/ftp.md | 2 + docs/modules/gamemanager.md | 2 + docs/modules/lgsl_with_img_mod.md | 2 + docs/modules/litefm.md | 2 + docs/modules/lostpwd.md | 2 + docs/modules/modulemanager.md | 2 + docs/modules/mysql.md | 2 + docs/modules/news.md | 2 + docs/modules/rcon.md | 2 + docs/modules/register.md | 2 + docs/modules/server.md | 2 + docs/modules/settings.md | 2 + docs/modules/status.md | 2 + docs/modules/steam_workshop.md | 2 + docs/modules/subusers.md | 2 + docs/modules/support.md | 2 + docs/modules/teamspeak3.md | 2 + docs/modules/tickets.md | 2 + docs/modules/ts3admin.md | 2 + docs/modules/tshock.md | 2 + docs/modules/update.md | 2 + docs/modules/user_admin.md | 2 + docs/modules/user_games.md | 2 + docs/modules/util.md | 2 + 92 files changed, 487 insertions(+), 110 deletions(-) create mode 100644 docs/AGENT_COMMUNICATION.md create mode 100644 docs/ARCHITECTURE.md create mode 100644 docs/COMMAND_FLOW.md create mode 100644 docs/PANEL_ARCHITECTURE.md create mode 100644 docs/REPOSITORY_STRUCTURE.md create mode 100644 docs/UPDATE_POLICY.md diff --git a/Panel/modules/addonsmanager/SERVER_CONTENT_WORKSHOP_PHASE1.md b/Panel/modules/addonsmanager/SERVER_CONTENT_WORKSHOP_PHASE1.md index c302a7c0..ec89abfa 100644 --- a/Panel/modules/addonsmanager/SERVER_CONTENT_WORKSHOP_PHASE1.md +++ b/Panel/modules/addonsmanager/SERVER_CONTENT_WORKSHOP_PHASE1.md @@ -16,14 +16,12 @@ Phase 1 adds manual Workshop ID support inside the existing `addonsmanager` modu - Update All - Panel generates a per-server manifest at: - `%home_path%/gsp_server_content/workshop_manifest.json` -- Panel runs an approved handler only, never a user-supplied command/path. -- If a game does not define a custom Workshop script, the panel stages the - bundled generic handler for the agent OS: - - Linux: `generic_steam_workshop_linux.sh` - - Windows/Cygwin: `generic_steam_workshop_windows_cygwin.sh` -- If a custom configured script is missing on the agent, the panel falls back - to the bundled generic handler and logs a warning instead of failing with - "script not found." +- Panel generates an approved per-job handler only, never a user-supplied command/path. +- The generated job is written under: + - `%home_path%/gsp_server_content/jobs/workshop/workshop_job__.sh` +- The generated job writes a temporary SteamCMD runscript and invokes SteamCMD with `+runscript`. +- Static Workshop script paths in XML are deprecated for the primary workflow. +- The agent does not need `generic_steam_workshop_linux.sh` or `generic_steam_workshop_windows_cygwin.sh` to exist on disk. ## Security model @@ -51,10 +49,7 @@ and keeps `OGP_DB_PREFIXaddons.addon_type` at `VARCHAR(32)` so `workshop` is val Each game should define and document: - `workshop_app_id` -- optional Linux workshop script path only when the bundled generic handler is - not sufficient -- optional Windows/Cygwin workshop script path only when the bundled generic - handler is not sufficient +- install strategy and target path - target install location - restart/update behavior diff --git a/Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_linux.sh b/Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_linux.sh index 6924e4dc..93259dd7 100755 --- a/Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_linux.sh +++ b/Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_linux.sh @@ -13,6 +13,7 @@ import os import shutil import subprocess import sys +import tempfile from datetime import datetime manifest_path = os.path.abspath(sys.argv[1]) @@ -192,14 +193,16 @@ try: if action in ('install', 'update', 'check_updates', 'download_only', 'validate_files'): if not workshop_app_id: fail(f"Workshop App ID is missing for Workshop item {workshop_id}.") - command = [ - steamcmd_path, - '+force_install_dir', server_root, - '+login', 'anonymous', - '+workshop_download_item', workshop_app_id, workshop_id, 'validate', - '+quit', - ] - log(f"workshop_id={workshop_id} steamcmd={' '.join(command)}", 'Downloading Workshop Item') + fd, runscript_path = tempfile.mkstemp(prefix=f"steamcmd_workshop_{workshop_id}_", suffix=".txt", dir=manifest_dir, text=True) + with os.fdopen(fd, 'w', encoding='utf-8') as script_handle: + script_handle.write("@ShutdownOnFailedCommand 0\n") + script_handle.write("@NoPromptForPassword 1\n") + script_handle.write(f"force_install_dir {server_root}\n") + script_handle.write("login anonymous\n") + script_handle.write(f"workshop_download_item {workshop_app_id} {workshop_id} validate\n") + script_handle.write("quit\n") + command = [steamcmd_path, '+runscript', runscript_path] + log(f"workshop_id={workshop_id} runscript={runscript_path}", 'Downloading Workshop Item') result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=server_root) if result.stdout: for line in result.stdout.splitlines(): diff --git a/Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_windows_cygwin.sh b/Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_windows_cygwin.sh index 24e7c5e8..21f7de40 100755 --- a/Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_windows_cygwin.sh +++ b/Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_windows_cygwin.sh @@ -13,6 +13,7 @@ import os import shutil import subprocess import sys +import tempfile from datetime import datetime manifest_path = os.path.abspath(sys.argv[1]) @@ -193,14 +194,16 @@ try: if action in ('install', 'update', 'check_updates', 'download_only', 'validate_files'): if not workshop_app_id: fail(f"Workshop App ID is missing for Workshop item {workshop_id}.") - command = [ - steamcmd_path, - '+force_install_dir', server_root, - '+login', 'anonymous', - '+workshop_download_item', workshop_app_id, workshop_id, 'validate', - '+quit', - ] - log(f"workshop_id={workshop_id} steamcmd={' '.join(command)}", 'Downloading Workshop Item') + fd, runscript_path = tempfile.mkstemp(prefix=f"steamcmd_workshop_{workshop_id}_", suffix=".txt", dir=manifest_dir, text=True) + with os.fdopen(fd, 'w', encoding='utf-8') as script_handle: + script_handle.write("@ShutdownOnFailedCommand 0\n") + script_handle.write("@NoPromptForPassword 1\n") + script_handle.write(f"force_install_dir {server_root}\n") + script_handle.write("login anonymous\n") + script_handle.write(f"workshop_download_item {workshop_app_id} {workshop_id} validate\n") + script_handle.write("quit\n") + command = [steamcmd_path, '+runscript', runscript_path] + log(f"workshop_id={workshop_id} runscript={runscript_path}", 'Downloading Workshop Item') result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=server_root) if result.stdout: for line in result.stdout.splitlines(): diff --git a/Panel/modules/addonsmanager/server_content_helpers.php b/Panel/modules/addonsmanager/server_content_helpers.php index b3f8e27c..c5e6a080 100644 --- a/Panel/modules/addonsmanager/server_content_helpers.php +++ b/Panel/modules/addonsmanager/server_content_helpers.php @@ -507,8 +507,8 @@ function scm_is_legacy_panel_workshop_script_path($script_path) function scm_get_agent_managed_workshop_script_path(array $home_info) { $home_path = rtrim(clean_path((string)$home_info['home_path']), '/'); - $filename = scm_is_windows_home($home_info) ? SCM_WORKSHOP_SCRIPT_WINDOWS_DEFAULT : SCM_WORKSHOP_SCRIPT_LINUX_DEFAULT; - $remote_path = clean_path($home_path . '/gsp_server_content/scripts/workshop/' . $filename); + $filename = 'workshop_job_' . date('Ymd_His') . '_' . mt_rand(1000, 9999) . '.sh'; + $remote_path = clean_path($home_path . '/gsp_server_content/jobs/workshop/' . $filename); if (!scm_path_is_under_home($home_path, $remote_path)) { return false; } @@ -520,20 +520,17 @@ function scm_prepare_workshop_script_for_agent($remote, array $home_info, $serve $error = ''; $configured_path = scm_get_configured_workshop_script_path($home_info, $server_xml); if ($configured_path !== '' && !scm_is_default_workshop_script_name($configured_path) && !scm_is_legacy_panel_workshop_script_path($configured_path)) { - if ((int)$remote->rfile_exists($configured_path) === 1) { - return $configured_path; - } scm_log_content_install_action(array( - 'type' => 'workshop_script_fallback', + 'type' => 'workshop_script_deprecated', 'home_id' => isset($home_info['home_id']) ? (int)$home_info['home_id'] : 0, 'configured_path' => $configured_path, - 'message' => 'Configured workshop script was not found on the agent; falling back to bundled generic handler.', + 'message' => 'Configured static Workshop script ignored; Server Content generates a per-job script and runs it through the generic agent exec path.', )); } $source_path = scm_get_bundled_workshop_script_source($home_info); if (!is_file($source_path)) { - $error = 'Bundled workshop script is missing from the panel: ' . $source_path; + $error = 'Panel Workshop job template is missing: ' . $source_path; return false; } @@ -545,7 +542,7 @@ function scm_prepare_workshop_script_for_agent($remote, array $home_info, $serve $script_body = @file_get_contents($source_path); if ($script_body === false || $script_body === '') { - $error = 'Failed to read bundled workshop script: ' . $source_path; + $error = 'Failed to read Panel Workshop job template: ' . $source_path; return false; } diff --git a/Panel/modules/addonsmanager/tests/workshop_helpers_test.php b/Panel/modules/addonsmanager/tests/workshop_helpers_test.php index db319392..25d127f7 100644 --- a/Panel/modules/addonsmanager/tests/workshop_helpers_test.php +++ b/Panel/modules/addonsmanager/tests/workshop_helpers_test.php @@ -75,26 +75,29 @@ $emptyXml = simplexml_load_string(''); $linuxRemote = new ScmWorkshopFakeRemote(); $error = ''; $script = scm_prepare_workshop_script_for_agent($linuxRemote, $linuxHome, $emptyXml, $error); -scm_workshop_test_assert($script === '/srv/games/arma3/gsp_server_content/scripts/workshop/generic_steam_workshop_linux.sh', 'stages default Linux script under server home'); -scm_workshop_test_assert(isset($linuxRemote->files[$script]), 'writes Linux bundled script to fake agent'); -scm_workshop_test_assert($error === '', 'default Linux script staging does not report missing script'); +scm_workshop_test_assert(strpos($script, '/srv/games/arma3/gsp_server_content/jobs/workshop/workshop_job_') === 0, 'stages per-job Linux script under server home'); +scm_workshop_test_assert(isset($linuxRemote->files[$script]), 'writes Linux per-job script to fake agent'); +scm_workshop_test_assert(strpos($linuxRemote->files[$script], '+runscript') !== false, 'Linux per-job script runs SteamCMD through runscript'); +scm_workshop_test_assert(strpos($linuxRemote->files[$script], 'workshop_download_item {workshop_app_id} {workshop_id} validate') !== false, 'Linux per-job script generates workshop_download_item runscript command'); +scm_workshop_test_assert($error === '', 'default Linux job staging does not report missing agent script'); $windowsRemote = new ScmWorkshopFakeRemote(); $script = scm_prepare_workshop_script_for_agent($windowsRemote, $windowsHome, $emptyXml, $error); -scm_workshop_test_assert($script === '/cygdrive/c/OGP_User_Files/11/gsp_server_content/scripts/workshop/generic_steam_workshop_windows_cygwin.sh', 'stages default Windows/Cygwin script under server home'); -scm_workshop_test_assert(isset($windowsRemote->files[$script]), 'writes Windows/Cygwin bundled script to fake agent'); -scm_workshop_test_assert($error === '', 'default Windows/Cygwin script staging does not report missing script'); +scm_workshop_test_assert(strpos($script, '/cygdrive/c/OGP_User_Files/11/gsp_server_content/jobs/workshop/workshop_job_') === 0, 'stages per-job Windows/Cygwin script under server home'); +scm_workshop_test_assert(isset($windowsRemote->files[$script]), 'writes Windows/Cygwin per-job script to fake agent'); +scm_workshop_test_assert(strpos($windowsRemote->files[$script], '+runscript') !== false, 'Windows/Cygwin per-job script runs SteamCMD through runscript'); +scm_workshop_test_assert($error === '', 'default Windows/Cygwin job staging does not report missing agent script'); $configuredXml = simplexml_load_string('/agent/custom/workshop.sh'); $customRemote = new ScmWorkshopFakeRemote(); $customRemote->existing[] = '/agent/custom/workshop.sh'; $script = scm_prepare_workshop_script_for_agent($customRemote, $linuxHome, $configuredXml, $error); -scm_workshop_test_assert($script === '/agent/custom/workshop.sh', 'uses existing configured custom script'); +scm_workshop_test_assert(strpos($script, '/srv/games/arma3/gsp_server_content/jobs/workshop/workshop_job_') === 0, 'ignores configured static script and uses generated per-job script'); $missingCustomRemote = new ScmWorkshopFakeRemote(); $script = scm_prepare_workshop_script_for_agent($missingCustomRemote, $linuxHome, $configuredXml, $error); -scm_workshop_test_assert($script === '/srv/games/arma3/gsp_server_content/scripts/workshop/generic_steam_workshop_linux.sh', 'falls back to bundled script when configured custom script is missing'); -scm_workshop_test_assert($error === '', 'missing custom script fallback does not expose script-not-found error'); +scm_workshop_test_assert(strpos($script, '/srv/games/arma3/gsp_server_content/jobs/workshop/workshop_job_') === 0, 'missing custom static script still uses generated per-job script'); +scm_workshop_test_assert($error === '', 'missing custom script does not expose script-not-found error'); @unlink(dirname(__DIR__) . '/logs/content_install.log'); @rmdir(dirname(__DIR__) . '/logs'); diff --git a/README.md b/README.md index fabe7f74..a031bae0 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ GSP is a game server hosting platform built around a web Panel, Linux and Windows/Cygwin agents, and a customer Website. +Workspace reference: [`GSP-WORKSPACE.md`](../GSP-WORKSPACE.md) + The goal of this repository is to let customers manage hosted game servers with the same practical control they would expect on their own machine: - start, stop, restart, and monitor servers @@ -46,6 +48,7 @@ The Panel is the control layer. It loads modules from `Panel/modules/`, stores p Start with: +- [`GSP-WORKSPACE.md`](../GSP-WORKSPACE.md) - workspace-wide source of truth - [docs/development/CODEX_GUIDE.md](docs/development/CODEX_GUIDE.md) - [docs/architecture/REPOSITORY_OVERVIEW.md](docs/architecture/REPOSITORY_OVERVIEW.md) - [docs/architecture/PANEL_AGENT_FLOW.md](docs/architecture/PANEL_AGENT_FLOW.md) @@ -61,6 +64,15 @@ Start with: - [docs/features/SCHEDULER_ACTIONS.md](docs/features/SCHEDULER_ACTIONS.md) - [docs/features/USER_API.md](docs/features/USER_API.md) +Additional repository entry points: + +- [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) +- [docs/PANEL_ARCHITECTURE.md](docs/PANEL_ARCHITECTURE.md) +- [docs/AGENT_COMMUNICATION.md](docs/AGENT_COMMUNICATION.md) +- [docs/REPOSITORY_STRUCTURE.md](docs/REPOSITORY_STRUCTURE.md) +- [docs/COMMAND_FLOW.md](docs/COMMAND_FLOW.md) +- [docs/UPDATE_POLICY.md](docs/UPDATE_POLICY.md) + Additional architecture and decision records: - [docs/architecture/AI_GSP_ARCHITECTURE.md](docs/architecture/AI_GSP_ARCHITECTURE.md) diff --git a/docs/AGENT_COMMUNICATION.md b/docs/AGENT_COMMUNICATION.md new file mode 100644 index 00000000..563c474b --- /dev/null +++ b/docs/AGENT_COMMUNICATION.md @@ -0,0 +1,28 @@ +# GSP Agent Communication + +Workspace reference: [`GSP-WORKSPACE.md`](../../GSP-WORKSPACE.md) + +This document is the short-form overview of how the Panel talks to the Linux and Windows agents. + +## Transport + +The Panel uses its remote communication layer to send commands to an agent, which in turn forwards work to the OGP Perl agent and the host OS. + +## Common flow + +1. Panel module builds a request. +2. `Panel/includes/lib_remote.php` sends it. +3. The agent receives the request. +4. The OGP Perl agent executes the requested action. +5. The agent returns status, logs, or command results. + +## Key properties + +- requests must be explicit and validated +- agents should report results, not decide policy +- status reporting should remain compatible between Linux and Windows where practical +- platform-specific differences should be isolated to the agent layer + +## Security rule + +Customer input must never become arbitrary shell command text. Panel-side validation and allowlists must happen before a request is sent to an agent. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md new file mode 100644 index 00000000..5266e07d --- /dev/null +++ b/docs/ARCHITECTURE.md @@ -0,0 +1,45 @@ +# GSP Architecture Overview + +Workspace reference: [`GSP-WORKSPACE.md`](../../GSP-WORKSPACE.md) + +This repository is the control plane for the GSP ecosystem. It owns the Panel, the Website, shared documentation, and the modules that decide what actions should be taken for each hosted server. + +## How to read this repo + +Start here: + +1. `README.md` +2. `docs/ARCHITECTURE.md` +3. `docs/PANEL_ARCHITECTURE.md` +4. `docs/AGENT_COMMUNICATION.md` +5. `docs/REPOSITORY_STRUCTURE.md` +6. `docs/COMMAND_FLOW.md` +7. `docs/UPDATE_POLICY.md` + +Then use the deeper docs under `docs/architecture/`, `docs/features/`, `docs/modules/`, and `docs/development/` for implementation details. + +## System boundary + +GSP owns: + +- user and admin-facing web UI +- server lifecycle orchestration +- module routing and shared state +- XML/configuration authoring +- update policy and backup policy +- documentation for the full ecosystem + +GSP does not own the OS-level execution engine. That responsibility belongs to the Linux and Windows agent repositories. + +## Canonical runtime model + +User action +→ Panel module +→ remote command generation +→ agent communication +→ Linux or Windows agent +→ OGP Perl agent +→ operating system +→ hosted game server + +The Panel is authoritative for business logic. Agents should execute requests and report results. diff --git a/docs/COMMAND_FLOW.md b/docs/COMMAND_FLOW.md new file mode 100644 index 00000000..7211634b --- /dev/null +++ b/docs/COMMAND_FLOW.md @@ -0,0 +1,27 @@ +# GSP Command Flow + +Workspace reference: [`GSP-WORKSPACE.md`](../../GSP-WORKSPACE.md) + +## Canonical flow + +User +→ Panel module +→ panel request builder +→ communication layer +→ Linux or Windows agent +→ OGP Perl agent +→ OS command or process control +→ game server process + +## Typical actions + +- start / stop / restart +- monitor status +- read logs +- install content or Workshop items +- update panel or agent binaries +- run scheduled tasks + +## Rule + +The Panel owns the decision. The agent owns execution. Keep those responsibilities separate. diff --git a/docs/PANEL_ARCHITECTURE.md b/docs/PANEL_ARCHITECTURE.md new file mode 100644 index 00000000..0c8bcab9 --- /dev/null +++ b/docs/PANEL_ARCHITECTURE.md @@ -0,0 +1,26 @@ +# GSP Panel Architecture + +Workspace reference: [`GSP-WORKSPACE.md`](../../GSP-WORKSPACE.md) + +The Panel is the orchestration layer for GSP. It handles authentication, routing, server lifecycle decisions, file/config management, Workshop/content workflows, status display, scheduling, and updates. + +## Responsibilities + +- load modules from `Panel/modules/` +- read and write panel-side database state +- generate requests for remote agents +- validate server configuration and XML +- render admin and customer workflows +- coordinate backups, updates, and rollback + +## Important implementation areas + +- `Panel/includes/lib_remote.php` for agent communication +- `Panel/modules/config_games/` for game XML definitions +- `Panel/modules/update/` and update-related administration modules +- `Panel/modules/gamemanager/` for server lifecycle and logs +- `Panel/modules/addonsmanager/` for server content and Workshop flows + +## Design rule + +The Panel decides what should happen. It does not depend on agents to make business decisions, only to execute requests and report their status. diff --git a/docs/REPOSITORY_STRUCTURE.md b/docs/REPOSITORY_STRUCTURE.md new file mode 100644 index 00000000..9470cc14 --- /dev/null +++ b/docs/REPOSITORY_STRUCTURE.md @@ -0,0 +1,27 @@ +# GSP Repository Structure + +Workspace reference: [`GSP-WORKSPACE.md`](../../GSP-WORKSPACE.md) + +This repository is the panel and documentation repository for the ecosystem. + +## Top-level layout + +| Path | Purpose | +| --- | --- | +| `Panel/` | Web panel modules, shared includes, config game XML, and admin tools | +| `Website/` | Public-facing site and customer content | +| `docs/` | Architecture, module, feature, and development documentation | +| `README.md` | Repository overview and entry point | + +## Panel layout + +- `Panel/modules/` - user/admin modules +- `Panel/includes/` - shared panel libraries +- `Panel/modules/config_games/` - XML game definitions and schema +- `Panel/modules/update/` - panel update workflow +- `Panel/modules/gamemanager/` - lifecycle and status UI +- `Panel/modules/addonsmanager/` - server content and Workshop workflows + +## Documentation rule + +If a change affects a module boundary, update flow, or agent contract, document it here and in the more specific architecture or feature docs. diff --git a/docs/UPDATE_POLICY.md b/docs/UPDATE_POLICY.md new file mode 100644 index 00000000..d01d8ef6 --- /dev/null +++ b/docs/UPDATE_POLICY.md @@ -0,0 +1,28 @@ +# GSP Update Policy + +Workspace reference: [`GSP-WORKSPACE.md`](../../GSP-WORKSPACE.md) + +## Update rule + +Code updates must never remove customer-owned data. + +Never overwrite or delete: + +- home folders +- game server data +- save files +- configuration files +- Workshop content +- custom scripts +- uploads +- logs unless a documented rotation policy applies + +## What may be updated + +- application code +- bundled helper scripts explicitly owned by the product +- update metadata used by the Panel or agents + +## Cross-repository rule + +If an update path changes panel behavior, agent startup behavior, or filesystem ownership assumptions, update the docs in all affected repositories before the code change is considered complete. diff --git a/docs/agents/LINUX_AGENT.md b/docs/agents/LINUX_AGENT.md index 5a1c76a2..95b54b69 100644 --- a/docs/agents/LINUX_AGENT.md +++ b/docs/agents/LINUX_AGENT.md @@ -1,5 +1,7 @@ # Linux Agent +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Role `Agent_Linux/ogp_agent.pl` is the Linux execution agent for GSP. It is responsible for: @@ -84,10 +86,11 @@ The agent reads screen logs and may also copy a local log file into the game hom The primary Workshop workflow is owned by the Panel `addonsmanager`, not the legacy `steam_workshop` RPC. For Linux servers the Panel: 1. writes `gsp_server_content/workshop_manifest.json` under the server home -2. stages `generic_steam_workshop_linux.sh` under `gsp_server_content/scripts/workshop/` -3. invokes the staged script through the authenticated `exec` RPC +2. writes a generated per-job shell script under `gsp_server_content/jobs/workshop/` +3. the generated job writes a temporary SteamCMD runscript and calls SteamCMD with `+runscript` +4. invokes the generated job script through the authenticated `exec` RPC -The staged script uses Python and SteamCMD, validates numeric Workshop IDs, keeps writes under the server home, logs to `gsp_server_content/workshop_install.log`, and supports DayZ/Arma-style `@mod` folders plus `.bikey` copying. +The generated job uses Python and SteamCMD, validates numeric Workshop IDs, keeps writes under the server home, logs to `gsp_server_content/workshop_install.log`, and supports DayZ/Arma-style `@mod` folders plus `.bikey` copying. The Linux agent does not need a permanent `generic_steam_workshop_linux.sh` file on disk. The older `steam_workshop` XML-RPC method remains for legacy compatibility only and should not be treated as the primary customer workflow. diff --git a/docs/agents/WINDOWS_AGENT.md b/docs/agents/WINDOWS_AGENT.md index ace743ca..a05dfbc8 100644 --- a/docs/agents/WINDOWS_AGENT.md +++ b/docs/agents/WINDOWS_AGENT.md @@ -1,5 +1,7 @@ # Windows Agent +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Role `Agent-Windows/OGP64/OGP/ogp_agent.pl` is the Windows/Cygwin execution agent currently tracked in this repository. It mirrors the Linux agent as closely as practical, while using Windows-compatible paths, processes, and wrappers. @@ -164,10 +166,11 @@ Windows/Cygwin logs come from screen logs and/or local copies. Log retrieval sho The primary Workshop workflow is owned by the Panel `addonsmanager`, not the legacy `steam_workshop` RPC. For Windows/Cygwin servers the Panel: 1. writes `gsp_server_content/workshop_manifest.json` under the server home -2. stages `generic_steam_workshop_windows_cygwin.sh` under `gsp_server_content/scripts/workshop/` -3. invokes the staged script through the authenticated `exec` RPC +2. writes a generated per-job shell script under `gsp_server_content/jobs/workshop/` +3. the generated job writes a temporary SteamCMD runscript and calls SteamCMD with `+runscript` +4. invokes the generated job script through the authenticated `exec` RPC -The staged script uses Python and SteamCMD, validates numeric Workshop IDs, keeps writes under the server home, logs to `gsp_server_content/workshop_install_windows.log`, and supports DayZ/Arma-style `@mod` folders plus `.bikey` copying. +The generated job uses Python and SteamCMD, validates numeric Workshop IDs, keeps writes under the server home, logs to `gsp_server_content/workshop_install_windows.log`, and supports DayZ/Arma-style `@mod` folders plus `.bikey` copying. The Windows agent does not need a permanent `generic_steam_workshop_windows_cygwin.sh` file on disk. The older `steam_workshop` XML-RPC method remains for legacy compatibility only and should not be treated as the primary customer workflow. diff --git a/docs/architecture/AI_GSP_ARCHITECTURE.md b/docs/architecture/AI_GSP_ARCHITECTURE.md index d4175d45..f2fc3759 100644 --- a/docs/architecture/AI_GSP_ARCHITECTURE.md +++ b/docs/architecture/AI_GSP_ARCHITECTURE.md @@ -1,5 +1,7 @@ # GSP Component Architecture +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + This repository contains the related GSP components together: - `/Agent-Windows` - Cygwin/Windows game server agent. diff --git a/docs/architecture/API_REFERENCE.md b/docs/architecture/API_REFERENCE.md index 754c797f..781aafda 100644 --- a/docs/architecture/API_REFERENCE.md +++ b/docs/architecture/API_REFERENCE.md @@ -1,5 +1,7 @@ # API Reference +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Scope This is the master reference for: @@ -193,9 +195,10 @@ Current preferred Workshop/content flow: 1. Panel validates Workshop IDs 2. Panel writes manifest JSON to server home -3. Panel stages bundled helper script to agent host via `writefile` -4. Panel runs helper with `exec` -5. Agent logs/install output is returned to Panel +3. Panel writes a generated per-job shell script to server home via `writefile` +4. The job script writes a temporary SteamCMD runscript +5. Panel runs the generated job script with `exec` +6. Agent logs/install output is returned to Panel Common manifest fields: diff --git a/docs/architecture/LIBRARY_REFERENCE.md b/docs/architecture/LIBRARY_REFERENCE.md index 6a12fa25..1fdab447 100644 --- a/docs/architecture/LIBRARY_REFERENCE.md +++ b/docs/architecture/LIBRARY_REFERENCE.md @@ -1,5 +1,7 @@ # Library Reference +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Scope This file documents the shared Panel libraries and helper entrypoints that multiple modules reuse. diff --git a/docs/architecture/MODULE_DEPENDENCIES.md b/docs/architecture/MODULE_DEPENDENCIES.md index e5201150..537e2571 100644 --- a/docs/architecture/MODULE_DEPENDENCIES.md +++ b/docs/architecture/MODULE_DEPENDENCIES.md @@ -1,5 +1,7 @@ # Module Dependencies +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Scope This file maps how Panel modules depend on: diff --git a/docs/architecture/PANEL_AGENT_COMMANDS.md b/docs/architecture/PANEL_AGENT_COMMANDS.md index a32422d6..e0cf0229 100644 --- a/docs/architecture/PANEL_AGENT_COMMANDS.md +++ b/docs/architecture/PANEL_AGENT_COMMANDS.md @@ -1,5 +1,7 @@ # Panel-Agent Commands +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Scope This file is the command catalog for the XML-RPC surface between the Panel and the agents. @@ -101,8 +103,9 @@ Common patterns: Current preferred implementation path: -- `addonsmanager` stages a manifest and helper script through `writefile` -- it executes the helper through `exec` +- `addonsmanager` stages a manifest and generated per-job script through `writefile` +- the generated script creates a temporary SteamCMD runscript and runs `steamcmd +runscript` +- it executes the generated job script through `exec` - it records per-server items and policies in Panel database tables - it uses `steam_workshop` only as legacy compatibility, not as the primary workflow - no new Workshop-specific business logic should be added to agents for the current design diff --git a/docs/architecture/PANEL_AGENT_FLOW.md b/docs/architecture/PANEL_AGENT_FLOW.md index b61e8d56..1d285f22 100644 --- a/docs/architecture/PANEL_AGENT_FLOW.md +++ b/docs/architecture/PANEL_AGENT_FLOW.md @@ -1,5 +1,7 @@ # Panel Agent Flow +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Overview The Panel does not directly run servers. It prepares the request, sends it to the agent, and interprets the response. @@ -100,4 +102,3 @@ Recommended status fields: - The agent should be the source of truth. - Marker files may exist, but they should be treated as hints only. - The same high-level flow should work for Linux and Windows/Cygwin. - diff --git a/docs/architecture/REPOSITORY_OVERVIEW.md b/docs/architecture/REPOSITORY_OVERVIEW.md index 5c3d17b6..9b24ae9d 100644 --- a/docs/architecture/REPOSITORY_OVERVIEW.md +++ b/docs/architecture/REPOSITORY_OVERVIEW.md @@ -1,5 +1,7 @@ # Repository Overview +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Purpose This repository contains the GSP game server hosting platform: diff --git a/docs/architecture/RPC_STATUS_REPAIR_REPORT.md b/docs/architecture/RPC_STATUS_REPAIR_REPORT.md index bb4d28d7..bd89b94c 100644 --- a/docs/architecture/RPC_STATUS_REPAIR_REPORT.md +++ b/docs/architecture/RPC_STATUS_REPAIR_REPORT.md @@ -1,5 +1,7 @@ # RPC Status Repair Report +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Purpose This report documents the investigation and repair for the Panel message: diff --git a/docs/decisions/0001-screen-vs-tmux.md b/docs/decisions/0001-screen-vs-tmux.md index e5e25bdf..749c293b 100644 --- a/docs/decisions/0001-screen-vs-tmux.md +++ b/docs/decisions/0001-screen-vs-tmux.md @@ -1,5 +1,7 @@ # Decision 0001: Keep `screen` As The Shared Backend +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Status Accepted diff --git a/docs/decisions/0002-status-detection.md b/docs/decisions/0002-status-detection.md index aecf9391..6e363dad 100644 --- a/docs/decisions/0002-status-detection.md +++ b/docs/decisions/0002-status-detection.md @@ -1,5 +1,7 @@ # Decision 0002: Agent-Truthed Status Detection +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Status Accepted diff --git a/docs/decisions/0003-companion-programs.md b/docs/decisions/0003-companion-programs.md index 76fea7f9..f89b49de 100644 --- a/docs/decisions/0003-companion-programs.md +++ b/docs/decisions/0003-companion-programs.md @@ -1,5 +1,7 @@ # Decision 0003: First-Class Companion Programs +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Status Accepted diff --git a/docs/decisions/0004-workshop-system.md b/docs/decisions/0004-workshop-system.md index fdcff73f..63d75001 100644 --- a/docs/decisions/0004-workshop-system.md +++ b/docs/decisions/0004-workshop-system.md @@ -1,5 +1,7 @@ # Decision 0004: Server Content Manager Is The Workshop Layer +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Status Accepted, Panel-side orchestration active @@ -10,7 +12,7 @@ Accepted, Panel-side orchestration active Phase 1 implements this decision by routing the user-facing Workshop install flow through `addonsmanager/workshop_content.php` and suppressing the standalone `steam_workshop` monitor button. -The current implementation keeps Workshop business logic in the Panel. Agents are generic executors: the Panel writes manifests, stages scripts, invokes `exec`, reads logs/results, and updates database state. New first-class Workshop subsystems should not be added to `Agent-Windows` or `Agent_Linux` unless a future decision explicitly changes this. +The current implementation keeps Workshop business logic in the Panel. Agents are generic executors: the Panel writes manifests, writes generated per-job scripts, invokes `exec`, reads logs/results, and updates database state. New first-class Workshop subsystems should not be added to `Agent-Windows` or `Agent_Linux` unless a future decision explicitly changes this. ## Reasoning @@ -32,10 +34,10 @@ The current implementation keeps Workshop business logic in the Panel. Agents ar - Workshop input accepts numeric IDs or Steam URLs, then stores numeric IDs only. - Manifests are written under the server home in `gsp_server_content`. -- Bundled Linux/Cygwin scripts are copied from the Panel module to an agent-managed folder under the server home before execution. -- These scripts are Panel-owned deployment artifacts, not persistent agent features. -- Default script names are treated as bundled handlers, not as existing agent paths. -- Missing custom scripts fall back to bundled handlers and log the fallback. +- A generated Linux/Cygwin-compatible job script is written under `gsp_server_content/jobs/workshop/` before execution. +- The generated job script creates a temporary SteamCMD runscript and runs SteamCMD with `+runscript`. +- Default script names are not treated as existing agent paths. +- Static custom Workshop scripts are deprecated for the primary path and logged if encountered. - Known Workshop items are cataloged in `server_content_workshop_catalog`. - Per-server item state, enablement, load order, update policy, and pending action are stored in `server_content_workshop`. - Scheduler integrates via `workshop_update`, `workshop_update_and_restart`, `workshop_download_only`, and `workshop_install_pending_on_restart`. diff --git a/docs/decisions/0005-control-path-layout.md b/docs/decisions/0005-control-path-layout.md index 934143f9..ac8b5583 100644 --- a/docs/decisions/0005-control-path-layout.md +++ b/docs/decisions/0005-control-path-layout.md @@ -1,5 +1,7 @@ # Decision 0005: Keep Managed Control Paths Outside Customer-Easy Edit Paths +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Status Accepted diff --git a/docs/decisions/0006-installers.md b/docs/decisions/0006-installers.md index 136b1996..2429eb3c 100644 --- a/docs/decisions/0006-installers.md +++ b/docs/decisions/0006-installers.md @@ -1,5 +1,7 @@ # Decision 0006: Installers Must Be Game-Capability Driven +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Status Accepted diff --git a/docs/decisions/COMPANION_PROGRAMS_DESIGN.md b/docs/decisions/COMPANION_PROGRAMS_DESIGN.md index 317fe4b4..eed3d97f 100644 --- a/docs/decisions/COMPANION_PROGRAMS_DESIGN.md +++ b/docs/decisions/COMPANION_PROGRAMS_DESIGN.md @@ -1,5 +1,7 @@ # Companion Programs Design Investigation +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + This is an investigation-only design report for adding first-class companion/sidecar application support to GSP game servers. No implementation is included here. Repository layout reviewed: diff --git a/docs/decisions/README.md b/docs/decisions/README.md index d3820fd8..008a62c6 100644 --- a/docs/decisions/README.md +++ b/docs/decisions/README.md @@ -1,5 +1,7 @@ # Decisions +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + This folder holds permanent architecture decisions and a small set of preserved investigation reports that informed those decisions. ## Decision Records diff --git a/docs/decisions/SCHEDULER_ACTIONS_DESIGN.md b/docs/decisions/SCHEDULER_ACTIONS_DESIGN.md index 695a586f..552a67c5 100644 --- a/docs/decisions/SCHEDULER_ACTIONS_DESIGN.md +++ b/docs/decisions/SCHEDULER_ACTIONS_DESIGN.md @@ -1,5 +1,7 @@ # GSP Scheduler Actions Design +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Scope This is an investigation and design report only. It does not implement code. diff --git a/docs/decisions/STEAM_WORKSHOP_DESIGN.md b/docs/decisions/STEAM_WORKSHOP_DESIGN.md index cd092d7e..c8797d2c 100644 --- a/docs/decisions/STEAM_WORKSHOP_DESIGN.md +++ b/docs/decisions/STEAM_WORKSHOP_DESIGN.md @@ -1,5 +1,7 @@ # GSP Steam Workshop and Server Content Design +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Scope This document is an investigation and design report only. It does not implement code. @@ -43,8 +45,8 @@ What exists: - Workshop IDs are validated as numeric strings. - A `server_content_workshop` table is created/migrated by helper code. - A remote manifest is written under the game server home. -- Bundled generic Linux and Cygwin/Windows scripts are copied to the agent and executed. -- The current scripts can call SteamCMD with `+workshop_download_item`. +- Panel-owned Linux and Cygwin/Windows templates are used to generate per-job scripts under the server home. +- The generated job script creates a temporary SteamCMD runscript and calls SteamCMD with `+runscript`. - Basic install, update, update selected, update all, and remove selected actions exist. - Actions are logged through the panel logger and the script writes a text log under `gsp_server_content`. @@ -74,18 +76,20 @@ The current user flow is: 3. Panel inserts or updates rows in `server_content_workshop`. 4. Panel writes a manifest to: - `{GAME_HOME}/gsp_server_content/workshop_manifest.json` -5. Panel copies a bundled script to: - - `{GAME_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_linux.sh` - - or `{GAME_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_windows_cygwin.sh` +5. Panel writes a generated job script to: + - `{GAME_HOME}/gsp_server_content/jobs/workshop/workshop_job__.sh` 6. Panel executes: - `bash ` -7. The script uses SteamCMD: - - `+force_install_dir ` - - `+login anonymous` - - `+workshop_download_item validate` -8. The script copies downloaded files to a target folder, defaulting to: +7. The script writes a temporary SteamCMD runscript: + - `@ShutdownOnFailedCommand 0` + - `@NoPromptForPassword 1` + - `force_install_dir ` + - `login anonymous` + - `workshop_download_item validate` +8. The script runs SteamCMD with `+runscript `. +9. The script copies downloaded files to a target folder, defaulting to: - `{SERVER_ROOT}/@{WORKSHOP_ID}` -9. Panel updates DB row state to `installed`, `failed`, or `removed`. +10. Panel updates DB row state to `installed`, `failed`, or `removed`. This is useful as a proof of concept, but it is not yet a commercial Workshop/mod system. @@ -121,7 +125,7 @@ The current helper also writes agent-side files under the server home: - `gsp_server_content/workshop_install.log` - `gsp_server_content/workshop_install_windows.log` - `gsp_server_content/workshop/removed/*` -- `gsp_server_content/scripts/workshop/*` +- `gsp_server_content/jobs/workshop/workshop_job_*.sh` Current DB weaknesses: @@ -1393,4 +1397,3 @@ The professional path is: - Generate startup parameters from structured enabled/load-ordered rows. - Treat LGSL/GameQ and game query systems as unrelated to content installation. - Keep customers away from raw commands, helper scripts, and managed control files. - diff --git a/docs/development/CODEX_GUIDE.md b/docs/development/CODEX_GUIDE.md index 3454a7f4..aed14aa2 100644 --- a/docs/development/CODEX_GUIDE.md +++ b/docs/development/CODEX_GUIDE.md @@ -1,5 +1,7 @@ # Codex Guide +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + This file is the first stop for future Codex sessions working in this repository. ## Repository Layout diff --git a/docs/development/GSP_PLATFORM_IMPROVEMENT_REPORT.md b/docs/development/GSP_PLATFORM_IMPROVEMENT_REPORT.md index 3ef6c733..9ce4f70b 100644 --- a/docs/development/GSP_PLATFORM_IMPROVEMENT_REPORT.md +++ b/docs/development/GSP_PLATFORM_IMPROVEMENT_REPORT.md @@ -1,5 +1,7 @@ # GSP Platform Improvement Report +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + Investigation date: 2026-06-05 Repository reviewed: diff --git a/docs/features/COMPANION_PROGRAMS.md b/docs/features/COMPANION_PROGRAMS.md index 2eb7a8c4..bed462fa 100644 --- a/docs/features/COMPANION_PROGRAMS.md +++ b/docs/features/COMPANION_PROGRAMS.md @@ -1,5 +1,7 @@ # Companion Programs +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current State Companion programs are not yet a first-class managed system. Current behavior is mostly script-driven and game-specific. diff --git a/docs/features/COMPETITOR_COMPARISON.md b/docs/features/COMPETITOR_COMPARISON.md index 28d64eb8..807c7c19 100644 --- a/docs/features/COMPETITOR_COMPARISON.md +++ b/docs/features/COMPETITOR_COMPARISON.md @@ -1,5 +1,7 @@ # Competitor Comparison +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Reviewed Hosts / Panels - Open Game Panel diff --git a/docs/features/FILE_EDITOR.md b/docs/features/FILE_EDITOR.md index 02a7c7e5..88f03d8b 100644 --- a/docs/features/FILE_EDITOR.md +++ b/docs/features/FILE_EDITOR.md @@ -1,5 +1,7 @@ # File Editor +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current State File editing is split across LiteFM, FTP, edit-config helpers, and agent remote read/write methods. diff --git a/docs/features/FTP_SYSTEM.md b/docs/features/FTP_SYSTEM.md index bb6c3a61..d3bcd92d 100644 --- a/docs/features/FTP_SYSTEM.md +++ b/docs/features/FTP_SYSTEM.md @@ -1,5 +1,7 @@ # FTP System +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current State GSP includes an FTP module and FTP-related provisioning fields. diff --git a/docs/features/INSTALLERS.md b/docs/features/INSTALLERS.md index eceaaa75..2855419d 100644 --- a/docs/features/INSTALLERS.md +++ b/docs/features/INSTALLERS.md @@ -1,5 +1,7 @@ # Installers +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current State Installer behavior is split across game XML, gamemanager startup, addonsmanager, SteamCMD helpers, and agent scripts. diff --git a/docs/features/LOGGING_SYSTEM.md b/docs/features/LOGGING_SYSTEM.md index ad6f43b2..c63adb7d 100644 --- a/docs/features/LOGGING_SYSTEM.md +++ b/docs/features/LOGGING_SYSTEM.md @@ -1,5 +1,7 @@ # Logging System +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current State Logging comes from multiple places: diff --git a/docs/features/PROVISIONING.md b/docs/features/PROVISIONING.md index 5f067942..2da1f07b 100644 --- a/docs/features/PROVISIONING.md +++ b/docs/features/PROVISIONING.md @@ -1,5 +1,7 @@ # Provisioning +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current State Server provisioning flows are centered in `user_games` and supported by billing and server manager modules. diff --git a/docs/features/RCON_SYSTEM.md b/docs/features/RCON_SYSTEM.md index fcc9dc14..d673f06b 100644 --- a/docs/features/RCON_SYSTEM.md +++ b/docs/features/RCON_SYSTEM.md @@ -1,5 +1,7 @@ # RCON System +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current State RCON support is part of the gamemanager and a dedicated admin RCON module. diff --git a/docs/features/SCHEDULER_ACTIONS.md b/docs/features/SCHEDULER_ACTIONS.md index 8e9aba42..05ad80de 100644 --- a/docs/features/SCHEDULER_ACTIONS.md +++ b/docs/features/SCHEDULER_ACTIONS.md @@ -1,5 +1,7 @@ # Scheduler Actions +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Scope This file is the command reference for the current scheduler system. diff --git a/docs/features/SCHEDULER_SYSTEM.md b/docs/features/SCHEDULER_SYSTEM.md index f6165c92..fcbef442 100644 --- a/docs/features/SCHEDULER_SYSTEM.md +++ b/docs/features/SCHEDULER_SYSTEM.md @@ -1,5 +1,7 @@ # Scheduler System +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current State The scheduler is implemented through the `cron` Panel module and agent-side `Schedule::Cron` execution. diff --git a/docs/features/STATUS_SYSTEM.md b/docs/features/STATUS_SYSTEM.md index cd072911..ecdbe479 100644 --- a/docs/features/STATUS_SYSTEM.md +++ b/docs/features/STATUS_SYSTEM.md @@ -1,5 +1,7 @@ # Status System +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Current Goal The status system should tell the truth about a server's state without depending on stale marker files or query success alone. diff --git a/docs/features/USER_API.md b/docs/features/USER_API.md index edde3c87..a2fce687 100644 --- a/docs/features/USER_API.md +++ b/docs/features/USER_API.md @@ -1,5 +1,7 @@ # User API +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Scope This file documents the externally reachable API and webhook surfaces discovered in the repository. diff --git a/docs/features/WORKSHOP_PHASE1_IMPLEMENTATION.md b/docs/features/WORKSHOP_PHASE1_IMPLEMENTATION.md index 6a4efc2a..9803a176 100644 --- a/docs/features/WORKSHOP_PHASE1_IMPLEMENTATION.md +++ b/docs/features/WORKSHOP_PHASE1_IMPLEMENTATION.md @@ -1,5 +1,7 @@ # Workshop Phase 1 Implementation +Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md) + ## Summary Phase 1 makes the active Server Content Manager Workshop path usable for DayZ/Arma-style Workshop installs without reviving the deprecated standalone `steam_workshop` user workflow. @@ -15,8 +17,8 @@ Active workflow: - `Panel/modules/addonsmanager/workshop_content.php` - `Panel/modules/addonsmanager/addons_manager.php` - `Panel/modules/addonsmanager/module.php` -- `Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_linux.sh` -- `Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_windows_cygwin.sh` +- `Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_linux.sh` (Panel template for generated jobs) +- `Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_windows_cygwin.sh` (Panel template for generated jobs) - `Panel/modules/steam_workshop/monitor_buttons.php` ## User Flow @@ -26,7 +28,7 @@ Active workflow: 3. Open the `Steam Workshop Mods` category. 4. Paste one or more Steam Workshop URLs or numeric Workshop IDs. 5. Click `Install / Queue`. -6. The Panel validates input, stores numeric Workshop IDs, writes a manifest, syncs the install script, executes it through the agent's existing `exec` primitive, and shows the result. +6. The Panel validates input, stores numeric Workshop IDs, writes a manifest, writes a generated per-job script, executes it through the agent's existing `exec` primitive, and shows the result. 7. Installed items can be enabled/disabled, updated, removed, downloaded without immediate install, assigned an update policy, and later used by Scheduler actions. Accepted input examples: @@ -53,17 +55,17 @@ The admin template defines capability and policy. The customer supplies only Wor 3. The Panel builds a manifest with per-item install details. 4. The manifest is written to: - `{SERVER_HOME}/gsp_server_content/workshop_manifest.json` -5. The correct bundled script is copied to: - - `{SERVER_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_linux.sh` - - or `{SERVER_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_windows_cygwin.sh` +5. A generated job script is written to: + - `{SERVER_HOME}/gsp_server_content/jobs/workshop/workshop_job__.sh` 6. The agent runs: - `bash