worshop work

This commit is contained in:
Frank Harris 2026-06-08 16:09:54 -05:00
parent 0d44c65ea5
commit 3829a4a83d
92 changed files with 487 additions and 110 deletions

View file

@ -16,14 +16,12 @@ Phase 1 adds manual Workshop ID support inside the existing `addonsmanager` modu
- Update All - Update All
- Panel generates a per-server manifest at: - Panel generates a per-server manifest at:
- `%home_path%/gsp_server_content/workshop_manifest.json` - `%home_path%/gsp_server_content/workshop_manifest.json`
- Panel runs an approved handler only, never a user-supplied command/path. - Panel generates an approved per-job handler only, never a user-supplied command/path.
- If a game does not define a custom Workshop script, the panel stages the - The generated job is written under:
bundled generic handler for the agent OS: - `%home_path%/gsp_server_content/jobs/workshop/workshop_job_<timestamp>_<random>.sh`
- Linux: `generic_steam_workshop_linux.sh` - The generated job writes a temporary SteamCMD runscript and invokes SteamCMD with `+runscript`.
- Windows/Cygwin: `generic_steam_workshop_windows_cygwin.sh` - Static Workshop script paths in XML are deprecated for the primary workflow.
- If a custom configured script is missing on the agent, the panel falls back - The agent does not need `generic_steam_workshop_linux.sh` or `generic_steam_workshop_windows_cygwin.sh` to exist on disk.
to the bundled generic handler and logs a warning instead of failing with
"script not found."
## Security model ## 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: Each game should define and document:
- `workshop_app_id` - `workshop_app_id`
- optional Linux workshop script path only when the bundled generic handler is - install strategy and target path
not sufficient
- optional Windows/Cygwin workshop script path only when the bundled generic
handler is not sufficient
- target install location - target install location
- restart/update behavior - restart/update behavior

View file

@ -13,6 +13,7 @@ import os
import shutil import shutil
import subprocess import subprocess
import sys import sys
import tempfile
from datetime import datetime from datetime import datetime
manifest_path = os.path.abspath(sys.argv[1]) 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 action in ('install', 'update', 'check_updates', 'download_only', 'validate_files'):
if not workshop_app_id: if not workshop_app_id:
fail(f"Workshop App ID is missing for Workshop item {workshop_id}.") fail(f"Workshop App ID is missing for Workshop item {workshop_id}.")
command = [ fd, runscript_path = tempfile.mkstemp(prefix=f"steamcmd_workshop_{workshop_id}_", suffix=".txt", dir=manifest_dir, text=True)
steamcmd_path, with os.fdopen(fd, 'w', encoding='utf-8') as script_handle:
'+force_install_dir', server_root, script_handle.write("@ShutdownOnFailedCommand 0\n")
'+login', 'anonymous', script_handle.write("@NoPromptForPassword 1\n")
'+workshop_download_item', workshop_app_id, workshop_id, 'validate', script_handle.write(f"force_install_dir {server_root}\n")
'+quit', script_handle.write("login anonymous\n")
] script_handle.write(f"workshop_download_item {workshop_app_id} {workshop_id} validate\n")
log(f"workshop_id={workshop_id} steamcmd={' '.join(command)}", 'Downloading Workshop Item') 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) result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=server_root)
if result.stdout: if result.stdout:
for line in result.stdout.splitlines(): for line in result.stdout.splitlines():

View file

@ -13,6 +13,7 @@ import os
import shutil import shutil
import subprocess import subprocess
import sys import sys
import tempfile
from datetime import datetime from datetime import datetime
manifest_path = os.path.abspath(sys.argv[1]) 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 action in ('install', 'update', 'check_updates', 'download_only', 'validate_files'):
if not workshop_app_id: if not workshop_app_id:
fail(f"Workshop App ID is missing for Workshop item {workshop_id}.") fail(f"Workshop App ID is missing for Workshop item {workshop_id}.")
command = [ fd, runscript_path = tempfile.mkstemp(prefix=f"steamcmd_workshop_{workshop_id}_", suffix=".txt", dir=manifest_dir, text=True)
steamcmd_path, with os.fdopen(fd, 'w', encoding='utf-8') as script_handle:
'+force_install_dir', server_root, script_handle.write("@ShutdownOnFailedCommand 0\n")
'+login', 'anonymous', script_handle.write("@NoPromptForPassword 1\n")
'+workshop_download_item', workshop_app_id, workshop_id, 'validate', script_handle.write(f"force_install_dir {server_root}\n")
'+quit', script_handle.write("login anonymous\n")
] script_handle.write(f"workshop_download_item {workshop_app_id} {workshop_id} validate\n")
log(f"workshop_id={workshop_id} steamcmd={' '.join(command)}", 'Downloading Workshop Item') 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) result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, cwd=server_root)
if result.stdout: if result.stdout:
for line in result.stdout.splitlines(): for line in result.stdout.splitlines():

View file

