workshop fix 1234

This commit is contained in:
Frank Harris 2026-06-11 12:50:45 -05:00
parent 6be904e903
commit 3d7aa64db6
15 changed files with 509 additions and 484 deletions

View file

@ -68,9 +68,9 @@ This file is the first stop for future Codex sessions working in this repository
- `Panel/modules/addonsmanager/module.php`
- `Panel/modules/addonsmanager/addons_manager.php`
- `Panel/modules/addonsmanager/user_addons.php`
- `Panel/modules/addonsmanager/workshop_content.php`
- `Panel/modules/addonsmanager/workshop_action.php`
- `Panel/modules/steam_workshop/module.php`
- `Panel/modules/steam_workshop/main.php`
- `Panel/modules/steam_workshop/monitor_buttons.php`
### XML Definitions

View file

@ -6,258 +6,56 @@ Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
The current Workshop/content work is split across two module lines:
- `Panel/modules/steam_workshop` - deprecated compatibility layer
- `Panel/modules/addonsmanager` - the active Server Content Manager path
- `Panel/modules/steam_workshop` - active user-facing Workshop module
- `Panel/modules/addonsmanager` - Server Content module, no longer a Workshop entry point
Important files:
- `Panel/modules/addonsmanager/module.php`
- `Panel/modules/addonsmanager/user_addons.php`
- `Panel/modules/addonsmanager/addons_manager.php`
- `Panel/modules/addonsmanager/workshop_content.php`
- `Panel/modules/addonsmanager/workshop_action.php`
- `Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_linux.sh`
- `Panel/modules/addonsmanager/scripts/workshop/generic_steam_workshop_windows_cygwin.sh`
- `Panel/modules/steam_workshop/module.php`
- `Panel/modules/steam_workshop/agent_update_workshop.php`
- `Panel/modules/steam_workshop/main.php`
- `Panel/modules/steam_workshop/monitor_buttons.php`
- `Panel/modules/steam_workshop/workshop_admin.php`
## Current Implemented Behavior
Workshop is Panel-side orchestration. The active workflow lives in Server Content Manager and uses existing agent primitives only:
Steam Workshop is handled by the dedicated `steam_workshop` module.
- Panel writes manifests with validated numeric Workshop IDs.
- Panel generates a per-job shell script under the server home.
- 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.
- Legacy agent RPCs from the old `steam_workshop` module remain compatibility-only and are not the primary path.
The active user workflow is now `addonsmanager` -> `workshop_content`.
Users can enter either:
- a numeric Workshop item ID
- a full Steam Workshop URL containing `id=<number>`
The Panel extracts and stores only numeric Workshop IDs. Invalid text is rejected before any manifest or shell command is built.
The Panel writes a manifest under the server home:
- `{SERVER_HOME}/gsp_server_content/workshop_manifest.json`
The Panel writes a generated per-job script to:
- `{SERVER_HOME}/gsp_server_content/jobs/workshop/workshop_job_<timestamp>_<random>.sh`
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/job rules:
1. Server Content Manager always generates the primary Workshop job script per action.
2. Game XML does not define static agent script paths.
3. The default script filename must never be treated as a pre-existing agent path.
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:
- `home_id`
- server/game path
- `workshop_app_id`
- Workshop item IDs
- per-item target paths
- install strategy
- key-copy settings
- content template metadata
Default install paths:
- Generic Workshop installs default to `{SERVER_ROOT}/workshop/{MOD_FOLDER}`.
- DayZ/Arma-style installs default to `dayz_mod_folder` or `arma_mod_folder` based on the game key/name/config file. Those strategies install to `{SERVER_ROOT}/{MOD_FOLDER}` so `@<workshop_id>` folders remain compatible with existing `-mod=` workflows.
- DayZ/Arma key-copy behavior copies `.bikey` files into the server `keys` folder when found. Missing key files are logged but do not fail the install.
App ID rules:
- `workshop_app_id` must come from the selected game's canonical `workshop_support` XML block.
- Server Content admin forms must not ask for Workshop app IDs, target paths, launch params, or Workshop script paths.
- Do not silently use the dedicated server Steam app ID as the Workshop app ID.
- Arma 3 XML declares Workshop app ID `107410`; its dedicated server Steam app ID remains `233780`.
Canonical XML:
```xml
<workshop_support>
<enabled>1</enabled>
<provider>steam</provider>
<steam_app_id>107410</steam_app_id>
<workshop_app_id>107410</workshop_app_id>
<download_method>steamcmd</download_method>
<install_strategy>arma_mod_folder</install_strategy>
<install_path>{SERVER_ROOT}/{MOD_FOLDER}</install_path>
<startup_param_format>-mod={MOD_LIST}</startup_param_format>
<mod_separator>;</mod_separator>
<mod_prefix>@</mod_prefix>
<copy_keys enabled="1">
<source_pattern>{MOD_PATH}/keys/*.bikey</source_pattern>
<target_path>{SERVER_ROOT}/keys</target_path>
</copy_keys>
<post_install_action></post_install_action>
</workshop_support>
```
The Panel helper parser reads `workshop_support` as the source of truth. New game XML must not use loose top-level Workshop tags, and the schema no longer accepts per-game static agent script tags such as `script_linux` or `script_windows`.
Server Content must not show a `Steam Workshop Mods` category or route users into `addonsmanager/workshop_content.php`.
## Database State
`server_content_workshop` tracks:
- `content_id`
- `home_id`
- `workshop_app_id`
- `workshop_item_id`
- `title`
- `install_path`
- `install_strategy`
- `enabled`
- `load_order`
- `update_policy`
- `pending_action`
- `install_state`
- `last_installed_at`
- `last_updated_at`
- `last_error`
Current install states used by Phase 1:
- `queued`
- `installing`
- `installed`
- `downloaded`
- `failed`
- `removed`
`server_content_workshop_catalog` tracks known/common Workshop items seen through Server Content Manager:
- `workshop_id`
- `app_id`
- `title`
- `author`
- `thumbnail_url`
- `install_count`
- `first_seen`
- `last_installed`
- `last_updated`
- `published_date`
- `tags`
- `game_key`
- `local_cache_path`
The catalog is Panel-side and does not require Steam Web API metadata. It grows from real installs and can be searched by Workshop ID, Steam URL, keyword/title, author, tag, or game key. Metadata can be enriched later through Steam Web API or SteamCMD output parsing.
The dedicated module still uses its own Workshop tables and per-game XML files under `Panel/modules/steam_workshop/game_configs/`.
## What Exists Today
The current direction already supports:
The dedicated module still provides:
- content records in the Panel database
- Workshop item IDs
- installation metadata
- install history tables
- XML-owned game compatibility fields
- XML-owned launch parameter format
- XML-owned post-install action placeholder
- user-facing Workshop pages
- monitor-button access from Game Monitor
- per-game Workshop configuration files
- uninstall and admin support pages
## Main Limitations
- Workshop metadata is still incomplete.
- Load order is tracked but not yet a full drag-and-drop or startup-param UX concept.
- Enable/disable is exposed and stored but does not yet regenerate startup parameters.
- update/remove are synchronous and should become background jobs.
- caching and cleanup policy need product-level design, not just ad hoc scripts.
- `-mod=` / `-serverMod=` generation still needs a safe structured implementation.
- Steam keyword/tag search currently searches the local Panel catalog and links to Steam's app-scoped Workshop search; direct Steam Web API search is Phase 2.
- Some repository docs still describe the abandoned addonsmanager Workshop direction and should be treated as historical until updated.
## Scheduler Integration
Workshop updates use the existing `cron` / Scheduler system. No second Workshop scheduler should be created.
Supported scheduler action keys:
- `workshop_update`
- `workshop_update_and_restart`
- `workshop_download_only`
- `workshop_install_pending_on_restart`
Compatibility Server Content keys remain available:
- `server_content_check_workshop_updates`
- `server_content_update_workshop`
- `server_content_install_updates_next_restart`
- `server_content_install_updates_and_restart`
Per-item update policy values stored on `server_content_workshop.update_policy`:
- `manual`
- `scheduled`
- `update_now`
- `update_and_restart`
- `download_only`
- `install_on_restart`
Scheduler behavior for Workshop should be evaluated against the dedicated module, not inferred from `addonsmanager`.
## Troubleshooting
| 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 generates a per-job script under `gsp_server_content/jobs/workshop/`. |
| `SteamCMD is missing on the agent host.` | The generated job could not find SteamCMD at `STEAMCMD_PATH` or common locations. | Install SteamCMD on the agent or set `STEAMCMD_PATH` for the agent environment. |
| `Workshop App ID is missing` | The selected game XML does not provide `workshop_support/workshop_app_id`. | Add a canonical `workshop_support` block to the game XML and validate it. |
| `This game XML does not enable Steam Workshop support` | The user opened Workshop for a game whose XML lacks enabled Workshop capability. | Add `workshop_support` with `enabled` and `workshop_app_id`, or do not expose Workshop for that game. |
| 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. |
| `Steam Workshop Mods` appears under `Server Content` | Old addonsmanager Workshop category logic is still present. | Remove the `workshop_item` category from Server Content UI and use the dedicated `steam_workshop` module. |
## Recommended Mental Model
Use `addonsmanager` as the main future home for:
- mods
- add-ons
- Workshop items
- scripts
- config packs
- server content manifests
- install history
Treat `steam_workshop` as a legacy bridge for migration only.
Use `steam_workshop` for Workshop. Use `addonsmanager` for normal Server Content items 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
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.
2. Panel writes `{SERVER_HOME}/gsp_server_content/workshop_manifest.json`.
3. Panel writes a generated per-job script under `{SERVER_HOME}/gsp_server_content/jobs/workshop/`.
4. The job script writes a temporary SteamCMD runscript.
5. Panel invokes the job script through the existing authenticated agent `exec` RPC.
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:
- `home_id`
- `home_cfg_id`
- `Panel/modules/steam_workshop` remains the active module in this repository checkout.
- `game_path`
- `server_path`
- `workshop_app_id`

View file

@ -32,7 +32,7 @@ This is the master module inventory for the Panel. Use it as the first stop befo
| [`server`](server.md) | Remote server and node manager | Production / administrative | Keep / Improve |
| [`settings`](settings.md) | Panel settings and themes | Production | Keep |
| [`status`](status.md) | Status page | Experimental / alpha | Rewrite / Deprecate |
| [`steam_workshop`](steam_workshop.md) | Legacy Workshop module | Deprecated | Deprecate / Merge |
| [`steam_workshop`](steam_workshop.md) | Dedicated Workshop module | Functional | Keep |
| [`subusers`](subusers.md) | Subuser permissions | Functional | Keep / Improve |
| [`support`](support.md) | Support landing page | Functional | Keep / Merge with tickets workflow |
| [`teamspeak3`](teamspeak3.md) | Teamspeak 3 web interface | Functional if sold | Keep or hide based on product line |

View file

@ -4,7 +4,7 @@ Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## 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 work.
The module title has already been moved toward `Server Content Manager`, but the schema and some folder names remain backward-compatible.
@ -13,8 +13,6 @@ Important files:
- `Panel/modules/addonsmanager/module.php`
- `Panel/modules/addonsmanager/addons_manager.php`
- `Panel/modules/addonsmanager/user_addons.php`
- `Panel/modules/addonsmanager/workshop_content.php`
- `Panel/modules/addonsmanager/workshop_action.php`
- `Panel/modules/addonsmanager/server_content_helpers.php`
- `Panel/modules/addonsmanager/server_content_categories.php`
@ -34,116 +32,21 @@ The module can already represent several content types, including:
- downloads/extracted packages
- post-script driven installs
- workshop-oriented items
- config packs
- future profile-type content
For Workshop items, the current flow lets users enter Workshop IDs or full Steam Workshop URLs and routes the install through module pages, staged manifests, and Panel-bundled scripts executed through existing agent primitives.
## Workshop Phase 1 Flow
1. Admin enables Workshop by adding a canonical `workshop_support` block to the game XML.
2. Server Content Manager detects that capability from the selected server's XML.
3. User opens `Server Content` from the game monitor.
4. User selects the Steam Workshop Mods category. A Server Content template is no longer required just to expose Workshop for XML-enabled games.
5. User enters one or more Workshop URLs or numeric IDs, searches the local catalog, or opens Steam's app-scoped Workshop search from the page.
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`.
8. Panel writes a generated per-job shell script into `{SERVER_HOME}/gsp_server_content/jobs/workshop/`.
9. The generated job script creates a temporary SteamCMD runscript containing `workshop_download_item <appid> <workshop_id> validate`.
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 XML-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.
Current job-script behavior:
- Server Content Manager generates a new job script for each Workshop action.
- Game XML does not define static Workshop script paths.
- 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:
- Generic Steam Workshop content: `{SERVER_ROOT}/workshop/{MOD_FOLDER}`
- DayZ / Arma strategy content: `{SERVER_ROOT}/{MOD_FOLDER}` for root `@<workshop_id>` folder compatibility
Game XML must use the canonical `workshop_support` block:
```xml
<workshop_support>
<enabled>1</enabled>
<provider>steam</provider>
<steam_app_id>107410</steam_app_id>
<workshop_app_id>107410</workshop_app_id>
<download_method>steamcmd</download_method>
<install_strategy>arma_mod_folder</install_strategy>
<install_path>{SERVER_ROOT}/{MOD_FOLDER}</install_path>
<startup_param_format>-mod={MOD_LIST}</startup_param_format>
<mod_separator>;</mod_separator>
<mod_prefix>@</mod_prefix>
<copy_keys enabled="1">
<source_pattern>{MOD_PATH}/keys/*.bikey</source_pattern>
<target_path>{SERVER_ROOT}/keys</target_path>
</copy_keys>
<post_install_action></post_install_action>
</workshop_support>
```
The Panel helper parser reads this block as the source of truth. Server Content admin forms do not collect Workshop app IDs, install paths, launch parameter additions, optional mod folder names, or static Workshop scripts.
SteamCMD requirements:
- 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 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.
The legacy `steam_workshop` monitor button is intentionally suppressed so users are not sent to the deprecated standalone module.
## Current User Controls
The `workshop_content.php` page supports:
- direct install by numeric ID or Steam Workshop URL
- keyword/tag search against the local catalog
- app-scoped Steam Workshop search links for the selected game
- a list of Workshop-enabled games matching the current search terms
- installed item list
- enable/disable selected items
- update selected items
- remove selected items
- download selected items without installing immediately
- update all saved Workshop items
- per-item update policy storage
- known/common item catalog sorted by name, Workshop ID, install count, published date, last updated, or last installed
Update policies are stored as data for Scheduler/automation:
- `manual`
- `scheduled`
- `update_now`
- `update_and_restart`
- `download_only`
- `install_on_restart`
Steam Workshop is no longer a user-facing Server Content category. Workshop access belongs to the dedicated `steam_workshop` module.
## Current Limitations
- Workshop and content metadata is still partial.
- Load order is tracked but not yet reorderable through a polished drag-and-drop UI.
- Enable/disable is tracked but not wired into startup-parameter generation yet.
- Async install job progress should be more visible.
- Install strategies are still being broadened and need consistent game-specific rules.
- DayZ/Arma style key-copy is implemented for Phase 1; startup-param behavior still needs a stronger canonical implementation.
- Cache and cleanup policy need a clearer product design.
- Direct Steam Web API keyword/tag search is not implemented yet; the current search page uses local catalog records and links out to Steam's Workshop search.
## Where To Start Reading
1. `Panel/modules/addonsmanager/module.php`
2. `Panel/modules/addonsmanager/addons_manager.php`
3. `Panel/modules/addonsmanager/user_addons.php`
4. `Panel/modules/addonsmanager/workshop_content.php`
5. `Panel/modules/addonsmanager/workshop_action.php`
4. `Panel/modules/addonsmanager/server_content_categories.php`
## Important Concept
@ -151,14 +54,11 @@ This module is the right place for:
- mods
- add-ons
- Workshop content
- config packs
- script-driven installs
- server content manifests
- install history
The old `steam_workshop` module should be treated as a deprecated compatibility layer, not the main future path.
## Validation
Relevant smoke tests:

View file

@ -33,6 +33,7 @@ Current listing flow uses `remote_dirlistfm`, where agent filenames are treated
- browse files
- upload/download
- edit common configs
- use the green `Up one Level` button for parent-directory navigation on mobile and desktop
Special-character names are supported end-to-end in browse/navigation/actions, including:
@ -84,4 +85,3 @@ Path safety model:
## Recommendation
- Keep / Improve

View file

@ -4,12 +4,12 @@ Workspace reference: [`GSP-WORKSPACE.md`](../../../GSP-WORKSPACE.md)
## Purpose
Legacy standalone Steam Workshop support.
Dedicated Steam Workshop support for game servers.
## Current Status
- Deprecated
- Compatibility only
- Active in this repository checkout
- User-facing Workshop module
## Dependencies
@ -28,30 +28,48 @@ Legacy standalone Steam Workshop support.
## User Workflow
- legacy workshop path only
- open the Steam Workshop monitor button from Game Monitor
- search by Workshop ID, Workshop URL, or keyword from the dedicated module
- search results are scoped to the current game's configured Workshop App ID
- select one or more search results with checkboxes and install them through the existing workflow
- manual Workshop ID entry remains available as a fallback
- install/update/uninstall Workshop items through the dedicated module
## Admin Workflow
- legacy migration / compatibility
- configure Workshop game XML files under `Panel/modules/steam_workshop/game_configs/`
- use `workshop_admin.php` for module administration
## Search Backend
- discovery is server-side in `Panel/modules/steam_workshop/main.php`
- the panel searches Steam Community Workshop browse results for the current game App ID
- result metadata is hydrated with `ISteamRemoteStorage/GetPublishedFileDetails`
- no Steam API key is currently required for the user-facing search flow
- selected result IDs and manual IDs are deduplicated before the existing install RPC runs
## UI Notes
- the main Workshop page `Back` link is rendered as a real panel button
- uninstall remains in the dedicated `steam_workshop` module
## Security Concerns
- should not compete with the current Server Content Manager
- should not be duplicated under `addonsmanager`
## Known Issues
- explicitly deprecated in code comments
- some repository docs still describe this module as deprecated
## Missing Functionality
- modern unified Workshop/content UX
- documentation cleanup so all references match the current module ownership
## Suggested Future Improvements
- keep only compatibility helpers
- migrate users into `addonsmanager`
- keep Workshop links and workflows isolated to this module
- remove old addonsmanager Workshop assumptions
## Recommendation
- Deprecate / Merge
- Keep as the dedicated Workshop module