feat(steam_workshop): production rewrite with full admin profile page and server settings

- module.php: bump db_version to 2; full v2 schema in install_queries[0]; ALTER TABLE migration in install_queries[2] adding 11 new profile columns plus server_workshop_settings table
- WorkshopRepository: expand saveProfile() with all new fields (steam_app_id, steamcmd_login_mode, steamcmd_path, mod_separator, copy_keys, key paths, pre/post scripts, validation_notes); add nullOrStr helper; add server settings CRUD (getServerSettings, saveServerSettings, recordUpdateResult, setUpdateQueued, listQueuedUpdateHomes); update insertOrUpdateMod with custom_folder; update listAllEnabledMods to select new columns
- WorkshopProfileController: full extractProfileData() with all new fields; validateProfileData with folder template check
- views/admin/profile_form.php: full rewrite – all required fields (steam_app_id, workshop_app_id, login mode, SteamCMD path, OS, cache path, install path, folder naming dropdown, launch params, mod separator, copy method, copy keys with JS show/hide, key paths, pre/per-mod/post bash scripts with DayZ example, validation notes, config file template)
- views/admin/profiles.php: updated list view columns (App IDs, Login, Method)
- WorkshopInstaller.php: full rewrite with %var% template support (+ legacy {var} compat); buildTemplateVars() resolves all 14 variables; pre/post script execution; triggerSteamCmdDownload uses new profile fields; copyKeys helper
- WorkshopModController: add save_settings and queue_update POST actions; handleModsPage loads serverSettings + allProfiles
- views/user_workshop_mods.php: full rewrite – server settings form (enable, profile selector, update mode, restart behavior), update status grid (status/error/time/success time), queue update button, mod table with custom_folder column and toggle/order auto-submit
- lang/en_US.php: ~80 new string keys for all v2 fields
- steam_workshop.css: new v2 styles (3-col grid, script textarea, status grid, server settings card, badges)"

Agent-Logs-Url: https://github.com/GameServerPanel/GSP/sessions/e7f0d80d-f775-4794-adbd-cf48b55bc9c1

Co-authored-by: iaretechnician <2749183+iaretechnician@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-05-04 19:49:36 +00:00 committed by GitHub
parent 199b398543
commit 69f415ad86
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 1334 additions and 312 deletions

View file

