Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract game space & config lists #257

Open
wants to merge 11 commits into
base: 1.19.3
Choose a base branch
from
49 changes: 25 additions & 24 deletions src/main/java/xyz/nucleoid/plasmid/command/GameCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@
import xyz.nucleoid.plasmid.command.argument.GameConfigArgument;
import xyz.nucleoid.plasmid.command.argument.GameSpaceArgument;
import xyz.nucleoid.plasmid.command.ui.GameJoinUi;
import xyz.nucleoid.plasmid.game.GameCloseReason;
import xyz.nucleoid.plasmid.game.GameOpenException;
import xyz.nucleoid.plasmid.game.GameSpace;
import xyz.nucleoid.plasmid.game.GameTexts;
import xyz.nucleoid.plasmid.game.*;
import xyz.nucleoid.plasmid.game.config.GameConfig;
import xyz.nucleoid.plasmid.game.config.GameConfigs;
import xyz.nucleoid.plasmid.game.config.GameConfigList;
import xyz.nucleoid.plasmid.game.config.GameConfigLists;
import xyz.nucleoid.plasmid.game.config.ListedGameConfig;
import xyz.nucleoid.plasmid.game.manager.GameSpaceManager;
import xyz.nucleoid.plasmid.game.player.GamePlayerJoiner;
import xyz.nucleoid.plasmid.util.Scheduler;
Expand Down Expand Up @@ -153,7 +152,7 @@ protected static int openAnonymousGame(CommandContext<ServerCommandSource> conte
}
}

private static int openGame(CommandContext<ServerCommandSource> context, GameConfig<?> config, boolean test) {
private static int openGame(CommandContext<ServerCommandSource> context, ListedGameConfig config, boolean test) {
var source = context.getSource();
var server = source.getServer();

Expand All @@ -167,12 +166,12 @@ private static int openGame(CommandContext<ServerCommandSource> context, GameCon
if (test) {
currentGameSpace.close(GameCloseReason.CANCELED);
} else {
currentGameSpace.getPlayers().kick(player);
currentGameSpace.kick(player);
}
}
}

GameSpaceManager.get().open(config)
config.open(server)
.handleAsync((gameSpace, throwable) -> {
if (throwable == null) {
onOpenSuccess(source, gameSpace, player, test);
Expand All @@ -186,16 +185,17 @@ private static int openGame(CommandContext<ServerCommandSource> context, GameCon
return Command.SINGLE_SUCCESS;
}

private static void onOpenSuccess(ServerCommandSource source, GameSpace gameSpace, ServerPlayerEntity player, boolean test) {
private static void onOpenSuccess(ServerCommandSource source, ListedGameSpace gameSpace, ServerPlayerEntity player, boolean test) {
var players = source.getServer().getPlayerManager();

var message = test ? GameTexts.Broadcast.gameOpenedTesting(source, gameSpace) : GameTexts.Broadcast.gameOpened(source, gameSpace);
players.broadcast(message, false);

if (test) {
// TODO: Handle more explicitly - only allow test command to run on local games
if (test && gameSpace instanceof GameSpace localGameSpace) {
joinAllPlayersToGame(source, gameSpace);

var startResult = gameSpace.requestStart();
var startResult = localGameSpace.requestStart();

if (!startResult.isOk()) {
var error = startResult.errorCopy().formatted(Formatting.RED);
Expand Down Expand Up @@ -238,7 +238,7 @@ private static int proposeCurrentGame(CommandContext<ServerCommandSource> contex
return proposeGame(source, gameSpace);
}

private static int proposeGame(ServerCommandSource source, GameSpace gameSpace) {
private static int proposeGame(ServerCommandSource source, ListedGameSpace gameSpace) {
var message = GameTexts.Broadcast.propose(source, gameSpace);

var playerManager = source.getServer().getPlayerManager();
Expand All @@ -260,7 +260,7 @@ private static int joinQualifiedGame(CommandContext<ServerCommandSource> context
}

private static int joinAllGame(CommandContext<ServerCommandSource> context) throws CommandSyntaxException {
GameSpace gameSpace = null;
ListedGameSpace gameSpace = null;

var entity = context.getSource().getEntity();
if (entity instanceof ServerPlayerEntity) {
Expand All @@ -283,32 +283,32 @@ private static int joinAllQualifiedGame(CommandContext<ServerCommandSource> cont
return Command.SINGLE_SUCCESS;
}

private static void joinAllPlayersToGame(ServerCommandSource source, GameSpace gameSpace) {
private static void joinAllPlayersToGame(ServerCommandSource source, ListedGameSpace gameSpace) {
var playerManager = source.getServer().getPlayerManager();

var players = playerManager.getPlayerList().stream()
.filter(player -> !GameSpaceManager.get().inGame(player))
.collect(Collectors.toList());

var screen = gameSpace.getPlayers().screenJoins(players);
var screen = gameSpace.screenJoins(players);
if (screen.isOk()) {
for (var player : players) {
gameSpace.getPlayers().offer(player);
gameSpace.offer(player);
}
} else {
source.sendError(screen.errorCopy().formatted(Formatting.RED));
}
}

private static void tryJoinGame(ServerPlayerEntity player, GameSpace gameSpace) {
private static void tryJoinGame(ServerPlayerEntity player, ListedGameSpace gameSpace) {
player.server.submit(() -> {
var results = GamePlayerJoiner.tryJoin(player, gameSpace);
results.sendErrorsTo(player);
});
}

private static GameSpace getJoinableGameSpace() throws CommandSyntaxException {
return GameSpaceManager.get().getOpenGameSpaces().stream()
private static ListedGameSpace getJoinableGameSpace() throws CommandSyntaxException {
return GameSpaceLists.composite().getOpenGameSpaces().stream()
.max(Comparator.comparingInt(space -> space.getPlayers().size()))
.orElseThrow(NO_GAME_OPEN::create);
}
Expand Down Expand Up @@ -337,7 +337,7 @@ private static int leaveGame(CommandContext<ServerCommandSource> context) throws
}

Scheduler.INSTANCE.submit(server -> {
gameSpace.getPlayers().kick(player);
gameSpace.kick(player);
});

return Command.SINGLE_SUCCESS;
Expand Down Expand Up @@ -417,14 +417,15 @@ private static int listGames(CommandContext<ServerCommandSource> context) {
var source = context.getSource();
source.sendFeedback(GameTexts.Command.gameList().formatted(Formatting.BOLD), false);

for (var id : GameConfigs.getKeys()) {
GameConfigList list = GameConfigLists.composite();
list.keys().forEach(id -> {
String command = "/game open " + id;

var link = GameConfigs.get(id).name().copy()
var link = list.byKey(id).name().copy()
.setStyle(GameTexts.commandLinkStyle(command));

source.sendFeedback(GameTexts.Command.listEntry(link), false);
}
});

return Command.SINGLE_SUCCESS;
}
Expand All @@ -444,7 +445,7 @@ private static int kickPlayers(CommandContext<ServerCommandSource> context) thro
playerManager.broadcast(message, false);

Scheduler.INSTANCE.submit(server -> {
gameSpace.getPlayers().kick(target);
gameSpace.kick(target);
});

successes += 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import xyz.nucleoid.plasmid.game.config.GameConfig;
import xyz.nucleoid.plasmid.game.config.GameConfigs;
import xyz.nucleoid.plasmid.game.config.GameConfigList;
import xyz.nucleoid.plasmid.game.config.GameConfigLists;
import xyz.nucleoid.plasmid.game.config.ListedGameConfig;

import java.util.Locale;
import java.util.function.Function;
Expand All @@ -25,20 +26,22 @@ public final class GameConfigArgument {
public static RequiredArgumentBuilder<ServerCommandSource, Identifier> argument(String name) {
return CommandManager.argument(name, IdentifierArgumentType.identifier())
.suggests((ctx, builder) -> {
Iterable<Identifier> candidates = GameConfigs.getKeys().stream()::iterator;
GameConfigList list = GameConfigLists.composite();
Iterable<Identifier> candidates = list.keys()::iterator;
var remaining = builder.getRemaining().toLowerCase(Locale.ROOT);

CommandSource.forEachMatching(candidates, remaining, Function.identity(), id -> {
builder.suggest(id.toString(), GameConfigs.get(id).name());
var config = list.byKey(id);
builder.suggest(id.toString(), config.name());
});
return builder.buildFuture();
});
}

public static Pair<Identifier, GameConfig<?>> get(CommandContext<ServerCommandSource> context, String name) throws CommandSyntaxException {
public static Pair<Identifier, ListedGameConfig> get(CommandContext<ServerCommandSource> context, String name) throws CommandSyntaxException {
var identifier = IdentifierArgumentType.getIdentifier(context, name);

var config = GameConfigs.get(identifier);
var config = GameConfigLists.composite().byKey(identifier);
if (config == null) {
throw GAME_NOT_FOUND.create(identifier);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,28 @@
import net.minecraft.server.command.ServerCommandSource;
import net.minecraft.text.Text;
import net.minecraft.util.Identifier;
import xyz.nucleoid.plasmid.game.GameSpace;
import xyz.nucleoid.plasmid.game.manager.GameSpaceManager;
import xyz.nucleoid.plasmid.game.GameSpaceLists;
import xyz.nucleoid.plasmid.game.ListedGameSpace;

public final class GameSpaceArgument {
private static final SimpleCommandExceptionType GAME_NOT_FOUND = new SimpleCommandExceptionType(Text.translatable("text.plasmid.game.not_found"));

public static RequiredArgumentBuilder<ServerCommandSource, Identifier> argument(String name) {
return CommandManager.argument(name, IdentifierArgumentType.identifier())
.suggests((context, builder) -> {
var gameSpaceManager = GameSpaceManager.get();
var gameSpaceList = GameSpaceLists.composite();

return CommandSource.suggestIdentifiers(
gameSpaceManager.getOpenGameSpaces().stream().map(space -> space.getMetadata().userId()),
gameSpaceList.getOpenGameSpaces().stream().map(space -> space.getMetadata().userId()),
builder
);
});
}

public static GameSpace get(CommandContext<ServerCommandSource> context, String name) throws CommandSyntaxException {
public static ListedGameSpace get(CommandContext<ServerCommandSource> context, String name) throws CommandSyntaxException {
var identifier = IdentifierArgumentType.getIdentifier(context, name);

var gameSpace = GameSpaceManager.get().byUserId(identifier);
var gameSpace = GameSpaceLists.composite().byUserId(identifier);
if (gameSpace == null) {
throw GAME_NOT_FOUND.create();
}
Expand Down
13 changes: 6 additions & 7 deletions src/main/java/xyz/nucleoid/plasmid/command/ui/GameJoinUi.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,8 @@
import net.minecraft.text.Text;
import net.minecraft.util.Formatting;
import net.minecraft.util.math.MathHelper;
import xyz.nucleoid.plasmid.game.GameSpace;
import xyz.nucleoid.plasmid.game.manager.GameSpaceManager;
import xyz.nucleoid.plasmid.game.manager.ManagedGameSpace;
import xyz.nucleoid.plasmid.game.GameSpaceLists;
import xyz.nucleoid.plasmid.game.ListedGameSpace;
import xyz.nucleoid.plasmid.game.player.GamePlayerJoiner;
import xyz.nucleoid.plasmid.util.Guis;

Expand All @@ -33,7 +32,7 @@ public GameJoinUi(ServerPlayerEntity player) {
this.updateUi();
}

private static void tryJoinGame(ServerPlayerEntity player, GameSpace gameSpace) {
private static void tryJoinGame(ServerPlayerEntity player, ListedGameSpace gameSpace) {
player.server.submit(() -> {
var results = GamePlayerJoiner.tryJoin(player, gameSpace);
results.sendErrorsTo(player);
Expand All @@ -53,7 +52,7 @@ private void updateUi() {
int i = 0;
int gameI = 0;

var games = new ArrayList<>(GameSpaceManager.get().getOpenGameSpaces());
var games = new ArrayList<>(GameSpaceLists.composite().getOpenGameSpaces());
games.sort(Comparator.comparingInt(space -> -space.getPlayers().size()));

int limit = this.size;
Expand All @@ -66,7 +65,7 @@ private void updateUi() {

this.page = MathHelper.clamp(this.page, 0, this.pageSize);

for (ManagedGameSpace gameSpace : games) {
for (ListedGameSpace gameSpace : games) {
if (gameI >= this.page * NAVBAR_POS) {
if (i < limit) {
this.setSlot(i++, this.createIconFor(gameSpace));
Expand Down Expand Up @@ -111,7 +110,7 @@ private void changePage(int change) {
this.updateUi();
}

private GuiElementBuilder createIconFor(GameSpace gameSpace) {
private GuiElementBuilder createIconFor(ListedGameSpace gameSpace) {
var sourceConfig = gameSpace.getMetadata().sourceConfig();
var element = GuiElementBuilder.from(sourceConfig.icon().copy())
.setName(sourceConfig.name().copy());
Expand Down
21 changes: 3 additions & 18 deletions src/main/java/xyz/nucleoid/plasmid/game/GameSpace.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
package xyz.nucleoid.plasmid.game;

import net.minecraft.server.MinecraftServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import xyz.nucleoid.fantasy.RuntimeWorldConfig;
import xyz.nucleoid.plasmid.game.event.GameActivityEvents;
import xyz.nucleoid.plasmid.game.event.GamePlayerEvents;
import xyz.nucleoid.plasmid.game.player.PlayerSet;
import xyz.nucleoid.plasmid.game.resource_packs.ResourcePackStates;
import xyz.nucleoid.plasmid.game.world.GameSpaceWorlds;

Expand All @@ -23,15 +21,13 @@
* @see GameType
* @see GameActivity
*/
public interface GameSpace {
public interface GameSpace extends ListedGameSpace {
/**
* @return the host server of this {@link GameSpace}
*/
MinecraftServer getServer();

/**
* @return all metadata associated with this {@link GameSpace}
*/
@Override
GameSpaceMetadata getMetadata();

/**
Expand Down Expand Up @@ -72,13 +68,7 @@ public interface GameSpace {
*/
void close(GameCloseReason reason);

/**
* Returns all {@link ServerPlayerEntity}s in this {@link GameSpace}.
*
* <p>{@link GameSpacePlayers#contains(ServerPlayerEntity)} can be used to check if a {@link ServerPlayerEntity} is in this {@link GameSpace} instead.
*
* @return a {@link PlayerSet} that contains all {@link ServerPlayerEntity}s in this {@link GameSpace}
*/
@Override
GameSpacePlayers getPlayers();

/**
Expand All @@ -105,10 +95,5 @@ public interface GameSpace {
*/
GameSpaceStatistics getStatistics();

/**
* @return true if this GameSpace is closed, false otherwise
*/
boolean isClosed();

ResourcePackStates getResourcePackStates();
}
37 changes: 37 additions & 0 deletions src/main/java/xyz/nucleoid/plasmid/game/GameSpaceList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package xyz.nucleoid.plasmid.game;

import net.minecraft.util.Identifier;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.List;
import java.util.UUID;

public interface GameSpaceList {
GameSpaceList EMPTY = new GameSpaceList() {
@Override
public Collection<? extends ListedGameSpace> getOpenGameSpaces() {
return List.of();
}

@Override
@Nullable
public ListedGameSpace byId(UUID id) {
return null;
}

@Override
@Nullable
public ListedGameSpace byUserId(Identifier userId) {
return null;
}
};

Collection<? extends ListedGameSpace> getOpenGameSpaces();

@Nullable
ListedGameSpace byId(UUID id);

@Nullable
ListedGameSpace byUserId(Identifier userId);
}
Loading