diff --git a/modules/billing/add_to_cart.php b/modules/billing/add_to_cart.php index 83606b46..4f36f8b4 100644 --- a/modules/billing/add_to_cart.php +++ b/modules/billing/add_to_cart.php @@ -29,19 +29,7 @@ function billing_generate_password(int $bytes = 12): string function billing_normalize_duration(string $duration): array { - $duration = strtolower(trim($duration)); - switch ($duration) { - case 'day': - case 'daily': - return ['invoice_duration' => 'day', 'rate_type' => 'daily', 'days' => 1]; - case 'year': - case 'yearly': - return ['invoice_duration' => 'year', 'rate_type' => 'yearly', 'days' => 365]; - case 'month': - case 'monthly': - default: - return ['invoice_duration' => 'month', 'rate_type' => 'monthly', 'days' => 31]; - } + return ['invoice_duration' => 'month', 'rate_type' => 'monthly', 'days' => 31]; } function billing_money_to_cents(float $amount): int @@ -60,23 +48,17 @@ function billing_rate_from_service(mysqli $db, string $table_prefix, int $servic return 0.0; } - $stmt = $db->prepare("SELECT price_daily, price_monthly, price_year FROM {$table_prefix}billing_services WHERE service_id = ? LIMIT 1"); + $stmt = $db->prepare("SELECT price_monthly FROM {$table_prefix}billing_services WHERE service_id = ? LIMIT 1"); if (!$stmt) { return 0.0; } $stmt->bind_param('i', $service_id); $stmt->execute(); - $stmt->bind_result($price_daily, $price_monthly, $price_year); + $stmt->bind_result($price_monthly); $rate = 0.0; if ($stmt->fetch()) { - if ($rate_type === 'daily') { - $rate = floatval($price_daily); - } elseif ($rate_type === 'yearly') { - $rate = floatval($price_year); - } else { - $rate = floatval($price_monthly); - } + $rate = floatval($price_monthly); } $stmt->close(); @@ -179,19 +161,13 @@ $slot_min_qty = 1; $slot_max_qty = 1; $durationInfo = billing_normalize_duration($invoice_duration); if ($service_id > 0) { - $stmt = $db->prepare("SELECT service_name, price_daily, price_monthly, price_year, slot_min_qty, slot_max_qty FROM {$table_prefix}billing_services WHERE service_id = ? LIMIT 1"); + $stmt = $db->prepare("SELECT service_name, price_monthly, slot_min_qty, slot_max_qty FROM {$table_prefix}billing_services WHERE service_id = ? LIMIT 1"); if ($stmt) { $stmt->bind_param('i', $service_id); $stmt->execute(); - $stmt->bind_result($service_name, $price_daily, $price_monthly, $price_year, $slot_min_qty, $slot_max_qty); + $stmt->bind_result($service_name, $price_monthly, $slot_min_qty, $slot_max_qty); if ($stmt->fetch()) { - if ($durationInfo['rate_type'] === 'daily') { - $base_rate = floatval($price_daily); - } elseif ($durationInfo['rate_type'] === 'yearly') { - $base_rate = floatval($price_year); - } else { - $base_rate = floatval($price_monthly); - } + $base_rate = floatval($price_monthly); // constrain slots if ($max_players < $slot_min_qty) $max_players = $slot_min_qty; if ($max_players > $slot_max_qty) $max_players = $slot_max_qty; diff --git a/modules/billing/adminserverlist.php b/modules/billing/adminserverlist.php index b22367c3..a0bca5a9 100644 --- a/modules/billing/adminserverlist.php +++ b/modules/billing/adminserverlist.php @@ -21,8 +21,8 @@ .muted { color: #999; font-size: 0.85em; } .flash-ok { background: #d4edda; border: 1px solid #c3e6cb; padding: 10px 12px; margin-bottom: 10px; border-radius: 6px; color: #155724; } .flash-err { background: #f8d7da; border: 1px solid #f5c6cb; padding: 10px 12px; margin-bottom: 10px; border-radius: 6px; color: #721c24; } - .servers-cell { text-align: left; } - .server-cb-label { display: block; white-space: nowrap; margin: 2px 0; } + .servers-cell { text-align: left; min-width: 240px; max-width: 280px; } + .server-cb-label { display: block; white-space: normal; margin: 2px 0; } .action-cell { text-align: center; min-width: 120px; } .btn-row-save, .btn-save-all { border: 1px solid #3e7ab8; @@ -65,7 +65,7 @@ * * Columns that are admin-editable and NEVER overwritten by sync: * enabled, slot_min_qty, slot_max_qty, - * price_daily, price_monthly, price_year, + * price_monthly, * remote_server_id, description, img_url */ @@ -310,7 +310,7 @@ $flashType = 'ok'; $sort = strtolower((string)($_GET['sort'] ?? $_POST['sort'] ?? 'game')); $dir = strtolower((string)($_GET['dir'] ?? $_POST['dir'] ?? 'asc')) === 'desc' ? 'desc' : 'asc'; $gameMode = strtolower((string)($_GET['game_mode'] ?? $_POST['game_mode'] ?? 'name')); -if (!in_array($sort, ['game', 'config', 'enabled', 'day', 'month', 'year', 'servers'], true)) { +if (!in_array($sort, ['game', 'config', 'enabled', 'month', 'servers'], true)) { $sort = 'game'; } if (!in_array($gameMode, ['name', 'enabled'], true)) { @@ -367,9 +367,7 @@ if (isset($_POST['save_services']) || isset($_POST['save_row'])) { continue; } $enabled = isset($svcData['enabled']) ? 1 : 0; - $priceDaily = number_format((float)($svcData['price_daily'] ?? 0), 2, '.', ''); $priceMonthly = number_format((float)($svcData['price_monthly'] ?? 0), 2, '.', ''); - $priceYear = number_format((float)($svcData['price_year'] ?? 0), 2, '.', ''); $slotMin = max(1, (int)($svcData['slot_min_qty'] ?? 1)); $slotMax = max(1, (int)($svcData['slot_max_qty'] ?? 1)); if ($slotMax < $slotMin) { $slotMax = $slotMin; } @@ -396,9 +394,7 @@ if (isset($_POST['save_services']) || isset($_POST['save_row'])) { $ok = $db->query( "UPDATE `{$table_prefix}billing_services` SET enabled = {$enabled}, - price_daily = '{$priceDaily}', price_monthly = '{$priceMonthly}', - price_year = '{$priceYear}', slot_min_qty = {$slotMin}, slot_max_qty = {$slotMax}, description = '{$description}', @@ -453,7 +449,7 @@ while ($rsRes && ($row = $rsRes->fetch_assoc())) { $services = []; $svcRes = $db->query( "SELECT bs.service_id, bs.service_name, bs.enabled, - bs.price_daily, bs.price_monthly, bs.price_year, + bs.price_monthly, bs.slot_min_qty, bs.slot_max_qty, bs.remote_server_id, bs.description, bs.img_url, ch.home_cfg_file @@ -474,15 +470,9 @@ if (!empty($services)) { case 'enabled': $cmp = ((int)($a['enabled'] ?? 0)) <=> ((int)($b['enabled'] ?? 0)); break; - case 'day': - $cmp = ((float)($a['price_daily'] ?? 0)) <=> ((float)($b['price_daily'] ?? 0)); - break; case 'month': $cmp = ((float)($a['price_monthly'] ?? 0)) <=> ((float)($b['price_monthly'] ?? 0)); break; - case 'year': - $cmp = ((float)($a['price_year'] ?? 0)) <=> ((float)($b['price_year'] ?? 0)); - break; case 'servers': $countA = trim((string)($a['remote_server_id'] ?? '')) === '' ? 0 : count(array_filter(explode(',', (string)$a['remote_server_id']), 'strlen')); $countB = trim((string)($b['remote_server_id'] ?? '')) === '' ? 0 : count(array_filter(explode(',', (string)$b['remote_server_id']), 'strlen')); @@ -549,18 +539,10 @@ if (!empty($services)) { Min Slots Max Slots - - - Price / Day ($) - Price / Month ($) - - - Price / Year ($) - Description Image @@ -615,24 +597,12 @@ if (!empty($services)) { value=""> - - - - - - - -
  • A service will only appear in the store when Enabled is checked and at least one server is selected.
  • +
  • Price / Month ($) is the canonical billing price used by cart, checkout, and provisioning.
  • The Game Name and Config XML columns are sourced from and are read-only here. To change them, update the game XML config in the panel.
  • diff --git a/modules/billing/api/capture_order.php b/modules/billing/api/capture_order.php index 1d5f6a68..a0f6b2cd 100644 --- a/modules/billing/api/capture_order.php +++ b/modules/billing/api/capture_order.php @@ -124,19 +124,7 @@ function cap_invoice_ids_from_custom_id(?string $customId): array { } function cap_get_duration_metadata(array $invoice): array { - $duration = strtolower((string)($invoice['invoice_duration'] ?? $invoice['rate_type'] ?? 'month')); - switch ($duration) { - case 'day': - case 'daily': - return ['invoice_duration' => 'day', 'rate_type' => 'daily', 'days' => 1]; - case 'year': - case 'yearly': - return ['invoice_duration' => 'year', 'rate_type' => 'yearly', 'days' => 365]; - case 'month': - case 'monthly': - default: - return ['invoice_duration' => 'month', 'rate_type' => 'monthly', 'days' => 31]; - } + return ['invoice_duration' => 'month', 'rate_type' => 'monthly', 'days' => 31]; } function cap_get_end_date(array $invoice, ?string $fromDate = null): string { diff --git a/modules/billing/checkout_free.php b/modules/billing/checkout_free.php index 6c9b8f03..b5453fbd 100644 --- a/modules/billing/checkout_free.php +++ b/modules/billing/checkout_free.php @@ -111,19 +111,7 @@ require_once __DIR__ . '/classes/BillingService.php'; $repo = new BillingRepository($mysqli, $table_prefix); $newOrderIds = []; $duration_meta = static function (array $invoice): array { - $duration = strtolower((string)($invoice['invoice_duration'] ?? $invoice['rate_type'] ?? 'month')); - switch ($duration) { - case 'day': - case 'daily': - return ['invoice_duration' => 'day', 'rate_type' => 'daily', 'days' => 1]; - case 'year': - case 'yearly': - return ['invoice_duration' => 'year', 'rate_type' => 'yearly', 'days' => 365]; - case 'month': - case 'monthly': - default: - return ['invoice_duration' => 'month', 'rate_type' => 'monthly', 'days' => 31]; - } + return ['invoice_duration' => 'month', 'rate_type' => 'monthly', 'days' => 31]; }; foreach ($invoices as $inv) { diff --git a/modules/billing/classes/BillingService.php b/modules/billing/classes/BillingService.php index eeee8aac..bca672ad 100644 --- a/modules/billing/classes/BillingService.php +++ b/modules/billing/classes/BillingService.php @@ -33,23 +33,9 @@ class BillingService { $qty = max(1, $qty); $players = max(1, $players); - - switch ($rateType) { - case 'daily': - $basePrice = (float)($service['price_daily'] ?? 0); - $periodDays = $qty; - break; - case 'yearly': - $basePrice = (float)($service['price_year'] ?? 0); - $periodDays = $qty * 365; - break; - case 'monthly': - default: - $rateType = 'monthly'; - $basePrice = (float)($service['price_monthly'] ?? 0); - $periodDays = $qty * 31; - break; - } + $rateType = 'monthly'; + $basePrice = (float)($service['price_monthly'] ?? 0); + $periodDays = $qty * 31; // price_monthly etc is the per-player per-period rate $ratePerPlayer = $basePrice; @@ -163,9 +149,7 @@ class BillingService $periodEnd = $invoiceRow['period_end'] ?? null; if (!$periodEnd) { - $rateType = $invoiceRow['rate_type'] ?? 'monthly'; - $periodMap = ['daily' => '+1 day', 'monthly' => '+31 days', 'yearly' => '+365 days']; - $periodEnd = date('Y-m-d H:i:s', strtotime($periodMap[$rateType] ?? '+31 days')); + $periodEnd = date('Y-m-d H:i:s', strtotime('+31 days')); } // If current expiry is in the future, extend from it; otherwise reset from period_end @@ -177,9 +161,7 @@ class BillingService if ($periodStart && $periodEndVal) { $currentPeriodSecs = strtotime($periodEndVal) - strtotime($periodStart); } else { - $rateType2 = $invoiceRow['rate_type'] ?? 'monthly'; - $periodSecMap = ['daily' => 86400, 'monthly' => 31 * 86400, 'yearly' => 365 * 86400]; - $currentPeriodSecs = $periodSecMap[$rateType2] ?? (31 * 86400); + $currentPeriodSecs = 31 * 86400; } $newExpiry = date('Y-m-d H:i:s', strtotime($currentExpiry) + max(86400, $currentPeriodSecs)); } else { diff --git a/modules/billing/create_servers.php b/modules/billing/create_servers.php index f304d505..46c8a8c5 100644 --- a/modules/billing/create_servers.php +++ b/modules/billing/create_servers.php @@ -1,6 +1,7 @@ mods->mod[0])) { - $mod_xml = $server_xml->mods->mod[0]; - $modkey = (string)$mod_xml['key']; - } - if ($mod_xml === false) { - $order_failed = true; - $order_failure_reason = "No installable mod profile exists in XML for home #{$home_id}."; - } else { - $installer_name = (string)$mod_xml->installer_name; - $resolved_mod_cfg_id = intval($selected_mod['mod_cfg_id'] ?? $resolved_mod_cfg_id); - } - } - } - - //Get Preinstall commands from xml - $precmd = !$order_failed ? $server_xml->pre_install : ''; - - - //Get Postinstall commands from xml - $postcmd = !$order_failed ? $server_xml->post_install : ''; - - //Enable FTP account in remote server if (!$order_failed && $ftp == "enabled") { $remote->ftp_mgr("useradd", $home_info['home_id'], $home_info['ftp_password'], $home_info['home_path']); $db->changeFtpStatus('enabled',$home_info['home_id']); } - - //Install files for this service in the remote server - if (!$order_failed) { - $exec_folder_path = clean_path($home_info['home_path'] . "/" . $server_xml->exe_location ); - $exec_path = clean_path($exec_folder_path . "/" . $server_xml->server_exec_name ); - } - if (!$order_failed && (string)$server_xml->installer === "steamcmd" && !empty((string)$installer_name) ) - { - if( preg_match("/win32/", $server_xml->game_key) OR preg_match("/win64/", $server_xml->game_key) ) - $cfg_os = "windows"; - elseif( preg_match("/linux/", $server_xml->game_key) ) - $cfg_os = "linux"; - - // Some games like L4D2 require anonymous login - if(!empty($mod_xml->installer_login)){ - $login = $mod_xml->installer_login; - $pass = ''; - }else{ - $login = $settings['steam_user']; - $pass = $settings['steam_pass']; - } - - $modname = ( $installer_name == '90' and !preg_match("/(cstrike|valve)/", $modkey) ) ? $modkey : ''; - $betaname = isset($mod_xml->betaname) ? $mod_xml->betaname : ''; - $betapwd = isset($mod_xml->betapwd) ? $mod_xml->betapwd : ''; - $arch = isset($mod_xml->steam_bitness) ? $mod_xml->steam_bitness : ''; - - $remote->steam_cmd( $home_id,$home_info['home_path'],$installer_name,$modname, - $betaname,$betapwd,$login,$pass,$settings['steam_guard'], - $exec_folder_path,$exec_path,$precmd,$postcmd,$cfg_os,'',$arch); - } - elseif (!$order_failed) - { - // No SteamCMD installer — run pre/post install scripts only. - if (!empty((string)$precmd)) { - $result = $remote->exec((string)$precmd); - if ($result === NULL) - $db->logger("Script-only install: pre_install script returned no output for home_id $home_id"); - } - if (!empty((string)$postcmd)) { - $result = $remote->exec((string)$postcmd); - if ($result === NULL) - $db->logger("Script-only install: post_install script returned no output for home_id $home_id"); + if (!$order_failed) { + $autoInstall = gamemanager_trigger_update_install( + $db, + $home_info, + intval($mod_id), + array('settings' => $settings) + ); + $mod_id = intval($autoInstall['mod_id'] ?? $mod_id); + if (empty($autoInstall['ok'])) { + $order_failed = true; + $order_failure_reason = "Server files have not been installed yet. " . ($autoInstall['message'] ?? 'Auto install could not be started.'); } } if (!$order_failed) { @@ -529,54 +455,18 @@ function exec_ogp_module() } $end_date_str = date('Y-m-d H:i:s', $existing_end); } - elseif ($order['invoice_duration'] == "day") + else { - - if(empty($order['end_date']) || $order['end_date'] === NULL){ - $end_date = strtotime('+'.$order['qty'].' day'); + $qty_days = max(1, intval($order['qty'])) * 31; + if (empty($order['end_date']) || $order['end_date'] === NULL) { + $end_date = strtotime('+' . $qty_days . ' day'); + } else { + $current_end = strtotime($order['end_date']); + if ($current_end === false) { + $current_end = time(); + } + $end_date = strtotime('+' . $qty_days . ' day', $current_end); } - else{ - //this is a renewel, start from end of previous order - $current_end = strtotime($order['end_date']); - if ($current_end === false) { - $current_end = time(); // fallback to now if date is invalid - } - $end_date = strtotime('+'.$order['qty'].' day', $current_end); - } - - } - elseif ($order['invoice_duration'] == "month") - { - // this is a new order - if(empty($order['end_date']) || $order['end_date'] === NULL){ - $end_date = strtotime('+'.(intval($order['qty']) * 31).' day'); - - } - else{ - //this is a renewel, start from end of previous order - $current_end = strtotime($order['end_date']); - if ($current_end === false) { - $current_end = time(); // fallback to now if date is invalid - } - $end_date = strtotime('+'.(intval($order['qty']) * 31).' day', $current_end); - } - } - elseif ($order['invoice_duration'] == "year") - { - // this is a new order - if(empty($order['end_date']) || $order['end_date'] === NULL){ - $end_date = strtotime('+'.$order['qty'].' year'); - } - else{ - //this is a renewel, start from end of previous order - $current_end = strtotime($order['end_date']); - if ($current_end === false) { - $current_end = time(); // fallback to now if date is invalid - } - $end_date = strtotime('+'.$order['qty'].' year', $current_end); - - } - } if (!isset($end_date_str)) { $end_date_str = date('Y-m-d H:i:s', $end_date); diff --git a/modules/billing/payment_success.php b/modules/billing/payment_success.php index f04de5f4..18ed9dce 100644 --- a/modules/billing/payment_success.php +++ b/modules/billing/payment_success.php @@ -176,7 +176,7 @@ if ($db && $user_id > 0) {

    What Happens Next?

    diff --git a/modules/gamemanager/update_actions.php b/modules/gamemanager/update_actions.php new file mode 100644 index 00000000..d24b779b --- /dev/null +++ b/modules/gamemanager/update_actions.php @@ -0,0 +1,131 @@ + 0 && isset($mods[$preferred_mod_id])) { + return $preferred_mod_id; + } + $keys = array_keys($mods); + return intval(reset($keys)); + } +} + +if (!function_exists('gamemanager_trigger_update_install')) { + function gamemanager_trigger_update_install($db, array $home_info, int $mod_id, array $options = array()): array + { + $home_id = intval($home_info['home_id'] ?? 0); + $mod_id = gamemanager_choose_mod_id($home_info, $mod_id); + if ($home_id <= 0) { + return array('ok' => false, 'pending' => true, 'message' => 'Invalid home_id.', 'mod_id' => $mod_id); + } + if ($mod_id <= 0 || empty($home_info['mods'][$mod_id])) { + return array('ok' => false, 'pending' => true, 'message' => "No mod profile configured for home #{$home_id}.", 'mod_id' => $mod_id); + } + + $server_xml = read_server_config(SERVER_CONFIG_LOCATION . "/" . $home_info['home_cfg_file']); + if (!$server_xml) { + return array('ok' => false, 'pending' => true, 'message' => "Could not read server config XML for home #{$home_id}.", 'mod_id' => $mod_id); + } + + $remote = new OGPRemoteLibrary($home_info['agent_ip'], $home_info['agent_port'], $home_info['encryption_key'], $home_info['timeout']); + if ($remote->status_chk() === 0) { + return array('ok' => false, 'pending' => true, 'message' => 'Agent is offline.', 'mod_id' => $mod_id); + } + if ($remote->is_screen_running(OGP_SCREEN_TYPE_HOME, $home_id) == 1) { + return array('ok' => false, 'pending' => false, 'message' => 'Server is running and cannot be updated.', 'mod_id' => $mod_id); + } + + $log_txt = ''; + $update_active = $remote->get_log(OGP_SCREEN_TYPE_UPDATE, $home_id, clean_path($home_info['home_path']), $log_txt); + if ($update_active == 1) { + return array('ok' => true, 'started' => true, 'already_running' => true, 'message' => 'Update already in progress.', 'mod_id' => $mod_id); + } + + $modkey = $home_info['mods'][$mod_id]['mod_key'] ?? ''; + $mod_xml = xml_get_mod($server_xml, $modkey); + if (!$mod_xml) { + return array('ok' => false, 'pending' => true, 'message' => "Mod key '{$modkey}' not found in XML.", 'mod_id' => $mod_id); + } + + $installer_name = isset($mod_xml->installer_name) ? (string)$mod_xml->installer_name : (string)$modkey; + $precmd = $home_info['mods'][$mod_id]['precmd'] == "" + ? ($home_info['mods'][$mod_id]['def_precmd'] == "" ? $server_xml->pre_install : $home_info['mods'][$mod_id]['def_precmd']) + : $home_info['mods'][$mod_id]['precmd']; + $postcmd = $home_info['mods'][$mod_id]['postcmd'] == "" + ? ($home_info['mods'][$mod_id]['def_postcmd'] == "" ? $server_xml->post_install : $home_info['mods'][$mod_id]['def_precmd']) + : $home_info['mods'][$mod_id]['postcmd']; + $exec_folder_path = clean_path($home_info['home_path'] . "/" . $server_xml->exe_location); + $exec_path = clean_path($exec_folder_path . "/" . $server_xml->server_exec_name); + + $master_server_home_id = intval($options['master_server_home_id'] ?? 0); + if ($master_server_home_id > 0) { + if ($db->getMasterServer($home_info['remote_server_id'], $home_info['home_cfg_id']) != $master_server_home_id) { + return array('ok' => false, 'pending' => false, 'message' => 'Attempting update from non-master server.', 'mod_id' => $mod_id); + } + if ($master_server_home_id == $home_id) { + return array('ok' => false, 'pending' => false, 'message' => 'Cannot update from own self.', 'mod_id' => $mod_id); + } + $ms_info = $db->getGameHome($master_server_home_id); + $steam_out = $remote->masterServerUpdate($home_id, $home_info['home_path'], $master_server_home_id, $ms_info['home_path'], $exec_folder_path, $exec_path, $precmd, $postcmd); + if ($steam_out === 0) { + return array('ok' => false, 'pending' => true, 'message' => 'Failed to start master update.', 'mod_id' => $mod_id); + } + return array('ok' => true, 'started' => true, 'message' => 'Update started.', 'mod_id' => $mod_id); + } + + $use_steamcmd = ((string)$server_xml->installer === "steamcmd"); + if ($use_steamcmd && !empty((string)$installer_name)) { + $cfg_os = ''; + if (preg_match("/win32/", $server_xml->game_key) || preg_match("/win64/", $server_xml->game_key)) { + $cfg_os = "windows"; + } elseif (preg_match("/linux/", $server_xml->game_key)) { + $cfg_os = "linux"; + } + + $settings = is_array($options['settings'] ?? null) ? $options['settings'] : $db->getSettings(); + if (!empty($mod_xml->installer_login)) { + $login = (string)$mod_xml->installer_login; + $pass = ''; + } else { + $login = (string)($settings['steam_user'] ?? ''); + $pass = (string)($settings['steam_pass'] ?? ''); + } + + $modname = ($installer_name == '90') ? $modkey : ''; + $betaname = isset($mod_xml->betaname) ? (string)$mod_xml->betaname : ''; + $betapwd = isset($mod_xml->betapwd) ? (string)$mod_xml->betapwd : ''; + $arch = isset($mod_xml->steam_bitness) ? (string)$mod_xml->steam_bitness : ''; + $lockFiles = (isset($server_xml->lock_files) && !empty($server_xml->lock_files)) ? trim((string)$server_xml->lock_files) : ""; + $steam_out = $remote->steam_cmd($home_id, $home_info['home_path'], $installer_name, $modname, + $betaname, $betapwd, $login, $pass, $settings['steam_guard'] ?? '', + $exec_folder_path, $exec_path, $precmd, $postcmd, $cfg_os, $lockFiles, $arch); + if ($steam_out === 0) { + return array('ok' => false, 'pending' => true, 'message' => 'Failed to start SteamCMD update.', 'mod_id' => $mod_id); + } + return array('ok' => true, 'started' => true, 'message' => 'Update started.', 'mod_id' => $mod_id); + } + + $ran_scripts = false; + if (!empty((string)$precmd)) { + $remote->exec((string)$precmd); + $ran_scripts = true; + } + if (!empty((string)$postcmd)) { + $remote->exec((string)$postcmd); + $ran_scripts = true; + } + return array( + 'ok' => true, + 'started' => $ran_scripts, + 'completed' => !$ran_scripts, + 'message' => $ran_scripts ? 'Script install started.' : 'No installer command was required.', + 'mod_id' => $mod_id + ); + } +} + diff --git a/modules/gamemanager/update_server.php b/modules/gamemanager/update_server.php index 53a1382c..799598d7 100644 --- a/modules/gamemanager/update_server.php +++ b/modules/gamemanager/update_server.php @@ -24,6 +24,7 @@ require_once("includes/lib_remote.php"); require_once("modules/config_games/server_config_parser.php"); +require_once("modules/gamemanager/update_actions.php"); function exec_ogp_module() { @@ -90,111 +91,27 @@ function exec_ogp_module() { // Start update. else if ($_GET['update'] == 'update' && $update_active != 1) { - $installer_name = $modkey; - - if ( isset( $mod_xml->installer_name ) ) - { - $installer_name = $mod_xml->installer_name; + $start_result = gamemanager_trigger_update_install( + $db, + $home_info, + intval($mod_id), + array( + 'master_server_home_id' => isset($_REQUEST['master_server_home_id']) ? intval($_REQUEST['master_server_home_id']) : 0, + 'settings' => $db->getSettings(), + ) + ); + $mod_id = intval($start_result['mod_id'] ?? $mod_id); + if (empty($start_result['ok'])) { + print_failure(!empty($start_result['message']) ? $start_result['message'] : get_lang("failed_to_start_steam_update")); + return; } - - $precmd = $home_info['mods'][$mod_id]['precmd'] == "" ? - ( $home_info['mods'][$mod_id]['def_precmd'] == "" ? $server_xml->pre_install : - $home_info['mods'][$mod_id]['def_precmd'] ) : $home_info['mods'][$mod_id]['precmd']; - - $postcmd = $home_info['mods'][$mod_id]['postcmd'] == "" ? - ( $home_info['mods'][$mod_id]['def_postcmd'] == "" ? $server_xml->post_install : - $home_info['mods'][$mod_id]['def_precmd'] ) : $home_info['mods'][$mod_id]['postcmd']; - - $exec_folder_path = clean_path($home_info['home_path'] . "/" . $server_xml->exe_location ); - $exec_path = clean_path($exec_folder_path . "/" . $server_xml->server_exec_name ); - - if( isset( $_REQUEST['master_server_home_id'] ) ) - { - $ms_home_id = $_REQUEST['master_server_home_id']; - - if ($db->getMasterServer($home_info['remote_server_id'], $home_info['home_cfg_id']) == $ms_home_id) { - if ($ms_home_id !== $home_id) { - $ms_info = $db->getGameHome($ms_home_id); - $steam_out = $remote->masterServerUpdate( $home_id,$home_info['home_path'],$ms_home_id,$ms_info['home_path'],$exec_folder_path,$exec_path,$precmd,$postcmd ); - } else { - print_failure(get_lang('cannot_update_from_own_self')); - $view->refresh('?m=gamemanager&p=game_monitor', 2); - - return; - } - } else { - $db->logger(get_lang_f('update_attempt_from_nonmaster_server', $_SESSION['users_login'], $home_id, $ms_home_id)); - print_failure(get_lang('attempting_nonmaster_update')); - $view->refresh('?m=gamemanager&p=game_monitor', 2); - - return; - } - - } - elseif ($use_steamcmd && !empty((string)$installer_name)) - { - if( preg_match("/win32/", $server_xml->game_key) OR preg_match("/win64/", $server_xml->game_key) ) - $cfg_os = "windows"; - elseif( preg_match("/linux/", $server_xml->game_key) ) - $cfg_os = "linux"; - - $settings = $db->getSettings(); - - // Some games like L4D2 require anonymous login - if($mod_xml->installer_login){ - $login = $mod_xml->installer_login; - $pass = ''; - }else{ - $login = $settings['steam_user']; - $pass = $settings['steam_pass']; - } - - $modname = ( $installer_name == '90' ) ? $modkey : ''; - $betaname = isset($mod_xml->betaname) ? $mod_xml->betaname : ''; - $betapwd = isset($mod_xml->betapwd) ? $mod_xml->betapwd : ''; - $arch = isset($mod_xml->steam_bitness) ? $mod_xml->steam_bitness : ''; - - // Additional files to lock - if(isset($server_xml->lock_files) && !empty($server_xml->lock_files)){ - $lockFiles = trim($server_xml->lock_files); - }else{ - $lockFiles = ""; - } - - $steam_out = $remote->steam_cmd( $home_id,$home_info['home_path'],$installer_name,$modname, - $betaname,$betapwd,$login,$pass,$settings['steam_guard'], - $exec_folder_path,$exec_path,$precmd,$postcmd,$cfg_os,$lockFiles,$arch); - } - else - { - // No SteamCMD installer — run pre/post install scripts only. - $ran_scripts = false; - if (!empty((string)$precmd)) { - $remote->exec((string)$precmd); - $ran_scripts = true; - } - if (!empty((string)$postcmd)) { - $remote->exec((string)$postcmd); - $ran_scripts = true; - } - if ($ran_scripts) { - print_success( get_lang("update_started") ); - } else { - print_success( get_lang("update_completed") ); - } + if (!empty($start_result['started'])) { + print_success(get_lang("update_started")); + } else { + print_success(get_lang("update_completed")); $view->refresh("?m=gamemanager&p=game_monitor&home_id=$home_id", 3); return; } - - if( $steam_out === 0 ) - { - print_failure( get_lang("failed_to_start_steam_update") ); - return; - } - else if ( $steam_out === 1 ) - { - print_success( get_lang("update_started") ); - } } // Refresh update page. else diff --git a/modules/litefm/fm_dir.php b/modules/litefm/fm_dir.php index 1f623ab6..d2862bb6 100644 --- a/modules/litefm/fm_dir.php +++ b/modules/litefm/fm_dir.php @@ -64,16 +64,30 @@ function exec_ogp_module() // We must always add the home directory to the fm_cwd so that user // can not go out of the homedir. - $path = clean_path($home_cfg['home_path']."/".@$_SESSION['fm_cwd_'.$home_id]); + $cwd_session_key = 'fm_cwd_' . $home_id; + if (!isset($_SESSION[$cwd_session_key]) || !is_string($_SESSION[$cwd_session_key])) { + $_SESSION[$cwd_session_key] = ''; + } + $path = clean_path($home_cfg['home_path']."/".$_SESSION[$cwd_session_key]); if (!$remote->rfile_exists($path)) { while(!$remote->rfile_exists($path)) { - $_SESSION['fm_cwd_'.$home_id] = dirname($_SESSION['fm_cwd_'.$home_id]); - $path = clean_path($home_cfg['home_path']."/".@$_SESSION['fm_cwd_'.$home_id]); + $current_cwd = isset($_SESSION[$cwd_session_key]) ? (string)$_SESSION[$cwd_session_key] : ''; + if ($current_cwd === '' || $current_cwd === '.' || $current_cwd === DIRECTORY_SEPARATOR) { + print_failure("Server files have not been installed yet."); + echo "
    << ".get_lang('back')."
    "; + return; + } + $parent_cwd = dirname($current_cwd); + if (!is_string($parent_cwd) || $parent_cwd === '.' || $parent_cwd === DIRECTORY_SEPARATOR) { + $parent_cwd = ''; + } + $_SESSION[$cwd_session_key] = $parent_cwd; + $path = clean_path($home_cfg['home_path']."/".$_SESSION[$cwd_session_key]); if($path == clean_path($home_cfg['home_path']."/")) { - print_failure(get_lang_f("dir_not_found",$path)); + print_failure("Server files have not been installed yet."); echo "
    << ".get_lang('back')."
    "; return; } @@ -214,7 +228,7 @@ function exec_ogp_module() { $remote->shell_action('remove_recursive', $files); $files = str_replace('" "','"
    "',$files); - $db->logger( get_lang("remove") . ": ${files}" ); + $db->logger( get_lang("remove") . ": {$files}" ); } } } @@ -349,7 +363,7 @@ function exec_ogp_module() if($items != '') { $retval = $remote->compress_files($items,$path,$archive_name,$archive_type); - $archive = clean_path( "${path}/${archive_name}.${archive_type}" ); + $archive = clean_path( "{$path}/{$archive_name}.{$archive_type}" ); if( $retval == 0 ) { do{