@ -23,33 +23,49 @@
*/
// Module general information
$module_title = "Steam Workshop";
$module_version = "2.2";
$db_version = 1;
$module_version = "2.3";
$db_version = 2;
$module_required = TRUE;
$module_menus = array();
// Database schema: create the three Workshop tables when the module is installed.
// $install_queries[0] is run during initial install (from db_version 0 to 1).
// Each table uses IF NOT EXISTS so re-running is safe.
// -----------------------------------------------------------------------
// $install_queries[0] run during FRESH install (all keys executed).
// $install_queries[2] run when upgrading an existing v1 install to v2.
// -----------------------------------------------------------------------
$install_queries = array();
// Full schema for fresh installs (includes every column from all versions).
$install_queries[0] = array(
"CREATE TABLE IF NOT EXISTS `".OGP_DB_PREFIX."workshop_game_profiles` (
`id` INT NOT NULL AUTO_INCREMENT,
`game_key` VARCHAR(100) NOT NULL,
`game_name` VARCHAR(255) NOT NULL,
`workshop_app_id` VARCHAR(32) NOT NULL,
`id` INT NOT NULL AUTO_INCREMENT,
`game_key` VARCHAR(100) NOT NULL,
`game_name` VARCHAR(255) NOT NULL,
`steam_app_id` VARCHAR(32) NOT NULL DEFAULT '',
`workshop_app_id` VARCHAR(32) NOT NULL,
`steam_login_required` TINYINT(1) NOT NULL DEFAULT 0,
`steamcmd_login_mode` ENUM('anonymous','account') NOT NULL DEFAULT 'anonymous',
`steamcmd_path` VARCHAR(512) NOT NULL DEFAULT '',
`supported_os` SET('linux','windows') NOT NULL DEFAULT 'linux',
`cache_path_template` TEXT NOT NULL,
`install_path_template` TEXT NOT NULL,
`folder_name_template` VARCHAR(255) NOT NULL DEFAULT '@{mod_id}',
`copy_method` ENUM('rsync','robocopy','custom_script') NOT NULL DEFAULT 'rsync',
`install_script` TEXT NULL,
`config_file_template` TEXT NULL,
`launch_param_template` TEXT NULL,
`requires_restart` TINYINT(1) NOT NULL DEFAULT 1,
`enabled` TINYINT(1) NOT NULL DEFAULT 1,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NULL,
`cache_path_template` TEXT NOT NULL,
`install_path_template` TEXT NOT NULL,
`folder_naming_format` ENUM('@%mod_name%','@%workshop_id%','custom') NOT NULL DEFAULT '@%workshop_id%',
`folder_name_template` VARCHAR(255) NOT NULL DEFAULT '@%workshop_id%',
`mod_launch_param` VARCHAR(512) NOT NULL DEFAULT '',
`mod_separator` ENUM('semicolon','comma','space') NOT NULL DEFAULT 'semicolon',
`copy_method` ENUM('copy','rsync','symlink') NOT NULL DEFAULT 'rsync',
`copy_keys` TINYINT(1) NOT NULL DEFAULT 0,
`key_source_path` TEXT NULL,
`key_dest_path` TEXT NULL,
`pre_update_script` TEXT NULL,
`install_script` TEXT NULL,
`post_update_script` TEXT NULL,
`config_file_template` TEXT NULL,
`launch_param_template` TEXT NULL,
`requires_restart` TINYINT(1) NOT NULL DEFAULT 1,
`validation_notes` TEXT NULL,
`enabled` TINYINT(1) NOT NULL DEFAULT 1,
`created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`updated_at` DATETIME NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_game_key` (`game_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
@ -78,6 +94,7 @@ $install_queries[0] = array(
`workshop_app_id` VARCHAR(32) NOT NULL,
`workshop_id` VARCHAR(64) NOT NULL,
`title` VARCHAR(255) NULL,
`custom_folder` VARCHAR(255) NOT NULL DEFAULT '',
`enabled` TINYINT(1) NOT NULL DEFAULT 1,
`install_path` TEXT NOT NULL,
`load_order` INT NOT NULL DEFAULT 0,
@ -85,5 +102,62 @@ $install_queries[0] = array(
`updated_at` DATETIME NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uniq_home_workshop` (`home_id`, `workshop_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci",
"CREATE TABLE IF NOT EXISTS `".OGP_DB_PREFIX."server_workshop_settings` (
`home_id` INT NOT NULL,
`workshop_enabled` TINYINT(1) NOT NULL DEFAULT 0,
`profile_id` INT NULL,
`update_mode` ENUM('manual','scheduled','on_restart') NOT NULL DEFAULT 'manual',
`restart_behavior` ENUM('none','queue','stop_update_start') NOT NULL DEFAULT 'none',
`update_queued` TINYINT(1) NOT NULL DEFAULT 0,
`last_update_status` VARCHAR(20) NOT NULL DEFAULT '',
`last_update_error` TEXT NULL,
`last_update_time` DATETIME NULL,
`last_success_time` DATETIME NULL,
`updated_at` DATETIME NULL,
PRIMARY KEY (`home_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
);
// Migration: upgrade existing v1 installs to v2 schema.
$install_queries[2] = array(
// New columns on workshop_game_profiles
"ALTER TABLE `".OGP_DB_PREFIX."workshop_game_profiles`
ADD COLUMN IF NOT EXISTS `steam_app_id` VARCHAR(32) NOT NULL DEFAULT '' AFTER `game_name`,
ADD COLUMN IF NOT EXISTS `steam_login_required` TINYINT(1) NOT NULL DEFAULT 0 AFTER `workshop_app_id`,
ADD COLUMN IF NOT EXISTS `steamcmd_login_mode` ENUM('anonymous','account') NOT NULL DEFAULT 'anonymous' AFTER `steam_login_required`,
ADD COLUMN IF NOT EXISTS `steamcmd_path` VARCHAR(512) NOT NULL DEFAULT '' AFTER `steamcmd_login_mode`,
ADD COLUMN IF NOT EXISTS `folder_naming_format` ENUM('@%mod_name%','@%workshop_id%','custom') NOT NULL DEFAULT '@%workshop_id%' AFTER `install_path_template`,
ADD COLUMN IF NOT EXISTS `mod_launch_param` VARCHAR(512) NOT NULL DEFAULT '' AFTER `folder_name_template`,
ADD COLUMN IF NOT EXISTS `mod_separator` ENUM('semicolon','comma','space') NOT NULL DEFAULT 'semicolon' AFTER `mod_launch_param`,
ADD COLUMN IF NOT EXISTS `copy_keys` TINYINT(1) NOT NULL DEFAULT 0 AFTER `copy_method`,
ADD COLUMN IF NOT EXISTS `key_source_path` TEXT NULL AFTER `copy_keys`,
ADD COLUMN IF NOT EXISTS `key_dest_path` TEXT NULL AFTER `key_source_path`,
ADD COLUMN IF NOT EXISTS `pre_update_script` TEXT NULL AFTER `key_dest_path`,
ADD COLUMN IF NOT EXISTS `post_update_script` TEXT NULL AFTER `install_script`,
ADD COLUMN IF NOT EXISTS `validation_notes` TEXT NULL AFTER `requires_restart`",
// Rename copy_method enum values to match new options (copy/rsync/symlink)
// (existing 'rsync' stays valid; 'robocopy'/'custom_script' are legacy)
// New column on server_workshop_mods
"ALTER TABLE `".OGP_DB_PREFIX."server_workshop_mods`
ADD COLUMN IF NOT EXISTS `custom_folder` VARCHAR(255) NOT NULL DEFAULT '' AFTER `title`",
// New server-level settings table
"CREATE TABLE IF NOT EXISTS `".OGP_DB_PREFIX."server_workshop_settings` (
`home_id` INT NOT NULL,
`workshop_enabled` TINYINT(1) NOT NULL DEFAULT 0,
`profile_id` INT NULL,
`update_mode` ENUM('manual','scheduled','on_restart') NOT NULL DEFAULT 'manual',
`restart_behavior` ENUM('none','queue','stop_update_start') NOT NULL DEFAULT 'none',
`update_queued` TINYINT(1) NOT NULL DEFAULT 0,
`last_update_status` VARCHAR(20) NOT NULL DEFAULT '',
`last_update_error` TEXT NULL,
`last_update_time` DATETIME NULL,
`last_success_time` DATETIME NULL,
`updated_at` DATETIME NULL,
PRIMARY KEY (`home_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
);