feat: redesign SCM workshop handling – remove workshop_item_id requirement, add user ID entry, deprecate steam_workshop menu
- server_content_helpers.php: remove workshop_item_id from required fields/validation; support newline-separated IDs; add scm_validate_workshop_user_ids(); update help text; add new template policy columns to ensure_phase2_schema; add content_id guard to ensure_workshop_schema - addons_manager.php: rename admin workshop_item_id row to "Default Workshop IDs (Optional)" with updated label - user_addons.php: route workshop_item type to workshop_content page instead of addons installer - workshop_content.php: accept addon_id param; show template info; use textarea for multi-ID entry; update heading/help text - workshop_action.php: accept addon_id param; resolve workshop_app_id from addon template; pass extra_manifest to manifest-and-run; store content_id on insert; use newline/comma-separated IDs - addons_installer.php: redirect workshop_item addon_type to workshop_content page - module.php: db_version 6 with allow_user_workshop_ids, max_workshop_ids, required_workshop_ids, blocked_workshop_ids on addons; content_id on server_content_workshop - server_content_categories.php: rename "Steam Workshop Item" → "Steam Workshop Mods" - steam_workshop/module.php: empty $module_menus, mark deprecated, bump version to 3.3 - addonsmanager.js: remove #scm-row-workshop-id from steam_workshop admin rows Agent-Logs-Url: https://github.com/GameServerPanel/GSP/sessions/6a328ac8-2f82-4943-93a9-7660bf42a2fd Co-authored-by: iaretechnician <2749183+iaretechnician@users.noreply.github.com>
This commit is contained in:
parent
cc041c9bc6
commit
6dd5088613
10 changed files with 263 additions and 59 deletions
|
|
@ -9,7 +9,7 @@ $(function() {
|
|||
|
||||
var methodToRows = {
|
||||
download_zip: ['#scm-row-url', '#scm-row-path'],
|
||||
steam_workshop: ['#scm-row-workshop-id', '#scm-row-workshop-app-id', '#scm-row-target-path-template', '#scm-row-optional-folder-name', '#scm-row-post-script', '#scm-row-launch-param-additions'],
|
||||
steam_workshop: ['#scm-row-workshop-app-id', '#scm-row-target-path-template', '#scm-row-optional-folder-name', '#scm-row-post-script', '#scm-row-launch-param-additions'],
|
||||
post_script: ['#scm-row-post-script'],
|
||||
config_edit: ['#scm-row-path', '#scm-row-config-edit-rule']
|
||||
};
|
||||
|
|
|
|||
|
|
@ -544,6 +544,27 @@ function exec_ogp_module() {
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
// Workshop items are managed through the dedicated workshop_content page
|
||||
// where users enter their own Workshop IDs. Redirect there immediately.
|
||||
if ($addon_type === 'workshop_item') {
|
||||
$first_addon_id = 0;
|
||||
$wk_addons = $db->resultQuery(
|
||||
"SELECT addon_id FROM OGP_DB_PREFIXaddons
|
||||
WHERE addon_type='workshop_item' AND home_cfg_id=" . (int)$home_cfg_id . $query_groups . "
|
||||
ORDER BY name ASC LIMIT 1"
|
||||
);
|
||||
if (is_array($wk_addons) && !empty($wk_addons[0]['addon_id'])) {
|
||||
$first_addon_id = (int)$wk_addons[0]['addon_id'];
|
||||
}
|
||||
$redirect = "?m=addonsmanager&p=workshop_content&home_id=" . (int)$home_id .
|
||||
"&mod_id=" . (int)$mod_id . "&ip=" . urlencode($ip) . "&port=" . urlencode($port) .
|
||||
($first_addon_id > 0 ? "&addon_id=" . $first_addon_id : '');
|
||||
$view->refresh($redirect);
|
||||
echo "<p>Redirecting to Workshop Content manager…<br>";
|
||||
echo "<a href='" . htmlspecialchars($redirect, ENT_QUOTES, 'UTF-8') . "'>Click here if not redirected.</a></p>";
|
||||
return;
|
||||
}
|
||||
?>
|
||||
<?php
|
||||
$category_labels = get_server_content_categories();
|
||||
|
|
|
|||
|
|
@ -198,11 +198,11 @@ function exec_ogp_module() {
|
|||
</tr>
|
||||
<tr id="scm-row-workshop-id">
|
||||
<td align="right">
|
||||
<b><?php print_lang('workshop_id'); ?></b>
|
||||
<b>Default Workshop IDs (Optional)</b>
|
||||
</td>
|
||||
<td align="left">
|
||||
<input type="text" value="<?php echo htmlspecialchars($workshop_item_id, ENT_QUOTES, 'UTF-8'); ?>" name="workshop_item_id" size="85" placeholder="e.g. 450814997" />
|
||||
<small style="color:#666;">Example Arma 3 Workshop ID: 450814997</small>
|
||||
<input type="text" value="<?php echo htmlspecialchars($workshop_item_id, ENT_QUOTES, 'UTF-8'); ?>" name="workshop_item_id" size="85" placeholder="Leave blank – users enter Workshop IDs on their server page" />
|
||||
<small style="color:#666;">Optional. Users enter the actual Workshop IDs they want installed from their own server page. This field is not required.</small>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="scm-row-workshop-app-id">
|
||||
|
|
|
|||
|
|
@ -18,13 +18,20 @@
|
|||
* backup_before_install / restart_after_install / is_cacheable /
|
||||
* description columns to addons table; add server_content_manifest
|
||||
* and server_content_install_history tables
|
||||
* 5 – add workshop_item_id / workshop_app_id / target_path_template /
|
||||
* optional_folder_name / config_edit_rule / launch_param_additions
|
||||
* columns to addons table
|
||||
* 6 – add admin template policy columns to addons table
|
||||
* (allow_user_workshop_ids, max_workshop_ids, required_workshop_ids,
|
||||
* blocked_workshop_ids); add content_id column to
|
||||
* server_content_workshop so user installs link to their template
|
||||
*
|
||||
*/
|
||||
|
||||
// Module general information
|
||||
$module_title = "Server Content Manager";
|
||||
$module_version = "2.3";
|
||||
$db_version = 5;
|
||||
$module_version = "2.4";
|
||||
$db_version = 6;
|
||||
$module_required = TRUE;
|
||||
$module_menus = array(
|
||||
array( 'subpage' => 'addons_manager', 'name' => 'Server Content Manager', 'group' => 'admin' )
|
||||
|
|
@ -196,4 +203,61 @@ $install_queries[4] = array(
|
|||
return true;
|
||||
},
|
||||
);
|
||||
// ── db_version 6 : admin template policy columns + content_id on workshop rows ──
|
||||
//
|
||||
// allow_user_workshop_ids – whether users may enter their own IDs (default 1)
|
||||
// max_workshop_ids – optional cap on how many IDs a user may install
|
||||
// required_workshop_ids – JSON list of IDs that must always be installed
|
||||
// blocked_workshop_ids – JSON list of IDs that must not be installed
|
||||
// content_id on server_content_workshop – links a user install row back to
|
||||
// the admin content template so the correct workshop_app_id is used.
|
||||
//
|
||||
$install_queries[5] = array(
|
||||
function ($db) {
|
||||
$prefix = OGP_DB_PREFIX;
|
||||
|
||||
// ── New policy columns on the addons (content template) table ─────────
|
||||
$addon_columns = array(
|
||||
'allow_user_workshop_ids' => "TINYINT(1) NOT NULL DEFAULT 1 AFTER `blocked_workshop_ids`",
|
||||
'max_workshop_ids' => "INT NULL AFTER `allow_user_workshop_ids`",
|
||||
'required_workshop_ids' => "TEXT NULL AFTER `max_workshop_ids`",
|
||||
'blocked_workshop_ids' => "TEXT NULL AFTER `launch_param_additions`",
|
||||
);
|
||||
foreach ($addon_columns as $col => $definition) {
|
||||
$escaped_col = $db->realEscapeSingle($col);
|
||||
$escaped_table = $db->realEscapeSingle($prefix . 'addons');
|
||||
$check = $db->resultQuery(
|
||||
"SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = '{$escaped_table}'
|
||||
AND COLUMN_NAME = '{$escaped_col}'"
|
||||
);
|
||||
if (empty($check)) {
|
||||
if (!$db->query("ALTER TABLE `{$prefix}addons` ADD COLUMN `{$col}` {$definition}")) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── content_id on server_content_workshop ─────────────────────────────
|
||||
$wk_table = $db->realEscapeSingle($prefix . 'server_content_workshop');
|
||||
$col_check = $db->resultQuery(
|
||||
"SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = '{$wk_table}'
|
||||
AND COLUMN_NAME = 'content_id'"
|
||||
);
|
||||
if (empty($col_check)) {
|
||||
if (!$db->query(
|
||||
"ALTER TABLE `{$prefix}server_content_workshop`
|
||||
ADD COLUMN `content_id` INT NULL AFTER `id`,
|
||||
ADD KEY `idx_content_id` (`content_id`)"
|
||||
)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
);
|
||||
?>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ function get_server_content_categories()
|
|||
{
|
||||
return array(
|
||||
'file_download' => 'Downloadable Mod',
|
||||
'workshop_item' => 'Steam Workshop Item',
|
||||
'workshop_item' => 'Steam Workshop Mods',
|
||||
'config_edit' => 'Configuration Package',
|
||||
'scripted_installer' => 'Scripted Installer',
|
||||
);
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ function scm_ensure_workshop_schema($db)
|
|||
$schema_checked = true;
|
||||
|
||||
$db->query("ALTER TABLE `".OGP_DB_PREFIX."addons` MODIFY `addon_type` VARCHAR(32) NOT NULL");
|
||||
return (bool)$db->query(
|
||||
$ok = (bool)$db->query(
|
||||
"CREATE TABLE IF NOT EXISTS `".OGP_DB_PREFIX."server_content_workshop` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
||||
`home_id` INT NOT NULL,
|
||||
|
|
@ -43,6 +43,24 @@ function scm_ensure_workshop_schema($db)
|
|||
KEY `idx_install_state` (`install_state`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"
|
||||
);
|
||||
|
||||
// Idempotently add content_id column (db_version 6).
|
||||
$wk_table = $db->realEscapeSingle(OGP_DB_PREFIX . 'server_content_workshop');
|
||||
$col_check = $db->resultQuery(
|
||||
"SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = '{$wk_table}'
|
||||
AND COLUMN_NAME = 'content_id'"
|
||||
);
|
||||
if (empty($col_check)) {
|
||||
$db->query(
|
||||
"ALTER TABLE `".OGP_DB_PREFIX."server_content_workshop`
|
||||
ADD COLUMN `content_id` INT NULL AFTER `id`,
|
||||
ADD KEY `idx_content_id` (`content_id`)"
|
||||
);
|
||||
}
|
||||
|
||||
return $ok;
|
||||
}
|
||||
|
||||
function scm_get_home_for_user($db, $home_id, $user_id)
|
||||
|
|
@ -89,7 +107,9 @@ function scm_parse_workshop_ids($raw, &$invalid = array())
|
|||
{
|
||||
$invalid = array();
|
||||
$ids = array();
|
||||
$parts = explode(',', (string)$raw);
|
||||
// Accept IDs separated by commas, newlines, or a mix of both.
|
||||
$normalized = str_replace(array("\r\n", "\r", "\n"), ',', (string)$raw);
|
||||
$parts = explode(',', $normalized);
|
||||
foreach ((array)$parts as $part) {
|
||||
$value = trim((string)$part);
|
||||
if ($value === '') {
|
||||
|
|
@ -323,7 +343,7 @@ function scm_get_install_methods()
|
|||
{
|
||||
return array(
|
||||
'download_zip' => 'Downloadable Mod',
|
||||
'steam_workshop' => 'Steam Workshop Item',
|
||||
'steam_workshop' => 'Steam Workshop Mods',
|
||||
'config_edit' => 'Configuration Package',
|
||||
'post_script' => 'Scripted Installer',
|
||||
);
|
||||
|
|
@ -333,7 +353,7 @@ function scm_get_install_method_help_text()
|
|||
{
|
||||
return array(
|
||||
'download_zip' => 'Download and extract a ZIP, RAR, or archive file.',
|
||||
'steam_workshop' => 'Install a Steam Workshop mod using Workshop ID.',
|
||||
'steam_workshop' => 'Configure how users may install Steam Workshop items for this game. Users enter the actual Workshop IDs from their server page.',
|
||||
'config_edit' => 'Install configuration files, profiles, or templates.',
|
||||
'post_script' => 'Run a custom scripted installation process.',
|
||||
);
|
||||
|
|
@ -342,20 +362,20 @@ function scm_get_install_method_help_text()
|
|||
function scm_get_install_method_required_fields()
|
||||
{
|
||||
return array(
|
||||
'download_zip' => array('url'),
|
||||
'steam_workshop' => array('workshop_item_id'),
|
||||
'post_script' => array('post_script'),
|
||||
'config_edit' => array('path', 'config_edit_rule'),
|
||||
'download_zip' => array('url'),
|
||||
'steam_workshop' => array(), // No required fields; users provide Workshop IDs on their server page
|
||||
'post_script' => array('post_script'),
|
||||
'config_edit' => array('path', 'config_edit_rule'),
|
||||
);
|
||||
}
|
||||
|
||||
function scm_get_install_method_validation_errors()
|
||||
{
|
||||
return array(
|
||||
'download_zip' => 'Please enter a download URL.',
|
||||
'steam_workshop' => 'Please enter a Workshop ID.',
|
||||
'config_edit' => 'Please enter the config target and edit action.',
|
||||
'post_script' => 'Please enter the installer script/action.',
|
||||
'download_zip' => 'Please enter a download URL.',
|
||||
'steam_workshop' => 'Please configure Workshop App ID or ensure the game XML provides one.',
|
||||
'config_edit' => 'Please enter the config target and edit action.',
|
||||
'post_script' => 'Please enter the installer script/action.',
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -433,9 +453,8 @@ function scm_validate_download_content(array $payload, &$message = '')
|
|||
|
||||
function scm_validate_workshop_content(array $payload, &$message = '')
|
||||
{
|
||||
if (!scm_validate_numeric_content_value(isset($payload['workshop_item_id']) ? $payload['workshop_item_id'] : '', 'Please enter a Workshop ID.', $message, false)) {
|
||||
return false;
|
||||
}
|
||||
// workshop_item_id is NOT required for admin content templates.
|
||||
// Users supply Workshop IDs on their server page (workshop_content.php).
|
||||
if (!scm_validate_numeric_content_value(isset($payload['workshop_app_id']) ? $payload['workshop_app_id'] : '', 'Workshop App ID must be numeric.', $message, true)) {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -448,6 +467,22 @@ function scm_validate_workshop_content(array $payload, &$message = '')
|
|||
return true;
|
||||
}
|
||||
|
||||
function scm_validate_workshop_user_ids($raw_ids, &$message = '')
|
||||
{
|
||||
$invalid = array();
|
||||
$ids = scm_parse_workshop_ids($raw_ids, $invalid);
|
||||
if (!empty($invalid)) {
|
||||
$message = 'Invalid Workshop IDs: ' . implode(', ', $invalid);
|
||||
return false;
|
||||
}
|
||||
if (empty($ids)) {
|
||||
$message = 'Enter at least one numeric Workshop ID.';
|
||||
return false;
|
||||
}
|
||||
$message = '';
|
||||
return true;
|
||||
}
|
||||
|
||||
function scm_validate_scripted_installer(array $payload, &$message = '')
|
||||
{
|
||||
$script = isset($payload['post_script']) ? trim((string)$payload['post_script']) : '';
|
||||
|
|
@ -497,11 +532,13 @@ function scm_validate_install_method_payload($install_method, array $payload, &$
|
|||
|
||||
function scm_build_workshop_runtime_context($db, array $home_info, $server_xml, array $payload, &$message = '')
|
||||
{
|
||||
// workshop_item_id is now optional in admin templates; validate only the
|
||||
// numeric format constraints (workshop_app_id, optional_folder_name).
|
||||
if (!scm_validate_workshop_content($payload, $message)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$workshop_item_id = trim((string)$payload['workshop_item_id']);
|
||||
$workshop_item_id = trim((string)(isset($payload['workshop_item_id']) ? $payload['workshop_item_id'] : ''));
|
||||
$target_path_template = trim((string)$payload['target_path_template']);
|
||||
$optional_folder_name = trim((string)$payload['optional_folder_name']);
|
||||
$workshop_app_id_override = trim((string)$payload['workshop_app_id']);
|
||||
|
|
@ -662,6 +699,10 @@ function scm_ensure_phase2_schema($db)
|
|||
'optional_folder_name' => "VARCHAR(255) NULL",
|
||||
'config_edit_rule' => "TEXT NULL",
|
||||
'launch_param_additions'=> "VARCHAR(255) NULL",
|
||||
'allow_user_workshop_ids' => "TINYINT(1) NOT NULL DEFAULT 1",
|
||||
'max_workshop_ids' => "INT NULL",
|
||||
'required_workshop_ids' => "TEXT NULL",
|
||||
'blocked_workshop_ids' => "TEXT NULL",
|
||||
);
|
||||
foreach ($new_columns as $col => $definition) {
|
||||
$escaped_col = $db->realEscapeSingle($col);
|
||||
|
|
|
|||
|
|
@ -75,16 +75,28 @@ function exec_ogp_module() {
|
|||
else
|
||||
echo "<td>\n";
|
||||
$printed_any_cell = true;
|
||||
// Display label comes from the category map; the internal
|
||||
// addon_type key is passed in the URL for backward compatibility.
|
||||
echo "<a href='?m=addonsmanager&p=addons" .
|
||||
"&home_id=" . (int)$home_id .
|
||||
"&mod_id=" . (int)$mod_id .
|
||||
"&addon_type=" . urlencode($type_key) .
|
||||
"&ip=" . htmlspecialchars($ip) .
|
||||
"&port=" . htmlspecialchars($port) . "'>" .
|
||||
htmlspecialchars($type_label) . " (" . $items_qty . ")" .
|
||||
"</a>\n";
|
||||
// Workshop items route to the workshop_content page where users
|
||||
// enter their own Workshop IDs. All other types use the installer.
|
||||
if ($type_key === 'workshop_item') {
|
||||
$first_addon_id = isset($items[0]['addon_id']) ? (int)$items[0]['addon_id'] : 0;
|
||||
echo "<a href='?m=addonsmanager&p=workshop_content" .
|
||||
"&home_id=" . (int)$home_id .
|
||||
"&mod_id=" . (int)$mod_id .
|
||||
($first_addon_id > 0 ? "&addon_id=" . $first_addon_id : '') .
|
||||
"&ip=" . htmlspecialchars($ip) .
|
||||
"&port=" . htmlspecialchars($port) . "'>" .
|
||||
htmlspecialchars($type_label) . " (" . $items_qty . ")" .
|
||||
"</a>\n";
|
||||
} else {
|
||||
echo "<a href='?m=addonsmanager&p=addons" .
|
||||
"&home_id=" . (int)$home_id .
|
||||
"&mod_id=" . (int)$mod_id .
|
||||
"&addon_type=" . urlencode($type_key) .
|
||||
"&ip=" . htmlspecialchars($ip) .
|
||||
"&port=" . htmlspecialchars($port) . "'>" .
|
||||
htmlspecialchars($type_label) . " (" . $items_qty . ")" .
|
||||
"</a>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ function scm_workshop_write_manifest_and_run($db, array $home_info, $server_xml,
|
|||
return true;
|
||||
}
|
||||
|
||||
function scm_workshop_handle_action($db, array $home_info, $user_id, $action, $raw_ids, array $selected_ids, &$message, &$is_error)
|
||||
function scm_workshop_handle_action($db, array $home_info, $user_id, $action, $raw_ids, array $selected_ids, &$message, &$is_error, $addon_id = 0)
|
||||
{
|
||||
$message = '';
|
||||
$is_error = true;
|
||||
|
|
@ -150,14 +150,32 @@ function scm_workshop_handle_action($db, array $home_info, $user_id, $action, $r
|
|||
return false;
|
||||
}
|
||||
|
||||
$home_id = (int)$home_info['home_id'];
|
||||
$user_id = (int)$user_id;
|
||||
$home_id = (int)$home_info['home_id'];
|
||||
$user_id = (int)$user_id;
|
||||
$addon_id = (int)$addon_id;
|
||||
$server_xml = read_server_config(SERVER_CONFIG_LOCATION . "/" . $home_info['home_cfg_file']);
|
||||
if ($server_xml === false) {
|
||||
$message = 'Unable to read server configuration for workshop action.';
|
||||
return false;
|
||||
}
|
||||
|
||||
// Resolve the workshop_app_id: prefer the admin content template, fall
|
||||
// back to the game XML.
|
||||
$template_workshop_app_id = '';
|
||||
if ($addon_id > 0) {
|
||||
$tpl = $db->resultQuery(
|
||||
"SELECT workshop_app_id FROM `" . OGP_DB_PREFIX . "addons`
|
||||
WHERE addon_id=" . $addon_id . " AND install_method='steam_workshop'"
|
||||
);
|
||||
if (is_array($tpl) && !empty($tpl[0]['workshop_app_id'])) {
|
||||
$template_workshop_app_id = trim((string)$tpl[0]['workshop_app_id']);
|
||||
}
|
||||
}
|
||||
$extra_manifest = array();
|
||||
if ($template_workshop_app_id !== '') {
|
||||
$extra_manifest['workshop_app_id'] = $template_workshop_app_id;
|
||||
}
|
||||
|
||||
if ($action === 'install_new') {
|
||||
$invalid = array();
|
||||
$item_ids = scm_parse_workshop_ids($raw_ids, $invalid);
|
||||
|
|
@ -170,19 +188,36 @@ function scm_workshop_handle_action($db, array $home_info, $user_id, $action, $r
|
|||
return false;
|
||||
}
|
||||
|
||||
// Determine the resolved workshop_app_id for storage (template first, then XML).
|
||||
$resolved_app_id = $template_workshop_app_id !== ''
|
||||
? $template_workshop_app_id
|
||||
: scm_extract_workshop_app_id($server_xml);
|
||||
|
||||
// Check whether the content_id column exists (added in db_version 6).
|
||||
$has_content_id_col = (bool)$db->resultQuery(
|
||||
"SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
|
||||
WHERE TABLE_SCHEMA = DATABASE()
|
||||
AND TABLE_NAME = '" . $db->realEscapeSingle(OGP_DB_PREFIX . 'server_content_workshop') . "'
|
||||
AND COLUMN_NAME = 'content_id'"
|
||||
);
|
||||
|
||||
foreach ($item_ids as $item_id) {
|
||||
$content_id_col = $has_content_id_col && $addon_id > 0 ? ", content_id" : '';
|
||||
$content_id_val = $has_content_id_col && $addon_id > 0 ? ", " . $addon_id : '';
|
||||
$content_id_upd = $has_content_id_col && $addon_id > 0 ? ", content_id=VALUES(content_id)" : '';
|
||||
$query = "INSERT INTO `".OGP_DB_PREFIX."server_content_workshop`
|
||||
(home_id, home_cfg_id, remote_server_id, workshop_app_id, workshop_item_id, install_state, created_by, created_at, updated_at)
|
||||
(home_id, home_cfg_id, remote_server_id, workshop_app_id, workshop_item_id, install_state, created_by, created_at, updated_at" . $content_id_col . ")
|
||||
VALUES (
|
||||
".$home_id.",
|
||||
".(int)$home_info['home_cfg_id'].",
|
||||
".(int)$home_info['remote_server_id'].",
|
||||
'".$db->realEscapeSingle(scm_extract_workshop_app_id($server_xml))."',
|
||||
'".$db->realEscapeSingle($resolved_app_id)."',
|
||||
'".$db->realEscapeSingle($item_id)."',
|
||||
'selected',
|
||||
".$user_id.",
|
||||
NOW(),
|
||||
NOW()
|
||||
" . $content_id_val . "
|
||||
)
|
||||
ON DUPLICATE KEY UPDATE
|
||||
home_cfg_id=VALUES(home_cfg_id),
|
||||
|
|
@ -190,22 +225,22 @@ function scm_workshop_handle_action($db, array $home_info, $user_id, $action, $r
|
|||
workshop_app_id=VALUES(workshop_app_id),
|
||||
install_state='selected',
|
||||
last_error=NULL,
|
||||
updated_at=NOW()";
|
||||
updated_at=NOW()" . $content_id_upd;
|
||||
$db->query($query);
|
||||
}
|
||||
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'installing', null, false, false);
|
||||
$error = '';
|
||||
$ok = scm_workshop_write_manifest_and_run($db, $home_info, $server_xml, 'install', $item_ids, $error);
|
||||
$ok = scm_workshop_write_manifest_and_run($db, $home_info, $server_xml, 'install', $item_ids, $error, $extra_manifest);
|
||||
if ($ok) {
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'installed', null, true, true);
|
||||
scm_workshop_log_action($db, $home_id, $user_id, "install_new ids=".implode(',', $item_ids)." status=success");
|
||||
scm_workshop_log_action($db, $home_id, $user_id, "install_new ids=".implode(',', $item_ids)." addon_id=".$addon_id." status=success");
|
||||
$is_error = false;
|
||||
$message = 'Workshop IDs installed successfully.';
|
||||
return true;
|
||||
}
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'failed', $error, false, false);
|
||||
scm_workshop_log_action($db, $home_id, $user_id, "install_new ids=".implode(',', $item_ids)." status=failed error=".$error);
|
||||
scm_workshop_log_action($db, $home_id, $user_id, "install_new ids=".implode(',', $item_ids)." addon_id=".$addon_id." status=failed error=".$error);
|
||||
$message = $error;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -219,20 +254,20 @@ function scm_workshop_handle_action($db, array $home_info, $user_id, $action, $r
|
|||
$target_action = ($action === 'remove_selected') ? 'remove' : 'update';
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'installing', null, false, false);
|
||||
$error = '';
|
||||
$ok = scm_workshop_write_manifest_and_run($db, $home_info, $server_xml, $target_action, $item_ids, $error);
|
||||
$ok = scm_workshop_write_manifest_and_run($db, $home_info, $server_xml, $target_action, $item_ids, $error, $extra_manifest);
|
||||
if ($ok) {
|
||||
if ($target_action === 'remove') {
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'removed', null, false, true);
|
||||
} else {
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'installed', null, false, true);
|
||||
}
|
||||
scm_workshop_log_action($db, $home_id, $user_id, $action." ids=".implode(',', $item_ids)." status=success");
|
||||
scm_workshop_log_action($db, $home_id, $user_id, $action." ids=".implode(',', $item_ids)." addon_id=".$addon_id." status=success");
|
||||
$is_error = false;
|
||||
$message = ($target_action === 'remove') ? 'Selected Workshop IDs marked removed.' : 'Selected Workshop IDs updated successfully.';
|
||||
return true;
|
||||
}
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'failed', $error, false, false);
|
||||
scm_workshop_log_action($db, $home_id, $user_id, $action." ids=".implode(',', $item_ids)." status=failed error=".$error);
|
||||
scm_workshop_log_action($db, $home_id, $user_id, $action." ids=".implode(',', $item_ids)." addon_id=".$addon_id." status=failed error=".$error);
|
||||
$message = $error;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -255,16 +290,16 @@ function scm_workshop_handle_action($db, array $home_info, $user_id, $action, $r
|
|||
}
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'installing', null, false, false);
|
||||
$error = '';
|
||||
$ok = scm_workshop_write_manifest_and_run($db, $home_info, $server_xml, 'update', $item_ids, $error);
|
||||
$ok = scm_workshop_write_manifest_and_run($db, $home_info, $server_xml, 'update', $item_ids, $error, $extra_manifest);
|
||||
if ($ok) {
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'installed', null, false, true);
|
||||
scm_workshop_log_action($db, $home_id, $user_id, "update_all ids=".implode(',', $item_ids)." status=success");
|
||||
scm_workshop_log_action($db, $home_id, $user_id, "update_all ids=".implode(',', $item_ids)." addon_id=".$addon_id." status=success");
|
||||
$is_error = false;
|
||||
$message = 'All saved Workshop IDs updated successfully.';
|
||||
return true;
|
||||
}
|
||||
scm_workshop_update_rows_state($db, $home_id, $item_ids, 'failed', $error, false, false);
|
||||
scm_workshop_log_action($db, $home_id, $user_id, "update_all ids=".implode(',', $item_ids)." status=failed error=".$error);
|
||||
scm_workshop_log_action($db, $home_id, $user_id, "update_all ids=".implode(',', $item_ids)." addon_id=".$addon_id." status=failed error=".$error);
|
||||
$message = $error;
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
<?php
|
||||
/*
|
||||
*
|
||||
* GSP - Server Content Workshop page (Phase 1)
|
||||
* GSP - Server Content Workshop page
|
||||
*
|
||||
* Users enter Steam Workshop IDs to install on their server.
|
||||
* The admin defines the content template (game, app ID, install path).
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -16,6 +19,7 @@ function exec_ogp_module() {
|
|||
$mod_id = isset($_REQUEST['mod_id']) ? (int)$_REQUEST['mod_id'] : 0;
|
||||
$ip = isset($_REQUEST['ip']) ? (string)$_REQUEST['ip'] : '';
|
||||
$port = isset($_REQUEST['port']) ? (string)$_REQUEST['port'] : '';
|
||||
$addon_id = isset($_REQUEST['addon_id']) ? (int)$_REQUEST['addon_id'] : 0;
|
||||
|
||||
if ($home_id <= 0 || $user_id <= 0) {
|
||||
print_failure(get_lang('no_rights'));
|
||||
|
|
@ -35,6 +39,19 @@ function exec_ogp_module() {
|
|||
return;
|
||||
}
|
||||
|
||||
// Load the admin content template if an addon_id was provided.
|
||||
$addon_template = null;
|
||||
if ($addon_id > 0) {
|
||||
$template_rows = $db->resultQuery(
|
||||
"SELECT addon_id, name, workshop_app_id, target_path_template, optional_folder_name, description
|
||||
FROM `" . OGP_DB_PREFIX . "addons`
|
||||
WHERE addon_id=" . $addon_id . " AND install_method='steam_workshop'"
|
||||
);
|
||||
if (is_array($template_rows) && !empty($template_rows)) {
|
||||
$addon_template = $template_rows[0];
|
||||
}
|
||||
}
|
||||
|
||||
$message = '';
|
||||
$is_error = false;
|
||||
$entered_ids = '';
|
||||
|
|
@ -45,6 +62,7 @@ function exec_ogp_module() {
|
|||
$entered_ids = isset($_POST['workshop_ids']) ? (string)$_POST['workshop_ids'] : '';
|
||||
$selected_ids = isset($_POST['selected_ids']) ? $_POST['selected_ids'] : array();
|
||||
$action = isset($_POST['workshop_action']) ? (string)$_POST['workshop_action'] : '';
|
||||
$posted_addon_id = isset($_POST['addon_id']) ? (int)$_POST['addon_id'] : 0;
|
||||
|
||||
if ($posted_home_id !== $home_id) {
|
||||
$is_error = true;
|
||||
|
|
@ -55,14 +73,22 @@ function exec_ogp_module() {
|
|||
$message = 'Invalid CSRF token for workshop action.';
|
||||
}
|
||||
else {
|
||||
scm_workshop_handle_action($db, $home_info, $user_id, $action, $entered_ids, (array)$selected_ids, $message, $is_error);
|
||||
scm_workshop_handle_action($db, $home_info, $user_id, $action, $entered_ids, (array)$selected_ids, $message, $is_error, $posted_addon_id > 0 ? $posted_addon_id : $addon_id);
|
||||
}
|
||||
}
|
||||
|
||||
$rows = scm_get_workshop_rows($db, $home_id);
|
||||
$csrf_token = scm_get_csrf_token();
|
||||
|
||||
echo "<h2>Workshop Content: ".scm_h($home_info['home_name'])."</h2>";
|
||||
echo "<h2>Workshop Mods: " . scm_h($home_info['home_name']) . "</h2>";
|
||||
if ($addon_template !== null) {
|
||||
echo "<p class='info'>Content template: <strong>" . scm_h($addon_template['name']) . "</strong>";
|
||||
if (!empty($addon_template['description'])) {
|
||||
echo " – " . scm_h($addon_template['description']);
|
||||
}
|
||||
echo "</p>";
|
||||
}
|
||||
|
||||
if ($message !== '') {
|
||||
if ($is_error) {
|
||||
print_failure($message);
|
||||
|
|
@ -83,16 +109,18 @@ function exec_ogp_module() {
|
|||
<input type='hidden' name='mod_id' value='<?php echo (int)$mod_id; ?>' />
|
||||
<input type='hidden' name='ip' value='<?php echo scm_h($ip); ?>' />
|
||||
<input type='hidden' name='port' value='<?php echo scm_h($port); ?>' />
|
||||
<input type='hidden' name='addon_id' value='<?php echo (int)$addon_id; ?>' />
|
||||
<input type='hidden' name='workshop_csrf' value='<?php echo scm_h($csrf_token); ?>' />
|
||||
|
||||
<table class='center'>
|
||||
<tr>
|
||||
<td align='right'><strong>Enter Workshop IDs</strong></td>
|
||||
<td align='right'><strong>Workshop Item IDs</strong></td>
|
||||
<td align='left'>
|
||||
<input type='text' name='workshop_ids' size='72' value='<?php echo scm_h($entered_ids); ?>' placeholder='1234567890, 9876543210, 555555555' />
|
||||
<textarea name='workshop_ids' rows='4' cols='72' placeholder='450814997 463939057 ...'><?php echo scm_h($entered_ids); ?></textarea>
|
||||
<br><small style="color:#666;">Enter one or more Steam Workshop IDs, one per line or comma-separated.<br>Example for Arma 3 CBA_A3: <code>450814997</code></small>
|
||||
</td>
|
||||
<td align='left'>
|
||||
<button type='submit' name='workshop_action' value='install_new'>Install New</button>
|
||||
<td align='left' style='vertical-align:top;padding-top:4px;'>
|
||||
<button type='submit' name='workshop_action' value='install_new'>Install / Queue</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
|||
|
|
@ -10,12 +10,15 @@
|
|||
*/
|
||||
|
||||
$module_title = "Steam Workshop";
|
||||
$module_version = "3.2";
|
||||
$module_version = "3.3";
|
||||
$db_version = 5;
|
||||
$module_required = FALSE;
|
||||
$module_menus = array(
|
||||
array('subpage' => 'admin', 'name' => 'Steam Workshop', 'group' => 'admin'),
|
||||
);
|
||||
// DEPRECATED: The Steam Workshop standalone module has been superseded by
|
||||
// Server Content Manager (addonsmanager). Navigation access is removed so
|
||||
// users are directed to the new unified workshop workflow. The DB tables
|
||||
// and helper functions are preserved for backward compatibility.
|
||||
// See Panel/modules/addonsmanager/ for the replacement implementation.
|
||||
$module_menus = array();
|
||||
|
||||
if (!function_exists('sw_module_db_prefix')) {
|
||||
function sw_module_db_prefix()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue