Skip to content

Commit

Permalink
Add JoinIntent parameter to offer and screen joins events, currently …
Browse files Browse the repository at this point in the history
…unused
  • Loading branch information
Gegy committed Jul 15, 2024
1 parent c13e2a4 commit 8ee6f3b
Show file tree
Hide file tree
Showing 14 changed files with 91 additions and 33 deletions.
9 changes: 5 additions & 4 deletions src/main/java/xyz/nucleoid/plasmid/command/GameCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -286,18 +286,19 @@ 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));
}
}

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);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
});
}
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/xyz/nucleoid/plasmid/game/GameSpacePlayers.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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<ServerPlayerEntity> players);
GameResult screenJoins(Collection<ServerPlayerEntity> players, JoinIntent intent);

/**
* Offers an individual player to join this game. If accepted, they will be teleported into the game, and if not
Expand All @@ -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}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -108,10 +109,10 @@ public final class GamePlayerEvents {
*
* @see GamePlayerEvents#OFFER
*/
public static final StimulusEvent<ScreenJoins> SCREEN_JOINS = StimulusEvent.create(ScreenJoins.class, ctx -> players -> {
public static final StimulusEvent<ScreenJoins> 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;
}
Expand Down Expand Up @@ -175,7 +176,7 @@ public interface Remove {
}

public interface ScreenJoins {
GameResult screenJoins(Collection<GameProfile> players);
GameResult screenJoins(Collection<GameProfile> players, JoinIntent intent);
}

public interface Offer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -196,8 +196,8 @@ public GameBehavior getBehavior() {
return this.state;
}

GameResult screenJoins(Collection<ServerPlayerEntity> players) {
var result = this.attemptScreenJoins(players.stream().map(PlayerEntity::getGameProfile).toList());
GameResult screenJoins(Collection<ServerPlayerEntity> players, JoinIntent intent) {
var result = this.attemptScreenJoins(players.stream().map(PlayerEntity::getGameProfile).toList(), intent);

if (result.isError()) {
this.players.attemptGarbageCollection();
Expand All @@ -206,12 +206,12 @@ GameResult screenJoins(Collection<ServerPlayerEntity> players) {
return result;
}

private GameResult attemptScreenJoins(Collection<GameProfile> players) {
private GameResult attemptScreenJoins(Collection<GameProfile> 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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -27,13 +28,13 @@ public final class ManagedGameSpacePlayers implements GameSpacePlayers {
}

@Override
public GameResult screenJoins(Collection<ServerPlayerEntity> players) {
return this.space.screenJoins(players);
public GameResult screenJoins(Collection<ServerPlayerEntity> 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();
Expand All @@ -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 -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -37,17 +37,17 @@ private static Set<ServerPlayerEntity> collectPlayersForJoin(ServerPlayerEntity
return players;
}

private static Results tryJoinAll(Collection<ServerPlayerEntity> players, GameSpace gameSpace) {
private static Results tryJoinAll(Collection<ServerPlayerEntity> 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());
}
Expand Down
42 changes: 42 additions & 0 deletions src/main/java/xyz/nucleoid/plasmid/game/player/JoinIntent.java
Original file line number Diff line number Diff line change
@@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -28,7 +29,7 @@ public RegistryEntry<GameConfig<?>> 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;
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down

0 comments on commit 8ee6f3b

Please sign in to comment.