@ -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) function scm_get_agent_managed_workshop_script_path(array $home_info)
{ {
$home_path = rtrim(clean_path((string)$home_info['home_path']), '/'); $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; $filename = 'workshop_job_' . date('Ymd_His') . '_' . mt_rand(1000, 9999) . '.sh';
$remote_path = clean_path($home_path . '/gsp_server_content/scripts/workshop/' . $filename); $remote_path = clean_path($home_path . '/gsp_server_content/jobs/workshop/' . $filename);
if (!scm_path_is_under_home($home_path, $remote_path)) { if (!scm_path_is_under_home($home_path, $remote_path)) {
return false; return false;
} }
@ -520,20 +520,17 @@ function scm_prepare_workshop_script_for_agent($remote, array $home_info, $serve
$error = ''; $error = '';
$configured_path = scm_get_configured_workshop_script_path($home_info, $server_xml); $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 ($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( 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, 'home_id' => isset($home_info['home_id']) ? (int)$home_info['home_id'] : 0,
'configured_path' => $configured_path, '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); $source_path = scm_get_bundled_workshop_script_source($home_info);
if (!is_file($source_path)) { 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; 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); $script_body = @file_get_contents($source_path);
if ($script_body === false || $script_body === '') { 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; return false;
} }

View file

@ -75,26 +75,29 @@ $emptyXml = simplexml_load_string('<game_config></game_config>');
$linuxRemote = new ScmWorkshopFakeRemote(); $linuxRemote = new ScmWorkshopFakeRemote();
$error = ''; $error = '';
$script = scm_prepare_workshop_script_for_agent($linuxRemote, $linuxHome, $emptyXml, $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(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 bundled script to fake agent'); scm_workshop_test_assert(isset($linuxRemote->files[$script]), 'writes Linux per-job script to fake agent');
scm_workshop_test_assert($error === '', 'default Linux script staging does not report missing script'); 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(); $windowsRemote = new ScmWorkshopFakeRemote();
$script = scm_prepare_workshop_script_for_agent($windowsRemote, $windowsHome, $emptyXml, $error); $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(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 bundled script to fake agent'); scm_workshop_test_assert(isset($windowsRemote->files[$script]), 'writes Windows/Cygwin per-job script to fake agent');
scm_workshop_test_assert($error === '', 'default Windows/Cygwin script staging does not report missing script'); 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('<game_config><workshop_support><script_linux>/agent/custom/workshop.sh</script_linux></workshop_support></game_config>'); $configuredXml = simplexml_load_string('<game_config><workshop_support><script_linux>/agent/custom/workshop.sh</script_linux></workshop_support></game_config>');
$customRemote = new ScmWorkshopFakeRemote(); $customRemote = new ScmWorkshopFakeRemote();
$customRemote->existing[] = '/agent/custom/workshop.sh'; $customRemote->existing[] = '/agent/custom/workshop.sh';
$script = scm_prepare_workshop_script_for_agent($customRemote, $linuxHome, $configuredXml, $error); $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(); $missingCustomRemote = new ScmWorkshopFakeRemote();
$script = scm_prepare_workshop_script_for_agent($missingCustomRemote, $linuxHome, $configuredXml, $error); $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(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 fallback does not expose script-not-found error'); scm_workshop_test_assert($error === '', 'missing custom script does not expose script-not-found error');
@unlink(dirname(__DIR__) . '/logs/content_install.log'); @unlink(dirname(__DIR__) . '/logs/content_install.log');
@rmdir(dirname(__DIR__) . '/logs'); @rmdir(dirname(__DIR__) . '/logs');

View file

@ -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. 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: 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 - 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: Start with:
- [`GSP-WORKSPACE.md`](../GSP-WORKSPACE.md) - workspace-wide source of truth
- [docs/development/CODEX_GUIDE.md](docs/development/CODEX_GUIDE.md) - [docs/development/CODEX_GUIDE.md](docs/development/CODEX_GUIDE.md)
- [docs/architecture/REPOSITORY_OVERVIEW.md](docs/architecture/REPOSITORY_OVERVIEW.md) - [docs/architecture/REPOSITORY_OVERVIEW.md](docs/architecture/REPOSITORY_OVERVIEW.md)
- [docs/architecture/PANEL_AGENT_FLOW.md](docs/architecture/PANEL_AGENT_FLOW.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/SCHEDULER_ACTIONS.md](docs/features/SCHEDULER_ACTIONS.md)
- [docs/features/USER_API.md](docs/features/USER_API.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: Additional architecture and decision records:
- [docs/architecture/AI_GSP_ARCHITECTURE.md](docs/architecture/AI_GSP_ARCHITECTURE.md) - [docs/architecture/AI_GSP_ARCHITECTURE.md](docs/architecture/AI_GSP_ARCHITECTURE.md)

View file

@ -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.

45
docs/ARCHITECTURE.md Normal file
View file

@ -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.

27
docs/COMMAND_FLOW.md Normal file
View file

@ -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.

View file

@ -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.

View file

@ -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.

28
docs/UPDATE_POLICY.md Normal file
View file

@ -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.

View file

@ -1,5 +1,7 @@
# Linux Agent # Linux Agent
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Role ## Role
`Agent_Linux/ogp_agent.pl` is the Linux execution agent for GSP. It is responsible for: `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: 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 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/` 2. writes a generated per-job shell script under `gsp_server_content/jobs/workshop/`
3. invokes the staged script through the authenticated `exec` RPC 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. The older `steam_workshop` XML-RPC method remains for legacy compatibility only and should not be treated as the primary customer workflow.

View file

@ -1,5 +1,7 @@
# Windows Agent # Windows Agent
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Role ## 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. `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: 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 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/` 2. writes a generated per-job shell script under `gsp_server_content/jobs/workshop/`
3. invokes the staged script through the authenticated `exec` RPC 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. The older `steam_workshop` XML-RPC method remains for legacy compatibility only and should not be treated as the primary customer workflow.

View file

@ -1,5 +1,7 @@
# GSP Component Architecture # GSP Component Architecture
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
This repository contains the related GSP components together: This repository contains the related GSP components together:
- `/Agent-Windows` - Cygwin/Windows game server agent. - `/Agent-Windows` - Cygwin/Windows game server agent.

View file

@ -1,5 +1,7 @@
# API Reference # API Reference
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This is the master reference for: This is the master reference for:
@ -193,9 +195,10 @@ Current preferred Workshop/content flow:
1. Panel validates Workshop IDs 1. Panel validates Workshop IDs
2. Panel writes manifest JSON to server home 2. Panel writes manifest JSON to server home
3. Panel stages bundled helper script to agent host via `writefile` 3. Panel writes a generated per-job shell script to server home via `writefile`
4. Panel runs helper with `exec` 4. The job script writes a temporary SteamCMD runscript
5. Agent logs/install output is returned to Panel 5. Panel runs the generated job script with `exec`
6. Agent logs/install output is returned to Panel
Common manifest fields: Common manifest fields:

View file

@ -1,5 +1,7 @@
# Library Reference # Library Reference
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This file documents the shared Panel libraries and helper entrypoints that multiple modules reuse. This file documents the shared Panel libraries and helper entrypoints that multiple modules reuse.

View file

@ -1,5 +1,7 @@
# Module Dependencies # Module Dependencies
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This file maps how Panel modules depend on: This file maps how Panel modules depend on:

View file

@ -1,5 +1,7 @@
# Panel-Agent Commands # Panel-Agent Commands
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This file is the command catalog for the XML-RPC surface between the Panel and the agents. 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: Current preferred implementation path:
- `addonsmanager` stages a manifest and helper script through `writefile` - `addonsmanager` stages a manifest and generated per-job script through `writefile`
- it executes the helper through `exec` - 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 records per-server items and policies in Panel database tables
- it uses `steam_workshop` only as legacy compatibility, not as the primary workflow - 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 - no new Workshop-specific business logic should be added to agents for the current design

View file

@ -1,5 +1,7 @@
# Panel Agent Flow # Panel Agent Flow
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Overview ## Overview
The Panel does not directly run servers. It prepares the request, sends it to the agent, and interprets the response. 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. - The agent should be the source of truth.
- Marker files may exist, but they should be treated as hints only. - Marker files may exist, but they should be treated as hints only.
- The same high-level flow should work for Linux and Windows/Cygwin. - The same high-level flow should work for Linux and Windows/Cygwin.

View file

@ -1,5 +1,7 @@
# Repository Overview # Repository Overview
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
This repository contains the GSP game server hosting platform: This repository contains the GSP game server hosting platform:

View file

@ -1,5 +1,7 @@
# RPC Status Repair Report # RPC Status Repair Report
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
This report documents the investigation and repair for the Panel message: This report documents the investigation and repair for the Panel message:

View file

@ -1,5 +1,7 @@
# Decision 0001: Keep `screen` As The Shared Backend # Decision 0001: Keep `screen` As The Shared Backend
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Status ## Status
Accepted Accepted

View file

@ -1,5 +1,7 @@
# Decision 0002: Agent-Truthed Status Detection # Decision 0002: Agent-Truthed Status Detection
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Status ## Status
Accepted Accepted

View file

@ -1,5 +1,7 @@
# Decision 0003: First-Class Companion Programs # Decision 0003: First-Class Companion Programs
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Status ## Status
Accepted Accepted

View file

@ -1,5 +1,7 @@
# Decision 0004: Server Content Manager Is The Workshop Layer # Decision 0004: Server Content Manager Is The Workshop Layer
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Status ## Status
Accepted, Panel-side orchestration active 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. 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 ## 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. - Workshop input accepts numeric IDs or Steam URLs, then stores numeric IDs only.
- Manifests are written under the server home in `gsp_server_content`. - 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. - A generated Linux/Cygwin-compatible job script is written under `gsp_server_content/jobs/workshop/` before execution.
- These scripts are Panel-owned deployment artifacts, not persistent agent features. - The generated job script creates a temporary SteamCMD runscript and runs SteamCMD with `+runscript`.
- Default script names are treated as bundled handlers, not as existing agent paths. - Default script names are not treated as existing agent paths.
- Missing custom scripts fall back to bundled handlers and log the fallback. - Static custom Workshop scripts are deprecated for the primary path and logged if encountered.
- Known Workshop items are cataloged in `server_content_workshop_catalog`. - 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`. - 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`. - Scheduler integrates via `workshop_update`, `workshop_update_and_restart`, `workshop_download_only`, and `workshop_install_pending_on_restart`.

View file

@ -1,5 +1,7 @@
# Decision 0005: Keep Managed Control Paths Outside Customer-Easy Edit Paths # Decision 0005: Keep Managed Control Paths Outside Customer-Easy Edit Paths
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Status ## Status
Accepted Accepted

View file

@ -1,5 +1,7 @@
# Decision 0006: Installers Must Be Game-Capability Driven # Decision 0006: Installers Must Be Game-Capability Driven
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Status ## Status
Accepted Accepted

View file

@ -1,5 +1,7 @@
# Companion Programs Design Investigation # 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. 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: Repository layout reviewed:

View file

@ -1,5 +1,7 @@
# Decisions # 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. This folder holds permanent architecture decisions and a small set of preserved investigation reports that informed those decisions.
## Decision Records ## Decision Records

View file

@ -1,5 +1,7 @@
# GSP Scheduler Actions Design # GSP Scheduler Actions Design
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This is an investigation and design report only. It does not implement code. This is an investigation and design report only. It does not implement code.

View file

@ -1,5 +1,7 @@
# GSP Steam Workshop and Server Content Design # GSP Steam Workshop and Server Content Design
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This document is an investigation and design report only. It does not implement code. 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. - Workshop IDs are validated as numeric strings.
- A `server_content_workshop` table is created/migrated by helper code. - A `server_content_workshop` table is created/migrated by helper code.
- A remote manifest is written under the game server home. - A remote manifest is written under the game server home.
- Bundled generic Linux and Cygwin/Windows scripts are copied to the agent and executed. - Panel-owned Linux and Cygwin/Windows templates are used to generate per-job scripts under the server home.
- The current scripts can call SteamCMD with `+workshop_download_item`. - 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. - 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`. - 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`. 3. Panel inserts or updates rows in `server_content_workshop`.
4. Panel writes a manifest to: 4. Panel writes a manifest to:
- `{GAME_HOME}/gsp_server_content/workshop_manifest.json` - `{GAME_HOME}/gsp_server_content/workshop_manifest.json`
5. Panel copies a bundled script to: 5. Panel writes a generated job script to:
- `{GAME_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_linux.sh` - `{GAME_HOME}/gsp_server_content/jobs/workshop/workshop_job_<timestamp>_<random>.sh`
- or `{GAME_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_windows_cygwin.sh`
6. Panel executes: 6. Panel executes:
- `bash <script_path> <manifest_path>` - `bash <script_path> <manifest_path>`
7. The script uses SteamCMD: 7. The script writes a temporary SteamCMD runscript:
- `+force_install_dir <server_root>` - `@ShutdownOnFailedCommand 0`
- `+login anonymous` - `@NoPromptForPassword 1`
- `+workshop_download_item <workshop_app_id> <workshop_id> validate` - `force_install_dir <server_root>`
8. The script copies downloaded files to a target folder, defaulting to: - `login anonymous`
- `workshop_download_item <workshop_app_id> <workshop_id> validate`
8. The script runs SteamCMD with `+runscript <scriptfile>`.
9. The script copies downloaded files to a target folder, defaulting to:
- `{SERVER_ROOT}/@{WORKSHOP_ID}` - `{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. 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.log`
- `gsp_server_content/workshop_install_windows.log` - `gsp_server_content/workshop_install_windows.log`
- `gsp_server_content/workshop/removed/*` - `gsp_server_content/workshop/removed/*`
- `gsp_server_content/scripts/workshop/*` - `gsp_server_content/jobs/workshop/workshop_job_*.sh`
Current DB weaknesses: Current DB weaknesses:
@ -1393,4 +1397,3 @@ The professional path is:
- Generate startup parameters from structured enabled/load-ordered rows. - Generate startup parameters from structured enabled/load-ordered rows.
- Treat LGSL/GameQ and game query systems as unrelated to content installation. - Treat LGSL/GameQ and game query systems as unrelated to content installation.
- Keep customers away from raw commands, helper scripts, and managed control files. - Keep customers away from raw commands, helper scripts, and managed control files.

View file

@ -1,5 +1,7 @@
# Codex Guide # Codex Guide
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
This file is the first stop for future Codex sessions working in this repository. This file is the first stop for future Codex sessions working in this repository.
## Repository Layout ## Repository Layout

View file

@ -1,5 +1,7 @@
# GSP Platform Improvement Report # GSP Platform Improvement Report
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
Investigation date: 2026-06-05 Investigation date: 2026-06-05
Repository reviewed: Repository reviewed:

View file

@ -1,5 +1,7 @@
# Companion Programs # Companion Programs
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
Companion programs are not yet a first-class managed system. Current behavior is mostly script-driven and game-specific. Companion programs are not yet a first-class managed system. Current behavior is mostly script-driven and game-specific.

View file

@ -1,5 +1,7 @@
# Competitor Comparison # Competitor Comparison
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Reviewed Hosts / Panels ## Reviewed Hosts / Panels
- Open Game Panel - Open Game Panel

View file

@ -1,5 +1,7 @@
# File Editor # File Editor
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
File editing is split across LiteFM, FTP, edit-config helpers, and agent remote read/write methods. File editing is split across LiteFM, FTP, edit-config helpers, and agent remote read/write methods.

View file

@ -1,5 +1,7 @@
# FTP System # FTP System
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
GSP includes an FTP module and FTP-related provisioning fields. GSP includes an FTP module and FTP-related provisioning fields.

View file

@ -1,5 +1,7 @@
# Installers # Installers
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
Installer behavior is split across game XML, gamemanager startup, addonsmanager, SteamCMD helpers, and agent scripts. Installer behavior is split across game XML, gamemanager startup, addonsmanager, SteamCMD helpers, and agent scripts.

View file

@ -1,5 +1,7 @@
# Logging System # Logging System
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
Logging comes from multiple places: Logging comes from multiple places:

View file

@ -1,5 +1,7 @@
# Provisioning # Provisioning
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
Server provisioning flows are centered in `user_games` and supported by billing and server manager modules. Server provisioning flows are centered in `user_games` and supported by billing and server manager modules.

View file

@ -1,5 +1,7 @@
# RCON System # RCON System
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
RCON support is part of the gamemanager and a dedicated admin RCON module. RCON support is part of the gamemanager and a dedicated admin RCON module.

View file

@ -1,5 +1,7 @@
# Scheduler Actions # Scheduler Actions
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This file is the command reference for the current scheduler system. This file is the command reference for the current scheduler system.

View file

@ -1,5 +1,7 @@
# Scheduler System # Scheduler System
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
The scheduler is implemented through the `cron` Panel module and agent-side `Schedule::Cron` execution. The scheduler is implemented through the `cron` Panel module and agent-side `Schedule::Cron` execution.

View file

@ -1,5 +1,7 @@
# Status System # Status System
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current Goal ## Current Goal
The status system should tell the truth about a server's state without depending on stale marker files or query success alone. The status system should tell the truth about a server's state without depending on stale marker files or query success alone.

View file

@ -1,5 +1,7 @@
# User API # User API
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This file documents the externally reachable API and webhook surfaces discovered in the repository. This file documents the externally reachable API and webhook surfaces discovered in the repository.

View file

@ -1,5 +1,7 @@
# Workshop Phase 1 Implementation # Workshop Phase 1 Implementation
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Summary ## 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. 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/workshop_content.php`
- `Panel/modules/addonsmanager/addons_manager.php` - `Panel/modules/addonsmanager/addons_manager.php`
- `Panel/modules/addonsmanager/module.php` - `Panel/modules/addonsmanager/module.php`
- `Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_linux.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/modules/addonsmanager/scripts/workshop/generic_steam_workshop_windows_cygwin.sh` (Panel template for generated jobs)
- `Panel/modules/steam_workshop/monitor_buttons.php` - `Panel/modules/steam_workshop/monitor_buttons.php`
## User Flow ## User Flow
@ -26,7 +28,7 @@ Active workflow:
3. Open the `Steam Workshop Mods` category. 3. Open the `Steam Workshop Mods` category.
4. Paste one or more Steam Workshop URLs or numeric Workshop IDs. 4. Paste one or more Steam Workshop URLs or numeric Workshop IDs.
5. Click `Install / Queue`. 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. 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: 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. 3. The Panel builds a manifest with per-item install details.
4. The manifest is written to: 4. The manifest is written to:
- `{SERVER_HOME}/gsp_server_content/workshop_manifest.json` - `{SERVER_HOME}/gsp_server_content/workshop_manifest.json`
5. The correct bundled script is copied to: 5. A generated job script is written to:
- `{SERVER_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_linux.sh` - `{SERVER_HOME}/gsp_server_content/jobs/workshop/workshop_job_<timestamp>_<random>.sh`
- or `{SERVER_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_windows_cygwin.sh`
6. The agent runs: 6. The agent runs:
- `bash <script> <manifest>` - `bash <script> <manifest>`
7. The script runs SteamCMD, copies downloaded content into the target mod folder when the action requires install, logs output, and copies `.bikey` files for DayZ/Arma-style strategies. 7. The script writes a temporary SteamCMD runscript containing `workshop_download_item <appid> <workshop_id> validate`.
8. The script runs SteamCMD with `+runscript`, copies downloaded content into the target mod folder when the action requires install, logs output, and copies `.bikey` files for DayZ/Arma-style strategies.
Current repair: Current repair:
- The default script filename is no longer treated as an agent-host path. - The default script filename is no longer treated as an agent-host path.
- Missing custom scripts fall back to the bundled generic handler and log a warning. - Static custom Workshop scripts are deprecated for the primary path; the Panel generates a per-job script instead.
- Generic installs default to `{SERVER_ROOT}/workshop/{MOD_FOLDER}`. - Generic installs default to `{SERVER_ROOT}/workshop/{MOD_FOLDER}`.
- DayZ/Arma installs keep `{SERVER_ROOT}/{MOD_FOLDER}` for `@<workshop_id>` compatibility. - DayZ/Arma installs keep `{SERVER_ROOT}/{MOD_FOLDER}` for `@<workshop_id>` compatibility.
- `download_only` and `validate_files` are accepted script actions and do not copy into live mod folders. - `download_only` and `validate_files` are accepted script actions and do not copy into live mod folders.

View file

@ -1,5 +1,7 @@
# Workshop System # Workshop System
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
The current Workshop/content work is split across two module lines: The current Workshop/content work is split across two module lines:
@ -24,8 +26,9 @@ Important files:
Workshop is Panel-side orchestration. The active workflow lives in Server Content Manager and uses existing agent primitives only: Workshop is Panel-side orchestration. The active workflow lives in Server Content Manager and uses existing agent primitives only:
- Panel writes manifests with validated numeric Workshop IDs. - Panel writes manifests with validated numeric Workshop IDs.
- Panel deploys an OS-appropriate bundled handler script into the server home. - Panel generates a per-job shell script under the server home.
- Panel invokes the handler through the existing authenticated agent `exec` RPC. - The generated job script writes a temporary SteamCMD runscript and runs `steamcmd +runscript <scriptfile>`.
- Panel invokes the job script through the existing authenticated agent `exec` RPC.
- Agents do not need new Workshop-specific business logic. - Agents do not need new Workshop-specific business logic.
- Legacy agent RPCs from the old `steam_workshop` module remain compatibility-only and are not the primary path. - Legacy agent RPCs from the old `steam_workshop` module remain compatibility-only and are not the primary path.
@ -42,19 +45,29 @@ The Panel writes a manifest under the server home:
- `{SERVER_HOME}/gsp_server_content/workshop_manifest.json` - `{SERVER_HOME}/gsp_server_content/workshop_manifest.json`
The Panel syncs the bundled install script to: The Panel writes a generated per-job script to:
- `{SERVER_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_linux.sh` - `{SERVER_HOME}/gsp_server_content/jobs/workshop/workshop_job_<timestamp>_<random>.sh`
- `{SERVER_HOME}/gsp_server_content/scripts/workshop/generic_steam_workshop_windows_cygwin.sh`
The agent executes the synced script with the manifest path by using the existing generic command execution path. Customers do not need to place scripts manually on the agent. The agent executes the generated script with the manifest path by using the existing generic command execution path. Customers do not need to place scripts manually on the agent.
Script selection rules: Script/job rules:
1. If game XML defines a custom `workshop_script_linux` or `workshop_script_windows` and that script exists on the agent, use it. 1. Server Content Manager always generates the primary Workshop job script per action.
2. If the custom script is missing, log a fallback warning and stage the bundled generic handler. 2. Old XML/static script settings are logged as deprecated and ignored by the primary path.
3. If no custom script is defined, stage the bundled generic handler for the server OS. 3. The default script filename must never be treated as a pre-existing agent path.
4. The default script filename must never be treated as a pre-existing agent path. The Panel must copy the bundled script first. 4. The agent does not require `generic_steam_workshop_linux.sh` or `generic_steam_workshop_windows_cygwin.sh` to exist on disk.
The generated job script uses this SteamCMD runscript pattern:
```text
@ShutdownOnFailedCommand 0
@NoPromptForPassword 1
force_install_dir <server_root>
login anonymous
workshop_download_item <workshop_app_id> <workshop_id> validate
quit
```
The manifest includes: The manifest includes:
@ -200,7 +213,7 @@ Per-item update policy values stored on `server_content_workshop.update_policy`:
| Symptom | Meaning | Fix | | Symptom | Meaning | Fix |
|---|---|---| |---|---|---|
| `Configured workshop script not found on agent host: generic_steam_workshop_windows_cygwin.sh` | Old Panel logic treated the default script filename as an agent path. | Update the Panel. Current logic stages the bundled handler under `gsp_server_content/scripts/workshop/`. | | `Configured workshop script not found on agent host: generic_steam_workshop_windows_cygwin.sh` | Old Panel logic treated the default script filename as an agent path. | Update the Panel. Current logic generates a per-job script under `gsp_server_content/jobs/workshop/`. |
| `SteamCMD is missing on the agent host.` | The handler could not find SteamCMD at the configured path, `STEAMCMD_PATH`, or common locations. | Install SteamCMD on the agent and/or set the SteamCMD path in the Workshop profile/template. | | `SteamCMD is missing on the agent host.` | The handler could not find SteamCMD at the configured path, `STEAMCMD_PATH`, or common locations. | Install SteamCMD on the agent and/or set the SteamCMD path in the Workshop profile/template. |
| `Workshop App ID is missing` | No template/profile/XML provided an app ID. | Add `workshop_app_id` to the Server Content template or game XML. | | `Workshop App ID is missing` | No template/profile/XML provided an app ID. | Add `workshop_app_id` to the Server Content template or game XML. |
| Download succeeds but mod does not load | Startup parameters are not yet regenerated from installed Workshop rows. | Manually add the installed `@...` folders to the game startup params until Phase 2 startup integration is complete. | | Download succeeds but mod does not load | Startup parameters are not yet regenerated from installed Workshop rows. | Manually add the installed `@...` folders to the game startup params until Phase 2 startup integration is complete. |
@ -219,16 +232,22 @@ Use `addonsmanager` as the main future home for:
Treat `steam_workshop` as a legacy bridge for migration only. Treat `steam_workshop` as a legacy bridge for migration only.
## References Reviewed
- `reference/Module-Steam_Workshop` is the local legacy OGP module. It confirms that the Panel historically owned Workshop state/configuration and used the agent for execution.
- The uploaded `steam-workshop-downloader` reference was not present in this workspace, but its reviewed behavior is reflected in the active design: generate a SteamCMD runscript, call `workshop_download_item <appid> <workshop_id> validate`, copy or link the downloaded `steamapps/workshop/content/<appid>/<workshop_id>` folder into the server's mod location, optionally lowercase files for Linux, copy Arma/DayZ keys, and generate future `-mod=` data from installed items.
## Panel-Agent Contract ## Panel-Agent Contract
Phase 1 does not use the legacy `steam_workshop` XML-RPC method for the primary user workflow. Instead: Phase 1 does not use the legacy `steam_workshop` XML-RPC method for the primary user workflow. Instead:
1. Panel parses customer input into numeric Workshop IDs. 1. Panel parses customer input into numeric Workshop IDs.
2. Panel writes `{SERVER_HOME}/gsp_server_content/workshop_manifest.json`. 2. Panel writes `{SERVER_HOME}/gsp_server_content/workshop_manifest.json`.
3. Panel stages the OS-appropriate bundled handler under `{SERVER_HOME}/gsp_server_content/scripts/workshop/`. 3. Panel writes a generated per-job script under `{SERVER_HOME}/gsp_server_content/jobs/workshop/`.
4. Panel invokes the handler through the existing authenticated agent `exec` RPC. 4. The job script writes a temporary SteamCMD runscript.
5. The handler writes `workshop_install.log` or `workshop_install_windows.log` under `gsp_server_content`. 5. Panel invokes the job script through the existing authenticated agent `exec` RPC.
6. Panel updates `server_content_workshop.install_state` from queued/installing to installed/failed/removed. 6. The job writes `workshop_install.log` or `workshop_install_windows.log` under `gsp_server_content`.
7. Panel updates `server_content_workshop.install_state` from queued/installing to installed/failed/removed.
Important manifest fields: Important manifest fields:
@ -245,7 +264,7 @@ Important manifest fields:
- `extra.copy_keys` - `extra.copy_keys`
- `extra.keys_target_path` - `extra.keys_target_path`
Both bundled handlers validate numeric item IDs, keep writes under the server home, use SteamCMD, copy files into the resolved target path, and copy `.bikey` files for DayZ/Arma strategies when enabled. Generated Workshop jobs validate numeric item IDs, keep writes under the server home, use SteamCMD through a temporary runscript, copy files into the resolved target path, and copy `.bikey` files for DayZ/Arma strategies when enabled.
Bundled handler actions: Bundled handler actions:

View file

@ -1,5 +1,7 @@
# XML Game Configuration System # XML Game Configuration System
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
The XML game configuration system describes how a game server should be started, queried, and customized. The XML game configuration system describes how a game server should be started, queried, and customized.
@ -94,7 +96,7 @@ XML definitions also feed:
Workshop-enabled games must use the canonical `workshop_support` block. Loose top-level tags such as `workshop_app_id` are compatibility parser fallbacks only and should not be used in new game XML because schema validation is intentionally strict. Workshop-enabled games must use the canonical `workshop_support` block. Loose top-level tags such as `workshop_app_id` are compatibility parser fallbacks only and should not be used in new game XML because schema validation is intentionally strict.
The `workshop_support` block is a capability declaration only. It does not install mods by itself and it does not create an agent-side Workshop subsystem. Server Content Manager reads these values, writes a per-server manifest, stages the Panel-bundled handler, and calls the agent's existing generic execution primitives. The `workshop_support` block is a capability declaration only. It does not install mods by itself and it does not create an agent-side Workshop subsystem. Server Content Manager reads these values, writes a per-server manifest, writes a generated per-job script, and calls the agent's existing generic execution primitives.
Example: Example:

View file

@ -1,5 +1,7 @@
# Games # Games
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
This folder is reserved for game-by-game documentation. This folder is reserved for game-by-game documentation.
## Current Role ## Current Role

View file

@ -1,5 +1,7 @@
# GameManager # GameManager
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Role ## Role
`Panel/modules/gamemanager` is the core customer server control module. It owns: `Panel/modules/gamemanager` is the core customer server control module. It owns:

View file

@ -1,5 +1,7 @@
# Module Index # Module Index
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
This is the master module inventory for the Panel. Use it as the first stop before opening module code. This is the master module inventory for the Panel. Use it as the first stop before opening module code.
| Module | Purpose | Status | Recommendation | | Module | Purpose | Status | Recommendation |

View file

@ -1,5 +1,7 @@
# Panel Update Module # Panel Update Module
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Scope ## Scope
This document covers the admin Panel updater implemented through: This document covers the admin Panel updater implemented through:

View file

@ -1,5 +1,7 @@
# Scheduler # Scheduler
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current Implementation ## Current Implementation
The scheduler lives in the `cron` module on the Panel and in scheduler methods inside the agents. The scheduler lives in the `cron` module on the Panel and in scheduler methods inside the agents.

View file

@ -1,5 +1,7 @@
# Server Content Manager # Server Content Manager
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Current State ## Current State
`Panel/modules/addonsmanager` is the current home of GSP's Server Content / Add-ons / Workshop work. `Panel/modules/addonsmanager` is the current home of GSP's Server Content / Add-ons / Workshop work.
@ -47,17 +49,19 @@ For Workshop items, the current flow lets users enter Workshop IDs or full Steam
5. User enters one or more Workshop URLs or numeric IDs. 5. User enters one or more Workshop URLs or numeric IDs.
6. Panel parses IDs, rejects invalid entries, and records rows in `server_content_workshop`. 6. Panel parses IDs, rejects invalid entries, and records rows in `server_content_workshop`.
7. Panel writes a manifest to `{SERVER_HOME}/gsp_server_content/workshop_manifest.json`. 7. Panel writes a manifest to `{SERVER_HOME}/gsp_server_content/workshop_manifest.json`.
8. Panel syncs the bundled Linux or Cygwin script into `{SERVER_HOME}/gsp_server_content/scripts/workshop/`. 8. Panel writes a generated per-job shell script into `{SERVER_HOME}/gsp_server_content/jobs/workshop/`.
9. Agent executes the script with the manifest path through the existing authenticated `exec` RPC. 9. The generated job script creates a temporary SteamCMD runscript containing `workshop_download_item <appid> <workshop_id> validate`.
10. Script runs SteamCMD, copies Workshop content into the configured target path, copies DayZ/Arma `.bikey` files when applicable, and writes a log under `gsp_server_content`. 10. Agent executes the generated script with the manifest path through the existing authenticated `exec` RPC.
11. Script runs SteamCMD with `+runscript`, copies Workshop content into the configured target path, copies DayZ/Arma `.bikey` files when applicable, and writes a log under `gsp_server_content`.
The agents are intentionally generic executors in this design. New Workshop business logic should not be added to `Agent-Windows` or `Agent_Linux`; use `remote_writefile`, `exec`, log reads, and normal start/stop/restart primitives instead. The agents are intentionally generic executors in this design. New Workshop business logic should not be added to `Agent-Windows` or `Agent_Linux`; use `remote_writefile`, `exec`, log reads, and normal start/stop/restart primitives instead.
Current script fallback behavior: Current job-script behavior:
- Admin-defined custom scripts are supported when they exist on the agent. - Server Content Manager generates a new job script for each Workshop action.
- Missing custom scripts fall back to the bundled generic handler and are logged. - Admin-defined static Workshop script paths are deprecated and ignored by the primary path.
- Default script names such as `generic_steam_workshop_windows_cygwin.sh` are copied from the Panel module source and must not be checked as bare files on the agent. - Default script names such as `generic_steam_workshop_windows_cygwin.sh` must not be checked as bare files on the agent.
- Agents need only the generic `writefile` and `exec` primitives.
Current default install paths: Current default install paths:
@ -90,7 +94,7 @@ The Panel helper parser reads this block first and only tolerates old direct tag
SteamCMD requirements: SteamCMD requirements:
- Linux agents need SteamCMD available at the configured profile/template path, `STEAMCMD_PATH`, `/home/gameserver/steamcmd/steamcmd.sh`, or in `PATH`. - Linux agents need SteamCMD available at the configured profile/template path, `STEAMCMD_PATH`, `/home/gameserver/steamcmd/steamcmd.sh`, or in `PATH`.
- Windows agents currently use the existing Cygwin agent model and run the bundled Cygwin-compatible shell handler. SteamCMD may be provided as `steamcmd.exe`, `steamcmd.sh`, an explicit configured path, or via `STEAMCMD_PATH`. - Windows agents currently use the existing Cygwin agent model and run the Panel-generated shell job. SteamCMD may be provided as `steamcmd.exe`, `steamcmd.sh`, an explicit configured path, or via `STEAMCMD_PATH`.
- Missing SteamCMD should return a clear error, not a generic script failure. - Missing SteamCMD should return a clear error, not a generic script failure.
The legacy `steam_workshop` monitor button is intentionally suppressed so users are not sent to the deprecated standalone module. The legacy `steam_workshop` monitor button is intentionally suppressed so users are not sent to the deprecated standalone module.

View file

@ -1,5 +1,7 @@
# TS3Admin # TS3Admin
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Teamspeak 3 admin interface module. Teamspeak 3 admin interface module.

View file

@ -1,5 +1,7 @@
# Update Module # Update Module
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
Primary operational reference: Primary operational reference:
- `docs/modules/PANEL_UPDATE.md` - `docs/modules/PANEL_UPDATE.md`

View file

@ -1,5 +1,7 @@
# Administration # Administration
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Admin utilities and logging helpers, including the watch logger and external link storage. Admin utilities and logging helpers, including the watch logger and external link storage.

View file

@ -1,5 +1,7 @@
# Backup Restore # Backup Restore
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Backup and restore UI for game server homes. Backup and restore UI for game server homes.

View file

@ -1,5 +1,7 @@
# Billing # Billing
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Commercial billing, provisioning, invoices, orders, transactions, coupons, and payment gateway integration. Commercial billing, provisioning, invoices, orders, transactions, coupons, and payment gateway integration.

View file

@ -1,5 +1,7 @@
# Circular # Circular
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Admin notifications / circular messages for broadcasting announcements to users. Admin notifications / circular messages for broadcasting announcements to users.

View file

@ -1,5 +1,7 @@
# Config Games # Config Games
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Game XML definitions, CLI parameter generation, mod definitions, and custom field mapping. Game XML definitions, CLI parameter generation, mod definitions, and custom field mapping.

View file

@ -1,5 +1,7 @@
# Cron # Cron
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Scheduler / CRON for game server automation. Scheduler / CRON for game server automation.

View file

@ -1,5 +1,7 @@
# Dashboard # Dashboard
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Main landing dashboard with widgets and quick server overview. Main landing dashboard with widgets and quick server overview.

View file

@ -1,5 +1,7 @@
# Dynamic Server Image # Dynamic Server Image
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Dynamic server image and artwork management for server cards. Dynamic server image and artwork management for server cards.

View file

@ -1,5 +1,7 @@
# Edit Config Files # Edit Config Files
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Game-specific shortcuts for editing common configuration files. Game-specific shortcuts for editing common configuration files.

View file

@ -1,5 +1,7 @@
# F.A.Q. # F.A.Q.
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Basic help and FAQ content for users. Basic help and FAQ content for users.

View file

@ -1,5 +1,7 @@
# Fast Download # Fast Download
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
FastDL support for Source/GoldSrc style content distribution. FastDL support for Source/GoldSrc style content distribution.

View file

@ -1,5 +1,7 @@
# FTP # FTP
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
FTP administration and access control for server homes. FTP administration and access control for server homes.

View file

@ -1,4 +1,6 @@
# gamemanager # gamemanager
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
This page is an alias for [GAMEMANAGER.md](GAMEMANAGER.md). The full module documentation lives there. This page is an alias for [GAMEMANAGER.md](GAMEMANAGER.md). The full module documentation lives there.

View file

@ -1,5 +1,7 @@
# LGSL With Image Mod # LGSL With Image Mod
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Legacy LGSL status listing and image-based server display. Legacy LGSL status listing and image-based server display.

View file

@ -1,5 +1,7 @@
# Lite File Manager # Lite File Manager
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
In-panel file manager and file editor for customer server homes. In-panel file manager and file editor for customer server homes.

View file

@ -1,5 +1,7 @@
# Lost Password # Lost Password
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Password recovery flow for users. Password recovery flow for users.

View file

@ -1,5 +1,7 @@
# Module Manager # Module Manager
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Install and manage Panel modules and access rights. Install and manage Panel modules and access rights.

View file

@ -1,5 +1,7 @@
# MySQL # MySQL
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
MySQL hosting/admin module for servers and databases. MySQL hosting/admin module for servers and databases.

View file

@ -1,5 +1,7 @@
# NewsLister # NewsLister
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Legacy news and announcement module. Legacy news and announcement module.

View file

@ -1,5 +1,7 @@
# Rcon # Rcon
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Admin RCON interface for issuing console commands to supported game servers. Admin RCON interface for issuing console commands to supported game servers.

View file

@ -1,5 +1,7 @@
# Register # Register
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
User registration module. User registration module.

View file

@ -1,5 +1,7 @@
# Server Manager # Server Manager
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Remote server/node management in the Panel. Remote server/node management in the Panel.

View file

@ -1,5 +1,7 @@
# Settings # Settings
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Panel settings, theme settings, and core site configuration. Panel settings, theme settings, and core site configuration.

View file

@ -1,5 +1,7 @@
# Status # Status
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Admin status page for server/node state. Admin status page for server/node state.

View file

@ -1,5 +1,7 @@
# Steam Workshop # Steam Workshop
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Legacy standalone Steam Workshop support. Legacy standalone Steam Workshop support.

View file

@ -1,5 +1,7 @@
# Subusers # Subusers
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Subuser permissions and delegated access management. Subuser permissions and delegated access management.

View file

@ -1,5 +1,7 @@
# Support # Support
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Simple support landing page for users. Simple support landing page for users.

View file

@ -1,5 +1,7 @@
# Teamspeak 3 Web Interface # Teamspeak 3 Web Interface
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Web interface for Teamspeak 3 hosting. Web interface for Teamspeak 3 hosting.

View file

@ -1,5 +1,7 @@
# Tickets # Tickets
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Support ticket system with messages, attachments, and settings. Support ticket system with messages, attachments, and settings.

View file

@ -1,4 +1,6 @@
# ts3admin # ts3admin
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
This page is an alias for [TS3Admin.md](TS3Admin.md). The full module documentation lives there. This page is an alias for [TS3Admin.md](TS3Admin.md). The full module documentation lives there.

View file

@ -1,5 +1,7 @@
# TShock # TShock
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Terraria / TShock-specific support module. Terraria / TShock-specific support module.

View file

@ -1,5 +1,7 @@
# Update # Update
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Panel update and patch management. Panel update and patch management.

View file

@ -1,5 +1,7 @@
# User Admin # User Admin
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
User, role, and group administration. User, role, and group administration.

View file

@ -1,5 +1,7 @@
# User Games # User Games
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Server provisioning, assignment, cloning, expiration, and home management. Server provisioning, assignment, cloning, expiration, and home management.

View file

@ -1,5 +1,7 @@
# Utilities # Utilities
Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose ## Purpose
Miscellaneous utility tools such as Steam ID conversion and game-adjacent helpers. Miscellaneous utility tools such as Steam ID conversion and game-adjacent helpers.