From 274e22728c688d943b01d824786e056f7b1053ed Mon Sep 17 00:00:00 2001 From: Patbox <39821509+Patbox@users.noreply.github.com> Date: Mon, 23 Dec 2024 20:50:09 +0100 Subject: [PATCH] Make /game join ui into game portal, split configs from backend more --- .../plasmid/api/game/player/JoinIntent.java | 22 +- .../xyz/nucleoid/plasmid/impl/Plasmid.java | 55 +++- .../plasmid/impl/command/GameCommand.java | 7 +- .../plasmid/impl/command/ui/GameJoinUi.java | 187 -------------- .../plasmid/impl/portal/GamePortal.java | 6 +- .../plasmid/impl/portal/GamePortalConfig.java | 25 -- .../impl/portal/GamePortalManager.java | 13 +- .../{ => backend}/GamePortalBackend.java | 8 +- .../game/ConcurrentGamePortalBackend.java | 2 +- .../game/GameConfigGamePortalBackend.java | 4 +- .../game/InvalidGamePortalBackend.java | 11 +- .../game/NewGamePortalBackend.java | 2 +- .../game/SingleGamePortalBackend.java | 3 +- .../backend/menu/ActiveGamePortalBackend.java | 236 ++++++++++++++++++ .../menu/AdvancedMenuPortalBackend.java | 8 +- .../{ => backend}/menu/MenuPortalBackend.java | 11 +- .../portal/config/ActiveGamePortalConfig.java | 38 +++ .../AdvancedMenuPortalConfig.java | 19 +- .../ConcurrentGamePortalConfig.java | 11 +- .../impl/portal/config/GamePortalConfig.java | 42 ++++ .../{menu => config}/MenuPortalConfig.java | 18 +- .../{game => config}/NewGamePortalConfig.java | 11 +- .../SingleGamePortalConfig.java | 11 +- .../game/LegacyOnDemandPortalConfig.java | 28 --- .../impl/portal/menu/GameMenuEntry.java | 4 +- .../impl/portal/menu/GameMenuEntryConfig.java | 2 +- .../plasmid/impl/portal/menu/MenuEntry.java | 2 +- .../plasmid/impl/portal/menu/PortalEntry.java | 2 +- 28 files changed, 432 insertions(+), 356 deletions(-) delete mode 100644 src/main/java/xyz/nucleoid/plasmid/impl/command/ui/GameJoinUi.java delete mode 100644 src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortalConfig.java rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{ => backend}/GamePortalBackend.java (90%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{ => backend}/game/ConcurrentGamePortalBackend.java (97%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{ => backend}/game/GameConfigGamePortalBackend.java (93%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{ => backend}/game/InvalidGamePortalBackend.java (73%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{ => backend}/game/NewGamePortalBackend.java (96%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{ => backend}/game/SingleGamePortalBackend.java (97%) create mode 100644 src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/ActiveGamePortalBackend.java rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{ => backend}/menu/AdvancedMenuPortalBackend.java (88%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{ => backend}/menu/MenuPortalBackend.java (85%) create mode 100644 src/main/java/xyz/nucleoid/plasmid/impl/portal/config/ActiveGamePortalConfig.java rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{menu => config}/AdvancedMenuPortalConfig.java (72%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{game => config}/ConcurrentGamePortalConfig.java (67%) create mode 100644 src/main/java/xyz/nucleoid/plasmid/impl/portal/config/GamePortalConfig.java rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{menu => config}/MenuPortalConfig.java (83%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{game => config}/NewGamePortalConfig.java (67%) rename src/main/java/xyz/nucleoid/plasmid/impl/portal/{game => config}/SingleGamePortalConfig.java (67%) delete mode 100644 src/main/java/xyz/nucleoid/plasmid/impl/portal/game/LegacyOnDemandPortalConfig.java diff --git a/src/main/java/xyz/nucleoid/plasmid/api/game/player/JoinIntent.java b/src/main/java/xyz/nucleoid/plasmid/api/game/player/JoinIntent.java index e2861ae1..0cd7f733 100644 --- a/src/main/java/xyz/nucleoid/plasmid/api/game/player/JoinIntent.java +++ b/src/main/java/xyz/nucleoid/plasmid/api/game/player/JoinIntent.java @@ -1,5 +1,6 @@ package xyz.nucleoid.plasmid.api.game.player; +import net.minecraft.util.StringIdentifiable; import xyz.nucleoid.plasmid.api.game.GameSpace; import xyz.nucleoid.plasmid.api.game.event.GamePlayerEvents; @@ -8,23 +9,25 @@ * It is up to the game implementation to respect this intent in the way that is appropriate for their game. This may be * accomplished by handling the {@link GamePlayerEvents#OFFER 'Join Offer'} events. */ -public enum JoinIntent { - /** - * The player has no particular intention. Generally, this should be considered as a preference to participate. - */ - //ANY, +public enum JoinIntent implements StringIdentifiable { /** * The player intends to join the game to participate. If they cannot be joined as a participant, they should not * be allowed to join. */ - PLAY, + PLAY("play"), /** * The player intends to join the game to spectate. Unless the game does not support spectators, this player should * generally always be accepted. */ - SPECTATE, + SPECTATE("spectate"), ; + private final String name; + + JoinIntent(String name) { + this.name = name; + } + /** * @return {@code true} if the player may join as a participant under any circumstances */ @@ -38,4 +41,9 @@ public boolean canPlay() { public boolean canSpectate() { return this != PLAY; } + + @Override + public String asString() { + return this.name; + } } diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/Plasmid.java b/src/main/java/xyz/nucleoid/plasmid/impl/Plasmid.java index f3095520..c5566bf6 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/Plasmid.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/Plasmid.java @@ -1,6 +1,5 @@ package xyz.nucleoid.plasmid.impl; -import com.mojang.serialization.Codec; import com.mojang.serialization.MapCodec; import com.sun.net.httpserver.HttpServer; import net.fabricmc.api.ModInitializer; @@ -12,17 +11,17 @@ import net.fabricmc.loader.api.FabricLoader; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.resource.ResourceManager; +import net.minecraft.screen.ScreenTexts; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.Identifier; -import net.minecraft.util.Unit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import xyz.nucleoid.plasmid.api.event.GameEvents; -import xyz.nucleoid.plasmid.api.game.GameOpenContext; import xyz.nucleoid.plasmid.api.game.GameOpenException; +import xyz.nucleoid.plasmid.api.game.GameSpaceManager; import xyz.nucleoid.plasmid.api.game.GameType; import xyz.nucleoid.plasmid.impl.game.composite.RandomGame; import xyz.nucleoid.plasmid.impl.game.composite.RandomGameConfig; @@ -30,15 +29,19 @@ import xyz.nucleoid.plasmid.api.game.config.GameConfigs; import xyz.nucleoid.plasmid.api.game.event.GameActivityEvents; import xyz.nucleoid.plasmid.impl.game.manager.GameSpaceManagerImpl; -import xyz.nucleoid.plasmid.impl.portal.GamePortalConfig; +import xyz.nucleoid.plasmid.impl.portal.backend.game.ConcurrentGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.game.NewGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.game.SingleGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.menu.ActiveGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.menu.AdvancedMenuPortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.menu.MenuPortalBackend; +import xyz.nucleoid.plasmid.impl.portal.config.GamePortalConfig; import xyz.nucleoid.plasmid.impl.portal.GamePortalInterface; import xyz.nucleoid.plasmid.impl.portal.GamePortalManager; -import xyz.nucleoid.plasmid.impl.portal.game.ConcurrentGamePortalConfig; -import xyz.nucleoid.plasmid.impl.portal.game.LegacyOnDemandPortalConfig; -import xyz.nucleoid.plasmid.impl.portal.game.NewGamePortalConfig; -import xyz.nucleoid.plasmid.impl.portal.game.SingleGamePortalConfig; +import xyz.nucleoid.plasmid.impl.portal.config.*; import xyz.nucleoid.plasmid.impl.command.*; import xyz.nucleoid.plasmid.impl.compatibility.TrinketsCompatibility; +import xyz.nucleoid.plasmid.impl.portal.menu.GameMenuEntryConfig; import xyz.nucleoid.plasmid.impl.portal.menu.*; public final class Plasmid implements ModInitializer { @@ -53,14 +56,48 @@ public void onInitialize() { GamePortalConfig.register(Identifier.of(ID, "single_game"), SingleGamePortalConfig.CODEC); GamePortalConfig.register(Identifier.of(ID, "new_game"), NewGamePortalConfig.CODEC); GamePortalConfig.register(Identifier.of(ID, "concurrent_game"), ConcurrentGamePortalConfig.CODEC); - GamePortalConfig.register(Identifier.of(ID, "on_demand"), LegacyOnDemandPortalConfig.CODEC); // old one + GamePortalConfig.register(Identifier.of(ID, "active_games"), ActiveGamePortalConfig.CODEC); GamePortalConfig.register(Identifier.of(ID, "menu"), MenuPortalConfig.CODEC); GamePortalConfig.register(Identifier.of(ID, "advanced_menu"), AdvancedMenuPortalConfig.CODEC); MenuEntryConfig.register(Identifier.of(ID, "game"), GameMenuEntryConfig.CODEC); MenuEntryConfig.register(Identifier.of(ID, "portal"), PortalEntryConfig.CODEC); + GamePortalConfig.registerFactory(SingleGamePortalConfig.class, ((server, id, config) -> new SingleGamePortalBackend(config.game()))); + GamePortalConfig.registerFactory(NewGamePortalConfig.class, ((server, id, config) -> new NewGamePortalBackend(config.game()))); + GamePortalConfig.registerFactory(ConcurrentGamePortalConfig.class, ((server, id, config) -> new ConcurrentGamePortalBackend(config.game()))); + GamePortalConfig.registerFactory(MenuPortalConfig.class, ((server, id, config) -> { + Text name; + if (config.name() != null && config.name() != ScreenTexts.EMPTY) { + name = config.name(); + } else { + name = Text.literal(id.toString()); + } + + return new MenuPortalBackend(name, config.description(), config.icon(), config.games()); + })); + GamePortalConfig.registerFactory(AdvancedMenuPortalConfig.class, ((server, id, config) -> { + Text name; + if (config.name() != null && config.name() != ScreenTexts.EMPTY) { + name = config.name(); + } else { + name = Text.literal(id.toString()); + } + return new AdvancedMenuPortalBackend(name, config.description(), config.icon(), config.entries()); + })); + + GamePortalConfig.registerFactory(ActiveGamePortalConfig.class, ((server, id, config) -> { + Text name; + if (config.name() != null && config.name() != ScreenTexts.EMPTY) { + name = config.name(); + } else { + name = Text.literal(id.toString()); + } + return new ActiveGamePortalBackend(name, config.description(), config.icon(), GameSpaceManager.get(), config.joinIntent()); + })); + + GameType.register(Identifier.of(Plasmid.ID, "random"), RandomGameConfig.CODEC, RandomGame::open); GameType.register(Identifier.of(Plasmid.ID, "invalid"), MapCodec.unit(""), (context) -> { var id = context.server().getRegistryManager().getOrThrow(GameConfigs.REGISTRY_KEY).getId(context.game()); diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/command/GameCommand.java b/src/main/java/xyz/nucleoid/plasmid/impl/command/GameCommand.java index 02164882..249b8a89 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/command/GameCommand.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/command/GameCommand.java @@ -16,11 +16,11 @@ import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.Formatting; +import net.minecraft.util.Identifier; import org.slf4j.Logger; import xyz.nucleoid.plasmid.impl.Plasmid; import xyz.nucleoid.plasmid.impl.command.argument.GameConfigArgument; import xyz.nucleoid.plasmid.impl.command.argument.GameSpaceArgument; -import xyz.nucleoid.plasmid.impl.command.ui.GameJoinUi; import xyz.nucleoid.plasmid.api.game.GameCloseReason; import xyz.nucleoid.plasmid.api.game.GameOpenException; import xyz.nucleoid.plasmid.api.game.GameSpace; @@ -31,6 +31,8 @@ import xyz.nucleoid.plasmid.api.game.player.GamePlayerJoiner; import xyz.nucleoid.plasmid.api.game.player.JoinIntent; import xyz.nucleoid.plasmid.api.util.Scheduler; +import xyz.nucleoid.plasmid.impl.portal.config.ActiveGamePortalConfig; +import xyz.nucleoid.plasmid.impl.portal.config.GamePortalConfig; import java.util.Comparator; import java.util.stream.Collectors; @@ -250,7 +252,8 @@ private static int proposeGame(ServerCommandSource source, GameSpace gameSpace) } private static int joinGame(CommandContext context, JoinIntent intent) throws CommandSyntaxException { - new GameJoinUi(context.getSource().getPlayerOrThrow(), intent).open(); + GamePortalConfig.create(context.getSource().getServer(), Identifier.of("plasmid", "join_command"), + ActiveGamePortalConfig.of(Text.translatable("text.plasmid.ui.game_join.title"), intent)).applyTo(context.getSource().getPlayerOrThrow(), false); return Command.SINGLE_SUCCESS; } diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/command/ui/GameJoinUi.java b/src/main/java/xyz/nucleoid/plasmid/impl/command/ui/GameJoinUi.java deleted file mode 100644 index 96e0cacc..00000000 --- a/src/main/java/xyz/nucleoid/plasmid/impl/command/ui/GameJoinUi.java +++ /dev/null @@ -1,187 +0,0 @@ -package xyz.nucleoid.plasmid.impl.command.ui; - -import eu.pb4.sgui.api.elements.GuiElementBuilder; -import eu.pb4.sgui.api.elements.GuiElementInterface; -import eu.pb4.sgui.api.gui.SimpleGui; -import net.minecraft.item.Items; -import net.minecraft.screen.ScreenHandlerType; -import net.minecraft.screen.ScreenTexts; -import net.minecraft.server.network.ServerPlayerEntity; -import net.minecraft.text.Style; -import net.minecraft.text.Text; -import net.minecraft.util.Formatting; -import net.minecraft.util.math.MathHelper; -import xyz.nucleoid.plasmid.api.game.GameSpace; -import xyz.nucleoid.plasmid.api.game.config.GameConfig; -import xyz.nucleoid.plasmid.impl.game.manager.GameSpaceManagerImpl; -import xyz.nucleoid.plasmid.impl.game.manager.ManagedGameSpace; -import xyz.nucleoid.plasmid.api.game.player.GamePlayerJoiner; -import xyz.nucleoid.plasmid.api.game.player.JoinIntent; -import xyz.nucleoid.plasmid.api.util.Guis; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; - -import java.util.ArrayList; -import java.util.Comparator; - -public class GameJoinUi extends SimpleGui { - private static final GuiElementInterface EMPTY = new GuiElementBuilder(Items.GRAY_STAINED_GLASS_PANE).hideTooltip().build(); - - private static final int NAVBAR_POS = 81; - private final ServerPlayerEntity player; - private final JoinIntent joinIntent; - private int tick; - private int page = 0; - private int pageSize; - - public GameJoinUi(ServerPlayerEntity player, JoinIntent intent) { - super(ScreenHandlerType.GENERIC_9X6, player, true); - this.joinIntent = intent; - this.player = player; - this.setTitle(Text.translatable("text.plasmid.ui.game_join.title")); - this.updateUi(); - } - - private static void tryJoinGame(ServerPlayerEntity player, GameSpace gameSpace, JoinIntent joinIntent) { - player.server.execute(() -> { - var result = GamePlayerJoiner.tryJoin(player, gameSpace, joinIntent); - if (result.isError()) { - player.sendMessage(result.errorCopy().formatted(Formatting.RED)); - } - }); - } - - @Override - public void onTick() { - super.onTick(); - this.tick++; - if (this.tick % 20 == 0) { - this.updateUi(); - } - } - - private void updateUi() { - int i = 0; - int gameI = 0; - - var games = new ArrayList<>(GameSpaceManagerImpl.get().getOpenGameSpaces()); - games.sort(Comparator.comparingInt(space -> -space.getPlayers().size())); - - int limit = this.size; - this.pageSize = 0; - - if (games.size() > this.size) { - limit = NAVBAR_POS; - this.pageSize = games.size() / NAVBAR_POS; - } - - this.page = MathHelper.clamp(this.page, 0, this.pageSize); - - for (var gameSpace : games) { - if (gameI >= this.page * NAVBAR_POS) { - if (i < limit) { - this.setSlot(i++, this.createIconFor(gameSpace)); - } - } - gameI++; - } - - for (; i < limit; i++) { - this.clearSlot(i); - } - - if (this.pageSize != 0) { - boolean hasPrevious = this.page != 0; - boolean hasNext = this.page < this.pageSize; - - this.setSlot(NAVBAR_POS, EMPTY); - this.setSlot(NAVBAR_POS + 1, EMPTY); - - this.setSlot(NAVBAR_POS + 2, new GuiElementBuilder(hasPrevious ? Items.LIME_STAINED_GLASS_PANE : Items.BLACK_STAINED_GLASS_PANE) - .setName(Text.translatable("spectatorMenu.previous_page").formatted(hasPrevious ? Formatting.GOLD : Formatting.DARK_GRAY)) - .setCallback((x, y, z) -> this.changePage(-1)) - ); - int pageValue = this.page + 1; - - var registries = this.player.getRegistryManager(); - this.setSlot(NAVBAR_POS + 3, Guis.getNumericBanner(registries, pageValue / 100)); - this.setSlot(NAVBAR_POS + 4, Guis.getNumericBanner(registries, pageValue / 10)); - this.setSlot(NAVBAR_POS + 5, Guis.getNumericBanner(registries, pageValue)); - - this.setSlot(NAVBAR_POS + 6, new GuiElementBuilder(hasNext ? Items.LIME_STAINED_GLASS_PANE : Items.BLACK_STAINED_GLASS_PANE) - .setName(Text.translatable("spectatorMenu.next_page").formatted(hasNext ? Formatting.GOLD : Formatting.DARK_GRAY)) - .setCallback((x, y, z) -> this.changePage(1)) - ); - - this.setSlot(NAVBAR_POS + 7, EMPTY); - this.setSlot(NAVBAR_POS + 8, EMPTY); - } - } - - private void changePage(int change) { - this.page = MathHelper.clamp(this.page + change, 0, this.pageSize); - this.updateUi(); - } - - private GuiElementBuilder createIconFor(GameSpace gameSpace) { - var state = gameSpace.getState(); - var sourceConfig = gameSpace.getMetadata().sourceConfig(); - var element = GuiElementBuilder.from(sourceConfig.value().icon().copy()).hideDefaultTooltip() - .setName(GameConfig.name(sourceConfig).copy()); - - for (var line : sourceConfig.value().description()) { - var text = line.copy(); - - if (line.getStyle().getColor() == null) { - text.setStyle(line.getStyle().withColor(Formatting.GRAY)); - } - - element.addLoreLine(text); - } - - boolean allowSpace = true; - - if (!state.state().hidden()) { - element.addLoreLine(ScreenTexts.EMPTY); - element.addLoreLine(Text.literal(" ").append(state.state().display()).formatted(Formatting.WHITE)); - allowSpace = false; - } - - if (state.players() > -1) { - if (allowSpace) { - element.addLoreLine(ScreenTexts.EMPTY); - allowSpace = false; - } - element.addLoreLine(Text.empty() - .append(Text.literal("» ").formatted(Formatting.DARK_GRAY)) - .append(Text.translatable("text.plasmid.ui.game_join.players", - Text.literal(state.players() + (state.maxPlayers() > 0 ? " / " + state.maxPlayers() : "")).formatted(Formatting.YELLOW)).formatted(Formatting.GOLD)) - ); - } - - if (state.spectators() > 0) { - if (allowSpace) { - element.addLoreLine(ScreenTexts.EMPTY); - allowSpace = false; - } - - element.addLoreLine(Text.empty() - .append(Text.literal("» ").formatted(Formatting.DARK_GRAY)) - .append(Text.translatable("text.plasmid.ui.game_join.spectators", - Text.literal( state.spectators() + "").formatted(Formatting.YELLOW)).formatted(Formatting.GOLD)) - ); - } - - var actionType = this.joinIntent == JoinIntent.PLAY ? GamePortalBackend.ActionType.PLAY : GamePortalBackend.ActionType.SPECTATE; - - if (actionType != GamePortalBackend.ActionType.NONE) { - element.addLoreLine(Text.empty().append(Text.literal(" [ ").formatted(Formatting.GRAY)) - .append(actionType.text()) - .append(Text.literal(" ]").formatted(Formatting.GRAY)).setStyle(Style.EMPTY.withColor(0x76ed6f))); - } - - element.hideDefaultTooltip(); - element.setCallback((a, b, c, d) -> tryJoinGame(this.getPlayer(), gameSpace, joinIntent)); - - return element; - } -} diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortal.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortal.java index ffd8c412..9f1e70db 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortal.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortal.java @@ -9,6 +9,8 @@ import net.minecraft.util.Identifier; import xyz.nucleoid.plasmid.api.game.GameSpace; import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.config.GamePortalConfig; import java.util.List; import java.util.Set; @@ -24,9 +26,9 @@ public final class GamePortal { private GamePortalDisplay lastDisplay = new GamePortalDisplay(); private GamePortalDisplay currentDisplay = new GamePortalDisplay(); - public GamePortal(MinecraftServer server, Identifier id, GamePortalBackend.Factory backendFactory) { + public GamePortal(Identifier id, GamePortalBackend backend) { this.id = id; - this.backend = backendFactory.create(server, id); + this.backend = backend; } void setCustom(CustomValuesConfig custom) { diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortalConfig.java deleted file mode 100644 index 7034b447..00000000 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortalConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -package xyz.nucleoid.plasmid.impl.portal; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.Identifier; -import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; -import xyz.nucleoid.plasmid.api.util.TinyRegistry; - -import java.util.function.Function; - -public interface GamePortalConfig { - TinyRegistry> REGISTRY = TinyRegistry.create(); - Codec CODEC = REGISTRY.dispatchStable(GamePortalConfig::codec, Function.identity()); - - static void register(Identifier key, MapCodec codec) { - REGISTRY.register(key, codec); - } - - GamePortalBackend createBackend(MinecraftServer server, Identifier id); - - CustomValuesConfig custom(); - - MapCodec codec(); -} diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortalManager.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortalManager.java index 678b9f9e..60f70f43 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortalManager.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/GamePortalManager.java @@ -3,7 +3,6 @@ import com.google.gson.JsonParseException; import com.google.gson.JsonParser; import com.mojang.serialization.JsonOps; -import com.mojang.serialization.MapCodec; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.registry.DynamicRegistryManager; import net.minecraft.resource.ResourceManager; @@ -14,7 +13,8 @@ import xyz.nucleoid.plasmid.impl.Plasmid; import xyz.nucleoid.plasmid.api.util.TinyRegistry; import xyz.nucleoid.plasmid.impl.PlasmidConfig; -import xyz.nucleoid.plasmid.impl.portal.game.InvalidGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.game.InvalidGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.config.GamePortalConfig; import java.io.IOException; import java.util.Collection; @@ -72,10 +72,13 @@ private void loadPortalsFrom(MinecraftServer server, Map consumer) {} - interface Factory { - GamePortalBackend create(MinecraftServer server, Identifier id); + interface Factory { + GamePortalBackend create(MinecraftServer server, Identifier id, T config); } record ActionType(Text text, Text textAlt) { diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/ConcurrentGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/ConcurrentGamePortalBackend.java similarity index 97% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/game/ConcurrentGamePortalBackend.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/ConcurrentGamePortalBackend.java index 5e8c445c..26d221ab 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/ConcurrentGamePortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/ConcurrentGamePortalBackend.java @@ -1,4 +1,4 @@ -package xyz.nucleoid.plasmid.impl.portal.game; +package xyz.nucleoid.plasmid.impl.portal.backend.game; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.MinecraftServer; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/GameConfigGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/GameConfigGamePortalBackend.java similarity index 93% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/game/GameConfigGamePortalBackend.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/GameConfigGamePortalBackend.java index b8db32f9..25c51327 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/GameConfigGamePortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/GameConfigGamePortalBackend.java @@ -1,4 +1,4 @@ -package xyz.nucleoid.plasmid.impl.portal.game; +package xyz.nucleoid.plasmid.impl.portal.backend.game; import net.minecraft.item.ItemStack; import net.minecraft.registry.entry.RegistryEntry; @@ -6,7 +6,7 @@ import xyz.nucleoid.plasmid.api.game.GameSpace; import xyz.nucleoid.plasmid.api.game.config.GameConfig; import xyz.nucleoid.plasmid.impl.game.manager.GameSpaceManagerImpl; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; import java.util.List; import java.util.function.Consumer; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/InvalidGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/InvalidGamePortalBackend.java similarity index 73% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/game/InvalidGamePortalBackend.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/InvalidGamePortalBackend.java index 9aeebd60..65d43da8 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/InvalidGamePortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/InvalidGamePortalBackend.java @@ -1,4 +1,4 @@ -package xyz.nucleoid.plasmid.impl.portal.game; +package xyz.nucleoid.plasmid.impl.portal.backend.game; import com.mojang.serialization.MapCodec; import net.minecraft.server.MinecraftServer; @@ -6,16 +6,11 @@ import net.minecraft.text.Text; import net.minecraft.util.Identifier; import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; -import xyz.nucleoid.plasmid.impl.portal.GamePortalConfig; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.config.GamePortalConfig; public record InvalidGamePortalBackend(Identifier identifier) implements GamePortalBackend { public static final GamePortalConfig CONFIG = new GamePortalConfig() { - @Override - public GamePortalBackend createBackend(MinecraftServer server, Identifier id) { - return new InvalidGamePortalBackend(id); - } - @Override public CustomValuesConfig custom() { return CustomValuesConfig.empty(); diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/NewGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/NewGamePortalBackend.java similarity index 96% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/game/NewGamePortalBackend.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/NewGamePortalBackend.java index 5dfab361..307c70fb 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/NewGamePortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/NewGamePortalBackend.java @@ -1,4 +1,4 @@ -package xyz.nucleoid.plasmid.impl.portal.game; +package xyz.nucleoid.plasmid.impl.portal.backend.game; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.MinecraftServer; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/SingleGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/SingleGamePortalBackend.java similarity index 97% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/game/SingleGamePortalBackend.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/SingleGamePortalBackend.java index 83b4091f..95639da2 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/SingleGamePortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/game/SingleGamePortalBackend.java @@ -1,4 +1,4 @@ -package xyz.nucleoid.plasmid.impl.portal.game; +package xyz.nucleoid.plasmid.impl.portal.backend.game; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.MinecraftServer; @@ -14,7 +14,6 @@ import xyz.nucleoid.plasmid.api.game.player.JoinIntent; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutionException; import java.util.function.Consumer; import java.util.function.Function; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/ActiveGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/ActiveGamePortalBackend.java new file mode 100644 index 00000000..895e6ee0 --- /dev/null +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/ActiveGamePortalBackend.java @@ -0,0 +1,236 @@ +package xyz.nucleoid.plasmid.impl.portal.backend.menu; + +import eu.pb4.sgui.api.elements.GuiElementBuilder; +import eu.pb4.sgui.api.elements.GuiElementInterface; +import eu.pb4.sgui.api.gui.SimpleGui; +import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.screen.ScreenHandlerType; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.server.network.ServerPlayerEntity; +import net.minecraft.text.Style; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.util.math.MathHelper; +import xyz.nucleoid.plasmid.api.game.GameSpace; +import xyz.nucleoid.plasmid.api.game.GameSpaceManager; +import xyz.nucleoid.plasmid.api.game.config.GameConfig; +import xyz.nucleoid.plasmid.api.game.player.GamePlayerJoiner; +import xyz.nucleoid.plasmid.api.game.player.JoinIntent; +import xyz.nucleoid.plasmid.api.util.Guis; +import xyz.nucleoid.plasmid.impl.game.manager.GameSpaceManagerImpl; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.game.ConcurrentGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.config.MenuPortalConfig; +import xyz.nucleoid.plasmid.impl.portal.menu.GameMenuEntry; +import xyz.nucleoid.plasmid.impl.portal.menu.MenuEntry; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.function.Consumer; + +public final class ActiveGamePortalBackend implements GamePortalBackend { + private final Text name; + private final List description; + private final ItemStack icon; + private final GameSpaceManager manager; + private final JoinIntent intent; + + public ActiveGamePortalBackend( Text name, List description, ItemStack icon, GameSpaceManager manager, JoinIntent intent) { + this.name = name; + this.description = description; + this.icon = icon; + this.manager = manager; + this.intent = intent; + } + + @Override + public Text getName() { + return this.name; + } + + @Override + public List getDescription() { + return this.description; + } + + @Override + public ItemStack getIcon() { + return this.icon; + } + + @Override + public void provideGameSpaces(Consumer consumer) { + this.manager.getOpenGameSpaces().forEach(consumer); + } + + @Override + public void applyTo(ServerPlayerEntity player, boolean alt) { + new GameJoinUi(player, this.name, this.intent).open(); + } + + private static final class GameJoinUi extends SimpleGui { + private static final GuiElementInterface EMPTY = new GuiElementBuilder(Items.GRAY_STAINED_GLASS_PANE).hideTooltip().build(); + + private static final int NAVBAR_POS = 81; + private final ServerPlayerEntity player; + private final JoinIntent joinIntent; + private int tick; + private int page = 0; + private int pageSize; + + public GameJoinUi(ServerPlayerEntity player, Text name, JoinIntent intent) { + super(ScreenHandlerType.GENERIC_9X6, player, true); + this.joinIntent = intent; + this.player = player; + this.setTitle(name); + this.updateUi(); + } + + private static void tryJoinGame(ServerPlayerEntity player, GameSpace gameSpace, JoinIntent joinIntent) { + player.server.execute(() -> { + var result = GamePlayerJoiner.tryJoin(player, gameSpace, joinIntent); + if (result.isError()) { + player.sendMessage(result.errorCopy().formatted(Formatting.RED)); + } + }); + } + + @Override + public void onTick() { + super.onTick(); + this.tick++; + if (this.tick % 20 == 0) { + this.updateUi(); + } + } + + private void updateUi() { + int i = 0; + int gameI = 0; + + var games = new ArrayList<>(GameSpaceManagerImpl.get().getOpenGameSpaces()); + games.sort(Comparator.comparingInt(space -> -space.getPlayers().size())); + + int limit = this.size; + this.pageSize = 0; + + if (games.size() > this.size) { + limit = NAVBAR_POS; + this.pageSize = games.size() / NAVBAR_POS; + } + + this.page = MathHelper.clamp(this.page, 0, this.pageSize); + + for (var gameSpace : games) { + if (gameI >= this.page * NAVBAR_POS) { + if (i < limit) { + this.setSlot(i++, this.createIconFor(gameSpace)); + } + } + gameI++; + } + + for (; i < limit; i++) { + this.clearSlot(i); + } + + if (this.pageSize != 0) { + boolean hasPrevious = this.page != 0; + boolean hasNext = this.page < this.pageSize; + + this.setSlot(NAVBAR_POS, EMPTY); + this.setSlot(NAVBAR_POS + 1, EMPTY); + + this.setSlot(NAVBAR_POS + 2, new GuiElementBuilder(hasPrevious ? Items.LIME_STAINED_GLASS_PANE : Items.BLACK_STAINED_GLASS_PANE) + .setName(Text.translatable("spectatorMenu.previous_page").formatted(hasPrevious ? Formatting.GOLD : Formatting.DARK_GRAY)) + .setCallback((x, y, z) -> this.changePage(-1)) + ); + int pageValue = this.page + 1; + + var registries = this.player.getRegistryManager(); + this.setSlot(NAVBAR_POS + 3, Guis.getNumericBanner(registries, pageValue / 100)); + this.setSlot(NAVBAR_POS + 4, Guis.getNumericBanner(registries, pageValue / 10)); + this.setSlot(NAVBAR_POS + 5, Guis.getNumericBanner(registries, pageValue)); + + this.setSlot(NAVBAR_POS + 6, new GuiElementBuilder(hasNext ? Items.LIME_STAINED_GLASS_PANE : Items.BLACK_STAINED_GLASS_PANE) + .setName(Text.translatable("spectatorMenu.next_page").formatted(hasNext ? Formatting.GOLD : Formatting.DARK_GRAY)) + .setCallback((x, y, z) -> this.changePage(1)) + ); + + this.setSlot(NAVBAR_POS + 7, EMPTY); + this.setSlot(NAVBAR_POS + 8, EMPTY); + } + } + + private void changePage(int change) { + this.page = MathHelper.clamp(this.page + change, 0, this.pageSize); + this.updateUi(); + } + + private GuiElementBuilder createIconFor(GameSpace gameSpace) { + var state = gameSpace.getState(); + var sourceConfig = gameSpace.getMetadata().sourceConfig(); + var element = GuiElementBuilder.from(sourceConfig.value().icon().copy()).hideDefaultTooltip() + .setName(GameConfig.name(sourceConfig).copy()); + + for (var line : sourceConfig.value().description()) { + var text = line.copy(); + + if (line.getStyle().getColor() == null) { + text.setStyle(line.getStyle().withColor(Formatting.GRAY)); + } + + element.addLoreLine(text); + } + + boolean allowSpace = true; + + if (!state.state().hidden()) { + element.addLoreLine(ScreenTexts.EMPTY); + element.addLoreLine(Text.literal(" ").append(state.state().display()).formatted(Formatting.WHITE)); + allowSpace = false; + } + + if (state.players() > -1) { + if (allowSpace) { + element.addLoreLine(ScreenTexts.EMPTY); + allowSpace = false; + } + element.addLoreLine(Text.empty() + .append(Text.literal("» ").formatted(Formatting.DARK_GRAY)) + .append(Text.translatable("text.plasmid.ui.game_join.players", + Text.literal(state.players() + (state.maxPlayers() > 0 ? " / " + state.maxPlayers() : "")).formatted(Formatting.YELLOW)).formatted(Formatting.GOLD)) + ); + } + + if (state.spectators() > 0) { + if (allowSpace) { + element.addLoreLine(ScreenTexts.EMPTY); + allowSpace = false; + } + + element.addLoreLine(Text.empty() + .append(Text.literal("» ").formatted(Formatting.DARK_GRAY)) + .append(Text.translatable("text.plasmid.ui.game_join.spectators", + Text.literal( state.spectators() + "").formatted(Formatting.YELLOW)).formatted(Formatting.GOLD)) + ); + } + + var actionType = this.joinIntent == JoinIntent.PLAY ? GamePortalBackend.ActionType.PLAY : GamePortalBackend.ActionType.SPECTATE; + + if (actionType != GamePortalBackend.ActionType.NONE) { + element.addLoreLine(Text.empty().append(Text.literal(" [ ").formatted(Formatting.GRAY)) + .append(actionType.text()) + .append(Text.literal(" ]").formatted(Formatting.GRAY)).setStyle(Style.EMPTY.withColor(0x76ed6f))); + } + + element.hideDefaultTooltip(); + element.setCallback((a, b, c, d) -> tryJoinGame(this.getPlayer(), gameSpace, joinIntent)); + + return element; + } + } +} diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/AdvancedMenuPortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/AdvancedMenuPortalBackend.java similarity index 88% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/AdvancedMenuPortalBackend.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/AdvancedMenuPortalBackend.java index 1f1a44a4..561a3121 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/AdvancedMenuPortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/AdvancedMenuPortalBackend.java @@ -1,4 +1,4 @@ -package xyz.nucleoid.plasmid.impl.portal.menu; +package xyz.nucleoid.plasmid.impl.portal.backend.menu; import eu.pb4.sgui.api.elements.GuiElementInterface; import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; @@ -6,8 +6,10 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import xyz.nucleoid.plasmid.api.game.GameSpace; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; import xyz.nucleoid.plasmid.api.util.Guis; +import xyz.nucleoid.plasmid.impl.portal.menu.MenuEntry; +import xyz.nucleoid.plasmid.impl.portal.menu.MenuEntryConfig; import java.util.ArrayList; import java.util.List; @@ -22,7 +24,7 @@ public final class AdvancedMenuPortalBackend implements GamePortalBackend { private final List entryConfigs; private List entries; - AdvancedMenuPortalBackend(Text name, List description, ItemStack icon, List entryConfigs) { + public AdvancedMenuPortalBackend(Text name, List description, ItemStack icon, List entryConfigs) { this.name = name; this.description = description; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuPortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/MenuPortalBackend.java similarity index 85% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuPortalBackend.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/MenuPortalBackend.java index 6ebe7c97..335b87c0 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuPortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/backend/menu/MenuPortalBackend.java @@ -1,4 +1,4 @@ -package xyz.nucleoid.plasmid.impl.portal.menu; +package xyz.nucleoid.plasmid.impl.portal.backend.menu; import eu.pb4.sgui.api.elements.GuiElementInterface; import it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet; @@ -6,10 +6,13 @@ import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; import xyz.nucleoid.plasmid.api.game.config.GameConfig; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; import xyz.nucleoid.plasmid.api.game.GameSpace; -import xyz.nucleoid.plasmid.impl.portal.game.ConcurrentGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.game.ConcurrentGamePortalBackend; import xyz.nucleoid.plasmid.api.util.Guis; +import xyz.nucleoid.plasmid.impl.portal.menu.GameMenuEntry; +import xyz.nucleoid.plasmid.impl.portal.menu.MenuEntry; +import xyz.nucleoid.plasmid.impl.portal.config.MenuPortalConfig; import java.util.ArrayList; import java.util.List; @@ -21,7 +24,7 @@ public final class MenuPortalBackend implements GamePortalBackend { private final List description; private final ItemStack icon; - MenuPortalBackend(Text name, List description, ItemStack icon, List games) { + public MenuPortalBackend(Text name, List description, ItemStack icon, List games) { this.name = name; this.description = description; this.icon = icon; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/ActiveGamePortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/ActiveGamePortalConfig.java new file mode 100644 index 00000000..989c3209 --- /dev/null +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/ActiveGamePortalConfig.java @@ -0,0 +1,38 @@ +package xyz.nucleoid.plasmid.impl.portal.config; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.screen.ScreenTexts; +import net.minecraft.text.Text; +import net.minecraft.util.StringIdentifiable; +import xyz.nucleoid.codecs.MoreCodecs; +import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; +import xyz.nucleoid.plasmid.api.game.player.JoinIntent; +import xyz.nucleoid.plasmid.api.util.PlasmidCodecs; + +import java.util.List; + +public record ActiveGamePortalConfig(Text name, + List description, + ItemStack icon, + JoinIntent joinIntent, + CustomValuesConfig custom) implements GamePortalConfig { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group( + PlasmidCodecs.TEXT.optionalFieldOf("name", ScreenTexts.EMPTY).forGetter(ActiveGamePortalConfig::name), + MoreCodecs.listOrUnit(PlasmidCodecs.TEXT).optionalFieldOf("description", List.of()).forGetter(ActiveGamePortalConfig::description), + MoreCodecs.ITEM_STACK.optionalFieldOf("icon", new ItemStack(Items.GRASS_BLOCK)).forGetter(ActiveGamePortalConfig::icon), + StringIdentifiable.createCodec(JoinIntent::values).fieldOf("join_intent").forGetter(ActiveGamePortalConfig::joinIntent), + CustomValuesConfig.CODEC.optionalFieldOf("custom", CustomValuesConfig.empty()).forGetter(ActiveGamePortalConfig::custom) + ).apply(i, ActiveGamePortalConfig::new)); + + @Override + public MapCodec codec() { + return CODEC; + } + + public static ActiveGamePortalConfig of(Text name, JoinIntent intent) { + return new ActiveGamePortalConfig(name, List.of(), ItemStack.EMPTY, intent, CustomValuesConfig.empty()); + } +} diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/AdvancedMenuPortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/AdvancedMenuPortalConfig.java similarity index 72% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/AdvancedMenuPortalConfig.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/config/AdvancedMenuPortalConfig.java index 273340a2..09fc92d8 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/AdvancedMenuPortalConfig.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/AdvancedMenuPortalConfig.java @@ -1,18 +1,15 @@ -package xyz.nucleoid.plasmid.impl.portal.menu; +package xyz.nucleoid.plasmid.impl.portal.config; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.item.ItemStack; import net.minecraft.item.Items; import net.minecraft.screen.ScreenTexts; -import net.minecraft.server.MinecraftServer; import net.minecraft.text.Text; -import net.minecraft.util.Identifier; import xyz.nucleoid.codecs.MoreCodecs; import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; -import xyz.nucleoid.plasmid.impl.portal.GamePortalConfig; import xyz.nucleoid.plasmid.api.util.PlasmidCodecs; +import xyz.nucleoid.plasmid.impl.portal.menu.MenuEntryConfig; import java.util.List; @@ -31,18 +28,6 @@ public record AdvancedMenuPortalConfig( CustomValuesConfig.CODEC.optionalFieldOf("custom", CustomValuesConfig.empty()).forGetter(config -> config.custom) ).apply(i, AdvancedMenuPortalConfig::new)); - @Override - public GamePortalBackend createBackend(MinecraftServer server, Identifier id) { - Text name; - if (this.name != null) { - name = this.name; - } else { - name = Text.literal(id.toString()); - } - - return new AdvancedMenuPortalBackend(name, description, icon, this.entries); - } - @Override public MapCodec codec() { return CODEC; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/ConcurrentGamePortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/ConcurrentGamePortalConfig.java similarity index 67% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/game/ConcurrentGamePortalConfig.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/config/ConcurrentGamePortalConfig.java index 433e0f6e..5a5a0c08 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/ConcurrentGamePortalConfig.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/ConcurrentGamePortalConfig.java @@ -1,14 +1,10 @@ -package xyz.nucleoid.plasmid.impl.portal.game; +package xyz.nucleoid.plasmid.impl.portal.config; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.Identifier; import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; import xyz.nucleoid.plasmid.api.game.config.GameConfig; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; -import xyz.nucleoid.plasmid.impl.portal.GamePortalConfig; public record ConcurrentGamePortalConfig(RegistryEntry> game, CustomValuesConfig custom) implements GamePortalConfig { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group( @@ -16,11 +12,6 @@ public record ConcurrentGamePortalConfig(RegistryEntry> game, Cust CustomValuesConfig.CODEC.optionalFieldOf("custom", CustomValuesConfig.empty()).forGetter(c -> c.custom) ).apply(i, ConcurrentGamePortalConfig::new)); - @Override - public GamePortalBackend createBackend(MinecraftServer server, Identifier id) { - return new ConcurrentGamePortalBackend(this.game); - } - @Override public MapCodec codec() { return CODEC; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/GamePortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/GamePortalConfig.java new file mode 100644 index 00000000..bf03c84b --- /dev/null +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/GamePortalConfig.java @@ -0,0 +1,42 @@ +package xyz.nucleoid.plasmid.impl.portal.config; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import net.minecraft.server.MinecraftServer; +import net.minecraft.util.Identifier; +import org.jetbrains.annotations.Nullable; +import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; +import xyz.nucleoid.plasmid.api.util.TinyRegistry; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; + +import java.util.IdentityHashMap; +import java.util.Map; +import java.util.function.Function; + +public interface GamePortalConfig { + TinyRegistry> REGISTRY = TinyRegistry.create(); + Codec CODEC = REGISTRY.dispatchStable(GamePortalConfig::codec, Function.identity()); + @Deprecated + Map, GamePortalBackend.Factory> FACTORIES = new IdentityHashMap<>(); + + static void register(Identifier key, MapCodec codec) { + REGISTRY.register(key, codec); + } + static void registerFactory(Class configClass, GamePortalBackend.Factory factory) { + FACTORIES.put(configClass, factory); + } + + @Nullable + static GamePortalBackend create(MinecraftServer server, Identifier identifier, T config) { + //noinspection unchecked + var factory = (GamePortalBackend.Factory) FACTORIES.get(config.getClass()); + if (factory != null) { + return factory.create(server, identifier, config); + } + return null; + } + + CustomValuesConfig custom(); + + MapCodec codec(); +} diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuPortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/MenuPortalConfig.java similarity index 83% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuPortalConfig.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/config/MenuPortalConfig.java index 7a040716..e9dfdf74 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuPortalConfig.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/MenuPortalConfig.java @@ -1,4 +1,4 @@ -package xyz.nucleoid.plasmid.impl.portal.menu; +package xyz.nucleoid.plasmid.impl.portal.config; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Codec; @@ -14,9 +14,9 @@ import xyz.nucleoid.codecs.MoreCodecs; import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; import xyz.nucleoid.plasmid.api.game.config.GameConfig; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; -import xyz.nucleoid.plasmid.impl.portal.GamePortalConfig; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; import xyz.nucleoid.plasmid.api.util.PlasmidCodecs; +import xyz.nucleoid.plasmid.impl.portal.backend.menu.MenuPortalBackend; import java.util.Collections; import java.util.List; @@ -39,18 +39,6 @@ public record MenuPortalConfig( CustomValuesConfig.CODEC.optionalFieldOf("custom", CustomValuesConfig.empty()).forGetter(config -> config.custom) ).apply(i, MenuPortalConfig::new)); - @Override - public GamePortalBackend createBackend(MinecraftServer server, Identifier id) { - Text name; - if (this.name != null && this.name != ScreenTexts.EMPTY) { - name = this.name; - } else { - name = Text.literal(id.toString()); - } - - return new MenuPortalBackend(name, this.description, this.icon, this.games); - } - @Override public MapCodec codec() { return CODEC; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/NewGamePortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/NewGamePortalConfig.java similarity index 67% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/game/NewGamePortalConfig.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/config/NewGamePortalConfig.java index 7c38ad6d..510bb1c7 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/NewGamePortalConfig.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/NewGamePortalConfig.java @@ -1,14 +1,10 @@ -package xyz.nucleoid.plasmid.impl.portal.game; +package xyz.nucleoid.plasmid.impl.portal.config; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.Identifier; import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; import xyz.nucleoid.plasmid.api.game.config.GameConfig; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; -import xyz.nucleoid.plasmid.impl.portal.GamePortalConfig; public record NewGamePortalConfig(RegistryEntry> game, CustomValuesConfig custom) implements GamePortalConfig { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group( @@ -16,11 +12,6 @@ public record NewGamePortalConfig(RegistryEntry> game, CustomValue CustomValuesConfig.CODEC.optionalFieldOf("custom", CustomValuesConfig.empty()).forGetter(c -> c.custom) ).apply(i, NewGamePortalConfig::new)); - @Override - public GamePortalBackend createBackend(MinecraftServer server, Identifier id) { - return new NewGamePortalBackend(this.game); - } - @Override public MapCodec codec() { return CODEC; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/SingleGamePortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/SingleGamePortalConfig.java similarity index 67% rename from src/main/java/xyz/nucleoid/plasmid/impl/portal/game/SingleGamePortalConfig.java rename to src/main/java/xyz/nucleoid/plasmid/impl/portal/config/SingleGamePortalConfig.java index 45f6dd02..ed991703 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/SingleGamePortalConfig.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/config/SingleGamePortalConfig.java @@ -1,14 +1,10 @@ -package xyz.nucleoid.plasmid.impl.portal.game; +package xyz.nucleoid.plasmid.impl.portal.config; import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.Identifier; import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; import xyz.nucleoid.plasmid.api.game.config.GameConfig; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; -import xyz.nucleoid.plasmid.impl.portal.GamePortalConfig; public record SingleGamePortalConfig(RegistryEntry> game, CustomValuesConfig custom) implements GamePortalConfig { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group( @@ -16,11 +12,6 @@ public record SingleGamePortalConfig(RegistryEntry> game, CustomVa CustomValuesConfig.CODEC.optionalFieldOf("custom", CustomValuesConfig.empty()).forGetter(c -> c.custom) ).apply(i, SingleGamePortalConfig::new)); - @Override - public GamePortalBackend createBackend(MinecraftServer server, Identifier id) { - return new SingleGamePortalBackend(this.game); - } - @Override public MapCodec codec() { return CODEC; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/LegacyOnDemandPortalConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/LegacyOnDemandPortalConfig.java deleted file mode 100644 index 287666d2..00000000 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/game/LegacyOnDemandPortalConfig.java +++ /dev/null @@ -1,28 +0,0 @@ -package xyz.nucleoid.plasmid.impl.portal.game; - -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.server.MinecraftServer; -import net.minecraft.util.Identifier; -import xyz.nucleoid.plasmid.api.game.config.CustomValuesConfig; -import xyz.nucleoid.plasmid.api.game.config.GameConfig; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; -import xyz.nucleoid.plasmid.impl.portal.GamePortalConfig; - -public record LegacyOnDemandPortalConfig(RegistryEntry> game, CustomValuesConfig custom) implements GamePortalConfig { - public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(i -> i.group( - GameConfig.CODEC.fieldOf("game").forGetter(c -> c.game), - CustomValuesConfig.CODEC.optionalFieldOf("custom", CustomValuesConfig.empty()).forGetter(c -> c.custom) - ).apply(i, LegacyOnDemandPortalConfig::new)); - - @Override - public GamePortalBackend createBackend(MinecraftServer server, Identifier id) { - return new ConcurrentGamePortalBackend(this.game); - } - - @Override - public MapCodec codec() { - return CODEC; - } -} diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/GameMenuEntry.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/GameMenuEntry.java index 7afafa16..2a220a99 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/GameMenuEntry.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/GameMenuEntry.java @@ -6,9 +6,9 @@ import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; import xyz.nucleoid.plasmid.api.game.GameSpace; -import xyz.nucleoid.plasmid.impl.portal.game.ConcurrentGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.game.ConcurrentGamePortalBackend; public record GameMenuEntry( ConcurrentGamePortalBackend game, diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/GameMenuEntryConfig.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/GameMenuEntryConfig.java index 5b543f88..458828f4 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/GameMenuEntryConfig.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/GameMenuEntryConfig.java @@ -7,7 +7,7 @@ import net.minecraft.text.Text; import xyz.nucleoid.codecs.MoreCodecs; import xyz.nucleoid.plasmid.api.game.config.GameConfig; -import xyz.nucleoid.plasmid.impl.portal.game.ConcurrentGamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.game.ConcurrentGamePortalBackend; import xyz.nucleoid.plasmid.api.util.PlasmidCodecs; import java.util.List; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuEntry.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuEntry.java index 1a7979a4..c40d798d 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuEntry.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/MenuEntry.java @@ -9,7 +9,7 @@ import net.minecraft.text.Text; import net.minecraft.util.Formatting; import org.jetbrains.annotations.Nullable; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; import xyz.nucleoid.plasmid.api.game.GameSpace; import java.util.List; diff --git a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/PortalEntry.java b/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/PortalEntry.java index a6e7364c..34f6b066 100644 --- a/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/PortalEntry.java +++ b/src/main/java/xyz/nucleoid/plasmid/impl/portal/menu/PortalEntry.java @@ -6,7 +6,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.text.Text; -import xyz.nucleoid.plasmid.impl.portal.GamePortalBackend; +import xyz.nucleoid.plasmid.impl.portal.backend.GamePortalBackend; import xyz.nucleoid.plasmid.api.game.GameSpace; import xyz.nucleoid.plasmid.impl.portal.GamePortal;