From 1d04e2a4e84f34507fba27172255c1343cea11fc Mon Sep 17 00:00:00 2001 From: iaretechnician Date: Wed, 10 Jun 2026 18:37:40 -0400 Subject: [PATCH] fixed server_stopped file check --- OGP64/OGP/ogp_agent.pl | 65 ++++++++++++++------------------------ docs/PROCESS_MANAGEMENT.md | 15 +++++---- 2 files changed, 32 insertions(+), 48 deletions(-) diff --git a/OGP64/OGP/ogp_agent.pl b/OGP64/OGP/ogp_agent.pl index 99e7d87d..03e49e60 100644 --- a/OGP64/OGP/ogp_agent.pl +++ b/OGP64/OGP/ogp_agent.pl @@ -502,7 +502,7 @@ sub create_screen_cmd sub create_screen_cmd_loop { - my ($screen_id, $exec_cmd, $priority, $affinity, $envVars) = @_; + my ($screen_id, $exec_cmd, $priority, $affinity, $envVars, $status_hint_file) = @_; my $server_start_batfile = "_serverStart.bat"; $exec_cmd = replace_OGP_Env_Vars($screen_id, "", "", $exec_cmd); @@ -517,6 +517,7 @@ sub create_screen_cmd_loop if(defined $envVars && $envVars ne ""){ $batch_server_command .= $envVars; }# lines 500-515, inside sub create_screen_cmd_loop + $status_hint_file = "" unless(defined($status_hint_file)); $batch_server_command .= "set STARTTIME=%TIME: =0%" . "\r\n" . "\@echo off\r\n" . "if exist \"_alsoRun.bat\" call \"_alsoRun.bat\"\r\n" @@ -529,7 +530,7 @@ $batch_server_command .= "set STARTTIME=%TIME: =0%" . "\r\n" . "set hour=%hh:~1%\r\n" . "set minute=%mm:~1%\r\n" . "set second=%ss:~1%\r\n" - . "if exist SERVER_STOPPED exit\r\n" + . "if exist \"$status_hint_file\" findstr /I /R /C:\"^[0-9][0-9]*,STOPPING$\" /C:\"^[0-9][0-9]*,STOPPED$\" \"$status_hint_file\" >nul && exit\r\n" . "IF \"%hour%\" == \"00\" IF \"%minute%\" == \"00\" IF %second% lss 60 exit\r\n" . "timeout /t 30 /nobreak >nul\r\n" . "goto TOP\r\n"; @@ -1052,9 +1053,8 @@ sub server_status_without_decrypt if(!$process_running && ((!PORT_VALIDATION_ENABLED && $game_port_listening) || ($expected_count > 0 && $listening_count > 0))) { - $status = "ONLINE"; - $ready = 1; - $status_state = $missing_count == 0 ? "Running" : "Warning"; + $status = "WARNING"; + $status_state = "Warning"; $last_error = "Required port is listening but the managed screen session is not running."; } elsif($process_running) @@ -1081,7 +1081,7 @@ sub server_status_without_decrypt elsif($effective_hint eq "STOPPING") { $status = "STOPPING"; - $status_state = "Starting"; + $status_state = "Stopping"; } elsif($hint_timestamp > 0 && (time() - $hint_timestamp) > $startup_timeout) { @@ -1127,6 +1127,7 @@ sub server_status_without_decrypt pid => $game_pid ne "" ? $game_pid : ($windows_pid ne "" ? $windows_pid : $screen_pid), screen_pid => $screen_pid, windows_pid => $windows_pid, + linux_pid => "", session_name => $screen_id, ip => $server_ip, port => $server_port, @@ -1137,17 +1138,6 @@ sub server_status_without_decrypt }; } -# Delete Server Stopped Status File: -sub deleteStoppedStatFile -{ - my ($home_path) = @_; - my $server_stop_status_file = Path::Class::File->new($home_path, "SERVER_STOPPED"); - if(-e $server_stop_status_file) - { - unlink $server_stop_status_file; - } -} - # Universal startup function sub universal_start { @@ -1223,6 +1213,9 @@ sub universal_start_without_decrypt } my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id); + my $status_hint_file = get_status_hint_path($home_id); + my $status_hint_file_windows = clean(`cygpath -wa $status_hint_file`); + chomp($status_hint_file_windows); # Replace any OGP variables $startup_cmd = replace_OGP_Env_Vars($screen_id, $home_id, $home_path, $startup_cmd, $game_key); @@ -1288,8 +1281,7 @@ sub universal_start_without_decrypt if($file_extension eq ".jar") { if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){ - deleteStoppedStatFile($home_path); - $cli_bin = create_screen_cmd_loop($screen_id, "$startup_cmd", $priority, $affinity); + $cli_bin = create_screen_cmd_loop($screen_id, "$startup_cmd", $priority, $affinity, undef, $status_hint_file_windows); }else{ $cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT $startup_cmd"); } @@ -1300,8 +1292,7 @@ sub universal_start_without_decrypt # but it can be a good way to improve the server startup. To be able to use # sh/bash scripts as server executable I added this piece to the agent: if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){ - deleteStoppedStatFile($home_path); - $cli_bin = create_screen_cmd_loop($screen_id, "bash $game_binary_dir/$server_exe $startup_cmd", $priority, $affinity); + $cli_bin = create_screen_cmd_loop($screen_id, "bash $game_binary_dir/$server_exe $startup_cmd", $priority, $affinity, undef, $status_hint_file_windows); }else{ $cli_bin = create_screen_cmd($screen_id, "cmd /Q /C start $priority $affinity /WAIT bash $game_binary_dir/$server_exe $startup_cmd"); } @@ -1309,8 +1300,7 @@ sub universal_start_without_decrypt else { if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){ - deleteStoppedStatFile($home_path); - $cli_bin = create_screen_cmd_loop($screen_id, "$win_game_binary_dir\\$server_exe $startup_cmd", $priority, $affinity); + $cli_bin = create_screen_cmd_loop($screen_id, "$win_game_binary_dir\\$server_exe $startup_cmd", $priority, $affinity, undef, $status_hint_file_windows); }else{ # Below lines should only be used for launching non-auto restart game servers $win_game_binary_dir =~ s/\\/\\\\/g; @@ -1634,21 +1624,6 @@ sub stop_server_without_decrypt or logger "Cannot remove the startup flag file $startup_file $!"; } - # Create file indicator that the game server has been stopped if defined - if(defined($Cfg::Preferences{ogp_autorestart_server}) && $Cfg::Preferences{ogp_autorestart_server} eq "1"){ - - # Get current directory and chdir into the game's home dir - my $curDir = getcwd(); - chdir $home_path; - - # Create stopped indicator file used by autorestart of OGP if server crashes - open(STOPFILE, '>', "SERVER_STOPPED"); - close(STOPFILE); - - # Return to original directory - chdir $curDir; - } - my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id); my $screen_pid = get_screen_pid_without_decrypt($home_id); my $pid_meta = read_pid_metadata($home_id); @@ -1675,15 +1650,16 @@ sub stop_server_without_decrypt system("cmd /C taskkill /F /T /PID $port_pid >nul 2>&1"); } - my $stop_result = verify_server_stopped_without_decrypt($home_id, $server_ip, $server_port); + my $stop_result = verify_runtime_stop_complete_without_decrypt($home_id, $server_ip, $server_port); if($stop_result == 0) { clear_pid_metadata($home_id); + write_status_hint($home_id, "STOPPED"); } return $stop_result; } -sub verify_server_stopped_without_decrypt +sub verify_runtime_stop_complete_without_decrypt { my ($home_id, $server_ip, $server_port) = @_; my $pid_meta = read_pid_metadata($home_id); @@ -1694,7 +1670,11 @@ sub verify_server_stopped_without_decrypt $pid_running = 1 if(defined($pid_meta->{windows_pid}) && $pid_meta->{windows_pid} =~ /^\d+$/ && is_pid_alive_without_decrypt($pid_meta->{windows_pid}) == 1); $pid_running = 1 if(!$pid_running && defined($pid_meta->{game_pid}) && $pid_meta->{game_pid} =~ /^\d+$/ && is_pid_alive_without_decrypt($pid_meta->{game_pid}) == 1); my $port_listening = is_port_listening_without_decrypt($server_ip, $server_port); - return 0 if(!$session_running && !$pid_running && !$port_listening); + if(!$session_running && !$pid_running && !$port_listening) + { + write_status_hint($home_id, "STOPPED"); + return 0; + } sleep 2; } my $screen_id = create_screen_id(SCREEN_TYPE_HOME, $home_id); @@ -1713,6 +1693,7 @@ sub verify_server_stopped_without_decrypt logger "Server $server_ip:$server_port is still running or listening after stop escalation."; return 1; } + write_status_hint($home_id, "STOPPED"); return 0; } @@ -3001,7 +2982,7 @@ sub restart_server_without_decrypt { logger "Waiting 60 seconds before starting the server again."; sleep 60; - if (verify_server_stopped_without_decrypt($home_id, $server_ip, $server_port) != 0) + if (verify_runtime_stop_complete_without_decrypt($home_id, $server_ip, $server_port) != 0) { logger "Restart cancelled: previous instance is still active after stop wait window."; return -2; diff --git a/docs/PROCESS_MANAGEMENT.md b/docs/PROCESS_MANAGEMENT.md index f4e7a344..161681ee 100644 --- a/docs/PROCESS_MANAGEMENT.md +++ b/docs/PROCESS_MANAGEMENT.md @@ -48,12 +48,15 @@ Tracked fields include PID/session information used to stop the right process re When stop is requested, the agent now: 1. marks status hint as `STOPPING` -2. creates `SERVER_STOPPED` marker for autorestart handling -3. removes startup flag for `-` -4. kills tracked PIDs (`screen_pid`, `windows_pid`, `game_pid`) if present -5. kills managed screen session -6. checks if the game port is still listening and kills the owning PID -7. verifies stop success (no managed session, no tracked running PID, no listening game port) +2. removes startup flag for `-` +3. kills tracked PIDs (`screen_pid`, `windows_pid`, `game_pid`) if present +4. kills managed screen session +5. checks if the game port is still listening and kills the owning PID +6. verifies stop success (no managed session, no tracked running PID, no listening game port) +7. writes status hint `STOPPED` only after verification passes + +The agent no longer creates or reads `SERVER_STOPPED`/`Server_Stopped` marker files for lifecycle control. +Autorestart loop control now uses agent-owned runtime status hints (`STARTING`/`STOPPING`/`STOPPED`) instead of game-home marker files. ## Restart behavior