diff --git a/Panel/lang/English/modules/steam_workshop.php b/Panel/lang/English/modules/steam_workshop.php index 335a7f09..4a5762bd 100644 --- a/Panel/lang/English/modules/steam_workshop.php +++ b/Panel/lang/English/modules/steam_workshop.php @@ -42,8 +42,8 @@ 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_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_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_copy_from_existing_workshop_config', "Copy Settings From Existing Workshop Config"); +define('LANG_copy_from_existing_workshop_config_info', "Copies Workshop configuration fields only. This does not copy installed mods or game server files."); 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"); @@ -51,7 +51,7 @@ define('LANG_workshop_config_copy_confirm_info', "Copy %s into %s and overwrite 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_workshop_config_copied', "Copied Workshop configuration settings from %s to %s."); define('LANG_select_game', "Select Game"); define('LANG_save_config', "Save Config"); define('LANG_mod_key_not_found_from_xml', "Mod key %s not found from xml."); diff --git a/Panel/modules/steam_workshop/functions.php b/Panel/modules/steam_workshop/functions.php index 0fdd9afc..1c13ed66 100644 --- a/Panel/modules/steam_workshop/functions.php +++ b/Panel/modules/steam_workshop/functions.php @@ -102,46 +102,93 @@ function steam_workshop_list_existing_configs() return $configs; } -function steam_workshop_get_existing_config_options($exclude_filename = '') +function steam_workshop_get_config_display_label($filename, $config, $friendly_names = array()) +{ + $label = isset($friendly_names[$filename]) && trim((string)$friendly_names[$filename]) !== '' ? (string)$friendly_names[$filename].' - '.$filename : $filename; + $meta = array(); + if(isset($config['workshop_id']) && $config['workshop_id'] !== '') + $meta[] = 'Workshop '.$config['workshop_id']; + if(isset($config['download_method']) && $config['download_method'] !== '') + $meta[] = $config['download_method']; + if(isset($config['mods_path']) && $config['mods_path'] !== '') + $meta[] = 'mods_path='.$config['mods_path']; + if(!empty($meta)) + $label .= ' ['.implode(' | ', $meta).']'; + return $label; +} + +function steam_workshop_get_existing_config_options($exclude_filename = '', $friendly_names = array()) { $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; + $options[$basename] = steam_workshop_get_config_display_label($basename, $config, $friendly_names); } return $options; } +function steam_workshop_is_safe_config_filename($filename) +{ + $filename = (string)$filename; + if($filename === '') + return false; + if(strpos($filename, '/') !== false || strpos($filename, '\\') !== false || strpos($filename, '..') !== false) + return false; + if(pathinfo($filename, PATHINFO_EXTENSION) !== 'xml') + return false; + return preg_match('/^[A-Za-z0-9._-]+\.xml$/', $filename) === 1; +} + 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 === '') + $selected_source = (string)$selected_source; + $destination_file = (string)$destination_file; + if($config_dir === false || !steam_workshop_is_safe_config_filename($selected_source) || !steam_workshop_is_safe_config_filename($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); + if(file_exists($destination_path)) + { + $destination_realpath = realpath($destination_path); + if($destination_realpath === false || strpos($destination_realpath, $config_dir.DIRECTORY_SEPARATOR) !== 0) + return array(false, false); + $destination_path = $destination_realpath; + } return array($source_path, $destination_path); } +function steam_workshop_copy_config_settings_only($source_path, $destination_path) +{ + $source = new DOMDocument(); + $source->preserveWhiteSpace = false; + if(!@$source->load($source_path) || !$source->documentElement) + return false; + + $destination = new DOMDocument('1.0', 'UTF-8'); + $destination->formatOutput = true; + $root = $destination->createElement('workshop_settings'); + $destination->appendChild($root); + + foreach($source->documentElement->childNodes as $child) + { + if($child->nodeType !== XML_ELEMENT_NODE) + continue; + if($child->nodeName === 'mods') + continue; + $root->appendChild($destination->importNode($child, true)); + } + + $root->appendChild($destination->createElement('mods')); + return $destination->save($destination_path) !== false; +} + function steam_workshop_request($url, $context, &$error = "") { $response = @file_get_contents($url, false, $context); diff --git a/Panel/modules/steam_workshop/workshop_admin.php b/Panel/modules/steam_workshop/workshop_admin.php index 54bb47a0..36f7ca47 100644 --- a/Panel/modules/steam_workshop/workshop_admin.php +++ b/Panel/modules/steam_workshop/workshop_admin.php @@ -93,12 +93,57 @@ function steam_workshop_admin_hidden_state($values) return $html; } +function steam_workshop_admin_get_game_options($db, &$workshop_config_labels) +{ + $games = array(0 => get_lang('select_game')); + $workshop_config_labels = array(); + $game_cfgs = $db->getGameCfgs(); + foreach($game_cfgs as $game_cfg) + { + $server_xml = read_server_config(SERVER_CONFIG_LOCATION."/".$game_cfg['home_cfg_file']); + if(isset($server_xml->installer) and $server_xml->installer == "steamcmd") + { + $cfgMods = $db->getCfgMods($game_cfg['home_cfg_id']); + foreach($cfgMods as $cfgMod) + { + $mod_xml = xml_get_mod($server_xml, $cfgMod['mod_key']); + if(isset($mod_xml->installer_name) and !in_array((string)$mod_xml->installer_name, get_blacklist())) + { + preg_match('/(linux|win)(32|64)?/i', $game_cfg['game_key'], $matches); + if(empty($matches[1])) + continue; + + if(strtolower($matches[1]) == 'linux') + $os = "Linux"; + elseif(strtolower($matches[1]) == 'win') + $os = "Windows"; + else + continue; + + if(isset($matches[2]) and strtolower($matches[2]) == '64') + $arch = "64"; + else + $arch = "32"; + + $modname = strtolower($cfgMod['mod_name']) == "none"? "":" [MOD:" . $cfgMod['mod_name']."]"; + $friendly_name = $game_cfg['game_name'] . " (" . $os . " " . $arch . "bits)$modname"; + $games[$game_cfg['home_cfg_id'].'-'.$cfgMod['mod_cfg_id'].'-'.$os] = $friendly_name; + $workshop_config_labels[(string)$mod_xml->installer_name."_".$os.".xml"] = $friendly_name; + } + } + } + } + return $games; +} + function exec_ogp_module() { Global $db,$view; echo '