Commit f3747995 authored by Nemo Ma's avatar Nemo Ma

fix: retire dead bots and support probabilistic respawn

parent e5c2446b
<?php
define('CURSCRIPT', 'revbotservice');
include './include/common.inc.php';
include GAME_ROOT . './include/game.func.php';
include GAME_ROOT . './bot/revbot.func.php';
$gameRoot = dirname(__DIR__).DIRECTORY_SEPARATOR;
if(is_dir($gameRoot)) {
chdir($gameRoot);
}
require_once $gameRoot.'include/common.inc.php';
require_once GAME_ROOT.'./include/game.func.php';
require_once GAME_ROOT.'./bot/revbot.func.php';
$bot_respawn_chance = isset($_GET['respawn_chance']) ? (int)$_GET['respawn_chance'] : 35;
if($bot_respawn_chance < 0) $bot_respawn_chance = 0;
if($bot_respawn_chance > 100) $bot_respawn_chance = 100;
# 注意:因为进程锁的存在,运行bot脚本时必须确保游戏处于未开始状态
# 否则请先中止游戏,并手动清空lock目录下所有文件,然后确保游戏正处于未开始状态下运行脚本
......@@ -11,6 +22,9 @@ include GAME_ROOT . './bot/revbot.func.php';
bot_prepare_flag:
$id = 0;
$dir = GAME_ROOT.'./bot/lock/';
if(!is_dir($dir)) {
mkdir($dir, 0777, true);
}
$scdir = scandir($dir);
# 为进程创建对应编号的进程锁
$process_id = $scdir ? count($scdir)+1 : 1;
......@@ -67,18 +81,33 @@ while($id)
{
$flag = bot_acts($id);
if ($flag == 0) {
unset($gamevars['botid'][array_search($botid, $gamevars['botid'])]);
$index = array_search($id, $gamevars['botid']);
if($index !== false) unset($gamevars['botid'][$index]);
$roll = mt_rand(1,100);
if($gamestate > 10 && $bot_respawn_chance > 0 && $roll <= $bot_respawn_chance) {
$gamevars['botplayer'] = isset($gamevars['botplayer']) ? (int)$gamevars['botplayer'] + 1 : 1;
echo "BOT:{$id} 已死亡;已加入重生队列。roll={$roll}, chance={$bot_respawn_chance}\n";
} else {
echo "BOT:{$id} 已死亡;不加入重生队列。roll={$roll}, chance={$bot_respawn_chance}\n";
}
save_gameinfo();
save_combatinfo();
if (empty($gamevars['botid'])) break;
ob_end_flush();
break;
}
echo "\nBOT:{$id} 行动完成\n";
ob_end_flush();
}
else
{
echo "BOT:{$id} 不在活动队列,进程退出。\n";
ob_end_flush();
break;
}
sleep(1);
}
else
{
goto bot_prepare_flag;
}
}
\ No newline at end of file
}
# bothost
独立于 PHPDTS 本体的 BOT 宿主程序。它运行在服务器 A,通过 HTTP 长连接托管多个目标 PHPDTS 站点的 `bot/revbotservice.php` 进程。
## 设计要点
- **不改 PHPDTS 主体代码**:只新增 `bothost/`
- **不依赖目标机 shell**:不需要在目标机执行 `bot_enable.sh`
- **多站点**:一个 bothost 可同时接入多个 PHPDTS 站点。
- **多 bot 并发**:每个站点可设多个 worker(等价多 BOT 守护连接)。
- **自动恢复**:连接中断/超时会自动重连。
## 使用方式
1. 准备配置:
```bash
cp bothost/config.example.json bothost/config.json
# 修改 bothost/config.json
```
2. 启动:
```bash
python bothost/main.py -c bothost/config.json
```
3. 停止:
- `Ctrl+C`,或发送 `SIGTERM`
## 配置说明
- `report_interval_sec`:状态汇总打印间隔。
- `targets[]`:目标站点列表。
- `name`:站点名。
- `revbotservice_url`:目标站点的 `.../bot/revbotservice.php` 完整 URL。
- `workers`:并发 worker 数(通常对应可并发 bot 初始化/行动进程数)。
- `connect_timeout_sec`:连接超时。
- `read_timeout_sec`:读取超时,超时会断开并重连。
- `restart_delay_sec`:重连等待秒数。
- `disable_env_proxy`:是否禁用环境变量中的 HTTP/HTTPS 代理(默认 true,建议保持)。
- `insecure_skip_tls_verify`:是否跳过 TLS 证书校验(默认 false,仅测试环境临时使用)。
- `headers`:额外请求头。
- `query`:附加查询参数。可加入 `respawn_chance`(0-100)控制 BOT 死亡后的随机补位概率。
## 注意事项
1. `revbotservice.php` 是长生命周期脚本,受目标 PHP 运行时参数影响(如 `max_execution_time`)。
2. 若目标前置代理(Nginx/CDN)对长连接有限制,需要放宽超时。
3. bothost 仅负责远程托管与状态监测;BOT 行为逻辑仍由 PHPDTS 原生 `revbot` 代码执行。
## 故障诊断
- 状态中 `err` 持续增长时,查看汇总下方 `last_error`,可直接看到最近一次 HTTP/网络错误详情。
- 若出现类似 `Tunnel connection failed: 403 Forbidden`,通常是环境代理劫持导致,请确认 `disable_env_proxy=true`
- 若出现证书错误,可先确认站点证书链;仅在临时测试中可设 `insecure_skip_tls_verify=true`
-`last_error` 中包含 `include(...common.inc.php): failed to open stream` 等报错,通常是目标站 `bot/revbotservice.php` 在 Web 环境下工作目录不正确;本仓库已修复为基于脚本目录计算 GAME_ROOT。
- 当目标端输出“已死亡;已加入重生队列 / 不加入重生队列”时,bothost 会将该 worker 标记为 `bot_dead_queued` / `bot_dead_retired`,并等待连接退出后自动重连。
# bothost 任务量化清单
> 目标:在**不修改 PHPDTS 主体代码**的前提下,在独立目录 `bothost/` 内实现可部署在服务器 A 的远程 BOT 守护方案。
## 任务点(量化)
1. **需求拆分与边界确认(1 点)**
- 明确方案仅新增 `bothost/`,不改动仓库其他目录。
- 确认通过 HTTP 直接拉起 `bot/revbotservice.php`,避免依赖目标机 shell 脚本。
2. **配置模型设计(2 点)**
- 支持多目标服务器(`targets[]`)。
- 每个目标支持 BOT 并发数(`workers`)与网络超时、重连、请求头等参数。
3. **远程拉起与守护(3 点)**
- 每个 worker 长连接到目标 `revbotservice.php`
- 连接断开、超时、异常后自动重连。
- 支持信号退出(SIGINT/SIGTERM)并停止所有 worker。
4. **状态检测与生命周期管理(3 点)**
- 解析输出中的“当前游戏状态/BOT 初始化/行动完成/等待中”等关键行。
- 维护每个 worker 的状态:连接态、重启次数、错误次数、最近输出。
- 周期打印汇总,便于实时观测 bot 存活与游戏状态。
5. **可用性交付(2 点)**
- 提供 `config.example.json`
- 提供运行文档(启动/停止/部署建议/限制说明)。
总计:**11 个任务点**
## 关于“是否改动 PHPDTS 主体代码”
本实现**没有**改动 PHPDTS 主体(仓库根目录既有逻辑)。
说明:
- 通过复用已存在的 `bot/revbotservice.php` 机制实现远程触发与守护,不需要新增 PHP 接口。
- 若目标站点限制直接访问 `bot/revbotservice.php`(如 WAF、鉴权、执行时长限制),才需要在目标环境做运维层调整(非本仓库代码变更)。
{
"report_interval_sec": 15,
"targets": [
{
"name": "demo-server",
"revbotservice_url": "https://example.com/path/to/phpdts/bot/revbotservice.php",
"workers": 2,
"connect_timeout_sec": 10,
"read_timeout_sec": 30,
"restart_delay_sec": 2,
"disable_env_proxy": true,
"insecure_skip_tls_verify": false,
"headers": {
"User-Agent": "bothost/0.3"
},
"query": {
"respawn_chance": "35"
}
}
]
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment