This commit is contained in:
Frank Harris 2026-06-07 16:04:39 -05:00
parent 5ead40a761
commit 6a15b114e6
23 changed files with 269 additions and 87 deletions

View file

@ -0,0 +1,13 @@
%Cfg::Config = (
logfile => '/OGP/ogp_agent.log',
listen_port => '12679',
listen_ip => '0.0.0.0',
version => 'v1.4',
key => 'CHANGE_ME_PANEL_AGENT_KEY',
steam_license => 'Accept',
sudo_password => '',
web_admin_api_key => '',
web_api_url => '',
steam_dl_limit => '0',
);

View file

@ -0,0 +1,13 @@
%Cfg::Config = (
logfile => '/OGP/ogp_agent.log',
listen_port => '12679',
listen_ip => '0.0.0.0',
version => 'v1.4',
key => 'CHANGE_ME_PANEL_AGENT_KEY',
steam_license => 'Accept',
sudo_password => '',
web_admin_api_key => '',
web_api_url => '',
steam_dl_limit => '0',
);

View file

@ -0,0 +1,9 @@
%Cfg::Preferences = (
screen_log_local => '1',
delete_logs_after => '30',
ogp_manages_ftp => '1',
ftp_method => 'PureFTPd',
ogp_autorestart_server => '1',
protocol_shutdown_waittime => '10',
);

View file

@ -0,0 +1,9 @@
%Cfg::Preferences = (
screen_log_local => '1',
delete_logs_after => '30',
ogp_manages_ftp => '1',
ftp_method => 'PureFTPd',
ogp_autorestart_server => '1',
protocol_shutdown_waittime => '10',
);

View file

@ -0,0 +1,9 @@
agent_auto_update=0
agent_update_repo_url=http://forge.runlevelsystems.com/dev/GSP.git
agent_update_branch=Panel-unstable
agent_update_raw_url=http://forge.runlevelsystems.com/dev/GSP/raw/branch/Panel-unstable/Agent-Windows/OGP64/OGP/ogp_agent.pl
run_pureftpd=0
ftp_port=21
ftp_ip=0.0.0.0
ftp_pasv_range=

View file

@ -0,0 +1,9 @@
agent_auto_update=0
agent_update_repo_url=http://forge.runlevelsystems.com/dev/GSP.git
agent_update_branch=Panel-unstable
agent_update_raw_url=http://forge.runlevelsystems.com/dev/GSP/raw/branch/Panel-unstable/Agent-Windows/OGP64/OGP/ogp_agent.pl
run_pureftpd=0
ftp_port=21
ftp_ip=0.0.0.0
ftp_pasv_range=

View file

