2025-08-04 15:11:07 +08:00

184 lines
7.7 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package org.branulf.playertime;
import com.google.gson.*;
import net.fabricmc.api.EnvType;
import net.fabricmc.loader.api.FabricLoader;
import java.io.*;
import java.nio.file.*;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ModConfig {
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
public final Path configPath;
// 配置项
public int webPort = 60048;
public String language = "zh_cn";
public static boolean whitelistOnly = true; // 默认只记录白名单玩家
public int saveIntervalMinutes = 5; // 默认每5分钟保存一次
public ModConfig(Path configDir) throws IOException {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
this.configPath = configDir.resolve("config").resolve("playertime-config.json");
} else {
this.configPath = configDir.resolve("playertime-config.json");
}
if (!Files.exists(this.configPath.getParent())) {
Files.createDirectories(this.configPath.getParent());
}
loadConfig();
}
// 加载配置
public void loadConfig() {
if (!Files.exists(configPath)) {
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件未找到,正在创建默认配置: {}", configPath);
saveConfig(); // 创建默认配置并保存
return;
}
try (Reader reader = Files.newBufferedReader(configPath)) {
JsonElement jsonElement = JsonParser.parseReader(reader);
if (jsonElement == null || !jsonElement.isJsonObject()) {
PlayerTimeMod.LOGGER.warn("[在线时间] 配置文件为空或格式错误,正在使用默认配置并覆盖: {}", configPath);
saveConfig(); // 使用默认配置并覆盖
return;
}
JsonObject json = jsonElement.getAsJsonObject();
// 读取 webPort
if (json.has("webPort") && json.get("webPort").isJsonPrimitive() && json.get("webPort").getAsJsonPrimitive().isNumber()) {
webPort = json.get("webPort").getAsInt();
if (webPort < 1 || webPort > 65535) {
PlayerTimeMod.LOGGER.warn("[在线时间] 配置文件中的 webPort ({}) 无效,使用默认值 {}", webPort, 60048);
webPort = 60048;
}
} else {
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少或 webPort 格式错误,使用默认值 {}", webPort);
// 不立即保存,等待所有字段读取完毕再决定是否保存
}
// 读取 language
if (json.has("language") && json.get("language").isJsonPrimitive() && json.get("language").getAsJsonPrimitive().isString()) {
language = json.get("language").getAsString();
} else {
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少或 language 格式错误,使用默认值 {}", language);
}
// 读取 whitelistOnly
if (json.has("whitelistOnly") && json.get("whitelistOnly").isJsonPrimitive() && json.get("whitelistOnly").getAsJsonPrimitive().isBoolean()) {
whitelistOnly = json.get("whitelistOnly").getAsBoolean();
} else {
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少或 whitelistOnly 格式错误,使用默认值 {}", whitelistOnly);
}
// 读取 saveIntervalMinutes
if (json.has("saveIntervalMinutes") && json.get("saveIntervalMinutes").isJsonPrimitive() && json.get("saveIntervalMinutes").getAsJsonPrimitive().isNumber()) {
saveIntervalMinutes = json.get("saveIntervalMinutes").getAsInt();
if (saveIntervalMinutes < 0) {
PlayerTimeMod.LOGGER.warn("[在线时间] 配置文件中的 saveIntervalMinutes ({}) 无效,使用默认值 {}", saveIntervalMinutes, 5);
saveIntervalMinutes = 5;
}
} else {
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少或 saveIntervalMinutes 格式错误,使用默认值 {}", saveIntervalMinutes);
}
// 检查是否有新字段需要添加到配置文件
if (!json.has("webPort") || !json.has("language") || !json.has("whitelistOnly") || !json.has("saveIntervalMinutes")) {
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少部分字段,正在添加并保存。");
saveConfig(); // 保存以添加新字段
} else {
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件加载成功: {}", configPath);
}
} catch (IOException e) {
PlayerTimeMod.LOGGER.error("[在线时间] 无法读取配置文件 {},使用默认配置", configPath, e);
saveConfig(); // 发生IO错误尝试保存默认配置
} catch (JsonParseException e) {
PlayerTimeMod.LOGGER.error("[在线时间] 配置文件 {} 格式错误,使用默认配置", configPath, e);
saveConfig(); // 发生JSON解析错误尝试保存默认配置
} catch (Exception e) {
PlayerTimeMod.LOGGER.error("[在线时间] 加载配置文件 {} 时发生未知错误,使用默认配置", configPath, e);
saveConfig(); // 发生未知错误,尝试保存默认配置
}
}
// 保存配置
public void saveConfig() {
JsonObject json = new JsonObject();
json.addProperty("webPort", webPort);
json.addProperty("language", language);
json.addProperty("whitelistOnly", whitelistOnly);
json.addProperty("saveIntervalMinutes", saveIntervalMinutes);
try {
Files.createDirectories(configPath.getParent());
try (Writer writer = Files.newBufferedWriter(configPath)) {
GSON.toJson(json, writer);
}
PlayerTimeMod.LOGGER.info("[在线时间] 配置已成功保存到 {}", configPath);
} catch (Exception e) {
PlayerTimeMod.LOGGER.error("[在线时间] 保存配置失败到 {}", configPath, e);
}
notifyConfigChanged();
}
// 获取端口
public int getWebPort() {
return webPort;
}
// 获取语言
public String getLanguage() {
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
try {
net.minecraft.client.MinecraftClient client = net.minecraft.client.MinecraftClient.getInstance();
if (client != null) {
String clientLang = client.options.language;
if (clientLang != null && !clientLang.isEmpty()) {
return clientLang;
}
}
} catch (Exception e) {
PlayerTimeMod.LOGGER.warn("[在线时间] 无法获取客户端语言,使用配置值", e);
}
}
return language;
}
// 获取是否只记录白名单
public boolean isWhitelistOnly() {
return whitelistOnly;
}
// 获取保存间隔(分钟)
public int getSaveIntervalMinutes() {
return saveIntervalMinutes;
}
private static final List<ConfigChangeListener> listeners = new CopyOnWriteArrayList<>();
public interface ConfigChangeListener {
void onConfigChanged(ModConfig config);
}
public static void addChangeListener(ConfigChangeListener listener) {
listeners.add(listener);
}
private void notifyConfigChanged() {
for (ConfigChangeListener listener : listeners) {
listener.onConfigChanged(this);
}
}
}