Skip to content

Commit

Permalink
refactor(utils): move command utils to command package
Browse files Browse the repository at this point in the history
  • Loading branch information
WakelessSloth56 committed Aug 25, 2022
1 parent c9d4601 commit 4786f49
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 69 deletions.
Expand Up @@ -5,8 +5,8 @@
import org.auioc.mcmod.arnicalib.ArnicaLib;
import org.auioc.mcmod.arnicalib.common.command.impl.VersionCommand;
import org.auioc.mcmod.arnicalib.server.command.impl.RtpCommand;
import org.auioc.mcmod.arnicalib.utils.game.DynamicCommandHandler;
import org.auioc.mcmod.arnicalib.utils.game.EnvironmentUtils;
import org.auioc.mcmod.arnicalib.utils.game.command.DynamicCommandHandler;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.tree.CommandNode;
import net.minecraft.commands.CommandSourceStack;
Expand Down
@@ -1,97 +1,54 @@
package org.auioc.mcmod.arnicalib.utils.game;

import static org.auioc.mcmod.arnicalib.ArnicaLib.i18n;
import static org.auioc.mcmod.arnicalib.utils.game.TextUtils.translatable;
import java.lang.reflect.Field;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import org.auioc.mcmod.arnicalib.api.mixin.common.IMixinCommandSourceStack;
import com.mojang.brigadier.context.CommandContext;
import org.auioc.mcmod.arnicalib.utils.game.command.CommandExceptions;
import org.auioc.mcmod.arnicalib.utils.game.command.CommandNodeUtils;
import org.auioc.mcmod.arnicalib.utils.game.command.CommandSourceUtils;
import com.mojang.brigadier.context.ParsedCommandNode;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
import com.mojang.brigadier.tree.LiteralCommandNode;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.level.ServerPlayer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