@ -7,6 +7,8 @@ PIDFILE="${1:-/OGP/ogp_agent_run.pid}"
PREFS_FILE="$AGENT_DIR/Cfg/bash_prefs.cfg"
REPO_URL_DEFAULT="http://forge.runlevelsystems.com/dev/GSP.git"
REPO_BRANCH_DEFAULT="Panel-unstable"
RAW_AGENT_URL_DEFAULT="http://forge.runlevelsystems.com/dev/GSP/raw/branch/Panel-unstable/Agent-Windows/OGP64/OGP/ogp_agent.pl"
REPO_AGENT_PATH="Agent-Windows/OGP64/OGP/ogp_agent.pl"
warn() {
printf 'WARNING: %s\n' "$*" >&2
@ -26,10 +28,45 @@ normalize_text_files() {
done
}
normalize_bash_preferences() {
[ -f "$PREFS_FILE" ] || return 0
sed -i 's/\r$//' "$PREFS_FILE" 2>/dev/null || warn "Could not normalize CRLF in $PREFS_FILE"
sed -i -E 's/^[[:space:]]+([A-Za-z_][A-Za-z0-9_]*=)/\1/' "$PREFS_FILE" 2>/dev/null || warn "Could not normalize assignments in $PREFS_FILE"
}
install_default_config_if_missing() {
local target="$1"
local template="$2"
if [ -f "$target" ]; then
return 0
fi
if [ ! -f "$template" ]; then
warn "Missing template $template; cannot create $target"
return 0
fi
mkdir -p "$(dirname "$target")" 2>/dev/null || {
warn "Cannot create config directory for $target"
return 0
}
cp "$template" "$target" 2>/dev/null || {
warn "Cannot create default config $target from $template"
return 0
}
sed -i 's/\r$//' "$target" 2>/dev/null || true
}
ensure_default_configs() {
install_default_config_if_missing "$AGENT_DIR/Cfg/Config.pm" "$AGENT_DIR/Cfg/Config.pm.default"
install_default_config_if_missing "$AGENT_DIR/Cfg/Preferences.pm" "$AGENT_DIR/Cfg/Preferences.pm.default"
install_default_config_if_missing "$AGENT_DIR/Cfg/bash_prefs.cfg" "$AGENT_DIR/Cfg/bash_prefs.cfg.default"
normalize_bash_preferences
}
load_agent_preferences() {
agent_auto_update=0
agent_update_repo_url="$REPO_URL_DEFAULT"
agent_update_branch="$REPO_BRANCH_DEFAULT"
agent_update_raw_url="$RAW_AGENT_URL_DEFAULT"
if [ -f "$PREFS_FILE" ]; then
# shellcheck disable=SC1090
@ -39,6 +76,64 @@ load_agent_preferences() {
agent_auto_update="${agent_auto_update:-0}"
agent_update_repo_url="${agent_update_repo_url:-$REPO_URL_DEFAULT}"
agent_update_branch="${agent_update_branch:-$REPO_BRANCH_DEFAULT}"
agent_update_raw_url="${agent_update_raw_url:-$RAW_AGENT_URL_DEFAULT}"
}
validate_agent_file() {
local candidate="$1"
[ -s "$candidate" ] || {
warn "Candidate agent file is empty: $candidate"
return 1
}
if head -5 "$candidate" | grep -Eiq '(<html|<!doctype|not found|404|forbidden|error)'; then
warn "Candidate agent file looks like an HTTP error page or text response: $candidate"
return 1
fi
if ! head -1 "$candidate" | grep -Eq '^#!.*perl'; then
warn "Candidate agent file does not start with a Perl shebang: $candidate"
return 1
fi
if ! grep -q 'use Cfg::Config' "$candidate"; then
warn "Candidate agent file does not look like the GSP/OGP Perl agent: $candidate"
return 1
fi
sed -i 's/\r$//' "$candidate" 2>/dev/null || true
perl -c "$candidate" >/tmp/gsp-agent-perl-check.log 2>&1 || {
warn "Candidate agent failed perl validation:"
cat /tmp/gsp-agent-perl-check.log >&2 2>/dev/null || true
return 1
}
return 0
}
download_agent_with_curl() {
local target="$1"
if ! command -v curl >/dev/null 2>&1; then
return 1
fi
echo "Downloading Windows agent from $agent_update_raw_url..."
curl -fsSL "$agent_update_raw_url" -o "$target"
}
download_agent_with_git() {
local target="$1"
if ! command -v git >/dev/null 2>&1; then
return 1
fi
local repo_dir source_file
repo_dir="$(dirname "$target")/repo"
echo "Checking for Windows agent update from $agent_update_repo_url ($agent_update_branch)..."
if ! git clone --depth 1 --branch "$agent_update_branch" "$agent_update_repo_url" "$repo_dir"; then
return 1
fi
source_file="$repo_dir/$REPO_AGENT_PATH"
if [ ! -f "$source_file" ]; then
warn "Updated Windows agent source was not found at $REPO_AGENT_PATH"
return 1
fi
cp "$source_file" "$target"
}
auto_update_windows_agent() {
@ -47,32 +142,32 @@ auto_update_windows_agent() {
return 0
}
if ! command -v git >/dev/null 2>&1; then
warn "git is not installed; skipping agent auto-update and using the current agent."
return 0
fi
local tmp_dir repo_dir source_file target_file backup_file
local tmp_dir candidate_file target_file backup_file
tmp_dir="$(mktemp -d /tmp/gsp-agent-update.XXXXXX 2>/dev/null)" || {
warn "Could not create temporary update directory; skipping auto-update."
return 0
}
repo_dir="$tmp_dir/repo"
candidate_file="$tmp_dir/ogp_agent.pl"
target_file="$AGENT_DIR/ogp_agent.pl"
backup_file="$AGENT_DIR/ogp_agent.pl.bak.$(date +%Y%m%d%H%M%S)"
echo "Checking for Windows agent update from $agent_update_repo_url ($agent_update_branch)..."
if ! git clone --depth 1 --branch "$agent_update_branch" "$agent_update_repo_url" "$repo_dir"; then
warn "Agent auto-update clone failed; using the current agent."
if ! download_agent_with_curl "$candidate_file"; then
warn "curl download failed or curl is unavailable; trying git fallback."
if ! download_agent_with_git "$candidate_file"; then
warn "Agent auto-update download failed; using the current agent."
rm -rf "$tmp_dir"
return 0
fi
fi
if ! validate_agent_file "$candidate_file"; then
warn "Downloaded Windows agent was rejected; using the current agent."
rm -rf "$tmp_dir"
return 0
fi
source_file="$repo_dir/Agent-Windows/ogp_agent.pl"
if [ ! -f "$source_file" ]; then
warn "Updated Windows agent source was not found at Agent-Windows/ogp_agent.pl; using the current agent."
rm -rf "$tmp_dir"
return 0
if ! validate_agent_file "$target_file"; then
warn "Current Windows agent does not validate. Auto-update can still replace it if backup succeeds."
fi
cp "$target_file" "$backup_file" 2>/dev/null || {
@ -81,18 +176,16 @@ auto_update_windows_agent() {
return 0
}
if ! cp "$source_file" "$target_file"; then
if ! cp "$candidate_file" "$target_file"; then
warn "Could not copy updated Windows agent; restoring backup."
cp "$backup_file" "$target_file" 2>/dev/null
rm -rf "$tmp_dir"
return 0
fi
sed -i 's/\r$//' "$target_file" 2>/dev/null || true
if ! perl -c "$target_file"; then
warn "Updated Windows agent failed perl syntax validation; restoring backup."
if ! validate_agent_file "$target_file"; then
warn "Updated Windows agent failed validation after install; restoring backup."
cp "$backup_file" "$target_file" 2>/dev/null
perl -c "$target_file" || true
rm -rf "$tmp_dir"
return 0
fi
@ -106,11 +199,12 @@ cd "$AGENT_DIR" || fail "Could not enter $AGENT_DIR. Is the Windows agent instal
normalize_text_files "$AGENT_DIR"
normalize_text_files "/Install"
ensure_default_configs
load_agent_preferences
auto_update_windows_agent
echo "Validating $AGENT_DIR/ogp_agent.pl..."
perl -c "$AGENT_DIR/ogp_agent.pl" || fail "Perl syntax/dependency validation failed. Install missing Cygwin Perl packages or restore a valid Windows agent file."
validate_agent_file "$AGENT_DIR/ogp_agent.pl" || fail "Perl syntax/dependency validation failed. Install missing Cygwin Perl packages or restore a valid Windows agent file."
echo "Launching GSP Windows Agent..."
exec perl "$AGENT_DIR/ogp_agent.pl" -pidfile "$PIDFILE"

View file

@ -21,6 +21,21 @@ Cygwin-based agent that lets the GameServer Panel manage Windows Server 2019/202
4. Edit `C:\\OGP\\Cfg\\Config.pm` so it matches the server entry you created in the GameServer Panel.
5. Start the “OGP agent start on boot” scheduled task (or reboot).
## Startup and auto-update
Use `C:\\OGP64\\agent_start.bat` or `C:\\OGP\\Install\\agent_start.bat` to start the agent manually. The launcher detects the bundled Cygwin `bash.exe` first, then falls back to `C:\\cygwin64\\bin\\bash.exe` and `C:\\cygwin\\bin\\bash.exe`.
`C:\\OGP\\Cfg\\bash_prefs.cfg` controls optional restart-time agent updates:
```bash
agent_auto_update=0
agent_update_repo_url=http://forge.runlevelsystems.com/dev/GSP.git
agent_update_branch=Panel-unstable
agent_update_raw_url=http://forge.runlevelsystems.com/dev/GSP/raw/branch/Panel-unstable/Agent-Windows/OGP64/OGP/ogp_agent.pl
```
When `agent_auto_update=1`, the launcher downloads to a temporary file, rejects HTML/404/empty/non-Perl content, validates with `perl -c`, backs up the current `ogp_agent.pl`, and rolls back if validation fails.
## Related repositories
- [GSP](https://github.com/GameServerPanel/GSP) PHP panel that issues commands to the agents.

View file

@ -31,12 +31,28 @@ The Windows agent bundles Cygwin, Perl, GNU Screen, and helper scripts so the Ga
## Updating the agent
Manual update:
1. Stop the scheduled task or kill any running `ogp_agent.pl` processes.
2. Pull the latest files (`git pull` inside `C:\\gsp-agent` or download the release ZIP again).
3. Copy updated files into `C:\\OGP`.
4. Re-run `rebase_post_ins.bat` if new Cygwin DLLs were added.
5. Start the agent task again.
Restart-time auto-update:
1. Edit `/OGP/Cfg/bash_prefs.cfg`.
2. Set `agent_auto_update=1`.
3. Keep the default Forgejo values unless you are testing another branch:
```bash
agent_update_repo_url=http://forge.runlevelsystems.com/dev/GSP.git
agent_update_branch=Panel-unstable
agent_update_raw_url=http://forge.runlevelsystems.com/dev/GSP/raw/branch/Panel-unstable/Agent-Windows/OGP64/OGP/ogp_agent.pl
```
4. Restart the agent with `C:\\OGP64\\agent_start.bat` or `C:\\OGP\\Install\\agent_start.bat`.
The updater downloads to a temporary file, rejects empty files, HTML error pages, `Not found` responses, and files without the expected Perl agent markers, then runs `perl -c` before replacing `/OGP/ogp_agent.pl`. Failed auto-update attempts are non-fatal and continue with the last known good agent.
## Logging & troubleshooting
- Main log: `C:\\OGP\\ogp_agent.log`
@ -44,6 +60,9 @@ The Windows agent bundles Cygwin, Perl, GNU Screen, and helper scripts so the Ga
- Customer servers run inside GNU Screen sessions—attach via `C:\\OGP\\bin\\screen -r ogp_agent`
- Firewall: open TCP 12679 (or your configured port) and any game-specific ports before provisioning.
- Authentication errors almost always mean the `key` in `Cfg/Config.pm` does not match the value stored in the panel → Administration → Servers.
- `/OGP/Cfg/bash_prefs.cfg` must use LF line endings and no leading whitespace before assignments. The launcher normalizes this automatically before sourcing the file.
- `./ogp_agent.pl: line 1: Not: command not found` means the agent file was replaced with text/HTTP error content. Restore a backup or enable auto-update after confirming the Forgejo raw URL above is reachable.
- `The user name could not be found. NET HELPMSG 2221.` came from the legacy root launcher that queried `cyg_server`. Use the maintained launchers above; they do not require that user for manual foreground startup.
## Usage tips

View file

@ -1,41 +1,20 @@
@echo off
@title OGP Agent
FOR /f "tokens=2,3,4 delims=[.]" %%a IN ('ver') DO SET WVer=%%a
FOR /f "tokens=2,3 delims= " %%a IN ('echo %WVer%') DO SET Ver=%%a
whoami /groups | find "S-1-16-12288" >nul 2>&1
if NOT %errorLevel% == 0 if %VER% GEQ 6 (
echo Failure: Current permissions inadequate.
echo[
echo Run this script by using "Run as administrator" in the context menu.
pause >nul
exit
)
set WD=%~dp0
pushd %WD%
set path=%WD%bin;%WD%usr\sbin;%path%
set CYGWIN=server ntsec
set SHELL=/bin/bash
set runAgentNormally=no
REM Stop any running agent
if exist %WD%var\run\pure-ftpd.pid set /p PID1=<%WD%var\run\pure-ftpd.pid
if exist %WD%OGP\ogp_agent.pid set /p PID2=<%WD%OGP\ogp_agent.pid
if exist %WD%OGP\ogp_agent_run.pid set /p PID3=<%WD%OGP\ogp_agent_run.pid
IF NOT [%PID1%] == [] kill -15 %PID1%
IF NOT [%PID2%] == [] kill -15 %PID2%
IF NOT [%PID3%] == [] kill -15 %PID3%
REM Check for cyg_server user and if it exists and the user running this script matches, run it the normal way, else prompt for elevation
if "%username%" == "" set runAgentNormally=yes
if "%username%" == "cyg_server" set runAgentNormally=yes
net user cyg_server
if %ERRORLEVEL% EQU 0 (
if %runAgentNormally% == yes (
bash ogp_agent -pidfile /OGP/ogp_agent_run.pid
) else (
cygstart cmd /c "runas /profile /user:cyg_server \"%WD%\bin\bash.exe %WD%\bin\ogp_agent -pidfile /OGP/ogp_agent_run.pid\""
)
) else (
bash ogp_agent -pidfile /OGP/ogp_agent_run.pid
)
@echo off
setlocal EnableExtensions
title GSP Windows Agent
set "ROOT=%~dp0"
set "INNER_START=%ROOT%OGP\Install\agent_start.bat"
if not exist "%INNER_START%" (
echo Failure: maintained agent launcher was not found.
echo.
echo Expected:
echo %INNER_START%
echo.
echo This checkout should contain OGP\Install\agent_start.bat.
pause
exit /b 1
)
call "%INNER_START%"
exit /b %ERRORLEVEL%