Files
Sdf1_login/freeze.php
T
ypsdf1 ae1ff5ffd8 异地登录检测/账号冻结解冻 + 公共邮件辅助函数
- core.php: 新增smtpSendEmail/queryLoginIpLocation/getBaseUrl/sendLocationAlertEmail
- security_alert.php: 接收Java通知比对IP归属并发送提醒邮件(含冻结/改密链接)
- freeze.php: 验证freeze_token冻结账号并写freeze指令
- sync.php: 冻结账号禁止Web登录; smtpSendEmail上移至core.php统一复用
- reset_password.php: 改密成功后解冻(清frozen+写unfreeze)
2026-07-09 17:09:35 +08:00

105 lines
4.1 KiB
PHP

<?php
/**
* 账号冻结页面(玩家从「异地登录提醒」邮件点击进入)
* 验证 freeze_token → 标记账号冻结(frozen=1) → 写入 web_admin_changes(freeze)
* 由 Java 插件 pollAdminChanges 拉取后执行 Bukkit 原生封禁。
* 解冻需在 reset_password.php 修改密码后由 PHP 写 web_admin_changes(unfreeze)。
*/
require_once __DIR__ . '/core.php';
$token = $_GET['token'] ?? '';
$error = '';
$success = false;
$player = '';
$resetLink = '';
if (!$token) {
die('无效链接');
}
$db = getDB();
$stmt = $db->prepare(
"SELECT player_name, frozen FROM users WHERE freeze_token = :t");
$stmt->bindValue(':t', $token, SQLITE3_TEXT);
$row = $stmt->execute()->fetchArray(SQLITE3_ASSOC);
if (!$row) {
die('链接无效或已使用');
}
$player = $row['player_name'];
if ($row['frozen'] == 1) {
// 已冻结,直接展示已冻结页
$success = true;
} else {
// 执行冻结
$db->exec("UPDATE users SET frozen = 1, freeze_token = '' WHERE player_name = "
. SQLite3::escapeString($player));
// 通知 Java 插件封禁该玩家(Bukkit 原生 ban)
$now = time();
$stmt2 = $db->prepare(
"INSERT INTO web_admin_changes
(change_type, target_id, target_name, change_data, created_at)
VALUES ('freeze', 0, :name, '{}', :now)");
$stmt2->bindValue(':name', $player, SQLITE3_TEXT);
$stmt2->bindValue(':now', $now, SQLITE3_INTEGER);
$stmt2->execute();
$success = true;
}
// 取一个有效改密 token 构造「去改密」链接
$stmt3 = $db->prepare(
"SELECT token FROM password_reset_tokens
WHERE player_name = :name AND expire_at > :now
ORDER BY expire_at DESC LIMIT 1");
$stmt3->bindValue(':name', $player, SQLITE3_TEXT);
$stmt3->bindValue(':now', time(), SQLITE3_INTEGER);
$r3 = $stmt3->execute()->fetchArray(SQLITE3_ASSOC);
if ($r3) {
$resetLink = getBaseUrl() . '/reset_password.php?token=' . $r3['token'];
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>账号已冻结 - Sdf1 Minecraft</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: 'Segoe UI', Tahoma, sans-serif;
background: linear-gradient(135deg, #2c3e50 0%, #4b6584 100%);
min-height: 100vh; display: flex; align-items: center;
justify-content: center; padding: 20px; }
.container { background: white; border-radius: 12px;
box-shadow: 0 10px 40px rgba(0,0,0,0.3);
max-width: 440px; width: 100%; padding: 40px; text-align: center; }
h1 { color: #e0533d; font-size: 26px; margin-bottom: 16px; }
.player { background: #f5f5f5; border-radius: 8px; padding: 14px;
margin: 20px 0; font-size: 18px; }
.player strong { color: #e0533d; }
.tip { color: #666; font-size: 14px; line-height: 1.7; margin: 12px 0; }
.btn { display: inline-block; width: 100%; padding: 14px;
background: linear-gradient(135deg, #e0533d, #c0392b);
color: white; border: none; border-radius: 8px;
font-size: 16px; font-weight: 600; text-decoration: none;
transition: transform 0.2s; }
.btn:hover { transform: translateY(-2px); }
</style>
</head>
<body>
<div class="container">
<h1>✅ 账号已冻结</h1>
<p class="tip">为防范账号被盗用,玩家 <b><?php echo htmlspecialchars($player); ?></b> 的账号已被临时冻结。</p>
<div class="player">玩家:<strong><?php echo htmlspecialchars($player); ?></strong></div>
<p class="tip">冻结期间将无法进入游戏。如需解冻,请<b>修改密码</b>,系统将自动解除冻结。</p>
<?php if ($resetLink): ?>
<a class="btn" href="<?php echo htmlspecialchars($resetLink); ?>">前往修改密码并解冻</a>
<?php else: ?>
<p class="tip">未找到有效的改密链接,请返回异地登录提醒邮件点击「修改密码」。</p>
<?php endif; ?>
</div>
</body>
</html>