Skip to main content

GameMode Command

This is a simple example of how you could create a gamemode command in minecraft (using bukkit), along with its shortcuts (e.g: /gms, /gmc). Before creating our command class, let's create a preprocess to make sure our gamemode command can be run by players only !

public final class OnlyPlayerProcessor implements CommandPreProcessor<BukkitSource> {
@Override
public void process(Imperat<BukkitSource> imperat, Context<BukkitSource> context, CommandUsage<BukkitSource> usage) throws ImperatException {
if(context.source().isConsole()) {
throw new SourceException("Only players are allowed to use this command !");
}
}
}

Now let's write our command class:


@Command({"gamemode", "gm"})
@Permission("lobby.gamemode")
@PreProcessor(OnlyPlayerProcessor.class)
public class GameModeCommand {

@Usage
public void defUsage(
BukkitSource source,
@NotNull @Named("gamemode") GameMode gameMode,
@Optional @Nullable @Named("player") Player other
) {
// /gamemode <gamemode> [player]
Player target = other == null ? source.asPlayer() : other;
target.setGameMode(gameMode);

LobbyCore.sendPrefixed(target, "&bYour gamemode has been set to &f&l" + capitalize(gameMode.name()));
if(other != null) {
LobbyCore.sendPrefixed(source.asPlayer(), "&7You have set &2" + other.getName() + "&7's gamemode to &2" + capitalize(gameMode.name()));
}
}

@Command("gmc")
public void gmc(BukkitSource source, @Optional @Named("player") Player target) {
defUsage(source, GameMode.CREATIVE, target);
}

@Command("gms")
public void gms(BukkitSource source, @Optional @Named("player") Player target) {
defUsage(source, GameMode.SURVIVAL, target);
}

@Command("gma")
public void gma(BukkitSource source, @Optional @Named("player") Player target) {
defUsage(source, GameMode.ADVENTURE, target);
}

@Command("gmsp")
public void gmsp(BukkitSource source, @Optional @Named("player") Player target) {
defUsage(source, GameMode.SPECTATOR, target);
}

private static String capitalize(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}

}

The above command class should work flawlessly. However, the command will only accept gamemode exact names, the players will not be able to enter the gamemode's id, (e.g: /gm 1 will not work and 1 will not be identified as a correct gamemode). To fix this, we should implement our own parameter type for GameMode as follows:

public final class ParameterGameMode extends BaseParameterType<BukkitSource, GameMode> {

public ParameterGameMode() {
super(GameMode.class);
this.suggestions.addAll(Arrays.stream(GameMode.values())
.map(GameMode::name)
.toList());
}

@Override
public GameMode resolve(@NotNull ExecutionContext<BukkitSource> context, @NotNull CommandInputStream<BukkitSource> stream, String input) throws ImperatException {
String englishInput = input.toLowerCase(Locale.ENGLISH);
if (TypeUtility.isInteger(englishInput)) {
int modeInput = Integer.parseInt(englishInput);
for (var gamemode : GameMode.values()) {
if (gamemode.getValue() == modeInput) {
return gamemode;
}
}
} else {

for (var gamemode : GameMode.values()) {
if (gamemode.name().toLowerCase().startsWith(englishInput)) {
return gamemode;
}
}

}
throw new SourceException("Invalid GameMode `" + input + "`");
}

}

Now let's register our parameter type onEnable:

private BukkitImperat imperat;
@Override
public void onEnable() {

imperat = BukkitImperat.builder(this)
.parameterType(GameMode.class, new ParameterGameMode())
.build();
}