@Deprecated(since = "5.4.4", forRemoval = true)
public interface CommandUtils {

SimpleCommandExceptionType INTERNAL_ERROR = new SimpleCommandExceptionType(translatable(i18n("command.failure.internal")));
SimpleCommandExceptionType LOGGABLE_INTERNAL_ERROR = new SimpleCommandExceptionType(translatable(i18n("command.failure.internal.loggable")));
SimpleCommandExceptionType NOT_SERVER_ERROR = new SimpleCommandExceptionType(translatable(i18n("command.failure.not_server")));
SimpleCommandExceptionType NOT_DEDICATED_SERVER_ERROR = new SimpleCommandExceptionType(translatable(i18n("command.failure.not_dedicated_server")));
SimpleCommandExceptionType GET_REAL_SOURCE_REFLECTION_ERROR = new SimpleCommandExceptionType(translatable(i18n("command.failure.get_real_source.reflection")));

Predicate<CommandSourceStack> IS_PLAYER = (source) -> source.getEntity() instanceof ServerPlayer;
Predicate<CommandSourceStack> PERMISSION_LEVEL_0 = (source) -> source.hasPermission(0);
Predicate<CommandSourceStack> PERMISSION_LEVEL_1 = (source) -> source.hasPermission(1);
Predicate<CommandSourceStack> PERMISSION_LEVEL_2 = (source) -> source.hasPermission(2);
Predicate<CommandSourceStack> PERMISSION_LEVEL_3 = (source) -> source.hasPermission(3);
Predicate<CommandSourceStack> PERMISSION_LEVEL_4 = (source) -> source.hasPermission(4);

/**
* @param sourceStack
* @return The real command source of the specified {@code CommandSourceStack}
* @throws NoSuchFieldException
* @throws SecurityException
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @since 4.0.0
* @deprecated Use {@link IMixinCommandSourceStack} instead {@code ((IMixinCommandSourceStack)stack).getSource()}
*/
@Deprecated(since = "4.1.5")
static CommandSource getPrivateSource(CommandSourceStack sourceStack) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
Field privateSourceField = CommandSourceStack.class.getDeclaredField("source");
privateSourceField.setAccessible(true);
return (CommandSource) privateSourceField.get(sourceStack);
SimpleCommandExceptionType INTERNAL_ERROR = CommandExceptions.INTERNAL_ERROR;
SimpleCommandExceptionType LOGGABLE_INTERNAL_ERROR = CommandExceptions.LOGGABLE_INTERNAL_ERROR;
SimpleCommandExceptionType NOT_SERVER_ERROR = CommandExceptions.NOT_SERVER_ERROR;
SimpleCommandExceptionType NOT_DEDICATED_SERVER_ERROR = CommandExceptions.NOT_DEDICATED_SERVER_ERROR;
SimpleCommandExceptionType GET_REAL_SOURCE_REFLECTION_ERROR = CommandExceptions.GET_REAL_SOURCE_REFLECTION_ERROR;

Predicate<CommandSourceStack> IS_PLAYER = CommandSourceUtils.IS_PLAYER;
Predicate<CommandSourceStack> PERMISSION_LEVEL_0 = CommandSourceUtils.PERMISSION_LEVEL_0;
Predicate<CommandSourceStack> PERMISSION_LEVEL_1 = CommandSourceUtils.PERMISSION_LEVEL_1;
Predicate<CommandSourceStack> PERMISSION_LEVEL_2 = CommandSourceUtils.PERMISSION_LEVEL_2;
Predicate<CommandSourceStack> PERMISSION_LEVEL_3 = CommandSourceUtils.PERMISSION_LEVEL_3;
Predicate<CommandSourceStack> PERMISSION_LEVEL_4 = CommandSourceUtils.PERMISSION_LEVEL_4;

static CommandSource getPrivateSource(CommandSourceStack sourceStack) {
return CommandSourceUtils.getRealSourceReflection(sourceStack);
}

@OnlyIn(Dist.CLIENT)
static LocalPlayer getLocalPlayerOrException(CommandSourceStack sourceStack) throws CommandSyntaxException {
var entity = sourceStack.getEntity();
if (entity instanceof LocalPlayer) {
return (LocalPlayer) entity;
}
throw CommandSourceStack.ERROR_NOT_PLAYER.create();
return CommandSourceUtils.getLocalPlayerOrException(sourceStack);
}

/**
* @param nodeList List of {@link ParsedCommandNode}s, from {@link CommandContext#getNodes()}
* @param fromIndex
* @param toIndex
* @param conventToSnakeCase
* @return String that concatenates the literals (or in its snake case) of all (or some of) {@link LiteralCommandNode}s in the {@link ParsedCommandNode} list, separated by dots
* @since 5.1.1
*/
static String joinLiteralNodes(List<ParsedCommandNode<CommandSourceStack>> nodeList, int fromIndex, int toIndex, boolean conventToSnakeCase) {
return nodeList
.subList(fromIndex, toIndex)
.stream()
.map(ParsedCommandNode::getNode)
.filter((node) -> node instanceof LiteralCommandNode)
.map((node) -> (LiteralCommandNode<CommandSourceStack>) node)
.map(LiteralCommandNode::getLiteral)
.map((literal) -> conventToSnakeCase ? literal.replaceAll("[A-Z]", "_$0").toLowerCase() : literal)
.collect(Collectors.joining("."));
return CommandNodeUtils.joinLiteralNodes(nodeList, fromIndex, toIndex);
}

/**
* @see {@link #joinLiteralNodes(List, int, int, boolean)}
*/
static String joinLiteralNodes(List<ParsedCommandNode<CommandSourceStack>> nodes, int fromIndex) {
return joinLiteralNodes(nodes, fromIndex, nodes.size(), true);
return CommandNodeUtils.joinLiteralNodes(nodes, fromIndex, nodes.size());
}

/**
* @see {@link #joinLiteralNodes(List, int, int, boolean)}
*/
static String joinLiteralNodes(List<ParsedCommandNode<CommandSourceStack>> nodes) {
return joinLiteralNodes(nodes, 0, nodes.size(), true);
return CommandNodeUtils.joinLiteralNodes(nodes, 0, nodes.size());
}

}
@@ -0,0 +1,23 @@
package org.auioc.mcmod.arnicalib.utils.game.command;

import org.auioc.mcmod.arnicalib.ArnicaLib;
import org.auioc.mcmod.arnicalib.utils.game.TextUtils;
import com.mojang.brigadier.exceptions.BuiltInExceptionProvider;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;

public class CommandExceptions {

public static final BuiltInExceptionProvider BUILT_IN_EXCEPTIONS = CommandSyntaxException.BUILT_IN_EXCEPTIONS;

public static final SimpleCommandExceptionType INTERNAL_ERROR = simple("command.failure.internal");
public static final SimpleCommandExceptionType LOGGABLE_INTERNAL_ERROR = simple("command.failure.internal.loggable");
public static final SimpleCommandExceptionType NOT_SERVER_ERROR = simple("command.failure.not_server");
public static final SimpleCommandExceptionType NOT_DEDICATED_SERVER_ERROR = simple("command.failure.not_dedicated_server");
public static final SimpleCommandExceptionType GET_REAL_SOURCE_REFLECTION_ERROR = simple("command.failure.get_real_source.reflection");

private static SimpleCommandExceptionType simple(String key) {
return new SimpleCommandExceptionType(TextUtils.translatable(ArnicaLib.i18n("command.failure.internal")));
}

}
@@ -0,0 +1,54 @@
package org.auioc.mcmod.arnicalib.utils.game.command;

import java.util.List;
import java.util.stream.Collectors;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.ParsedCommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import net.minecraft.commands.CommandSourceStack;

