diff options
| author | Anhgelus Morhtuuzh <william@herges.fr> | 2026-03-18 13:11:45 +0100 |
|---|---|---|
| committer | Anhgelus Morhtuuzh <william@herges.fr> | 2026-03-18 13:11:45 +0100 |
| commit | 7ba39f866a3ab293ce81b5397c1e2975241919cb (patch) | |
| tree | e2292d94c7b83ede75c72fff61c4bffd5c8de3b3 /src/main/java/world | |
| parent | 3b694a936c7138acc5eaca3da2ec528c2e8c0894 (diff) | |
style(): switch to tab and to lf
Diffstat (limited to 'src/main/java/world')
13 files changed, 915 insertions, 927 deletions
diff --git a/src/main/java/world/anhgelus/molehunt/Molehunt.java b/src/main/java/world/anhgelus/molehunt/Molehunt.java index d5df320..6486700 100644 --- a/src/main/java/world/anhgelus/molehunt/Molehunt.java +++ b/src/main/java/world/anhgelus/molehunt/Molehunt.java @@ -40,199 +40,186 @@ import static net.minecraft.server.command.CommandManager.literal; 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; - - public static final SimpleConfig CONFIG_FILE = Config.configFile(MOD_ID); - - public static final GameRule<Integer> GAME_DURATION = GameRuleBuilder - .forInteger(CONFIG_FILE.getOrDefault("game_duration", 90)) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "gameDurationMinutes")); - - public static final GameRule<Integer> MOLE_PERCENTAGE = GameRuleBuilder - .forInteger(CONFIG_FILE.getOrDefault("mole_percentage", 25)) - .range(0, 100) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "molePercentage")); - - public static final GameRule<Integer> MOLE_COUNT = GameRuleBuilder - .forInteger(CONFIG_FILE.getOrDefault("mole_count", -1)) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "moleCount")); - - public static final GameRule<Boolean> SHOW_NAMETAGS = GameRuleBuilder - .forBoolean(CONFIG_FILE.getOrDefault("show_nametags", false)) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "showNametags")); - - public static final GameRule<Boolean> SHOW_TAB = GameRuleBuilder - .forBoolean(CONFIG_FILE.getOrDefault("show_tab", false)) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "showTab")); - - public static final GameRule<Boolean> SHOW_SKINS = GameRuleBuilder - .forBoolean(CONFIG_FILE.getOrDefault("show_skins", false)) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "showSkins")); - - public static final GameRule<Integer> INITIAL_WORLD_SIZE = GameRuleBuilder - .forInteger(CONFIG_FILE.getOrDefault("initial_world_size", 600)) - .minValue(0) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "initialWorldSize")); - - public static final GameRule<Integer> FINAL_WORLD_SIZE = GameRuleBuilder - .forInteger(CONFIG_FILE.getOrDefault("final_world_size", 100)) - .minValue(0) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "finalWorldSize")); - - public static final GameRule<Integer> MOVING_STARTING_TIME_OFFSET = GameRuleBuilder - .forInteger(CONFIG_FILE.getOrDefault("border_moving_starting_time_offset", 30)) - .minValue(0) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "borderMovingStartingTimeOffsetMinutes")); - - public static final GameRule<Boolean> ENABLE_PORTALS = GameRuleBuilder - .forBoolean(CONFIG_FILE.getOrDefault("enable_portals", false)) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "enablePortals")); - - public static final GameRule<Boolean> FOOD_ON_START = GameRuleBuilder - .forBoolean(CONFIG_FILE.getOrDefault("food_on_start", true)) - .category(GameRuleCategory.MISC) - .buildAndRegister(Identifier.of(MOD_ID, "foodOnStart")); - - public Game game; - - public static HashMap<UUID, Boolean> timerVisibility = new HashMap<>(); - - private static <T> void sendConfigPayload(T v, MinecraftServer server) { - if (CONFIG == null) return; - CONFIG.sendConfigPayload(); - } - - static { - GameRuleEvents.changeCallback(SHOW_NAMETAGS).register(Molehunt::sendConfigPayload); - GameRuleEvents.changeCallback(SHOW_TAB).register(Molehunt::sendConfigPayload); - GameRuleEvents.changeCallback(SHOW_SKINS).register(Molehunt::sendConfigPayload); - } - - @Override - public void onInitialize() { - LOGGER.info("Initializing Molehunt"); - - final var command = literal("molehunt"); - command.then(literal("start") - .requires(CommandManager.requirePermissionLevel(CommandManager.GAMEMASTERS_CHECK)) - .executes(context -> { - game = new Game(context.getSource().getServer()); - game.start(); - return Command.SINGLE_SUCCESS; - })); - command.then(literal("timer").requires(ServerCommandSource::isExecutedByPlayer).then( - literal("show").executes(context -> { - var player = context.getSource().getPlayer(); - assert player != null; - - timerVisibility.put(player.getUuid(), true); - context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.show"), false); - - if (game == null || !game.started()) { - player.networkHandler.sendPacket(new OverlayMessageS2CPacket( - Text.translatable("commands.molehunt.error.game_not_started").formatted(Formatting.RED) - )); - } else { - player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(game.getRemainingText()))); - } - - return Command.SINGLE_SUCCESS; - }) - ).then( - literal("hide").executes(context -> { - var player = context.getSource().getPlayer(); - assert player != null; - - timerVisibility.put(player.getUuid(), false); - context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.hide"), false); - return Command.SINGLE_SUCCESS; - }) - )); - command.then(literal("role") - .requires(ServerCommandSource::isExecutedByPlayer) - .executes(context -> { - if (game == null || !game.started()) { - throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.error.game_not_started"))).create(); - } - - final var source = context.getSource(); - final var player = source.getPlayer(); - assert player != null; - - if (game.isMole(player)) { - source.sendFeedback( - () -> Text.translatable("commands.molehunt.role.mole") - .append("\n\n") - .append(Text.translatable("commands.molehunt.role.mole.list", game.getMolesAsString())), - false); - } else if (player.isSpectator()) { - source.sendFeedback( - () -> Text.translatable("commands.molehunt.role.survivor.mole_count", game.getMoles().size()), - false); - } else { - source.sendFeedback( - () -> Text.translatable("commands.molehunt.role.survivor") - .append("\n\n") - .append(Text.translatable("commands.molehunt.role.survivor.mole_count", game.getMoles().size())), - false); - } - - return Command.SINGLE_SUCCESS; - })); - command.then(literal("stop") - .requires(CommandManager.requirePermissionLevel(CommandManager.GAMEMASTERS_CHECK)) - .executes(context -> { - if (game == null || !game.started()) { - throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.error.game_not_started"))).create(); - } - - game.stop(); - - return Command.SINGLE_SUCCESS; - })); - - ServerLifecycleEvents.SERVER_STARTED.register(server -> CONFIG = new Config(server)); - - CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(command)); - - ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> false); - - ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> { - if (!(entity instanceof ServerPlayerEntity) || game == null) return; - if (!game.started()) return; - if (game.wonByMoles()) game.end(); - }); - - ServerPlayerEvents.AFTER_RESPAWN.register((oldPlayer, newPlayer, alive) -> { - if (game == null) return; - if (!game.started()) return; - newPlayer.changeGameMode(GameMode.SPECTATOR); - }); - - ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { - ServerPlayNetworking.send( - handler.player, - new ConfigPayload(CONFIG.nametagsEnabled(), CONFIG.skinsEnabled(), CONFIG.tabEnabled()) - ); - ServerPlayNetworking.send( - handler.player, - new GamePayload(game != null && game.started()) - ); - }); - - PayloadTypeRegistry.playS2C().register(ConfigPayload.ID, ConfigPayload.CODEC); - PayloadTypeRegistry.playS2C().register(GamePayload.ID, GamePayload.CODEC); - } + public static final String MOD_ID = "molehunt"; + public static final Logger LOGGER = LoggerFactory.getLogger(MOD_ID); + public static final SimpleConfig CONFIG_FILE = Config.configFile(MOD_ID); + public static final GameRule<Integer> GAME_DURATION = GameRuleBuilder + .forInteger(CONFIG_FILE.getOrDefault("game_duration", 90)) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "gameDurationMinutes")); + public static final GameRule<Integer> MOLE_PERCENTAGE = GameRuleBuilder + .forInteger(CONFIG_FILE.getOrDefault("mole_percentage", 25)) + .range(0, 100) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "molePercentage")); + public static final GameRule<Integer> MOLE_COUNT = GameRuleBuilder + .forInteger(CONFIG_FILE.getOrDefault("mole_count", -1)) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "moleCount")); + public static final GameRule<Boolean> SHOW_NAMETAGS = GameRuleBuilder + .forBoolean(CONFIG_FILE.getOrDefault("show_nametags", false)) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "showNametags")); + public static final GameRule<Boolean> SHOW_TAB = GameRuleBuilder + .forBoolean(CONFIG_FILE.getOrDefault("show_tab", false)) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "showTab")); + public static final GameRule<Boolean> SHOW_SKINS = GameRuleBuilder + .forBoolean(CONFIG_FILE.getOrDefault("show_skins", false)) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "showSkins")); + public static final GameRule<Integer> INITIAL_WORLD_SIZE = GameRuleBuilder + .forInteger(CONFIG_FILE.getOrDefault("initial_world_size", 600)) + .minValue(0) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "initialWorldSize")); + public static final GameRule<Integer> FINAL_WORLD_SIZE = GameRuleBuilder + .forInteger(CONFIG_FILE.getOrDefault("final_world_size", 100)) + .minValue(0) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "finalWorldSize")); + public static final GameRule<Integer> MOVING_STARTING_TIME_OFFSET = GameRuleBuilder + .forInteger(CONFIG_FILE.getOrDefault("border_moving_starting_time_offset", 30)) + .minValue(0) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "borderMovingStartingTimeOffsetMinutes")); + public static final GameRule<Boolean> ENABLE_PORTALS = GameRuleBuilder + .forBoolean(CONFIG_FILE.getOrDefault("enable_portals", false)) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "enablePortals")); + public static final GameRule<Boolean> FOOD_ON_START = GameRuleBuilder + .forBoolean(CONFIG_FILE.getOrDefault("food_on_start", true)) + .category(GameRuleCategory.MISC) + .buildAndRegister(Identifier.of(MOD_ID, "foodOnStart")); + public static Config CONFIG; + public static HashMap<UUID, Boolean> timerVisibility = new HashMap<>(); + + static { + GameRuleEvents.changeCallback(SHOW_NAMETAGS).register(Molehunt::sendConfigPayload); + GameRuleEvents.changeCallback(SHOW_TAB).register(Molehunt::sendConfigPayload); + GameRuleEvents.changeCallback(SHOW_SKINS).register(Molehunt::sendConfigPayload); + } + + public Game game; + + private static <T> void sendConfigPayload(T v, MinecraftServer server) { + if (CONFIG == null) return; + CONFIG.sendConfigPayload(); + } + + @Override + public void onInitialize() { + LOGGER.info("Initializing Molehunt"); + + final var command = literal("molehunt"); + command.then(literal("start") + .requires(CommandManager.requirePermissionLevel(CommandManager.GAMEMASTERS_CHECK)) + .executes(context -> { + game = new Game(context.getSource().getServer()); + game.start(); + return Command.SINGLE_SUCCESS; + })); + command.then(literal("timer").requires(ServerCommandSource::isExecutedByPlayer).then( + literal("show").executes(context -> { + var player = context.getSource().getPlayer(); + assert player != null; + + timerVisibility.put(player.getUuid(), true); + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.show"), false); + + if (game == null || !game.started()) { + player.networkHandler.sendPacket(new OverlayMessageS2CPacket( + Text.translatable("commands.molehunt.error.game_not_started").formatted(Formatting.RED) + )); + } else { + player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(game.getRemainingText()))); + } + + return Command.SINGLE_SUCCESS; + }) + ).then( + literal("hide").executes(context -> { + var player = context.getSource().getPlayer(); + assert player != null; + + timerVisibility.put(player.getUuid(), false); + context.getSource().sendFeedback(() -> Text.translatable("commands.molehunt.timer.hide"), false); + return Command.SINGLE_SUCCESS; + }) + )); + command.then(literal("role") + .requires(ServerCommandSource::isExecutedByPlayer) + .executes(context -> { + if (game == null || !game.started()) { + throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.error.game_not_started"))).create(); + } + + final var source = context.getSource(); + final var player = source.getPlayer(); + assert player != null; + + if (game.isMole(player)) { + source.sendFeedback( + () -> Text.translatable("commands.molehunt.role.mole") + .append("\n\n") + .append(Text.translatable("commands.molehunt.role.mole.list", game.getMolesAsString())), + false); + } else if (player.isSpectator()) { + source.sendFeedback( + () -> Text.translatable("commands.molehunt.role.survivor.mole_count", game.getMoles().size()), + false); + } else { + source.sendFeedback( + () -> Text.translatable("commands.molehunt.role.survivor") + .append("\n\n") + .append(Text.translatable("commands.molehunt.role.survivor.mole_count", game.getMoles().size())), + false); + } + + return Command.SINGLE_SUCCESS; + })); + command.then(literal("stop") + .requires(CommandManager.requirePermissionLevel(CommandManager.GAMEMASTERS_CHECK)) + .executes(context -> { + if (game == null || !game.started()) { + throw (new SimpleCommandExceptionType(Text.translatable("commands.molehunt.error.game_not_started"))).create(); + } + + game.stop(); + + return Command.SINGLE_SUCCESS; + })); + + ServerLifecycleEvents.SERVER_STARTED.register(server -> CONFIG = new Config(server)); + + CommandRegistrationCallback.EVENT.register((dispatcher, registryAccess, environment) -> dispatcher.register(command)); + + ServerMessageEvents.ALLOW_CHAT_MESSAGE.register((message, sender, params) -> false); + + ServerLivingEntityEvents.AFTER_DEATH.register((entity, damageSource) -> { + if (!(entity instanceof ServerPlayerEntity) || game == null) return; + if (!game.started()) return; + if (game.wonByMoles()) game.end(); + }); + + ServerPlayerEvents.AFTER_RESPAWN.register((oldPlayer, newPlayer, alive) -> { + if (game == null) return; + if (!game.started()) return; + newPlayer.changeGameMode(GameMode.SPECTATOR); + }); + + ServerPlayConnectionEvents.JOIN.register((handler, sender, server) -> { + ServerPlayNetworking.send( + handler.player, + new ConfigPayload(CONFIG.nametagsEnabled(), CONFIG.skinsEnabled(), CONFIG.tabEnabled()) + ); + ServerPlayNetworking.send( + handler.player, + new GamePayload(game != null && game.started()) + ); + }); + + PayloadTypeRegistry.playS2C().register(ConfigPayload.ID, ConfigPayload.CODEC); + PayloadTypeRegistry.playS2C().register(GamePayload.ID, GamePayload.CODEC); + } } diff --git a/src/main/java/world/anhgelus/molehunt/config/Config.java b/src/main/java/world/anhgelus/molehunt/config/Config.java index 08c3850..d65b569 100644 --- a/src/main/java/world/anhgelus/molehunt/config/Config.java +++ b/src/main/java/world/anhgelus/molehunt/config/Config.java @@ -6,135 +6,135 @@ import world.anhgelus.molehunt.Molehunt; public class Config { - private final MinecraftServer server; - - public Config(MinecraftServer server) { - this.server = server; - - sendConfigPayload(nametagsEnabled(), skinsEnabled(), tabEnabled()); - } - - public void sendConfigPayload() { - final var payload = new ConfigPayload(nametagsEnabled(), skinsEnabled(), tabEnabled()); - 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.getOverworld().getGameRules().getValue(Molehunt.GAME_DURATION); - } - - public int getMolePercentage() { - return server.getOverworld().getGameRules().getValue(Molehunt.MOLE_PERCENTAGE); - } - - public int getMoleCount() { - return server.getOverworld().getGameRules().getValue(Molehunt.MOLE_COUNT); - } - - public boolean nametagsEnabled() { - return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_NAMETAGS); - } - - public boolean skinsEnabled() { - return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_SKINS); - } - - public boolean tabEnabled() { - return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_TAB); - } - - public int getInitialWorldSize() { - return server.getOverworld().getGameRules().getValue(Molehunt.INITIAL_WORLD_SIZE); - } - - public int getFinalWorldSize() { - return server.getOverworld().getGameRules().getValue(Molehunt.FINAL_WORLD_SIZE); - } - - public int getBorderShrinkingStartingTimeOffset() { - return server.getOverworld().getGameRules().getValue(Molehunt.MOVING_STARTING_TIME_OFFSET); - } - - public boolean portalsEnabled() { - return server.getOverworld().getGameRules().getValue(Molehunt.ENABLE_PORTALS); - } - - public boolean foodOnStart() { - return server.getOverworld().getGameRules().getValue(Molehunt.FOOD_ON_START); - } - - 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 - # To regenerate the default configuration, delete, move or rename this file. - - # Game settings - - # 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). - # This setting will overwrite the mole_percentage setting. - # If set below 0, this setting is disabled. - # Default: -1. - mole_count = -1 - - # Give food on start - # Default: true - food_on_start = true - - - # Client-side settings (applies to all players) - - # Show nametags - # Default: false - show_nametags = false - - # Show skins - # Default: false - show_skins = false - - # Show tab - # Default: false - show_tab = false - - - # World border settings - - # Initial world size (in blocks). - # Default: 600 blocks. - initial_world_size = 600 - - # Final world size (in blocks). - # Default: 100 blocks. - final_world_size = 100 - - # Moving starting time offset (in minutes) - # The time before starting to move the world borders. - # If this value is greater than the game duration, borders will never move. - # Default: 30 minutes. - border_moving_starting_time_offset = 30 - - # Other - - # Enable portals (nether, end, end gateway). - # Default: false. - enable_portals = false - """; - } + private final MinecraftServer server; + + public Config(MinecraftServer server) { + this.server = server; + + sendConfigPayload(nametagsEnabled(), skinsEnabled(), tabEnabled()); + } + + 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 + # To regenerate the default configuration, delete, move or rename this file. + + # Game settings + + # 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). + # This setting will overwrite the mole_percentage setting. + # If set below 0, this setting is disabled. + # Default: -1. + mole_count = -1 + + # Give food on start + # Default: true + food_on_start = true + + + # Client-side settings (applies to all players) + + # Show nametags + # Default: false + show_nametags = false + + # Show skins + # Default: false + show_skins = false + + # Show tab + # Default: false + show_tab = false + + + # World border settings + + # Initial world size (in blocks). + # Default: 600 blocks. + initial_world_size = 600 + + # Final world size (in blocks). + # Default: 100 blocks. + final_world_size = 100 + + # Moving starting time offset (in minutes) + # The time before starting to move the world borders. + # If this value is greater than the game duration, borders will never move. + # Default: 30 minutes. + border_moving_starting_time_offset = 30 + + # Other + + # Enable portals (nether, end, end gateway). + # Default: false. + enable_portals = false + """; + } + + public void sendConfigPayload() { + final var payload = new ConfigPayload(nametagsEnabled(), skinsEnabled(), tabEnabled()); + 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.getOverworld().getGameRules().getValue(Molehunt.GAME_DURATION); + } + + public int getMolePercentage() { + return server.getOverworld().getGameRules().getValue(Molehunt.MOLE_PERCENTAGE); + } + + public int getMoleCount() { + return server.getOverworld().getGameRules().getValue(Molehunt.MOLE_COUNT); + } + + public boolean nametagsEnabled() { + return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_NAMETAGS); + } + + public boolean skinsEnabled() { + return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_SKINS); + } + + public boolean tabEnabled() { + return server.getOverworld().getGameRules().getValue(Molehunt.SHOW_TAB); + } + + public int getInitialWorldSize() { + return server.getOverworld().getGameRules().getValue(Molehunt.INITIAL_WORLD_SIZE); + } + + public int getFinalWorldSize() { + return server.getOverworld().getGameRules().getValue(Molehunt.FINAL_WORLD_SIZE); + } + + public int getBorderShrinkingStartingTimeOffset() { + return server.getOverworld().getGameRules().getValue(Molehunt.MOVING_STARTING_TIME_OFFSET); + } + + public boolean portalsEnabled() { + return server.getOverworld().getGameRules().getValue(Molehunt.ENABLE_PORTALS); + } + + public boolean foodOnStart() { + return server.getOverworld().getGameRules().getValue(Molehunt.FOOD_ON_START); + } } diff --git a/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java b/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java index b43bd1b..f33e2c5 100644 --- a/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java +++ b/src/main/java/world/anhgelus/molehunt/config/ConfigPayload.java @@ -8,18 +8,18 @@ import net.minecraft.util.Identifier; import world.anhgelus.molehunt.Molehunt;
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 Identifier CONFIG_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "config");
- public static final CustomPayload.Id<ConfigPayload> ID = new CustomPayload.Id<>(CONFIG_PACKET_ID);
- public static final PacketCodec<RegistryByteBuf, ConfigPayload> CODEC = PacketCodec.tuple(
- PacketCodecs.BOOLEAN, ConfigPayload::showNametags,
- PacketCodecs.BOOLEAN, ConfigPayload::showSkins,
- PacketCodecs.BOOLEAN, ConfigPayload::showTab,
- ConfigPayload::new
- );
+ public static final CustomPayload.Id<ConfigPayload> ID = new CustomPayload.Id<>(CONFIG_PACKET_ID);
+ public static final PacketCodec<RegistryByteBuf, ConfigPayload> CODEC = PacketCodec.tuple(
+ PacketCodecs.BOOLEAN, ConfigPayload::showNametags,
+ PacketCodecs.BOOLEAN, ConfigPayload::showSkins,
+ PacketCodecs.BOOLEAN, ConfigPayload::showTab,
+ ConfigPayload::new
+ );
- @Override
- public Id<? extends CustomPayload> getId() {
- return ID;
- }
+ @Override
+ public Id<? extends CustomPayload> getId() {
+ return ID;
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java b/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java index 2b65829..6b7060a 100644 --- a/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java +++ b/src/main/java/world/anhgelus/molehunt/config/SimpleConfig.java @@ -38,216 +38,216 @@ import java.util.Scanner; public class SimpleConfig { - private static final Logger LOGGER = LogManager.getLogger("SimpleConfig"); - private final HashMap<String, String> 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, StandardCharsets.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("{} is missing, generating default one...", identifier); - - try { - createConfig(); - } catch (IOException e) { - LOGGER.error("{} failed to generate!", identifier); - LOGGER.trace( e ); - broken = true; - } - } - - if( !broken ) { - try { - loadConfig(); - } catch (Exception e) { - LOGGER.error("{} failed to load!", identifier); - 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 '{}' was removed from existence! Restart the game to regenerate it.", request.filename); - return request.file.delete(); - } + private static final Logger LOGGER = LogManager.getLogger("SimpleConfig"); + private final HashMap<String, String> config = new HashMap<>(); + private final ConfigRequest request; + private boolean broken = false; + + private SimpleConfig(ConfigRequest request) { + this.request = request; + String identifier = "Config '" + request.filename + "'"; + + if (!request.file.exists()) { + LOGGER.info("{} is missing, generating default one...", identifier); + + try { + createConfig(); + } catch (IOException e) { + LOGGER.error("{} failed to generate!", identifier); + LOGGER.trace(e); + broken = true; + } + } + + if (!broken) { + try { + loadConfig(); + } catch (Exception e) { + LOGGER.error("{} failed to load!", identifier); + LOGGER.trace(e); + broken = true; + } + } + + } + + /** + * 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, StandardCharsets.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 + "!"); + } + } + } + + /** + * 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 '{}' was removed from existence! Restart the game to regenerate it.", request.filename); + return request.file.delete(); + } + + public interface DefaultConfig { + static String empty(String namespace) { + return ""; + } + + String get(String namespace); + } + + 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"; + } + + } }
\ No newline at end of file diff --git a/src/main/java/world/anhgelus/molehunt/game/Game.java b/src/main/java/world/anhgelus/molehunt/game/Game.java index 4f3234c..35c45fa 100644 --- a/src/main/java/world/anhgelus/molehunt/game/Game.java +++ b/src/main/java/world/anhgelus/molehunt/game/Game.java @@ -25,176 +25,176 @@ import java.util.stream.Collectors; public class Game {
- public final int defaultTime = Molehunt.CONFIG.getGameDuration() * 60;
- private final MinecraftServer server;
- private final List<UUID> moles = new ArrayList<>();
- private final TitleFadeS2CPacket timing = new TitleFadeS2CPacket(20, 40, 20);
- private int remaining = defaultTime;
- private boolean started = false;
-
- public Game(MinecraftServer server) {
- this.server = server;
- }
-
- public void start() {
- 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();
-
- final var players = new ArrayList<>(playerManager.getPlayerList());
- 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!");
- moles.add(mole.getUuid());
- players.remove(r);
- }
-
- final var gamerules = server.getOverworld().getGameRules();
- // immutable gamerules
- gamerules.setValue(GameRules.SHOW_DEATH_MESSAGES, false, server);
- gamerules.setValue(GameRules.ANNOUNCE_ADVANCEMENTS, false, server);
- // gamerules for the start
- gamerules.setValue(GameRules.DO_IMMEDIATE_RESPAWN, true, server);
-
- final var timer = TimerAccess.getTimerFromOverworld(server);
-
- final var worldBorder = server.getOverworld().getWorldBorder();
- worldBorder.setSize(Molehunt.CONFIG.getInitialWorldSize());
- if (Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset() < Molehunt.CONFIG.getGameDuration()) {
- timer.dds_runTask(new TickTask(() -> worldBorder.interpolateSize(
- Molehunt.CONFIG.getInitialWorldSize(),
- Molehunt.CONFIG.getFinalWorldSize(),
- (Molehunt.CONFIG.getGameDuration() - Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset()) * 60 * 20L,
- 0L
- ), Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset() * 60 * 20L));
- }
-
- final var title = new TitleS2CPacket(Text.translatable("molehunt.game.start.suspense"));
- playerManager.getPlayerList().forEach(p -> {
- p.getInventory().clear();
- p.kill(p.getEntityWorld());
- p.networkHandler.sendPacket(timing);
- p.networkHandler.sendPacket(title);
- p.changeGameMode(GameMode.SURVIVAL);
- if (Molehunt.CONFIG.foodOnStart()) p.giveItemStack(new ItemStack(Items.COOKED_BEEF, 64));
- });
-
- server.setDefaultGameMode(GameMode.SPECTATOR);
-
- timer.dds_runTask(new TickTask(() -> {
- playerManager.getPlayerList().forEach(p -> {
- p.networkHandler.sendPacket(timing);
- if (moles.contains(p.getUuid())) {
- 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.translatable("molehunt.game.start.survivor.title")));
- p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("molehunt.game.start.survivor.subtitle")));
- }
- // reset health and food level
- p.setHealth(p.getMaxHealth());
- p.getHungerManager().setFoodLevel(20);
- p.getHungerManager().setSaturationLevel(5.0f);
- });
- // reset gamerules after the start
- gamerules.setValue(GameRules.DO_IMMEDIATE_RESPAWN, false, server);
- // reset time and weather
- server.getOverworld().setTimeOfDay(0);
- server.getOverworld().resetWeather();
- changeState(true);
- timer.dds_runTask(new TickTask(() -> {
- remaining--;
- playerManager.getPlayerList().forEach(player -> {
- if (Molehunt.timerVisibility.getOrDefault(player.getUuid(), true)) {
- player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(getRemainingText())));
- }
- });
- playerManager.sendToAll(timing);
- if (remaining == 0) end();
- }, 5 * 20, 20));
- }, 4 * 20));
- }
-
- public void stop() {
- server.getPlayerManager().broadcast(Text.translatable("commands.molehunt.stop.success"), false);
- end();
- }
-
- public void end() {
- final var timer = TimerAccess.getTimerFromOverworld(server);
- timer.dds_cancel();
-
- final var worldBorder = server.getOverworld().getWorldBorder();
- // Stops the border shrinking.
- worldBorder.setSize(worldBorder.getSize());
-
- changeState(false);
- final var pm = server.getPlayerManager();
- final var winnerSuspense = new TitleS2CPacket(Text.translatable("molehunt.game.end.suspense.title"));
- pm.getPlayerList().forEach(p -> {
- p.networkHandler.sendPacket(timing);
- p.networkHandler.sendPacket(winnerSuspense);
- p.changeGameMode(GameMode.CREATIVE);
- });
- timer.dds_runTask(new TickTask(() -> {
- TitleS2CPacket winner;
- if (wonByMoles()) {
- winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.moles.title"));
- } else {
- winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.survivors.title"));
- }
- pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle", getMolesAsString())));
- pm.sendToAll(winner);
- pm.sendToAll(timing);
- moles.clear();
- }, 4 * 20));
- }
-
- public Text getRemainingText() {
- return Text.of("§c" + TimeUtils.generateShortString(remaining));
- }
-
- public List<ServerPlayerEntity> getMoles() {
- return moles.stream()
- .map(uuid -> server.getPlayerManager().getPlayer(uuid))
- .filter(Objects::nonNull)
- .filter(p -> !p.isSpectator())
- .toList();
- }
-
- public String getMolesAsString() {
- return getMoles().stream()
- .map(PlayerEntity::getDisplayName)
- .filter(Objects::nonNull)
- .map(Object::toString)
- .collect(Collectors.joining(", "));
- }
-
- public boolean isMole(ServerPlayerEntity player) {
- return moles.contains(player.getUuid());
- }
-
- public boolean wonByMoles() {
- return new HashSet<>(moles).containsAll(
- server.getPlayerManager()
- .getPlayerList()
- .stream()
- .filter(p -> !p.isSpectator() && !p.isCreative())
- .map(Entity::getUuid)
- .toList()
- );
- }
-
- public boolean started() {
- return started;
- }
-
- private void changeState(boolean hasStarted) {
- started = hasStarted;
- final var payload = new GamePayload(hasStarted);
- server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload));
- }
+ public final int defaultTime = Molehunt.CONFIG.getGameDuration() * 60;
+ private final MinecraftServer server;
+ private final List<UUID> moles = new ArrayList<>();
+ private final TitleFadeS2CPacket timing = new TitleFadeS2CPacket(20, 40, 20);
+ private int remaining = defaultTime;
+ private boolean started = false;
+
+ public Game(MinecraftServer server) {
+ this.server = server;
+ }
+
+ public void start() {
+ 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();
+
+ final var players = new ArrayList<>(playerManager.getPlayerList());
+ 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!");
+ moles.add(mole.getUuid());
+ players.remove(r);
+ }
+
+ final var gamerules = server.getOverworld().getGameRules();
+ // immutable gamerules
+ gamerules.setValue(GameRules.SHOW_DEATH_MESSAGES, false, server);
+ gamerules.setValue(GameRules.ANNOUNCE_ADVANCEMENTS, false, server);
+ // gamerules for the start
+ gamerules.setValue(GameRules.DO_IMMEDIATE_RESPAWN, true, server);
+
+ final var timer = TimerAccess.getTimerFromOverworld(server);
+
+ final var worldBorder = server.getOverworld().getWorldBorder();
+ worldBorder.setSize(Molehunt.CONFIG.getInitialWorldSize());
+ if (Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset() < Molehunt.CONFIG.getGameDuration()) {
+ timer.dds_runTask(new TickTask(() -> worldBorder.interpolateSize(
+ Molehunt.CONFIG.getInitialWorldSize(),
+ Molehunt.CONFIG.getFinalWorldSize(),
+ (Molehunt.CONFIG.getGameDuration() - Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset()) * 60 * 20L,
+ 0L
+ ), Molehunt.CONFIG.getBorderShrinkingStartingTimeOffset() * 60 * 20L));
+ }
+
+ final var title = new TitleS2CPacket(Text.translatable("molehunt.game.start.suspense"));
+ playerManager.getPlayerList().forEach(p -> {
+ p.getInventory().clear();
+ p.kill(p.getEntityWorld());
+ p.networkHandler.sendPacket(timing);
+ p.networkHandler.sendPacket(title);
+ p.changeGameMode(GameMode.SURVIVAL);
+ if (Molehunt.CONFIG.foodOnStart()) p.giveItemStack(new ItemStack(Items.COOKED_BEEF, 64));
+ });
+
+ server.setDefaultGameMode(GameMode.SPECTATOR);
+
+ timer.dds_runTask(new TickTask(() -> {
+ playerManager.getPlayerList().forEach(p -> {
+ p.networkHandler.sendPacket(timing);
+ if (moles.contains(p.getUuid())) {
+ 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.translatable("molehunt.game.start.survivor.title")));
+ p.networkHandler.sendPacket(new SubtitleS2CPacket(Text.translatable("molehunt.game.start.survivor.subtitle")));
+ }
+ // reset health and food level
+ p.setHealth(p.getMaxHealth());
+ p.getHungerManager().setFoodLevel(20);
+ p.getHungerManager().setSaturationLevel(5.0f);
+ });
+ // reset gamerules after the start
+ gamerules.setValue(GameRules.DO_IMMEDIATE_RESPAWN, false, server);
+ // reset time and weather
+ server.getOverworld().setTimeOfDay(0);
+ server.getOverworld().resetWeather();
+ changeState(true);
+ timer.dds_runTask(new TickTask(() -> {
+ remaining--;
+ playerManager.getPlayerList().forEach(player -> {
+ if (Molehunt.timerVisibility.getOrDefault(player.getUuid(), true)) {
+ player.networkHandler.sendPacket(new OverlayMessageS2CPacket(Text.of(getRemainingText())));
+ }
+ });
+ playerManager.sendToAll(timing);
+ if (remaining == 0) end();
+ }, 5 * 20, 20));
+ }, 4 * 20));
+ }
+
+ public void stop() {
+ server.getPlayerManager().broadcast(Text.translatable("commands.molehunt.stop.success"), false);
+ end();
+ }
+
+ public void end() {
+ final var timer = TimerAccess.getTimerFromOverworld(server);
+ timer.dds_cancel();
+
+ final var worldBorder = server.getOverworld().getWorldBorder();
+ // Stops the border shrinking.
+ worldBorder.setSize(worldBorder.getSize());
+
+ changeState(false);
+ final var pm = server.getPlayerManager();
+ final var winnerSuspense = new TitleS2CPacket(Text.translatable("molehunt.game.end.suspense.title"));
+ pm.getPlayerList().forEach(p -> {
+ p.networkHandler.sendPacket(timing);
+ p.networkHandler.sendPacket(winnerSuspense);
+ p.changeGameMode(GameMode.CREATIVE);
+ });
+ timer.dds_runTask(new TickTask(() -> {
+ TitleS2CPacket winner;
+ if (wonByMoles()) {
+ winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.moles.title"));
+ } else {
+ winner = new TitleS2CPacket(Text.translatable("molehunt.game.end.winners.survivors.title"));
+ }
+ pm.sendToAll(new SubtitleS2CPacket(Text.translatable("molehunt.game.end.winners.subtitle", getMolesAsString())));
+ pm.sendToAll(winner);
+ pm.sendToAll(timing);
+ moles.clear();
+ }, 4 * 20));
+ }
+
+ public Text getRemainingText() {
+ return Text.of("§c" + TimeUtils.generateShortString(remaining));
+ }
+
+ public List<ServerPlayerEntity> getMoles() {
+ return moles.stream()
+ .map(uuid -> server.getPlayerManager().getPlayer(uuid))
+ .filter(Objects::nonNull)
+ .filter(p -> !p.isSpectator())
+ .toList();
+ }
+
+ public String getMolesAsString() {
+ return getMoles().stream()
+ .map(PlayerEntity::getDisplayName)
+ .filter(Objects::nonNull)
+ .map(Object::toString)
+ .collect(Collectors.joining(", "));
+ }
+
+ public boolean isMole(ServerPlayerEntity player) {
+ return moles.contains(player.getUuid());
+ }
+
+ public boolean wonByMoles() {
+ return new HashSet<>(moles).containsAll(
+ server.getPlayerManager()
+ .getPlayerList()
+ .stream()
+ .filter(p -> !p.isSpectator() && !p.isCreative())
+ .map(Entity::getUuid)
+ .toList()
+ );
+ }
+
+ public boolean started() {
+ return started;
+ }
+
+ private void changeState(boolean hasStarted) {
+ started = hasStarted;
+ final var payload = new GamePayload(hasStarted);
+ server.getPlayerManager().getPlayerList().forEach(p -> ServerPlayNetworking.send(p, payload));
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/game/GamePayload.java b/src/main/java/world/anhgelus/molehunt/game/GamePayload.java index 66e3209..1532fa9 100644 --- a/src/main/java/world/anhgelus/molehunt/game/GamePayload.java +++ b/src/main/java/world/anhgelus/molehunt/game/GamePayload.java @@ -8,16 +8,16 @@ import net.minecraft.util.Identifier; import world.anhgelus.molehunt.Molehunt;
public record GamePayload(boolean gameLaunched) implements CustomPayload {
- public static final Identifier GAME_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "game");
+ public static final Identifier GAME_PACKET_ID = Identifier.of(Molehunt.MOD_ID, "game");
- public static final CustomPayload.Id<GamePayload> ID = new CustomPayload.Id<>(GAME_PACKET_ID);
- public static final PacketCodec<RegistryByteBuf, GamePayload> CODEC = PacketCodec.tuple(
- PacketCodecs.BOOLEAN, GamePayload::gameLaunched,
- GamePayload::new
- );
+ public static final CustomPayload.Id<GamePayload> ID = new CustomPayload.Id<>(GAME_PACKET_ID);
+ public static final PacketCodec<RegistryByteBuf, GamePayload> CODEC = PacketCodec.tuple(
+ PacketCodecs.BOOLEAN, GamePayload::gameLaunched,
+ GamePayload::new
+ );
- @Override
- public Id<? extends CustomPayload> getId() {
- return ID;
- }
+ @Override
+ public Id<? extends CustomPayload> getId() {
+ return ID;
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java b/src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java index a82a21e..0dfd624 100644 --- a/src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java +++ b/src/main/java/world/anhgelus/molehunt/mixin/NoJoinLeaveMessage.java @@ -9,10 +9,10 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(PlayerManager.class)
public class NoJoinLeaveMessage {
- @Inject(at = @At("HEAD"), method = "broadcast*", cancellable = true)
- public void broadcastNoJoinLeaveMessage(Text message, boolean overlay, CallbackInfo ci) {
- final var content = message.getContent().toString();
- if (content.startsWith("translation{key='multiplayer.player.joined")) ci.cancel();
- else if (content.startsWith("translation{key='multiplayer.player.left")) ci.cancel();
- }
+ @Inject(at = @At("HEAD"), method = "broadcast*", cancellable = true)
+ public void broadcastNoJoinLeaveMessage(Text message, boolean overlay, CallbackInfo ci) {
+ final var content = message.getContent().toString();
+ if (content.startsWith("translation{key='multiplayer.player.joined")) ci.cancel();
+ else if (content.startsWith("translation{key='multiplayer.player.left")) ci.cancel();
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java b/src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java index 2727143..f698f1c 100644 --- a/src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java +++ b/src/main/java/world/anhgelus/molehunt/mixin/NoMsgCommand.java @@ -10,8 +10,8 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(MessageCommand.class)
public class NoMsgCommand {
- @Inject(at = @At("HEAD"), method = "register", cancellable = true)
- private static void register(CommandDispatcher<ServerCommandSource> dispatcher, CallbackInfo ci) {
- ci.cancel();
- }
+ @Inject(at = @At("HEAD"), method = "register", cancellable = true)
+ private static void register(CommandDispatcher<ServerCommandSource> dispatcher, CallbackInfo ci) {
+ ci.cancel();
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java b/src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java index a71e6d1..2648f25 100644 --- a/src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java +++ b/src/main/java/world/anhgelus/molehunt/mixin/NoPortals.java @@ -11,9 +11,9 @@ import world.anhgelus.molehunt.Molehunt; @Mixin(PortalManager.class)
public class NoPortals {
- @Inject(at = @At("HEAD"), method = "tick", cancellable = true)
- public void disableTick(ServerWorld world, Entity entity, boolean canUsePortals, CallbackInfoReturnable<Boolean> cir) {
- if (Molehunt.CONFIG == null || Molehunt.CONFIG.portalsEnabled()) return;
- cir.setReturnValue(false);
- }
+ @Inject(at = @At("HEAD"), method = "tick", cancellable = true)
+ public void disableTick(ServerWorld world, Entity entity, boolean canUsePortals, CallbackInfoReturnable<Boolean> cir) {
+ if (Molehunt.CONFIG == null || Molehunt.CONFIG.portalsEnabled()) return;
+ cir.setReturnValue(false);
+ }
}
diff --git a/src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java b/src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java index cd8a1b4..1e0ba12 100644 --- a/src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java +++ b/src/main/java/world/anhgelus/molehunt/mixin/WorldTimerAccess.java @@ -14,32 +14,32 @@ import java.util.function.BooleanSupplier; @Mixin(ServerWorld.class) public class WorldTimerAccess implements TimerAccess { - @Unique - private final List<TickTask> tasks = new ArrayList<>(); - - @Unique - private final List<TimerAccess.TickTask> tasksToAdd = new ArrayList<>(); - - @Inject(method = "tick", at = @At("TAIL")) - private void onTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) { - tasks.stream().filter(TickTask::isRunning).forEach(TickTask::tick); - tasks.addAll(tasksToAdd); - tasksToAdd.clear(); - } - - @Override - public void dds_runTask(TimerAccess.TickTask task) { - tasksToAdd.add(task); - } - - @Override - public void dds_cancel() { - tasks.stream().filter(TickTask::isRunning).forEach(TickTask::cancel); - tasks.clear(); - } - - @Override - public List<TickTask> dds_getTasks() { - return tasks.stream().filter(TickTask::isRunning).toList(); - } + @Unique + private final List<TickTask> tasks = new ArrayList<>(); + + @Unique + private final List<TimerAccess.TickTask> tasksToAdd = new ArrayList<>(); + + @Inject(method = "tick", at = @At("TAIL")) + private void onTick(BooleanSupplier shouldKeepTicking, CallbackInfo ci) { + tasks.stream().filter(TickTask::isRunning).forEach(TickTask::tick); + tasks.addAll(tasksToAdd); + tasksToAdd.clear(); + } + + @Override + public void dds_runTask(TimerAccess.TickTask task) { + tasksToAdd.add(task); + } + + @Override + public void dds_cancel() { + tasks.stream().filter(TickTask::isRunning).forEach(TickTask::cancel); + tasks.clear(); + } + + @Override + public List<TickTask> dds_getTasks() { + return tasks.stream().filter(TickTask::isRunning).toList(); + } }
\ No newline at end of file diff --git a/src/main/java/world/anhgelus/molehunt/timer/TickTask.java b/src/main/java/world/anhgelus/molehunt/timer/TickTask.java index 8c74b89..1cc83e2 100644 --- a/src/main/java/world/anhgelus/molehunt/timer/TickTask.java +++ b/src/main/java/world/anhgelus/molehunt/timer/TickTask.java @@ -4,69 +4,69 @@ package world.anhgelus.molehunt.timer; * Represents a complete task called each tick */ public class TickTask implements TimerAccess.TickTask { - public final long ticksDelay; - public final long ticksRepeat; - public final boolean repeating; - public final TimerAccess.Task task; - private boolean cancelled = false; - private long currentTicking; + public final long ticksDelay; + public final long ticksRepeat; + public final boolean repeating; + public final TimerAccess.Task task; + private boolean cancelled = false; + private long currentTicking; - /** - * Create a new repeating TickTask - * - * @param task Task to run after the delay or the repeat time - * @param ticksDelay Delay before the first task's run - * @param ticksRepeat Repeat each tick (if the repeat is 0, it will repeat each tick, if it is below 0, it will not repeat) - * @throws IllegalArgumentException if ticksDelay is below 0 - */ - public TickTask(TimerAccess.Task task, long ticksDelay, long ticksRepeat) { - if (ticksDelay < 0) throw new IllegalArgumentException("Ticks delay must be non-negative"); - this.ticksDelay = ticksDelay; - this.ticksRepeat = ticksRepeat; - this.task = task; - repeating = ticksRepeat >= 0; - currentTicking = ticksDelay; - } + /** + * Create a new repeating TickTask + * + * @param task Task to run after the delay or the repeat time + * @param ticksDelay Delay before the first task's run + * @param ticksRepeat Repeat each tick (if the repeat is 0, it will repeat each tick, if it is below 0, it will not repeat) + * @throws IllegalArgumentException if ticksDelay is below 0 + */ + public TickTask(TimerAccess.Task task, long ticksDelay, long ticksRepeat) { + if (ticksDelay < 0) throw new IllegalArgumentException("Ticks delay must be non-negative"); + this.ticksDelay = ticksDelay; + this.ticksRepeat = ticksRepeat; + this.task = task; + repeating = ticksRepeat >= 0; + currentTicking = ticksDelay; + } - /** - * Create a new delayed TickTask - * - * @param task Task to run after the delay or the repeat time - * @param ticksDelay Delay before the first task's run - * @throws IllegalArgumentException if ticksDelay or if ticksRepeat is below 0 - */ - public TickTask(TimerAccess.Task task, long ticksDelay) { - if (ticksDelay < 0) throw new IllegalArgumentException("Ticks delay must be non-negative"); - this.ticksDelay = ticksDelay; - this.ticksRepeat = -1; - this.task = task; - repeating = false; - currentTicking = ticksDelay; - } + /** + * Create a new delayed TickTask + * + * @param task Task to run after the delay or the repeat time + * @param ticksDelay Delay before the first task's run + * @throws IllegalArgumentException if ticksDelay or if ticksRepeat is below 0 + */ + public TickTask(TimerAccess.Task task, long ticksDelay) { + if (ticksDelay < 0) throw new IllegalArgumentException("Ticks delay must be non-negative"); + this.ticksDelay = ticksDelay; + this.ticksRepeat = -1; + this.task = task; + repeating = false; + currentTicking = ticksDelay; + } - public void tick() { - if (--currentTicking > 0) return; - task.run(); - if (repeating) { - currentTicking = ticksRepeat; - } else { - cancel(); - } - } + public void tick() { + if (--currentTicking > 0) return; + task.run(); + if (repeating) { + currentTicking = ticksRepeat; + } else { + cancel(); + } + } - public long cancel() { - if (cancelled) throw new IllegalStateException("Task already cancelled"); - cancelled = true; - return currentTicking; - } + public long cancel() { + if (cancelled) throw new IllegalStateException("Task already cancelled"); + cancelled = true; + return currentTicking; + } - public boolean isRunning() { - return !cancelled; - } + public boolean isRunning() { + return !cancelled; + } - @Override - public long getTickingBeforeRun() { - if (cancelled) return -1; - return currentTicking; - } + @Override + public long getTickingBeforeRun() { + if (cancelled) return -1; + return currentTicking; + } }
\ No newline at end of file diff --git a/src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java b/src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java index 2e02b12..32ee611 100644 --- a/src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java +++ b/src/main/java/world/anhgelus/molehunt/timer/TimerAccess.java @@ -6,60 +6,60 @@ import net.minecraft.world.World; import java.util.List; public interface TimerAccess { - /** - * Get the timer linked to the overworld - * - * @param server Current server - * @return TimerAccess linked to the overworld - */ - static TimerAccess getTimerFromOverworld(MinecraftServer server) { - final var timer = (TimerAccess) server.getWorld(World.OVERWORLD); - if (timer == null) - throw new NullPointerException("Impossible to get TimerAccess from the overworld (it is null)"); - return timer; - } + /** + * Get the timer linked to the overworld + * + * @param server Current server + * @return TimerAccess linked to the overworld + */ + static TimerAccess getTimerFromOverworld(MinecraftServer server) { + final var timer = (TimerAccess) server.getWorld(World.OVERWORLD); + if (timer == null) + throw new NullPointerException("Impossible to get TimerAccess from the overworld (it is null)"); + return timer; + } - /** - * Run a task (called each tick ticked) - * - * @param task Task to run - */ - void dds_runTask(TimerAccess.TickTask task); + /** + * Run a task (called each tick ticked) + * + * @param task Task to run + */ + void dds_runTask(TimerAccess.TickTask task); - void dds_cancel(); + void dds_cancel(); - /** - * @return All non-cancelled tasks - */ - List<TickTask> dds_getTasks(); + /** + * @return All non-cancelled tasks + */ + List<TickTask> dds_getTasks(); - interface TickTask { - /** - * Tick the task - */ - void tick(); + interface TickTask { + /** + * Tick the task + */ + void tick(); - /** - * Cancel the task - * - * @return the remaining ticks before the run of the Task - * @throws IllegalStateException if the task is already cancelled - */ - long cancel(); + /** + * Cancel the task + * + * @return the remaining ticks before the run of the Task + * @throws IllegalStateException if the task is already cancelled + */ + long cancel(); - boolean isRunning(); + boolean isRunning(); - /** - * @return the number of ticks before run of the task (if the task is cancelled, returns -1) - */ - long getTickingBeforeRun(); - } + /** + * @return the number of ticks before run of the task (if the task is cancelled, returns -1) + */ + long getTickingBeforeRun(); + } - /** - * Represents a task to run after ticking - */ - @FunctionalInterface - interface Task { - void run(); - } + /** + * Represents a task to run after ticking + */ + @FunctionalInterface + interface Task { + void run(); + } } diff --git a/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java b/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java index 2b96606..952f2d2 100644 --- a/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java +++ b/src/main/java/world/anhgelus/molehunt/utils/TimeUtils.java @@ -2,50 +2,51 @@ package world.anhgelus.molehunt.utils; public class TimeUtils {
- private record Time(long hours, long minutes, long seconds) {}
-
- public static String generateString(long time) {
- final var pt = generateTime(time);
-
- StringBuilder sb = new StringBuilder();
- if (pt.hours != 0) {
- sb.append(pt.hours).append(" hours ");
- }
- if (pt.minutes != 0 || pt.hours != 0) {
- sb.append(pt.minutes).append(" minutes ");
- }
- sb.append(pt.seconds).append(" seconds");
-
- return sb.toString();
- }
-
- public static String generateShortString(long time) {
- final var pt = generateTime(time);
-
- return padLeft(pt.hours) + ":" +
- padLeft(pt.minutes) + ":" +
- padLeft(pt.seconds);
- }
-
- private static Time generateTime(long time) {
- long hours = 0;
- if (time > 3600) {
- hours = Math.floorDiv(time, 3600);
- }
- long minutes = 0;
- if (hours != 0 || time > 60) {
- minutes = Math.floorDiv(time - hours * 3600, 60);
- }
- long seconds = (long) Math.floor(time - hours * 3600 - minutes * 60);
- return new Time(hours, minutes, seconds);
- }
-
- private static String padLeft(long n) {
- if (n < 10 && n != 0) {
- return "0" + Math.round(n);
- } else if (n == 0) {
- return "00";
- }
- return Long.toString(Math.round(n));
- }
+ public static String generateString(long time) {
+ final var pt = generateTime(time);
+
+ StringBuilder sb = new StringBuilder();
+ if (pt.hours != 0) {
+ sb.append(pt.hours).append(" hours ");
+ }
+ if (pt.minutes != 0 || pt.hours != 0) {
+ sb.append(pt.minutes).append(" minutes ");
+ }
+ sb.append(pt.seconds).append(" seconds");
+
+ return sb.toString();
+ }
+
+ public static String generateShortString(long time) {
+ final var pt = generateTime(time);
+
+ return padLeft(pt.hours) + ":" +
+ padLeft(pt.minutes) + ":" +
+ padLeft(pt.seconds);
+ }
+
+ private static Time generateTime(long time) {
+ long hours = 0;
+ if (time > 3600) {
+ hours = Math.floorDiv(time, 3600);
+ }
+ long minutes = 0;
+ if (hours != 0 || time > 60) {
+ minutes = Math.floorDiv(time - hours * 3600, 60);
+ }
+ long seconds = (long) Math.floor(time - hours * 3600 - minutes * 60);
+ return new Time(hours, minutes, seconds);
+ }
+
+ private static String padLeft(long n) {
+ if (n < 10 && n != 0) {
+ return "0" + Math.round(n);
+ } else if (n == 0) {
+ return "00";
+ }
+ return Long.toString(Math.round(n));
+ }
+
+ private record Time(long hours, long minutes, long seconds) {
+ }
}
|
