修复4个问题: 用户组购买确认弹窗、在线曲线清理、高频出售缓冲、每小时活跃数据

This commit is contained in:
ypsdf1
2026-07-20 13:18:58 +08:00
parent 312f40c94a
commit c3d9c0925d
7 changed files with 392 additions and 31 deletions
+46
View File
@@ -1433,6 +1433,13 @@ function syncOnlinePlayers() {
$db->exec('PRAGMA busy_timeout=10000');
$db->exec("CREATE TABLE IF NOT EXISTS online_players (player_name TEXT PRIMARY KEY, login_time INTEGER NOT NULL)");
$db->exec("CREATE TABLE IF NOT EXISTS online_player_hb (id INTEGER PRIMARY KEY DEFAULT 1, last_seen INTEGER DEFAULT 0)");
// ★ 每小时活跃玩家表:记录本小时内所有曾上线的玩家(离线不清空,跨小时清理)
$db->exec("CREATE TABLE IF NOT EXISTS hourly_active_players (
player_name TEXT PRIMARY KEY,
first_seen INTEGER NOT NULL,
last_seen INTEGER NOT NULL,
hour_key TEXT NOT NULL
)");
// ★ 迁移:修复旧表结构(旧行无主键导致INSERT OR REPLACE失效)
try {
$colCheck = $db->query("PRAGMA table_info(online_player_hb)");
@@ -1510,6 +1517,25 @@ function syncOnlinePlayers() {
@error_log("[syncOnlinePlayers] FAIL insert $name: " . $e->getMessage());
}
// ★ 每小时活跃玩家追踪:记录曾上线的玩家(离线不清空,跨小时清理)
try {
$hourKey = date('Y-m-d H', $now);
$haStmt = $db->prepare("INSERT INTO hourly_active_players (player_name, first_seen, last_seen, hour_key)
VALUES (:name, :now, :now, :hk)
ON CONFLICT(player_name) DO UPDATE SET
last_seen = :now2,
hour_key = CASE WHEN excluded.hour_key > hourly_active_players.hour_key THEN excluded.hour_key ELSE hourly_active_players.hour_key END,
first_seen = CASE WHEN excluded.hour_key > hourly_active_players.hour_key THEN :now3 ELSE hourly_active_players.first_seen END");
$haStmt->bindValue(':name', $name, SQLITE3_TEXT);
$haStmt->bindValue(':now', $now, SQLITE3_INTEGER);
$haStmt->bindValue(':now2', $now, SQLITE3_INTEGER);
$haStmt->bindValue(':now3', $now, SQLITE3_INTEGER);
$haStmt->bindValue(':hk', $hourKey, SQLITE3_TEXT);
$haStmt->execute();
} catch (\Throwable $e) {
@error_log("[syncOnlinePlayers] hourly_active记录失败 {$name}: " . $e->getMessage());
}
// ★ 如果Java推送了IP,同步更新 player_ip_changes(实时IP来源)
$ip = $player['ip'] ?? '';
if (!empty($ip)) {
@@ -1546,6 +1572,26 @@ function syncOnlinePlayers() {
@error_log("[syncOnlinePlayers] heartbeat update error: " . $e->getMessage());
}
// ★ 每小时清理:跨小时时,删除上一个小时不再在线的玩家
try {
$currentHourKey = date('Y-m-d H', $now);
$prevHourKey = date('Y-m-d H', $now - 3600);
// 只在刚进入新小时的前5分钟执行清理(避免每次推送都扫表)
$minuteOfHour = (int)date('i', $now);
if ($minuteOfHour < 5) {
// 删除上一个小时及更早的玩家(他们已不在本小时内)
$delStmt = $db->prepare("DELETE FROM hourly_active_players WHERE hour_key < :hk");
$delStmt->bindValue(':hk', $currentHourKey, SQLITE3_TEXT);
$delStmt->execute();
$deleted = $db->changes();
if ($deleted > 0) {
@error_log("[syncOnlinePlayers] ★ 跨小时清理:删除" . $deleted . "条上一个小时的活跃记录");
}
}
} catch (\Throwable $e) {
@error_log("[syncOnlinePlayers] hourly_active清理失败: " . $e->getMessage());
}
$db->exec("COMMIT");
} catch (\Throwable $e) {
try { $db->exec("ROLLBACK"); } catch (\Throwable $e2) {}