Merge pull request #117 from GameServerPanel/copilot/fix-ui-module-issues
This commit is contained in:
commit
d36e85c71f
7 changed files with 238 additions and 52 deletions
|
|
@ -32,6 +32,7 @@ define('LANG_message', "Message");
|
|||
define('LANG_email_must_be_filled_out', "The email address must be filled out.");
|
||||
define('LANG_subject_must_be_filled_out', "The subject must be filled out.");
|
||||
define('LANG_message_must_be_filled_out', "The message must be filled out.");
|
||||
define('LANG_optional', "optional");
|
||||
define('LANG_send', "Send");
|
||||
define('LANG_error', "Error");
|
||||
define('LANG_info', "Info");
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
*/
|
||||
|
||||
require_once("server_config_parser.php");
|
||||
require_once(__DIR__ . "/xml_tag_descriptions.php");
|
||||
|
||||
/**
|
||||
* Safely convert any config value (string, NULL, or array from SimpleXML) to a
|
||||
|
|
@ -264,6 +265,14 @@ function config_games_print_editor_css()
|
|||
.xml-raw-section textarea{width:100%;min-height:300px;font-family:monospace;font-size:0.85rem;background:#0c0c0c;color:#eee;border:1px solid #3a3a3a;border-radius:4px;padding:8px}
|
||||
.xml-raw-warning{background:#2d2200;border:1px solid #7a5a00;border-radius:4px;padding:8px 12px;color:#f0c050;font-size:0.85rem;margin-bottom:6px}
|
||||
.xml-section-header{margin:20px 0 4px;font-size:0.8rem;color:#888;text-transform:uppercase;letter-spacing:0.1em;border-bottom:1px solid #2a2a2a;padding-bottom:4px}
|
||||
.xml-node__desc{font-size:0.82rem;color:#aaa;background:#0e0e0e;border-left:3px solid #2a4a7a;padding:6px 10px;margin:6px 0 8px;border-radius:0 4px 4px 0}
|
||||
.xml-node__options{margin:4px 0 4px 12px;padding:0;list-style:disc inside}
|
||||
.xml-node__options li{margin-bottom:2px}
|
||||
.xml-node__options code{color:#7eb3f0;background:rgba(30,100,200,0.12);padding:1px 4px;border-radius:3px}
|
||||
.xml-node__example{display:block;margin-top:4px;color:#888}
|
||||
.xml-node__example code{color:#a0d0a0;background:rgba(30,150,50,0.1);padding:1px 4px;border-radius:3px}
|
||||
.xml-jump-link{display:inline-block;margin-bottom:12px;padding:6px 14px;background:#1c6dd0;color:#fff;border-radius:4px;text-decoration:none;font-size:0.9rem}
|
||||
.xml-jump-link:hover{background:#1f7aec;text-decoration:none}
|
||||
</style>
|
||||
CSS;
|
||||
}
|
||||
|
|
@ -296,12 +305,34 @@ function config_games_render_node(SimpleXMLElement $node, array $ancestors, arra
|
|||
? "<span class='xml-node__badge xml-node__badge--required'>required</span>"
|
||||
: "<span class='xml-node__badge xml-node__badge--optional'>optional</span>";
|
||||
|
||||
// Look up per-tag description from the descriptions helper.
|
||||
$tagDescriptions = config_games_tag_descriptions();
|
||||
$tagDesc = $tagDescriptions[$name] ?? null;
|
||||
|
||||
$html = "<div class='{$nodeClass}'>";
|
||||
$actionId = 'node_action_' . substr(md5($safePath . $index), 0, 8);
|
||||
$html .= "<div class='xml-node__header'><div><div class='xml-node__title'>{$safeLabel}{$badge}</div><div class='xml-node__path'>{$displayPath}</div></div>";
|
||||
$html .= "<div class='xml-node__actions'><label for=\"{$actionId}\">Action</label>";
|
||||
$html .= "<select id=\"{$actionId}\" name=\"nodes[{$safeNodeKey}][action]\"><option value='keep'>Save Changes</option><option value='remove'>Remove Node</option></select>";
|
||||
$html .= "<button type='submit' name='save_xml' value='1' class='xml-node__apply'>Apply</button></div></div>";
|
||||
if ($tagDesc !== null) {
|
||||
$safeDesc = htmlspecialchars($tagDesc['desc'], ENT_QUOTES, 'UTF-8');
|
||||
$html .= "<div class='xml-node__desc'>{$safeDesc}";
|
||||
if (!empty($tagDesc['options'])) {
|
||||
$html .= "<ul class='xml-node__options'>";
|
||||
foreach ($tagDesc['options'] as $optVal => $optLabel) {
|
||||
$safeOptVal = htmlspecialchars((string)$optVal, ENT_QUOTES, 'UTF-8');
|
||||
$safeOptLabel = htmlspecialchars($optLabel, ENT_QUOTES, 'UTF-8');
|
||||
$html .= "<li><code>{$safeOptVal}</code> – {$safeOptLabel}</li>";
|
||||
}
|
||||
$html .= "</ul>";
|
||||
}
|
||||
if (!empty($tagDesc['example'])) {
|
||||
$safeExample = htmlspecialchars($tagDesc['example'], ENT_QUOTES, 'UTF-8');
|
||||
$html .= "<span class='xml-node__example'>Example: <code>{$safeExample}</code></span>";
|
||||
}
|
||||
$html .= "</div>";
|
||||
}
|
||||
$html .= "<div class='xml-node__body'>";
|
||||
$html .= "<input type='hidden' name=\"nodes[{$safeNodeKey}][path]\" value=\"{$safePath}\">";
|
||||
$html .= "<input type='hidden' name=\"nodes[{$safeNodeKey}][has_children]\" value=\"" . ($hasChildren ? '1' : '0') . "\">";
|
||||
|
|
@ -667,7 +698,8 @@ function exec_ogp_module() {
|
|||
</table>\n";
|
||||
|
||||
if ( isset($_GET['home_cfg_id']) )
|
||||
{
|
||||
{
|
||||
echo "<p><a class='xml-jump-link' href='#xml-editor-section' aria-label='Jump to XML Editor section below'>↓ Jump to XML Editor</a></p>";
|
||||
$home_cfg_id = trim($_GET['home_cfg_id']);
|
||||
|
||||
$cfg_info = $db->getGameCfg($home_cfg_id);
|
||||
|
|
@ -721,6 +753,7 @@ function exec_ogp_module() {
|
|||
print_failure(get_lang_f("error_when_handling_file",$config_file));
|
||||
} else {
|
||||
$raw_xml_content = htmlspecialchars(file_get_contents($config_file), ENT_QUOTES, 'UTF-8');
|
||||
echo "<div id='xml-editor-section'>";
|
||||
echo "<form action='?m=config_games&home_cfg_id=".$home_cfg_id."' method='post'>";
|
||||
echo "<input type='hidden' name='home_cfg_id' value='".(int)$home_cfg_id."'>";
|
||||
echo "<button type='submit' name='save_xml' value='1' class='xml-global-save xml-global-save--top'>".get_lang('save')."</button>";
|
||||
|
|
@ -738,6 +771,7 @@ function exec_ogp_module() {
|
|||
echo "<div class='xml-actions' style='margin-top:8px'><button type='submit' name='save_xml' value='1' class='xml-global-save'>Save Raw XML</button></div>";
|
||||
echo "</div>";
|
||||
echo "</form>";
|
||||
echo "</div>"; // #xml-editor-section
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
155
modules/config_games/xml_tag_descriptions.php
Normal file
155
modules/config_games/xml_tag_descriptions.php
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
<?php
|
||||
/*
|
||||
* OGP / GSP – Config Games XML tag descriptions
|
||||
*
|
||||
* Each entry maps an XML element name to an array with:
|
||||
* 'desc' – Short human-readable description of what the element does.
|
||||
* 'options' – (optional) array of allowed values with labels.
|
||||
* 'example' – (optional) A short illustrative value.
|
||||
*
|
||||
* Sourced from the OGP XML documentation and the schema in
|
||||
* modules/config_games/schema_server_config.xml.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the description map for all known game-config XML tags.
|
||||
*
|
||||
* @return array<string, array{desc: string, options?: array<string,string>, example?: string}>
|
||||
*/
|
||||
function config_games_tag_descriptions(): array
|
||||
{
|
||||
return [
|
||||
'game_key' => [
|
||||
'desc' => 'Unique lowercase identifier for this game configuration. Used internally to link homes, mods, and Workshop profiles.',
|
||||
'example' => 'arma3_linux64',
|
||||
],
|
||||
'protocol' => [
|
||||
'desc' => 'Query protocol used to monitor server status.',
|
||||
'options' => [
|
||||
'lgsl' => 'LGSL – Lightweight Game Server Library',
|
||||
'gameq' => 'GameQ – PHP-based multi-protocol server query',
|
||||
'' => 'None (server is not queryable)',
|
||||
],
|
||||
],
|
||||
'lgsl_query_name' => [
|
||||
'desc' => 'LGSL type string identifying the game in the LGSL library (only used when protocol is "lgsl").',
|
||||
'example' => 'arma3',
|
||||
],
|
||||
'gameq_query_name' => [
|
||||
'desc' => 'GameQ protocol name identifying the game (only used when protocol is "gameq").',
|
||||
'example' => 'arma3',
|
||||
],
|
||||
'installer' => [
|
||||
'desc' => 'Installer/updater helper used to download and update game server files.',
|
||||
'options' => [
|
||||
'steam' => 'SteamCMD / HLDSUpdateTool',
|
||||
'steamcmd' => 'SteamCMD (explicit)',
|
||||
'' => 'None (manual installation)',
|
||||
],
|
||||
],
|
||||
'game_name' => [
|
||||
'desc' => 'Display name shown in the panel UI for this game.',
|
||||
'example' => 'Arma 3',
|
||||
],
|
||||
'server_exec_name' => [
|
||||
'desc' => 'Filename of the server executable (without path). The panel uses this to detect whether the server process is running.',
|
||||
'example' => 'arma3server_x64',
|
||||
],
|
||||
'query_port' => [
|
||||
'desc' => 'Port offset added to the main port to obtain the query port used for status monitoring.',
|
||||
'example' => '1',
|
||||
],
|
||||
'cli_template' => [
|
||||
'desc' => 'Command-line template used to launch the server. Supports placeholder tokens such as %ip%, %port%, %slots%.',
|
||||
'example' => '-ip=%ip% -port=%port% -maxPlayers=%slots%',
|
||||
],
|
||||
'cli_params' => [
|
||||
'desc' => 'Container for individual <param> child elements that define configurable launch parameters shown in the panel UI.',
|
||||
],
|
||||
'reserve_ports' => [
|
||||
'desc' => 'Additional sequential ports (beyond the main port) that must be reserved for this server instance.',
|
||||
'example' => '3',
|
||||
],
|
||||
'cli_allow_chars' => [
|
||||
'desc' => 'Extra characters that are safe to include in command-line parameter values (extends the default whitelist).',
|
||||
'example' => '@_-.',
|
||||
],
|
||||
'maps_location' => [
|
||||
'desc' => 'Path inside the server directory where map files are stored. The panel uses this to populate map-selection dropdowns.',
|
||||
'example' => 'Maps',
|
||||
],
|
||||
'map_list' => [
|
||||
'desc' => 'Hardcoded comma-separated list of map names when maps cannot be read from disk.',
|
||||
],
|
||||
'console_log' => [
|
||||
'desc' => 'Relative path to the server log file that the panel displays in the console viewer.',
|
||||
'example' => 'logs/console.log',
|
||||
],
|
||||
'exe_location' => [
|
||||
'desc' => 'Subdirectory within the server installation where the executable resides. Leave empty if the executable is at the root.',
|
||||
'example' => 'Binaries/Win64',
|
||||
],
|
||||
'max_user_amount' => [
|
||||
'desc' => 'Maximum player slots the panel will allow for this game type. Enforced in the panel UI when creating or editing a server.',
|
||||
'example' => '64',
|
||||
],
|
||||
'control_protocol' => [
|
||||
'desc' => 'Protocol used to send RCON/admin commands to the running server.',
|
||||
'options' => [
|
||||
'rcon' => 'RCON (remote console)',
|
||||
'rconhl' => 'Half-Life RCON',
|
||||
'' => 'None',
|
||||
],
|
||||
],
|
||||
'control_protocol_type' => [
|
||||
'desc' => 'Sub-type or variant that further qualifies the control protocol.',
|
||||
'example' => 'rcon_password',
|
||||
],
|
||||
'mods' => [
|
||||
'desc' => 'Container element for mod definitions. Child <mod> elements describe each variant of the server configuration.',
|
||||
],
|
||||
'replace_texts' => [
|
||||
'desc' => 'Container for text-replacement rules applied to config files on the server.',
|
||||
],
|
||||
'server_params' => [
|
||||
'desc' => 'Additional fixed parameters appended verbatim to the server launch command.',
|
||||
],
|
||||
'custom_fields' => [
|
||||
'desc' => 'Container for admin-defined extra fields displayed in the server control panel.',
|
||||
],
|
||||
'list_players_command' => [
|
||||
'desc' => 'RCON command sent to the server to retrieve the current player list.',
|
||||
'example' => 'players',
|
||||
],
|
||||
'player_info_regex' => [
|
||||
'desc' => 'Regular expression used to parse each line of the player-list response into name and other fields.',
|
||||
],
|
||||
'player_info' => [
|
||||
'desc' => 'Defines which capture groups from player_info_regex map to player attributes (name, score, ping, etc.).',
|
||||
],
|
||||
'player_commands' => [
|
||||
'desc' => 'Container for RCON commands that can be executed on individual players (kick, ban, etc.).',
|
||||
],
|
||||
'pre_install' => [
|
||||
'desc' => 'Shell/batch script executed on the agent BEFORE the game server files are installed or updated.',
|
||||
],
|
||||
'post_install' => [
|
||||
'desc' => 'Shell/batch script executed on the agent AFTER the game server files are installed or updated.',
|
||||
],
|
||||
'pre_start' => [
|
||||
'desc' => 'Shell/batch script executed on the agent BEFORE the game server process is started.',
|
||||
],
|
||||
'post_start' => [
|
||||
'desc' => 'Shell/batch script executed on the agent AFTER the game server process has started.',
|
||||
],
|
||||
'environment_variables' => [
|
||||
'desc' => 'Container for environment variables that are set in the server process environment at startup.',
|
||||
],
|
||||
'lock_files' => [
|
||||
'desc' => 'Files that should not be overwritten when updating the server. Paths are relative to the server installation directory.',
|
||||
],
|
||||
'configuration_files' => [
|
||||
'desc' => 'Container listing server configuration files that the panel can display and edit via the config-file editor.',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ return [
|
|||
'button_save' => 'Save settings',
|
||||
'button_cancel' => 'Back to list',
|
||||
'label_feature_flag' => 'Enable scheduled Workshop updates for this server',
|
||||
'label_adapter' => 'Game adapter',
|
||||
'label_adapter' => 'Game type',
|
||||
'label_interval' => 'Update interval (minutes)',
|
||||
'label_interval_hint' => 'Runs on the agent scheduler. Allowed range: 15–360 minutes.',
|
||||
'label_staging_dir' => 'Staging directory (optional)',
|
||||
|
|
@ -17,24 +17,24 @@ return [
|
|||
'label_mod_import' => 'Workshop IDs list (one "id,@ModName" per line)',
|
||||
'hint_mod_import' => 'Paste from Modlist.txt or import from a collection. IDs are sanitized automatically.',
|
||||
'hint_admin_only' => 'Managed by your administrator.',
|
||||
'adapter_locked_note' => 'This adapter is enforced for the current game type by your administrator.',
|
||||
'admin_heading_game_mapping' => 'Adapter mapping by game type',
|
||||
'admin_subheading_game_mapping' => 'Pick which adapter becomes the default whenever a server of that game opens the Workshop UI.',
|
||||
'adapter_locked_note' => 'The game type for this server is managed by your administrator.',
|
||||
'admin_heading_game_mapping' => 'Game type mapping',
|
||||
'admin_subheading_game_mapping' => 'Pick which game configuration becomes the default whenever a server of that game opens the Workshop UI.',
|
||||
'admin_col_game_key' => 'Game key',
|
||||
'admin_col_adapter' => 'Adapter',
|
||||
'admin_col_adapter' => 'Game configuration',
|
||||
'admin_no_game_keys' => 'No server configuration XML files were detected.',
|
||||
'admin_heading_adapters' => 'Available adapters',
|
||||
'admin_heading_adapters' => 'Available game configurations',
|
||||
'admin_col_key' => 'Key',
|
||||
'admin_col_mods_dir' => 'Mods directory',
|
||||
'admin_col_notes' => 'Notes',
|
||||
'admin_heading_per_game' => 'Per-game adapters',
|
||||
'admin_subheading_per_game' => 'Each game should have its own adapter XML for Steam Workshop automation.',
|
||||
'admin_heading_per_game' => 'Per-game Workshop configurations',
|
||||
'admin_subheading_per_game' => 'Each game should have its own Workshop configuration to control how mods are installed.',
|
||||
'admin_col_status' => 'Status',
|
||||
'admin_col_updated' => 'Last updated',
|
||||
'admin_col_actions' => 'Actions',
|
||||
'admin_heading_edit_adapter' => 'Editing adapter for %s',
|
||||
'admin_hint_select_game' => 'Select a game in the table above to edit or create its adapter.',
|
||||
'status_no_adapter' => 'No adapter defined',
|
||||
'admin_heading_edit_adapter' => 'Editing Workshop configuration for %s',
|
||||
'admin_hint_select_game' => 'Select a game in the table above to edit or create its Workshop configuration.',
|
||||
'status_no_adapter' => 'Not configured',
|
||||
'status_enabled' => 'Enabled',
|
||||
'status_disabled' => 'Disabled',
|
||||
'status_hot_reload' => 'Hot reload ready',
|
||||
|
|
@ -55,15 +55,15 @@ return [
|
|||
'install_staging' => 'Download to staging only (manual apply)',
|
||||
'action_queue_for_restart' => 'Queue for restart',
|
||||
'action_hot_reload_if_supported' => 'Hot reload if the adapter allows it',
|
||||
'summary_adapter' => 'Adapter',
|
||||
'summary_adapter' => 'Game',
|
||||
'summary_interval' => 'Interval',
|
||||
'summary_mods' => 'Mods',
|
||||
'summary_last_saved' => 'Last saved',
|
||||
'summary_hot_reload' => 'Hot reload',
|
||||
'raw_definition_label' => 'Raw Workshop list',
|
||||
'message_mappings_saved' => 'Adapter mappings saved.',
|
||||
'message_adapter_saved' => 'Adapter saved.',
|
||||
'message_adapter_deleted' => 'Adapter deleted.',
|
||||
'message_mappings_saved' => 'Game type mappings saved.',
|
||||
'message_adapter_saved' => 'Game configuration saved.',
|
||||
'message_adapter_deleted' => 'Game configuration deleted.',
|
||||
'error_admin_only' => 'Administrator access required.',
|
||||
'mod_picker_heading' => 'Workshop library',
|
||||
'mod_picker_hint' => 'Search Steam Workshop and add mods to keep them synced automatically.',
|
||||
|
|
@ -87,15 +87,15 @@ return [
|
|||
'mod_picker_request_label' => 'Submitting request',
|
||||
'mod_picker_request_hint' => 'Exact Steam URL preview. The input shows the text that will be submitted.',
|
||||
'mod_picker_request_input_label' => 'Workshop query preview',
|
||||
'error_game_key_required' => 'Select a valid game key before editing the adapter.',
|
||||
'error_adapter_delete_failed' => 'Adapter could not be deleted.',
|
||||
'error_game_key_required' => 'Select a valid game key before editing the Workshop configuration.',
|
||||
'error_adapter_delete_failed' => 'Game configuration could not be deleted.',
|
||||
'button_edit_adapter' => 'Edit',
|
||||
'button_create_adapter' => 'Create',
|
||||
'button_delete_adapter' => 'Delete',
|
||||
'button_save_adapter' => 'Save adapter',
|
||||
'confirm_delete_adapter' => 'Delete this adapter? Servers mapped to it will fall back to defaults.',
|
||||
'button_save_adapter' => 'Save game configuration',
|
||||
'confirm_delete_adapter' => 'Delete this game configuration? Servers mapped to it will fall back to defaults.',
|
||||
'label_game_key' => 'Game key',
|
||||
'label_adapter_name' => 'Adapter display name',
|
||||
'label_adapter_name' => 'Game display name',
|
||||
'label_adapter_app_id' => 'Steam App ID',
|
||||
'label_adapter_mods_dir' => 'Mods directory',
|
||||
'label_adapter_keys_dir' => 'Keys directory (optional)',
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ declare(strict_types=1);
|
|||
<span class="sw-game-label__name"><?php echo htmlspecialchars($row['game_name']); ?></span>
|
||||
<span class="sw-badge sw-badge--app">App ID <?php echo htmlspecialchars($row['app_id']); ?></span>
|
||||
<?php if ($row['exists']): ?>
|
||||
<span class="sw-badge sw-badge--custom"><?php echo htmlspecialchars($lang['badge_custom_xml'] ?? 'Custom XML'); ?></span>
|
||||
<span class="sw-badge sw-badge--custom"><?php echo htmlspecialchars($lang['badge_custom_xml'] ?? 'Custom config'); ?></span>
|
||||
<?php endif; ?>
|
||||
</div>
|
||||
<div class="sw-game-variants">
|
||||
|
|
@ -61,7 +61,7 @@ declare(strict_types=1);
|
|||
<?php endforeach; ?>
|
||||
</div>
|
||||
</div>
|
||||
<small class="sw-game-label__hint"><?php echo htmlspecialchars($lang['admin_hint_inline_edit'] ?? 'Use the toggle to edit the XML inline.'); ?></small>
|
||||
<small class="sw-game-label__hint"><?php echo htmlspecialchars($lang['admin_hint_inline_edit'] ?? 'Use the toggle to configure this game inline.'); ?></small>
|
||||
</td>
|
||||
<td>
|
||||
<select form="sw-mapping-form" name="mapping[<?php echo htmlspecialchars($groupKey); ?>]">
|
||||
|
|
@ -86,13 +86,13 @@ declare(strict_types=1);
|
|||
</td>
|
||||
<td class="sw-actions">
|
||||
<button type="button" class="btn secondary js-toggle-adapter" data-target="<?php echo htmlspecialchars($formId); ?>" aria-expanded="<?php echo $isOpen ? 'true' : 'false'; ?>">
|
||||
<?php echo htmlspecialchars($row['exists'] ? ($lang['button_edit_adapter'] ?? 'Edit adapter') : ($lang['button_create_adapter'] ?? 'Create adapter')); ?>
|
||||
<?php echo htmlspecialchars($row['exists'] ? ($lang['button_edit_adapter'] ?? 'Edit') : ($lang['button_create_adapter'] ?? 'Create')); ?>
|
||||
</button>
|
||||
<?php if ($row['exists']): ?>
|
||||
<form method="post" class="sw-inline-delete">
|
||||
<input type="hidden" name="admin_action" value="delete_adapter">
|
||||
<input type="hidden" name="game_key" value="<?php echo htmlspecialchars($primaryKey); ?>">
|
||||
<button type="submit" class="btn danger" onclick="return confirm('<?php echo htmlspecialchars($lang['confirm_delete_adapter'] ?? 'Delete this adapter?'); ?>');">
|
||||
<button type="submit" class="btn danger" onclick="return confirm('<?php echo htmlspecialchars($lang['confirm_delete_adapter'] ?? 'Delete this game configuration?'); ?>');">
|
||||
<?php echo htmlspecialchars($lang['button_delete_adapter'] ?? 'Delete'); ?>
|
||||
</button>
|
||||
</form>
|
||||
|
|
@ -111,7 +111,7 @@ declare(strict_types=1);
|
|||
<input type="text" value="<?php echo htmlspecialchars($form['game_key']); ?>" readonly>
|
||||
</label>
|
||||
<label>
|
||||
<?php echo htmlspecialchars($lang['label_adapter_name'] ?? 'Adapter display name'); ?>
|
||||
<?php echo htmlspecialchars($lang['label_adapter_name'] ?? 'Game display name'); ?>
|
||||
<input type="text" name="adapter[name]" value="<?php echo htmlspecialchars($form['name']); ?>" required>
|
||||
</label>
|
||||
<label>
|
||||
|
|
@ -143,7 +143,7 @@ declare(strict_types=1);
|
|||
</label>
|
||||
|
||||
<div class="sw-form__actions">
|
||||
<button class="btn primary" type="submit"><?php echo htmlspecialchars($lang['button_save_adapter'] ?? 'Save adapter'); ?></button>
|
||||
<button class="btn primary" type="submit"><?php echo htmlspecialchars($lang['button_save_adapter'] ?? 'Save game configuration'); ?></button>
|
||||
<button type="button" class="btn js-toggle-adapter" data-target="<?php echo htmlspecialchars($formId); ?>"><?php echo htmlspecialchars($lang['button_cancel'] ?? 'Cancel'); ?></button>
|
||||
</div>
|
||||
</form>
|
||||
|
|
@ -159,12 +159,12 @@ declare(strict_types=1);
|
|||
<button class="btn primary" type="submit" form="sw-mapping-form"><?php echo htmlspecialchars($lang['button_save']); ?></button>
|
||||
</div>
|
||||
|
||||
<h3><?php echo htmlspecialchars($lang['admin_heading_adapters'] ?? 'Available adapters'); ?></h3>
|
||||
<h3><?php echo htmlspecialchars($lang['admin_heading_adapters'] ?? 'Available game configurations'); ?></h3>
|
||||
<table class="table sw-mods__table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php echo htmlspecialchars($lang['admin_col_key'] ?? 'Key'); ?></th>
|
||||
<th><?php echo htmlspecialchars($lang['summary_adapter']); ?></th>
|
||||
<th><?php echo htmlspecialchars($lang['summary_adapter'] ?? 'Game'); ?></th>
|
||||
<th>Steam App ID</th>
|
||||
<th><?php echo htmlspecialchars($lang['admin_col_mods_dir'] ?? 'Mods Dir'); ?></th>
|
||||
<th><?php echo htmlspecialchars($lang['summary_hot_reload']); ?></th>
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ $currentAdapterName = $adapterOptions[$formConfig['adapter_key']] ?? strtoupper(
|
|||
</label>
|
||||
|
||||
<label>
|
||||
<span><?php echo htmlspecialchars($lang['label_adapter']); ?></span>
|
||||
<span><?php echo htmlspecialchars($lang['label_adapter'] ?? 'Game type'); ?></span>
|
||||
<?php if ($adapterLocked): ?>
|
||||
<input type="text" value="<?php echo htmlspecialchars($currentAdapterName); ?>" disabled />
|
||||
<small><?php echo htmlspecialchars($lang['adapter_locked_note'] ?? 'This adapter is managed by the administrator.'); ?></small>
|
||||
<small><?php echo htmlspecialchars($lang['adapter_locked_note'] ?? 'The game type for this server is managed by the administrator.'); ?></small>
|
||||
<?php else: ?>
|
||||
<select name="workshop[adapter_key]">
|
||||
<?php foreach ((array)$adapterOptions as $key => $label): ?>
|
||||
|
|
|
|||
|
|
@ -36,10 +36,17 @@ function exec_ogp_module() {
|
|||
|
||||
if(isset($_POST["submit"])){
|
||||
|
||||
$email = $_POST["email"];
|
||||
$email = isset($_POST["email"]) ? trim($_POST["email"]) : '';
|
||||
$gameserver = $_POST['gameserver'];
|
||||
$subject = get_lang('support').": ".$_POST["subject"];
|
||||
$message = $_POST["message"];
|
||||
$subjectRaw = isset($_POST["subject"]) ? trim($_POST["subject"]) : '';
|
||||
$subject = get_lang('support') . ($subjectRaw !== '' ? ": " . $subjectRaw : '');
|
||||
$message = isset($_POST["message"]) ? trim($_POST["message"]) : '';
|
||||
|
||||
if ($message === '') {
|
||||
$errMsg = get_lang('message_must_be_filled_out');
|
||||
$errTitle = get_lang('error');
|
||||
echo "<script>$(document).ready(function(){\$('#dialog').html('<p><img src=\"modules/support/images/error.png\">" . htmlspecialchars($errMsg, ENT_QUOTES) . "</p>').attr('title', '" . htmlspecialchars($errTitle, ENT_QUOTES) . "').dialog();});</script>";
|
||||
} else {
|
||||
|
||||
//TICKET SUBMITTED, POST ON DISCORD and log
|
||||
//logger
|
||||
|
|
@ -59,8 +66,8 @@ if (!empty($webhook)) {
|
|||
}
|
||||
//end discord
|
||||
|
||||
$content = get_lang_f('support_email_content', $user['users_login'], $email, $gameserver, $message);
|
||||
if( mymail($email, $subject, $content, $settings, $user['users_login']) == TRUE )
|
||||
$content = get_lang_f('support_email_content', $user['users_login'], $email, $gameserver, $message);
|
||||
if ($email === '' || mymail($email, $subject, $content, $settings, $user['users_login']) == TRUE)
|
||||
{
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
|
|
@ -70,7 +77,8 @@ if (!empty($webhook)) {
|
|||
</script>
|
||||
<?php
|
||||
}
|
||||
} // End else
|
||||
} // end else (message not empty)
|
||||
} // end if submit
|
||||
echo '<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css" integrity="sha512-DTOQO9RWCH3ppGqcWaEA1BIZOC6xxalwEsw9c2QQeAIftl+Vegovlnee1c9QX4TctnWMn13TZye+giMm8e2LwA==" crossorigin="anonymous" referrerpolicy="no-referrer" />';
|
||||
echo "<h2>".get_lang('support')."</h2>";
|
||||
echo '
|
||||
|
|
@ -95,7 +103,7 @@ if (!empty($webhook)) {
|
|||
|
||||
if(!isset($user['users_email']) or $user['users_email'] == "")
|
||||
{
|
||||
echo get_lang('email_address').':
|
||||
echo get_lang('email_address').' <em>('.get_lang('optional').')</em>:
|
||||
<br />
|
||||
<input type="text" name="email" id="email" style="width: 250px;" />
|
||||
<br />
|
||||
|
|
@ -106,7 +114,7 @@ if (!empty($webhook)) {
|
|||
echo '<input type="hidden" name="email" id="email" value="'.$user['users_email'].'" />';
|
||||
}
|
||||
|
||||
echo get_lang('subject').':
|
||||
echo get_lang('subject').' <em>('.get_lang('optional').')</em>:
|
||||
<br />
|
||||
<input type="text" name="subject" id="subject" style="width: 250px;" />
|
||||
<br />
|
||||
|
|
@ -123,20 +131,8 @@ if (!empty($webhook)) {
|
|||
<script type="text/javascript">
|
||||
function validateForm()
|
||||
{
|
||||
var $email=document.forms["contactForm"]["email"].value;
|
||||
var $subject=document.forms["contactForm"]["subject"].value;
|
||||
var $message=document.forms["contactForm"]["message"].value;
|
||||
if ($email==null || $email=="")
|
||||
{
|
||||
$('#dialog').html('<p><img src="modules/support/images/error.png" ><?php print_lang('email_must_be_filled_out'); ?></p>').attr('title', '<?php print_lang('error'); ?>').dialog();
|
||||
return false;
|
||||
}
|
||||
else if ($subject==null || $subject=="")
|
||||
{
|
||||
$('#dialog').html('<p><img src="modules/support/images/error.png" ><?php print_lang('subject_must_be_filled_out'); ?></p>').attr('title', '<?php print_lang('error'); ?>').dialog();
|
||||
return false;
|
||||
}
|
||||
else if ($message==null || $message=="")
|
||||
if ($message==null || $message=="")
|
||||
{
|
||||
$('#dialog').html('<p><img src="modules/support/images/error.png" ><?php print_lang('message_must_be_filled_out'); ?></p>').attr('title', '<?php print_lang('error'); ?>').dialog();
|
||||
return false;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue