Skip to content

Commit

Permalink
Add 1.20 support for registering commands during server runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
willkroboth committed Jul 26, 2023
1 parent f0643d4 commit 06e9c21
Show file tree
Hide file tree
Showing 3 changed files with 117 additions and 148 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -20,56 +20,6 @@
*******************************************************************************/
package dev.jorel.commandapi.nms;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;

import dev.jorel.commandapi.CommandAPIHandler;
import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.Particle;
import org.bukkit.Particle.DustOptions;
import org.bukkit.Particle.DustTransition;
import org.bukkit.Vibration;
import org.bukkit.Vibration.Destination;
import org.bukkit.Vibration.Destination.BlockDestination;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.craftbukkit.v1_20_R1.CraftLootTable;
import org.bukkit.craftbukkit.v1_20_R1.CraftParticle;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.CraftSound;
import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R1.command.VanillaCommandWrapper;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.help.CustomHelpTopic;
import org.bukkit.craftbukkit.v1_20_R1.help.SimpleHelpMap;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.help.HelpTopic;
import org.bukkit.inventory.Recipe;
import org.bukkit.potion.PotionEffectType;

import com.google.common.collect.ImmutableList;
import com.google.common.io.Files;
import com.google.gson.GsonBuilder;
Expand All @@ -80,9 +30,10 @@
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.SuggestionProvider;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.logging.LogUtils;

import dev.jorel.commandapi.CommandAPI;
import dev.jorel.commandapi.CommandAPIHandler;
import dev.jorel.commandapi.SafeVarHandle;
import dev.jorel.commandapi.arguments.ArgumentSubType;
import dev.jorel.commandapi.arguments.SuggestionProviders;
Expand All @@ -92,12 +43,7 @@
import dev.jorel.commandapi.preprocessor.Differs;
import dev.jorel.commandapi.preprocessor.NMSMeta;
import dev.jorel.commandapi.preprocessor.RequireField;
import dev.jorel.commandapi.wrappers.ComplexRecipeImpl;
import dev.jorel.commandapi.wrappers.FunctionWrapper;
import dev.jorel.commandapi.wrappers.Location2D;
import dev.jorel.commandapi.wrappers.NativeProxyCommandSender;
import dev.jorel.commandapi.wrappers.ParticleData;
import dev.jorel.commandapi.wrappers.SimpleFunctionWrapper;
import dev.jorel.commandapi.wrappers.*;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
Expand All @@ -106,13 +52,7 @@
import net.minecraft.commands.CommandFunction.Entry;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.commands.SharedSuggestionProvider;
import net.minecraft.commands.arguments.ColorArgument;
import net.minecraft.commands.arguments.ComponentArgument;
import net.minecraft.commands.arguments.DimensionArgument;
import net.minecraft.commands.arguments.EntityArgument;
import net.minecraft.commands.arguments.ParticleArgument;
import net.minecraft.commands.arguments.ResourceArgument;
import net.minecraft.commands.arguments.ResourceLocationArgument;
import net.minecraft.commands.arguments.*;
import net.minecraft.commands.arguments.blocks.BlockPredicateArgument;
import net.minecraft.commands.arguments.blocks.BlockStateArgument;
import net.minecraft.commands.arguments.coordinates.BlockPosArgument;
Expand All @@ -127,15 +67,7 @@
import net.minecraft.commands.synchronization.ArgumentUtils;
import net.minecraft.core.BlockPos;
import net.minecraft.core.RegistryAccess.Frozen;
import net.minecraft.core.particles.BlockParticleOption;
import net.minecraft.core.particles.DustColorTransitionOptions;
import net.minecraft.core.particles.DustParticleOptions;
import net.minecraft.core.particles.ItemParticleOption;
import net.minecraft.core.particles.ParticleOptions;
import net.minecraft.core.particles.SculkChargeParticleOptions;
import net.minecraft.core.particles.ShriekParticleOption;
import net.minecraft.core.particles.SimpleParticleType;
import net.minecraft.core.particles.VibrationParticleOption;
import net.minecraft.core.particles.*;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.core.registries.Registries;
import net.minecraft.nbt.CompoundTag;
Expand Down Expand Up @@ -165,6 +97,44 @@
import net.minecraft.world.level.storage.loot.LootDataType;
import net.minecraft.world.phys.Vec2;
import net.minecraft.world.phys.Vec3;
import org.bukkit.*;
import org.bukkit.Particle.DustOptions;
import org.bukkit.Particle.DustTransition;
import org.bukkit.Vibration.Destination;
import org.bukkit.Vibration.Destination.BlockDestination;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.craftbukkit.v1_20_R1.CraftLootTable;
import org.bukkit.craftbukkit.v1_20_R1.CraftParticle;
import org.bukkit.craftbukkit.v1_20_R1.CraftServer;
import org.bukkit.craftbukkit.v1_20_R1.CraftSound;
import org.bukkit.craftbukkit.v1_20_R1.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R1.command.VanillaCommandWrapper;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.help.CustomHelpTopic;
import org.bukkit.craftbukkit.v1_20_R1.help.SimpleHelpMap;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.help.HelpTopic;
import org.bukkit.inventory.Recipe;
import org.bukkit.potion.PotionEffectType;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;

