diff --git a/Panel/modules/gamemanager/home_handling_functions.php b/Panel/modules/gamemanager/home_handling_functions.php index 141258b0..5690b13d 100644 --- a/Panel/modules/gamemanager/home_handling_functions.php +++ b/Panel/modules/gamemanager/home_handling_functions.php @@ -78,6 +78,7 @@ function get_agent_server_status($remote, $server_xml, $home_id, $server_ip, $se $fallback_session = gsp_agent_screen_running($remote, $home_id); $fallback_port = gsp_agent_port_listening($remote, $server_port); + $status_name = isset($agent_status['status']) ? strtoupper((string)$agent_status['status']) : 'UNKNOWN'; if ($fallback_session === true) { $agent_status['session_running'] = 1; $agent_status['process_running'] = 1; @@ -85,7 +86,7 @@ function get_agent_server_status($remote, $server_xml, $home_id, $server_ip, $se if ($fallback_port === true) { $agent_status['game_port_listening'] = 1; } - if ($fallback_session === true || $fallback_port === true || !empty($agent_status['session_running']) || !empty($agent_status['process_running']) || !empty($agent_status['game_port_listening'])) { + if (($status_name === 'UNKNOWN' || $status_name === 'OFFLINE') && ($fallback_session === true || $fallback_port === true || !empty($agent_status['session_running']) || !empty($agent_status['process_running']) || !empty($agent_status['game_port_listening']))) { $agent_status['status'] = 'ONLINE'; $agent_status['ready'] = 1; if (empty($agent_status['last_error']) || $agent_status['last_error'] === 'Agent status RPC unavailable.' || $agent_status['last_error'] === 'Panel remote library does not support agent status.') { @@ -94,7 +95,7 @@ function get_agent_server_status($remote, $server_xml, $home_id, $server_ip, $se $agent_status['status_source'] = ($fallback_port === true) ? 'port' : 'session'; return $agent_status; } - if (isset($agent_status['status']) && strtoupper((string)$agent_status['status']) === 'UNKNOWN') { + if ($status_name === 'UNKNOWN') { if ($fallback_session === false && $fallback_port === false) { $agent_status['status'] = 'OFFLINE'; $agent_status['last_error'] = ''; @@ -370,7 +371,7 @@ function exec_operation( $action, $home_id, $mod_id, $ip, $port, $override = fal $agent_status = get_agent_server_status($remote, $server_xml, $home_info['home_id'], $ip, $port); $screen_running = is_agent_status_active($agent_status); - if ( $action == "stop" AND $screen_running ) + if ( $action == "stop" ) { $remote_retval = $remote->remote_stop_server($home_info['home_id'], $ip, $port, $server_xml->control_protocol, @@ -381,8 +382,6 @@ function exec_operation( $action, $home_id, $mod_id, $ip, $port, $override = fal return FALSE; elseif( $remote_retval === -2 ) return FALSE; - elseif( isset($agent_status['status']) && strtoupper($agent_status['status']) !== "OFFLINE" ) - return FALSE; else { $firewall_settings = $db->getFirewallSettings($home_info['remote_server_id']); @@ -416,7 +415,7 @@ function exec_operation( $action, $home_id, $mod_id, $ip, $port, $override = fal return TRUE; } } - elseif ( $action == "restart" AND $screen_running ) + elseif ( $action == "restart" ) { $start_cmd = get_start_cmd($remote,$server_xml,$home_info,$mod_id,$ip,$port,$db); // Do text replacements in cfg file diff --git a/Panel/modules/gamemanager/restart_server.php b/Panel/modules/gamemanager/restart_server.php index b6a6c4d3..0e8bfd3a 100644 --- a/Panel/modules/gamemanager/restart_server.php +++ b/Panel/modules/gamemanager/restart_server.php @@ -124,11 +124,12 @@ function exec_ogp_module() { $retry = 0; else $retry = $_GET['retry']; - - if ($status_name === "UNKNOWN") + + if ($retry < 25 && in_array($status_name, array("UNKNOWN", "STOPPING", "OFFLINE", "STARTING"), true)) { - print_failure(get_lang("agent_offline")); - $view->refresh("?m=gamemanager&p=game_monitor&home_id-mod_id-ip-port=$home_id-$mod_id-$ip-$port",3); + $retry++; + echo "
".htmlentities("Restart waiting 60 seconds. Current status: $status_name")."
"; + $view->refresh("?m=gamemanager&p=restart&refresh&ip=$ip&port=$port&home_id=$home_id&mod_id=$mod_id&retry=".$retry,3); return; } @@ -208,7 +209,8 @@ function exec_ogp_module() { if ( $remote_retval === 1 ) { - print("".get_lang('restarting_server')."
"); + print("".get_lang('restarting_server')."
"); + echo "Restart waiting 60 seconds before start.
"; $view->refresh("?m=gamemanager&p=restart&refresh&ip=$ip&port=$port&home_id=$home_id&mod_id=$mod_id",3); return; } diff --git a/Panel/modules/gamemanager/stop_server.php b/Panel/modules/gamemanager/stop_server.php index 540df966..eded5fa6 100644 --- a/Panel/modules/gamemanager/stop_server.php +++ b/Panel/modules/gamemanager/stop_server.php @@ -103,9 +103,6 @@ function exec_ogp_module() { $ip, $port, $server_xml->control_protocol, $home_info['control_password'],$control_type, $home_path); $agent_status = get_agent_server_status($remote, $server_xml, $home_id, $ip, $port, "STOPPING"); - if ($remote_retval === 1 && isset($agent_status['status']) && strtoupper($agent_status['status']) !== "OFFLINE") { - $remote_retval = -2; - } $db->logger(get_lang_f('server_stopped', $home_info['home_name'] ) . "($ip:$port)"); $firewall_settings = $db->getFirewallSettings($home_info['remote_server_id']); if ( $remote_retval === 1 ) @@ -144,9 +141,6 @@ function exec_ogp_module() { $remote_retval = $remote->remote_stop_server($home_info['home_id'], $ip, $port, $server_xml->control_protocol,"",$control_type,$home_path); $agent_status = get_agent_server_status($remote, $server_xml, $home_id, $ip, $port, "STOPPING"); - if ($remote_retval === 1 && isset($agent_status['status']) && strtoupper($agent_status['status']) !== "OFFLINE") { - $remote_retval = -2; - } if ($remote_retval === 1 ) { print_success(get_lang_f("server_stopped",htmlentities($home_info['home_name']))); @@ -190,6 +184,14 @@ function exec_ogp_module() { $message = isset($agent_status['last_error']) && $agent_status['last_error'] !== "" ? $agent_status['last_error'] : "Remote stop did not verify that the process/session and game port are stopped."; print_failure("Error occurred on the remote host. Agent status: ".htmlentities($status_name).". ".htmlentities($message)); } + else + { + $status_name = isset($agent_status['status']) ? strtoupper($agent_status['status']) : "UNKNOWN"; + if ($status_name !== "OFFLINE" && $status_name !== "STOPPING") + { + echo "Agent stop returned success; current status is ".htmlentities($status_name).". Refreshing monitor for final state.
"; + } + } } $view->refresh("?m=gamemanager&p=game_monitor&home_id-mod_id-ip-port=". $home_id . "-". $mod_id . "-" . $ip . "-" . $port,3); } diff --git a/docs/features/STATUS_SYSTEM.md b/docs/features/STATUS_SYSTEM.md index ecdbe479..54374810 100644 --- a/docs/features/STATUS_SYSTEM.md +++ b/docs/features/STATUS_SYSTEM.md @@ -87,3 +87,14 @@ The Panel fallback does not replace a full agent-owned status model. It exists s - use state hints for start/stop transitions - expose clear messages for `STARTING` and `UNRESPONSIVE` - add precise log excerpts when startup fails + +## Lifecycle action behavior + +Panel gamemanager stop/restart now prioritizes executing lifecycle actions over status-only gating: + +- Stop action always attempts remote stop when requested. +- `UNKNOWN` status or temporary RPC status ambiguity does not block stop execution. +- Restart UI shows explicit wait messaging while agent-enforced restart delay is in progress. +- Restart polling tolerates temporary `UNKNOWN`/`STOPPING`/`OFFLINE` states during the restart window before final start status is confirmed. + +This prevents dead-end failures such as "Agent status RPC unavailable" from blocking user-initiated stop/restart actions.