第十九批:封禁公示按播报起点过滤(web_player_bans补created_time列并随推送入库、web_ban_board_cfg存ban_cutoff、查询加created_time>=起点) + 登录页人机验证组件300px按容器宽等比缩放对齐防溢出
This commit is contained in:
+33
-2
@@ -5416,9 +5416,20 @@ function getBanBoard() {
|
||||
// 若路由到的那侧根本没有这张表(个别站点库未切分/表在另一侧)→ 显式换侧再查一次。
|
||||
// 仅公示名字封禁(ban_type='name'),IP 封禁不公开(IP 属敏感信息)
|
||||
$now = time();
|
||||
// ★ 第十九批:只公示「播报起点」之后创建的封禁 —— 与游戏内播报同源(Java推送时下发),
|
||||
// 插件上服务器之前的历史封禁不上公示;起点未下发(0)时不过滤,行为与旧版一致。
|
||||
try { $db->exec("ALTER TABLE web_player_bans ADD COLUMN created_time INTEGER DEFAULT 0"); } catch (Throwable $e) {}
|
||||
$cutoff = 0;
|
||||
try {
|
||||
$cr = $db->query("SELECT start_cutoff FROM web_ban_board_cfg WHERE id = 1");
|
||||
if ($cr) {
|
||||
$crow = $cr->fetchArray(SQLITE3_ASSOC);
|
||||
if ($crow) $cutoff = (int) ($crow['start_cutoff'] ?? 0);
|
||||
}
|
||||
} catch (Throwable $e) { $cutoff = 0; }
|
||||
$sql = "SELECT target, ban_type, reason, expire_time, synced_at
|
||||
FROM web_player_bans
|
||||
WHERE ban_type = 'name'
|
||||
WHERE ban_type = 'name' AND created_time >= " . $cutoff . "
|
||||
ORDER BY synced_at DESC
|
||||
LIMIT " . $limit;
|
||||
|
||||
@@ -5483,8 +5494,12 @@ function syncBans() {
|
||||
source TEXT DEFAULT '',
|
||||
expire_time INTEGER DEFAULT 0,
|
||||
synced_at INTEGER DEFAULT 0,
|
||||
created_time INTEGER DEFAULT 0,
|
||||
PRIMARY KEY (target, ban_type)
|
||||
)");
|
||||
// ★ 第十九批:老库补列(CREATE TABLE IF NOT EXISTS 不会给老表补列)——
|
||||
// created_time = 封禁创建时间(毫秒),公示按它过滤插件上架前的历史封禁
|
||||
try { $db->exec("ALTER TABLE web_player_bans ADD COLUMN created_time INTEGER DEFAULT 0"); } catch (Throwable $e) {}
|
||||
|
||||
$now = time();
|
||||
// ★ 第十六批:保留旧 synced_at 作为「首见时间」,供封禁公示按时间从近到远排序
|
||||
@@ -5498,7 +5513,7 @@ function syncBans() {
|
||||
}
|
||||
// 先清空旧数据再全量写入
|
||||
$db->exec("DELETE FROM web_player_bans");
|
||||
$stmt = $db->prepare("INSERT OR REPLACE INTO web_player_bans (target, ban_type, reason, source, expire_time, synced_at) VALUES (:target, :type, :reason, :source, :expire, :now)");
|
||||
$stmt = $db->prepare("INSERT OR REPLACE INTO web_player_bans (target, ban_type, reason, source, expire_time, synced_at, created_time) VALUES (:target, :type, :reason, :source, :expire, :now, :created)");
|
||||
foreach ($bans as $ban) {
|
||||
if (empty($ban['target'])) continue;
|
||||
$stmt->bindValue(':target', $ban['target'], SQLITE3_TEXT);
|
||||
@@ -5506,6 +5521,7 @@ function syncBans() {
|
||||
$stmt->bindValue(':reason', $ban['reason'] ?? '', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':source', $ban['source'] ?? '', SQLITE3_TEXT);
|
||||
$stmt->bindValue(':expire', (int)($ban['expire'] ?? 0), SQLITE3_INTEGER);
|
||||
$stmt->bindValue(':created', (int)($ban['created'] ?? 0), SQLITE3_INTEGER);
|
||||
$fk = $ban['target'] . "\x1f" . ($ban['type'] ?? 'name');
|
||||
$stmt->bindValue(':now', (isset($firstSeen[$fk]) && $firstSeen[$fk] > 0) ? $firstSeen[$fk] : $now, SQLITE3_INTEGER);
|
||||
$stmt->execute();
|
||||
@@ -5522,6 +5538,21 @@ function syncBans() {
|
||||
}
|
||||
}
|
||||
|
||||
// ★ 第十九批:接收 Java 端「播报起点」(与游戏内封禁播报同源),
|
||||
// get_ban_board 用它过滤插件上服务器之前的历史封禁;Java 没传/传0 = 不过滤
|
||||
$cutoffRaw = getParam('ban_cutoff', '');
|
||||
if ($cutoffRaw !== null && $cutoffRaw !== '') {
|
||||
$cutoff = (int) $cutoffRaw;
|
||||
if ($cutoff < 0) $cutoff = 0;
|
||||
try {
|
||||
$db->exec("CREATE TABLE IF NOT EXISTS web_ban_board_cfg (id INTEGER PRIMARY KEY, start_cutoff INTEGER DEFAULT 0, updated_at INTEGER DEFAULT 0)");
|
||||
$cst = $db->prepare("INSERT OR REPLACE INTO web_ban_board_cfg (id, start_cutoff, updated_at) VALUES (1, :c, :t)");
|
||||
$cst->bindValue(':c', $cutoff, SQLITE3_INTEGER);
|
||||
$cst->bindValue(':t', $now, SQLITE3_INTEGER);
|
||||
$cst->execute();
|
||||
} catch (Throwable $e) {}
|
||||
}
|
||||
|
||||
success(['count' => count($bans), 'ip_blacklist' => $ipCount]);
|
||||
}
|
||||
|
||||
|
||||
@@ -343,6 +343,7 @@ function cgWidgetHtml() {
|
||||
.cg-badge.bad{background:#da3633;color:#fff}
|
||||
.cg-badge.warn{background:#9e6a03;color:#fff}
|
||||
.cg-err{display:none;margin-top:8px;font-size:12.5px;color:#f85149}
|
||||
#cgCfBox{width:100%}
|
||||
.cg-btn{width:100%;padding:11px 14px;font-size:14px;font-weight:600;border:none;border-radius:6px;
|
||||
background:#21262d;color:#e6edf3;cursor:not-allowed}
|
||||
.cg-btn:enabled{background:#238636;color:#fff;cursor:pointer}
|
||||
@@ -375,6 +376,19 @@ function cgWidgetHtml() {
|
||||
function loadScript(src,ok,failFn){var s=document.createElement('script');s.src=src;s.async=true;
|
||||
s.onload=ok;s.onerror=failFn;document.head.appendChild(s);}
|
||||
|
||||
// ★ 第十九批:Turnstile 挂件固定 300px 宽,容器(如管理后台登录卡)比它窄时右侧溢出边框 ——
|
||||
// 按容器宽度整体等比缩放(原点左上),视觉与 .cg-box 边框对齐;容器够宽则还原不缩放
|
||||
function fitCf(){
|
||||
var box=el('cgCfBox'); if(!box) return;
|
||||
var w=box.clientWidth||0;
|
||||
if(!w) return;
|
||||
if(w>=300){ box.style.transform=''; box.style.marginBottom=''; return; }
|
||||
var s=w/300;
|
||||
box.style.transformOrigin='top left';
|
||||
box.style.transform='scale('+s+')';
|
||||
box.style.marginBottom=(65*s-65)+'px';
|
||||
}
|
||||
|
||||
function initCf(){
|
||||
el('cgCfBox').style.display='block';
|
||||
// ★ 关键:本页必须自己拉起 Turnstile SDK(测试页是 <script src> 引的,本挂件漏了)
|
||||
@@ -401,6 +415,10 @@ function cgWidgetHtml() {
|
||||
'error-callback': function(m){ fail('验证错误: '+m); },
|
||||
'expired-callback': function(){ st.tok=''; put(); badge('已过期,请重新勾选','warn'); }
|
||||
});
|
||||
// widget 的 iframe 是异步插入的,分几次校准(含低网速兜底)
|
||||
setTimeout(fitCf, 400);
|
||||
setTimeout(fitCf, 1500);
|
||||
setTimeout(fitCf, 4000);
|
||||
}catch(ex){ fail('render 异常: '+ex.message); }
|
||||
})();
|
||||
}
|
||||
@@ -464,6 +482,7 @@ function cgWidgetHtml() {
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('resize', fitCf);
|
||||
if (P === 'cf') initCf(); else initVa();
|
||||
})();
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user