Compare commits
2 Commits
245103cf44
...
50021fc726
Author | SHA1 | Date | |
---|---|---|---|
50021fc726 | |||
98b04f7155 |
@ -14,7 +14,9 @@ preprocess {
|
|||||||
def mc12105 = createNode("1.21.5", 1_21_05, "")
|
def mc12105 = createNode("1.21.5", 1_21_05, "")
|
||||||
def mc12106 = createNode("1.21.6", 1_21_06, "")
|
def mc12106 = createNode("1.21.6", 1_21_06, "")
|
||||||
def mc12107 = createNode("1.21.7", 1_21_07, "")
|
def mc12107 = createNode("1.21.7", 1_21_07, "")
|
||||||
|
def mc12108 = createNode("1.21.8", 1_21_08, "")
|
||||||
|
|
||||||
|
mc12108.link(mc12107, file("versions/mapping_12108_12107.txt"))
|
||||||
mc12107.link(mc12106, file("versions/mapping_12107_12106.txt"))
|
mc12107.link(mc12106, file("versions/mapping_12107_12106.txt"))
|
||||||
mc12106.link(mc12105, file("versions/mapping_12106_12105.txt"))
|
mc12106.link(mc12105, file("versions/mapping_12106_12105.txt"))
|
||||||
mc12105.link(mc12104, file("versions/mapping_12105_12104.txt"))
|
mc12105.link(mc12104, file("versions/mapping_12105_12104.txt"))
|
||||||
|
@ -32,6 +32,12 @@ dependencies {
|
|||||||
|
|
||||||
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
|
modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_api_version}"
|
||||||
|
|
||||||
|
include modApi("me.shedaniel.cloth:cloth-config-fabric:${project.cloth_config_version}") {
|
||||||
|
exclude(group: "net.fabricmc.fabric-api")
|
||||||
|
}
|
||||||
|
modImplementation "me.shedaniel.cloth:cloth-config-fabric:${project.cloth_config_version}"
|
||||||
|
modImplementation("com.terraformersmc:modmenu:${project.modmenu_version}")
|
||||||
|
|
||||||
implementation 'com.google.code.gson:gson:2.8.9'
|
implementation 'com.google.code.gson:gson:2.8.9'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ loader_version=0.16.10
|
|||||||
# Mod Properties
|
# Mod Properties
|
||||||
mod_name=Disc Jockey Revive
|
mod_name=Disc Jockey Revive
|
||||||
mod_id=disc_jockey_revive
|
mod_id=disc_jockey_revive
|
||||||
mod_version=1.14.514.144
|
mod_version=1.14.514.148
|
||||||
maven_group=org.example1
|
maven_group=org.example1
|
||||||
archives_base_name=ServerPlayerOnlineTracker
|
archives_base_name=ServerPlayerOnlineTracker
|
||||||
# Dependencies
|
# Dependencies
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"1.21.4",
|
"1.21.4",
|
||||||
"1.21.5",
|
"1.21.5",
|
||||||
"1.21.6",
|
"1.21.6",
|
||||||
"1.21.7"
|
"1.21.7",
|
||||||
|
"1.21.8"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
46
src/main/java/org/branulf/playertime/ClothConfigScreen.java
Normal file
46
src/main/java/org/branulf/playertime/ClothConfigScreen.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package org.branulf.playertime;
|
||||||
|
|
||||||
|
import me.shedaniel.clothconfig2.api.ConfigBuilder;
|
||||||
|
import me.shedaniel.clothconfig2.api.ConfigCategory;
|
||||||
|
import me.shedaniel.clothconfig2.api.ConfigEntryBuilder;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import org.branulf.playertime.ModConfig;
|
||||||
|
|
||||||
|
public class ClothConfigScreen {
|
||||||
|
public static Screen create(Screen parent, ModConfig config) {
|
||||||
|
ConfigBuilder builder = ConfigBuilder.create()
|
||||||
|
.setParentScreen(parent)
|
||||||
|
.setTitle(Text.translatable("title.playertime.config"))
|
||||||
|
.setSavingRunnable(config::saveConfig);
|
||||||
|
|
||||||
|
ConfigEntryBuilder entryBuilder = builder.entryBuilder();
|
||||||
|
ConfigCategory general = builder.getOrCreateCategory(Text.translatable("category.playertime.general"));
|
||||||
|
|
||||||
|
// 端口
|
||||||
|
general.addEntry(entryBuilder.startIntField(Text.translatable("option.playertime.webPort"), config.webPort)
|
||||||
|
.setDefaultValue(60048)
|
||||||
|
.setMin(1024).setMax(65535)
|
||||||
|
.setTooltip(Text.translatable("tooltip.playertime.webPort"))
|
||||||
|
.setSaveConsumer(newValue -> config.webPort = newValue)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
|
||||||
|
// 白名单
|
||||||
|
general.addEntry(entryBuilder.startBooleanToggle(Text.translatable("option.playertime.whitelistOnly"), ModConfig.whitelistOnly)
|
||||||
|
.setDefaultValue(true)
|
||||||
|
.setTooltip(Text.translatable("tooltip.playertime.whitelistOnly"))
|
||||||
|
.setSaveConsumer(newValue -> ModConfig.whitelistOnly = newValue)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
// 间隔
|
||||||
|
general.addEntry(entryBuilder.startIntField(Text.translatable("option.playertime.saveIntervalMinutes"), config.saveIntervalMinutes)
|
||||||
|
.setDefaultValue(5)
|
||||||
|
.setMin(1).setMax(60)
|
||||||
|
.setTooltip(Text.translatable("tooltip.playertime.saveIntervalMinutes"))
|
||||||
|
.setSaveConsumer(newValue -> config.saveIntervalMinutes = newValue)
|
||||||
|
.build());
|
||||||
|
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
}
|
@ -1,26 +1,39 @@
|
|||||||
package org.branulf.playertime;
|
package org.branulf.playertime;
|
||||||
|
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.file.*;
|
import java.nio.file.*;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
public class ModConfig {
|
public class ModConfig {
|
||||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
public static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||||
private final Path configPath;
|
public final Path configPath;
|
||||||
|
|
||||||
// 配置项
|
// 配置项
|
||||||
private int webPort = 60048;
|
public int webPort = 60048;
|
||||||
private String language = "zh_cn";
|
public String language = "zh_cn";
|
||||||
private boolean whitelistOnly = true; // 默认只记录白名单玩家
|
public static boolean whitelistOnly = true; // 默认只记录白名单玩家
|
||||||
private int saveIntervalMinutes = 5; // 默认每5分钟保存一次
|
public int saveIntervalMinutes = 5; // 默认每5分钟保存一次
|
||||||
|
|
||||||
public ModConfig(Path configDir) {
|
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");
|
this.configPath = configDir.resolve("playertime-config.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Files.exists(this.configPath.getParent())) {
|
||||||
|
Files.createDirectories(this.configPath.getParent());
|
||||||
|
}
|
||||||
loadConfig();
|
loadConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载配置
|
// 加载配置
|
||||||
private void loadConfig() {
|
public void loadConfig() {
|
||||||
if (!Files.exists(configPath)) {
|
if (!Files.exists(configPath)) {
|
||||||
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件未找到,正在创建默认配置: {}", configPath);
|
PlayerTimeMod.LOGGER.info("[在线时间] 配置文件未找到,正在创建默认配置: {}", configPath);
|
||||||
saveConfig(); // 创建默认配置并保存
|
saveConfig(); // 创建默认配置并保存
|
||||||
@ -97,7 +110,7 @@ public class ModConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 保存配置
|
// 保存配置
|
||||||
private void saveConfig() {
|
public void saveConfig() {
|
||||||
JsonObject json = new JsonObject();
|
JsonObject json = new JsonObject();
|
||||||
json.addProperty("webPort", webPort);
|
json.addProperty("webPort", webPort);
|
||||||
json.addProperty("language", language);
|
json.addProperty("language", language);
|
||||||
@ -113,6 +126,7 @@ public class ModConfig {
|
|||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
PlayerTimeMod.LOGGER.error("[在线时间] 保存配置失败到 {}", configPath, e);
|
PlayerTimeMod.LOGGER.error("[在线时间] 保存配置失败到 {}", configPath, e);
|
||||||
}
|
}
|
||||||
|
notifyConfigChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取端口
|
// 获取端口
|
||||||
@ -122,6 +136,19 @@ public class ModConfig {
|
|||||||
|
|
||||||
// 获取语言
|
// 获取语言
|
||||||
public String getLanguage() {
|
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;
|
return language;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,4 +161,23 @@ public class ModConfig {
|
|||||||
public int getSaveIntervalMinutes() {
|
public int getSaveIntervalMinutes() {
|
||||||
return saveIntervalMinutes;
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
18
src/main/java/org/branulf/playertime/ModMenuIntegration.java
Normal file
18
src/main/java/org/branulf/playertime/ModMenuIntegration.java
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package org.branulf.playertime;
|
||||||
|
|
||||||
|
import me.shedaniel.autoconfig.AutoConfig;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
|
import net.minecraft.client.gui.screen.Screen;
|
||||||
|
import org.branulf.playertime.ModConfig;
|
||||||
|
import org.branulf.playertime.PlayerTimeMod;
|
||||||
|
import com.terraformersmc.modmenu.api.ConfigScreenFactory;
|
||||||
|
import com.terraformersmc.modmenu.api.ModMenuApi;
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public class ModMenuIntegration implements ModMenuApi {
|
||||||
|
@Override
|
||||||
|
public ConfigScreenFactory<?> getModConfigScreenFactory() {
|
||||||
|
return parent -> ClothConfigScreen.create(parent, PlayerTimeMod.getConfig());
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,9 @@
|
|||||||
package org.branulf.playertime;
|
package org.branulf.playertime;
|
||||||
|
|
||||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.api.Environment;
|
||||||
import net.fabricmc.api.ModInitializer;
|
import net.fabricmc.api.ModInitializer;
|
||||||
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
|
||||||
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
|
||||||
@ -303,7 +306,7 @@ public class PlayerTimeMod implements ModInitializer {
|
|||||||
LOGGER.warn("[在线时间] 下载链接: {}", latestVersionLink);
|
LOGGER.warn("[在线时间] 下载链接: {}", latestVersionLink);
|
||||||
LOGGER.warn("==================================================");
|
LOGGER.warn("==================================================");
|
||||||
} else {
|
} else {
|
||||||
LOGGER.info("[在线时间] 当前已是最新版本(或检查失败)。");
|
LOGGER.info("[在线时间] 当前已是最新版本。");
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (javax.xml.parsers.ParserConfigurationException e) {
|
} catch (javax.xml.parsers.ParserConfigurationException e) {
|
||||||
@ -356,4 +359,11 @@ public class PlayerTimeMod implements ModInitializer {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Environment(EnvType.CLIENT)
|
||||||
|
public static class ClientInitializer implements ClientModInitializer {
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
package org.branulf.playertime;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
|
||||||
|
public class PlayerTimeModClient implements ClientModInitializer {
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
PlayerTimeMod.LOGGER.info("[在线时间] 客户端初始化完成");
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,8 @@ package org.branulf.playertime;
|
|||||||
|
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
import com.mojang.authlib.GameProfile;
|
import com.mojang.authlib.GameProfile;
|
||||||
|
import net.fabricmc.api.EnvType;
|
||||||
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.server.MinecraftServer;
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.PlayerManager;
|
import net.minecraft.server.PlayerManager;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
@ -25,8 +27,14 @@ public class PlayerTimeTracker {
|
|||||||
public PlayerTimeTracker(MinecraftServer server, ModConfig config) {
|
public PlayerTimeTracker(MinecraftServer server, ModConfig config) {
|
||||||
this.server = server;
|
this.server = server;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
if (FabricLoader.getInstance().getEnvironmentType() == EnvType.CLIENT) {
|
||||||
|
this.dataFile = FabricLoader.getInstance().getGameDir().resolve("saves")
|
||||||
|
.resolve(server.getSaveProperties().getLevelName())
|
||||||
|
.resolve("player_time_data.json");
|
||||||
|
} else {
|
||||||
this.dataFile = server.getRunDirectory().resolve("player_time_data.json");
|
this.dataFile = server.getRunDirectory().resolve("player_time_data.json");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void loadData() {
|
public void loadData() {
|
||||||
if (!Files.exists(dataFile)) {
|
if (!Files.exists(dataFile)) {
|
||||||
@ -136,9 +144,11 @@ public class PlayerTimeTracker {
|
|||||||
long now = Instant.now().getEpochSecond();
|
long now = Instant.now().getEpochSecond();
|
||||||
List<PlayerTimeStatsWithNames> statsList = new ArrayList<>();
|
List<PlayerTimeStatsWithNames> statsList = new ArrayList<>();
|
||||||
|
|
||||||
|
boolean shouldCategorize = config.isWhitelistOnly();
|
||||||
|
|
||||||
// 获取白名单 UUID 集合 (如果需要过滤)
|
// 获取白名单 UUID 集合 (如果需要过滤)
|
||||||
Set<UUID> whitelistUuids;
|
Set<UUID> whitelistUuids;
|
||||||
if (config.isWhitelistOnly()) {
|
if (shouldCategorize) {
|
||||||
whitelistUuids = new HashSet<>();
|
whitelistUuids = new HashSet<>();
|
||||||
if (server != null && server.getPlayerManager() != null && server.getUserCache() != null) {
|
if (server != null && server.getPlayerManager() != null && server.getUserCache() != null) {
|
||||||
for (String name : server.getPlayerManager().getWhitelist().getNames()) {
|
for (String name : server.getPlayerManager().getWhitelist().getNames()) {
|
||||||
|
@ -16,6 +16,8 @@ import java.util.concurrent.*;
|
|||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
// 导入API类,别忘了
|
// 导入API类,别忘了
|
||||||
|
import net.minecraft.server.PlayerManager;
|
||||||
|
import net.minecraft.server.Whitelist;
|
||||||
import org.branulf.playertime.api.PlayerStatsResponse;
|
import org.branulf.playertime.api.PlayerStatsResponse;
|
||||||
import org.branulf.playertime.api.ServerStatusResponse;
|
import org.branulf.playertime.api.ServerStatusResponse;
|
||||||
import org.branulf.playertime.api.OnlinePlayersResponse;
|
import org.branulf.playertime.api.OnlinePlayersResponse;
|
||||||
@ -230,6 +232,9 @@ public class WebServer {
|
|||||||
status.uptime = uptimeMillis / 1000; // 秒
|
status.uptime = uptimeMillis / 1000; // 秒
|
||||||
status.uptime_formatted = formatUptime(uptimeMillis);
|
status.uptime_formatted = formatUptime(uptimeMillis);
|
||||||
|
|
||||||
|
status.configWhitelistOnly = ModConfig.whitelistOnly;
|
||||||
|
status.serverWhitelistEnabled = minecraftServer.getPlayerManager().isWhitelistEnabled();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
File diskPartition = new File(".");
|
File diskPartition = new File(".");
|
||||||
status.disk.total = diskPartition.getTotalSpace();
|
status.disk.total = diskPartition.getTotalSpace();
|
||||||
|
@ -10,6 +10,8 @@ public class ServerStatusResponse {
|
|||||||
public long uptime; // 秒
|
public long uptime; // 秒
|
||||||
public String uptime_formatted;
|
public String uptime_formatted;
|
||||||
public ServerInfo server = new ServerInfo();
|
public ServerInfo server = new ServerInfo();
|
||||||
|
public boolean configWhitelistOnly;
|
||||||
|
public boolean serverWhitelistEnabled;
|
||||||
|
|
||||||
public static class MemoryStats {
|
public static class MemoryStats {
|
||||||
public long max; // 字节
|
public long max; // 字节
|
||||||
|
BIN
src/main/resources/assets/playertime/icon.ico
Normal file
BIN
src/main/resources/assets/playertime/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 330 KiB |
Binary file not shown.
Before Width: | Height: | Size: 21 KiB |
@ -12,7 +12,7 @@
|
|||||||
"playertime.command.error.player_only": "This command can only be executed by a player.",
|
"playertime.command.error.player_only": "This command can only be executed by a player.",
|
||||||
|
|
||||||
"playertime.web.title": "Player online and status statistics",
|
"playertime.web.title": "Player online and status statistics",
|
||||||
"playertime.web.warning": "Data tracking starts from the mod installation time and does not include any data before installation.",
|
"playertime.web.warning": "Note: Data tracking starts from the mod installation time and does not include any data before installation.",
|
||||||
"playertime.web.status.online_players": "Online Players",
|
"playertime.web.status.online_players": "Online Players",
|
||||||
"playertime.web.status.total": "Total",
|
"playertime.web.status.total": "Total",
|
||||||
"playertime.web.status.players": "Players",
|
"playertime.web.status.players": "Players",
|
||||||
@ -61,5 +61,17 @@
|
|||||||
|
|
||||||
"playertime.web.error.load_failed": "Failed to load data, check console",
|
"playertime.web.error.load_failed": "Failed to load data, check console",
|
||||||
|
|
||||||
"playertime.web.footer.license": "This project is open source under the GPL3 license"
|
"playertime.web.footer.license": "This project is open source under the GPL3 license",
|
||||||
|
|
||||||
|
"title.playertime.config": "Player Time Tracker Config",
|
||||||
|
"category.playertime.general": "General Settings",
|
||||||
|
"option.playertime.webPort": "Web Server Port",
|
||||||
|
"tooltip.playertime.webPort": "Port for the web server (default: 60048)",
|
||||||
|
"option.playertime.language": "Language",
|
||||||
|
"tooltip.playertime.language": "Mod display language",
|
||||||
|
"option.playertime.whitelistOnly": "Whitelist Only",
|
||||||
|
"tooltip.playertime.whitelistOnly": "Only track whitelisted players",
|
||||||
|
"option.playertime.saveIntervalMinutes": "Save Interval (minutes)",
|
||||||
|
"tooltip.playertime.saveIntervalMinutes": "Auto-save interval for player data",
|
||||||
|
"playertime.web.warning.whitelist_disabled": "Warning: Whitelist-only tracking is enabled, but server whitelist is not active. Non-whitelisted players will be classified as non-players."
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
|
|
||||||
"playertime.web.title": "玩家在线及状态统计",
|
"playertime.web.title": "玩家在线及状态统计",
|
||||||
"playertime.web.warning": "数据统计时间开始于此MOD安装时间,不包含安装之前的所有数据",
|
"playertime.web.warning": "注意:数据统计时间开始于此MOD安装时间,不包含安装之前的所有数据",
|
||||||
"playertime.web.status.online_players": "在线玩家",
|
"playertime.web.status.online_players": "在线玩家",
|
||||||
"playertime.web.status.total": "总数",
|
"playertime.web.status.total": "总数",
|
||||||
"playertime.web.status.players": "玩家",
|
"playertime.web.status.players": "玩家",
|
||||||
@ -63,5 +63,17 @@
|
|||||||
|
|
||||||
"playertime.web.error.load_failed": "加载数据失败,请检查控制台",
|
"playertime.web.error.load_failed": "加载数据失败,请检查控制台",
|
||||||
|
|
||||||
"playertime.web.footer.license": "本项目基于 GPL3许可证 开源"
|
"playertime.web.footer.license": "本项目基于 GPL3许可证 开源",
|
||||||
|
|
||||||
|
"title.playertime.config": "玩家在线时长配置",
|
||||||
|
"category.playertime.general": "通用设置",
|
||||||
|
"option.playertime.webPort": "Web服务器端口",
|
||||||
|
"tooltip.playertime.webPort": "Web服务器的端口(默认:60048)",
|
||||||
|
"option.playertime.language": "语言",
|
||||||
|
"tooltip.playertime.language": "模组的显示语言",
|
||||||
|
"option.playertime.whitelistOnly": "仅记录白名单",
|
||||||
|
"tooltip.playertime.whitelistOnly": "只记录白名单上的玩家",
|
||||||
|
"option.playertime.saveIntervalMinutes": "保存间隔(分钟)",
|
||||||
|
"tooltip.playertime.saveIntervalMinutes": "自动保存数据的时间间隔",
|
||||||
|
"playertime.web.warning.whitelist_disabled": "警告:配置为仅记录白名单玩家,但服务端未启用白名单功能。非白名单玩家将被视为假人。"
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
--border-color: #e9ecef;
|
--border-color: #e9ecef;
|
||||||
--hover-bg: #f1f3f5;
|
--hover-bg: #f1f3f5;
|
||||||
--success-color: #4CAF50;
|
--success-color: #4CAF50;
|
||||||
--warning-color: #FFC107;
|
--warning-color: #bf9107;
|
||||||
|
--note-color: #3a56d4;
|
||||||
--danger-color: #FF5722;
|
--danger-color: #FF5722;
|
||||||
|
|
||||||
--accent-blue: #4361ee;
|
--accent-blue: #4361ee;
|
||||||
@ -49,6 +50,7 @@
|
|||||||
--hover-bg: #2d2d2d;
|
--hover-bg: #2d2d2d;
|
||||||
--success-color: #66BB6A;
|
--success-color: #66BB6A;
|
||||||
--warning-color: #FFEE58;
|
--warning-color: #FFEE58;
|
||||||
|
--note-color: #4d79cf;
|
||||||
--danger-color: #FF8A65;
|
--danger-color: #FF8A65;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +196,12 @@ body {
|
|||||||
border-left: 4px solid var(--warning-color);
|
border-left: 4px solid var(--warning-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.notification.note {
|
||||||
|
background-color: rgba(7, 197, 255, 0.1);
|
||||||
|
color: var(--note-color);
|
||||||
|
border-left: 4px solid var(--note-color);
|
||||||
|
}
|
||||||
|
|
||||||
.stats-grid {
|
.stats-grid {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||||
|
Binary file not shown.
Before Width: | Height: | Size: 40 KiB |
BIN
src/main/resources/assets/playertime/web/icon.ico
Normal file
BIN
src/main/resources/assets/playertime/web/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 330 KiB |
@ -6,7 +6,7 @@
|
|||||||
<title data-lang-key="playertime.web.title">玩家在线及状态统计</title>
|
<title data-lang-key="playertime.web.title">玩家在线及状态统计</title>
|
||||||
<link rel="stylesheet" href="css/style.css">
|
<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="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">
|
<link rel="icon" href="icon.ico" type="image/x-icon">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||||
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/chartjs-adapter-date-fns/dist/chartjs-adapter-date-fns.bundle.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
@ -29,9 +29,12 @@
|
|||||||
|
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<!-- 警告信息 -->
|
<!-- 警告信息 -->
|
||||||
<div class="notification warning" data-lang-key="playertime.web.warning">
|
<div class="notification note" data-lang-key="playertime.web.warning">
|
||||||
<i class="fas fa-exclamation-circle"></i>
|
<i class="fas fa-exclamation-circle"></i>
|
||||||
<span>数据统计时间开始于此MOD安装时间,不包含安装之前的所有数据</span>
|
<span>注意:数据统计时间开始于此MOD安装时间,不包含安装之前的所有数据</span>
|
||||||
|
</div>
|
||||||
|
<div class="notification warning" id="whitelist-warning" style="display: none;">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 在线玩家卡片 -->
|
<!-- 在线玩家卡片 -->
|
||||||
|
@ -165,6 +165,9 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
updatePlayerCounts(playerCountsData);
|
updatePlayerCounts(playerCountsData);
|
||||||
updateServerStatus(serverStatusData);
|
updateServerStatus(serverStatusData);
|
||||||
|
|
||||||
|
if (serverStatusData.configWhitelistOnly && !serverStatusData.serverWhitelistEnabled) {
|
||||||
|
showWarning(getLangString('playertime.web.warning.whitelist_disabled'));
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('加载数据出错:', error);
|
console.error('加载数据出错:', error);
|
||||||
showError(getLangString('playertime.web.error.load_failed'));
|
showError(getLangString('playertime.web.error.load_failed'));
|
||||||
@ -586,4 +589,15 @@ document.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
element.style.color = color;
|
element.style.color = color;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showWarning(message) {
|
||||||
|
const warningEl = document.getElementById('whitelist-warning');
|
||||||
|
if (!warningEl) return;
|
||||||
|
|
||||||
|
warningEl.innerHTML = `
|
||||||
|
<i class="fas fa-exclamation-triangle"></i>
|
||||||
|
<span>${message}</span>
|
||||||
|
`;
|
||||||
|
warningEl.style.display = 'block';
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
@ -11,17 +11,25 @@
|
|||||||
"homepage": "https://git.branulf.top/Branulf",
|
"homepage": "https://git.branulf.top/Branulf",
|
||||||
"sources": "https://git.branulf.top/Branulf/ServerPlayerOnlineTracker"
|
"sources": "https://git.branulf.top/Branulf/ServerPlayerOnlineTracker"
|
||||||
},
|
},
|
||||||
"icon": "assets/playertime/icon540.png",
|
"icon": "assets/playertime/icon.ico",
|
||||||
"license": "GPL3",
|
"license": "GPL3",
|
||||||
"environment": "server",
|
"environment": "*",
|
||||||
"entrypoints": {
|
"entrypoints": {
|
||||||
"main": [
|
"main": [
|
||||||
"org.branulf.playertime.PlayerTimeMod"
|
"org.branulf.playertime.PlayerTimeMod"
|
||||||
|
],
|
||||||
|
"client": [
|
||||||
|
"org.branulf.playertime.PlayerTimeModClient"
|
||||||
|
],
|
||||||
|
"modmenu": [
|
||||||
|
"org.branulf.playertime.ModMenuIntegration"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"depends": {
|
"depends": {
|
||||||
"fabricloader": ">=${loader_version}",
|
"fabricloader": ">=${loader_version}",
|
||||||
"fabric": "*",
|
"fabric": "*",
|
||||||
"minecraft": "${minecraft_version}"
|
"minecraft": "${minecraft_version}",
|
||||||
|
"cloth-config": "*",
|
||||||
|
"modmenu": "*"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1 +0,0 @@
|
|||||||
public field net/minecraft/server/MinecraftServer workerExecutor Ljava/util/concurrent/Executor;
|
|
@ -6,3 +6,6 @@ minecraft_dependency=1.21.4
|
|||||||
game_versions=1.21.4
|
game_versions=1.21.4
|
||||||
|
|
||||||
fabric_api_version=0.119.2+1.21.4
|
fabric_api_version=0.119.2+1.21.4
|
||||||
|
|
||||||
|
modmenu_version=13.0.3
|
||||||
|
cloth_config_version=17.0.144
|
||||||
|
@ -6,3 +6,7 @@ minecraft_dependency=1.21.5
|
|||||||
game_versions=1.21.5
|
game_versions=1.21.5
|
||||||
|
|
||||||
fabric_api_version=0.119.5+1.21.5
|
fabric_api_version=0.119.5+1.21.5
|
||||||
|
|
||||||
|
modmenu_version=14.0.0-rc.2
|
||||||
|
cloth_config_version=18.0.145
|
||||||
|
|
||||||
|
@ -6,3 +6,6 @@ minecraft_dependency=1.21.6
|
|||||||
game_versions=1.21.6
|
game_versions=1.21.6
|
||||||
|
|
||||||
fabric_api_version=0.127.0+1.21.6
|
fabric_api_version=0.127.0+1.21.6
|
||||||
|
|
||||||
|
modmenu_version=15.0.0-beta.3
|
||||||
|
cloth_config_version=19.0.147
|
||||||
|
@ -6,3 +6,6 @@ minecraft_dependency=1.21.7
|
|||||||
game_versions=1.21.7
|
game_versions=1.21.7
|
||||||
|
|
||||||
fabric_api_version=0.128.1+1.21.7
|
fabric_api_version=0.128.1+1.21.7
|
||||||
|
|
||||||
|
modmenu_version=15.0.0-beta.3
|
||||||
|
cloth_config_version=19.0.147
|
11
versions/1.21.8/gradle.properties
Normal file
11
versions/1.21.8/gradle.properties
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
minecraft_version=1.21.8
|
||||||
|
yarn_mappings=1.21.8+build.1
|
||||||
|
|
||||||
|
minecraft_dependency=1.21.8
|
||||||
|
|
||||||
|
game_versions=1.21.8
|
||||||
|
|
||||||
|
fabric_api_version=0.129.0+1.21.8
|
||||||
|
|
||||||
|
modmenu_version=15.0.0-beta.3
|
||||||
|
cloth_config_version=19.0.147
|
0
versions/mapping_12108_12107.txt
Normal file
0
versions/mapping_12108_12107.txt
Normal file
Loading…
x
Reference in New Issue
Block a user