Skip to content

Commit

Permalink
Remove screen joins event and reimplement with offer
Browse files Browse the repository at this point in the history
  • Loading branch information
pufmat committed Jul 16, 2024
1 parent a4309eb commit 8c02c3f
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 79 deletions.
8 changes: 3 additions & 5 deletions src/main/java/xyz/nucleoid/plasmid/command/GameCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,9 @@ private static void joinAllPlayersToGame(ServerCommandSource source, GameSpace g
.collect(Collectors.toList());

var intent = JoinIntent.ANY;
var screen = gameSpace.getPlayers().screenJoins(players, intent);
if (screen.isOk()) {
gameSpace.getPlayers().offer(players, intent);
} else {
source.sendError(screen.errorCopy().formatted(Formatting.RED));
var result = gameSpace.getPlayers().offer(players, intent);
if (result.isError()) {
source.sendError(result.errorCopy().formatted(Formatting.RED));
}
}

Expand Down
9 changes: 4 additions & 5 deletions src/main/java/xyz/nucleoid/plasmid/game/GameSpacePlayers.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,17 @@
*/
public interface GameSpacePlayers extends PlayerSet {
/**
* Screens a player or group of players and returns whether the collective group should be allowed into the game.
* Simulates offer to join a player or group of players and returns whether they should be allowed into the game.
* <p>
* This logic is controlled through the active {@link GameActivity} through {@link GamePlayerEvents#SCREEN_JOINS}.
* This logic is controlled through the active {@link GameActivity} through {@link GamePlayerEvents#OFFER}.
*
* @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 these players can join this game, or an error if not
* @see GamePlayerEvents#SCREEN_JOINS
* @see GameSpacePlayers#offer(Collection, JoinIntent)
* @see GameSpacePlayers#offer(Collection, JoinIntent)
* @see xyz.nucleoid.plasmid.game.player.GamePlayerJoiner
*/
GameResult screenJoins(Collection<ServerPlayerEntity> players, JoinIntent intent);
GameResult simulateOffer(Collection<ServerPlayerEntity> players, JoinIntent intent);

/**
* Offers a player or group of players to join this game. If accepted, they will be teleported into the game, and if not
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ 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, (players, intent) -> lobby.screenJoins(players));
activity.listen(GamePlayerEvents.OFFER, lobby::offerPlayer);
activity.listen(GamePlayerEvents.REMOVE, lobby::onRemovePlayer);

Expand Down Expand Up @@ -170,17 +169,9 @@ private GameResult requestStart() {
}
}

private GameResult screenJoins(Collection<GameProfile> players) {
int newPlayerCount = this.gameSpace.getPlayers().size() + players.size();
if (newPlayerCount > this.playerConfig.maxPlayers()) {
return GameResult.error(GameTexts.Join.gameFull());
}

return GameResult.ok();
}

private JoinOfferResult offerPlayer(JoinOffer offer) {
if (this.isFull()) {
int newPlayerCount = this.gameSpace.getPlayers().size() + offer.players().size();
if (newPlayerCount > this.playerConfig.maxPlayers()) {
return offer.reject(GameTexts.Join.gameFull());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,39 +101,15 @@ public final class GamePlayerEvents {
}
});

/**
* Called when a group of players try to join this game. This should be used to reject multiple players as a group,
* such as when a party tries to join but has too many players to fit into the game.
* <p>
* This is called before {@link GamePlayerEvents#OFFER} which handles specifically bringing a player into the game.
*
* @see GamePlayerEvents#OFFER
*/
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, intent);
if (result.isError()) {
return result;
}
}
return GameResult.ok();
} catch (Throwable throwable) {
ctx.handleException(throwable);
return GameResult.error(GameTexts.Join.unexpectedError());
}
});

/**
* Called when a single {@link ServerPlayerEntity} tries to join this game. This event is responsible for bringing
* the player into the {@link GameSpace} world in the correct location.
* <p>
* Games must respond to this event in order for a player to be able to join by returning either
* {@link JoinOffer#accept(ServerWorld, Vec3d)} or {@link JoinOffer#reject(Text)}.
* {@link JoinOffer#accept(ServerWorld)} or {@link JoinOffer#reject(Text)}.
*
* @see JoinOffer
* @see JoinOfferResult
* @see GamePlayerEvents#SCREEN_JOINS
* @see GamePlayerEvents#JOIN
*/
public static final StimulusEvent<Offer> OFFER = StimulusEvent.create(Offer.class, ctx -> offer -> {
Expand Down Expand Up @@ -175,10 +151,6 @@ public interface Remove {
void onRemovePlayer(ServerPlayerEntity player);
}

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

public interface Offer {
JoinOfferResult onOfferPlayer(JoinOffer offer);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,24 +196,6 @@ public GameBehavior getBehavior() {
return this.state;
}

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

if (result.isError()) {
this.players.attemptGarbageCollection();
}

return result;
}

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

JoinOfferResult offerPlayer(LocalJoinOffer offer) {
if (this.closed) {
return offer.reject(GameTexts.Join.gameClosed());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,18 @@ public final class ManagedGameSpacePlayers implements GameSpacePlayers {
}

@Override
public GameResult screenJoins(Collection<ServerPlayerEntity> players, JoinIntent intent) {
return this.space.screenJoins(players, intent);
public GameResult simulateOffer(Collection<ServerPlayerEntity> players, JoinIntent intent) {
if (players.stream().anyMatch(this.set::contains)) {
return GameResult.error(GameTexts.Join.alreadyJoined());
}

var offer = new LocalJoinOffer(players, intent);

return switch (this.space.offerPlayer(offer)) {
case JoinOfferResult.Accept accept -> GameResult.ok();
case JoinOfferResult.Reject reject -> GameResult.error(reject.reason());
default -> GameResult.error(GameTexts.Join.genericError());
};
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

/**
* Utility class for joining players to a {@link GameSpace}. This handles all logic such as collecting all party
* members, screening, and offering players to the {@link GameSpace}.
* members, and offering players to the {@link GameSpace}.
*/
public final class GamePlayerJoiner {
public static Results tryJoin(ServerPlayerEntity player, GameSpace gameSpace, JoinIntent intent) {
Expand All @@ -40,12 +40,6 @@ private static Set<ServerPlayerEntity> collectPlayersForJoin(ServerPlayerEntity
private static Results tryJoinAll(Collection<ServerPlayerEntity> players, GameSpace gameSpace, JoinIntent intent) {
var results = new Results();

var screenResult = gameSpace.getPlayers().screenJoins(players, intent);
if (screenResult.isError()) {
results.globalError = screenResult.error();
return results;
}

var result = gameSpace.getPlayers().offer(players, intent);
if (result.isError()) {
for (var player : players) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
/**
* 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 'Join Offer'} events.
* accomplished by handling the {@link GamePlayerEvents#OFFER 'Join Offer'} events.
*/
public enum JoinIntent {
/**
Expand Down

0 comments on commit 8c02c3f

Please sign in to comment.