public class CommandNodeUtils {

public static String getLastLiteral(List<ParsedCommandNode<CommandSourceStack>> nodeList) {
for (int i = nodeList.size(); i-- > 0;) {
if (nodeList.get(i).getNode() instanceof LiteralCommandNode) {
return ((LiteralCommandNode<CommandSourceStack>) nodeList.get(i).getNode()).getLiteral();
}
}
return null;
}

/**
* @param nodeList List of {@link ParsedCommandNode}s, from {@link CommandContext#getNodes()}
* @param fromIndex
* @param toIndex
* @param conventToSnakeCase
* @return String that concatenates the literals (or in its snake case) of all (or some of) {@link LiteralCommandNode}s in the {@link ParsedCommandNode} list, separated by dots
* @since 5.1.1
*/
public static String joinLiteralNodes(List<ParsedCommandNode<CommandSourceStack>> nodeList, int fromIndex, int toIndex) {
return nodeList
.subList(fromIndex, toIndex)
.stream()
.map(ParsedCommandNode::getNode)
.filter((node) -> node instanceof LiteralCommandNode)
.map((node) -> (LiteralCommandNode<CommandSourceStack>) node)
.map(LiteralCommandNode::getLiteral)
.collect(Collectors.joining("."));
}

/**
* @see {@link #joinLiteralNodes(List, int, int, boolean)}
*/
public static String joinLiteralNodes(List<ParsedCommandNode<CommandSourceStack>> nodes, int fromIndex) {
return joinLiteralNodes(nodes, fromIndex, nodes.size());
}

/**
* @see {@link #joinLiteralNodes(List, int, int, boolean)}
*/
public static String joinLiteralNodes(List<ParsedCommandNode<CommandSourceStack>> nodes) {
return joinLiteralNodes(nodes, 0, nodes.size());
}

}
@@ -0,0 +1,53 @@
package org.auioc.mcmod.arnicalib.utils.game.command;

import java.util.function.Predicate;
import org.auioc.mcmod.arnicalib.api.mixin.common.IMixinCommandSourceStack;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.CommandSource;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.BaseCommandBlock;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper;
import net.minecraftforge.fml.util.ObfuscationReflectionHelper.UnableToAccessFieldException;

public class CommandSourceUtils {

public static final Predicate<CommandSourceStack> PERMISSION_LEVEL_0 = (sourceStack) -> sourceStack.hasPermission(0);
public static final Predicate<CommandSourceStack> PERMISSION_LEVEL_1 = (sourceStack) -> sourceStack.hasPermission(1);
public static final Predicate<CommandSourceStack> PERMISSION_LEVEL_2 = (sourceStack) -> sourceStack.hasPermission(2);
public static final Predicate<CommandSourceStack> PERMISSION_LEVEL_3 = (sourceStack) -> sourceStack.hasPermission(3);
public static final Predicate<CommandSourceStack> PERMISSION_LEVEL_4 = (sourceStack) -> sourceStack.hasPermission(4);

public static final Predicate<CommandSourceStack> IS_PLAYER = (sourceStack) -> sourceStack.getEntity() instanceof Player;
public static final Predicate<CommandSourceStack> IS_COMMAND_BLOCK = (sourceStack) -> getRealSource(sourceStack) instanceof BaseCommandBlock;
public static final Predicate<CommandSourceStack> IS_DEDICATED_SERVER = (sourceStack) -> getRealSource(sourceStack) instanceof DedicatedServer;

/**
* @param sourceStack
* @return The real command source of the specified {@code CommandSourceStack}
* @throws UnableToAccessFieldException
* @since 4.0.0
* @deprecated Use {@link #getPrivateSource} instead
*/
@Deprecated(since = "4.1.5")
public static CommandSource getRealSourceReflection(CommandSourceStack sourceStack) {
return ObfuscationReflectionHelper.getPrivateValue(CommandSourceStack.class, sourceStack, "f_81288_");
}

public static CommandSource getRealSource(CommandSourceStack sourceStack) {
return ((IMixinCommandSourceStack) sourceStack).getSource();
}


@OnlyIn(Dist.CLIENT)
public static LocalPlayer getLocalPlayerOrException(CommandSourceStack sourceStack) throws CommandSyntaxException {
var entity = sourceStack.getEntity();
if (entity instanceof LocalPlayer) return (LocalPlayer) entity;
throw CommandSourceStack.ERROR_NOT_PLAYER.create();
}

}
@@ -1,4 +1,4 @@
package org.auioc.mcmod.arnicalib.utils.game;
package org.auioc.mcmod.arnicalib.utils.game.command;

import static org.auioc.mcmod.arnicalib.ArnicaLib.LOGGER;
import java.lang.reflect.InvocationTargetException;
Expand All @@ -21,7 +21,7 @@ public static int run(String className, String methodName, CommandContext<Comman
LOGGER.warn(MARKER, "Command handler " + className + " throws a CommandSyntaxException");
throw cse;
}
throw CommandUtils.LOGGABLE_INTERNAL_ERROR.create();
throw CommandExceptions.LOGGABLE_INTERNAL_ERROR.create();
}
return Command.SINGLE_SUCCESS;
}
Expand Down

0 comments on commit 4786f49

Please sign in to comment.