feat: Implement gamerule command (#2840)

* Feat: Add /gamerule

Signed-off-by: Ben Woo <30431861+benwoo1110@users.noreply.github.com>

* Chore: Accept sugguestion

Co-authored-by: Ben Woo <30431861+benwoo1110@users.noreply.github.com>

* Chore: Implement (most) suggestions from Ben

* feat: Implement gamerule context

* feat: Implement MVworld[] array context

* feat: Implement context for gamerule value

---------

Signed-off-by: Ben Woo <30431861+benwoo1110@users.noreply.github.com>
Co-authored-by: Ben Woo <30431861+benwoo1110@users.noreply.github.com>
This commit is contained in:
Zax71 2023-02-15 02:25:53 +00:00 committed by GitHub
parent 15ae0ea54f
commit 9cf2c68fe8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 182 additions and 5 deletions

View File

@ -33,6 +33,7 @@ import com.onarandombox.MultiverseCore.commands.ConfirmCommand;
import com.onarandombox.MultiverseCore.commands.CreateCommand;
import com.onarandombox.MultiverseCore.commands.DebugCommand;
import com.onarandombox.MultiverseCore.commands.DeleteCommand;
import com.onarandombox.MultiverseCore.commands.GameruleCommand;
import com.onarandombox.MultiverseCore.commands.LoadCommand;
import com.onarandombox.MultiverseCore.commands.RegenCommand;
import com.onarandombox.MultiverseCore.commands.ReloadCommand;
@ -207,6 +208,7 @@ public class MultiverseCore extends JavaPlugin implements MVCore {
this.commandManager.registerCommand(new CreateCommand(this));
this.commandManager.registerCommand(new DebugCommand(this));
this.commandManager.registerCommand(new DeleteCommand(this));
this.commandManager.registerCommand(new GameruleCommand(this));
this.commandManager.registerCommand(new LoadCommand(this));
this.commandManager.registerCommand(new RegenCommand(this));
this.commandManager.registerCommand(new ReloadCommand(this));

View File

@ -0,0 +1,63 @@
package com.onarandombox.MultiverseCore.commands;
import co.aikar.commands.BukkitCommandIssuer;
import co.aikar.commands.annotation.CommandAlias;
import co.aikar.commands.annotation.CommandCompletion;
import co.aikar.commands.annotation.CommandPermission;
import co.aikar.commands.annotation.Description;
import co.aikar.commands.annotation.Flags;
import co.aikar.commands.annotation.Subcommand;
import co.aikar.commands.annotation.Syntax;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.commandtools.context.GameRuleValue;
import org.bukkit.ChatColor;
import org.bukkit.GameRule;
import org.jetbrains.annotations.NotNull;
@CommandAlias("mv")
public class GameruleCommand extends MultiverseCoreCommand {
public GameruleCommand(@NotNull MultiverseCore plugin) {
super(plugin);
}
@Subcommand("gamerule")
@CommandPermission("multiverse.core.gamerule")
@CommandCompletion("@gamerules true|false|@range:1-10 @mvworlds|*")
@Syntax("<Gamerule> <Gamerule value> [World or *]")
@Description("Changes a gamerule in one or more worlds")
public void onGameruleCommand(BukkitCommandIssuer issuer,
@Syntax("<Gamerule>")
@Description("Gamerule to set")
GameRule gamerule,
@Syntax("<Value>")
@Description("Value of gamerule")
GameRuleValue gameRuleValue,
@Flags("resolve=issuerAware")
@Syntax("[World or *]")
@Description("World to apply gamerule to, current world by default")
MVWorld[] worlds
) {
Object value = gameRuleValue.getValue();
boolean success = true;
for(MVWorld world : worlds) {
// Set gamerules and add false to list if it fails
if (!world.getCBWorld().setGameRule(gamerule, value)) {
issuer.sendMessage(ChatColor.RED + "Failed to set gamerule " + gamerule.getName() + " to " + value + " in " + world.getName() + ". It should be a " + gamerule.getType());
success = false;
}
}
// Tell user if it was successful
if (success) {
if (worlds.length == 1) {
issuer.sendMessage(ChatColor.GREEN + "Successfully set " + gamerule.getName() + " to " + value + " in " + worlds[0].getName());
}
else if (worlds.length > 1) {
issuer.sendMessage(ChatColor.GREEN + "Successfully set " + gamerule.getName() + " to " + value + " in " + worlds.length + " worlds.");
}
}
}
}

View File

@ -1,9 +1,7 @@
package com.onarandombox.MultiverseCore.commandtools;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.*;
import java.util.stream.Collectors;
import co.aikar.commands.BukkitCommandCompletionContext;
import co.aikar.commands.BukkitCommandIssuer;
@ -11,6 +9,7 @@ import co.aikar.commands.PaperCommandCompletions;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.api.MVWorldManager;
import org.bukkit.GameRule;
import org.jetbrains.annotations.NotNull;
public class MVCommandCompletions extends PaperCommandCompletions {
@ -27,6 +26,8 @@ public class MVCommandCompletions extends PaperCommandCompletions {
registerAsyncCompletion("destinations", this::suggestDestinations);
registerAsyncCompletion("flags", this::suggestFlags);
registerAsyncCompletion("mvworlds", this::suggestMVWorlds);
// Only updates on first load, helps with lag
registerStaticCompletion("gamerules", this::suggestGamerules);
}
private Collection<String> suggestDestinations(BukkitCommandCompletionContext context) {
@ -66,4 +67,8 @@ public class MVCommandCompletions extends PaperCommandCompletions {
return worlds;
}
private Collection<String> suggestGamerules() {
return Arrays.stream(GameRule.values()).map(GameRule::getName).collect(Collectors.toList());
}
}

View File

@ -4,14 +4,17 @@ import co.aikar.commands.BukkitCommandExecutionContext;
import co.aikar.commands.BukkitCommandIssuer;
import co.aikar.commands.InvalidCommandArgument;
import co.aikar.commands.PaperCommandContexts;
import co.aikar.commands.contexts.ContextResolver;
import com.google.common.base.Strings;
import com.onarandombox.MultiverseCore.MultiverseCore;
import com.onarandombox.MultiverseCore.api.MVWorld;
import com.onarandombox.MultiverseCore.commandtools.context.GameRuleValue;
import com.onarandombox.MultiverseCore.destination.ParsedDestination;
import com.onarandombox.MultiverseCore.display.filters.ContentFilter;
import com.onarandombox.MultiverseCore.display.filters.DefaultContentFilter;
import com.onarandombox.MultiverseCore.display.filters.RegexContentFilter;
import com.onarandombox.MultiverseCore.utils.PlayerFinder;
import org.bukkit.GameRule;
import org.bukkit.entity.Player;
public class MVCommandContexts extends PaperCommandContexts {
@ -23,8 +26,11 @@ public class MVCommandContexts extends PaperCommandContexts {
registerIssuerOnlyContext(BukkitCommandIssuer.class, BukkitCommandExecutionContext::getIssuer);
registerOptionalContext(ContentFilter.class, this::parseContentFilter);
registerIssuerAwareContext(MVWorld.class, this::parseMVWorld);
registerContext(ParsedDestination.class, this::parseDestination);
registerContext(GameRule.class, this::parseGameRule);
registerContext(GameRuleValue.class, this::parseGameRuleValue);
registerIssuerAwareContext(MVWorld.class, this::parseMVWorld);
registerIssuerAwareContext(MVWorld[].class, this::parseMVWorldArray);
registerIssuerAwareContext(Player.class, this::parsePlayer);
registerIssuerAwareContext(Player[].class, this::parsePlayerArray);
}
@ -51,6 +57,43 @@ public class MVCommandContexts extends PaperCommandContexts {
return parsedDestination;
}
private GameRule<?> parseGameRule(BukkitCommandExecutionContext context) {
String gameRuleName = context.popFirstArg();
if (Strings.isNullOrEmpty(gameRuleName)) {
throw new InvalidCommandArgument("No game rule specified.");
}
GameRule<?> gameRule = GameRule.getByName(gameRuleName);
if (gameRule == null) {
throw new InvalidCommandArgument("The game rule " + gameRuleName + " is not valid.");
}
return gameRule;
}
private GameRuleValue parseGameRuleValue(BukkitCommandExecutionContext context) {
GameRule<?> gameRule = (GameRule<?>) context.getResolvedArg(GameRule.class);
if (gameRule == null) {
throw new InvalidCommandArgument("No game rule specified.");
}
String valueString = context.getFirstArg();
if (Strings.isNullOrEmpty(valueString)) {
throw new InvalidCommandArgument("No game rule value specified.");
}
ContextResolver<?, BukkitCommandExecutionContext> resolver = getResolver(gameRule.getType());
if (resolver == null) {
return new GameRuleValue(valueString);
}
Object resolvedValue = resolver.getContext(context);
if (resolvedValue == null) {
throw new InvalidCommandArgument("The game rule value " + valueString + " is not valid for game rule " + gameRule.getName() + ".");
}
return new GameRuleValue(resolvedValue);
}
private MVWorld parseMVWorld(BukkitCommandExecutionContext context) {
String resolve = context.getFlagValue("resolve", "");
@ -94,6 +137,57 @@ public class MVCommandContexts extends PaperCommandContexts {
throw new InvalidCommandArgument("World " + worldName + " is not a loaded multiverse world.");
}
private MVWorld[] parseMVWorldArray(BukkitCommandExecutionContext context) {
String resolve = context.getFlagValue("resolve", "");
MVWorld playerWorld = null;
if (context.getIssuer().isPlayer()) {
playerWorld = plugin.getMVWorldManager().getMVWorld(context.getIssuer().getPlayer().getWorld());
}
// Get world based on sender only
if (resolve.equals("issuerOnly")) {
if (playerWorld != null) {
return new MVWorld[]{playerWorld};
}
if (context.isOptional()) {
return null;
}
throw new InvalidCommandArgument("This command can only be used by a player in a Multiverse World.");
}
String worldName = context.getFirstArg();
MVWorld world = plugin.getMVWorldManager().getMVWorld(worldName);
MVWorld[] worlds = "*".equals(worldName)
? plugin.getMVWorldManager().getMVWorlds().toArray(new MVWorld[0])
: (world != null ? new MVWorld[]{world} : null);
// Get world based on input, fallback to sender if input is not a world
if (resolve.equals("issuerAware")) {
if (worlds != null) {
context.popFirstArg();
return worlds;
}
if (playerWorld != null) {
return new MVWorld[]{playerWorld};
}
if (context.isOptional()) {
return null;
}
throw new InvalidCommandArgument("Player is not in a Multiverse World.");
}
// Get world based on input only
if (worlds != null) {
context.popFirstArg();
return worlds;
}
if (!context.isOptional()) {
return null;
}
throw new InvalidCommandArgument("World " + worldName + " is not a loaded multiverse world.");
}
private Player parsePlayer(BukkitCommandExecutionContext context) {
String resolve = context.getFlagValue("resolve", "");

View File

@ -0,0 +1,13 @@
package com.onarandombox.MultiverseCore.commandtools.context;
public class GameRuleValue {
private final Object value;
public GameRuleValue(Object value) {
this.value = value;
}
public Object getValue() {
return value;
}
}