Files
Sdf1_login/txt/ConfigManager.txt
T

452 lines
18 KiB
Plaintext

package Sdf1_login;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;
import static java.lang.Double.parseDouble;
public class ConfigManager {
private final File dataFolder;
private final Map<String, String> messages = new LinkedHashMap<>();
private final Map<String, String> smtpSettings = new LinkedHashMap<>();
public String adminTag = "admin";
public String adminPassword = "qweasd";
public int maxAccountsPerIP = 3;
public String approvalMode = "manual";
public int autoApproveDelayMinutes = 30;
public int loginTimeout = 60;
public boolean afkEnabled = false;
public int afkTimeout = 300;
public boolean smtpSsl = true;
public String smtpVerifyCode = "";
public long smtpVerifyExpire = 0;
public long smtpLastSendTime = 0;
public String smtpConfiguringPlayer = "";
public ConfigManager(File dataFolder) {
this.dataFolder = dataFolder;
}
// ==================== 消息 ====================
public void loadMessages() {
messages.clear();
File file = new File(dataFolder, "消息.txt");
if (!file.exists()) createDefaultMessages(file);
loadMap(file, messages);
}
public String msg(String key) {
String val = messages.getOrDefault(key, key);
val = val.replace("<b>", "&l");
val = val.replace("</b>", "&r");
val = val.replace("<br>", "\n");
val = val.replace("\\n", "\n");
// &颜色码 转换为 §颜色码
val = val.replaceAll(
"&([0-9a-fk-orA-FK-OR])", "§$1");
return val;
}
private void createDefaultMessages(File f) {
List<String> L = new ArrayList<>();
L.add("# ==========================================");
L.add("# Sdf1_login 消息配置文件");
L.add("# ==========================================");
L.add("# 颜色代码使用 § 符号");
L.add("# §0黑色 §1深蓝 §2深绿 §3深青");
L.add("# §4深红 §5深紫 §6金色 §7灰色");
L.add("# §8深灰 §9蓝色 §a绿色 §b浅蓝");
L.add("# §c红色 §d粉色 §e黄色 §f白色");
L.add("# §l粗体 §n下划线 §o斜体 §r重置");
L.add("#");
L.add("# 占位符用 {xxx} 表示,运行时自动替换");
L.add("# 支持 <b>粗体</b> 标签");
L.add("# 支持 \\n 或 <br> 换行");
L.add("# 修改后执行 /sdf1_login reload 重载");
L.add("# ==========================================");
L.add("");
// --- 登录/注册 ---
L.add("# ---- 登录注册相关 ----");
L.add("# login_timeout: 登录超时被踢出时的提示");
L.add("login_timeout=§c登录超时,请重新登录");
L.add("# not_registered: 未注册玩家收到的提示");
L.add("not_registered=§e您尚未注册,请使用 /reg <密码>");
L.add("# not_logged_in: 已注册但未登录的提示");
L.add("not_logged_in=§e您尚未登录,请使用 /login <密码>");
L.add("# already_registered: 已注册玩家再次注册时的提示");
L.add("already_registered=§c您已注册过账号");
L.add("# already_logged_in: 已登录玩家再次登录时的提示");
L.add("already_logged_in=§c您已登录");
L.add("# reg_success: 注册成功提示");
L.add("reg_success=§a注册成功!欢迎来到服务器");
L.add("# login_success: 登录成功提示");
L.add("login_success=§a登录成功!");
L.add("# login_failed: 密码错误提示");
L.add("login_failed=§c密码错误,请重试");
L.add("");
// --- 密码 ---
L.add("# ---- 密码相关 ----");
L.add("# password_wrong: 旧密码验证失败");
L.add("password_wrong=§c密码错误");
L.add("# password_changed: 密码修改成功");
L.add("password_changed=§a密码修改成功!");
L.add("# password_format_error: 密码格式不符合要求");
L.add("password_format_error=§c密码需6位以上,含大小写字母和数字");
L.add("# password_same: 新密码与旧密码相同");
L.add("password_same=§c新密码不能与旧密码相同");
L.add("# reset_no_email: 找回密码时未绑定邮箱");
L.add("reset_no_email=§c您未绑定邮箱,无法找回密码");
L.add("# reset_sent: 临时密码已发送到邮箱");
L.add("reset_sent=§a临时密码已发送到您的邮箱,请查收");
L.add("");
// --- 签到积分 ---
L.add("# ---- 签到积分相关 ----");
L.add("# checkin_already: 今日已签到");
L.add("checkin_already=§c您今日已签到");
L.add("# checkin_success: 签到成功,{points}=获得积分 {streak}=连续天数 {multi}=倍率");
L.add("checkin_success=§a签到成功!获得 {points} 积分,连续 {streak} 天,倍率 x{multi}");
L.add("# points_insufficient: 积分不足");
L.add("points_insufficient=§c积分不足,当前: {points}");
L.add("# points_purchase_success: 积分购买成功");
L.add("points_purchase_success=§a购买成功!消耗 {count} 积分");
L.add("");
// --- 挂机 ---
L.add("# ---- 挂机检测相关 ----");
L.add("# afk_set_enabled: 挂机检测开启");
L.add("afk_set_enabled=§a挂机检测已开启");
L.add("# afk_set_disabled: 挂机检测关闭");
L.add("afk_set_disabled=§c挂机检测已关闭");
L.add("# afk_kick: 因挂机被踢出");
L.add("afk_kick=§c因挂机过久被踢出");
L.add("");
// --- 邮箱 ---
L.add("# ---- 邮箱相关 ----");
L.add("# email_set: 邮箱设置成功");
L.add("email_set=§a邮箱设置成功:{email}");
L.add("# email_format_error: 邮箱格式错误");
L.add("email_format_error=§c邮箱格式不正确");
L.add("");
// --- 邀请 ---
L.add("# ---- 邀请相关 ----");
L.add("# invite_code_generated: 邀请码生成");
L.add("invite_code_generated=§a邀请码:{code}");
L.add("# invite_used: 使用邀请码成功");
L.add("invite_used=§a邀请成功,邀请人:{player}");
L.add("# invite_self: 使用自己的邀请码");
L.add("invite_self=§c不能使用自己的邀请码");
L.add("# invite_not_found: 邀请码不存在");
L.add("invite_not_found=§c邀请码不存在");
L.add("# invite_referral_bonus: 被邀请人签到后邀请人获得奖励");
L.add("invite_referral_bonus=§a邀请奖励!获得 {points} 积分");
L.add("");
// --- 礼包 ---
L.add("# ---- 新人礼包相关 ----");
L.add("# gift_not_ready: 礼包条件未满足");
L.add("gift_not_ready=§c礼包条件未满足");
L.add("# gift_claimed: 礼包领取成功");
L.add("gift_claimed=§a礼包领取成功!");
L.add("");
// --- 审批/IP ---
L.add("# ---- 审批与IP限制 ----");
L.add("# need_approval: 注册需审批");
L.add("need_approval=§e注册需审批 (工单#{id})");
L.add("# ip_max_accounts: IP注册已达上限");
L.add("ip_max_accounts=§cIP注册已达上限");
L.add("");
// --- 管理员 ---
L.add("# ---- 管理员操作 ----");
L.add("# admin_delete_confirm: 管理员删除账号确认提示");
L.add("admin_delete_confirm=§c请在聊天中输入玩家名确认删除");
L.add("");
// --- 聊天过滤 ---
L.add("# ---- 聊天过滤 ----");
L.add("# chat_muted: 禁言玩家尝试聊天");
L.add("chat_muted=§c§l[Sdf1_chat] §f你已被禁言,无法聊天");
L.add("# chat_url_blocked: 发送违规链接被拦截");
L.add("# {url}=检测到的链接地址");
L.add("chat_url_blocked=§c§l[Sdf1_chat] §f检测到违规第三方链接: §e{url}");
L.add("# chat_url_violation: 当前违规次数");
L.add("# {count}=当前违规次数");
L.add("chat_url_violation=§7当前违规次数: §e{count}");
L.add("# chat_url_admin_notify: 通知管理员,{player}=玩家名 {url}=链接 {count}=次数");
L.add("chat_url_admin_notify=§e§l[Sdf1_chat] §f{player} 发送违规链接: {url} (第{count}次)");
L.add("# chat_url_broadcast: 全服通报,{player}=玩家名");
L.add("chat_url_broadcast=§c§l[Sdf1_chat] §e{player} §f因发送违规链接被处罚");
L.add("");
// --- 通用 ---
L.add("# ---- 通用 ----");
L.add("# 未知参数: 未知命令或权限不足时的提示");
L.add("未知参数=§c未知参数或权限不足");
L.add("# only_player: 仅玩家可用的命令");
L.add("# only_player=§c此命令仅玩家可用");
writeLines(f, L);
}
// ==================== SMTP ====================
public void loadSmtp() {
smtpSettings.clear();
File file = new File(dataFolder, "SMTP设置.txt");
if (!file.exists()) createDefaultSmtp(file);
loadMap(file, smtpSettings);
}
private double parseDouble(String s, double def) {
try { return Double.parseDouble(s.trim()); }
catch (Exception e) { return def; }
}
public String getSmtp(String key) {
return smtpSettings.getOrDefault(key, "");
}
/** 获取挂机白名单列表 */
public List<String> getAfkWhitelist() {
List<String> list = new ArrayList<>();
File file = new File(dataFolder, "挂机白名单.txt");
if (!file.exists()) {
try {
file.createNewFile();
try (BufferedWriter w = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream(file),
StandardCharsets.UTF_8))) {
w.write("# 每行一个玩家名,前面加 # 为注释");
w.newLine();
w.write("# 以下玩家不会被挂机踢出");
w.newLine();
}
} catch (IOException ignored) {}
}
try (BufferedReader r = new BufferedReader(
new InputStreamReader(
new FileInputStream(file),
StandardCharsets.UTF_8))) {
String line;
while ((line = r.readLine()) != null) {
line = line.trim();
if (!line.isEmpty() && !line.startsWith("#")) {
list.add(line);
}
}
} catch (IOException ignored) {}
return list;
}
/** 设置SMTP单项(聊天输入用) */
public void setSmtp(String key, String value) {
smtpSettings.put(key, value);
}
/** 将当前SMTP设置写回文件 */
public void saveSmtp() {
File file = new File(dataFolder, "SMTP设置.txt");
List<String> L = new ArrayList<>();
L.add("# ===== SMTP 邮件服务器配置 =====");
for (Map.Entry<String, String> e : smtpSettings.entrySet()) {
L.add(e.getKey() + "=" + e.getValue());
}
writeLines(file, L);
}
private void createDefaultSmtp(File f) {
List<String> L = new ArrayList<>();
L.add("# ===== SMTP 邮件服务器配置 =====");
L.add("smtp地址=smtp.example.com");
L.add("smtp端口=465");
L.add("smtp账号=your_email@example.com");
L.add("smtp密码=");
L.add("发件人名称=Sdf1_login");
L.add("smtp加密=true");
writeLines(f, L);
}
// ==================== 插件设置 ====================
public void loadSettings() {
File file = new File(dataFolder, "插件设置.txt");
if (!file.exists()) createDefaultSettings(file);
Map<String, String> m = new LinkedHashMap<>();
loadMap(file, m);
adminTag = m.getOrDefault("管理标签", adminTag);
adminPassword = m.getOrDefault("管理密码", adminPassword);
maxAccountsPerIP = parseInt(
m.getOrDefault("每IP最大账号数", "3"), 3);
approvalMode = m.getOrDefault("审批模式", approvalMode);
autoApproveDelayMinutes = parseInt(
m.getOrDefault("自动审批延迟分钟", "30"), 30);
loginTimeout = parseInt(
m.getOrDefault("登录超时秒数", "60"), 60);
afkEnabled = Boolean.parseBoolean(
m.getOrDefault("挂机踢出", "false"));
afkTimeout = parseInt(
m.getOrDefault("挂机超时秒数", "300"), 300);
smtpSsl = Boolean.parseBoolean(
m.getOrDefault("smtp加密", "true"));
providerPointsPerScore = parseDouble(
m.getOrDefault("服务商积分倍率", "2.0"),
2.0);
baseEconomyReward = parseInt(
m.getOrDefault("基础经济奖励", "100"),
100);
providerEconomyPerScore = parseDouble(
m.getOrDefault("经济奖励每评分", "50.0"),
50.0);
requesterPointsReward = parseInt(
m.getOrDefault("报单人积分奖励", "10"),
10);
}
public void saveSettings() {
File file = new File(dataFolder, "插件设置.txt");
List<String> L = new ArrayList<>();
L.add("# ===== Sdf1_login 插件设置 =====");
L.add("管理标签=" + adminTag);
L.add("管理密码=" + adminPassword);
L.add("每IP最大账号数=" + maxAccountsPerIP);
L.add("审批模式=" + approvalMode);
L.add("自动审批延迟分钟=" + autoApproveDelayMinutes);
L.add("登录超时秒数=" + loginTimeout);
L.add("挂机踢出=" + afkEnabled);
L.add("挂机超时秒数=" + afkTimeout);
// 垃圾站设置
L.add("# ---- 垃圾站 ----");
L.add("垃圾站_启用: "
+ garbageEnabled);
L.add("垃圾站_清理间隔秒: "
+ garbageInterval);
L.add("垃圾站_保留轮数: "
+ garbageMaxRounds);
writeLines(file, L);
}
public double providerPointsPerScore = 2.0;
public int baseEconomyReward = 100;
public double providerEconomyPerScore = 50.0;
public int requesterPointsReward = 10;
public boolean garbageEnabled = true;
public int garbageInterval = 300;
public int garbageMaxRounds = 1;
private void createDefaultSettings(File f) {
List<String> L = new ArrayList<>();
L.add("# ===== Sdf1_login 插件设置 =====");
L.add("管理标签=admin");
L.add("管理密码=qweasd");
L.add("每IP最大账号数=3");
L.add("审批模式=manual");
L.add("自动审批延迟分钟=30");
L.add("登录超时秒数=60");
L.add("挂机踢出=false");
L.add("挂机超时秒数=300");
L.add("服务商积分倍率=" + providerPointsPerScore);
L.add("基础经济奖励=" + baseEconomyReward);
L.add("经济奖励每评分=" + providerEconomyPerScore);
L.add("报单人积分奖励=" + requesterPointsReward);
writeLines(f, L);
}
// ==================== 通用读写 ====================
private void loadMap(File file, Map<String, String> map) {
try (BufferedReader r = new BufferedReader(
new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) {
String line;
while ((line = r.readLine()) != null) {
line = line.trim();
if (line.isEmpty() || line.startsWith("#")) continue;
int eq = line.indexOf('=');
if (eq > 0) map.put(line.substring(0, eq).trim(), line.substring(eq + 1).trim());
}
} catch (IOException e) {
System.err.println("[Sdf1_login] 读取失败: " + file.getName());
}
}
private void writeLines(File file, List<String> lines) {
try (BufferedWriter w = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8))) {
for (String l : lines) { w.write(l); w.newLine(); }
} catch (IOException e) {
System.err.println("[Sdf1_login] 写入失败: " + file.getName());
}
}
private int parseInt(String s, int def) {
try { return Integer.parseInt(s.trim()); } catch (Exception e) { return def; }
}
/**
* 生成6位验证码(字母+数字)
*/
public String generateSmtpVerifyCode() {
String chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789";
StringBuilder sb = new StringBuilder();
java.util.Random r = new java.util.Random();
for (int i = 0; i < 6; i++) {
sb.append(chars.charAt(r.nextInt(
chars.length())));
}
smtpVerifyCode = sb.toString();
smtpVerifyExpire =
System.currentTimeMillis() + 300000L;
return smtpVerifyCode;
}
/**
* 检查验证码是否有效
*/
public boolean checkSmtpVerifyCode(String code) {
if (System.currentTimeMillis() > smtpVerifyExpire) {
smtpVerifyCode = "";
return false;
}
return smtpVerifyCode.equalsIgnoreCase(code);
}
/**
* 清除验证码
*/
public void clearSmtpVerifyCode() {
smtpVerifyCode = "";
smtpVerifyExpire = 0;
}
/**
* 检查发送间隔是否>=1分钟
*/
public boolean canSendSmtpVerify() {
return System.currentTimeMillis()
- smtpLastSendTime >= 60000L;
}
public void recordSmtpSendTime() {
smtpLastSendTime = System.currentTimeMillis();
}
}