no idea
This commit is contained in:
parent
3d7aa64db6
commit
f7d4c3e11b
8 changed files with 310 additions and 121 deletions
|
|
@ -42,6 +42,16 @@ define('LANG_open_workshop_page', "Open Workshop page");
|
||||||
define('LANG_unable_to_contact_steam_workshop', "Unable to contact the Steam Workshop.");
|
define('LANG_unable_to_contact_steam_workshop', "Unable to contact the Steam Workshop.");
|
||||||
define('LANG_unable_to_parse_steam_workshop_response', "Unable to parse the Steam Workshop response.");
|
define('LANG_unable_to_parse_steam_workshop_response', "Unable to parse the Steam Workshop response.");
|
||||||
define('LANG_failed_to_fetch_workshop_item_details', "Failed to fetch Workshop item details for %s.");
|
define('LANG_failed_to_fetch_workshop_item_details', "Failed to fetch Workshop item details for %s.");
|
||||||
|
define('LANG_copy_from_existing_workshop_config', "Copy From Existing Workshop Config");
|
||||||
|
define('LANG_copy_from_existing_workshop_config_info', "Copy an existing Workshop XML into the currently selected game and OS configuration.");
|
||||||
|
define('LANG_select_config_to_copy', "Select config to copy");
|
||||||
|
define('LANG_copy_selected_config', "Copy Selected Config");
|
||||||
|
define('LANG_confirm_copy_workshop_config', "Confirm Workshop config copy");
|
||||||
|
define('LANG_workshop_config_copy_confirm_info', "Copy %s into %s and overwrite the current configuration?");
|
||||||
|
define('LANG_invalid_workshop_config_copy_source', "Invalid Workshop config source.");
|
||||||
|
define('LANG_cannot_copy_workshop_config_to_itself', "Cannot copy a Workshop config onto itself.");
|
||||||
|
define('LANG_failed_to_copy_workshop_config', "Failed to copy the selected Workshop config.");
|
||||||
|
define('LANG_workshop_config_copied', "Copied Workshop config %s to %s.");
|
||||||
define('LANG_select_game', "Select Game");
|
define('LANG_select_game', "Select Game");
|
||||||
define('LANG_save_config', "Save Config");
|
define('LANG_save_config', "Save Config");
|
||||||
define('LANG_mod_key_not_found_from_xml', "Mod key %s not found from xml.");
|
define('LANG_mod_key_not_found_from_xml', "Mod key %s not found from xml.");
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,92 @@ function steam_workshop_h($value)
|
||||||
return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
|
return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function steam_workshop_has_config_file_path($filepath)
|
||||||
|
{
|
||||||
|
return trim((string)$filepath) !== '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function steam_workshop_resolve_config_filepath($home_path, $filepath)
|
||||||
|
{
|
||||||
|
$filepath = trim((string)$filepath);
|
||||||
|
if($filepath === '')
|
||||||
|
return '';
|
||||||
|
|
||||||
|
return clean_path(rtrim($home_path, '/').'/'.$filepath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function steam_workshop_get_configs_dir()
|
||||||
|
{
|
||||||
|
return dirname(__FILE__).'/game_configs';
|
||||||
|
}
|
||||||
|
|
||||||
|
function steam_workshop_list_existing_configs()
|
||||||
|
{
|
||||||
|
$configs = array();
|
||||||
|
$config_dir = steam_workshop_get_configs_dir();
|
||||||
|
if(!is_dir($config_dir))
|
||||||
|
return $configs;
|
||||||
|
|
||||||
|
$files = glob($config_dir.'/*.xml');
|
||||||
|
if($files === false)
|
||||||
|
return $configs;
|
||||||
|
|
||||||
|
sort($files, SORT_NATURAL | SORT_FLAG_CASE);
|
||||||
|
foreach($files as $file)
|
||||||
|
{
|
||||||
|
$basename = basename($file);
|
||||||
|
$xml = @simplexml_load_file($file);
|
||||||
|
$configs[$basename] = array(
|
||||||
|
'filename' => $basename,
|
||||||
|
'workshop_id' => $xml !== false && isset($xml->workshop_id) ? (string)$xml->workshop_id : '',
|
||||||
|
'download_method' => $xml !== false && isset($xml->download_method) ? (string)$xml->download_method : '',
|
||||||
|
'mods_path' => $xml !== false && isset($xml->mods_path) ? (string)$xml->mods_path : '',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $configs;
|
||||||
|
}
|
||||||
|
|
||||||
|
function steam_workshop_get_existing_config_options($exclude_filename = '')
|
||||||
|
{
|
||||||
|
$options = array('' => get_lang('select_config_to_copy'));
|
||||||
|
foreach(steam_workshop_list_existing_configs() as $basename => $config)
|
||||||
|
{
|
||||||
|
if($basename === $exclude_filename)
|
||||||
|
continue;
|
||||||
|
$label = $basename;
|
||||||
|
$meta = array();
|
||||||
|
if($config['workshop_id'] !== '')
|
||||||
|
$meta[] = 'Workshop '.$config['workshop_id'];
|
||||||
|
if($config['download_method'] !== '')
|
||||||
|
$meta[] = $config['download_method'];
|
||||||
|
if($config['mods_path'] !== '')
|
||||||
|
$meta[] = 'mods_path='.$config['mods_path'];
|
||||||
|
if(!empty($meta))
|
||||||
|
$label .= ' ['.implode(' | ', $meta).']';
|
||||||
|
$options[$basename] = $label;
|
||||||
|
}
|
||||||
|
return $options;
|
||||||
|
}
|
||||||
|
|
||||||
|
function steam_workshop_get_safe_config_copy_paths($selected_source, $destination_file)
|
||||||
|
{
|
||||||
|
$selected_source = basename((string)$selected_source);
|
||||||
|
$destination_file = basename((string)$destination_file);
|
||||||
|
$config_dir = realpath(steam_workshop_get_configs_dir());
|
||||||
|
if($config_dir === false || $selected_source === '' || $destination_file === '')
|
||||||
|
return array(false, false);
|
||||||
|
|
||||||
|
$source_path = realpath($config_dir.'/'.$selected_source);
|
||||||
|
$destination_path = $config_dir.'/'.$destination_file;
|
||||||
|
if($source_path === false || strpos($source_path, $config_dir.DIRECTORY_SEPARATOR) !== 0)
|
||||||
|
return array(false, false);
|
||||||
|
if(pathinfo($source_path, PATHINFO_EXTENSION) !== 'xml' || pathinfo($destination_path, PATHINFO_EXTENSION) !== 'xml')
|
||||||
|
return array(false, false);
|
||||||
|
|
||||||
|
return array($source_path, $destination_path);
|
||||||
|
}
|
||||||
|
|
||||||
function steam_workshop_request($url, $context, &$error = "")
|
function steam_workshop_request($url, $context, &$error = "")
|
||||||
{
|
{
|
||||||
$response = @file_get_contents($url, false, $context);
|
$response = @file_get_contents($url, false, $context);
|
||||||
|
|
@ -422,15 +508,18 @@ function steam_workshop_search_items($workshop_id, $query, &$error = "")
|
||||||
|
|
||||||
function get_installed_mods($home_cfg, $remote, $xml)
|
function get_installed_mods($home_cfg, $remote, $xml)
|
||||||
{
|
{
|
||||||
$workshop_id = $xml->workshop_id;
|
|
||||||
$config = $xml->config;
|
$config = $xml->config;
|
||||||
$regex = $config->regex;
|
$regex = $config->regex;
|
||||||
$mods_backreference_index = (int)$config->mods_backreference_index;
|
$mods_backreference_index = (int)$config->mods_backreference_index;
|
||||||
$string_separator = stripcslashes($config->string_separator);
|
$string_separator = stripcslashes($config->string_separator);
|
||||||
$filepath = $config->filepath;
|
$filepath = $config->filepath;
|
||||||
$mods = $xml->mods->mod;
|
$full_filepath = steam_workshop_resolve_config_filepath($home_cfg['home_path'], $filepath);
|
||||||
|
|
||||||
$full_filepath = clean_path($home_cfg['home_path']."/$filepath");
|
if(!steam_workshop_has_config_file_path($filepath))
|
||||||
|
{
|
||||||
|
$retval = $remote->get_workshop_mods_info($mod_info_array);
|
||||||
|
return $retval == "1" && !empty($mod_info_array) ? $mod_info_array : False;
|
||||||
|
}
|
||||||
|
|
||||||
if($remote->rfile_exists($full_filepath) === 0)
|
if($remote->rfile_exists($full_filepath) === 0)
|
||||||
return False;
|
return False;
|
||||||
|
|
@ -476,40 +565,44 @@ function remove_mod($home_cfg, $remote, $xml, $mod_string)
|
||||||
$string_separator = stripcslashes($config->string_separator);
|
$string_separator = stripcslashes($config->string_separator);
|
||||||
$filepath = $config->filepath;
|
$filepath = $config->filepath;
|
||||||
|
|
||||||
$full_filepath = $home_cfg['home_path']."/$filepath";
|
$full_filepath = steam_workshop_resolve_config_filepath($home_cfg['home_path'], $filepath);
|
||||||
$mods_full_path = clean_path($home_cfg['home_path'].'/'.$xml->mods_path);
|
$mods_full_path = clean_path($home_cfg['home_path'].'/'.$xml->mods_path);
|
||||||
|
|
||||||
if($remote->rfile_exists($full_filepath) === 0)
|
if(steam_workshop_has_config_file_path($filepath))
|
||||||
return False;
|
|
||||||
|
|
||||||
$remote->remote_readfile($full_filepath, $file_content);
|
|
||||||
|
|
||||||
if(preg_match("/$regex/m", $file_content, $matches))
|
|
||||||
{
|
{
|
||||||
$full_regex_string = trim($matches[0]);
|
if($remote->rfile_exists($full_filepath) === 0)
|
||||||
$current_mods_string = trim($matches[$mods_backreference_index]);
|
return False;
|
||||||
if($current_mods_string != '')
|
|
||||||
|
$remote->remote_readfile($full_filepath, $file_content);
|
||||||
|
|
||||||
|
if(preg_match("/$regex/m", $file_content, $matches))
|
||||||
{
|
{
|
||||||
$current = explode($string_separator, $current_mods_string);
|
$full_regex_string = trim($matches[0]);
|
||||||
|
$current_mods_string = trim($matches[$mods_backreference_index]);
|
||||||
foreach($current as $index => $c)
|
if($current_mods_string != '')
|
||||||
{
|
{
|
||||||
if(trim($c) == $mod_string)
|
$current = explode($string_separator, $current_mods_string);
|
||||||
unset($current[$index]);
|
|
||||||
|
foreach($current as $index => $c)
|
||||||
|
{
|
||||||
|
if(trim($c) == $mod_string)
|
||||||
|
unset($current[$index]);
|
||||||
|
}
|
||||||
|
$current = array_filter($current);
|
||||||
|
$new_mods_string = implode($string_separator, $current);
|
||||||
|
|
||||||
|
$replacement = $variable.$new_mods_string;
|
||||||
|
$file_content = str_replace($full_regex_string, $replacement, $file_content);
|
||||||
}
|
}
|
||||||
$current = array_filter($current);
|
else
|
||||||
$new_mods_string = implode($string_separator, $current);
|
return False;
|
||||||
|
|
||||||
$replacement = $variable.$new_mods_string;
|
|
||||||
$file_content = str_replace($full_regex_string, $replacement, $file_content);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return False;
|
return False;
|
||||||
|
|
||||||
|
$remote->remote_writefile($full_filepath, $file_content);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return False;
|
|
||||||
|
|
||||||
$remote->remote_writefile($full_filepath, $file_content);
|
|
||||||
$uninstall_filepath = clean_path($mods_full_path.'/postuninstall.sh');
|
$uninstall_filepath = clean_path($mods_full_path.'/postuninstall.sh');
|
||||||
$uninstallcmd = str_replace('%mods_full_path%', $mods_full_path, $xml->uninstall);
|
$uninstallcmd = str_replace('%mods_full_path%', $mods_full_path, $xml->uninstall);
|
||||||
$uninstallcmd = str_replace('%mod_string%', $mod_string, $uninstallcmd);
|
$uninstallcmd = str_replace('%mod_string%', $mod_string, $uninstallcmd);
|
||||||
|
|
|
||||||
|
|
@ -205,7 +205,7 @@ function exec_ogp_module()
|
||||||
$place_after = $config->place_after;
|
$place_after = $config->place_after;
|
||||||
$mod_string = $config->mod_string;
|
$mod_string = $config->mod_string;
|
||||||
$string_separator = $config->string_separator;
|
$string_separator = $config->string_separator;
|
||||||
$config_file_path = clean_path($home_cfg['home_path']."/".$config->filepath);
|
$config_file_path = steam_workshop_resolve_config_filepath($home_cfg['home_path'], $config->filepath);
|
||||||
$post_install = $xml->post_install;
|
$post_install = $xml->post_install;
|
||||||
$mod_names_list = get_mod_names_list($mods_list, $xml->mods->mod);
|
$mod_names_list = get_mod_names_list($mods_list, $xml->mods->mod);
|
||||||
$mods_full_path = clean_path($home_cfg['home_path'].'/'.$xml->mods_path);
|
$mods_full_path = clean_path($home_cfg['home_path'].'/'.$xml->mods_path);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,68 @@ require_once(dirname(__FILE__) . '/simple_admin_helper.php');
|
||||||
*/
|
*/
|
||||||
require_once('includes/form_table_class.php');
|
require_once('includes/form_table_class.php');
|
||||||
require_once("modules/steam_workshop/functions.php");
|
require_once("modules/steam_workshop/functions.php");
|
||||||
|
|
||||||
|
function steam_workshop_admin_save_xml($xml_file, $post, $removed_ids = array())
|
||||||
|
{
|
||||||
|
$xml = new SimpleXMLElement('<workshop_settings/>');
|
||||||
|
$xml->addChild('workshop_id', trim((string)$post['workshop_id']));
|
||||||
|
$xml->addChild('download_method', trim((string)$post['download_method']));
|
||||||
|
$xml->addChild('anonymous_login', trim((string)$post['anonymous_login']));
|
||||||
|
$xml->addChild('mods_path', trim((string)$post['mods_path']));
|
||||||
|
$mods = $xml->addChild('mods');
|
||||||
|
if(file_exists($xml_file))
|
||||||
|
{
|
||||||
|
$file_xml = simplexml_load_file($xml_file);
|
||||||
|
if($file_xml !== false && isset($file_xml->mods))
|
||||||
|
{
|
||||||
|
foreach($file_xml->mods->mod as $xml_mod)
|
||||||
|
{
|
||||||
|
if(in_array((string)$xml_mod['id'], $removed_ids, true))
|
||||||
|
continue;
|
||||||
|
$mod = $mods->addChild('mod');
|
||||||
|
$mod->addAttribute('id', (string)$xml_mod['id']);
|
||||||
|
$mod->addChild('name', (string)$xml_mod->name);
|
||||||
|
$mod->addChild('description', (string)$xml_mod->description);
|
||||||
|
$mod->addChild('image_url', (string)$xml_mod->image_url);
|
||||||
|
$mod->addChild('download_url', (string)$xml_mod->download_url);
|
||||||
|
$mod->addChild('filename', (string)$xml_mod->filename);
|
||||||
|
$mod->addChild('file_size', (string)$xml_mod->file_size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$config = $xml->addChild('config');
|
||||||
|
$config->addChild('regex', trim((string)$post['regex']));
|
||||||
|
$config->addChild('mods_backreference_index', trim((string)$post['mods_backreference_index']));
|
||||||
|
$config->addChild('variable', (string)$post['variable']);
|
||||||
|
$config->addChild('place_after', (string)$post['place_after']);
|
||||||
|
$config->addChild('mod_string', (string)$post['mod_string']);
|
||||||
|
$config->addChild('string_separator', (string)$post['string_separator']);
|
||||||
|
$config->addChild('filepath', trim((string)$post['filepath']));
|
||||||
|
$xml->addChild('post_install', str_replace('&','&', (string)$post['post_install']));
|
||||||
|
$xml->addChild('uninstall', str_replace('&','&', (string)$post['uninstall']));
|
||||||
|
|
||||||
|
$dom = dom_import_simplexml($xml)->ownerDocument;
|
||||||
|
$dom->formatOutput = true;
|
||||||
|
file_put_contents($xml_file, $dom->saveXML());
|
||||||
|
}
|
||||||
|
|
||||||
|
function steam_workshop_admin_hidden_state($values)
|
||||||
|
{
|
||||||
|
$fields = array(
|
||||||
|
'workshop_id','download_method','anonymous_login','mods_path','regex',
|
||||||
|
'mods_backreference_index','variable','place_after','mod_string',
|
||||||
|
'string_separator','filepath','post_install','uninstall'
|
||||||
|
);
|
||||||
|
$html = '';
|
||||||
|
foreach($fields as $field)
|
||||||
|
{
|
||||||
|
$value = isset($values[$field]) ? (string)$values[$field] : '';
|
||||||
|
$html .= '<input type="hidden" name="'.steam_workshop_h($field).'" value="'.steam_workshop_h($value).'" />'."\n";
|
||||||
|
}
|
||||||
|
return $html;
|
||||||
|
}
|
||||||
|
|
||||||
function exec_ogp_module()
|
function exec_ogp_module()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
@ -62,86 +124,63 @@ function exec_ogp_module()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$xml_file = CONFIGS.$mod_xml->installer_name."_".$os.".xml";
|
$xml_file = CONFIGS.$mod_xml->installer_name."_".$os.".xml";
|
||||||
|
$workshop_id = '';
|
||||||
|
$download_method = 'steamcmd';
|
||||||
|
$anonymous_login = 1;
|
||||||
|
$mods_path = '';
|
||||||
|
$regex = '';
|
||||||
|
$mods_backreference_index = '';
|
||||||
|
$variable = '';
|
||||||
|
$place_after = '';
|
||||||
|
$mod_string = '';
|
||||||
|
$string_separator = '';
|
||||||
|
$filepath = '';
|
||||||
|
$post_install = '';
|
||||||
|
$uninstall = '';
|
||||||
|
|
||||||
if(isset($_POST['save_config']))
|
if(isset($_POST['save_config']))
|
||||||
{
|
{
|
||||||
$xml = new SimpleXMLElement('<workshop_settings/>');
|
steam_workshop_admin_save_xml($xml_file, $_POST);
|
||||||
$xml->addChild('workshop_id', $_POST['workshop_id']);
|
|
||||||
$xml->addChild('download_method', $_POST['download_method']);
|
|
||||||
$xml->addChild('anonymous_login', $_POST['anonymous_login']);
|
|
||||||
$xml->addChild('mods_path', $_POST['mods_path']);
|
|
||||||
$mods = $xml->addChild('mods');
|
|
||||||
if(file_exists($xml_file))
|
|
||||||
{
|
|
||||||
$file_xml = simplexml_load_file($xml_file);
|
|
||||||
foreach($file_xml->mods->mod as $xml_mod)
|
|
||||||
{
|
|
||||||
$mod = $mods->addChild('mod');
|
|
||||||
$mod->addAttribute('id', $xml_mod['id']);
|
|
||||||
$mod->addChild('name', $xml_mod->name);
|
|
||||||
$mod->addChild('description', $xml_mod->description);
|
|
||||||
$mod->addChild('image_url', $xml_mod->image_url);
|
|
||||||
$mod->addChild('download_url', $xml_mod->download_url);
|
|
||||||
$mod->addChild('filename', $xml_mod->filename);
|
|
||||||
$mod->addChild('file_size', $xml_mod->file_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$config = $xml->addChild('config');
|
|
||||||
$config->addChild('regex', $_POST['regex']);
|
|
||||||
$config->addChild('mods_backreference_index', $_POST['mods_backreference_index']);
|
|
||||||
$config->addChild('variable', $_POST['variable']);
|
|
||||||
$config->addChild('place_after', $_POST['place_after']);
|
|
||||||
$config->addChild('mod_string', $_POST['mod_string']);
|
|
||||||
$config->addChild('string_separator', $_POST['string_separator']);
|
|
||||||
$config->addChild('filepath', $_POST['filepath']);
|
|
||||||
$xml->addChild('post_install', str_replace('&','&',$_POST['post_install']));
|
|
||||||
$xml->addChild('uninstall', str_replace('&','&',$_POST['uninstall']));
|
|
||||||
|
|
||||||
$dom = dom_import_simplexml($xml)->ownerDocument;
|
|
||||||
$dom->formatOutput = true;
|
|
||||||
file_put_contents($xml_file, $dom->saveXML());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($_POST['remove_mods']))
|
if(isset($_POST['remove_mods']))
|
||||||
{
|
{
|
||||||
$xml = new SimpleXMLElement('<workshop_settings/>');
|
$removed_ids = isset($_POST['workshop_mod_id']) && is_array($_POST['workshop_mod_id']) ? array_map('strval', $_POST['workshop_mod_id']) : array();
|
||||||
$xml->addChild('workshop_id', $_POST['workshop_id']);
|
steam_workshop_admin_save_xml($xml_file, $_POST, $removed_ids);
|
||||||
$xml->addChild('download_method', $_POST['download_method']);
|
}
|
||||||
$xml->addChild('anonymous_login', $_POST['anonymous_login']);
|
|
||||||
$xml->addChild('mods_path', $_POST['mods_path']);
|
if(isset($_POST['copy_selected_config']) || isset($_POST['confirm_copy_config']))
|
||||||
$mods = $xml->addChild('mods');
|
{
|
||||||
if(file_exists($xml_file))
|
list($source_path, $destination_path) = steam_workshop_get_safe_config_copy_paths(
|
||||||
|
isset($_POST['copy_source_config']) ? $_POST['copy_source_config'] : '',
|
||||||
|
basename($xml_file)
|
||||||
|
);
|
||||||
|
if($source_path === false || $destination_path === false)
|
||||||
{
|
{
|
||||||
$file_xml = simplexml_load_file($xml_file);
|
print_failure(get_lang('invalid_workshop_config_copy_source'));
|
||||||
foreach($file_xml->mods->mod as $xml_mod)
|
}
|
||||||
{
|
elseif(realpath($source_path) === realpath($destination_path))
|
||||||
if(in_array($xml_mod['id'],$_POST['workshop_mod_id']))
|
{
|
||||||
continue;
|
print_failure(get_lang('cannot_copy_workshop_config_to_itself'));
|
||||||
$mod = $mods->addChild('mod');
|
}
|
||||||
$mod->addAttribute('id', $xml_mod['id']);
|
elseif(file_exists($destination_path) && !isset($_POST['confirm_copy_config']))
|
||||||
$mod->addChild('name', $xml_mod->name);
|
{
|
||||||
$mod->addChild('description', $xml_mod->description);
|
echo "<div class='info' style='margin:10px 0;padding:10px;'><strong>".get_lang('confirm_copy_workshop_config')."</strong><br>".
|
||||||
$mod->addChild('image_url', $xml_mod->image_url);
|
get_lang_f('workshop_config_copy_confirm_info', basename($source_path), basename($destination_path)).
|
||||||
$mod->addChild('download_url', $xml_mod->download_url);
|
"<form method='post' action='?m=steam_workshop&p=workshop_admin'>".
|
||||||
$mod->addChild('filename', $xml_mod->filename);
|
"<input type='hidden' name='home_cfg_id-mod_cfg_id-os' value='".steam_workshop_h($_REQUEST['home_cfg_id-mod_cfg_id-os'])."' />".
|
||||||
$mod->addChild('file_size', $xml_mod->file_size);
|
"<input type='hidden' name='copy_source_config' value='".steam_workshop_h(basename($source_path))."' />".
|
||||||
}
|
"<button type='submit' class='btn btn-sm btn-warning mt-2' name='confirm_copy_config' value='1'>".get_lang('copy_selected_config')."</button>".
|
||||||
|
"</form></div>";
|
||||||
|
}
|
||||||
|
elseif(@copy($source_path, $destination_path))
|
||||||
|
{
|
||||||
|
print_success(get_lang_f('workshop_config_copied', basename($source_path), basename($destination_path)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
print_failure(get_lang('failed_to_copy_workshop_config'));
|
||||||
}
|
}
|
||||||
$config = $xml->addChild('config');
|
|
||||||
$config->addChild('regex', $_POST['regex']);
|
|
||||||
$config->addChild('mods_backreference_index', $_POST['mods_backreference_index']);
|
|
||||||
$config->addChild('variable', $_POST['variable']);
|
|
||||||
$config->addChild('place_after', $_POST['place_after']);
|
|
||||||
$config->addChild('mod_string', $_POST['mod_string']);
|
|
||||||
$config->addChild('string_separator', $_POST['string_separator']);
|
|
||||||
$config->addChild('filepath', $_POST['filepath']);
|
|
||||||
$xml->addChild('post_install', $_POST['post_install']);
|
|
||||||
$xml->addChild('uninstall', $_POST['uninstall']);
|
|
||||||
|
|
||||||
$dom = dom_import_simplexml($xml)->ownerDocument;
|
|
||||||
$dom->formatOutput = true;
|
|
||||||
file_put_contents($xml_file, $dom->saveXML());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(file_exists($xml_file))
|
if(file_exists($xml_file))
|
||||||
|
|
@ -162,9 +201,24 @@ function exec_ogp_module()
|
||||||
$post_install = $xml->post_install;
|
$post_install = $xml->post_install;
|
||||||
$uninstall = $xml->uninstall;
|
$uninstall = $xml->uninstall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$current_values = array(
|
||||||
|
'workshop_id' => isset($workshop_id) ? $workshop_id : '',
|
||||||
|
'download_method' => isset($download_method) ? $download_method : '',
|
||||||
|
'anonymous_login' => isset($anonymous_login) ? $anonymous_login : '',
|
||||||
|
'mods_path' => isset($mods_path) ? $mods_path : '',
|
||||||
|
'regex' => isset($regex) ? $regex : '',
|
||||||
|
'mods_backreference_index' => isset($mods_backreference_index) ? $mods_backreference_index : '',
|
||||||
|
'variable' => isset($variable) ? $variable : '',
|
||||||
|
'place_after' => isset($place_after) ? $place_after : '',
|
||||||
|
'mod_string' => isset($mod_string) ? $mod_string : '',
|
||||||
|
'string_separator' => isset($string_separator) ? $string_separator : '',
|
||||||
|
'filepath' => isset($filepath) ? $filepath : '',
|
||||||
|
'post_install' => isset($post_install) ? $post_install : '',
|
||||||
|
'uninstall' => isset($uninstall) ? $uninstall : '',
|
||||||
|
);
|
||||||
|
|
||||||
$game_cfgs = $db->getGameCfgs();
|
$game_cfgs = $db->getGameCfgs();
|
||||||
$games[0] = get_lang('select_game');
|
$games[0] = get_lang('select_game');
|
||||||
|
|
@ -206,6 +260,15 @@ function exec_ogp_module()
|
||||||
$ft->add_custom_field('game', create_drop_box_from_array_onchange($games, "home_cfg_id-mod_cfg_id-os", @$_REQUEST['home_cfg_id-mod_cfg_id-os']));
|
$ft->add_custom_field('game', create_drop_box_from_array_onchange($games, "home_cfg_id-mod_cfg_id-os", @$_REQUEST['home_cfg_id-mod_cfg_id-os']));
|
||||||
if(isset($home_cfg_id) and isset($mod_cfg_id))
|
if(isset($home_cfg_id) and isset($mod_cfg_id))
|
||||||
{
|
{
|
||||||
|
$copy_options = steam_workshop_get_existing_config_options(isset($xml_file) ? basename($xml_file) : '');
|
||||||
|
echo "<div class='info' style='margin:10px 0;padding:10px;'><strong>".get_lang('copy_from_existing_workshop_config')."</strong><br>".
|
||||||
|
get_lang('copy_from_existing_workshop_config_info').
|
||||||
|
"<form method='post' action='?m=steam_workshop&p=workshop_admin' style='margin-top:8px;' autocomplete='off'>".
|
||||||
|
"<input type='hidden' name='home_cfg_id-mod_cfg_id-os' value='".steam_workshop_h($_REQUEST['home_cfg_id-mod_cfg_id-os'])."' />".
|
||||||
|
create_drop_box_from_array($copy_options, "copy_source_config", '').
|
||||||
|
" <button type='submit' class='btn btn-sm btn-secondary' name='copy_selected_config' value='1'>".get_lang('copy_selected_config')."</button>".
|
||||||
|
"</form></div>";
|
||||||
|
|
||||||
$ft->add_field('string','workshop_id',@$workshop_id);
|
$ft->add_field('string','workshop_id',@$workshop_id);
|
||||||
$ft->add_custom_field('download_method',create_drop_box_from_array($download_methods, "download_method", @$download_method));
|
$ft->add_custom_field('download_method',create_drop_box_from_array($download_methods, "download_method", @$download_method));
|
||||||
$ft->add_field('on_off','anonymous_login',@$anonymous_login);
|
$ft->add_field('on_off','anonymous_login',@$anonymous_login);
|
||||||
|
|
@ -237,19 +300,7 @@ function exec_ogp_module()
|
||||||
$ft->start_form("?m=steam_workshop&p=workshop_admin&home_cfg_id-mod_cfg_id-os=".$_REQUEST['home_cfg_id-mod_cfg_id-os'], "post", "autocomplete=\"off\"");
|
$ft->start_form("?m=steam_workshop&p=workshop_admin&home_cfg_id-mod_cfg_id-os=".$_REQUEST['home_cfg_id-mod_cfg_id-os'], "post", "autocomplete=\"off\"");
|
||||||
$ft->start_table();
|
$ft->start_table();
|
||||||
echo "<tr><td>";
|
echo "<tr><td>";
|
||||||
$ft->add_field_hidden('workshop_id',$workshop_id);
|
echo steam_workshop_admin_hidden_state($current_values);
|
||||||
$ft->add_field_hidden('download_method',$download_method);
|
|
||||||
$ft->add_field_hidden('anonymous_login',$anonymous_login);
|
|
||||||
$ft->add_field_hidden('mods_path',$mods_path);
|
|
||||||
$ft->add_field_hidden('regex',$regex);
|
|
||||||
$ft->add_field_hidden('mods_backreference_index',$mods_backreference_index);
|
|
||||||
$ft->add_field_hidden('variable',$variable);
|
|
||||||
$ft->add_field_hidden('place_after',$place_after);
|
|
||||||
$ft->add_field_hidden('mod_string',$mod_string);
|
|
||||||
$ft->add_field_hidden('string_separator',$string_separator);
|
|
||||||
$ft->add_field_hidden('filepath',$filepath);
|
|
||||||
$ft->add_field_hidden('post_install',$post_install);
|
|
||||||
$ft->add_field_hidden('uninstall',$uninstall);
|
|
||||||
echo "</td></tr>".
|
echo "</td></tr>".
|
||||||
'<tr><td colspan=2><div id="scrolling_checkbox">';
|
'<tr><td colspan=2><div id="scrolling_checkbox">';
|
||||||
foreach($xml->mods->mod as $mod)
|
foreach($xml->mods->mod as $mod)
|
||||||
|
|
@ -262,4 +313,4 @@ function exec_ogp_module()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (function_exists('gsp_steam_workshop_simple_admin_script')) { gsp_steam_workshop_simple_admin_script(); }
|
if (function_exists('gsp_steam_workshop_simple_admin_script')) { gsp_steam_workshop_simple_admin_script(); }
|
||||||
?>
|
?>
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,7 @@ The agent reads screen logs and may also copy a local log file into the game hom
|
||||||
|
|
||||||
## Workshop / Server Content
|
## Workshop / Server Content
|
||||||
|
|
||||||
The primary Workshop workflow is owned by the Panel `addonsmanager`, not the legacy `steam_workshop` RPC. For Linux servers the Panel:
|
The current customer-facing Workshop workflow is the dedicated Panel `steam_workshop` module. The older `steam_workshop` XML-RPC method is still used by that module for compatibility. 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. writes a generated per-job shell script under `gsp_server_content/jobs/workshop/`
|
2. writes a generated per-job shell script under `gsp_server_content/jobs/workshop/`
|
||||||
|
|
@ -92,7 +92,11 @@ The primary Workshop workflow is owned by the Panel `addonsmanager`, not the leg
|
||||||
|
|
||||||
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 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.
|
For legacy `steam_workshop` RPC installs:
|
||||||
|
|
||||||
|
- blank `config_file_path` means no config-file editing
|
||||||
|
- the generated post-install script still runs
|
||||||
|
- `WorkshopModsInfo` is still written so uninstall can work without parsing a game config file
|
||||||
|
|
||||||
## Scheduler
|
## Scheduler
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ Windows/Cygwin logs come from screen logs and/or local copies. Log retrieval sho
|
||||||
|
|
||||||
## Workshop / Server Content
|
## Workshop / Server Content
|
||||||
|
|
||||||
The primary Workshop workflow is owned by the Panel `addonsmanager`, not the legacy `steam_workshop` RPC. For Windows/Cygwin servers the Panel:
|
The current customer-facing Workshop workflow is the dedicated Panel `steam_workshop` module. The older `steam_workshop` XML-RPC method is still used by that module for compatibility. 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. writes a generated per-job shell script under `gsp_server_content/jobs/workshop/`
|
2. writes a generated per-job shell script under `gsp_server_content/jobs/workshop/`
|
||||||
|
|
@ -172,7 +172,11 @@ The primary Workshop workflow is owned by the Panel `addonsmanager`, not the leg
|
||||||
|
|
||||||
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 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.
|
For legacy `steam_workshop` RPC installs:
|
||||||
|
|
||||||
|
- blank `config_file_path` means no config-file editing
|
||||||
|
- the generated post-install script still runs
|
||||||
|
- `WorkshopModsInfo` is still written so uninstall can work without parsing a game config file
|
||||||
|
|
||||||
## Scheduler
|
## Scheduler
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,22 @@ The dedicated module still provides:
|
||||||
- monitor-button access from Game Monitor
|
- monitor-button access from Game Monitor
|
||||||
- per-game Workshop configuration files
|
- per-game Workshop configuration files
|
||||||
- uninstall and admin support pages
|
- uninstall and admin support pages
|
||||||
|
- optional regex/config-file editing for games that need automatic mod-list updates
|
||||||
|
- post-install-only workflows for games that only need a move/copy script
|
||||||
|
|
||||||
|
## Legacy RPC Install Semantics
|
||||||
|
|
||||||
|
The dedicated `steam_workshop` module still uses the legacy `steam_workshop` agent RPC for installs.
|
||||||
|
|
||||||
|
Current rule:
|
||||||
|
|
||||||
|
- if `config/filepath` is blank, the Panel passes a blank `config_file_path`
|
||||||
|
- agents must skip the generated config-file editing block entirely
|
||||||
|
- post-install scripts still run
|
||||||
|
- `WorkshopModsInfo` still records installed items
|
||||||
|
- uninstall can rely on `WorkshopModsInfo` when no config file is managed
|
||||||
|
|
||||||
|
This keeps advanced regex editing available without forcing it for simple Arma/DayZ-style `@mod` installs.
|
||||||
|
|
||||||
## Main Limitations
|
## Main Limitations
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,9 @@ Dedicated Steam Workshop support for game servers.
|
||||||
|
|
||||||
- configure Workshop game XML files under `Panel/modules/steam_workshop/game_configs/`
|
- configure Workshop game XML files under `Panel/modules/steam_workshop/game_configs/`
|
||||||
- use `workshop_admin.php` for module administration
|
- use `workshop_admin.php` for module administration
|
||||||
|
- `File Path` and the regex/mod-string fields are optional
|
||||||
|
- a blank `File Path` means post-install and uninstall scripts run without any automatic config-file editing
|
||||||
|
- the admin page can copy one existing XML config into the currently selected game/OS config
|
||||||
|
|
||||||
## Search Backend
|
## Search Backend
|
||||||
|
|
||||||
|
|
@ -53,6 +56,14 @@ Dedicated Steam Workshop support for game servers.
|
||||||
- the main Workshop page `Back` link is rendered as a real panel button
|
- the main Workshop page `Back` link is rendered as a real panel button
|
||||||
- uninstall remains in the dedicated `steam_workshop` module
|
- uninstall remains in the dedicated `steam_workshop` module
|
||||||
|
|
||||||
|
## Legacy RPC Behavior
|
||||||
|
|
||||||
|
- the dedicated module still calls the legacy agent `steam_workshop` XML-RPC method
|
||||||
|
- when `config/filepath` is blank, the Panel now passes an empty `config_file_path`
|
||||||
|
- both agents skip the generated `cat` / regex / config-write block when `config_file_path` is blank
|
||||||
|
- both agents still run custom post-install scripts and still write `WorkshopModsInfo`
|
||||||
|
- uninstall falls back to `WorkshopModsInfo` when no config file is managed
|
||||||
|
|
||||||
## Security Concerns
|
## Security Concerns
|
||||||
|
|
||||||
- should not be duplicated under `addonsmanager`
|
- should not be duplicated under `addonsmanager`
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue