Add mod state in console

This commit is contained in:
Darto KLoning
2026-09-06 14:28:45 +07:00
parent 7c747f9036
commit ecc67d99ae
10 changed files with 689 additions and 329 deletions
@@ -27,12 +27,15 @@ public final class LegacyConfigMigrator {
Files.createDirectories(target.getParent());
Files.move(source, target, StandardCopyOption.REPLACE_EXISTING);
LobbySystemsMod.LOGGER.info("Migrated legacy {}: {} -> {}", label, source, target);
LobbyLog.state("LEGACY CONFIG MIGRATED", "Type: " + label, "From: " + source, "To: " + target);
} catch (Exception moveError) {
try {
Files.copy(source, target, StandardCopyOption.REPLACE_EXISTING);
LobbySystemsMod.LOGGER.info("Copied legacy {}: {} -> {}", label, source, target);
LobbyLog.state("LEGACY CONFIG COPIED", "Type: " + label, "From: " + source, "To: " + target);
} catch (Exception copyError) {
LobbySystemsMod.LOGGER.error("Failed to migrate legacy {} from {} to {}", label, source, target, copyError);
LobbyLog.state("LEGACY MIGRATION FAILED", "Type: " + label, "From: " + source, "To: " + target);
}
}
}
@@ -0,0 +1,46 @@
package id.dartokloning.lobbysystems;
import net.fabricmc.loader.api.FabricLoader;
/**
* Logger visual untuk state penting Lobby Systems.
* Separator sengaja dipakai agar state mod mudah terlihat di console server.
*/
public final class LobbyLog {
private static final String SEPARATOR = "============================================";
private LobbyLog() {}
public static String modVersion() {
return FabricLoader.getInstance()
.getModContainer(LobbySystemsMod.MOD_ID)
.map(container -> container.getMetadata().getVersion().getFriendlyString())
.orElse("unknown");
}
public static String minecraftVersion() {
return FabricLoader.getInstance()
.getModContainer("minecraft")
.map(container -> container.getMetadata().getVersion().getFriendlyString())
.orElse("unknown");
}
public static void state(String title, String... details) {
LobbySystemsMod.LOGGER.info(SEPARATOR);
LobbySystemsMod.LOGGER.info(" Lobby Systems - {}", title);
for (String detail : details) {
LobbySystemsMod.LOGGER.info(" {}", detail);
}
LobbySystemsMod.LOGGER.info(SEPARATOR);
}
public static void startup() {
state(
"STARTING",
"Version: " + modVersion(),
"Minecraft: " + minecraftVersion(),
"Namespace: id.dartokloning.lobbysystems",
"Mod ID: " + LobbySystemsMod.MOD_ID
);
}
}
@@ -1,7 +1,6 @@
package id.dartokloning.lobbysystems;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.logging.LogUtils;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerTickEvents;
@@ -19,10 +18,11 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.level.Level;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public final class LobbySystemsMod implements ModInitializer {
public static final String MOD_ID = "dartokloning";
public static final Logger LOGGER = LogUtils.getLogger();
public static final Logger LOGGER = LoggerFactory.getLogger("Lobby Systems");
private static final ConfigManager CONFIG = new ConfigManager();
private static final SessionTracker SESSIONS = new SessionTracker();
@@ -33,18 +33,43 @@ public final class LobbySystemsMod implements ModInitializer {
@Override
public void onInitialize() {
LobbyLog.startup();
LegacyConfigMigrator.migrate();
CONFIG.load();
boolean configLoaded = CONFIG.load();
LobbyLog.state(
configLoaded ? "CONFIG LOADED" : "CONFIG LOAD FAILED",
"File: " + CONFIG.path(),
"Lobby dimension: " + CONFIG.get().lobbyDimension
);
POSITIONS.load();
POSITIONS.setExcludedDimension(lobbyKey());
PORTALS.load();
LobbyLog.state(
"PLAYER POSITIONS READY",
"File: " + ConfigPaths.PLAYER_POSITIONS,
"Lobby persistence: excluded"
);
boolean portalsLoaded = PORTALS.load();
LobbyLog.state(
portalsLoaded ? "PORTALS LOADED" : "PORTAL LOAD FAILED",
"File: " + ConfigPaths.PORTALS,
"Portals: " + PORTALS.size()
);
ServerPlayConnectionEvents.JOIN.register((listener, sender, server) -> {
ServerPlayer player = listener.getPlayer();
server.execute(() -> {
POSITIONS.captureCurrent(player);
TELEPORTS.scheduleJoinToLobby(player);
LOGGER.info("Scheduled lobby login teleport for {} ({})", player.getName().getString(), player.getUUID());
LobbyLog.state(
"PLAYER JOIN",
"Player: " + player.getName().getString(),
"UUID: " + player.getUUID(),
"Lobby teleport: scheduled"
);
});
});
@@ -54,6 +79,12 @@ public final class LobbySystemsMod implements ModInitializer {
SESSIONS.onDisconnect(player.getUUID());
TELEPORTS.onDisconnect(player.getUUID());
PORTALS.onDisconnect(player.getUUID());
LobbyLog.state(
"PLAYER DISCONNECT",
"Player: " + player.getName().getString(),
"UUID: " + player.getUUID(),
"Session state: saved/cleared"
);
});
ServerTickEvents.END_SERVER_TICK.register(server -> {
@@ -128,8 +159,15 @@ public final class LobbySystemsMod implements ModInitializer {
);
});
LOGGER.info("Lobby Systems v1.2.0 initialized for Minecraft 26.2. Config directory: {}", ConfigPaths.DIRECTORY);
LOGGER.info("WorldEdit integration: {}", WorldEditSelectionBridge.isAvailable() ? "available" : "not installed (saved portals still work)");
LobbyLog.state(
"READY",
"Version: " + LobbyLog.modVersion(),
"Minecraft: " + LobbyLog.minecraftVersion(),
"Config directory: " + ConfigPaths.DIRECTORY,
"WorldEdit: " + (WorldEditSelectionBridge.isAvailable()
? "available"
: "not installed (saved portals still work)")
);
}
private static int handleLobbyCommand(ServerPlayer player, MinecraftServer server) {
@@ -154,7 +192,14 @@ public final class LobbySystemsMod implements ModInitializer {
}
private static int reloadAll(MinecraftServer server, CommandSourceStack source) {
LobbyLog.state(
"RELOAD START",
"Config: " + ConfigPaths.CONFIG,
"Portals: " + ConfigPaths.PORTALS
);
if (!CONFIG.load()) {
LobbyLog.state("RELOAD FAILED", "Reason: config.json gagal dibaca");
source.sendFailure(Component.literal("§cLobby Systems: reload config gagal. Cek console untuk detail JSON."));
return 0;
}
@@ -164,10 +209,12 @@ public final class LobbySystemsMod implements ModInitializer {
key = lobbyKey();
if (server.getLevel(key) == null) {
source.sendFailure(Component.literal("§eConfig terbaca, tetapi lobbyDimension '" + CONFIG.get().lobbyDimension + "' tidak sedang ter-load."));
LobbyLog.state("RELOAD FAILED", "Reason: lobby dimension tidak ter-load", "Lobby: " + CONFIG.get().lobbyDimension);
return 0;
}
} catch (Exception e) {
source.sendFailure(Component.literal("§cConfig terbaca, tetapi lobbyDimension tidak valid: " + CONFIG.get().lobbyDimension));
LobbyLog.state("RELOAD FAILED", "Reason: lobbyDimension tidak valid", "Lobby: " + CONFIG.get().lobbyDimension);
return 0;
}
@@ -175,6 +222,7 @@ public final class LobbySystemsMod implements ModInitializer {
boolean portalOk = PORTALS.load();
if (!portalOk) {
source.sendFailure(Component.literal("§eConfig utama direload, tetapi portals.json bermasalah. Cek console."));
LobbyLog.state("RELOAD FAILED", "Reason: portals.json gagal dibaca");
return 0;
}
@@ -182,6 +230,13 @@ public final class LobbySystemsMod implements ModInitializer {
"§aLobby Systems direload. §7Lobby: §f" + CONFIG.get().lobbyDimension
+ " §7| Minimum play: §f" + CONFIG.get().minimumPlaySeconds + "s"
+ " §7| Portals: §f" + PORTALS.size()), false);
LobbyLog.state(
"RELOAD COMPLETE",
"Lobby: " + CONFIG.get().lobbyDimension,
"Minimum play: " + CONFIG.get().minimumPlaySeconds + "s",
"Portals: " + PORTALS.size(),
"Player positions lobby exclusion: active"
);
return 1;
}
@@ -218,6 +273,12 @@ public final class LobbySystemsMod implements ModInitializer {
PORTALS.suppress(player.getUUID(), Math.max(CONFIG.get().portalCooldownTicks, 100));
player.sendSystemMessage(Component.literal(
"§aPortal §f" + name + "§a dibuat. §7" + portal.sourceDimension + " §8→ §f" + targetId));
LobbyLog.state(
"PORTAL CREATED",
"Name: " + name,
"Source: " + portal.sourceDimension,
"Target: " + targetId
);
return 1;
} catch (Exception e) {
LOGGER.warn("Failed to read WorldEdit selection for {}", player.getUUID(), e);
@@ -233,6 +294,7 @@ public final class LobbySystemsMod implements ModInitializer {
return 0;
}
source.sendSuccess(() -> Component.literal("§aPortal §f" + key + "§a dihapus."), false);
LobbyLog.state("PORTAL DELETED", "Name: " + key);
return 1;
}
@@ -83,17 +83,26 @@ public final class TeleportCoordinator {
TeleportTransition.DO_NOTHING
);
LobbySystemsMod.LOGGER.info(
"Teleporting {} ({}): {} -> {} @ [{}, {}, {}]",
player.getName().getString(), player.getUUID(),
from.identifier(), to.identifier(),
String.format("%.2f", x), String.format("%.2f", y), String.format("%.2f", z)
LobbyLog.state(
"TELEPORT",
"Player: " + player.getName().getString() + " (" + player.getUUID() + ")",
"From: " + from.identifier(),
"To: " + to.identifier(),
"Position: [" + String.format("%.2f", x) + ", "
+ String.format("%.2f", y) + ", "
+ String.format("%.2f", z) + "]"
);
ServerPlayer result = player.teleport(transition);
if (result == null) {
lockedUntilTick.remove(player.getUUID());
LobbySystemsMod.LOGGER.warn("Teleport failed for {}: {} -> {}", player.getUUID(), from.identifier(), to.identifier());
LobbyLog.state(
"TELEPORT FAILED",
"Player: " + player.getName().getString() + " (" + player.getUUID() + ")",
"From: " + from.identifier(),
"To: " + to.identifier()
);
return false;
}