Allow custom selector types to be defined (#4259)
This commit is contained in:
parent
2a546955a4
commit
aa2480c7a1
|
@ -1,6 +1,18 @@
|
||||||
--- ../src-base/minecraft/net/minecraft/command/EntitySelector.java
|
--- ../src-base/minecraft/net/minecraft/command/EntitySelector.java
|
||||||
+++ ../src-work/minecraft/net/minecraft/command/EntitySelector.java
|
+++ ../src-work/minecraft/net/minecraft/command/EntitySelector.java
|
||||||
@@ -153,6 +153,7 @@
|
@@ -121,6 +121,11 @@
|
||||||
|
|
||||||
|
public static <T extends Entity> List<T> func_179656_b(ICommandSender p_179656_0_, String p_179656_1_, Class <? extends T > p_179656_2_) throws CommandException
|
||||||
|
{
|
||||||
|
+ return net.minecraftforge.common.command.SelectorHandlerManager.matchEntities(p_179656_0_, p_179656_1_, p_179656_2_);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static <T extends Entity> List<T> matchEntitiesDefault(ICommandSender p_179656_0_, String p_179656_1_, Class <? extends T > p_179656_2_) throws CommandException
|
||||||
|
+ {
|
||||||
|
Matcher matcher = field_82389_a.matcher(p_179656_1_);
|
||||||
|
|
||||||
|
if (matcher.matches() && p_179656_0_.func_70003_b(1, "@"))
|
||||||
|
@@ -153,6 +158,7 @@
|
||||||
list2.addAll(func_184951_f(map));
|
list2.addAll(func_184951_f(map));
|
||||||
list2.addAll(func_180698_a(map, vec3d));
|
list2.addAll(func_180698_a(map, vec3d));
|
||||||
list2.addAll(func_179662_g(map));
|
list2.addAll(func_179662_g(map));
|
||||||
|
@ -8,3 +20,27 @@
|
||||||
|
|
||||||
if ("s".equalsIgnoreCase(s))
|
if ("s".equalsIgnoreCase(s))
|
||||||
{
|
{
|
||||||
|
@@ -786,6 +792,11 @@
|
||||||
|
|
||||||
|
public static boolean func_82377_a(String p_82377_0_) throws CommandException
|
||||||
|
{
|
||||||
|
+ return net.minecraftforge.common.command.SelectorHandlerManager.matchesMultiplePlayers(p_82377_0_);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static boolean matchesMultiplePlayersDefault(String p_82377_0_) throws CommandException
|
||||||
|
+ {
|
||||||
|
Matcher matcher = field_82389_a.matcher(p_82377_0_);
|
||||||
|
|
||||||
|
if (!matcher.matches())
|
||||||
|
@@ -803,6 +814,11 @@
|
||||||
|
|
||||||
|
public static boolean func_82378_b(String p_82378_0_)
|
||||||
|
{
|
||||||
|
+ return net.minecraftforge.common.command.SelectorHandlerManager.isSelector(p_82378_0_);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ public static boolean isSelectorDefault(String p_82378_0_)
|
||||||
|
+ {
|
||||||
|
return field_82389_a.matcher(p_82378_0_).matches();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecraftforge.common.command;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.command.CommandException;
|
||||||
|
import net.minecraft.command.ICommandSender;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for custom types of selectors registered with {@link SelectorHandlerManager}
|
||||||
|
*/
|
||||||
|
public interface SelectorHandler
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns a {@link List} of {@link Entity Entities} of class {@code targetClass} ({@code T}) represented by {@code token}<br>
|
||||||
|
* <b>Note:</b> If {@code token} does not match the overall syntax defined by {@link #isSelector}, this method should return an empty list.
|
||||||
|
* For any other error, an exception should be thrown
|
||||||
|
*
|
||||||
|
* @param sender The {@link ICommandSender} that initiated the query
|
||||||
|
*/
|
||||||
|
public <T extends Entity> List<T> matchEntities(ICommandSender sender, String token, Class<? extends T> targetClass) throws CommandException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the selector string potentially matches multiple entities
|
||||||
|
*/
|
||||||
|
public boolean matchesMultiplePlayers(String selectorStr) throws CommandException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the string matches the overall syntax of the selector<br>
|
||||||
|
* <b>Note:</b> If this returns {@code false}, {@link #matchEntities} should return an empty list
|
||||||
|
*/
|
||||||
|
public boolean isSelector(String selectorStr);
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
/*
|
||||||
|
* Minecraft Forge
|
||||||
|
* Copyright (c) 2016.
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation version 2.1
|
||||||
|
* of the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
package net.minecraftforge.common.command;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.NavigableMap;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
|
||||||
|
import net.minecraft.command.CommandException;
|
||||||
|
import net.minecraft.command.EntitySelector;
|
||||||
|
import net.minecraft.command.ICommandSender;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraftforge.fml.common.Loader;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows registration of custom selector types by assigning a {@link SelectorHandler} to a prefix
|
||||||
|
* This class handles calls to the {@link EntitySelector} methods {@link EntitySelector#matchEntities matchEntities},
|
||||||
|
* {@link EntitySelector#matchesMultiplePlayers matchesMultiplePlayers} and {@link EntitySelector#isSelector isSelector}.<br>
|
||||||
|
* The calls are delegated to the handler with the longest matching prefix.<br>
|
||||||
|
* <br>
|
||||||
|
* <b>Note:</b> If you register a {@link SelectorHandler} to a broader domain (not just a single selector), you should take care of possible shadowing conflicts yourself.
|
||||||
|
* For this you can use the information provided by {@link #selectorHandlers} and {@link #registeringMods}.
|
||||||
|
*/
|
||||||
|
public class SelectorHandlerManager
|
||||||
|
{
|
||||||
|
private SelectorHandlerManager()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//the ordering is reversed such that longer prefixes appear before their shorter substrings
|
||||||
|
public static final NavigableMap<String, SelectorHandler> selectorHandlers = new TreeMap<String, SelectorHandler>(Collections.<String> reverseOrder());
|
||||||
|
public static final NavigableMap<String, String> registeringMods = new TreeMap<String, String>(Collections.<String> reverseOrder());
|
||||||
|
|
||||||
|
private static final SelectorHandler vanillaHandler = new SelectorHandler()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public <T extends Entity> List<T> matchEntities(final ICommandSender sender, final String token, final Class<? extends T> targetClass) throws CommandException
|
||||||
|
{
|
||||||
|
return EntitySelector.matchEntitiesDefault(sender, token, targetClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesMultiplePlayers(final String selectorStr) throws CommandException
|
||||||
|
{
|
||||||
|
return EntitySelector.matchesMultiplePlayersDefault(selectorStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelector(final String selectorStr)
|
||||||
|
{
|
||||||
|
return EntitySelector.isSelectorDefault(selectorStr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
for (final String prefix : ArrayUtils.toArray("@p", "@a", "@r", "@e", "@s"))
|
||||||
|
{
|
||||||
|
selectorHandlers.put(prefix, vanillaHandler);
|
||||||
|
registeringMods.put(prefix, "minecraft");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new {@link SelectorHandler} for {@code prefix}.<br>
|
||||||
|
*
|
||||||
|
* @param prefix The domain the specified {@code handler} is registered for.
|
||||||
|
* If you want to register just a single selector, {@code prefix} has the form '@{selectorName}'
|
||||||
|
*/
|
||||||
|
public static void register(final String prefix, final SelectorHandler handler)
|
||||||
|
{
|
||||||
|
if (prefix.isEmpty())
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Prefix must not be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
final String modId = Loader.instance().activeModContainer().getModId();
|
||||||
|
|
||||||
|
selectorHandlers.put(prefix, handler);
|
||||||
|
registeringMods.put(prefix, modId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the best matching handler for the given string. Defaults to the vanilla handler if no prefix applies
|
||||||
|
*/
|
||||||
|
public static SelectorHandler getHandler(final String selectorStr)
|
||||||
|
{
|
||||||
|
if (!selectorStr.isEmpty())
|
||||||
|
{
|
||||||
|
for (final Entry<String, SelectorHandler> handler : selectorHandlers.subMap(selectorStr, true, selectorStr.substring(0, 1), true).entrySet())
|
||||||
|
{
|
||||||
|
if (selectorStr.startsWith(handler.getKey()))
|
||||||
|
{
|
||||||
|
return handler.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return vanillaHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
//These methods are called by the vanilla methods
|
||||||
|
|
||||||
|
public static <T extends Entity> List<T> matchEntities(final ICommandSender sender, final String token, final Class<? extends T> targetClass) throws CommandException
|
||||||
|
{
|
||||||
|
return getHandler(token).matchEntities(sender, token, targetClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean matchesMultiplePlayers(final String selectorStr) throws CommandException
|
||||||
|
{
|
||||||
|
return getHandler(selectorStr).matchesMultiplePlayers(selectorStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSelector(final String selectorStr)
|
||||||
|
{
|
||||||
|
return getHandler(selectorStr).isSelector(selectorStr);
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,3 +61,7 @@ net/minecraft/world/storage/loot/LootEntryEmpty.<init>(II[Lnet/minecraft/world/s
|
||||||
net/minecraft/world/chunk/BlockStateContainer.setBits(IZ)V=|p_186012_1_,forceBits
|
net/minecraft/world/chunk/BlockStateContainer.setBits(IZ)V=|p_186012_1_,forceBits
|
||||||
net/minecraft/village/Village.getPlayerReputation(Ljava/util/UUID;)I=|p_82684_1_
|
net/minecraft/village/Village.getPlayerReputation(Ljava/util/UUID;)I=|p_82684_1_
|
||||||
net/minecraft/village/Village.modifyPlayerReputation(Ljava/util/UUID;I)I=|p_82688_1_,p_82688_2_
|
net/minecraft/village/Village.modifyPlayerReputation(Ljava/util/UUID;I)I=|p_82688_1_,p_82688_2_
|
||||||
|
|
||||||
|
net/minecraft/command/EntitySelector.matchEntitiesDefault(Lnet/minecraft/command/ICommandSender;Ljava/lang/String;Ljava/lang/Class;)Ljava/util/List;=|p_179656_0_,p_179656_1_,p_179656_2_
|
||||||
|
net/minecraft/command/EntitySelector.matchesMultiplePlayersDefault(Ljava/lang/String;)Z=|p_82377_0_
|
||||||
|
net/minecraft/command/EntitySelector.isSelectorDefault(Ljava/lang/String;)Z=|p_82378_0_
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
package net.minecraftforge.test;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.minecraft.command.CommandException;
|
||||||
|
import net.minecraft.command.ICommandSender;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraftforge.common.command.SelectorHandler;
|
||||||
|
import net.minecraftforge.common.command.SelectorHandlerManager;
|
||||||
|
import net.minecraftforge.fml.common.Mod;
|
||||||
|
import net.minecraftforge.fml.common.Mod.EventHandler;
|
||||||
|
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
|
||||||
|
|
||||||
|
@Mod(modid = "selectorhandlertest", name = "Selector Handler Test", version = "0.0.0")
|
||||||
|
public class SelectorHandlerTest
|
||||||
|
{
|
||||||
|
@EventHandler
|
||||||
|
public void init(final FMLInitializationEvent event)
|
||||||
|
{
|
||||||
|
SelectorHandlerManager.register(Handler.name, new Handler());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Handler implements SelectorHandler
|
||||||
|
{
|
||||||
|
protected static final String name = "@self";
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public <T extends Entity> List<T> matchEntities(final ICommandSender sender, final String token, final Class<? extends T> targetClass) throws CommandException
|
||||||
|
{
|
||||||
|
final Entity senderEntity = sender.getCommandSenderEntity();
|
||||||
|
return senderEntity != null && targetClass.isAssignableFrom(senderEntity.getClass()) && name.equals(token)
|
||||||
|
? Collections.singletonList((T) sender.getCommandSenderEntity())
|
||||||
|
: Collections.<T> emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesMultiplePlayers(final String selectorStr) throws CommandException
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSelector(final String selectorStr)
|
||||||
|
{
|
||||||
|
return name.equals(selectorStr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue