From fb4719187abe82136643906ccf947ffd5c9e3a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Thu, 22 Aug 2024 22:45:00 +0200 Subject: feat: support translation to enable configuration of all mod strings. --- src/client/resources/assets/molehunt/lang/en_us.json | 15 +++++++++++++++ src/main/java/world/anhgelus/molehunt/Game.java | 18 +++++++++--------- src/main/java/world/anhgelus/molehunt/Molehunt.java | 16 +++++++++------- 3 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 src/client/resources/assets/molehunt/lang/en_us.json diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json new file mode 100644 index 0000000..d68fd0e --- /dev/null +++ b/src/client/resources/assets/molehunt/lang/en_us.json @@ -0,0 +1,15 @@ +{ + "commands.molehunt.stop.failed": "The Molehunt game has not been started yet.", + "commands.molehunt.timer.show": "Showing Molehunt timer.", + "commands.molehunt.timer.hide": "Hiding Molehunt timer.", + "commands.molehunt.moles.list": "List of moles:", + "commands.molehunt.stop.success": "The Molehunt game has been stopped.", + "molehunt.game.end.suspense.title": "And the winners are...", + "molehunt.game.end.winners.moles.title": "§cThe Moles!", + "molehunt.game.end.winners.survivors.title": "§aThe survivors!", + "molehunt.game.end.winners.subtitle": "The moles were", + "molehunt.game.start.suspense": "You are...", + "molehunt.game.start.mole.title": "§cThe Mole!", + "molehunt.game.start.mole.subtitle": "Get the list of moles with §6/molehunt moles", + "molehunt.game.start.survivor": "§aNot the Mole!" +} \ No newline at end of file diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 9c3910b..c680a8f 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -53,7 +53,7 @@ public class Game { gamerules.get(GameRules.DO_IMMEDIATE_RESPAWN).set(true, server); gamerules.get(GameRules.DO_ENTITY_DROPS).set(false, server); - final var title = new TitleS2CPacket(Text.of("You are...")); + final var title = new TitleS2CPacket(Text.translatable("molehunt.game.start.suspense")); playerManager.getPlayerList().forEach(p -> { p.kill(); p.networkHandler.sendPacket(timing); @@ -69,10 +69,10 @@ public class Game { playerManager.getPlayerList().forEach(p -> { p.networkHandler.sendPacket(timing); if (moles.contains(p)) { - p.networkHandler.sendPacket(new TitleS2CPacket(Text.of("The Mole!"))); - p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.of("Get the list of moles with /molehunt moles"))); + p.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("molehunt.game.start.mole.title"))); + p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("molehunt.game.start.mole.subtitle"))); } else { - p.networkHandler.sendPacket(new TitleS2CPacket(Text.of("Not the Mole!"))); + p.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("molehunt.game.start.survivor"))); } // reset health and food level p.setHealth(p.getMaxHealth()); @@ -110,7 +110,7 @@ public class Game { } public void stop() { - server.getPlayerManager().broadcast(Text.of("Game stopped"), false); + server.getPlayerManager().broadcast(Text.translatable("commands.molehunt.stop.success"), false); end(); } @@ -119,7 +119,7 @@ public class Game { timer = new Timer(); started = false; final var pm = server.getPlayerManager(); - final var winnerSuspense = new TitleS2CPacket(Text.of("And the winners are...")); + final var winnerSuspense = new TitleS2CPacket(Text.translatable("molehunt.game.end.suspense.title")); pm.getPlayerList().forEach(p -> { p.networkHandler.sendPacket(timing); p.networkHandler.sendPacket(winnerSuspense); @@ -130,11 +130,11 @@ public class Game { public void run() { TitleS2CPacket winner; if (gameWonByMoles()) { - winner = new TitleS2CPacket(Text.of("The Moles!")); + winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.moles.title")); } else { - winner = new TitleS2CPacket(Text.of("The survivors!")); + winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.survivors.title")); } - pm.sendToAll(new SubtitleS2CPacket(Text.of("The moles were " + getMolesAsString()))); + pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle").append(getMolesAsString()))); pm.sendToAll(winner); pm.sendToAll(timing); } diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 49e775d..b2d3842 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -1,6 +1,7 @@ package world.anhgelus.molehunt; import com.mojang.brigadier.Command; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; @@ -9,7 +10,7 @@ import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; import net.minecraft.network.packet.s2c.play.OverlayMessageS2CPacket; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.Text; +import net.minecraft.text.*; import net.minecraft.world.GameMode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,13 +45,13 @@ public class Molehunt implements ModInitializer { command.then(literal("timer").requires(ServerCommandSource::isExecutedByPlayer).then( literal("show").executes(context -> { timerVisibility.put(context.getSource().getPlayer(), true); - context.getSource().sendFeedback(() -> Text.of("Showing molehunt timer"), false); + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.show"), false); var player = context.getSource().getPlayer(); assert player != null; if (game == null || !game.hasStarted()) { - player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of("§cGame has not started yet"))); + player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.translatable("commands.molehunt.stop.failed").setStyle(Style.EMPTY.withColor(16733525)))); } else { player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(game.getShortRemainingText()))); } @@ -60,18 +61,19 @@ public class Molehunt implements ModInitializer { ).then( literal("hide").executes(context -> { timerVisibility.put(context.getSource().getPlayer(), false); - context.getSource().sendFeedback(() -> Text.of("Hiding molehunt timer"), false); + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.hide"), false); return Command.SINGLE_SUCCESS; }) )); command.then(literal("moles").requires(source -> (game != null) && game.hasStarted() && game.isAMole(source.getPlayer())).executes(context -> { - context.getSource().sendFeedback(() -> Text.literal("List of moles: " + game.getMolesAsString()),false); + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.moles.list").append(" " + game.getMolesAsString()),false); return Command.SINGLE_SUCCESS; })); command.then(literal("stop").requires(source -> source.hasPermissionLevel(1)).executes(context -> { if (game == null || !game.hasStarted()) { - context.getSource().sendError(Text.of("Game has not started yet")); - return Command.SINGLE_SUCCESS; + var e = new SimpleCommandExceptionType(Text.translatable("commands.molehunt.stop.failed")); + + throw e.create(); } game.stop(); -- cgit v1.2.3 From c74eeb19ff9d8c6472588dc88fa672a764ec8078 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Thu, 22 Aug 2024 22:48:28 +0200 Subject: docs: add translation feature in readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 06c25bd..b3084ed 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ Stop the game when every innocent is dead or when the timer ended (one hour and The moles can see the name of other moles with `/molehunt moles`. +You can configure every text with a resource pack (for reference, check out [the default lang file](src/client/resources/assets/molehunt/lang/en_us.json)). + ## Technologies - Java 21 -- cgit v1.2.3 From 06f970b1bdb370afd38d321ec6225f47b6cf3d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Thu, 22 Aug 2024 22:45:00 +0200 Subject: feat: support translation to enable configuration of all mod strings. --- .../resources/assets/molehunt/lang/en_us.json | 15 +++++++++++++ src/main/java/world/anhgelus/molehunt/Game.java | 26 +++++++++------------- .../java/world/anhgelus/molehunt/Molehunt.java | 16 +++++++------ 3 files changed, 34 insertions(+), 23 deletions(-) create mode 100644 src/client/resources/assets/molehunt/lang/en_us.json diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json new file mode 100644 index 0000000..d68fd0e --- /dev/null +++ b/src/client/resources/assets/molehunt/lang/en_us.json @@ -0,0 +1,15 @@ +{ + "commands.molehunt.stop.failed": "The Molehunt game has not been started yet.", + "commands.molehunt.timer.show": "Showing Molehunt timer.", + "commands.molehunt.timer.hide": "Hiding Molehunt timer.", + "commands.molehunt.moles.list": "List of moles:", + "commands.molehunt.stop.success": "The Molehunt game has been stopped.", + "molehunt.game.end.suspense.title": "And the winners are...", + "molehunt.game.end.winners.moles.title": "§cThe Moles!", + "molehunt.game.end.winners.survivors.title": "§aThe survivors!", + "molehunt.game.end.winners.subtitle": "The moles were", + "molehunt.game.start.suspense": "You are...", + "molehunt.game.start.mole.title": "§cThe Mole!", + "molehunt.game.start.mole.subtitle": "Get the list of moles with §6/molehunt moles", + "molehunt.game.start.survivor": "§aNot the Mole!" +} \ No newline at end of file diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index bf0f294..1091c0f 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -7,7 +7,6 @@ import net.minecraft.network.packet.s2c.play.TitleS2CPacket; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; -import net.minecraft.text.TextContent; import net.minecraft.world.GameMode; import net.minecraft.world.GameRules; import world.anhgelus.molehunt.utils.TimeUtils; @@ -35,10 +34,9 @@ public class Game { } public void start() { - if (started) return; final int n = (server.getCurrentPlayerCount() - server.getCurrentPlayerCount() % 4)/4; final var playerManager = server.getPlayerManager(); - final var players = new ArrayList<>(playerManager.getPlayerList()); + final var players = playerManager.getPlayerList(); for (int i = 0; i < n; i++) { final var r = ThreadLocalRandom.current().nextInt(0, players.size()); final var mole = players.get(r); @@ -71,10 +69,10 @@ public class Game { playerManager.getPlayerList().forEach(p -> { p.networkHandler.sendPacket(timing); if (moles.contains(p)) { - p.networkHandler.sendPacket(new TitleS2CPacket(Text.of("§cThe Mole!"))); - p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.of("§6get the list of moles with /molehunt moles"))); + p.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("molehunt.game.start.mole.title"))); + p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("molehunt.game.start.mole.subtitle"))); } else { - p.networkHandler.sendPacket(new TitleS2CPacket(Text.of("§aNot the Mole!"))); + p.networkHandler.sendPacket(new TitleS2CPacket(Text.translatable("molehunt.game.start.survivor"))); } // reset health and food level p.setHealth(p.getMaxHealth()); @@ -112,7 +110,7 @@ public class Game { } public void stop() { - server.getPlayerManager().broadcast(Text.of("Game stopped"), false); + server.getPlayerManager().broadcast(Text.translatable("commands.molehunt.stop.success"), false); end(); } @@ -121,7 +119,7 @@ public class Game { timer = new Timer(); started = false; final var pm = server.getPlayerManager(); - final var winnerSuspense = new TitleS2CPacket(Text.of("§eAnd the winners are...")); + final var winnerSuspense = new TitleS2CPacket(Text.translatable("molehunt.game.end.suspense.title")); pm.getPlayerList().forEach(p -> { p.networkHandler.sendPacket(timing); p.networkHandler.sendPacket(winnerSuspense); @@ -132,11 +130,11 @@ public class Game { public void run() { TitleS2CPacket winner; if (gameWonByMoles()) { - winner = new TitleS2CPacket(Text.of("§cThe Moles!")); + winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.moles.title")); } else { - winner = new TitleS2CPacket(Text.of("§aNot the Mole!")); + winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.survivors.title")); } - pm.sendToAll(new SubtitleS2CPacket(Text.of("§6Moles were " + getMolesAsString()))); + pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle").append(getMolesAsString()))); pm.sendToAll(winner); pm.sendToAll(timing); } @@ -160,11 +158,7 @@ public class Game { } public String getMolesAsString() { - return moles.stream() - .map(ServerPlayerEntity::getDisplayName) - .filter(Objects::nonNull) - .map(Text::getString) - .collect(Collectors.joining(", ")); + return moles.stream().map(ServerPlayerEntity::getDisplayName).filter(Objects::nonNull).map(Text::toString).collect(Collectors.joining(", ")); } public boolean isAMole(ServerPlayerEntity player) { diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 49e775d..b2d3842 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -1,6 +1,7 @@ package world.anhgelus.molehunt; import com.mojang.brigadier.Command; +import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; @@ -9,7 +10,7 @@ import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; import net.minecraft.network.packet.s2c.play.OverlayMessageS2CPacket; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.Text; +import net.minecraft.text.*; import net.minecraft.world.GameMode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -44,13 +45,13 @@ public class Molehunt implements ModInitializer { command.then(literal("timer").requires(ServerCommandSource::isExecutedByPlayer).then( literal("show").executes(context -> { timerVisibility.put(context.getSource().getPlayer(), true); - context.getSource().sendFeedback(() -> Text.of("Showing molehunt timer"), false); + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.show"), false); var player = context.getSource().getPlayer(); assert player != null; if (game == null || !game.hasStarted()) { - player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of("§cGame has not started yet"))); + player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.translatable("commands.molehunt.stop.failed").setStyle(Style.EMPTY.withColor(16733525)))); } else { player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(game.getShortRemainingText()))); } @@ -60,18 +61,19 @@ public class Molehunt implements ModInitializer { ).then( literal("hide").executes(context -> { timerVisibility.put(context.getSource().getPlayer(), false); - context.getSource().sendFeedback(() -> Text.of("Hiding molehunt timer"), false); + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.hide"), false); return Command.SINGLE_SUCCESS; }) )); command.then(literal("moles").requires(source -> (game != null) && game.hasStarted() && game.isAMole(source.getPlayer())).executes(context -> { - context.getSource().sendFeedback(() -> Text.literal("List of moles: " + game.getMolesAsString()),false); + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.moles.list").append(" " + game.getMolesAsString()),false); return Command.SINGLE_SUCCESS; })); command.then(literal("stop").requires(source -> source.hasPermissionLevel(1)).executes(context -> { if (game == null || !game.hasStarted()) { - context.getSource().sendError(Text.of("Game has not started yet")); - return Command.SINGLE_SUCCESS; + var e = new SimpleCommandExceptionType(Text.translatable("commands.molehunt.stop.failed")); + + throw e.create(); } game.stop(); -- cgit v1.2.3 From 29e19bca3f4b1f7b6e2e9ea35ab72bc62c4c4868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Thu, 22 Aug 2024 22:48:28 +0200 Subject: docs: add translation feature in readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 06c25bd..b3084ed 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ Stop the game when every innocent is dead or when the timer ended (one hour and The moles can see the name of other moles with `/molehunt moles`. +You can configure every text with a resource pack (for reference, check out [the default lang file](src/client/resources/assets/molehunt/lang/en_us.json)). + ## Technologies - Java 21 -- cgit v1.2.3 From ecfc9f0d622672fbdccce80583eab7974cc4cc15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Thu, 22 Aug 2024 23:04:28 +0200 Subject: fix: bad merging --- src/main/java/world/anhgelus/molehunt/Game.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 10ef74e..c680a8f 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -53,7 +53,6 @@ public class Game { gamerules.get(GameRules.DO_IMMEDIATE_RESPAWN).set(true, server); gamerules.get(GameRules.DO_ENTITY_DROPS).set(false, server); - final var title = new TitleS2CPacket(Text.of("§eYou are...")); final var title = new TitleS2CPacket(Text.translatable("molehunt.game.start.suspense")); playerManager.getPlayerList().forEach(p -> { p.kill(); -- cgit v1.2.3 From 67e912c50efd23228932b011676ec128aedf58bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Fri, 23 Aug 2024 12:05:59 +0200 Subject: style: add more colors to text --- src/client/resources/assets/molehunt/lang/en_us.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json index d68fd0e..63ac06d 100644 --- a/src/client/resources/assets/molehunt/lang/en_us.json +++ b/src/client/resources/assets/molehunt/lang/en_us.json @@ -4,12 +4,12 @@ "commands.molehunt.timer.hide": "Hiding Molehunt timer.", "commands.molehunt.moles.list": "List of moles:", "commands.molehunt.stop.success": "The Molehunt game has been stopped.", - "molehunt.game.end.suspense.title": "And the winners are...", + "molehunt.game.end.suspense.title": "§eAnd the winners are...", "molehunt.game.end.winners.moles.title": "§cThe Moles!", - "molehunt.game.end.winners.survivors.title": "§aThe survivors!", - "molehunt.game.end.winners.subtitle": "The moles were", - "molehunt.game.start.suspense": "You are...", + "molehunt.game.end.winners.survivors.title": "§aNot the Moles!", + "molehunt.game.end.winners.subtitle": "§6The moles were", + "molehunt.game.start.suspense": "§eYou are...", "molehunt.game.start.mole.title": "§cThe Mole!", - "molehunt.game.start.mole.subtitle": "Get the list of moles with §6/molehunt moles", + "molehunt.game.start.mole.subtitle": "§eGet the list of moles with §6/molehunt moles", "molehunt.game.start.survivor": "§aNot the Mole!" } \ No newline at end of file -- cgit v1.2.3 From 2ec447626c1b87a74cb3201ecc5407ee3f447cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Fri, 23 Aug 2024 13:07:31 +0200 Subject: feat: add config file --- README.md | 6 +- src/main/java/world/anhgelus/molehunt/Game.java | 15 +- .../java/world/anhgelus/molehunt/Molehunt.java | 4 + .../world/anhgelus/molehunt/config/Config.java | 38 ++++ .../anhgelus/molehunt/config/SimpleConfig.java | 252 +++++++++++++++++++++ 5 files changed, 312 insertions(+), 3 deletions(-) create mode 100644 src/main/java/world/anhgelus/molehunt/config/Config.java create mode 100644 src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java diff --git a/README.md b/README.md index b3084ed..401b81f 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,11 @@ Stop the game when every innocent is dead or when the timer ended (one hour and The moles can see the name of other moles with `/molehunt moles`. -You can configure every text with a resource pack (for reference, check out [the default lang file](src/client/resources/assets/molehunt/lang/en_us.json)). +You can configure every text line and the skin with a resource pack (for reference, check out +[the default lang file](src/client/resources/assets/molehunt/lang/en_us.json) and [the default +skin file](src/client/resources/assets/molehunt/textures/skin.png)). + +Also, more server-side values can be changed in the configuration file, located in your server config directory. ## Technologies diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index c680a8f..3092bc9 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -18,7 +18,7 @@ import java.util.stream.Collectors; public class Game { private Timer timer = new Timer(); - public final static int DEFAULT_TIME = 90*60; // 1:30 + public final static int DEFAULT_TIME = Molehunt.CONFIG.GAME_DURATION; private int remaining = DEFAULT_TIME; private final MinecraftServer server; @@ -34,10 +34,21 @@ public class Game { } public void start() { - final int n = (server.getCurrentPlayerCount() - server.getCurrentPlayerCount() % 4)/4; + final int n; + if (Molehunt.CONFIG.MOLE_COUNT < 0) { + n = Math.floorDiv(server.getCurrentPlayerCount(), Math.floorDiv(100, (int) Molehunt.CONFIG.MOLE_PERCENTAGE)); + } else { + n = Molehunt.CONFIG.MOLE_COUNT; + } +// final int n = (server.getCurrentPlayerCount() - server.getCurrentPlayerCount() % 4)/4; + final var playerManager = server.getPlayerManager(); + final var players = playerManager.getPlayerList(); for (int i = 0; i < n; i++) { + // Can happen if the mole count is greater than the player count + if (players.isEmpty()) break; + final var r = ThreadLocalRandom.current().nextInt(0, players.size()); final var mole = players.get(r); if (mole == null) throw new IllegalStateException("Mole is null!"); diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index b2d3842..078afa6 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -14,6 +14,7 @@ import net.minecraft.text.*; import net.minecraft.world.GameMode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import world.anhgelus.molehunt.config.Config; import java.util.HashMap; @@ -24,6 +25,8 @@ public class Molehunt implements ModInitializer { public static final String MOD_ID = "molehunt"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + public static final Config CONFIG = new Config(MOD_ID); + public Game game; public static HashMap timerVisibility = new HashMap<>(); @@ -31,6 +34,7 @@ public class Molehunt implements ModInitializer { @Override public void onInitialize() { LOGGER.info("Initializing Molehunt"); + LOGGER.info(String.valueOf(CONFIG.GAME_DURATION)); final var command = literal("molehunt"); command.then(literal("start").requires(source -> source.hasPermissionLevel(1)).executes(context -> { diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java new file mode 100644 index 0000000..fc5104d --- /dev/null +++ b/src/main/java/world/anhgelus/molehunt/config/Config.java @@ -0,0 +1,38 @@ +package world.anhgelus.molehunt.config; + +import world.anhgelus.molehunt.Molehunt; + +public class Config { + public final int GAME_DURATION; + public final double MOLE_PERCENTAGE; + public final int MOLE_COUNT; + + public Config(String fileName) { + final SimpleConfig CONFIG = SimpleConfig.of(fileName).provider(Config::defaultConfig).request(); + + // In seconds + GAME_DURATION = CONFIG.getOrDefault("game_duration", 90) * 60; + MOLE_PERCENTAGE = CONFIG.getOrDefault("mole_percentage", 25); + MOLE_COUNT = CONFIG.getOrDefault("mole_count", -1); + } + + private static String defaultConfig(String s) { + return """ + # Molehunt mod configuration file + + # The duration of a molehunt game, in minutes. + # Default : 90 minutes (1 hour 30 minutes). + game_duration = 90 + + # Mole percentage. + # For example, a mole percentage of 25% will get 1 mole every 4 players. + # Default : 25 %. + mole_percentage = 25 + + # Mole count (absolute) + # If set, this setting will overwrite the mole_percentage setting. + # Default : not set + #mole_count = 2 + """; + } +} diff --git a/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java b/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java new file mode 100644 index 0000000..ef8bef3 --- /dev/null +++ b/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java @@ -0,0 +1,252 @@ +package world.anhgelus.molehunt.config; + +/* + * Copyright (c) 2021 magistermaks + * Slightly modified by Léo-21 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +import net.fabricmc.loader.api.FabricLoader; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.HashMap; +import java.util.Scanner; + +public class SimpleConfig { + + private static final Logger LOGGER = LogManager.getLogger("SimpleConfig"); + private final HashMap config = new HashMap<>(); + private final ConfigRequest request; + private boolean broken = false; + + public interface DefaultConfig { + String get( String namespace ); + + static String empty( String namespace ) { + return ""; + } + } + + public static class ConfigRequest { + + private final File file; + private final String filename; + private DefaultConfig provider; + + private ConfigRequest(File file, String filename ) { + this.file = file; + this.filename = filename; + this.provider = DefaultConfig::empty; + } + + /** + * Sets the default config provider, used to generate the + * config if it's missing. + * + * @param provider default config provider + * @return current config request object + * @see DefaultConfig + */ + public ConfigRequest provider( DefaultConfig provider ) { + this.provider = provider; + return this; + } + + /** + * Loads the config from the filesystem. + * + * @return config object + * @see SimpleConfig + */ + public SimpleConfig request() { + return new SimpleConfig( this ); + } + + private String getConfig() { + return provider.get( filename ) + "\n"; + } + + } + + /** + * Creates new config request object, ideally `namespace` + * should be the name of the mod id of the requesting mod + * + * @param filename - name of the config file + * @return new config request object + */ + public static ConfigRequest of( String filename ) { + Path path = FabricLoader.getInstance().getConfigDir(); + return new ConfigRequest( path.resolve( filename + ".properties" ).toFile(), filename ); + } + + private void createConfig() throws IOException { + + // try creating missing files + request.file.getParentFile().mkdirs(); + Files.createFile( request.file.toPath() ); + + // write default config data + PrintWriter writer = new PrintWriter(request.file, "UTF-8"); + writer.write( request.getConfig() ); + writer.close(); + + } + + private void loadConfig() throws IOException { + Scanner reader = new Scanner( request.file ); + for( int line = 1; reader.hasNextLine(); line ++ ) { + parseConfigEntry( reader.nextLine(), line ); + } + } + + private void parseConfigEntry( String entry, int line ) { + if( !entry.isEmpty() && !entry.startsWith( "#" ) ) { + String[] parts = entry.split("=", 2); + if( parts.length == 2 ) { + config.put( parts[0].stripTrailing(), parts[1].strip() ); + }else{ + throw new RuntimeException("Syntax error in config file on line " + line + "!"); + } + } + } + + private SimpleConfig( ConfigRequest request ) { + this.request = request; + String identifier = "Config '" + request.filename + "'"; + + if( !request.file.exists() ) { + LOGGER.info( identifier + " is missing, generating default one..." ); + + try { + createConfig(); + } catch (IOException e) { + LOGGER.error( identifier + " failed to generate!" ); + LOGGER.trace( e ); + broken = true; + } + } + + if( !broken ) { + try { + loadConfig(); + } catch (Exception e) { + LOGGER.error( identifier + " failed to load!" ); + LOGGER.trace( e ); + broken = true; + } + } + + } + + /** + * Queries a value from config, returns `null` if the + * key does not exist. + * + * @return value corresponding to the given key + * @see SimpleConfig#getOrDefault + */ + @Deprecated + public String get( String key ) { + return config.get( key ); + } + + /** + * Returns string value from config corresponding to the given + * key, or the default string if the key is missing. + * + * @return value corresponding to the given key, or the default value + */ + public String getOrDefault( String key, String def ) { + String val = get(key); + return val == null ? def : val; + } + + /** + * Returns integer value from config corresponding to the given + * key, or the default integer if the key is missing or invalid. + * + * @return value corresponding to the given key, or the default value + */ + public int getOrDefault( String key, int def ) { + try { + return Integer.parseInt( get(key) ); + } catch (Exception e) { + return def; + } + } + + /** + * Returns boolean value from config corresponding to the given + * key, or the default boolean if the key is missing. + * + * @return value corresponding to the given key, or the default value + */ + public boolean getOrDefault( String key, boolean def ) { + String val = get(key); + if( val != null ) { + return val.equalsIgnoreCase("true"); + } + + return def; + } + + /** + * Returns double value from config corresponding to the given + * key, or the default string if the key is missing or invalid. + * + * @return value corresponding to the given key, or the default value + */ + public double getOrDefault( String key, double def ) { + try { + return Double.parseDouble( get(key) ); + } catch (Exception e) { + return def; + } + } + + /** + * If any error occurred during loading or reading from the config + * a 'broken' flag is set, indicating that the config's state + * is undefined and should be discarded using `delete()` + * + * @return the 'broken' flag of the configuration + */ + public boolean isBroken() { + return broken; + } + + /** + * deletes the config file from the filesystem + * + * @return true if the operation was successful + */ + public boolean delete() { + LOGGER.warn( "Config '" + request.filename + "' was removed from existence! Restart the game to regenerate it." ); + return request.file.delete(); + } + +} \ No newline at end of file -- cgit v1.2.3 From da7d7c502a8c99dfeae5d3294c54ad4f892edcb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Fri, 23 Aug 2024 13:08:20 +0200 Subject: style: remove unnecessary imports --- src/main/java/world/anhgelus/molehunt/config/Config.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java index fc5104d..519166d 100644 --- a/src/main/java/world/anhgelus/molehunt/config/Config.java +++ b/src/main/java/world/anhgelus/molehunt/config/Config.java @@ -1,7 +1,5 @@ package world.anhgelus.molehunt.config; -import world.anhgelus.molehunt.Molehunt; - public class Config { public final int GAME_DURATION; public final double MOLE_PERCENTAGE; -- cgit v1.2.3 From 007ad4b3f9eb0d683f72a3008ec3208c1121217d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Fri, 23 Aug 2024 13:11:40 +0200 Subject: style: remove commented and unused code --- src/main/java/world/anhgelus/molehunt/Game.java | 9 --------- src/main/java/world/anhgelus/molehunt/Molehunt.java | 4 ---- 2 files changed, 13 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 3092bc9..df90044 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -40,7 +40,6 @@ public class Game { } else { n = Molehunt.CONFIG.MOLE_COUNT; } -// final int n = (server.getCurrentPlayerCount() - server.getCurrentPlayerCount() % 4)/4; final var playerManager = server.getPlayerManager(); @@ -152,14 +151,6 @@ public class Game { }, 4*1000); } - public int getRemaining() { - return remaining; - } - - public Text getRemainingText() { - return Text.of("Time remaining: "+ TimeUtils.printTime(remaining)); - } - public Text getShortRemainingText() { return Text.of("§c" + TimeUtils.printShortTime(remaining)); } diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 078afa6..1752d26 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -42,10 +42,6 @@ public class Molehunt implements ModInitializer { game.start(); return Command.SINGLE_SUCCESS; })); -// command.then(literal("time").executes(context -> { -// context.getSource().sendFeedback(() -> game.getRemainingText(), false); -// return Command.SINGLE_SUCCESS; -// })); command.then(literal("timer").requires(ServerCommandSource::isExecutedByPlayer).then( literal("show").executes(context -> { timerVisibility.put(context.getSource().getPlayer(), true); -- cgit v1.2.3 From f2537409c7705f53f8a612a67b2af2497cd3830d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Fri, 23 Aug 2024 14:24:19 +0200 Subject: fix: convert player list to arraylist --- src/main/java/world/anhgelus/molehunt/Game.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index df90044..32dea83 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -43,7 +43,7 @@ public class Game { final var playerManager = server.getPlayerManager(); - final var players = playerManager.getPlayerList(); + final var players = new ArrayList<>(playerManager.getPlayerList()); for (int i = 0; i < n; i++) { // Can happen if the mole count is greater than the player count if (players.isEmpty()) break; -- cgit v1.2.3 From d89d380f3229ab22a47e43e6cef50c604629bda1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Fri, 23 Aug 2024 14:27:22 +0200 Subject: style: improve code as suggested by @anhgelus --- src/main/java/world/anhgelus/molehunt/Game.java | 11 ++++++----- src/main/java/world/anhgelus/molehunt/Molehunt.java | 5 +---- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 32dea83..54e5c3a 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -44,10 +44,7 @@ public class Game { final var playerManager = server.getPlayerManager(); final var players = new ArrayList<>(playerManager.getPlayerList()); - for (int i = 0; i < n; i++) { - // Can happen if the mole count is greater than the player count - if (players.isEmpty()) break; - + for (int i = 0; i < n && !players.isEmpty(); i++) { final var r = ThreadLocalRandom.current().nextInt(0, players.size()); final var mole = players.get(r); if (mole == null) throw new IllegalStateException("Mole is null!"); @@ -160,7 +157,11 @@ public class Game { } public String getMolesAsString() { - return moles.stream().map(ServerPlayerEntity::getDisplayName).filter(Objects::nonNull).map(Text::toString).collect(Collectors.joining(", ")); + return moles.stream() + .map(ServerPlayerEntity::getDisplayName) + .filter(Objects::nonNull) + .map(Text::toString) + .collect(Collectors.joining(", ")); } public boolean isAMole(ServerPlayerEntity player) { diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 1752d26..5df63b1 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -34,7 +34,6 @@ public class Molehunt implements ModInitializer { @Override public void onInitialize() { LOGGER.info("Initializing Molehunt"); - LOGGER.info(String.valueOf(CONFIG.GAME_DURATION)); final var command = literal("molehunt"); command.then(literal("start").requires(source -> source.hasPermissionLevel(1)).executes(context -> { @@ -71,9 +70,7 @@ public class Molehunt implements ModInitializer { })); command.then(literal("stop").requires(source -> source.hasPermissionLevel(1)).executes(context -> { if (game == null || !game.hasStarted()) { - var e = new SimpleCommandExceptionType(Text.translatable("commands.molehunt.stop.failed")); - - throw e.create(); + throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.stop.failed"))).create(); } game.stop(); -- cgit v1.2.3 From a3fbb77bfc0490e8dfac39d0466ff9b87a14fec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Kosman?= Date: Fri, 23 Aug 2024 15:07:51 +0200 Subject: style: change default config mole_count --- src/main/java/world/anhgelus/molehunt/config/Config.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java index 519166d..75301ad 100644 --- a/src/main/java/world/anhgelus/molehunt/config/Config.java +++ b/src/main/java/world/anhgelus/molehunt/config/Config.java @@ -27,10 +27,11 @@ public class Config { # Default : 25 %. mole_percentage = 25 - # Mole count (absolute) - # If set, this setting will overwrite the mole_percentage setting. - # Default : not set - #mole_count = 2 + # Mole count (absolute). + # This setting will overwrite the mole_percentage setting. + # If set below 0, this setting is disabled. + # Default : -1. + mole_count = -1 """; } } -- cgit v1.2.3 From 7f6043a230b83cff57126625cd8b19063c85a599 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 13:41:22 +0000 Subject: feat(config): packet sending config to client --- .../anhgelus/molehunt/client/MolehuntClient.java | 35 ++++++++++++++++------ .../anhgelus/molehunt/client/mixin/NoSkin.java | 4 +-- .../java/world/anhgelus/molehunt/Molehunt.java | 4 +++ .../anhgelus/molehunt/config/ConfigPayload.java | 25 ++++++++++++++++ 4 files changed, 57 insertions(+), 11 deletions(-) create mode 100644 src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java diff --git a/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java b/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java index e6de219..5f6b735 100644 --- a/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java +++ b/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java @@ -1,20 +1,37 @@ package world.anhgelus.molehunt.client; -import com.mojang.authlib.GameProfile; import net.fabricmc.api.ClientModInitializer; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.UUID; +import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import world.anhgelus.molehunt.config.ConfigPayload; public class MolehuntClient implements ClientModInitializer { - public static final String MOD_ID = "molehunt"; - public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - - public final static GameProfile ANONYMOUS_PROFILE = new GameProfile(UUID.fromString("015f3266-4e0a-412e-9b80-1ca76af79453"), "Molehunt"); + private static boolean SHOW_SKINS = false; + private static boolean SHOW_NAMETAGS = false; + private static boolean SHOW_TAB = false; @Override public void onInitializeClient() { + ClientPlayNetworking.registerGlobalReceiver(ConfigPayload.ID, (payload, context) -> { + try (final var client = context.client()) { + client.execute(() -> { + SHOW_SKINS = payload.showSkins(); + SHOW_NAMETAGS = payload.showNametag(); + SHOW_TAB = payload.showNametag(); + }); + } + }); + } + + public static boolean showSkins() { + return SHOW_SKINS; + } + + public static boolean showNameTags() { + return SHOW_NAMETAGS; + } + + public static boolean showTab() { + return SHOW_TAB; } } diff --git a/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java b/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java index edbfd15..425ded7 100644 --- a/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java +++ b/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java @@ -7,14 +7,14 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import world.anhgelus.molehunt.client.MolehuntClient; +import world.anhgelus.molehunt.Molehunt; @Mixin(AbstractClientPlayerEntity.class) public class NoSkin { @Inject(at = @At("HEAD"), method = "getSkinTextures", cancellable = true) public void getSkin(CallbackInfoReturnable cir) { cir.setReturnValue(new SkinTextures( - Identifier.of(MolehuntClient.MOD_ID, "textures/skin.png"), + Identifier.of(Molehunt.MOD_ID, "textures/skin.png"), null, null, null, diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 5df63b1..140ab14 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -7,6 +7,7 @@ import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; +import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.minecraft.network.packet.s2c.play.OverlayMessageS2CPacket; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; @@ -15,6 +16,7 @@ import net.minecraft.world.GameMode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import world.anhgelus.molehunt.config.Config; +import world.anhgelus.molehunt.config.ConfigPayload; import java.util.HashMap; @@ -93,5 +95,7 @@ public class Molehunt implements ModInitializer { if (game.getMoles().contains(oldPlayer)) game.updateMole(oldPlayer, newPlayer); newPlayer.changeGameMode(GameMode.SPECTATOR); }); + + PayloadTypeRegistry.playS2C().register(ConfigPayload.ID, ConfigPayload.CODEC); } } diff --git a/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java b/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java new file mode 100644 index 0000000..a884c9a --- /dev/null +++ b/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java @@ -0,0 +1,25 @@ +package world.anhgelus.molehunt.config; + +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.network.packet.CustomPayload; +import net.minecraft.util.Identifier; +import world.anhgelus.molehunt.Molehunt; + +public record ConfigPayload(boolean showNametag, boolean showSkins, boolean showTab) implements CustomPayload { + public static final Identifier CONFIG_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "config"); + + public static final CustomPayload.Id ID = new CustomPayload.Id<>(CONFIG_PACKET_ID); + public static final PacketCodec CODEC = PacketCodec.tuple( + PacketCodecs.BOOL, ConfigPayload::showNametag, + PacketCodecs.BOOL, ConfigPayload::showSkins, + PacketCodecs.BOOL, ConfigPayload::showTab, + ConfigPayload::new + ); + + @Override + public Id getId() { + return ID; + } +} -- cgit v1.2.3 From 7fd5caf38a9b3ef71d94d9085ee92b47c3c449e3 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 13:42:56 +0000 Subject: feat(config): disable mixins according to config's packet --- .../world/anhgelus/molehunt/client/mixin/NoNametags.java | 3 ++- .../anhgelus/molehunt/client/mixin/NoPlayerListHud.java | 2 ++ .../java/world/anhgelus/molehunt/client/mixin/NoSkin.java | 12 +++++++----- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java b/src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java index 7996c49..3482abb 100644 --- a/src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java +++ b/src/client/java/world/anhgelus/molehunt/client/mixin/NoNametags.java @@ -9,12 +9,13 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import world.anhgelus.molehunt.client.MolehuntClient; @Mixin(EntityRenderer.class) public class NoNametags { @Inject(at = @At("HEAD"), method = "render", cancellable = true) private void renderLabelOrNot(T entity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light, CallbackInfo ci) { - if (!(entity instanceof PlayerEntity)) return; + if (!(entity instanceof PlayerEntity) || MolehuntClient.showNameTags()) return; ci.cancel(); } } \ No newline at end of file diff --git a/src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java b/src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java index 8ef33fd..00308ea 100644 --- a/src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java +++ b/src/client/java/world/anhgelus/molehunt/client/mixin/NoPlayerListHud.java @@ -5,11 +5,13 @@ import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import world.anhgelus.molehunt.client.MolehuntClient; @Mixin(PlayerListHud.class) public class NoPlayerListHud { @Inject(at = @At("HEAD"), method = "render", cancellable = true) public void render(CallbackInfo ci) { + if (MolehuntClient.showTab()) return; ci.cancel(); } } diff --git a/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java b/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java index 425ded7..775d789 100644 --- a/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java +++ b/src/client/java/world/anhgelus/molehunt/client/mixin/NoSkin.java @@ -8,17 +8,19 @@ import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import world.anhgelus.molehunt.Molehunt; +import world.anhgelus.molehunt.client.MolehuntClient; @Mixin(AbstractClientPlayerEntity.class) public class NoSkin { @Inject(at = @At("HEAD"), method = "getSkinTextures", cancellable = true) public void getSkin(CallbackInfoReturnable cir) { + if (MolehuntClient.showSkins()) return; cir.setReturnValue(new SkinTextures( - Identifier.of(Molehunt.MOD_ID, "textures/skin.png"), - null, - null, - null, - SkinTextures.Model.WIDE, true) + Identifier.of(Molehunt.MOD_ID, "textures/skin.png"), + null, + null, + null, + SkinTextures.Model.WIDE, true) ); } } -- cgit v1.2.3 From 909f9ed08454a26e3c42d2cfcf9338cded41c8fb Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 13:44:29 +0000 Subject: style(config): rename variables SPACE_CASE used for non static var --- src/main/java/world/anhgelus/molehunt/Game.java | 8 ++++---- src/main/java/world/anhgelus/molehunt/config/Config.java | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 54e5c3a..a50598e 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -18,7 +18,7 @@ import java.util.stream.Collectors; public class Game { private Timer timer = new Timer(); - public final static int DEFAULT_TIME = Molehunt.CONFIG.GAME_DURATION; + public final static int DEFAULT_TIME = Molehunt.CONFIG.gameDuration; private int remaining = DEFAULT_TIME; private final MinecraftServer server; @@ -35,10 +35,10 @@ public class Game { public void start() { final int n; - if (Molehunt.CONFIG.MOLE_COUNT < 0) { - n = Math.floorDiv(server.getCurrentPlayerCount(), Math.floorDiv(100, (int) Molehunt.CONFIG.MOLE_PERCENTAGE)); + if (Molehunt.CONFIG.moleCount < 0) { + n = Math.floorDiv(server.getCurrentPlayerCount(), Math.floorDiv(100, (int) Molehunt.CONFIG.molePercentage)); } else { - n = Molehunt.CONFIG.MOLE_COUNT; + n = Molehunt.CONFIG.moleCount; } final var playerManager = server.getPlayerManager(); diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java index 75301ad..a396a39 100644 --- a/src/main/java/world/anhgelus/molehunt/config/Config.java +++ b/src/main/java/world/anhgelus/molehunt/config/Config.java @@ -1,17 +1,17 @@ package world.anhgelus.molehunt.config; public class Config { - public final int GAME_DURATION; - public final double MOLE_PERCENTAGE; - public final int MOLE_COUNT; + public final int gameDuration; + public final double molePercentage; + public final int moleCount; public Config(String fileName) { final SimpleConfig CONFIG = SimpleConfig.of(fileName).provider(Config::defaultConfig).request(); // In seconds - GAME_DURATION = CONFIG.getOrDefault("game_duration", 90) * 60; - MOLE_PERCENTAGE = CONFIG.getOrDefault("mole_percentage", 25); - MOLE_COUNT = CONFIG.getOrDefault("mole_count", -1); + gameDuration = CONFIG.getOrDefault("game_duration", 90) * 60; + molePercentage = CONFIG.getOrDefault("mole_percentage", 25); + moleCount = CONFIG.getOrDefault("mole_count", -1); } private static String defaultConfig(String s) { -- cgit v1.2.3 From a39de9ad78f0e3b4b03453dc3f5da0b649f69288 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 13:49:13 +0000 Subject: feat(config): config for nametag, skins and tab --- .../anhgelus/molehunt/client/MolehuntClient.java | 4 ++-- .../world/anhgelus/molehunt/config/Config.java | 25 +++++++++++++++++++--- .../anhgelus/molehunt/config/ConfigPayload.java | 4 ++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java b/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java index 5f6b735..7770a1b 100644 --- a/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java +++ b/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java @@ -16,8 +16,8 @@ public class MolehuntClient implements ClientModInitializer { try (final var client = context.client()) { client.execute(() -> { SHOW_SKINS = payload.showSkins(); - SHOW_NAMETAGS = payload.showNametag(); - SHOW_TAB = payload.showNametag(); + SHOW_NAMETAGS = payload.showNametags(); + SHOW_TAB = payload.showTab(); }); } }); diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java index a396a39..9edfc1b 100644 --- a/src/main/java/world/anhgelus/molehunt/config/Config.java +++ b/src/main/java/world/anhgelus/molehunt/config/Config.java @@ -4,6 +4,9 @@ public class Config { public final int gameDuration; public final double molePercentage; public final int moleCount; + public final boolean showNametags; + public final boolean showTab; + public final boolean showSkins; public Config(String fileName) { final SimpleConfig CONFIG = SimpleConfig.of(fileName).provider(Config::defaultConfig).request(); @@ -12,6 +15,10 @@ public class Config { gameDuration = CONFIG.getOrDefault("game_duration", 90) * 60; molePercentage = CONFIG.getOrDefault("mole_percentage", 25); moleCount = CONFIG.getOrDefault("mole_count", -1); + // bool + showNametags = CONFIG.getOrDefault("show_nametags", false); + showSkins = CONFIG.getOrDefault("show_skins", false); + showTab = CONFIG.getOrDefault("show_tab", false); } private static String defaultConfig(String s) { @@ -19,19 +26,31 @@ public class Config { # Molehunt mod configuration file # The duration of a molehunt game, in minutes. - # Default : 90 minutes (1 hour 30 minutes). + # Default: 90 minutes (1 hour 30 minutes). game_duration = 90 # Mole percentage. # For example, a mole percentage of 25% will get 1 mole every 4 players. - # Default : 25 %. + # Default: 25 %. mole_percentage = 25 # Mole count (absolute). # This setting will overwrite the mole_percentage setting. # If set below 0, this setting is disabled. - # Default : -1. + # Default: -1. mole_count = -1 + + # Show nametags + # Default: false + show_nametags = false + + # Show skins + # Default: false + show_skins = false + + # Show tab + # Default: false + show_tab = false """; } } diff --git a/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java b/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java index a884c9a..0123e74 100644 --- a/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java +++ b/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java @@ -7,12 +7,12 @@ import net.minecraft.network.packet.CustomPayload; import net.minecraft.util.Identifier; import world.anhgelus.molehunt.Molehunt; -public record ConfigPayload(boolean showNametag, boolean showSkins, boolean showTab) implements CustomPayload { +public record ConfigPayload(boolean showNametags, boolean showSkins, boolean showTab) implements CustomPayload { public static final Identifier CONFIG_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "config"); public static final CustomPayload.Id ID = new CustomPayload.Id<>(CONFIG_PACKET_ID); public static final PacketCodec CODEC = PacketCodec.tuple( - PacketCodecs.BOOL, ConfigPayload::showNametag, + PacketCodecs.BOOL, ConfigPayload::showNametags, PacketCodecs.BOOL, ConfigPayload::showSkins, PacketCodecs.BOOL, ConfigPayload::showTab, ConfigPayload::new -- cgit v1.2.3 From a638839550837f43216b02a9bdee359a24814f37 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 13:53:17 +0000 Subject: fix(network): not sending packet on connection --- src/main/java/world/anhgelus/molehunt/Molehunt.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 140ab14..79903e2 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -8,6 +8,8 @@ import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; +import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; import net.minecraft.network.packet.s2c.play.OverlayMessageS2CPacket; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; @@ -96,6 +98,10 @@ public class Molehunt implements ModInitializer { newPlayer.changeGameMode(GameMode.SPECTATOR); }); + ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { + ServerPlayNetworking.send(handler.player, new ConfigPayload(CONFIG.showNametags, CONFIG.showSkins, CONFIG.showTab)); + }); + PayloadTypeRegistry.playS2C().register(ConfigPayload.ID, ConfigPayload.CODEC); } } -- cgit v1.2.3 From c6e309f02732eb79a24db6780c4f8f718fac2a29 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 14:01:38 +0000 Subject: feat(config): hot reload with /molehunt reload --- README.md | 2 ++ src/main/java/world/anhgelus/molehunt/Molehunt.java | 13 ++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 401b81f..2d22e84 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ skin file](src/client/resources/assets/molehunt/textures/skin.png)). Also, more server-side values can be changed in the configuration file, located in your server config directory. +Config hot reloadable with `/molehunt reload` + ## Technologies - Java 21 diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 79903e2..4a728a0 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -29,7 +29,7 @@ public class Molehunt implements ModInitializer { public static final String MOD_ID = "molehunt"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static final Config CONFIG = new Config(MOD_ID); + public static Config CONFIG = new Config(MOD_ID); public Game game; @@ -81,6 +81,17 @@ public class Molehunt implements ModInitializer { return Command.SINGLE_SUCCESS; })); + command.then(literal("reload").requires(source -> source.hasPermissionLevel(1)).executes(context -> { + if (game != null && game.hasStarted()) { + game.end(); + game = null; + } + CONFIG = new Config(MOD_ID); + context.getSource().getServer().getPlayerManager().getPlayerList().forEach(p -> { + ServerPlayNetworking.send(p, new ConfigPayload(CONFIG.showNametags, CONFIG.showSkins, CONFIG.showTab)); + }); + return Command.SINGLE_SUCCESS; + })); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(command)); -- cgit v1.2.3 From 2e87ea59da4e7a3a56f24641c22aeac50cc5b607 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 14:22:41 +0000 Subject: fix(networking): crash while joining server --- .../java/world/anhgelus/molehunt/client/MolehuntClient.java | 12 +++++------- .../java/world/anhgelus/molehunt/config/SimpleConfig.java | 13 +++++++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java b/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java index 7770a1b..1f92573 100644 --- a/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java +++ b/src/client/java/world/anhgelus/molehunt/client/MolehuntClient.java @@ -13,13 +13,11 @@ public class MolehuntClient implements ClientModInitializer { @Override public void onInitializeClient() { ClientPlayNetworking.registerGlobalReceiver(ConfigPayload.ID, (payload, context) -> { - try (final var client = context.client()) { - client.execute(() -> { - SHOW_SKINS = payload.showSkins(); - SHOW_NAMETAGS = payload.showNametags(); - SHOW_TAB = payload.showTab(); - }); - } + context.client().execute(() -> { + SHOW_SKINS = payload.showSkins(); + SHOW_NAMETAGS = payload.showNametags(); + SHOW_TAB = payload.showTab(); + }); }); } diff --git a/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java b/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java index ef8bef3..2b65829 100644 --- a/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java +++ b/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java @@ -2,7 +2,7 @@ package world.anhgelus.molehunt.config; /* * Copyright (c) 2021 magistermaks - * Slightly modified by Léo-21 + * Slightly modified by Léo-21 and Anhgelus Morhtuuzh * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,6 +30,7 @@ import org.apache.logging.log4j.Logger; import java.io.File; import java.io.IOException; import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; @@ -110,7 +111,7 @@ public class SimpleConfig { Files.createFile( request.file.toPath() ); // write default config data - PrintWriter writer = new PrintWriter(request.file, "UTF-8"); + PrintWriter writer = new PrintWriter(request.file, StandardCharsets.UTF_8); writer.write( request.getConfig() ); writer.close(); @@ -139,12 +140,12 @@ public class SimpleConfig { String identifier = "Config '" + request.filename + "'"; if( !request.file.exists() ) { - LOGGER.info( identifier + " is missing, generating default one..." ); + LOGGER.info("{} is missing, generating default one...", identifier); try { createConfig(); } catch (IOException e) { - LOGGER.error( identifier + " failed to generate!" ); + LOGGER.error("{} failed to generate!", identifier); LOGGER.trace( e ); broken = true; } @@ -154,7 +155,7 @@ public class SimpleConfig { try { loadConfig(); } catch (Exception e) { - LOGGER.error( identifier + " failed to load!" ); + LOGGER.error("{} failed to load!", identifier); LOGGER.trace( e ); broken = true; } @@ -245,7 +246,7 @@ public class SimpleConfig { * @return true if the operation was successful */ public boolean delete() { - LOGGER.warn( "Config '" + request.filename + "' was removed from existence! Restart the game to regenerate it." ); + LOGGER.warn("Config '{}' was removed from existence! Restart the game to regenerate it.", request.filename); return request.file.delete(); } -- cgit v1.2.3 From e3611b77c66d303d97528fa221553c1c1a44d1c6 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 18:22:14 +0000 Subject: feat(config): options are now gamerules --- README.md | 8 ++- gradle.properties | 2 +- .../resources/assets/molehunt/lang/en_us.json | 8 ++- src/main/java/world/anhgelus/molehunt/Game.java | 13 ++-- .../java/world/anhgelus/molehunt/Molehunt.java | 62 ++++++++++++++---- .../world/anhgelus/molehunt/config/Config.java | 76 ++++++++++++++++++---- 6 files changed, 130 insertions(+), 39 deletions(-) diff --git a/README.md b/README.md index 2d22e84..8cbd471 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,13 @@ skin file](src/client/resources/assets/molehunt/textures/skin.png)). Also, more server-side values can be changed in the configuration file, located in your server config directory. -Config hot reloadable with `/molehunt reload` +You can edit the configuration with these gamerules: +- `gameDuration` +- `molePercentage` +- `moleCount` +- `showNametags` +- `showTab` +- `showSkins` ## Technologies diff --git a/gradle.properties b/gradle.properties index a5e4f25..4629a79 100644 --- a/gradle.properties +++ b/gradle.properties @@ -6,7 +6,7 @@ minecraft_version=1.21.1 yarn_mappings=1.21.1+build.3 loader_version=0.16.2 # Mod Properties -mod_version=1.0.0 +mod_version=1.1.0 maven_group=world.anhgelus archives_base_name=Molehunt # Dependencies diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json index 63ac06d..33aef84 100644 --- a/src/client/resources/assets/molehunt/lang/en_us.json +++ b/src/client/resources/assets/molehunt/lang/en_us.json @@ -11,5 +11,11 @@ "molehunt.game.start.suspense": "§eYou are...", "molehunt.game.start.mole.title": "§cThe Mole!", "molehunt.game.start.mole.subtitle": "§eGet the list of moles with §6/molehunt moles", - "molehunt.game.start.survivor": "§aNot the Mole!" + "molehunt.game.start.survivor": "§aNot the Mole!", + "gamerule.gameDuration": "Duration of a game", + "gamerule.molePercentage": "Percentage of mole", + "gamerule.moleCount": "Number of mole", + "gamerule.showNametags": "Show players' nametag", + "gamerule.showTab": "Enable the tab", + "gamerule.showSkins": "Show players' skin" } \ No newline at end of file diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index a50598e..2f94a8b 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -18,8 +18,8 @@ import java.util.stream.Collectors; public class Game { private Timer timer = new Timer(); - public final static int DEFAULT_TIME = Molehunt.CONFIG.gameDuration; - private int remaining = DEFAULT_TIME; + public final int defaultTime = Molehunt.CONFIG.getGameDuration(); + private int remaining = defaultTime; private final MinecraftServer server; @@ -34,12 +34,9 @@ public class Game { } public void start() { - final int n; - if (Molehunt.CONFIG.moleCount < 0) { - n = Math.floorDiv(server.getCurrentPlayerCount(), Math.floorDiv(100, (int) Molehunt.CONFIG.molePercentage)); - } else { - n = Molehunt.CONFIG.moleCount; - } + final int n = Molehunt.CONFIG.getMoleCount() < 0 + ? Math.floorDiv(server.getCurrentPlayerCount(), Math.floorDiv(100, Molehunt.CONFIG.getMolePercentage())) + : Molehunt.CONFIG.getMoleCount(); final var playerManager = server.getPlayerManager(); diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 4a728a0..0ec3c3b 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -6,6 +6,9 @@ import net.fabricmc.api.ModInitializer; import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback; import net.fabricmc.fabric.api.entity.event.v1.ServerLivingEntityEvents; import net.fabricmc.fabric.api.entity.event.v1.ServerPlayerEvents; +import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents; +import net.fabricmc.fabric.api.gamerule.v1.GameRuleFactory; +import net.fabricmc.fabric.api.gamerule.v1.GameRuleRegistry; import net.fabricmc.fabric.api.message.v1.ServerMessageEvents; import net.fabricmc.fabric.api.networking.v1.PayloadTypeRegistry; import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents; @@ -15,6 +18,7 @@ import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.*; import net.minecraft.world.GameMode; +import net.minecraft.world.GameRules; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import world.anhgelus.molehunt.config.Config; @@ -29,7 +33,41 @@ public class Molehunt implements ModInitializer { public static final String MOD_ID = "molehunt"; public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); - public static Config CONFIG = new Config(MOD_ID); + public static Config CONFIG; + + public static final GameRules.Key GAME_DURATION = GameRuleRegistry.register( + "gameDuration", GameRules.Category.MISC, GameRuleFactory.createIntRule(90) + ); + public static final GameRules.Key MOLE_PERCENTAGE = GameRuleRegistry.register( + "molePercentage", GameRules.Category.MISC, GameRuleFactory.createIntRule(25) + ); + public static final GameRules.Key MOLE_COUNT = GameRuleRegistry.register( + "moleCount", GameRules.Category.MISC, GameRuleFactory.createIntRule(-1) + ); + public static final GameRules.Key SHOW_NAMETAGS = GameRuleRegistry.register( + "showNametags", + GameRules.Category.MISC, + GameRuleFactory.createBooleanRule(false, (server, val) -> { + if (CONFIG == null) return; + CONFIG.sendConfigPayload(); + }) + ); + public static final GameRules.Key SHOW_TAB = GameRuleRegistry.register( + "showTab" + , GameRules.Category.MISC, + GameRuleFactory.createBooleanRule(false, (server, val) -> { + if (CONFIG == null) return; + CONFIG.sendConfigPayload(); + }) + ); + public static final GameRules.Key SHOW_SKINS = GameRuleRegistry.register( + "showSkins", + GameRules.Category.MISC, + GameRuleFactory.createBooleanRule(false, (server, val) -> { + if (CONFIG == null) return; + CONFIG.sendConfigPayload(); + }) + ); public Game game; @@ -54,7 +92,9 @@ public class Molehunt implements ModInitializer { assert player != null; if (game == null || !game.hasStarted()) { - player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.translatable("commands.molehunt.stop.failed").setStyle(Style.EMPTY.withColor(16733525)))); + player.networkHandler.sendPacket(new OverlayMessageS2CPacket( + Text.translatable("commands.molehunt.stop.failed").setStyle(Style.EMPTY.withColor(16733525)) + )); } else { player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(game.getShortRemainingText()))); } @@ -81,17 +121,8 @@ public class Molehunt implements ModInitializer { return Command.SINGLE_SUCCESS; })); - command.then(literal("reload").requires(source -> source.hasPermissionLevel(1)).executes(context -> { - if (game != null && game.hasStarted()) { - game.end(); - game = null; - } - CONFIG = new Config(MOD_ID); - context.getSource().getServer().getPlayerManager().getPlayerList().forEach(p -> { - ServerPlayNetworking.send(p, new ConfigPayload(CONFIG.showNametags, CONFIG.showSkins, CONFIG.showTab)); - }); - return Command.SINGLE_SUCCESS; - })); + + ServerLifecycleEvents.SERVER_STARTED.register(server -> CONFIG = new Config(MOD_ID, server)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(command)); @@ -110,7 +141,10 @@ public class Molehunt implements ModInitializer { }); ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { - ServerPlayNetworking.send(handler.player, new ConfigPayload(CONFIG.showNametags, CONFIG.showSkins, CONFIG.showTab)); + ServerPlayNetworking.send( + handler.player, + new ConfigPayload(CONFIG.areNametagsEnabled(), CONFIG.areSkinsEnabled(), CONFIG.isTabEnabled()) + ); }); PayloadTypeRegistry.playS2C().register(ConfigPayload.ID, ConfigPayload.CODEC); diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java index 9edfc1b..03ca86e 100644 --- a/src/main/java/world/anhgelus/molehunt/config/Config.java +++ b/src/main/java/world/anhgelus/molehunt/config/Config.java @@ -1,24 +1,72 @@ package world.anhgelus.molehunt.config; +import net.fabricmc.fabric.api.networking.v1.ServerPlayNetworking; +import net.minecraft.server.MinecraftServer; +import world.anhgelus.molehunt.Molehunt; + public class Config { - public final int gameDuration; - public final double molePercentage; - public final int moleCount; - public final boolean showNametags; - public final boolean showTab; - public final boolean showSkins; - - public Config(String fileName) { + + private final MinecraftServer server; + + public Config(String fileName, MinecraftServer server) { final SimpleConfig CONFIG = SimpleConfig.of(fileName).provider(Config::defaultConfig).request(); + this.server = server; + + final var rules = server.getGameRules(); + // In seconds - gameDuration = CONFIG.getOrDefault("game_duration", 90) * 60; - molePercentage = CONFIG.getOrDefault("mole_percentage", 25); - moleCount = CONFIG.getOrDefault("mole_count", -1); + final var gameDuration = CONFIG.getOrDefault("game_duration", 90) * 60; + rules.get(Molehunt.GAME_DURATION).set(gameDuration/60, server); + final var molePercentage = CONFIG.getOrDefault("mole_percentage", 25); + rules.get(Molehunt.MOLE_PERCENTAGE).set(molePercentage, server); + final var moleCount = CONFIG.getOrDefault("mole_count", -1); + rules.get(Molehunt.MOLE_COUNT).set(moleCount, server); // bool - showNametags = CONFIG.getOrDefault("show_nametags", false); - showSkins = CONFIG.getOrDefault("show_skins", false); - showTab = CONFIG.getOrDefault("show_tab", false); + final var showNametags = CONFIG.getOrDefault("show_nametags", false); + rules.get(Molehunt.SHOW_NAMETAGS).set(showNametags, server); + final var showSkins = CONFIG.getOrDefault("show_skins", false); + rules.get(Molehunt.SHOW_SKINS).set(showSkins, server); + final var showTab = CONFIG.getOrDefault("show_tab", false); + rules.get(Molehunt.SHOW_TAB).set(showTab, server); + + sendConfigPayload(showNametags, showSkins, showTab); + } + + public void sendConfigPayload() { + final var payload = new ConfigPayload(areNametagsEnabled(), areSkinsEnabled(), isTabEnabled()); + server.getPlayerManager().getPlayerList().forEach(p -> { + ServerPlayNetworking.send(p, payload); + }); + } + + public void sendConfigPayload(boolean showNametags, boolean showSkins, boolean showTab) { + final var payload = new ConfigPayload(showNametags, showSkins, showTab); + server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload)); + } + + public int getGameDuration() { + return server.getGameRules().getInt(Molehunt.GAME_DURATION); + } + + public int getMolePercentage() { + return server.getGameRules().getInt(Molehunt.MOLE_PERCENTAGE); + } + + public int getMoleCount() { + return server.getGameRules().getInt(Molehunt.MOLE_COUNT); + } + + public boolean areNametagsEnabled() { + return server.getGameRules().getBoolean(Molehunt.SHOW_NAMETAGS); + } + + public boolean areSkinsEnabled() { + return server.getGameRules().getBoolean(Molehunt.SHOW_SKINS); + } + + public boolean isTabEnabled() { + return server.getGameRules().getBoolean(Molehunt.SHOW_TAB); } private static String defaultConfig(String s) { -- cgit v1.2.3 From 42bffd9743060356a7fbf1f4157c175a1f23edda Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 18:25:11 +0000 Subject: docs(info): update readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8cbd471..f352a66 100644 --- a/README.md +++ b/README.md @@ -24,13 +24,15 @@ Stop the game when every innocent is dead or when the timer ended (one hour and The moles can see the name of other moles with `/molehunt moles`. +## Configuration + You can configure every text line and the skin with a resource pack (for reference, check out [the default lang file](src/client/resources/assets/molehunt/lang/en_us.json) and [the default skin file](src/client/resources/assets/molehunt/textures/skin.png)). Also, more server-side values can be changed in the configuration file, located in your server config directory. -You can edit the configuration with these gamerules: +The configuration can be modified in game with these gamerules: - `gameDuration` - `molePercentage` - `moleCount` -- cgit v1.2.3 From 4256a3a18897f232b169ad2ebb48feea1a51ba1d Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 18:28:43 +0000 Subject: feat(translation): french --- .../resources/assets/molehunt/lang/en_us.json | 6 +++--- .../resources/assets/molehunt/lang/fr_fr.json | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 src/client/resources/assets/molehunt/lang/fr_fr.json diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json index 33aef84..73cbe97 100644 --- a/src/client/resources/assets/molehunt/lang/en_us.json +++ b/src/client/resources/assets/molehunt/lang/en_us.json @@ -7,14 +7,14 @@ "molehunt.game.end.suspense.title": "§eAnd the winners are...", "molehunt.game.end.winners.moles.title": "§cThe Moles!", "molehunt.game.end.winners.survivors.title": "§aNot the Moles!", - "molehunt.game.end.winners.subtitle": "§6The moles were", + "molehunt.game.end.winners.subtitle": "§6The Moles were", "molehunt.game.start.suspense": "§eYou are...", "molehunt.game.start.mole.title": "§cThe Mole!", "molehunt.game.start.mole.subtitle": "§eGet the list of moles with §6/molehunt moles", "molehunt.game.start.survivor": "§aNot the Mole!", "gamerule.gameDuration": "Duration of a game", - "gamerule.molePercentage": "Percentage of mole", - "gamerule.moleCount": "Number of mole", + "gamerule.molePercentage": "Percentage of Mole", + "gamerule.moleCount": "Number of Mole", "gamerule.showNametags": "Show players' nametag", "gamerule.showTab": "Enable the tab", "gamerule.showSkins": "Show players' skin" diff --git a/src/client/resources/assets/molehunt/lang/fr_fr.json b/src/client/resources/assets/molehunt/lang/fr_fr.json new file mode 100644 index 0000000..c5c87d4 --- /dev/null +++ b/src/client/resources/assets/molehunt/lang/fr_fr.json @@ -0,0 +1,21 @@ +{ + "commands.molehunt.stop.failed": "La partie de Molehunt n'a pas encore commencé.", + "commands.molehunt.timer.show": "Affiche le timer.", + "commands.molehunt.timer.hide": "Cache le timer.", + "commands.molehunt.moles.list": "Liste des taupes:", + "commands.molehunt.stop.success": "La partie de Molehunt a été stoppée.", + "molehunt.game.end.suspense.title": "§eEt les gagnants sont...", + "molehunt.game.end.winners.moles.title": "§cLes Taupes !", + "molehunt.game.end.winners.survivors.title": "§aPas les Taupes !", + "molehunt.game.end.winners.subtitle": "§Les Taupes sont", + "molehunt.game.start.suspense": "§eVous êtes...", + "molehunt.game.start.mole.title": "§cLa Taupe !", + "molehunt.game.start.mole.subtitle": "§eRécupérer la liste des taupes avec §6/molehunt moles", + "molehunt.game.start.survivor": "§aPas la Taupe!", + "gamerule.gameDuration": "Durée d'une partie", + "gamerule.molePercentage": "Pourcentage de Taupes", + "gamerule.moleCount": "Nombre de Taupes", + "gamerule.showNametags": "Affiche les nametags des joueurs", + "gamerule.showTab": "Active le tab", + "gamerule.showSkins": "Affiche les skins des joueurs" +} \ No newline at end of file -- cgit v1.2.3 From 3a3edf9e104b8ead888970a49bd2ac69ea1508f2 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 20:18:47 +0000 Subject: fix(game): blinking titles --- src/main/java/world/anhgelus/molehunt/Game.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 2f94a8b..959b01b 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -96,19 +96,15 @@ public class Game { @Override public void run() { remaining--; - playerManager.sendToAll(timing); - playerManager.getPlayerList().forEach(player -> { if (Molehunt.timerVisibility.getOrDefault(player, true)) { player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(getShortRemainingText()))); } }); - - if (remaining == 0) { - end(); - } + playerManager.sendToAll(timing); + if (remaining == 0) end(); } - }, 4*1000, 1000); + }, 5*1000, 1000); } }, 4*1000); } -- cgit v1.2.3 From 25e5c35509eac87c1091361390debbf32e49f16f Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 20:23:21 +0000 Subject: fix(game): wrong display of moles' list --- src/main/java/world/anhgelus/molehunt/Game.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 959b01b..6101525 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -18,7 +18,7 @@ import java.util.stream.Collectors; public class Game { private Timer timer = new Timer(); - public final int defaultTime = Molehunt.CONFIG.getGameDuration(); + public final int defaultTime = Molehunt.CONFIG.getGameDuration()*60; private int remaining = defaultTime; private final MinecraftServer server; @@ -153,7 +153,7 @@ public class Game { return moles.stream() .map(ServerPlayerEntity::getDisplayName) .filter(Objects::nonNull) - .map(Text::toString) + .map(Text::getString) .collect(Collectors.joining(", ")); } -- cgit v1.2.3 From 32617ff3a18f966a445890d50c4b911817e162eb Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 20:39:32 +0000 Subject: fix(command): no autocompletion for /molehunt moles --- src/client/resources/assets/molehunt/lang/en_us.json | 3 ++- src/client/resources/assets/molehunt/lang/fr_fr.json | 3 ++- src/main/java/world/anhgelus/molehunt/Game.java | 2 +- src/main/java/world/anhgelus/molehunt/Molehunt.java | 9 +++++++-- 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json index 73cbe97..fb5f1fa 100644 --- a/src/client/resources/assets/molehunt/lang/en_us.json +++ b/src/client/resources/assets/molehunt/lang/en_us.json @@ -3,11 +3,12 @@ "commands.molehunt.timer.show": "Showing Molehunt timer.", "commands.molehunt.timer.hide": "Hiding Molehunt timer.", "commands.molehunt.moles.list": "List of moles:", + "commands.molehunt.moles.list.deny": "You can't see the list of moles.", "commands.molehunt.stop.success": "The Molehunt game has been stopped.", "molehunt.game.end.suspense.title": "§eAnd the winners are...", "molehunt.game.end.winners.moles.title": "§cThe Moles!", "molehunt.game.end.winners.survivors.title": "§aNot the Moles!", - "molehunt.game.end.winners.subtitle": "§6The Moles were", + "molehunt.game.end.winners.subtitle": "§6The Moles were ", "molehunt.game.start.suspense": "§eYou are...", "molehunt.game.start.mole.title": "§cThe Mole!", "molehunt.game.start.mole.subtitle": "§eGet the list of moles with §6/molehunt moles", diff --git a/src/client/resources/assets/molehunt/lang/fr_fr.json b/src/client/resources/assets/molehunt/lang/fr_fr.json index c5c87d4..5a47c07 100644 --- a/src/client/resources/assets/molehunt/lang/fr_fr.json +++ b/src/client/resources/assets/molehunt/lang/fr_fr.json @@ -3,11 +3,12 @@ "commands.molehunt.timer.show": "Affiche le timer.", "commands.molehunt.timer.hide": "Cache le timer.", "commands.molehunt.moles.list": "Liste des taupes:", + "commands.molehunt.moles.list.deny": "Vous ne pouvez pas voir la liste des taupes.", "commands.molehunt.stop.success": "La partie de Molehunt a été stoppée.", "molehunt.game.end.suspense.title": "§eEt les gagnants sont...", "molehunt.game.end.winners.moles.title": "§cLes Taupes !", "molehunt.game.end.winners.survivors.title": "§aPas les Taupes !", - "molehunt.game.end.winners.subtitle": "§Les Taupes sont", + "molehunt.game.end.winners.subtitle": "§Les Taupes sont ", "molehunt.game.start.suspense": "§eVous êtes...", "molehunt.game.start.mole.title": "§cLa Taupe !", "molehunt.game.start.mole.subtitle": "§eRécupérer la liste des taupes avec §6/molehunt moles", diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 6101525..89ee9b3 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -158,7 +158,7 @@ public class Game { } public boolean isAMole(ServerPlayerEntity player) { - return moles.contains(player); + return hasStarted() && moles.contains(player); } public boolean gameWonByMoles() { diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 0ec3c3b..a07cb18 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -108,8 +108,13 @@ public class Molehunt implements ModInitializer { return Command.SINGLE_SUCCESS; }) )); - command.then(literal("moles").requires(source -> (game != null) && game.hasStarted() && game.isAMole(source.getPlayer())).executes(context -> { - context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.moles.list").append(" " + game.getMolesAsString()),false); + command.then(literal("moles").executes(context -> { + final var source = context.getSource(); + if (game == null || !game.isAMole(source.getPlayer())) { + source.sendFeedback(() -> Text.translatable("commands.molehunt.moles.list.deny"),false); + return Command.SINGLE_SUCCESS; + } + source.sendFeedback(() -> Text.translatable("commands.molehunt.moles.list").append(" " + game.getMolesAsString()),false); return Command.SINGLE_SUCCESS; })); command.then(literal("stop").requires(source -> source.hasPermissionLevel(1)).executes(context -> { -- cgit v1.2.3 From a26e8d4b279a55af41c665a0a95fd733ebd76471 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 20:59:54 +0000 Subject: fix(game): gamerules reset after restart (or leave/reconnect in the world) --- .../java/world/anhgelus/molehunt/Molehunt.java | 33 +++++++++++++--------- .../world/anhgelus/molehunt/config/Config.java | 27 ++++-------------- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index a07cb18..aba2ad4 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -23,6 +23,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import world.anhgelus.molehunt.config.Config; import world.anhgelus.molehunt.config.ConfigPayload; +import world.anhgelus.molehunt.config.SimpleConfig; import java.util.HashMap; @@ -35,19 +36,27 @@ public class Molehunt implements ModInitializer { public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); public static Config CONFIG; + public static final SimpleConfig CONFIG_FILE = Config.configFile(MOD_ID); + public static final GameRules.Key GAME_DURATION = GameRuleRegistry.register( - "gameDuration", GameRules.Category.MISC, GameRuleFactory.createIntRule(90) + "gameDuration", + GameRules.Category.MISC, + GameRuleFactory.createIntRule(CONFIG_FILE.getOrDefault("game_duration", 90)) ); public static final GameRules.Key MOLE_PERCENTAGE = GameRuleRegistry.register( - "molePercentage", GameRules.Category.MISC, GameRuleFactory.createIntRule(25) + "molePercentage", + GameRules.Category.MISC, + GameRuleFactory.createIntRule(CONFIG_FILE.getOrDefault("mole_percentage", 25)) ); public static final GameRules.Key MOLE_COUNT = GameRuleRegistry.register( - "moleCount", GameRules.Category.MISC, GameRuleFactory.createIntRule(-1) + "moleCount", + GameRules.Category.MISC, + GameRuleFactory.createIntRule(CONFIG_FILE.getOrDefault("mole_count", -1)) ); public static final GameRules.Key SHOW_NAMETAGS = GameRuleRegistry.register( "showNametags", GameRules.Category.MISC, - GameRuleFactory.createBooleanRule(false, (server, val) -> { + GameRuleFactory.createBooleanRule(CONFIG_FILE.getOrDefault("show_nametags", false), (server, val) -> { if (CONFIG == null) return; CONFIG.sendConfigPayload(); }) @@ -55,7 +64,7 @@ public class Molehunt implements ModInitializer { public static final GameRules.Key SHOW_TAB = GameRuleRegistry.register( "showTab" , GameRules.Category.MISC, - GameRuleFactory.createBooleanRule(false, (server, val) -> { + GameRuleFactory.createBooleanRule(CONFIG_FILE.getOrDefault("show_tab", false), (server, val) -> { if (CONFIG == null) return; CONFIG.sendConfigPayload(); }) @@ -63,7 +72,7 @@ public class Molehunt implements ModInitializer { public static final GameRules.Key SHOW_SKINS = GameRuleRegistry.register( "showSkins", GameRules.Category.MISC, - GameRuleFactory.createBooleanRule(false, (server, val) -> { + GameRuleFactory.createBooleanRule(CONFIG_FILE.getOrDefault("show_skins", false), (server, val) -> { if (CONFIG == null) return; CONFIG.sendConfigPayload(); }) @@ -127,7 +136,7 @@ public class Molehunt implements ModInitializer { return Command.SINGLE_SUCCESS; })); - ServerLifecycleEvents.SERVER_STARTED.register(server -> CONFIG = new Config(MOD_ID, server)); + ServerLifecycleEvents.SERVER_STARTED.register(server -> CONFIG = new Config(server)); CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(command)); @@ -145,12 +154,10 @@ public class Molehunt implements ModInitializer { newPlayer.changeGameMode(GameMode.SPECTATOR); }); - ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { - ServerPlayNetworking.send( - handler.player, - new ConfigPayload(CONFIG.areNametagsEnabled(), CONFIG.areSkinsEnabled(), CONFIG.isTabEnabled()) - ); - }); + ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> ServerPlayNetworking.send( + handler.player, + new ConfigPayload(CONFIG.areNametagsEnabled(), CONFIG.areSkinsEnabled(), CONFIG.isTabEnabled()) + )); PayloadTypeRegistry.playS2C().register(ConfigPayload.ID, ConfigPayload.CODEC); } diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java index 03ca86e..dbaebcf 100644 --- a/src/main/java/world/anhgelus/molehunt/config/Config.java +++ b/src/main/java/world/anhgelus/molehunt/config/Config.java @@ -8,29 +8,10 @@ public class Config { private final MinecraftServer server; - public Config(String fileName, MinecraftServer server) { - final SimpleConfig CONFIG = SimpleConfig.of(fileName).provider(Config::defaultConfig).request(); - + public Config(MinecraftServer server) { this.server = server; - final var rules = server.getGameRules(); - - // In seconds - final var gameDuration = CONFIG.getOrDefault("game_duration", 90) * 60; - rules.get(Molehunt.GAME_DURATION).set(gameDuration/60, server); - final var molePercentage = CONFIG.getOrDefault("mole_percentage", 25); - rules.get(Molehunt.MOLE_PERCENTAGE).set(molePercentage, server); - final var moleCount = CONFIG.getOrDefault("mole_count", -1); - rules.get(Molehunt.MOLE_COUNT).set(moleCount, server); - // bool - final var showNametags = CONFIG.getOrDefault("show_nametags", false); - rules.get(Molehunt.SHOW_NAMETAGS).set(showNametags, server); - final var showSkins = CONFIG.getOrDefault("show_skins", false); - rules.get(Molehunt.SHOW_SKINS).set(showSkins, server); - final var showTab = CONFIG.getOrDefault("show_tab", false); - rules.get(Molehunt.SHOW_TAB).set(showTab, server); - - sendConfigPayload(showNametags, showSkins, showTab); + sendConfigPayload(areNametagsEnabled(), areSkinsEnabled(), isTabEnabled()); } public void sendConfigPayload() { @@ -69,6 +50,10 @@ public class Config { return server.getGameRules().getBoolean(Molehunt.SHOW_TAB); } + public static SimpleConfig configFile(String fileName) { + return SimpleConfig.of(fileName).provider(Config::defaultConfig).request(); + } + private static String defaultConfig(String s) { return """ # Molehunt mod configuration file -- cgit v1.2.3 From b5434aa054090fd8a3c67590363c0638cb7eb612 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 21:02:47 +0000 Subject: docs(info): update config section in readme --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f352a66..bbc6634 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,10 @@ You can configure every text line and the skin with a resource pack (for referen skin file](src/client/resources/assets/molehunt/textures/skin.png)). Also, more server-side values can be changed in the configuration file, located in your server config directory. +These settings will be applied by default to every new world. +If you want to customize only one world, use the gamerules. -The configuration can be modified in game with these gamerules: +Every setting can be modified in game with these gamerules: - `gameDuration` - `molePercentage` - `moleCount` -- cgit v1.2.3 From 4e15b847ada05e7539ca2b8e45dce770f1b300ef Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 21:09:08 +0000 Subject: style(game): add mod_id prefix to all gamerules --- src/client/resources/assets/molehunt/lang/en_us.json | 12 ++++++------ src/client/resources/assets/molehunt/lang/fr_fr.json | 12 ++++++------ src/main/java/world/anhgelus/molehunt/Molehunt.java | 12 ++++++------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json index fb5f1fa..7d882e4 100644 --- a/src/client/resources/assets/molehunt/lang/en_us.json +++ b/src/client/resources/assets/molehunt/lang/en_us.json @@ -13,10 +13,10 @@ "molehunt.game.start.mole.title": "§cThe Mole!", "molehunt.game.start.mole.subtitle": "§eGet the list of moles with §6/molehunt moles", "molehunt.game.start.survivor": "§aNot the Mole!", - "gamerule.gameDuration": "Duration of a game", - "gamerule.molePercentage": "Percentage of Mole", - "gamerule.moleCount": "Number of Mole", - "gamerule.showNametags": "Show players' nametag", - "gamerule.showTab": "Enable the tab", - "gamerule.showSkins": "Show players' skin" + "gamerule.molehunt:gameDuration": "Duration of a game", + "gamerule.molehunt:molePercentage": "Percentage of Mole", + "gamerule.molehunt:moleCount": "Number of Mole", + "gamerule.molehunt:showNametags": "Show players' nametag", + "gamerule.molehunt:showTab": "Enable the tab", + "gamerule.molehunt:showSkins": "Show players' skin" } \ No newline at end of file diff --git a/src/client/resources/assets/molehunt/lang/fr_fr.json b/src/client/resources/assets/molehunt/lang/fr_fr.json index 5a47c07..cfd52d8 100644 --- a/src/client/resources/assets/molehunt/lang/fr_fr.json +++ b/src/client/resources/assets/molehunt/lang/fr_fr.json @@ -13,10 +13,10 @@ "molehunt.game.start.mole.title": "§cLa Taupe !", "molehunt.game.start.mole.subtitle": "§eRécupérer la liste des taupes avec §6/molehunt moles", "molehunt.game.start.survivor": "§aPas la Taupe!", - "gamerule.gameDuration": "Durée d'une partie", - "gamerule.molePercentage": "Pourcentage de Taupes", - "gamerule.moleCount": "Nombre de Taupes", - "gamerule.showNametags": "Affiche les nametags des joueurs", - "gamerule.showTab": "Active le tab", - "gamerule.showSkins": "Affiche les skins des joueurs" + "gamerule.molehunt:gameDuration": "Durée d'une partie", + "gamerule.molehunt:molePercentage": "Pourcentage de Taupes", + "gamerule.molehunt:moleCount": "Nombre de Taupes", + "gamerule.molehunt:showNametags": "Affiche les nametags des joueurs", + "gamerule.molehunt:showTab": "Active le tab", + "gamerule.molehunt:showSkins": "Affiche les skins des joueurs" } \ No newline at end of file diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index aba2ad4..7a55450 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -39,22 +39,22 @@ public class Molehunt implements ModInitializer { public static final SimpleConfig CONFIG_FILE = Config.configFile(MOD_ID); public static final GameRules.Key GAME_DURATION = GameRuleRegistry.register( - "gameDuration", + MOD_ID +":gameDuration", GameRules.Category.MISC, GameRuleFactory.createIntRule(CONFIG_FILE.getOrDefault("game_duration", 90)) ); public static final GameRules.Key MOLE_PERCENTAGE = GameRuleRegistry.register( - "molePercentage", + MOD_ID +":molePercentage", GameRules.Category.MISC, GameRuleFactory.createIntRule(CONFIG_FILE.getOrDefault("mole_percentage", 25)) ); public static final GameRules.Key MOLE_COUNT = GameRuleRegistry.register( - "moleCount", + MOD_ID +":moleCount", GameRules.Category.MISC, GameRuleFactory.createIntRule(CONFIG_FILE.getOrDefault("mole_count", -1)) ); public static final GameRules.Key SHOW_NAMETAGS = GameRuleRegistry.register( - "showNametags", + MOD_ID +":showNametags", GameRules.Category.MISC, GameRuleFactory.createBooleanRule(CONFIG_FILE.getOrDefault("show_nametags", false), (server, val) -> { if (CONFIG == null) return; @@ -62,7 +62,7 @@ public class Molehunt implements ModInitializer { }) ); public static final GameRules.Key SHOW_TAB = GameRuleRegistry.register( - "showTab" + MOD_ID +":showTab" , GameRules.Category.MISC, GameRuleFactory.createBooleanRule(CONFIG_FILE.getOrDefault("show_tab", false), (server, val) -> { if (CONFIG == null) return; @@ -70,7 +70,7 @@ public class Molehunt implements ModInitializer { }) ); public static final GameRules.Key SHOW_SKINS = GameRuleRegistry.register( - "showSkins", + MOD_ID +":showSkins", GameRules.Category.MISC, GameRuleFactory.createBooleanRule(CONFIG_FILE.getOrDefault("show_skins", false), (server, val) -> { if (CONFIG == null) return; -- cgit v1.2.3 From 191d51a2c337d37a83d6076abf5c67c76f6235b7 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 21:10:15 +0000 Subject: docs(info): update new gamerules' name in readme --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bbc6634..f739a69 100644 --- a/README.md +++ b/README.md @@ -35,12 +35,12 @@ These settings will be applied by default to every new world. If you want to customize only one world, use the gamerules. Every setting can be modified in game with these gamerules: -- `gameDuration` -- `molePercentage` -- `moleCount` -- `showNametags` -- `showTab` -- `showSkins` +- `molehunt:gameDuration` +- `molehunt:molePercentage` +- `molehunt:moleCount` +- `molehunt:showNametags` +- `molehunt:showTab` +- `molehunt:showSkins` ## Technologies -- cgit v1.2.3 From 6401c130571f5dbd069cd04e7b1c58fb97d6de08 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 22:26:50 +0000 Subject: fix(game): ending game just after the start --- src/main/java/world/anhgelus/molehunt/Game.java | 4 ++-- src/main/java/world/anhgelus/molehunt/Molehunt.java | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index 89ee9b3..ce6f335 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -89,7 +89,6 @@ public class Game { // reset time and weather server.getOverworld().setTimeOfDay(0); server.getOverworld().resetWeather(); - started = true; timer.scheduleAtFixedRate(new TimerTask() { @@ -137,6 +136,7 @@ public class Game { pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle").append(getMolesAsString()))); pm.sendToAll(winner); pm.sendToAll(timing); + moles.clear(); } }, 4*1000); } @@ -158,7 +158,7 @@ public class Game { } public boolean isAMole(ServerPlayerEntity player) { - return hasStarted() && moles.contains(player); + return moles.contains(player); } public boolean gameWonByMoles() { diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index 7a55450..c6ce7c7 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -102,7 +102,7 @@ public class Molehunt implements ModInitializer { if (game == null || !game.hasStarted()) { player.networkHandler.sendPacket(new OverlayMessageS2CPacket( - Text.translatable("commands.molehunt.stop.failed").setStyle(Style.EMPTY.withColor(16733525)) + Text.translatable("commands.molehunt.stop.failed").setStyle(Style.EMPTY.withColor(16733525)) )); } else { player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(game.getShortRemainingText()))); @@ -144,6 +144,7 @@ public class Molehunt implements ModInitializer { ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> { if (!(entity instanceof ServerPlayerEntity) || game == null) return; + if (!game.hasStarted()) return; if (game.gameWonByMoles()) game.end(); }); -- cgit v1.2.3 From d1d56e097d1aaa90358069370f454e65fc9dbbd5 Mon Sep 17 00:00:00 2001 From: anhgelus Date: Fri, 23 Aug 2024 22:29:40 +0000 Subject: feat(command): disable autocompletion for /molehunt moles when not mole --- src/client/resources/assets/molehunt/lang/en_us.json | 2 +- src/client/resources/assets/molehunt/lang/fr_fr.json | 2 +- src/main/java/world/anhgelus/molehunt/Game.java | 4 +++- src/main/java/world/anhgelus/molehunt/Molehunt.java | 9 ++------- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/client/resources/assets/molehunt/lang/en_us.json b/src/client/resources/assets/molehunt/lang/en_us.json index 7d882e4..3a50d81 100644 --- a/src/client/resources/assets/molehunt/lang/en_us.json +++ b/src/client/resources/assets/molehunt/lang/en_us.json @@ -8,7 +8,7 @@ "molehunt.game.end.suspense.title": "§eAnd the winners are...", "molehunt.game.end.winners.moles.title": "§cThe Moles!", "molehunt.game.end.winners.survivors.title": "§aNot the Moles!", - "molehunt.game.end.winners.subtitle": "§6The Moles were ", + "molehunt.game.end.winners.subtitle": "§6The Moles were", "molehunt.game.start.suspense": "§eYou are...", "molehunt.game.start.mole.title": "§cThe Mole!", "molehunt.game.start.mole.subtitle": "§eGet the list of moles with §6/molehunt moles", diff --git a/src/client/resources/assets/molehunt/lang/fr_fr.json b/src/client/resources/assets/molehunt/lang/fr_fr.json index cfd52d8..bb73ca8 100644 --- a/src/client/resources/assets/molehunt/lang/fr_fr.json +++ b/src/client/resources/assets/molehunt/lang/fr_fr.json @@ -8,7 +8,7 @@ "molehunt.game.end.suspense.title": "§eEt les gagnants sont...", "molehunt.game.end.winners.moles.title": "§cLes Taupes !", "molehunt.game.end.winners.survivors.title": "§aPas les Taupes !", - "molehunt.game.end.winners.subtitle": "§Les Taupes sont ", + "molehunt.game.end.winners.subtitle": "§Les Taupes sont", "molehunt.game.start.suspense": "§eVous êtes...", "molehunt.game.start.mole.title": "§cLa Taupe !", "molehunt.game.start.mole.subtitle": "§eRécupérer la liste des taupes avec §6/molehunt moles", diff --git a/src/main/java/world/anhgelus/molehunt/Game.java b/src/main/java/world/anhgelus/molehunt/Game.java index ce6f335..dbe7ebd 100644 --- a/src/main/java/world/anhgelus/molehunt/Game.java +++ b/src/main/java/world/anhgelus/molehunt/Game.java @@ -133,7 +133,9 @@ public class Game { } else { winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.survivors.title")); } - pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle").append(getMolesAsString()))); + pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle") + .append(" " + getMolesAsString())) + ); pm.sendToAll(winner); pm.sendToAll(timing); moles.clear(); diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index c6ce7c7..d7c0d58 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -117,13 +117,8 @@ public class Molehunt implements ModInitializer { return Command.SINGLE_SUCCESS; }) )); - command.then(literal("moles").executes(context -> { - final var source = context.getSource(); - if (game == null || !game.isAMole(source.getPlayer())) { - source.sendFeedback(() -> Text.translatable("commands.molehunt.moles.list.deny"),false); - return Command.SINGLE_SUCCESS; - } - source.sendFeedback(() -> Text.translatable("commands.molehunt.moles.list").append(" " + game.getMolesAsString()),false); + command.then(literal("moles").requires(source -> game != null && game.isAMole(source.getPlayer())).executes(context -> { + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.moles.list").append(" " + game.getMolesAsString()),false); return Command.SINGLE_SUCCESS; })); command.then(literal("stop").requires(source -> source.hasPermissionLevel(1)).executes(context -> { -- cgit v1.2.3