// Mojang-Mapped reflection
/**
Expand Down Expand Up @@ -253,10 +223,8 @@ public final ArgumentType<?> _ArgumentSyntheticBiome() {
}

@Override
public final void addToHelpMap(Map<String, HelpTopic> helpTopicsToAdd) {
// We have to use VarHandles to use helpTopics.put (instead of .addTopic)
// because we're updating an existing help topic, not adding a new help topic
helpMapTopics.get((SimpleHelpMap) Bukkit.getServer().getHelpMap()).putAll(helpTopicsToAdd);
public final Map<String, HelpTopic> getHelpMap() {
return helpMapTopics.get((SimpleHelpMap) Bukkit.getHelpMap());
}

@Override
Expand Down Expand Up @@ -339,8 +307,8 @@ public final BlockData getBlockState(CommandContext<CommandSourceStack> cmdCtx,
}

@Override
public final com.mojang.brigadier.CommandDispatcher<CommandSourceStack> getBrigadierDispatcher() {
return this.<MinecraftServer>getMinecraftServer().vanillaCommandDispatcher.getDispatcher();
public final CommandDispatcher<CommandSourceStack> getResourcesDispatcher() {
return this.<MinecraftServer>getMinecraftServer().getCommands().getDispatcher();
}

@Override
Expand Down Expand Up @@ -650,6 +618,11 @@ public final boolean isVanillaCommandWrapper(Command command) {
return command instanceof VanillaCommandWrapper;
}

@Override
public Command wrapToVanillaCommandWrapper(LiteralCommandNode<CommandSourceStack> node) {
return new VanillaCommandWrapper(this.<MinecraftServer>getMinecraftServer().vanillaCommandDispatcher, node);
}

@Override
public final void reloadDataPacks() {
CommandAPI.logNormal("Reloading datapacks...");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@
@SuppressWarnings({ "unchecked", "rawtypes" })
public abstract class ArgumentNMS extends MockPlatform<CommandSourceStack> {

CommandAPIBukkit<?> baseNMS;
CommandAPIBukkit<CommandSourceStack> baseNMS;

protected ArgumentNMS(CommandAPIBukkit<?> baseNMS) {
this.baseNMS = baseNMS;
this.baseNMS = (CommandAPIBukkit<CommandSourceStack>) baseNMS;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,58 +1,17 @@
package dev.jorel.commandapi.test;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;

import java.io.File;
import java.io.IOException;
import java.security.CodeSource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import org.bukkit.Bukkit;
import org.bukkit.Color;
import org.bukkit.Location;
import org.bukkit.NamespacedKey;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.craftbukkit.v1_20_R1.CraftParticle;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemFactory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.help.HelpTopic;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scoreboard.Team;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mockito.Mockito;

import com.google.common.collect.Streams;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.CommandDispatcher;

import be.seeseemelk.mockbukkit.ServerMock;
import be.seeseemelk.mockbukkit.WorldMock;
import be.seeseemelk.mockbukkit.enchantments.EnchantmentMock;
import be.seeseemelk.mockbukkit.help.HelpMapMock;
import be.seeseemelk.mockbukkit.potion.MockPotionEffectType;
import com.google.common.collect.Streams;
import com.mojang.authlib.GameProfile;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.tree.LiteralCommandNode;
import dev.jorel.commandapi.Brigadier;
import dev.jorel.commandapi.CommandAPIBukkit;
import dev.jorel.commandapi.SafeVarHandle;
import dev.jorel.commandapi.commandsenders.AbstractCommandSender;
import dev.jorel.commandapi.commandsenders.BukkitCommandSender;
import dev.jorel.commandapi.commandsenders.BukkitPlayer;
Expand All @@ -66,12 +25,7 @@
import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.Bootstrap;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.ServerAdvancementManager;
import net.minecraft.server.ServerFunctionLibrary;
import net.minecraft.server.ServerFunctionManager;
import net.minecraft.server.ServerScoreboard;
import net.minecraft.server.*;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.players.GameProfileCache;
Expand All @@ -90,8 +44,37 @@
import net.minecraft.world.scores.PlayerTeam;
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
import net.minecraft.world.scores.criteria.ObjectiveCriteria.RenderType;
import org.bukkit.*;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.craftbukkit.v1_20_R1.CraftParticle;
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemFactory;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.help.HelpTopic;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scoreboard.Team;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.mockito.Mockito;

import java.io.File;
import java.io.IOException;
import java.security.CodeSource;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

import static org.mockito.ArgumentMatchers.*;

public class MockNMS extends Enums {
private static final SafeVarHandle<HelpMapMock, Map<String, HelpTopic>> helpMapTopics =
SafeVarHandle.ofOrNull(HelpMapMock.class, "topics", "topics", Map.class);

static {
CodeSource src = PotionEffectType.class.getProtectionDomain().getCodeSource();
Expand All @@ -113,7 +96,7 @@ public MockNMS(CommandAPIBukkit<?> baseNMS) {
super(baseNMS);

// Stub in our getMinecraftServer implementation
CommandAPIBukkit<?> nms = Mockito.spy(super.baseNMS);
CommandAPIBukkit<CommandSourceStack> nms = Mockito.spy(super.baseNMS);
Mockito.when(nms.getMinecraftServer()).thenAnswer(i -> getMinecraftServer());
super.baseNMS = nms;

Expand All @@ -140,6 +123,18 @@ public MockNMS(CommandAPIBukkit<?> baseNMS) {
this.recipeManager = new RecipeManager();
this.functions = new HashMap<>();
registerDefaultRecipes();

// Setup playerListMock
playerListMock = Mockito.mock(PlayerList.class);
Mockito.when(playerListMock.getPlayerByName(anyString())).thenAnswer(invocation -> {
String playerName = invocation.getArgument(0);
for (ServerPlayer onlinePlayer : players) {
if (onlinePlayer.getBukkitEntity().getName().equals(playerName)) {
return onlinePlayer;
}
}
return null;
});
}

/*************************
Expand Down Expand Up @@ -256,6 +251,16 @@ public SimpleCommandMap getSimpleCommandMap() {
return ((ServerMock) Bukkit.getServer()).getCommandMap();
}

@Override
public boolean isVanillaCommandWrapper(Command command) {
return baseNMS.isVanillaCommandWrapper(command);
}

@Override
public Command wrapToVanillaCommandWrapper(LiteralCommandNode<CommandSourceStack> node) {
return baseNMS.wrapToVanillaCommandWrapper(node);
}

@SuppressWarnings({ "deprecation", "unchecked" })
@Override
public CommandSourceStack getBrigadierSourceFromCommandSender(AbstractCommandSender<? extends CommandSender> senderWrapper) {
Expand Down Expand Up @@ -301,19 +306,6 @@ public CommandSourceStack getBrigadierSourceFromCommandSender(AbstractCommandSen
players.add(entityPlayerMock);
}

if (playerListMock == null) {
playerListMock = Mockito.mock(PlayerList.class);
Mockito.when(playerListMock.getPlayerByName(anyString())).thenAnswer(invocation -> {
String playerName = invocation.getArgument(0);
for (ServerPlayer onlinePlayer : players) {
if (onlinePlayer.getBukkitEntity().getName().equals(playerName)) {
return onlinePlayer;
}
}
return null;
});
}

// CommandSourceStack#levels
Mockito.when(css.levels()).thenAnswer(invocation -> {
Set<ResourceKey<Level>> set = new HashSet<>();
Expand Down Expand Up @@ -808,4 +800,8 @@ public HelpTopic generateHelpTopic(String commandName, String shortDescription,
return baseNMS.generateHelpTopic(commandName, shortDescription, fullDescription, permission);
}

@Override
public Map<String, HelpTopic> getHelpMap() {
return helpMapTopics.get((HelpMapMock) Bukkit.getHelpMap());
}
}

0 comments on commit 06e9c21

Please sign in to comment.