From 8ee6f3b517ea56ffcb5567dbc5ae73de27afecaf Mon Sep 17 00:00:00 2001 From: Gegy Date: Mon, 15 Jul 2024 22:02:12 +0200 Subject: [PATCH] Add JoinIntent parameter to offer and screen joins events, currently unused --- .../nucleoid/plasmid/command/GameCommand.java | 9 ++-- .../plasmid/command/ui/GameJoinUi.java | 3 +- .../plasmid/game/GameSpacePlayers.java | 9 ++-- .../plasmid/game/common/GameWaitingLobby.java | 2 +- .../plasmid/game/event/GamePlayerEvents.java | 7 ++-- .../game/manager/ManagedGameSpace.java | 10 ++--- .../game/manager/ManagedGameSpacePlayers.java | 13 +++--- .../plasmid/game/player/GamePlayerJoiner.java | 10 ++--- .../plasmid/game/player/JoinIntent.java | 42 +++++++++++++++++++ .../plasmid/game/player/LocalPlayerOffer.java | 2 +- .../plasmid/game/player/PlayerOffer.java | 6 +++ .../game/ConcurrentGamePortalBackend.java | 5 ++- .../portal/game/NewGamePortalBackend.java | 3 +- .../portal/game/SingleGamePortalBackend.java | 3 +- 14 files changed, 91 insertions(+), 33 deletions(-) create mode 100644 src/main/java/xyz/nucleoid/plasmid/game/player/JoinIntent.java diff --git a/src/main/java/xyz/nucleoid/plasmid/command/GameCommand.java b/src/main/java/xyz/nucleoid/plasmid/command/GameCommand.java index 1f6d7328..7e71bdb3 100644 --- a/src/main/java/xyz/nucleoid/plasmid/command/GameCommand.java +++ b/src/main/java/xyz/nucleoid/plasmid/command/GameCommand.java @@ -9,7 +9,6 @@ import com.mojang.logging.LogUtils; import net.minecraft.command.argument.EntityArgumentType; import net.minecraft.command.argument.NbtCompoundArgumentType; -import net.minecraft.entity.player.PlayerEntity; import net.minecraft.nbt.NbtOps; import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.server.command.ServerCommandSource; @@ -30,6 +29,7 @@ import xyz.nucleoid.plasmid.game.config.GameConfigs; import xyz.nucleoid.plasmid.game.manager.GameSpaceManager; import xyz.nucleoid.plasmid.game.player.GamePlayerJoiner; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import xyz.nucleoid.plasmid.util.Scheduler; import java.util.Comparator; @@ -286,10 +286,11 @@ private static void joinAllPlayersToGame(ServerCommandSource source, GameSpace g .filter(player -> !GameSpaceManager.get().inGame(player)) .collect(Collectors.toList()); - var screen = gameSpace.getPlayers().screenJoins(players); + var intent = JoinIntent.ANY; + var screen = gameSpace.getPlayers().screenJoins(players, intent); if (screen.isOk()) { for (var player : players) { - gameSpace.getPlayers().offer(player); + gameSpace.getPlayers().offer(player, intent); } } else { source.sendError(screen.errorCopy().formatted(Formatting.RED)); @@ -297,7 +298,7 @@ private static void joinAllPlayersToGame(ServerCommandSource source, GameSpace g } private static void tryJoinGame(ServerPlayerEntity player, GameSpace gameSpace) { - var results = GamePlayerJoiner.tryJoin(player, gameSpace); + var results = GamePlayerJoiner.tryJoin(player, gameSpace, JoinIntent.ANY); results.sendErrorsTo(player); } diff --git a/src/main/java/xyz/nucleoid/plasmid/command/ui/GameJoinUi.java b/src/main/java/xyz/nucleoid/plasmid/command/ui/GameJoinUi.java index 2efba57c..000bdb17 100644 --- a/src/main/java/xyz/nucleoid/plasmid/command/ui/GameJoinUi.java +++ b/src/main/java/xyz/nucleoid/plasmid/command/ui/GameJoinUi.java @@ -15,6 +15,7 @@ import xyz.nucleoid.plasmid.game.manager.GameSpaceManager; import xyz.nucleoid.plasmid.game.manager.ManagedGameSpace; import xyz.nucleoid.plasmid.game.player.GamePlayerJoiner; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import xyz.nucleoid.plasmid.util.Guis; import java.util.ArrayList; @@ -38,7 +39,7 @@ public GameJoinUi(ServerPlayerEntity player) { private static void tryJoinGame(ServerPlayerEntity player, GameSpace gameSpace) { player.server.execute(() -> { - var results = GamePlayerJoiner.tryJoin(player, gameSpace); + var results = GamePlayerJoiner.tryJoin(player, gameSpace, JoinIntent.ANY); results.sendErrorsTo(player); }); } diff --git a/src/main/java/xyz/nucleoid/plasmid/game/GameSpacePlayers.java b/src/main/java/xyz/nucleoid/plasmid/game/GameSpacePlayers.java index 6f6b0697..1dd79dbb 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/GameSpacePlayers.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/GameSpacePlayers.java @@ -2,6 +2,7 @@ import net.minecraft.server.network.ServerPlayerEntity; import xyz.nucleoid.plasmid.game.event.GamePlayerEvents; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import xyz.nucleoid.plasmid.game.player.PlayerOps; import xyz.nucleoid.plasmid.game.player.PlayerSet; @@ -21,12 +22,13 @@ public interface GameSpacePlayers extends PlayerSet { * This logic is controlled through the active {@link GameActivity} through {@link GamePlayerEvents#SCREEN_JOINS}. * * @param players the group of players trying to join + * @param intent the intent of the players trying to join, such as whether they want to participate or spectate * @return a {@link GameResult} describing whether this group can join this game, or an error if not * @see GamePlayerEvents#SCREEN_JOINS - * @see GameSpacePlayers#offer(ServerPlayerEntity) + * @see GameSpacePlayers#offer(ServerPlayerEntity, JoinIntent) * @see xyz.nucleoid.plasmid.game.player.GamePlayerJoiner */ - GameResult screenJoins(Collection players); + GameResult screenJoins(Collection players, JoinIntent intent); /** * Offers an individual player to join this game. If accepted, they will be teleported into the game, and if not @@ -35,11 +37,12 @@ public interface GameSpacePlayers extends PlayerSet { * This logic is controlled through the active {@link GameActivity} through {@link GamePlayerEvents#OFFER}. * * @param player the player trying to join + * @param intent the intent of the players trying to join, such as whether they want to participate or spectate * @return a {@link GameResult} describing whether this player joined the game, or an error if not * @see GamePlayerEvents#OFFER * @see xyz.nucleoid.plasmid.game.player.GamePlayerJoiner */ - GameResult offer(ServerPlayerEntity player); + GameResult offer(ServerPlayerEntity player, JoinIntent intent); /** * Attempts to remove the given {@link ServerPlayerEntity} from this {@link GameSpace}. diff --git a/src/main/java/xyz/nucleoid/plasmid/game/common/GameWaitingLobby.java b/src/main/java/xyz/nucleoid/plasmid/game/common/GameWaitingLobby.java index 603a55b7..838e75c7 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/common/GameWaitingLobby.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/common/GameWaitingLobby.java @@ -89,7 +89,7 @@ public static GameWaitingLobby addTo(GameActivity activity, PlayerConfig playerC activity.listen(GameActivityEvents.TICK, lobby::onTick); activity.listen(GameActivityEvents.REQUEST_START, lobby::requestStart); - activity.listen(GamePlayerEvents.SCREEN_JOINS, lobby::screenJoins); + activity.listen(GamePlayerEvents.SCREEN_JOINS, (players, intent) -> lobby.screenJoins(players)); activity.listen(GamePlayerEvents.OFFER, lobby::offerPlayer); activity.listen(GamePlayerEvents.REMOVE, lobby::onRemovePlayer); diff --git a/src/main/java/xyz/nucleoid/plasmid/game/event/GamePlayerEvents.java b/src/main/java/xyz/nucleoid/plasmid/game/event/GamePlayerEvents.java index 5698141b..a347fa98 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/event/GamePlayerEvents.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/event/GamePlayerEvents.java @@ -9,6 +9,7 @@ import xyz.nucleoid.plasmid.game.GameResult; import xyz.nucleoid.plasmid.game.GameSpace; import xyz.nucleoid.plasmid.game.GameTexts; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import xyz.nucleoid.plasmid.game.player.PlayerOffer; import xyz.nucleoid.plasmid.game.player.PlayerOfferResult; import xyz.nucleoid.stimuli.event.StimulusEvent; @@ -108,10 +109,10 @@ public final class GamePlayerEvents { * * @see GamePlayerEvents#OFFER */ - public static final StimulusEvent SCREEN_JOINS = StimulusEvent.create(ScreenJoins.class, ctx -> players -> { + public static final StimulusEvent SCREEN_JOINS = StimulusEvent.create(ScreenJoins.class, ctx -> (players, intent) -> { try { for (var listener : ctx.getListeners()) { - var result = listener.screenJoins(players); + var result = listener.screenJoins(players, intent); if (result.isError()) { return result; } @@ -175,7 +176,7 @@ public interface Remove { } public interface ScreenJoins { - GameResult screenJoins(Collection players); + GameResult screenJoins(Collection players, JoinIntent intent); } public interface Offer { diff --git a/src/main/java/xyz/nucleoid/plasmid/game/manager/ManagedGameSpace.java b/src/main/java/xyz/nucleoid/plasmid/game/manager/ManagedGameSpace.java index a5f2f105..f6abc17f 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/manager/ManagedGameSpace.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/manager/ManagedGameSpace.java @@ -19,8 +19,8 @@ import xyz.nucleoid.plasmid.game.config.GameConfig; import xyz.nucleoid.plasmid.game.event.GameActivityEvents; import xyz.nucleoid.plasmid.game.event.GamePlayerEvents; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import xyz.nucleoid.plasmid.game.player.LocalPlayerOffer; -import xyz.nucleoid.plasmid.game.player.PlayerOffer; import xyz.nucleoid.plasmid.game.player.PlayerOfferResult; import java.util.Collection; @@ -196,8 +196,8 @@ public GameBehavior getBehavior() { return this.state; } - GameResult screenJoins(Collection players) { - var result = this.attemptScreenJoins(players.stream().map(PlayerEntity::getGameProfile).toList()); + GameResult screenJoins(Collection players, JoinIntent intent) { + var result = this.attemptScreenJoins(players.stream().map(PlayerEntity::getGameProfile).toList(), intent); if (result.isError()) { this.players.attemptGarbageCollection(); @@ -206,12 +206,12 @@ GameResult screenJoins(Collection players) { return result; } - private GameResult attemptScreenJoins(Collection players) { + private GameResult attemptScreenJoins(Collection players, JoinIntent intent) { if (this.closed) { return GameResult.error(GameTexts.Join.gameClosed()); } - return this.state.invoker(GamePlayerEvents.SCREEN_JOINS).screenJoins(players); + return this.state.invoker(GamePlayerEvents.SCREEN_JOINS).screenJoins(players, intent); } PlayerOfferResult offerPlayer(LocalPlayerOffer offer) { diff --git a/src/main/java/xyz/nucleoid/plasmid/game/manager/ManagedGameSpacePlayers.java b/src/main/java/xyz/nucleoid/plasmid/game/manager/ManagedGameSpacePlayers.java index 7bc3ade9..593dcd36 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/manager/ManagedGameSpacePlayers.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/manager/ManagedGameSpacePlayers.java @@ -6,6 +6,7 @@ import xyz.nucleoid.plasmid.game.GameResult; import xyz.nucleoid.plasmid.game.GameSpacePlayers; import xyz.nucleoid.plasmid.game.GameTexts; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import xyz.nucleoid.plasmid.game.player.LocalPlayerOffer; import xyz.nucleoid.plasmid.game.player.MutablePlayerSet; import xyz.nucleoid.plasmid.game.player.PlayerOfferResult; @@ -27,13 +28,13 @@ public final class ManagedGameSpacePlayers implements GameSpacePlayers { } @Override - public GameResult screenJoins(Collection players) { - return this.space.screenJoins(players); + public GameResult screenJoins(Collection players, JoinIntent intent) { + return this.space.screenJoins(players, intent); } @Override - public GameResult offer(ServerPlayerEntity player) { - var result = this.attemptOffer(player); + public GameResult offer(ServerPlayerEntity player, JoinIntent intent) { + var result = this.attemptOffer(player, intent); if (result.isError()) { this.attemptGarbageCollection(); @@ -42,12 +43,12 @@ public GameResult offer(ServerPlayerEntity player) { return result; } - private GameResult attemptOffer(ServerPlayerEntity player) { + private GameResult attemptOffer(ServerPlayerEntity player, JoinIntent intent) { if (this.set.contains(player)) { return GameResult.error(GameTexts.Join.alreadyJoined()); } - var offer = new LocalPlayerOffer(player); + var offer = new LocalPlayerOffer(player, intent); switch (this.space.offerPlayer(offer)) { case LocalPlayerOffer.Accept accept -> { diff --git a/src/main/java/xyz/nucleoid/plasmid/game/player/GamePlayerJoiner.java b/src/main/java/xyz/nucleoid/plasmid/game/player/GamePlayerJoiner.java index 8085154a..cd76e5cf 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/player/GamePlayerJoiner.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/player/GamePlayerJoiner.java @@ -19,10 +19,10 @@ * members, screening, and offering players to the {@link GameSpace}. */ public final class GamePlayerJoiner { - public static Results tryJoin(ServerPlayerEntity player, GameSpace gameSpace) { + public static Results tryJoin(ServerPlayerEntity player, GameSpace gameSpace, JoinIntent intent) { try { var players = collectPlayersForJoin(player, gameSpace); - return tryJoinAll(players, gameSpace); + return tryJoinAll(players, gameSpace, intent); } catch (Throwable throwable) { return handleJoinException(throwable); } @@ -37,17 +37,17 @@ private static Set collectPlayersForJoin(ServerPlayerEntity return players; } - private static Results tryJoinAll(Collection players, GameSpace gameSpace) { + private static Results tryJoinAll(Collection players, GameSpace gameSpace, JoinIntent intent) { var results = new Results(); - var screenResult = gameSpace.getPlayers().screenJoins(players); + var screenResult = gameSpace.getPlayers().screenJoins(players, intent); if (screenResult.isError()) { results.globalError = screenResult.error(); return results; } for (var player : players) { - var result = gameSpace.getPlayers().offer(player); + var result = gameSpace.getPlayers().offer(player, intent); if (result.isError()) { results.playerErrors.put(player, result.error()); } diff --git a/src/main/java/xyz/nucleoid/plasmid/game/player/JoinIntent.java b/src/main/java/xyz/nucleoid/plasmid/game/player/JoinIntent.java new file mode 100644 index 00000000..adaade71 --- /dev/null +++ b/src/main/java/xyz/nucleoid/plasmid/game/player/JoinIntent.java @@ -0,0 +1,42 @@ +package xyz.nucleoid.plasmid.game.player; + +import xyz.nucleoid.plasmid.game.GameSpace; +import xyz.nucleoid.plasmid.game.event.GamePlayerEvents; + +/** + * Represents the "intention" of a player or group of players joining a {@link GameSpace}. + * 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#SCREEN_JOINS 'Screen Joins'} and + * {@link GamePlayerEvents#OFFER 'Player Offer'} events. + */ +public enum JoinIntent { + /** + * The player has no particular intention. Generally, this should be considered as a preference to participate. + */ + ANY, + /** + * 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, + /** + * The player intends to join the game to spectate. Unless the game does not support spectators, this player should + * generally always be accepted. + */ + SPECTATE, + ; + + /** + * @return {@code true} if the player may join as a participant under any circumstances + */ + public boolean canPlay() { + return this != SPECTATE; + } + + /** + * @return {@code true} if the player may join as a spectator under any circumstances + */ + public boolean canSpectate() { + return this != PLAY; + } +} diff --git a/src/main/java/xyz/nucleoid/plasmid/game/player/LocalPlayerOffer.java b/src/main/java/xyz/nucleoid/plasmid/game/player/LocalPlayerOffer.java index 059043e8..81e2cdbb 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/player/LocalPlayerOffer.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/player/LocalPlayerOffer.java @@ -11,7 +11,7 @@ import java.util.List; import java.util.function.Consumer; -public record LocalPlayerOffer(ServerPlayerEntity player) implements PlayerOffer { +public record LocalPlayerOffer(ServerPlayerEntity player, JoinIntent intent) implements PlayerOffer { @Override public GameProfile profile() { return this.player.getGameProfile(); diff --git a/src/main/java/xyz/nucleoid/plasmid/game/player/PlayerOffer.java b/src/main/java/xyz/nucleoid/plasmid/game/player/PlayerOffer.java index bd697897..1b82d964 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/player/PlayerOffer.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/player/PlayerOffer.java @@ -41,6 +41,12 @@ default String playerName() { return this.profile().getName(); } + /** + * @return the {@link JoinIntent 'intent'} of the player, such as whether they want to participate or spectate + * @see JoinIntent + */ + JoinIntent intent(); + /** * Returns an offer result that accepts this player offer and allows the player into this {@link GameSpace}. *

diff --git a/src/main/java/xyz/nucleoid/plasmid/game/portal/game/ConcurrentGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/game/portal/game/ConcurrentGamePortalBackend.java index 9ac7a93f..5afc7b7f 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/portal/game/ConcurrentGamePortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/portal/game/ConcurrentGamePortalBackend.java @@ -7,6 +7,7 @@ import xyz.nucleoid.plasmid.game.manager.GameSpaceManager; import xyz.nucleoid.plasmid.game.manager.ManagedGameSpace; import xyz.nucleoid.plasmid.game.player.GamePlayerJoiner; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import java.util.concurrent.CompletableFuture; import java.util.function.Function; @@ -28,7 +29,7 @@ public RegistryEntry> game() { public void applyTo(ServerPlayerEntity player) { for (var gameSpace : GameSpaceManager.get().getOpenGameSpaces()) { if (gameSpace.getMetadata().sourceConfig().equals(this.game)) { - var results = GamePlayerJoiner.tryJoin(player, gameSpace); + var results = GamePlayerJoiner.tryJoin(player, gameSpace, JoinIntent.ANY); if (results.globalError == null && results.playerErrors.get(player) == null) { return; @@ -42,7 +43,7 @@ public void applyTo(ServerPlayerEntity player) { this.gameFuture = null; GamePlayerJoiner.Results results; if (gameSpace != null) { - results = GamePlayerJoiner.tryJoin(player, gameSpace); + results = GamePlayerJoiner.tryJoin(player, gameSpace, JoinIntent.ANY); } else { results = GamePlayerJoiner.handleJoinException(throwable); } diff --git a/src/main/java/xyz/nucleoid/plasmid/game/portal/game/NewGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/game/portal/game/NewGamePortalBackend.java index 2abcac09..2d633c86 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/portal/game/NewGamePortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/portal/game/NewGamePortalBackend.java @@ -7,6 +7,7 @@ import xyz.nucleoid.plasmid.game.manager.GameSpaceManager; import xyz.nucleoid.plasmid.game.manager.ManagedGameSpace; import xyz.nucleoid.plasmid.game.player.GamePlayerJoiner; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import java.util.concurrent.CompletableFuture; import java.util.function.Function; @@ -19,7 +20,7 @@ public void applyTo(ServerPlayerEntity player) { .handleAsync((gameSpace, throwable) -> { GamePlayerJoiner.Results results; if (gameSpace != null) { - results = GamePlayerJoiner.tryJoin(player, gameSpace); + results = GamePlayerJoiner.tryJoin(player, gameSpace, JoinIntent.ANY); } else { results = GamePlayerJoiner.handleJoinException(throwable); } diff --git a/src/main/java/xyz/nucleoid/plasmid/game/portal/game/SingleGamePortalBackend.java b/src/main/java/xyz/nucleoid/plasmid/game/portal/game/SingleGamePortalBackend.java index bf7614b6..a16b1986 100644 --- a/src/main/java/xyz/nucleoid/plasmid/game/portal/game/SingleGamePortalBackend.java +++ b/src/main/java/xyz/nucleoid/plasmid/game/portal/game/SingleGamePortalBackend.java @@ -10,6 +10,7 @@ import xyz.nucleoid.plasmid.game.manager.GameSpaceManager; import xyz.nucleoid.plasmid.game.manager.ManagedGameSpace; import xyz.nucleoid.plasmid.game.player.GamePlayerJoiner; +import xyz.nucleoid.plasmid.game.player.JoinIntent; import java.util.concurrent.CompletableFuture; import java.util.function.Function; @@ -29,7 +30,7 @@ public void applyTo(ServerPlayerEntity player) { .handleAsync((gameSpace, throwable) -> { GamePlayerJoiner.Results results; if (gameSpace != null) { - results = GamePlayerJoiner.tryJoin(player, gameSpace); + results = GamePlayerJoiner.tryJoin(player, gameSpace, JoinIntent.ANY); } else { results = GamePlayerJoiner.handleJoinException(throwable); }