Java tutorial
/* * Minecraft Forge * Copyright (c) 2016-2018. * * 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); } }