package dev.jorel.commandapi.nms; import java.io.File; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import java.util.EnumSet; import java.util.function.ToIntBiFunction; import java.util.stream.Collectors; import org.bukkit.Axis; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.Location; import org.bukkit.NamespacedKey; import org.bukkit.Particle; import org.bukkit.Sound; import org.bukkit.World.Environment; import org.bukkit.block.Biome; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.SimpleCommandMap; import org.bukkit.craftbukkit.v1_14_R1.CraftLootTable; import org.bukkit.craftbukkit.v1_14_R1.CraftParticle; import org.bukkit.craftbukkit.v1_14_R1.CraftServer; import org.bukkit.craftbukkit.v1_14_R1.CraftSound; import org.bukkit.craftbukkit.v1_14_R1.CraftWorld; import org.bukkit.craftbukkit.v1_14_R1.command.ProxiedNativeCommandSender; import org.bukkit.craftbukkit.v1_14_R1.command.VanillaCommandWrapper; import org.bukkit.craftbukkit.v1_14_R1.enchantments.CraftEnchantment; import org.bukkit.craftbukkit.v1_14_R1.entity.CraftEntity; import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer; import org.bukkit.craftbukkit.v1_14_R1.inventory.CraftItemStack; import org.bukkit.craftbukkit.v1_14_R1.potion.CraftPotionEffectType; import org.bukkit.craftbukkit.v1_14_R1.util.CraftChatMessage; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import org.bukkit.loot.LootTable; import org.bukkit.potion.PotionEffectType; import com.google.common.io.Files; import com.google.gson.GsonBuilder; import com.mojang.authlib.GameProfile; import com.mojang.brigadier.CommandDispatcher; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.suggestion.SuggestionProvider; import com.mojang.brigadier.suggestion.Suggestions; import de.tr7zw.nbtapi.NBTContainer; import dev.jorel.commandapi.CommandAPIHandler; import dev.jorel.commandapi.arguments.LocationType; import dev.jorel.commandapi.arguments.ICustomProvidedArgument.SuggestionProviders; import dev.jorel.commandapi.exceptions.BiomeArgumentException; import dev.jorel.commandapi.arguments.EntitySelectorArgument.EntitySelector; import dev.jorel.commandapi.nms.NMS; import dev.jorel.commandapi.wrappers.FunctionWrapper; import dev.jorel.commandapi.wrappers.Location2D; import dev.jorel.commandapi.wrappers.MathOperation; import dev.jorel.commandapi.wrappers.Rotation; import dev.jorel.commandapi.wrappers.ScoreboardSlot; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.chat.ComponentSerializer; import net.minecraft.server.v1_14_R1.Advancement; import net.minecraft.server.v1_14_R1.ArgumentChat; import net.minecraft.server.v1_14_R1.ArgumentChatComponent; import net.minecraft.server.v1_14_R1.ArgumentChatFormat; import net.minecraft.server.v1_14_R1.ArgumentCriterionValue; import net.minecraft.server.v1_14_R1.ArgumentDimension; import net.minecraft.server.v1_14_R1.ArgumentEnchantment; import net.minecraft.server.v1_14_R1.ArgumentEntity; import net.minecraft.server.v1_14_R1.ArgumentEntitySummon; import net.minecraft.server.v1_14_R1.ArgumentItemStack; import net.minecraft.server.v1_14_R1.ArgumentMathOperation; import net.minecraft.server.v1_14_R1.ArgumentMinecraftKeyRegistered; import net.minecraft.server.v1_14_R1.ArgumentMobEffect; import net.minecraft.server.v1_14_R1.ArgumentNBTTag; import net.minecraft.server.v1_14_R1.ArgumentParticle; import net.minecraft.server.v1_14_R1.ArgumentPosition; import net.minecraft.server.v1_14_R1.ArgumentProfile; import net.minecraft.server.v1_14_R1.ArgumentRegistry; import net.minecraft.server.v1_14_R1.ArgumentRotation; import net.minecraft.server.v1_14_R1.ArgumentRotationAxis; import net.minecraft.server.v1_14_R1.ArgumentScoreboardCriteria; import net.minecraft.server.v1_14_R1.ArgumentScoreboardObjective; import net.minecraft.server.v1_14_R1.ArgumentScoreboardSlot; import net.minecraft.server.v1_14_R1.ArgumentScoreboardTeam; import net.minecraft.server.v1_14_R1.ArgumentScoreholder; import net.minecraft.server.v1_14_R1.ArgumentTag; import net.minecraft.server.v1_14_R1.ArgumentTime; import net.minecraft.server.v1_14_R1.ArgumentVec2; import net.minecraft.server.v1_14_R1.ArgumentVec2I; import net.minecraft.server.v1_14_R1.ArgumentVec3; import net.minecraft.server.v1_14_R1.BlockPosition; import net.minecraft.server.v1_14_R1.BlockPosition2D; import net.minecraft.server.v1_14_R1.CommandListenerWrapper; import net.minecraft.server.v1_14_R1.CompletionProviders; import net.minecraft.server.v1_14_R1.CriterionConditionValue.FloatRange; import net.minecraft.server.v1_14_R1.CriterionConditionValue.IntegerRange; import net.minecraft.server.v1_14_R1.CustomFunction; import net.minecraft.server.v1_14_R1.CustomFunctionData; import net.minecraft.server.v1_14_R1.DimensionManager; import net.minecraft.server.v1_14_R1.Entity; import net.minecraft.server.v1_14_R1.EnumDirection.EnumAxis; import net.minecraft.server.v1_14_R1.IChatBaseComponent.ChatSerializer; import net.minecraft.server.v1_14_R1.ICompletionProvider; import net.minecraft.server.v1_14_R1.IRegistry; import net.minecraft.server.v1_14_R1.IVectorPosition; import net.minecraft.server.v1_14_R1.LootTableRegistry; import net.minecraft.server.v1_14_R1.MinecraftKey; import net.minecraft.server.v1_14_R1.MinecraftServer; import net.minecraft.server.v1_14_R1.ScoreboardScore; import net.minecraft.server.v1_14_R1.Vec2F; import net.minecraft.server.v1_14_R1.Vec3D; @SuppressWarnings({ "unchecked", "rawtypes" }) public class NMS_1_14_3 implements NMS { @Override public ArgumentType<?> _ArgumentAxis() { return ArgumentRotationAxis.a(); } @Override public ArgumentType<?> _ArgumentChat() { return ArgumentChat.a(); } @Override public ArgumentType _ArgumentChatComponent() { return ArgumentChatComponent.a(); } @Override public ArgumentType _ArgumentChatFormat() { return ArgumentChatFormat.a(); } @Override public ArgumentType<?> _ArgumentDimension() { return ArgumentDimension.a(); } @Override public ArgumentType _ArgumentEnchantment() { return ArgumentEnchantment.a(); } @Override public ArgumentType _ArgumentEntity(EntitySelector selector) { switch (selector) { case MANY_ENTITIES: return ArgumentEntity.multipleEntities(); case MANY_PLAYERS: return ArgumentEntity.d(); case ONE_ENTITY: return ArgumentEntity.a(); case ONE_PLAYER: return ArgumentEntity.c(); } return null; } @Override public ArgumentType _ArgumentEntitySummon() { return ArgumentEntitySummon.a(); } @Override public ArgumentType<?> _ArgumentFloatRange() { return new ArgumentCriterionValue.a(); } @Override public ArgumentType<?> _ArgumentIntRange() { return new ArgumentCriterionValue.b(); } @Override public ArgumentType _ArgumentItemStack() { return ArgumentItemStack.a(); } @Override public ArgumentType _ArgumentMinecraftKeyRegistered() { return ArgumentMinecraftKeyRegistered.a(); } @Override public ArgumentType _ArgumentMobEffect() { return ArgumentMobEffect.a(); } @Override public ArgumentType _ArgumentParticle() { return ArgumentParticle.a(); } @Override public ArgumentType _ArgumentPosition() { return ArgumentPosition.a(); } @Override public ArgumentType<?> _ArgumentPosition2D() { return ArgumentVec2I.a(); } @Override public ArgumentType _ArgumentProfile() { return ArgumentProfile.a(); } @Override public ArgumentType<?> _ArgumentRotation() { return ArgumentRotation.a(); } @Override public ArgumentType<?> _ArgumentScoreboardCriteria() { return ArgumentScoreboardCriteria.a(); } @Override public ArgumentType<?> _ArgumentScoreboardObjective() { return ArgumentScoreboardObjective.a(); } @Override public ArgumentType<?> _ArgumentScoreboardSlot() { return ArgumentScoreboardSlot.a(); } @Override public ArgumentType<?> _ArgumentScoreboardTeam() { return ArgumentScoreboardTeam.a(); } @Override public ArgumentType _ArgumentTag() { return ArgumentTag.a(); } @Override public ArgumentType<?> _ArgumentTime() { return ArgumentTime.a(); } @Override public ArgumentType<?> _ArgumentVec2() { return ArgumentVec2.a(); } @Override public ArgumentType _ArgumentVec3() { return ArgumentVec3.a(); } @Override public String[] compatibleVersions() { return new String[]{ "1.14.3" }; } @Override public void createDispatcherFile(Object server, File file, CommandDispatcher dispatcher) throws IOException { Files.write((new GsonBuilder()).setPrettyPrinting().create().toJson(ArgumentRegistry.a(dispatcher, dispatcher.getRoot())), file, StandardCharsets.UTF_8); } @Override public org.bukkit.advancement.Advancement getAdvancement(CommandContext cmdCtx, String key) throws CommandSyntaxException { return ArgumentMinecraftKeyRegistered.a(cmdCtx, key).bukkit; } @Override public EnumSet<Axis> getAxis(CommandContext cmdCtx, String key) { EnumSet<Axis> set = EnumSet.noneOf(Axis.class); EnumSet<EnumAxis> parsedEnumSet = ArgumentRotationAxis.a(cmdCtx, key); for (EnumAxis element : parsedEnumSet) { switch (element) { case X: set.add(Axis.X); break; case Y: set.add(Axis.Y); break; case Z: set.add(Axis.Z); break; } } return set; } @Override public CommandDispatcher getBrigadierDispatcher(Object server) { return ((MinecraftServer) server).commandDispatcher.a(); } @Override public BaseComponent[] getChat(CommandContext cmdCtx, String key) throws CommandSyntaxException { String resultantString = ChatSerializer.a(ArgumentChat.a(cmdCtx, key)); return ComponentSerializer.parse(resultantString); } @Override public ChatColor getChatColor(CommandContext cmdCtx, String str) { return CraftChatMessage.getColor(ArgumentChatFormat.a(cmdCtx, str)); } @Override public BaseComponent[] getChatComponent(CommandContext cmdCtx, String str) { String resultantString = ChatSerializer.a(ArgumentChatComponent.a(cmdCtx, str)); return ComponentSerializer.parse(resultantString); } private CommandListenerWrapper getCLW(CommandContext cmdCtx) { return (CommandListenerWrapper) cmdCtx.getSource(); } @Override public CommandSender getCommandSenderForCLW(Object clw) { try { return ((CommandListenerWrapper) clw).getBukkitSender(); } catch (UnsupportedOperationException e) { return null; } } @Override public Environment getDimension(CommandContext cmdCtx, String key) { DimensionManager manager = ArgumentDimension.a(cmdCtx, key); switch (manager.getDimensionID()) { case 0: return Environment.NORMAL; case -1: return Environment.NETHER; case 1: return Environment.THE_END; } return null; } @Override public Enchantment getEnchantment(CommandContext cmdCtx, String str) { return new CraftEnchantment(ArgumentEnchantment.a(cmdCtx, str)); } @Override public Object getEntitySelector(CommandContext cmdCtx, String str, EntitySelector selector) throws CommandSyntaxException { switch (selector) { case MANY_ENTITIES: try { return ArgumentEntity.c(cmdCtx, str).stream().map(entity -> ((Entity) entity).getBukkitEntity()).collect(Collectors.toList()); } catch (CommandSyntaxException e) { return new ArrayList<org.bukkit.entity.Entity>(); } case MANY_PLAYERS: try { return ArgumentEntity.d(cmdCtx, str).stream().map(player -> ((Entity) player).getBukkitEntity()).collect(Collectors.toList()); } catch (CommandSyntaxException e) { return new ArrayList<Player>(); } case ONE_ENTITY: return ArgumentEntity.a(cmdCtx, str).getBukkitEntity(); case ONE_PLAYER: return ArgumentEntity.e(cmdCtx, str).getBukkitEntity(); } return null; } @Override public EntityType getEntityType(CommandContext cmdCtx, String str, CommandSender sender) throws CommandSyntaxException { Entity entity = IRegistry.ENTITY_TYPE.get(ArgumentEntitySummon.a(cmdCtx, str)).a(((CraftWorld) getCommandSenderWorld(sender)).getHandle()); return entity.getBukkitEntity().getType(); } @Override public dev.jorel.commandapi.wrappers.FloatRange getFloatRange(CommandContext<?> cmdCtx, String key) { FloatRange range = cmdCtx.getArgument(key, FloatRange.class); float low = range.a() == null ? -Float.MAX_VALUE : range.a(); float high = range.b() == null ? Float.MAX_VALUE : range.b(); return new dev.jorel.commandapi.wrappers.FloatRange(low, high); } @Override public FunctionWrapper[] getFunction(CommandContext cmdCtx, String str) throws CommandSyntaxException { Collection<CustomFunction> customFuncList = ArgumentTag.a(cmdCtx, str); FunctionWrapper[] result = new FunctionWrapper[customFuncList.size()]; CustomFunctionData customFunctionData = getCLW(cmdCtx).getServer().getFunctionData(); CommandListenerWrapper commandListenerWrapper = getCLW(cmdCtx).a().b(2); int count = 0; for(CustomFunction customFunction : customFuncList) { @SuppressWarnings("deprecation") NamespacedKey minecraftKey = new NamespacedKey(customFunction.a().b(), customFunction.a().getKey()); ToIntBiFunction<CustomFunction, CommandListenerWrapper> obj = customFunctionData::a; FunctionWrapper wrapper = new FunctionWrapper(minecraftKey, obj, customFunction, commandListenerWrapper, e -> getCLW(cmdCtx).a(((CraftEntity) e).getHandle())); result[count] = wrapper; count++; } return result; } @Override public dev.jorel.commandapi.wrappers.IntegerRange getIntRange(CommandContext cmdCtx, String key) { IntegerRange range = ArgumentCriterionValue.b.a(cmdCtx, key); int low = range.a() == null ? Integer.MIN_VALUE : range.a(); int high = range.b() == null ? Integer.MAX_VALUE : range.b(); return new dev.jorel.commandapi.wrappers.IntegerRange(low, high); } @Override public ItemStack getItemStack(CommandContext cmdCtx, String str) throws CommandSyntaxException { return CraftItemStack.asBukkitCopy(ArgumentItemStack.a(cmdCtx, str).a(1, false)); } @Override public Location getLocation(CommandContext cmdCtx, String str, LocationType locationType, CommandSender sender) throws CommandSyntaxException { switch (locationType) { case BLOCK_POSITION: BlockPosition blockPos = ArgumentPosition.a(cmdCtx, str); return new Location(getCommandSenderWorld(sender), blockPos.getX(), blockPos.getY(), blockPos.getZ()); case PRECISE_POSITION: Vec3D vecPos = ArgumentVec3.a(cmdCtx, str); return new Location(getCommandSenderWorld(sender), vecPos.x, vecPos.y, vecPos.z); } return null; } @Override public Location2D getLocation2D(CommandContext cmdCtx, String key, LocationType locationType2d, CommandSender sender) throws CommandSyntaxException { switch (locationType2d) { case BLOCK_POSITION: BlockPosition2D blockPos = ArgumentVec2I.a(cmdCtx, key); return new Location2D(getCommandSenderWorld(sender), blockPos.a, blockPos.b); case PRECISE_POSITION: Vec2F vecPos = ArgumentVec2.a(cmdCtx, key); return new Location2D(getCommandSenderWorld(sender), vecPos.i, vecPos.j); } return null; } @SuppressWarnings("deprecation") @Override public LootTable getLootTable(CommandContext cmdCtx, String str) { MinecraftKey minecraftKey = ArgumentMinecraftKeyRegistered.c(cmdCtx, str); String namespace = minecraftKey.b(); String key = minecraftKey.getKey(); net.minecraft.server.v1_14_R1.LootTable lootTable = getCLW(cmdCtx).getServer().getLootTableRegistry().getLootTable(minecraftKey); return new CraftLootTable(new NamespacedKey(namespace, key), lootTable); } @Override public String getObjective(CommandContext cmdCtx, String key, CommandSender sender) throws IllegalArgumentException, CommandSyntaxException { return ArgumentScoreboardObjective.a(cmdCtx, key).getName(); } @Override public String getObjectiveCriteria(CommandContext cmdCtx, String key) { return ArgumentScoreboardCriteria.a(cmdCtx, key).getName(); } @Override public Particle getParticle(CommandContext cmdCtx, String str) { return CraftParticle.toBukkit(ArgumentParticle.a(cmdCtx, str)); } @Override public Player getPlayer(CommandContext cmdCtx, String str) throws CommandSyntaxException { Player target = Bukkit.getPlayer(((GameProfile) ArgumentProfile.a(cmdCtx, str).iterator().next()).getId()); if (target == null) { throw ArgumentProfile.a.create(); } else { return target; } } @Override public PotionEffectType getPotionEffect(CommandContext cmdCtx, String str) throws CommandSyntaxException { return new CraftPotionEffectType(ArgumentMobEffect.a(cmdCtx, str)); } @Override public Recipe getRecipe(CommandContext cmdCtx, String key) throws CommandSyntaxException { return ArgumentMinecraftKeyRegistered.b(cmdCtx, key).toBukkitRecipe(); } @Override public Rotation getRotation(CommandContext cmdCtx, String key) { IVectorPosition pos = ArgumentRotation.a(cmdCtx, key); Vec2F vec = pos.b(getCLW(cmdCtx)); return new Rotation(vec.i, vec.j); } @Override public ScoreboardSlot getScoreboardSlot(CommandContext cmdCtx, String key) { return new ScoreboardSlot(ArgumentScoreboardSlot.a(cmdCtx, key)); } @Override public CommandSender getSenderForCommand(CommandContext cmdCtx) { CommandSender sender = getCLW(cmdCtx).getBukkitSender(); Entity proxyEntity = getCLW(cmdCtx).getEntity(); if (proxyEntity != null) { CommandSender proxy = proxyEntity.getBukkitEntity(); if (!proxy.equals(sender)) { sender = new ProxiedNativeCommandSender(getCLW(cmdCtx), sender, proxy); } } return sender; } @Override public SimpleCommandMap getSimpleCommandMap() { return ((CraftServer) Bukkit.getServer()).getCommandMap(); } @Override public Sound getSound(CommandContext cmdCtx, String key) { MinecraftKey minecraftKey = ArgumentMinecraftKeyRegistered.c(cmdCtx, key); for(CraftSound sound : CraftSound.values()) { try { if(CommandAPIHandler.getField(CraftSound.class, "minecraftKey").get(sound).equals(minecraftKey.getKey())) { return Sound.valueOf(sound.name()); } } catch (IllegalArgumentException | IllegalAccessException e1) { e1.printStackTrace(); } } return null; } @Override public SuggestionProvider getSuggestionProvider(SuggestionProviders provider) { switch (provider) { case FUNCTION: return (context, builder) -> { CustomFunctionData functionData = getCLW(context).getServer().getFunctionData(); ICompletionProvider.a(functionData.h().a(), builder, "#"); return ICompletionProvider.a(functionData.c().keySet(), builder); }; case RECIPES: return CompletionProviders.b; case SOUNDS: return CompletionProviders.c; case ADVANCEMENTS: return (cmdCtx, builder) -> { Collection<Advancement> advancements = ((CommandListenerWrapper) cmdCtx.getSource()).getServer().getAdvancementData().a(); return ICompletionProvider.a(advancements.stream().map(Advancement::getName), builder); }; case LOOT_TABLES: return (context, builder) -> { LootTableRegistry lootTables = getCLW(context).getServer().getLootTableRegistry(); return ICompletionProvider.a(lootTables.a(), builder); }; case ENTITIES: return CompletionProviders.d; case BIOMES: default: return (context, builder) -> Suggestions.empty(); } } @Override public String getTeam(CommandContext cmdCtx, String key, CommandSender sender) throws CommandSyntaxException { return ArgumentScoreboardTeam.a(cmdCtx, key).getName(); } @Override public int getTime(CommandContext<?> cmdCtx, String key) { return cmdCtx.getArgument(key, Integer.class); } @Override public boolean isVanillaCommandWrapper(Command command) { return command instanceof VanillaCommandWrapper; } @Override public void resendPackets(Player player) { CraftPlayer craftPlayer = (CraftPlayer) player; CraftServer craftServer = (CraftServer) Bukkit.getServer(); @SuppressWarnings("resource") net.minecraft.server.v1_14_R1.CommandDispatcher nmsDispatcher = craftServer.getServer().commandDispatcher; nmsDispatcher.a(craftPlayer.getHandle()); } @Override public ArgumentType<?> _ArgumentScoreholder(boolean single) { return single ? ArgumentScoreholder.a() : ArgumentScoreholder.b(); } @Override public Collection<String> getScoreHolderMultiple(CommandContext cmdCtx, String key) throws CommandSyntaxException { return ArgumentScoreholder.b(cmdCtx, key); } @Override public String getScoreHolderSingle(CommandContext cmdCtx, String key) throws CommandSyntaxException { return ArgumentScoreholder.a(cmdCtx, key); } @Override public NBTContainer getNBTCompound(CommandContext<?> cmdCtx, String key) { return new NBTContainer(ArgumentNBTTag.a(cmdCtx, key)); } @Override public ArgumentType<?> _ArgumentNBTCompound() { return ArgumentNBTTag.a(); } @Override public ArgumentType<?> _ArgumentMathOperation() { return ArgumentMathOperation.a(); } @Override public MathOperation getMathOperation(CommandContext cmdCtx, String key) throws CommandSyntaxException { ArgumentMathOperation.a result = ArgumentMathOperation.a(cmdCtx, key); net.minecraft.server.v1_14_R1.Scoreboard board = new net.minecraft.server.v1_14_R1.Scoreboard(); ScoreboardScore tester_left = new ScoreboardScore(board, null, null); ScoreboardScore tester_right = new ScoreboardScore(board, null, null); tester_left.setScore(6); tester_right.setScore(2); result.apply(tester_left, tester_right); switch (tester_left.getScore()) { case 8: return MathOperation.ADD; case 4: return MathOperation.SUBTRACT; case 12: return MathOperation.MULTIPLY; case 3: return MathOperation.DIVIDE; case 0: return MathOperation.MOD; case 6: return MathOperation.MAX; case 2: { if (tester_right.getScore() == 6) return MathOperation.SWAP; tester_left.setScore(2); tester_right.setScore(6); result.apply(tester_left, tester_right); if (tester_left.getScore() == 2) return MathOperation.MIN; return MathOperation.ASSIGN; } } return null; } @Override public Biome getBiome(CommandContext cmdCtx, String key) { throw new BiomeArgumentException(); } }