-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add a very simple gamemode command
- Loading branch information
1 parent
275c4e7
commit bc86277
Showing
13 changed files
with
402 additions
and
7 deletions.
There are no files selected for viewing
64 changes: 64 additions & 0 deletions
64
...ensink-common/src/main/java/org/incendo/kitchensink/command/commands/GameModeCommand.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2024 Incendo | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// | ||
package org.incendo.kitchensink.command.commands; | ||
|
||
import jakarta.inject.Singleton; | ||
import net.kyori.adventure.text.format.NamedTextColor; | ||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
import org.incendo.cloud.Command; | ||
import org.incendo.cloud.bean.CommandProperties; | ||
import org.incendo.kitchensink.command.KitchenSinkCommandBean; | ||
import org.incendo.kitchensink.command.KitchenSinkCommandSender; | ||
import org.incendo.kitchensink.entity.player.GameMode; | ||
import org.incendo.kitchensink.entity.player.KitchenSinkPlayer; | ||
|
||
import static net.kyori.adventure.text.Component.text; | ||
import static org.incendo.kitchensink.command.parser.GameModeParser.gameModeParser; | ||
|
||
@Singleton | ||
public final class GameModeCommand extends KitchenSinkCommandBean { | ||
|
||
@Override | ||
protected @NonNull CommandProperties properties() { | ||
return CommandProperties.of("gamemode", "gm"); | ||
} | ||
|
||
@Override | ||
protected Command.@NonNull Builder<? extends KitchenSinkCommandSender> configureKitchenSinkCommand( | ||
final Command.@NonNull Builder<KitchenSinkCommandSender> builder | ||
) { | ||
// TODO(City): Make the command take in an optional player argument that defaults | ||
// to the executing player (if the sender is a player). | ||
return builder.required("gameMode", gameModeParser()) | ||
.senderType(KitchenSinkPlayer.class) | ||
.handler((FutureCommandExecutionHandler<KitchenSinkPlayer>) context -> { | ||
final GameMode gameMode = context.get("gameMode"); | ||
return context.sender().gameMode(gameMode).whenComplete(($, error) -> { | ||
context.sender() | ||
.sendMessage(text("Your game mode has been set to ", NamedTextColor.GRAY) | ||
.append(text(gameMode.key(), NamedTextColor.GOLD))); | ||
}); | ||
}); | ||
} | ||
} |
141 changes: 141 additions & 0 deletions
141
kitchensink-common/src/main/java/org/incendo/kitchensink/command/parser/GameModeParser.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2024 Incendo | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// | ||
package org.incendo.kitchensink.command.parser; | ||
|
||
import java.util.Objects; | ||
import java.util.stream.Collectors; | ||
import org.apiguardian.api.API; | ||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
import org.incendo.cloud.caption.CaptionVariable; | ||
import org.incendo.cloud.caption.StandardCaptionKeys; | ||
import org.incendo.cloud.context.CommandContext; | ||
import org.incendo.cloud.context.CommandInput; | ||
import org.incendo.cloud.exception.parsing.ParserException; | ||
import org.incendo.cloud.parser.ArgumentParseResult; | ||
import org.incendo.cloud.parser.ArgumentParser; | ||
import org.incendo.cloud.parser.ParserDescriptor; | ||
import org.incendo.cloud.suggestion.BlockingSuggestionProvider; | ||
import org.incendo.cloud.suggestion.Suggestion; | ||
import org.incendo.cloud.type.range.Range; | ||
import org.incendo.kitchensink.command.KitchenSinkCommandSender; | ||
import org.incendo.kitchensink.entity.player.GameMode; | ||
|
||
public final class GameModeParser implements ArgumentParser<KitchenSinkCommandSender, GameMode>, | ||
BlockingSuggestionProvider<KitchenSinkCommandSender> { | ||
|
||
/** | ||
* Creates a new game mode parser. | ||
* | ||
* @return the parser | ||
*/ | ||
public static ParserDescriptor<KitchenSinkCommandSender, GameMode> gameModeParser() { | ||
return ParserDescriptor.of(new GameModeParser(), GameMode.class); | ||
} | ||
|
||
@Override | ||
public @NonNull ArgumentParseResult<@NonNull GameMode> parse( | ||
final @NonNull CommandContext<@NonNull KitchenSinkCommandSender> commandContext, | ||
final @NonNull CommandInput commandInput | ||
) { | ||
if (commandInput.isValidInteger(Range.intRange(0, 3))) { | ||
return ArgumentParseResult.success(GameMode.fromId(commandInput.readInteger())); | ||
} | ||
|
||
final String input = commandInput.readString(); | ||
try { | ||
return ArgumentParseResult.success(GameMode.fromKey(input)); | ||
} catch (final IllegalArgumentException ignored) { | ||
return ArgumentParseResult.failure(new GameModeParseException(input, commandContext)); | ||
} | ||
} | ||
|
||
@Override | ||
public @NonNull Iterable<@NonNull Suggestion> suggestions( | ||
final @NonNull CommandContext<KitchenSinkCommandSender> context, | ||
final @NonNull CommandInput input | ||
) { | ||
return GameMode.gameModes() | ||
.stream() | ||
.map(GameMode::key) | ||
.map(Suggestion::simple) | ||
.toList(); | ||
} | ||
|
||
|
||
@API(status = API.Status.STABLE) | ||
public static final class GameModeParseException extends ParserException { | ||
|
||
private final String input; | ||
|
||
/** | ||
* Construct a new game mode parse exception. | ||
* | ||
* @param input input | ||
* @param context command context | ||
*/ | ||
public GameModeParseException( | ||
final @NonNull String input, | ||
final @NonNull CommandContext<?> context | ||
) { | ||
super( | ||
GameModeParser.class, | ||
context, | ||
StandardCaptionKeys.ARGUMENT_PARSE_FAILURE_ENUM, | ||
CaptionVariable.of("input", input), | ||
CaptionVariable.of("acceptableValues", GameMode.gameModes() | ||
.stream() | ||
.map(GameMode::key) | ||
.collect(Collectors.joining(", ")) | ||
) | ||
); | ||
this.input = input; | ||
} | ||
|
||
/** | ||
* Returns the input provided by the sender. | ||
* | ||
* @return input | ||
*/ | ||
public @NonNull String input() { | ||
return this.input; | ||
} | ||
|
||
@Override | ||
public boolean equals(final Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || this.getClass() != o.getClass()) { | ||
return false; | ||
} | ||
final GameModeParseException that = (GameModeParseException) o; | ||
return this.input.equals(that.input); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(this.input); | ||
} | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
kitchensink-common/src/main/java/org/incendo/kitchensink/command/parser/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/** | ||
* Custom parsers. | ||
*/ | ||
package org.incendo.kitchensink.command.parser; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
kitchensink-common/src/main/java/org/incendo/kitchensink/entity/player/GameMode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// | ||
// MIT License | ||
// | ||
// Copyright (c) 2024 Incendo | ||
// | ||
// Permission is hereby granted, free of charge, to any person obtaining a copy | ||
// of this software and associated documentation files (the "Software"), to deal | ||
// in the Software without restriction, including without limitation the rights | ||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
// copies of the Software, and to permit persons to whom the Software is | ||
// furnished to do so, subject to the following conditions: | ||
// | ||
// The above copyright notice and this permission notice shall be included in all | ||
// copies or substantial portions of the Software. | ||
// | ||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
// SOFTWARE. | ||
// | ||
package org.incendo.kitchensink.entity.player; | ||
|
||
import java.util.Collection; | ||
import java.util.List; | ||
import java.util.Locale; | ||
import java.util.Objects; | ||
import org.checkerframework.checker.nullness.qual.NonNull; | ||
|
||
public final class GameMode { | ||
|
||
public static final GameMode SURVIVAL = new GameMode("survival", 0); | ||
public static final GameMode CREATIVE = new GameMode("creative", 1); | ||
public static final GameMode ADVENTURE = new GameMode("adventure", 2); | ||
public static final GameMode SPECTATOR = new GameMode("spectator", 3); | ||
|
||
// Has to come after because of the forward referencing that would otherwise occur. | ||
private static final List<@NonNull GameMode> GAME_MODES = List.of(SURVIVAL, CREATIVE, ADVENTURE, SPECTATOR); | ||
|
||
/** | ||
* Returns the game mode that corresponds to the given {@code key}. | ||
* | ||
* @param key game mode key | ||
* @return the game mode | ||
* @throws IllegalArgumentException if the game mode does not exist | ||
*/ | ||
public static @NonNull GameMode fromKey(final @NonNull String key) { | ||
return switch (key.toLowerCase(Locale.ENGLISH)) { | ||
case "survival" -> GameMode.SURVIVAL; | ||
case "creative" -> GameMode.CREATIVE; | ||
case "adventure" -> GameMode.ADVENTURE; | ||
case "spectator" -> GameMode.SPECTATOR; | ||
default -> throw new IllegalArgumentException("Unknown game mode: " + key); | ||
}; | ||
} | ||
|
||
/** | ||
* Returns the game mode that corresponds to the given {@code id}. | ||
* | ||
* @param id game mode id | ||
* @return the game mode | ||
* @throws IllegalArgumentException if the game mode does not exist | ||
*/ | ||
public static @NonNull GameMode fromId(final int id) { | ||
return switch (id) { | ||
case 0 -> GameMode.SURVIVAL; | ||
case 1 -> GameMode.CREATIVE; | ||
case 2 -> GameMode.ADVENTURE; | ||
case 3 -> GameMode.SPECTATOR; | ||
default -> throw new IllegalArgumentException("Unknown game mode: " + id); | ||
}; | ||
} | ||
|
||
/** | ||
* Returns the available game modes. | ||
* | ||
* @return the game modes | ||
*/ | ||
public static @NonNull Collection<@NonNull GameMode> gameModes() { | ||
return List.copyOf(GAME_MODES); | ||
} | ||
|
||
private final String key; | ||
private final int id; | ||
|
||
private GameMode( | ||
final @NonNull String key, | ||
final int id | ||
) { | ||
this.key = Objects.requireNonNull(key, "key"); | ||
this.id = id; | ||
} | ||
|
||
/** | ||
* Returns the game mode key. | ||
* | ||
* @return the key | ||
*/ | ||
public @NonNull String key() { | ||
return this.key; | ||
} | ||
|
||
/** | ||
* Returns the numerical id that represents this game mode. | ||
* | ||
* @return the id | ||
*/ | ||
public int id() { | ||
return this.id; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 4 additions & 0 deletions
4
kitchensink-common/src/main/java/org/incendo/kitchensink/entity/player/package-info.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
/** | ||
* Classes related to players. | ||
*/ | ||
package org.incendo.kitchensink.entity.player; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.