From 96daf58e9301303f62118819f840bc646eec0d10 Mon Sep 17 00:00:00 2001 From: kyrptonaught Date: Thu, 1 Feb 2024 02:30:19 -0500 Subject: [PATCH] Switch to ModTools 2.0 format. Add support for loading lobbies. --- build.gradle | 2 +- gradle.properties | 2 +- .../CustomMapLoaderCommands.java | 57 ++++- .../customMapLoader/CustomMapLoaderMod.java | 198 ++++++++++++------ .../customMapLoader/LemModConfig.java | 78 ------- .../serverutils/customMapLoader/MapSize.java | 4 +- .../serverutils/customMapLoader/Votebook.java | 80 +++---- .../serverutils/customMapLoader/Voter.java | 30 +-- .../customMapLoader/addons/BaseAddon.java | 52 +++++ .../addons/BattleMapAddon.java | 43 ++++ .../customMapLoader/addons/LobbyAddon.java | 22 ++ src/main/resources/fabric.mod.json | 2 +- 12 files changed, 361 insertions(+), 209 deletions(-) delete mode 100644 src/main/java/net/kyrptonaught/serverutils/customMapLoader/LemModConfig.java create mode 100644 src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/BaseAddon.java create mode 100644 src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/BattleMapAddon.java create mode 100644 src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/LobbyAddon.java diff --git a/build.gradle b/build.gradle index b6202e9..04b59a8 100644 --- a/build.gradle +++ b/build.gradle @@ -67,7 +67,7 @@ dependencies { shadow implementation("io.javalin:javalin:6.0.0") //Apache Compress - shadow implementation("org.apache.commons:commons-compress:1.24.0") + shadow implementation("org.apache.commons:commons-compress:1.25.0") } loom { diff --git a/gradle.properties b/gradle.properties index 98fd1a5..a59f863 100644 --- a/gradle.properties +++ b/gradle.properties @@ -9,7 +9,7 @@ loader_version=0.15.6 fabric_version=0.95.4+1.20.4 # Mod Properties -mod_version=1.0.8b1-1.20.4 +mod_version=1.0.8b2-1.20.4 maven_group=net.kyrptonaught archives_base_name=ServerUtils diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/CustomMapLoaderCommands.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/CustomMapLoaderCommands.java index 08d01a9..3dae8b6 100644 --- a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/CustomMapLoaderCommands.java +++ b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/CustomMapLoaderCommands.java @@ -3,12 +3,14 @@ import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.builder.LiteralArgumentBuilder; +import net.minecraft.command.argument.EntityArgumentType; import net.minecraft.command.argument.IdentifierArgumentType; import net.minecraft.server.command.CommandManager; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.util.Identifier; +import java.util.Collection; import java.util.List; public class CustomMapLoaderCommands { @@ -19,18 +21,18 @@ public static void registerCommands(CommandDispatcher dispa cmd.then(CommandManager.literal("voting") .then(CommandManager.literal("openBook") .executes(context -> { - Votebook.generateBookLibrary(CustomMapLoaderMod.loadedMaps.values().stream().toList()); + Votebook.generateBookLibrary(CustomMapLoaderMod.BATTLE_MAPS.values().stream().toList()); Votebook.openbook(context.getSource().getPlayer(), "title"); return 1; })) .then(CommandManager.literal("giveBook") .executes(context -> { - Votebook.generateBookLibrary(CustomMapLoaderMod.loadedMaps.values().stream().toList()); + Votebook.generateBookLibrary(CustomMapLoaderMod.BATTLE_MAPS.values().stream().toList()); Votebook.giveBook(context.getSource().getPlayer(), "title"); return 1; })) .then(CommandManager.literal("showBookPage") - .then(CommandManager.argument("page", StringArgumentType.word()) + .then(CommandManager.argument("page", StringArgumentType.greedyString()) .executes(context -> { String page = StringArgumentType.getString(context, "page"); @@ -41,19 +43,19 @@ public static void registerCommands(CommandDispatcher dispa .fork(dispatcher.getRoot(), (context -> { context.getChild().getCommand().run(context); - Votebook.generateBookLibrary(CustomMapLoaderMod.loadedMaps.values().stream().toList()); + Votebook.generateBookLibrary(CustomMapLoaderMod.BATTLE_MAPS.values().stream().toList()); String page = StringArgumentType.getString(context, "page"); Votebook.openbook(context.getSource().getPlayer(), page); return List.of(); }))))) .then(CommandManager.literal("vote") - .then(CommandManager.argument("map", StringArgumentType.word()) + .then(CommandManager.argument("map", IdentifierArgumentType.identifier()) .executes(context -> { ServerPlayerEntity player = context.getSource().getPlayer(); - String map = StringArgumentType.getString(context, "map"); + Identifier map = IdentifierArgumentType.getIdentifier(context, "map"); - Voter.voteFor(context.getSource().getServer(), player, map, CustomMapLoaderMod.loadedMaps.get(map).getName()); + Voter.voteFor(context.getSource().getServer(), player, map, CustomMapLoaderMod.BATTLE_MAPS.get(map).getNameText()); return 1; }))) .then(CommandManager.literal("removeVote") @@ -63,14 +65,15 @@ public static void registerCommands(CommandDispatcher dispa })) .then(CommandManager.literal("start") .executes(context -> { - Voter.prepVote(context.getSource().getServer(), CustomMapLoaderMod.loadedMaps.values().stream().toList()); + Voter.prepVote(context.getSource().getServer(), CustomMapLoaderMod.BATTLE_MAPS.values().stream().toList()); return 1; })) .then(CommandManager.literal("end") .then(CommandManager.argument("dimID", IdentifierArgumentType.identifier()) .executes(context -> { Identifier id = IdentifierArgumentType.getIdentifier(context, "dimID"); - CustomMapLoaderMod.prepareLemmod(context.getSource().getServer(), id); + Identifier winner = Voter.endVote(context.getSource().getServer()); + CustomMapLoaderMod.prepareBattleMap(context.getSource().getServer(), winner, id); return 1; })))); @@ -84,7 +87,43 @@ public static void registerCommands(CommandDispatcher dispa return 1; }))))); } + cmd.then(CommandManager.literal("unload") + .then(CommandManager.argument("dimID", IdentifierArgumentType.identifier()) + .executes(context -> { + Identifier id = IdentifierArgumentType.getIdentifier(context, "dimID"); + CustomMapLoaderMod.unloadMap(context.getSource().getServer(), id); + return 1; + }))); + + cmd.then(CommandManager.literal("lobby") + .then(CommandManager.literal("load") + .then(CommandManager.argument("lobby", IdentifierArgumentType.identifier()) + .then(CommandManager.argument("dimID", IdentifierArgumentType.identifier()) + .executes(context -> { + Identifier id = IdentifierArgumentType.getIdentifier(context, "dimID"); + Identifier lobbyID = IdentifierArgumentType.getIdentifier(context, "lobby"); + CustomMapLoaderMod.prepareLobby(context.getSource().getServer(), lobbyID, id); + return 1; + })))) + .then(CommandManager.literal("tp") + .then(CommandManager.argument("dimID", IdentifierArgumentType.identifier()) + .then(CommandManager.argument("players", EntityArgumentType.players()) + .then(CommandManager.argument("winner", EntityArgumentType.player()) + .executes(context -> { + Identifier id = IdentifierArgumentType.getIdentifier(context, "dimID"); + Collection players = EntityArgumentType.getPlayers(context, "players"); + ServerPlayerEntity winner = EntityArgumentType.getPlayer(context, "winner"); + + CustomMapLoaderMod.teleportToLobby(id, players, winner); + return 1; + })) + .executes(context -> { + Identifier id = IdentifierArgumentType.getIdentifier(context, "dimID"); + Collection players = EntityArgumentType.getPlayers(context, "players"); + CustomMapLoaderMod.teleportToLobby(id, players, null); + return 1; + }))))); dispatcher.register(cmd); } } diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/CustomMapLoaderMod.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/CustomMapLoaderMod.java index 27f147a..9ccec7c 100644 --- a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/CustomMapLoaderMod.java +++ b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/CustomMapLoaderMod.java @@ -1,6 +1,7 @@ package net.kyrptonaught.serverutils.customMapLoader; import com.google.gson.JsonElement; +import com.google.gson.JsonObject; import com.mojang.brigadier.CommandDispatcher; import com.mojang.serialization.DataResult; import com.mojang.serialization.JsonOps; @@ -9,6 +10,9 @@ import net.kyrptonaught.serverutils.FileHelper; import net.kyrptonaught.serverutils.Module; import net.kyrptonaught.serverutils.ServerUtilsMod; +import net.kyrptonaught.serverutils.customMapLoader.addons.BaseAddon; +import net.kyrptonaught.serverutils.customMapLoader.addons.BattleMapAddon; +import net.kyrptonaught.serverutils.customMapLoader.addons.LobbyAddon; import net.kyrptonaught.serverutils.dimensionLoader.CustomDimHolder; import net.kyrptonaught.serverutils.dimensionLoader.DimensionLoaderMod; import net.minecraft.registry.Registry; @@ -16,6 +20,7 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.server.command.ServerCommandSource; import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.server.world.ServerWorld; import net.minecraft.util.Identifier; import net.minecraft.util.WorldSavePath; import net.minecraft.util.math.Vec3d; @@ -25,18 +30,19 @@ import java.nio.file.Files; import java.nio.file.Path; -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; +import java.util.*; import java.util.stream.Stream; public class CustomMapLoaderMod extends Module { - public static final HashMap loadedMaps = new HashMap<>(); + public static final HashMap BATTLE_MAPS = new HashMap<>(); + public static final HashMap LOBBY_MAPS = new HashMap<>(); + + public static final HashMap LOADED_MAPS = new HashMap<>(); @Override public void onInitialize() { - ServerLifecycleEvents.SERVER_STARTING.register(this::discoverLemmods); + ServerLifecycleEvents.SERVER_STARTING.register(this::discoverAddons); } @Override @@ -44,70 +50,124 @@ public void registerCommands(CommandDispatcher dispatcher) CustomMapLoaderCommands.registerCommands(dispatcher); } - public static void prepareLemmod(MinecraftServer server, Identifier dimID) { - String winner = Voter.endVote(server); - - LemModConfig config = CustomMapLoaderMod.loadedMaps.get(winner); + public static void prepareBattleMap(MinecraftServer server, Identifier addon, Identifier dimID) { + BattleMapAddon config = CustomMapLoaderMod.BATTLE_MAPS.get(addon); MapSize mapSize = CustomMapLoaderMod.autoSelectMapSize(config, server.getCurrentPlayerCount()); - Vec3d pos = config.getCoordsForSize(mapSize); + + String[] coords = config.getMapDataForSize(mapSize).center_coords.split(" "); + Vec3d pos = new Vec3d(Double.parseDouble(coords[0]), Double.parseDouble(coords[1]), Double.parseDouble(coords[2])); Path path = server.getSavePath(WorldSavePath.ROOT).resolve("dimensions").resolve(dimID.getNamespace()).resolve(dimID.getPath()); CustomMapLoaderMod.unZipMap(path, config, mapSize); - DimensionLoaderMod.loadDimension(dimID, config.dimensionType, server2 -> { + DimensionLoaderMod.loadDimension(dimID, config.dimensionType_id, server2 -> { CustomDimHolder holder = DimensionLoaderMod.loadedWorlds.get(dimID); for (ServerPlayerEntity player : server.getPlayerManager().getPlayerList()) { - ServerUtilsMod.SwitchableResourcepacksModule.execute(config.pack, Collections.singleton(player)); + ServerUtilsMod.SwitchableResourcepacksModule.execute(config.resource_pack, Collections.singleton(player)); player.teleport(holder.world.asWorld(), pos.x, pos.y, pos.z, player.getYaw(), player.getPitch()); } }); + LOADED_MAPS.put(dimID, config); + } + + public static void prepareLobby(MinecraftServer server, Identifier addon, Identifier dimID) { + LobbyAddon config = CustomMapLoaderMod.LOBBY_MAPS.get(addon); + + Path path = server.getSavePath(WorldSavePath.ROOT).resolve("dimensions").resolve(dimID.getNamespace()).resolve(dimID.getPath()); + CustomMapLoaderMod.unZipMap(path, config, null); + + DimensionLoaderMod.loadDimension(dimID, config.dimensionType_id, server2 -> teleportToLobby(dimID, server.getPlayerManager().getPlayerList(), null)); + LOADED_MAPS.put(dimID, config); + } + + public static void teleportToLobby(Identifier dimID, Collection players, ServerPlayerEntity winner) { + LobbyAddon config = (LobbyAddon) LOADED_MAPS.get(dimID); + CustomDimHolder holder = DimensionLoaderMod.loadedWorlds.get(dimID); + Random random = new Random(); + + List availCoords = new ArrayList<>(Arrays.asList(config.spawn_coords)); + + if (winner != null) { + ServerUtilsMod.SwitchableResourcepacksModule.execute(config.resource_pack, Collections.singleton(winner)); + + if (config.winner_coords != null) + tpPlayer(holder.world.asWorld(), winner, config.winner_coords.split(" ")); + else + tpPlayer(holder.world.asWorld(), winner, availCoords.remove(random.nextInt(availCoords.size())).split(" ")); + } + + for (ServerPlayerEntity player : players) { + ServerUtilsMod.SwitchableResourcepacksModule.execute(config.resource_pack, Collections.singleton(player)); + + tpPlayer(holder.world.asWorld(), player, availCoords.remove(random.nextInt(availCoords.size())).split(" ")); + } + } + + public static void tpPlayer(ServerWorld world, ServerPlayerEntity player, String[] coords) { + float yaw = player.getYaw(); + float pitch = player.getPitch(); + + if (coords.length == 5) { + yaw = Float.parseFloat(coords[3]); + pitch = Float.parseFloat(coords[4]); + } + + Vec3d pos = new Vec3d(Double.parseDouble(coords[0]), Double.parseDouble(coords[1]), Double.parseDouble(coords[2])); + player.teleport(world, pos.x, pos.y, pos.z, yaw, pitch); + } + + public static void unloadMap(MinecraftServer server, Identifier dimID) { + LOADED_MAPS.remove(dimID); + DimensionLoaderMod.unLoadDimension(server, dimID, null); } - public void discoverLemmods(MinecraftServer server) { - long time = System.nanoTime(); - Path dir = FabricLoader.getInstance().getGameDir().resolve("lebmods"); + public void discoverAddons(MinecraftServer server) { + Path dir = FabricLoader.getInstance().getGameDir().resolve("lemaddons"); try (Stream files = Files.walk(dir, 2)) { files.forEach(path -> { try { - if (!Files.isDirectory(path) && path.getFileName().toString().endsWith(".lebmod")) { + if (!Files.isDirectory(path) && path.getFileName().toString().endsWith(".lemaddon")) { String configJson = FileHelper.readFileFromZip(path, "config.json"); - LemModConfig config = ServerUtilsMod.getGson().fromJson(configJson, LemModConfig.class); + BaseAddon config = null; + JsonObject rawConfig = ServerUtilsMod.getGson().fromJson(configJson, JsonObject.class); + + String type = rawConfig.get("addon_type").getAsString(); + if (BattleMapAddon.TYPE.equals(type)) + config = ServerUtilsMod.getGson().fromJson(rawConfig, BattleMapAddon.class); + if (LobbyAddon.TYPE.equals(type)) + config = ServerUtilsMod.getGson().fromJson(rawConfig, LobbyAddon.class); if (path.getParent().getFileName().toString().equals("base")) { - config.isBaseMap = true; - config.mappack = "base_" + config.mappack; + config.isBaseAddon = true; + config.addon_pack = "base_" + config.addon_pack; } else if (!path.getParent().getFileName().toString().equals("lebmods")) { - config.mappack = path.getParent().getFileName().toString(); + config.addon_pack = path.getParent().getFileName().toString(); } - if (config.mappack == null || config.mappack.isEmpty()) { - config.mappack = "Other"; + if (config.addon_pack == null || config.addon_pack.isEmpty()) { + config.addon_pack = "Other"; } - config.mappack = FileHelper.cleanFileName(config.mappack); + config.addon_pack = FileHelper.cleanFileName(config.addon_pack); config.filePath = path; - if (config.dimensionType == null) { - config.dimensionType = new Identifier("lem", config.id); - - String dimJson = FileHelper.readFileFromZip(path, "world/dimension_type.json"); - if (dimJson != null) { - DataResult result = DimensionType.CODEC.parse(JsonOps.INSTANCE, ServerUtilsMod.getGson().fromJson(dimJson, JsonElement.class)); - DimensionType type = result.result().get(); - - Registry dimensionTypeRegistry = server.getRegistryManager().get(RegistryKeys.DIMENSION_TYPE); - ((RegistryUnfreezer) dimensionTypeRegistry).unfreeze(); - Registry.register(dimensionTypeRegistry, config.dimensionType, type); - - config.loadedDimensionType = type; + if (config instanceof BattleMapAddon battleConfig) { + if (battleConfig.dimensionType_id == null) { + battleConfig.dimensionType_id = config.addon_id; + battleConfig.loadedDimensionType = addDimensionType(server, battleConfig.filePath, battleConfig.dimensionType_id); + } + BATTLE_MAPS.put(config.addon_id, battleConfig); + } else if (config instanceof LobbyAddon lobbyConfig) { + if (lobbyConfig.dimensionType_id == null) { + lobbyConfig.dimensionType_id = config.addon_id; + lobbyConfig.loadedDimensionType = addDimensionType(server, lobbyConfig.filePath, lobbyConfig.dimensionType_id); } + LOBBY_MAPS.put(config.addon_id, lobbyConfig); } - - loadedMaps.put(config.id, config); } } catch (Exception e) { e.printStackTrace(); @@ -117,63 +177,59 @@ public void discoverLemmods(MinecraftServer server) { } catch (Exception e) { e.printStackTrace(); } - System.out.println(System.nanoTime() - time); } - - public static MapSize autoSelectMapSize(LemModConfig config, int playerCount) { + public static MapSize autoSelectMapSize(BattleMapAddon config, int playerCount) { switch (HostOptions.selectedMapSize) { case SMALL -> { - if (config.hassmall) + if (config.hasSize(MapSize.SMALL)) return MapSize.SMALL; } case LARGE -> { - if (config.haslarge) + if (config.hasSize(MapSize.LARGE)) return MapSize.LARGE; } case LARGE_PLUS -> { - if (config.haslargeplus) + if (config.hasSize(MapSize.LARGE_PLUS)) return MapSize.LARGE_PLUS; } case REMASTERED -> { - if (config.hasremastered) + if (config.hasSize(MapSize.REMASTERED)) return MapSize.REMASTERED; } } //no size available, or Auto selected if (playerCount >= 0 && playerCount <= 6) { - if (config.hassmall) return MapSize.SMALL; - if (config.haslarge) return MapSize.LARGE; - if (config.haslargeplus) return MapSize.LARGE_PLUS; - if (config.hasremastered) return MapSize.REMASTERED; + if (config.hasSize(MapSize.SMALL)) return MapSize.SMALL; + if (config.hasSize(MapSize.LARGE)) return MapSize.LARGE; + if (config.hasSize(MapSize.LARGE_PLUS)) return MapSize.LARGE_PLUS; + if (config.hasSize(MapSize.REMASTERED)) return MapSize.REMASTERED; } if (playerCount >= 7 && playerCount <= 8) { - if (config.haslarge) return MapSize.LARGE; - if (config.haslargeplus) return MapSize.LARGE_PLUS; - if (config.hassmall) return MapSize.SMALL; - if (config.hasremastered) return MapSize.REMASTERED; + if (config.hasSize(MapSize.LARGE)) return MapSize.LARGE; + if (config.hasSize(MapSize.LARGE_PLUS)) return MapSize.LARGE_PLUS; + if (config.hasSize(MapSize.SMALL)) return MapSize.SMALL; + if (config.hasSize(MapSize.REMASTERED)) return MapSize.REMASTERED; } if (playerCount >= 9) { - if (config.haslargeplus) return MapSize.LARGE_PLUS; - if (config.haslarge) return MapSize.LARGE; - if (config.hassmall) return MapSize.SMALL; - if (config.hasremastered) return MapSize.REMASTERED; + if (config.hasSize(MapSize.LARGE_PLUS)) return MapSize.LARGE_PLUS; + if (config.hasSize(MapSize.LARGE)) return MapSize.LARGE; + if (config.hasSize(MapSize.SMALL)) return MapSize.SMALL; + if (config.hasSize(MapSize.REMASTERED)) return MapSize.REMASTERED; } return null; } - public static Path unZipMap(Path outputPath, LemModConfig config, MapSize mapSize) { - Path lebmod = config.filePath; - - try (ZipFile zip = new ZipFile(lebmod)) { + public static void unZipMap(Path outputPath, BaseAddon config, MapSize mapSize) { + try (ZipFile zip = new ZipFile(config.filePath)) { Enumeration entries = zip.getEntries(); while (entries.hasMoreElements()) { ZipArchiveEntry entry = entries.nextElement(); - if (entry.getName().startsWith("world/" + mapSize.fileName + "/")) { - Path newOut = outputPath.resolve(entry.getName().replace("world/" + mapSize.fileName + "/", "")); + if (entry.getName().startsWith(config.getDirectoryInZip(mapSize))) { + Path newOut = outputPath.resolve(entry.getName().replace(config.getDirectoryInZip(mapSize), "")); if (entry.isDirectory()) { Files.createDirectories(newOut); } else { @@ -182,10 +238,24 @@ public static Path unZipMap(Path outputPath, LemModConfig config, MapSize mapSiz } } } - return outputPath; } catch (Exception e) { e.printStackTrace(); } + } + + public static DimensionType addDimensionType(MinecraftServer server, Path addonPath, Identifier dimID) { + String dimJson = FileHelper.readFileFromZip(addonPath, "world/dimension_type.json"); + if (dimJson != null) { + DataResult result = DimensionType.CODEC.parse(JsonOps.INSTANCE, ServerUtilsMod.getGson().fromJson(dimJson, JsonElement.class)); + DimensionType type = result.result().get(); + + Registry dimensionTypeRegistry = server.getRegistryManager().get(RegistryKeys.DIMENSION_TYPE); + ((RegistryUnfreezer) dimensionTypeRegistry).unfreeze(); + Registry.register(dimensionTypeRegistry, dimID, type); + + return type; + } + return null; } } diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/LemModConfig.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/LemModConfig.java deleted file mode 100644 index 1653992..0000000 --- a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/LemModConfig.java +++ /dev/null @@ -1,78 +0,0 @@ -package net.kyrptonaught.serverutils.customMapLoader; - -import net.minecraft.text.MutableText; -import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.math.Vec3d; -import net.minecraft.world.dimension.DimensionType; - -import java.nio.file.Path; - -public class LemModConfig { - - private String name; - private String description; - - private String name_key; - private String description_key; - - public String authors; - public String version; - public String id; - public String type; - public String pack; - - public boolean hassmall = false; - public boolean haslarge = false; - public boolean haslargeplus = false; - public boolean hasremastered = false; - - public String centercoords_small; - public String centercoords_large; - public String centercoords_largeplus; - public String centercoords_remastered; - - public String mappack; - - public String mappack_key; - - public Identifier dimensionType; - - public transient DimensionType loadedDimensionType; - - public transient Path filePath; - - public transient boolean isBaseMap = false; - - public transient boolean isEnabled = true; - - public MutableText getName() { - if (name_key != null) - return Text.translatable(name_key); - return Text.literal(name); - } - - public MutableText getDescription() { - if (description_key != null) - return Text.translatable(description_key); - return Text.literal(description); - } - - public MutableText getMapPack() { - if (mappack_key != null) - return Text.translatable(mappack_key); - return Text.literal(mappack); - } - - public Vec3d getCoordsForSize(MapSize mapSize) { - String[] coords = (switch (mapSize) { - case AUTO -> null; - case SMALL -> centercoords_small; - case LARGE -> centercoords_large; - case LARGE_PLUS -> centercoords_largeplus; - case REMASTERED -> centercoords_remastered; - }).split(" "); - - return new Vec3d(Double.parseDouble(coords[0]), Double.parseDouble(coords[1]), Double.parseDouble(coords[2])); - } -} diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/MapSize.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/MapSize.java index 3624718..0d8542a 100644 --- a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/MapSize.java +++ b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/MapSize.java @@ -7,8 +7,8 @@ public enum MapSize { LARGE_PLUS("largeplus", "Large+"), REMASTERED("remastered", "Remastered"); - String fileName; - String id; + public final String fileName; + public final String id; MapSize(String fileName, String id) { this.fileName = fileName; diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/Votebook.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/Votebook.java index e1fc622..f700486 100644 --- a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/Votebook.java +++ b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/Votebook.java @@ -2,9 +2,11 @@ import eu.pb4.sgui.api.elements.BookElementBuilder; import eu.pb4.sgui.api.gui.BookGui; +import net.kyrptonaught.serverutils.customMapLoader.addons.BattleMapAddon; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.*; import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; import java.util.*; @@ -12,7 +14,7 @@ public class Votebook { public static HashMap bookLibrary = new HashMap<>(); - public static void generateBookLibrary(List lemmods) { + public static void generateBookLibrary(List addons) { bookLibrary.clear(); bookLibrary.put("404", createBasicBook().addPage( Text.literal("404"), @@ -54,9 +56,9 @@ public static void generateBookLibrary(List lemmods) { )); generateHostSettings(); - generateMapPacks(false, lemmods.stream().filter(config -> !config.isBaseMap).toList()); - generateMapPacks(true, lemmods.stream().filter(config -> config.isBaseMap).toList()); - generateMaps(lemmods); + generateMapPacks(false, addons.stream().filter(config -> !config.isBaseAddon).toList()); + generateMapPacks(true, addons.stream().filter(config -> config.isBaseAddon).toList()); + generateMapPages(addons); } private static BookElementBuilder createBasicBook() { @@ -81,11 +83,11 @@ public static void giveBook(ServerPlayerEntity player, String book) { player.giveItemStack(new BookGui(player, bookElement).getBook()); } - public static void generateMapPacks(boolean isBase, List lemmods) { - HashMap> packs = new HashMap<>(); + public static void generateMapPacks(boolean isBase, List addons) { + HashMap> packs = new HashMap<>(); - for (LemModConfig config : lemmods) { - String pack = config.mappack; + for (BattleMapAddon config : addons) { + String pack = config.addon_pack; if (!packs.containsKey(pack)) { packs.put(pack, new ArrayList<>()); @@ -103,15 +105,15 @@ public static void generateMapPacks(boolean isBase, List lemmods) BookElementBuilder builder = createBasicBook(); - List packMods = packs.get(pack); - List> packPages = generateMapPackPages(packMods, true); + List packAddons = packs.get(pack); + List> packPages = generateMapPackPages(packAddons, true); MutableText hover = Text.empty(); - for (int i = 0; i < 6 && i < packMods.size(); i++) { - hover.append(packMods.get(i).getName()); - if (i != packMods.size() - 1) hover.append("\n"); - if (i == 5 && packMods.size() > 6) hover.append("..."); + for (int i = 0; i < 6 && i < packAddons.size(); i++) { + hover.append(packAddons.get(i).getNameText()); + if (i != packAddons.size() - 1) hover.append("\n"); + if (i == 5 && packAddons.size() > 6) hover.append("..."); } for (int i = 0; i < packPages.size(); i++) { @@ -134,11 +136,11 @@ public static void generateMapPacks(boolean isBase, List lemmods) builder.addPage(packPages.get(i).toArray(Text[]::new)); } - packsText.add(withOpenCmd(bracket(packs.get(pack).get(0).getMapPack()).formatted(Formatting.GOLD), "mapPack_" + pack, hover)); + packsText.add(withOpenCmd(bracket(packs.get(pack).get(0).getAddonPackText()).formatted(Formatting.GOLD), "mapPack_" + pack, hover)); bookLibrary.put("mapPack_" + pack, builder); } - if(isBase) { + if(isBase && packs.containsKey("base_base")) { List> base_pages = generateMapPackPages(packs.get("base_base"), false); packsText.addAll(base_pages.get(0)); } @@ -148,7 +150,7 @@ public static void generateMapPacks(boolean isBase, List lemmods) bookLibrary.put(isBase ? "baseMaps" : "customMaps", createBasicBook().addPage(packsText.toArray(Text[]::new))); } - public static List> generateMapPackPages(List packMods, boolean includeHeader) { + public static List> generateMapPackPages(List packMods, boolean includeHeader) { int maxPerPage = 10; int lastUsed = 0; @@ -157,25 +159,25 @@ public static List> generateMapPackPages(List packMods, while (lastUsed < packMods.size()) { List pageText = new ArrayList<>(); if(includeHeader) { - pageText.add(dash(packMods.get(0).getMapPack())); + pageText.add(dash(packMods.get(0).getAddonPackText())); pageText.add(Text.empty()); } for (; lastUsed < packMods.size() && lastUsed - (pages.size() * maxPerPage) < maxPerPage; lastUsed++) { - LemModConfig config = packMods.get(lastUsed); + BattleMapAddon config = packMods.get(lastUsed); Text availableSizes = Text.literal("Available sizes: ") - .append(Text.translatable(config.hassmall ? "lem.battle.menu.host.config.maps.option.small" : "")) - .append(Text.translatable(config.haslarge ? "lem.battle.menu.host.config.maps.option.large" : "")) - .append(Text.translatable(config.haslargeplus ? "lem.battle.menu.host.config.maps.option.largeplus" : "")) - .append(Text.translatable(config.hasremastered ? "lem.battle.menu.host.config.maps.option.remastered" : "")); + .append(Text.translatable(config.hasSize(MapSize.SMALL) ? "lem.battle.menu.host.config.maps.option.small" : "")) + .append(Text.translatable(config.hasSize(MapSize.LARGE) ? "lem.battle.menu.host.config.maps.option.large" : "")) + .append(Text.translatable(config.hasSize(MapSize.LARGE_PLUS) ? "lem.battle.menu.host.config.maps.option.largeplus" : "")) + .append(Text.translatable(config.hasSize(MapSize.REMASTERED) ? "lem.battle.menu.host.config.maps.option.remastered" : "")); - Text tooltip = config.getName().append("\n") + Text tooltip = config.getNameText().append("\n") .append(Text.translatable("mco.template.select.narrate.authors", config.authors)).append("\n") .append(Text.translatable("mco.version", config.version)).append("\n") - .append("Resource Pack: " + config.pack).append("\n") + .append("Resource Pack: " + config.resource_pack).append("\n") .append(availableSizes); - pageText.add(withHover(withOpenCmd(bracket(trimName(config.getName(), 20)), "map_" + config.id), tooltip)); + pageText.add(withHover(withOpenCmd(bracket(trimName(config.getNameText(), 20)), "map_" + config.addon_id), tooltip)); } pages.add(pageText); } @@ -183,29 +185,29 @@ public static List> generateMapPackPages(List packMods, return pages; } - public static void generateMaps(List lemmods) { - for (LemModConfig config : lemmods) { + public static void generateMapPages(List lemmods) { + for (BattleMapAddon config : lemmods) { List mapText = new ArrayList<>(); Text availableSizes = Text.literal("Available sizes: ") - .append(Text.translatable(config.hassmall ? "lem.battle.menu.host.config.maps.option.small" : "")) - .append(Text.translatable(config.haslarge ? "lem.battle.menu.host.config.maps.option.large" : "")) - .append(Text.translatable(config.haslargeplus ? "lem.battle.menu.host.config.maps.option.largeplus" : "")) - .append(Text.translatable(config.hasremastered ? "lem.battle.menu.host.config.maps.option.remastered" : "")); + .append(Text.translatable(config.hasSize(MapSize.SMALL) ? "lem.battle.menu.host.config.maps.option.small" : "")) + .append(Text.translatable(config.hasSize(MapSize.LARGE) ? "lem.battle.menu.host.config.maps.option.large" : "")) + .append(Text.translatable(config.hasSize(MapSize.LARGE_PLUS) ? "lem.battle.menu.host.config.maps.option.largeplus" : "")) + .append(Text.translatable(config.hasSize(MapSize.REMASTERED) ? "lem.battle.menu.host.config.maps.option.remastered" : "")); - Text tooltip = config.getName().append("\n") + Text tooltip = config.getNameText().append("\n") .append(Text.translatable("mco.template.select.narrate.authors", config.authors)).append("\n") .append(Text.translatable("mco.version", config.version)).append("\n") - .append("Resource Pack: " + config.pack).append("\n") + .append("Resource Pack: " + config.resource_pack).append("\n") .append(availableSizes); - mapText.add(withHover(config.getName().formatted(Formatting.BLUE), tooltip)); - mapText.add(config.getDescription().formatted(Formatting.DARK_AQUA)); + mapText.add(withHover(config.getNameText().formatted(Formatting.BLUE), tooltip)); + mapText.add(config.getDescriptionText().formatted(Formatting.DARK_AQUA)); mapText.add(Text.empty()); - mapText.add(voteButton(config.id).append(" ").append(backButton("mapPack_" + config.mappack))); + mapText.add(voteButton(config.addon_id).append(" ").append(backButton("mapPack_" + config.addon_pack))); - bookLibrary.put("map_" + config.id, createBasicBook().addPage(mapText.toArray(Text[]::new))); + bookLibrary.put("map_" + config.addon_id, createBasicBook().addPage(mapText.toArray(Text[]::new))); } } @@ -278,7 +280,7 @@ public static MutableText dash(MutableText text) { return colored(Text.literal("- ").append(text).append(" -"), Formatting.BLUE); } - public static MutableText voteButton(String map) { + public static MutableText voteButton(Identifier map) { return bracketTrans("lem.mapdecider.menu.vote").styled(style -> style.withClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/custommaploader voting vote " + map))); } diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/Voter.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/Voter.java index 367df3f..7d7d2ed 100644 --- a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/Voter.java +++ b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/Voter.java @@ -1,22 +1,24 @@ package net.kyrptonaught.serverutils.customMapLoader; +import net.kyrptonaught.serverutils.customMapLoader.addons.BattleMapAddon; import net.minecraft.scoreboard.*; import net.minecraft.server.MinecraftServer; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; +import net.minecraft.util.Identifier; import org.jetbrains.annotations.Nullable; import java.util.*; public class Voter { - private static final HashMap> mapVotes = new HashMap<>(); - private static String objName = "lem.voting.mapvotes"; + private static final HashMap> mapVotes = new HashMap<>(); + private static final String objName = "lem.voting.mapvotes"; - public static void prepVote(MinecraftServer server, List loadedMods) { + public static void prepVote(MinecraftServer server, List loadedMods) { mapVotes.clear(); - for (LemModConfig mod : loadedMods) { - mapVotes.put(mod.id, new HashSet<>()); + for (BattleMapAddon config : loadedMods) { + mapVotes.put(config.addon_id, new HashSet<>()); } ServerScoreboard scoreboard = server.getScoreboard(); @@ -29,18 +31,18 @@ public static void prepVote(MinecraftServer server, List loadedMod scoreboard.setObjectiveSlot(ScoreboardDisplaySlot.SIDEBAR, obj); } - public static String endVote(MinecraftServer server){ + public static Identifier endVote(MinecraftServer server){ ServerScoreboard scoreboard = server.getScoreboard(); scoreboard.setObjectiveSlot(ScoreboardDisplaySlot.SIDEBAR, null); return calculateWinner(); } - private static String calculateWinner() { + private static Identifier calculateWinner() { int maxVotes = 0; - List winningMaps = new ArrayList<>(); + List winningMaps = new ArrayList<>(); - for (String map : mapVotes.keySet()) { + for (Identifier map : mapVotes.keySet()) { int votes = mapVotes.get(map).size(); if (votes > maxVotes) { @@ -58,7 +60,7 @@ private static String calculateWinner() { } - public static void voteFor(MinecraftServer server, ServerPlayerEntity player, String map, Text mapName) { + public static void voteFor(MinecraftServer server, ServerPlayerEntity player, Identifier map, Text mapName) { if (!mapVotes.containsKey(map)) mapVotes.put(map, new HashSet<>()); removeVote(server, player); @@ -67,19 +69,19 @@ public static void voteFor(MinecraftServer server, ServerPlayerEntity player, St } public static void removeVote(MinecraftServer server, ServerPlayerEntity player) { - for (String id : mapVotes.keySet()) { + for (Identifier id : mapVotes.keySet()) { if (mapVotes.get(id).remove(player.getUuid())) { - updateScore(server, id, CustomMapLoaderMod.loadedMaps.get(id).getName()); + updateScore(server, id, CustomMapLoaderMod.BATTLE_MAPS.get(id).getNameText()); } } } - private static void updateScore(MinecraftServer server, String map, Text mapName) { + private static void updateScore(MinecraftServer server, Identifier map, Text mapName) { ScoreHolder holder = new ScoreHolder() { @Override public String getNameForScoreboard() { - return map; + return map.toString(); } @Nullable diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/BaseAddon.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/BaseAddon.java new file mode 100644 index 0000000..1099c25 --- /dev/null +++ b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/BaseAddon.java @@ -0,0 +1,52 @@ +package net.kyrptonaught.serverutils.customMapLoader.addons; + +import net.kyrptonaught.serverutils.customMapLoader.MapSize; +import net.minecraft.text.MutableText; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import java.nio.file.Path; + +public class BaseAddon { + + public Identifier addon_id; + + private String name; + private String name_key; + + private String description; + private String description_key; + + public String authors; + public String version; + + public String addon_type; + public String addon_pack; + public String addon_pack_key; + + public transient Path filePath; + public transient boolean isBaseAddon = false; + public transient boolean isAddonEnabled = true; + + public MutableText getNameText() { + if (name_key != null) + return Text.translatable(name_key); + return Text.literal(name); + } + + public MutableText getDescriptionText() { + if (description_key != null) + return Text.translatable(description_key); + return Text.literal(description); + } + + public MutableText getAddonPackText() { + if (addon_pack_key != null) + return Text.translatable(addon_pack_key); + return Text.literal(addon_pack); + } + + public String getDirectoryInZip(MapSize mapSize) { + return "world/" + mapSize.fileName + "/"; + } +} diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/BattleMapAddon.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/BattleMapAddon.java new file mode 100644 index 0000000..6752cc9 --- /dev/null +++ b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/BattleMapAddon.java @@ -0,0 +1,43 @@ +package net.kyrptonaught.serverutils.customMapLoader.addons; + +import net.kyrptonaught.serverutils.customMapLoader.MapSize; +import net.minecraft.util.Identifier; +import net.minecraft.world.dimension.DimensionType; + +public class BattleMapAddon extends BaseAddon { + public static final String TYPE = "battle_map"; + public String resource_pack; + + public Identifier dimensionType_id; + public transient DimensionType loadedDimensionType; + + public MapSizeConfig small_map; + public MapSizeConfig large_map; + public MapSizeConfig large_plus_map; + public MapSizeConfig remastered_map; + + public MapSizeConfig getMapDataForSize(MapSize mapSize) { + return (switch (mapSize) { + case AUTO -> null; + case SMALL -> small_map; + case LARGE -> large_map; + case LARGE_PLUS -> large_plus_map; + case REMASTERED -> remastered_map; + }); + } + + public boolean hasSize(MapSize size){ + return getMapDataForSize(size) != null; + } + + public static class MapSizeConfig { + public String center_coords; + public String spawn_coords; + public String world_border_coords_1; + public String world_border_coords_2; + + public String[] chest_tracker_coords; + //datapack interactables + } + +} diff --git a/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/LobbyAddon.java b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/LobbyAddon.java new file mode 100644 index 0000000..935adee --- /dev/null +++ b/src/main/java/net/kyrptonaught/serverutils/customMapLoader/addons/LobbyAddon.java @@ -0,0 +1,22 @@ +package net.kyrptonaught.serverutils.customMapLoader.addons; + +import net.kyrptonaught.serverutils.customMapLoader.MapSize; +import net.minecraft.util.Identifier; +import net.minecraft.world.dimension.DimensionType; + +public class LobbyAddon extends BaseAddon { + public static final String TYPE = "lobby_map"; + + public String resource_pack; + + public Identifier dimensionType_id; + public transient DimensionType loadedDimensionType; + + public String[] spawn_coords; + + public String winner_coords; + + public String getDirectoryInZip(MapSize mapSize) { + return "world/lobby/"; + } +} diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index e1dacf4..e822f5d 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -1,7 +1,7 @@ { "schemaVersion": 1, "id": "serverutils", - "version": "1.0.8b1-1.20.4", + "version": "1.0.8b2-1.20.4", "name": "Server Utils", "description": "A group of utilities for servers", "authors": [