diff --git a/gradle.properties b/gradle.properties index a6aa206..c701e7c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ minecraft_version=1.21.4 yarn_mappings=1.21.4+build.8 loader_version=0.16.10 # Mod Properties -mod_version=1.14.514.131 +mod_version=1.14.514.132 maven_group=org.example1 archives_base_name=ServerPlayerOnlineTracker # Dependencies diff --git a/src/main/java/com/example/playertime/ModConfig.java b/src/main/java/com/example/playertime/ModConfig.java index e59a1f5..e98d1c4 100644 --- a/src/main/java/com/example/playertime/ModConfig.java +++ b/src/main/java/com/example/playertime/ModConfig.java @@ -9,7 +9,6 @@ public class ModConfig { private final Path configPath; private int webPort = 60048; private String language = "zh_cn"; - private long autoSaveSeconds = 300; public ModConfig(Path configDir) { this.configPath = configDir.resolve("playertime-config.json"); @@ -37,19 +36,13 @@ public class ModConfig { if (json.has("webPort")) { webPort = json.get("webPort").getAsInt(); } else { - PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少“webPort”字段,添加默认值'%s'并保存", webPort); + PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少webPort字段,添加默认值'%s'并保存", webPort); saveConfig(); } if (json.has("language")) { language = json.get("language").getAsString(); } else { - PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少“language”字段,添加默认值'%s'并保存", language); - saveConfig(); - } - if (json.has("autoSaveSeconds")) { - autoSaveSeconds = json.get("autoSaveSeconds").getAsLong(); - } else { - PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少“autoSaveSeconds”字段,添加默认值'%s'并保存", autoSaveSeconds); + PlayerTimeMod.LOGGER.info("[在线时间] 配置文件缺少language字段,添加默认值'%s'并保存", language); saveConfig(); } @@ -64,7 +57,6 @@ public class ModConfig { JsonObject json = new JsonObject(); json.addProperty("webPort", webPort); json.addProperty("language", language); - json.addProperty("autoSaveSeconds", autoSaveSeconds); try { Files.createDirectories(configPath.getParent()); @@ -86,9 +78,4 @@ public class ModConfig { public String getLanguage() { return language; } - - // 获取保存间隔 - public long getSeconds() { - return autoSaveSeconds; - } } diff --git a/src/main/java/com/example/playertime/PlayerTimeMod.java b/src/main/java/com/example/playertime/PlayerTimeMod.java index 72314f4..01c024a 100644 --- a/src/main/java/com/example/playertime/PlayerTimeMod.java +++ b/src/main/java/com/example/playertime/PlayerTimeMod.java @@ -19,10 +19,6 @@ import org.slf4j.LoggerFactory; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; public class PlayerTimeMod implements ModInitializer { @@ -30,29 +26,16 @@ public class PlayerTimeMod implements ModInitializer { private static PlayerTimeTracker timeTracker; private static WebServer webServer; private static ModConfig config; - public static LocalizationManager localizationManager; // 新增本地化管理器 - - // TODO 定时保存配置文件没整,暂时硬编码 - private ScheduledExecutorService scheduler; - private ScheduledFuture saveTask; - private static long AUTO_SAVE_INTERVAL_SECONDS; - - // 后续还是想把logger改成英文 + public static LocalizationManager localizationManager; @Override public void onInitialize() { - config = new ModConfig(FabricLoader.getInstance().getConfigDir()); localizationManager = new LocalizationManager(config.getLanguage()); - scheduler = Executors.newSingleThreadScheduledExecutor(); - - try { LOGGER.info("[在线时间] 初始化 玩家在线时长视奸Mod"); - AUTO_SAVE_INTERVAL_SECONDS = config.getSeconds(); - ServerLifecycleEvents.SERVER_STARTING.register(server -> { timeTracker = new PlayerTimeTracker(server); try { @@ -62,21 +45,6 @@ public class PlayerTimeMod implements ModInitializer { } catch (Exception e) { LOGGER.error("[在线时间] 无法启动Web服务器", e); } - - LOGGER.info("[在线时间] 每{}秒({}分钟)安排自动保存任务。", - AUTO_SAVE_INTERVAL_SECONDS, AUTO_SAVE_INTERVAL_SECONDS / 60); - saveTask = scheduler.scheduleAtFixedRate( - () -> { - if (timeTracker != null) { - LOGGER.info("[在线时间] 自动保存玩家数据中..."); - timeTracker.saveAll(); - LOGGER.info("[在线时间] 自动保存完成。"); - } - }, - AUTO_SAVE_INTERVAL_SECONDS, - AUTO_SAVE_INTERVAL_SECONDS, - TimeUnit.SECONDS - ); }); ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { @@ -94,24 +62,6 @@ public class PlayerTimeMod implements ModInitializer { ServerLifecycleEvents.SERVER_STOPPING.register(server -> { LOGGER.info("[在线时间] 服务器停止 - 正在保存数据"); - if (saveTask != null) { - saveTask.cancel(false); - LOGGER.info("[在线时间] 自动保存任务已取消。"); - } - if (scheduler != null && !scheduler.isShutdown()) { - scheduler.shutdown(); - try { - if (!scheduler.awaitTermination(5, TimeUnit.SECONDS)) { - LOGGER.warn("[在线时间] 调度程序未在5秒内终止。"); - } - } catch (InterruptedException e) { - LOGGER.error("[在线时间] 调度程序终止被中断", e); - Thread.currentThread().interrupt(); - } - LOGGER.info("[在线时间] 调度程序关闭"); - } - - if (webServer != null) { webServer.stop(); } @@ -123,12 +73,8 @@ public class PlayerTimeMod implements ModInitializer { } }); - } catch (Exception e) { - LOGGER.error("[在线时间] Mod出屎化失败", e); - if (scheduler != null && !scheduler.isShutdown()) { - scheduler.shutdownNow(); - } + LOGGER.error("[在线时间] Mod初始化失败", e); throw new RuntimeException("[在线时间] Mod初始化失败 ", e); } registerCommands(); @@ -146,12 +92,11 @@ public class PlayerTimeMod implements ModInitializer { return localizationManager; } - public static void registerCommands() { CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> { dispatcher.register(CommandManager.literal("onlineTime") .requires(source -> source.hasPermissionLevel(0)) - .executes(context -> showOnlineTime(context.getSource(), 1)) // 默认第一页 + .executes(context -> showOnlineTime(context.getSource(), 1)) .then(CommandManager.argument("page", IntegerArgumentType.integer(1)) .executes(context -> showOnlineTime( context.getSource(), @@ -172,7 +117,7 @@ public class PlayerTimeMod implements ModInitializer { Map stats = tracker.getWhitelistedPlayerStats(); List sorted = stats.entrySet().stream() - .sorted((a, b) -> comparePlayTime(b.getValue(), a.getValue())) + .sorted((a, b) -> comparePlayTime(a.getValue(), b.getValue())) .map(entry -> formatPlayerTime(entry.getKey(), entry.getValue())) .collect(Collectors.toList()); @@ -249,5 +194,4 @@ public class PlayerTimeMod implements ModInitializer { player.sendMessage(footer, false); } - } diff --git a/src/main/java/com/example/playertime/PlayerTimeTracker.java b/src/main/java/com/example/playertime/PlayerTimeTracker.java index 6e04a9d..fb85f41 100644 --- a/src/main/java/com/example/playertime/PlayerTimeTracker.java +++ b/src/main/java/com/example/playertime/PlayerTimeTracker.java @@ -27,16 +27,6 @@ public class PlayerTimeTracker { loadData(); } - // 没用了,但是先保留吧 - // private boolean isWhitelisted(String playerName) { - // MinecraftServer server = this.server; - // if (server == null) return false; - // - // return server.getPlayerManager().getWhitelist() - // .isAllowed(server.getUserCache().findByName(playerName).orElse(null)); - // } - - public void onPlayerJoin(ServerPlayerEntity player) { PlayerTimeData data = playerData.computeIfAbsent(player.getUuid(), uuid -> new PlayerTimeData()); data.lastLogin = Instant.now().getEpochSecond(); @@ -202,17 +192,6 @@ public class PlayerTimeTracker { PlayerTimeMod.LOGGER.info("[在线时间] 开始保存所有玩家数据..."); JsonObject root = new JsonObject(); playerData.forEach((uuid, data) -> { - if (data.lastLogin > 0) { - long now = Instant.now().getEpochSecond(); - long sessionTime = now - data.lastLogin; - if (sessionTime > 0) { - data.totalTime += sessionTime; - data.rolling30Days.addPlayTime(now, sessionTime); - data.rolling7Days.addPlayTime(now, sessionTime); - PlayerTimeMod.LOGGER.debug("[在线时间] 累积当前会话时间 {} 秒,保存期间玩家 {}", sessionTime, getPlayerName(uuid)); - } - data.lastLogin = 0; - } root.add(uuid.toString(), GSON.toJsonTree(data)); }); @@ -254,7 +233,6 @@ public class PlayerTimeTracker { try (Writer writer = Files.newBufferedWriter(dataFile)) { GSON.toJson(root, writer); - // PlayerTimeMod.LOGGER.debug("[在线时间] Async save successful for player {}", getPlayerName(uuid)); } catch (Exception e) { PlayerTimeMod.LOGGER.error("[在线时间] 无法异步保存玩家的在线时间数据 " + getPlayerName(uuid) + " (UUID: " + uuid + ")", e); } @@ -325,5 +303,4 @@ public class PlayerTimeTracker { public Path getDataFile() { return this.dataFile; } - } diff --git a/src/main/resources/assets/playertime/web/favicon.ico b/src/main/resources/assets/playertime/web/favicon.ico new file mode 100644 index 0000000..1037c10 Binary files /dev/null and b/src/main/resources/assets/playertime/web/favicon.ico differ diff --git a/src/main/resources/assets/playertime/web/index.html b/src/main/resources/assets/playertime/web/index.html index 99b5cd1..b4f122b 100644 --- a/src/main/resources/assets/playertime/web/index.html +++ b/src/main/resources/assets/playertime/web/index.html @@ -6,6 +6,7 @@ 玩家在线及状态统计 +