修bug修bug
This commit is contained in:
parent
a5b4efc36e
commit
eef2bbebad
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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<String, String> stats = tracker.getWhitelistedPlayerStats();
|
||||
|
||||
List<String> 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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
src/main/resources/assets/playertime/web/favicon.ico
Normal file
BIN
src/main/resources/assets/playertime/web/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 40 KiB |
@ -6,6 +6,7 @@
|
||||
<title data-lang-key="playertime.web.title">玩家在线及状态统计</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
||||
<link rel="icon" href="favicon.ico" type="image/x-icon">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
</head>
|
||||
|
Loading…
x
Reference in New Issue
Block a user