Merged some modules to fix future dependency issues

This commit is contained in:
2022-12-24 11:33:54 +01:00
parent 6564beb3a0
commit 0756781b26
80 changed files with 50 additions and 224 deletions

View File

@@ -41,6 +41,12 @@
</exclusions>
</dependency>
<dependency>
<groupId>fr.pandacube.lib</groupId>
<artifactId>pandalib-commands</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>fr.pandacube.lib</groupId>
<artifactId>pandalib-reflect</artifactId>
@@ -65,6 +71,13 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>fr.pandacube.lib</groupId>
<artifactId>pandalib-paper-permissions</artifactId>
<version>${project.version}</version>
<scope>provided</scope>
</dependency>
<!-- Paper -->
<dependency>
<groupId>io.papermc.paper</groupId>
@@ -76,6 +89,26 @@
<artifactId>paper-mojangapi</artifactId>
<version>${paper.version}-SNAPSHOT</version>
</dependency>
<!-- Needed to read obfuscation mapping file. Already included in Paper -->
<dependency>
<groupId>net.fabricmc</groupId>
<artifactId>mapping-io</artifactId>
<version>0.3.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<excludePackageNames>fr.pandacube.lib.paper.reflect.wrapper.*</excludePackageNames>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,669 @@
package fr.pandacube.lib.paper.commands;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
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.tree.CommandNode;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.mojang.brigadier.tree.RootCommandNode;
import fr.pandacube.lib.chat.Chat;
import fr.pandacube.lib.commands.BrigadierCommand;
import fr.pandacube.lib.commands.SuggestionsSupplier;
import fr.pandacube.lib.paper.permissions.PandalibPaperPermissions;
import fr.pandacube.lib.paper.reflect.PandalibPaperReflect;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftServer;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftVector;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.VanillaCommandWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.BlockPosArgument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Commands;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.ComponentArgument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Coordinates;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.EntityArgument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.EntitySelector;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Vec3Argument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.BlockPos;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerPlayer;
import fr.pandacube.lib.paper.reflect.wrapper.paper.PaperAdventure;
import fr.pandacube.lib.players.standalone.AbstractOffPlayer;
import fr.pandacube.lib.players.standalone.AbstractOnlinePlayer;
import fr.pandacube.lib.players.standalone.AbstractPlayerManager;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.util.Log;
import net.kyori.adventure.text.Component;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.Command;
import org.bukkit.command.CommandMap;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerCommandSendEvent;
import org.bukkit.event.server.ServerLoadEvent;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.BlockVector;
import org.bukkit.util.Vector;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* Abstract class to hold a command to be integrated into a Paper server vanilla command dispatcher.
*/
public abstract class PaperBrigadierCommand extends BrigadierCommand<BukkitBrigadierCommandSource> implements Listener {
private static final Commands vanillaCommandDispatcher;
private static final CommandDispatcher<BukkitBrigadierCommandSource> nmsDispatcher;
static {
PandalibPaperReflect.init();
vanillaCommandDispatcher = ReflectWrapper.wrapTyped(Bukkit.getServer(), CraftServer.class)
.getServer()
.vanillaCommandDispatcher();
nmsDispatcher = vanillaCommandDispatcher.dispatcher();
}
/**
* Removes a plugin command that overrides a vanilla command, so the vanilla command functionnalities are fully
* restored (so, not only the usage, but also the suggestions and the command structure sent to the client).
* @param name the name of the command to restore.
*/
public static void restoreVanillaCommand(String name) {
CommandMap bukkitCmdMap = Bukkit.getCommandMap();
Command bukkitCommand = bukkitCmdMap.getCommand(name);
if (bukkitCommand != null) {
if (VanillaCommandWrapper.REFLECT.get().isInstance(bukkitCommand)) {
//Log.info("Command /" + name + " is already a vanilla command.");
return;
}
Log.info("Removing Bukkit command /" + name + " (" + getCommandIdentity(bukkitCommand) + ")");
bukkitCmdMap.getKnownCommands().remove(name.toLowerCase(java.util.Locale.ENGLISH));
bukkitCommand.unregister(bukkitCmdMap);
LiteralCommandNode<BukkitBrigadierCommandSource> node = (LiteralCommandNode<BukkitBrigadierCommandSource>) getRootNode().getChild(name);
Command newCommand = new VanillaCommandWrapper(vanillaCommandDispatcher, node).__getRuntimeInstance();
bukkitCmdMap.getKnownCommands().put(name.toLowerCase(), newCommand);
newCommand.register(bukkitCmdMap);
}
}
/**
* Returns the vanilla instance of the Brigadier dispatcher.
* @return the vanilla instance of the Brigadier dispatcher.
*/
public static CommandDispatcher<BukkitBrigadierCommandSource> getNMSDispatcher() {
return nmsDispatcher;
}
/**
* Returns the root command node of the Brigadier dispatcher.
* @return the root command node of the Brigadier dispatcher.
*/
protected static RootCommandNode<BukkitBrigadierCommandSource> getRootNode() {
return nmsDispatcher.getRoot();
}
private final Plugin plugin;
/**
* The command node of this command.
*/
protected final LiteralCommandNode<BukkitBrigadierCommandSource> commandNode;
private final RegistrationPolicy registrationPolicy;
private Set<String> registeredAliases;
/**
* Instanciate this command instance.
*
* @param pl the plugin instance.
* @param regPolicy the registration policy for this command.
*/
public PaperBrigadierCommand(Plugin pl, RegistrationPolicy regPolicy) {
plugin = pl;
registrationPolicy = regPolicy;
commandNode = buildCommand().build();
postBuildCommand(commandNode);
register();
Bukkit.getPluginManager().registerEvents(this, plugin);
try {
PandalibPaperPermissions.addPermissionMapping("minecraft.command." + commandNode.getLiteral().toLowerCase(), getTargetPermission().toLowerCase());
} catch (NoClassDefFoundError ignored) { }
}
/**
* Instanciate this command isntance with a registration policy of {@link RegistrationPolicy#ONLY_BASE_COMMAND}.
* @param pl the plugin instance.
*/
public PaperBrigadierCommand(Plugin pl) {
this(pl, RegistrationPolicy.ONLY_BASE_COMMAND);
}
private void register() {
String[] aliases = getAliases();
if (aliases == null)
aliases = new String[0];
String pluginName = plugin.getName().toLowerCase();
registeredAliases = new HashSet<>();
registerNode(commandNode, false);
registerAlias(pluginName + ":" + commandNode.getLiteral(), true);
for (String alias : aliases) {
registerAlias(alias, false);
registerAlias(pluginName + ":" + alias, true);
}
}
private void registerAlias(String alias, boolean prefixed) {
LiteralCommandNode<BukkitBrigadierCommandSource> node = literal(alias)
.requires(commandNode.getRequirement())
.executes(commandNode.getCommand())
.redirect(commandNode)
.build();
registerNode(node, prefixed);
}
private void registerNode(LiteralCommandNode<BukkitBrigadierCommandSource> node, boolean prefixed) {
RootCommandNode<BukkitBrigadierCommandSource> root = getRootNode();
String name = node.getLiteral();
boolean isAlias = node.getRedirect() == commandNode;
boolean forceRegistration = switch (registrationPolicy) {
case NONE -> false;
case ONLY_BASE_COMMAND -> prefixed || !isAlias;
case ALL -> true;
};
// nmsDispatcher integration and conflit resolution
boolean nmsRegister = false, nmsRegistered = false;
CommandNode<BukkitBrigadierCommandSource> nmsConflited = root.getChild(name);
if (nmsConflited != null) {
if (isFromThisCommand(nmsConflited)) {
// this command is already registered in NMS. Dont need to register again
nmsRegistered = true;
}
else if (forceRegistration) {
nmsRegister = true;
Log.info("Overwriting Brigadier command /" + name);
}
else if (prefixed || !isAlias) {
Log.severe("/" + name + " already in NMS Brigadier instance."
+ " Wont replace it because registration is not forced for prefixed or initial name of a command.");
}
else { // conflict, wont replace, not forced but only an alias anyway
Log.info("/" + name + " already in NMS Brigadier instance."
+ " Wont replace it because registration is not forced for a non-prefixed alias.");
}
}
else {
nmsRegister = true;
}
if (nmsRegister) {
@SuppressWarnings("unchecked")
var rCommandNode = ReflectWrapper.wrapTyped(root, fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode.class);
rCommandNode.removeCommand(name);
root.addChild(node);
nmsRegistered = true;
}
if (!nmsRegistered) {
return;
}
registeredAliases.add(name);
// bukkit dispatcher conflict resolution
boolean bukkitRegister = false;
CommandMap bukkitCmdMap = Bukkit.getCommandMap();
Command bukkitConflicted = bukkitCmdMap.getCommand(name);
if (bukkitConflicted != null) {
if (!isFromThisCommand(bukkitConflicted)) {
if (forceRegistration) {
bukkitRegister = true;
Log.info("Overwriting Bukkit command /" + name
+ " (" + getCommandIdentity(bukkitConflicted) + ")");
}
else if (prefixed || !isAlias) {
Log.severe("/" + name + " already in Bukkit dispatcher (" + getCommandIdentity(bukkitConflicted) + ")." +
" Wont replace it because registration is not forced for prefixed or initial name of a command.");
}
else {
Log.info("/" + name + " already in Bukkit dispatcher (" + getCommandIdentity(bukkitConflicted) + ")." +
" Wont replace it because registration is not forced for a non-prefixed alias.");
}
}
}
else {
bukkitRegister = true;
}
if (bukkitRegister) {
bukkitCmdMap.getKnownCommands().remove(name.toLowerCase());
if (bukkitConflicted != null)
bukkitConflicted.unregister(bukkitCmdMap);
Command newCommand = new VanillaCommandWrapper(vanillaCommandDispatcher, node).__getRuntimeInstance();
bukkitCmdMap.getKnownCommands().put(name.toLowerCase(), newCommand);
newCommand.register(bukkitCmdMap);
}
}
private boolean isFromThisCommand(CommandNode<BukkitBrigadierCommandSource> node) {
return node == commandNode || node.getRedirect() == commandNode;
}
private boolean isFromThisCommand(Command bukkitCmd) {
if (VanillaCommandWrapper.REFLECT.get().isInstance(bukkitCmd)) {
return isFromThisCommand(ReflectWrapper.wrapTyped((BukkitCommand) bukkitCmd, VanillaCommandWrapper.class).vanillaCommand());
}
return false;
}
private static String getCommandIdentity(Command bukkitCmd) {
if (bukkitCmd instanceof PluginCommand cmd) {
return "Bukkit command: /" + cmd.getName() + " from plugin " + cmd.getPlugin().getName();
}
else if (VanillaCommandWrapper.REFLECT.get().isInstance(bukkitCmd)) {
return "Vanilla command: /" + bukkitCmd.getName();
}
else
return bukkitCmd.getClass().getName() + ": /" + bukkitCmd.getName();
}
/**
* Player command sender event handler.
* @param event the event.
*/
@EventHandler
public void onPlayerCommandSend(PlayerCommandSendEvent event) {
event.getCommands().removeAll(registeredAliases.stream().map(s -> "minecraft:" + s).toList());
}
/**
* Server load event handler.
* @param event the event.
*/
@EventHandler
public void onServerLoad(ServerLoadEvent event) {
register();
}
/**
* Returns the permission that should be tested instead of "minecraft.command.cmdName". The conversion from the
* minecraft prefixed permission node to the returned node is done by the {@code pandalib-paper-permissions} if it
* is present in the classpath during runtime.
* @return the permission that should be tested instead of "minecraft.command.cmdName".
*/
protected abstract String getTargetPermission();
public boolean isConsole(BukkitBrigadierCommandSource wrapper) {
return isConsole(getCommandSender(wrapper));
}
public boolean isPlayer(BukkitBrigadierCommandSource wrapper) {
return isPlayer(getCommandSender(wrapper));
}
public Predicate<BukkitBrigadierCommandSource> hasPermission(String permission) {
return wrapper -> getCommandSender(wrapper).hasPermission(permission);
}
/**
* Tells if the provided command sender is the console.
* @param sender the sender to test if its the console or not.
* @return true if the sender is the console, false otherwise.
*/
public boolean isConsole(CommandSender sender) {
return sender instanceof ConsoleCommandSender;
}
/**
* Tells if the provided command sender is a player.
* @param sender the sender to test if its a player or not.
* @return true if the sender is a player, false otherwise.
*/
public boolean isPlayer(CommandSender sender) {
return sender instanceof Player;
}
/**
* Gets the Bukkit command sender from the provided context.
* @param context the command context from which to get the Bukkit command sender.
* @return the Bukkit command sender.
*/
public static CommandSender getCommandSender(CommandContext<BukkitBrigadierCommandSource> context) {
return getCommandSender(context.getSource());
}
/**
* Gets the Bukkit command sender from the provided wrapper.
* @param wrapper the wrapper from which to get the Bukkit command sender.
* @return the Bukkit command sender.
*/
public static CommandSender getCommandSender(BukkitBrigadierCommandSource wrapper) {
return wrapper.getBukkitSender();
}
/**
* Gets a new instance of a command sender wrapper for the provided command sender.
* @param sender the command sender.
* @return a new instance of a command sender wrapper for the provided command sender.
*/
public static BukkitBrigadierCommandSource getBrigadierCommandSource(CommandSender sender) {
return VanillaCommandWrapper.getListener(sender);
}
/**
* A suggestions supplier that suggests the names of the currently connected players (that the command sender can see).
*/
public static final SuggestionsSupplier<CommandSender> TAB_PLAYER_CURRENT_SERVER = (sender, ti, token, a) -> {
@SuppressWarnings("unchecked")
AbstractPlayerManager<AbstractOnlinePlayer, AbstractOffPlayer> pm = (AbstractPlayerManager<AbstractOnlinePlayer, AbstractOffPlayer>) AbstractPlayerManager.getInstance();
Stream<String> plStream;
if (pm == null)
plStream = Bukkit.getOnlinePlayers().stream().filter(p -> !(sender instanceof Player senderP) || senderP.canSee(p)).map(Player::getName);
else
plStream = pm.getNamesOnlyVisible(sender instanceof Player senderP ? pm.getOffline(senderP.getUniqueId()) : null).stream();
return SuggestionsSupplier.collectFilteredStream(plStream, token);
};
/**
* A suggestions supplier that suggests the names of the worlds currently loaded on this server.
*/
public static final SuggestionsSupplier<CommandSender> TAB_WORLDS = SuggestionsSupplier.fromStreamSupplier(() -> Bukkit.getWorlds().stream().map(World::getName));
/**
* Wraps the provided {@link SuggestionsSupplier} into a Brigadiers {@link SuggestionProvider}.
* @param suggestions the suggestions to wrap.
* @return a {@link SuggestionProvider} generating the suggestions from the provided {@link SuggestionsSupplier}.
*/
protected SuggestionProvider<BukkitBrigadierCommandSource> wrapSuggestions(SuggestionsSupplier<CommandSender> suggestions) {
return wrapSuggestions(suggestions, PaperBrigadierCommand::getCommandSender);
}
/**
* Wraps the provided brigadier command executor in another one that logs eventual throw exceptions and informs the
* player.
* The default behaviour of the vanilla instance of the Brigadier dispatcher is to ignore any unchecked exception
* thrown by a command executor.
* @param cmd the command executor to wrap.
* @return a wrapper command executor.
*/
protected static com.mojang.brigadier.Command<BukkitBrigadierCommandSource> wrapCommand(com.mojang.brigadier.Command<BukkitBrigadierCommandSource> cmd) {
return context -> {
try {
return cmd.run(context);
} catch(CommandSyntaxException e) {
throw e;
} catch (Throwable t) {
Log.severe(t);
getCommandSender(context).sendMessage(Chat.failureText("Error while executing the command: " + t));
return 0;
}
};
}
/*
* Minecraft argument type
*/
/**
* Creates a new instance of the Brigadier argument type {@code minecraft:entity}.
* @param singleTarget if this argument takes only a single target.
* @param playersOnly if this argument takes players only.
* @return the {@code minecraft:entity} argument type with the specified parameters.
*/
public static ArgumentType<Object> argumentMinecraftEntity(boolean singleTarget, boolean playersOnly) {
if (playersOnly) {
return singleTarget ? EntityArgument.player() : EntityArgument.players();
}
else {
return singleTarget ? EntityArgument.entity() : EntityArgument.entities();
}
}
/**
* Gets the value of the provided argument of type {@code minecraft:entity} (list of entities), from the provided context.
* @param context the command execution context.
* @param argument the argument name.
* @return the value of the argument, or null if not found.
*/
public List<Entity> tryGetMinecraftEntityArgument(CommandContext<BukkitBrigadierCommandSource> context, String argument) {
EntitySelector es = ReflectWrapper.wrap(tryGetArgument(context, argument, EntitySelector.MAPPING.runtimeClass()), EntitySelector.class);
if (es == null)
return null;
List<fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Entity> nmsEntityList = es.findEntities(context.getSource());
List<Entity> entityList = new ArrayList<>(nmsEntityList.size());
for (fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Entity nmsEntity : nmsEntityList) {
entityList.add(nmsEntity.getBukkitEntity());
}
return entityList;
}
/**
* Gets the value of the provided argument of type {@code minecraft:entity} (list of players), from the provided context.
* @param context the command execution context.
* @param argument the argument name.
* @return the value of the argument, or null if not found.
*/
public List<Player> tryGetMinecraftEntityArgumentPlayers(CommandContext<BukkitBrigadierCommandSource> context, String argument) {
EntitySelector es = ReflectWrapper.wrap(tryGetArgument(context, argument, EntitySelector.MAPPING.runtimeClass()), EntitySelector.class);
if (es == null)
return null;
List<ServerPlayer> nmsPlayerList = es.findPlayers(context.getSource());
List<Player> playerList = new ArrayList<>(nmsPlayerList.size());
for (ServerPlayer nmsPlayer : nmsPlayerList) {
playerList.add(nmsPlayer.getBukkitEntity());
}
return playerList;
}
/**
* Gets the value of the provided argument of type {@code minecraft:entity} (one entity), from the provided context.
* @param context the command execution context.
* @param argument the argument name.
* @return the value of the argument, or null if not found.
*/
public Entity tryGetMinecraftEntityArgumentOneEntity(CommandContext<BukkitBrigadierCommandSource> context, String argument) {
EntitySelector es = ReflectWrapper.wrap(tryGetArgument(context, argument, EntitySelector.MAPPING.runtimeClass()), EntitySelector.class);
if (es == null)
return null;
fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Entity nmsEntity = es.findSingleEntity(context.getSource());
return nmsEntity == null ? null : nmsEntity.getBukkitEntity();
}
/**
* Gets the value of the provided argument of type {@code minecraft:entity} (one player), from the provided context.
* @param context the command execution context.
* @param argument the argument name.
* @return the value of the argument, or null if not found.
*/
public Player tryGetMinecraftEntityArgumentOnePlayer(CommandContext<BukkitBrigadierCommandSource> context, String argument) {
EntitySelector es = ReflectWrapper.wrap(tryGetArgument(context, argument, EntitySelector.MAPPING.runtimeClass()), EntitySelector.class);
if (es == null)
return null;
ServerPlayer nmsPlayer = es.findSinglePlayer(context.getSource());
return nmsPlayer == null ? null : nmsPlayer.getBukkitEntity();
}
/**
* Creates a new instance of the Brigadier argument type {@code minecraft:block_pos}.
* @return the {@code minecraft:block_pos} argument type.
*/
public static ArgumentType<Object> argumentMinecraftBlockPosition() {
return BlockPosArgument.blockPos();
}
/**
* Gets the value of the provided argument of type {@code minecraft:block_pos}, from the provided context.
* @param context the command execution context.
* @param argument the argument name.
* @param deflt a defualt value if the argument is not found.
* @return the value of the argument.
*/
public BlockVector tryGetMinecraftBlockPositionArgument(CommandContext<BukkitBrigadierCommandSource> context,
String argument, BlockVector deflt) {
return tryGetArgument(context, argument, Coordinates.MAPPING.runtimeClass(), nmsCoord -> {
BlockPos bp = ReflectWrapper.wrap(nmsCoord, Coordinates.class).getBlockPos(context.getSource());
return new BlockVector(bp.getX(), bp.getY(), bp.getZ());
}, deflt);
}
/**
* Creates a new instance of the Brigadier argument type {@code minecraft:vec3}.
* @return the {@code minecraft:vec3} argument type.
*/
public static ArgumentType<Object> argumentMinecraftVec3() {
return Vec3Argument.vec3(true);
}
/**
* Gets the value of the provided argument of type {@code minecraft:vec3}, from the provided context.
* @param context the command execution context.
* @param argument the argument name.
* @param deflt a defualt value if the argument is not found.
* @return the value of the argument.
*/
public Vector tryGetMinecraftVec3Argument(CommandContext<BukkitBrigadierCommandSource> context, String argument,
Vector deflt) {
return tryGetArgument(context, argument, Coordinates.MAPPING.runtimeClass(),
nmsCoord -> CraftVector.toBukkit(
ReflectWrapper.wrap(nmsCoord, Coordinates.class).getPosition(context.getSource())
),
deflt);
}
/**
* Creates a new instance of the Brigadier argument type {@code minecraft:component}.
* @return the {@code minecraft:component} argument type.
*/
public static ArgumentType<Object> argumentMinecraftChatComponent() {
return ComponentArgument.textComponent();
}
/**
* Gets the value of the provided argument of type {@code minecraft:component}, from the provided context.
* @param context the command execution context.
* @param argument the argument name.
* @param deflt a defualt value if the argument is not found.
* @return the value of the argument.
*/
public Component tryGetMinecraftChatComponentArgument(CommandContext<BukkitBrigadierCommandSource> context,
String argument, Component deflt) {
return tryGetArgument(context, argument,
fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.chat.Component.MAPPING.runtimeClass(),
nmsComp -> PaperAdventure.asAdventure(
ReflectWrapper.wrap(nmsComp,
fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.chat.Component.class)
),
deflt);
}
/**
* All possible choices on how to force the registration of a command, based on certain conditions.
*/
public enum RegistrationPolicy {
/**
* Do not force to register a command node or an alias if there is already a command with that name in the
* vanilla Brigadier dispatcher.
* Note that all plugin-name-prefixed aliases will be registered anyway.
*/
NONE,
/**
* Force only the base command (but not the aliases) to be registered, even if a command with that name already
* exists in the vanilla Brigadier dispatcher.
*/
ONLY_BASE_COMMAND,
/**
* Force the command and all of its aliases to be registered, even if a command with the same name or alias
* already exists in the vanilla Brigadier dispatcher.
*/
ALL
}
}

View File

@@ -0,0 +1,716 @@
package fr.pandacube.lib.paper.reflect;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import fr.pandacube.lib.util.Log;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectField;
import fr.pandacube.lib.reflect.ReflectMember;
import fr.pandacube.lib.reflect.ReflectMethod;
import net.fabricmc.mappingio.MappingReader;
import net.fabricmc.mappingio.format.MappingFormat;
import net.fabricmc.mappingio.tree.MappingTree;
import net.fabricmc.mappingio.tree.MemoryMappingTree;
/**
* Provides reflection tools related to Minecraft servers internals.
* It automatically deals with the obfuscated classes and methods.
*/
public class NMSReflect {
private static String OBF_NAMESPACE;
private static String MOJ_NAMESPACE;
/* package */ static final Map<String, ClassMapping> CLASSES_BY_OBF = new TreeMap<>();
/* package */ static final Map<String, ClassMapping> CLASSES_BY_MOJ = new TreeMap<>();
private static Boolean IS_SERVER_OBFUSCATED;
private static boolean isInit = false;
/**
* Initialize all the obfuscation mapping data.
*/
public static void init() {
synchronized (NMSReflect.class) {
if (isInit)
return;
isInit = true;
}
Log.info("[NMSReflect] Initializing NMS obfuscation mapping...");
try {
ReflectClass<?> obfHelperClass;
try {
obfHelperClass = Reflect.ofClass("io.papermc.paper.util.ObfHelper");
OBF_NAMESPACE = (String) obfHelperClass.field("SPIGOT_NAMESPACE").getStaticValue();
MOJ_NAMESPACE = (String) obfHelperClass.field("MOJANG_PLUS_YARN_NAMESPACE").getStaticValue();
} catch (ReflectiveOperationException e) {
throw new ReflectiveOperationException("Unable to find the Paper ofbuscation mapping class or class members.", e);
}
List<ClassMapping> mappings = loadMappings(obfHelperClass);
for (ClassMapping clazz : mappings) {
CLASSES_BY_OBF.put(clazz.obfName, clazz);
CLASSES_BY_MOJ.put(clazz.mojName, clazz);
}
// determine if the runtime server is obfuscated
ClassNotFoundException exIfUnableToDetermine = null;
for (ClassMapping clazz : CLASSES_BY_OBF.values()) {
if (clazz.obfName.equals(clazz.mojName) // avoid direct collision between obf and unobf class names
|| CLASSES_BY_MOJ.containsKey(clazz.obfName) // avoid indirect collision
|| CLASSES_BY_OBF.containsKey(clazz.mojName))// avoid indirect collision
continue;
try {
Class.forName(clazz.obfName);
IS_SERVER_OBFUSCATED = true;
break;
} catch (ClassNotFoundException e) {
try {
Class.forName(clazz.mojName);
IS_SERVER_OBFUSCATED = false;
break;
} catch (ClassNotFoundException ee) {
ee.addSuppressed(e);
if (exIfUnableToDetermine == null)
exIfUnableToDetermine = ee;
}
}
}
if (IS_SERVER_OBFUSCATED == null) {
throw new IllegalStateException("Unable to determine if this server is obfuscated or not", exIfUnableToDetermine);
}
if (IS_SERVER_OBFUSCATED) {
Log.info("[NMSReflect] NMS runtime classes are obfuscated.");
}
else {
Log.info("[NMSReflect] NMS runtime classes are mojang mapped.");
}
int missingRuntimeClasses = 0;
for (ClassMapping clazz : mappings) {
try {
clazz.cacheReflectClass();
} catch (Throwable e) {
missingRuntimeClasses++;
if (e instanceof ClassNotFoundException cnfe) {
Log.warning("[NMSReflect] Missing runtime class " + cnfe.getMessage() + (IS_SERVER_OBFUSCATED ? (" (moj class: " + clazz.mojName + ")") : ""));
}
else {
Log.warning("[NMSReflect] Unable to load runtime class " + (IS_SERVER_OBFUSCATED ? (clazz.obfName + " (moj class: " + clazz.mojName + ")") : clazz.mojName));
Log.warning(e); // throwable on separate log message due to sometimes the message not showing at all because of this exception
}
CLASSES_BY_OBF.remove(clazz.obfName);
CLASSES_BY_MOJ.remove(clazz.mojName);
}
}
if (missingRuntimeClasses > 0) {
Log.warning("[NMSReflect] " + missingRuntimeClasses + " class have been removed from the mapping data due to the previously stated errors.");
}
} catch (Throwable t) {
CLASSES_BY_OBF.clear();
CLASSES_BY_MOJ.clear();
Log.severe("[NMSReflect] The plugin will not have access to NMS stuff due to an error while loading the obfuscation mapping.", t);
}
Log.info("[NMSReflect] Obfuscation mapping loaded for " + CLASSES_BY_OBF.size() + " classes.");
}
/**
* Returns the class mapping instance for the provided class.
* @param mojName the binary name of the desired class, on the mojang mapping.
* @return the class mapping instance for the provided class.
* @throws NullPointerException if there is no mapping for the provided Mojang mapped class.
*/
public static ClassMapping mojClass(String mojName) {
return Objects.requireNonNull(CLASSES_BY_MOJ.get(mojName), "Unable to find the Mojang mapped class '" + mojName + "'");
}
private static List<ClassMapping> loadMappings(ReflectClass<?> obfHelperClass) throws IOException {
try (final InputStream mappingsInputStream = obfHelperClass.get().getClassLoader().getResourceAsStream("META-INF/mappings/reobf.tiny")) {
if (mappingsInputStream == null) {
throw new RuntimeException("Unable to find the ofbuscation mapping file in the Paper jar.");
}
MemoryMappingTree tree = new MemoryMappingTree();
MappingReader.read(new InputStreamReader(mappingsInputStream, StandardCharsets.UTF_8), MappingFormat.TINY_2, tree);
List<ClassMapping> classes = new ArrayList<>();
for (MappingTree.ClassMapping cls : tree.getClasses()) {
classes.add(new ClassMapping(cls));
}
return classes;
}
}
/**
* Prints an HTML rendering of the currently loaded obfuscation mapping, into the provided {@link PrintStream}.
* @param out the stream in which to print the HTML content.
*/
public static void printHTMLMapping(PrintStream out) {
String title = "Obfuscation mapping - " + Bukkit.getName() + " version " + Bukkit.getVersion();
out.println("<!DOCTYPE html><html><head>\n"
+ "<title>" + title + "</title>\n"
+ """
<style>
html {
background-color: #2F2F2F;
color: white;
font-size: 14px;
font-family: Consolas, monospace;
}
a:not(.cl) {
color: #1290C3;
}
table {
border-collapse: collapse;
width: 100%;
margin: auto;
}
tr:nth-child(2n) {
background-color: #373737;
}
tr:hover {
background-color: #555;
}
tr > *:first-child {
padding-right: .5em;
white-space: nowrap;
}
b.pu {
color: #0C0;
}
b.pt {
color: #FC0;
}
b.pv {
color: #F00;
}
b.pk {
color: #66F;
}
td {
padding-top: 0;
padding-bottom: 0;
}
th {
text-align: left;
font-size: 1.1em;
border-top: solid 1px white;
}
.kw {
color: #CC6C1D;
}
.cl {
color: #1290C3;
}
.mtd {
color: #1EB540;
}
.fld {
color: #8DDAF8;
}
.st {
font-style: italic;
}
.st.fn {
font-weight: bold;
}
</style>
</head><body>
"""
+ "<h1>" + title + "</h1>\n"
+ """
<p>
<b>C</b>: <span class='kw'>class</span>&nbsp;&nbsp;
<b>E</b>: <span class='kw'>enum</span>&nbsp;&nbsp;
<b>I</b>: <span class='kw'>interface</span>&nbsp;&nbsp;
<b>@</b>: <span class='kw'>@interface</span>&nbsp;&nbsp;
<b>R</b>: <span class='kw'>record</span><br>
<b>●</b>: field&nbsp;&nbsp;
<b>c</b>: constructor&nbsp;&nbsp;
<b>⬤</b>: method<br>
<b class='pu'>⬤</b>: <span class='kw'>public</span>&nbsp;&nbsp;
<b class='pt'>⬤</b>: <span class='kw'>protected</span>&nbsp;&nbsp;
<b class='pk'>⬤</b>: package&nbsp;&nbsp;
<b class='pv'>⬤</b>: <span class='kw'>private</span><br>
<sup>S</sup>: <span class='kw'>static</span>&nbsp;&nbsp;
<sup>A</sup>: <span class='kw'>abstract</span>&nbsp;&nbsp;
<sup>F</sup>: <span class='kw'>final</span>
</p>
<table>
""");
out.println("<tr><th>ns</th><th>" + OBF_NAMESPACE + "</th><th>" + MOJ_NAMESPACE + "</th></tr>");
for (ClassMapping clazz : CLASSES_BY_OBF.values()) {
clazz.printHTML(out);
}
out.println("</table><p>Generated by <a href='https://github.com/marcbal'>marcbal</a>"
+ " using <a href='https://github.com/PandacubeFr/PandaLib/blob/master/Paper/src/main/java/fr/pandacube/lib/paper/reflect/NMSReflect.java'>this tool</a>"
+ " running on <a href='https://papermc.io/'>" + Bukkit.getName() + "</a> version " + Bukkit.getVersion() + "</p>"
+ "</body></html>");
}
/**
* Represents the mapping between the obfuscated and mojang names of a class and all its members.
*/
public static class ClassMapping {
private static int nextID = 0;
/* package */ final int id = nextID++;
/* package */ final String obfName;
/* package */ final String mojName;
private final Map<MethodId, MemberMapping<MethodId, ReflectMethod<?>>> methodsByObf = new TreeMap<>();
private final Map<MethodId, MemberMapping<MethodId, ReflectMethod<?>>> methodsByMoj = new TreeMap<>();
private final Map<String, MemberMapping<String, ReflectField<?>>> fieldsByObf = new TreeMap<>();
private final Map<String, MemberMapping<String, ReflectField<?>>> fieldsByMoj = new TreeMap<>();
private ReflectClass<?> runtimeReflectClass = null;
private ClassMapping(MappingTree.ClassMapping cls) {
obfName = binaryClassName(cls.getName(OBF_NAMESPACE));
mojName = binaryClassName(cls.getName(MOJ_NAMESPACE));
cls.getMethods().stream().map(MemberMapping::of).forEach(method -> {
method.declaringClass = this;
methodsByObf.put(method.obfDesc.identifier, method);
methodsByMoj.put(method.mojDesc.identifier, method);
});
cls.getFields().stream().map(MemberMapping::of).forEach(field -> {
field.declaringClass = this;
fieldsByObf.put(field.obfDesc.identifier, field);
fieldsByMoj.put(field.mojDesc.identifier, field);
});
}
private synchronized void cacheReflectClass() throws ClassNotFoundException {
if (runtimeReflectClass == null)
runtimeReflectClass = Reflect.ofClass(IS_SERVER_OBFUSCATED ? obfName : mojName);
}
/**
* Returns the actual runtime {@link Class} represented by this {@link ClassMapping}, wrapped into a
* {@link ReflectClass}.
* @return the actual runtime {@link Class} represented by this {@link ClassMapping}, wrapped into a
* * {@link ReflectClass}.
*/
public ReflectClass<?> runtimeReflect() {
return runtimeReflectClass;
}
/**
* Returns the actual runtime Class represented by this {@link ClassMapping}.
* @return the actual runtime Class represented by this {@link ClassMapping}.
*/
public Class<?> runtimeClass() {
return runtimeReflectClass.get();
}
/**
* Returns the actual runtime Method that has the provided mojang name and parameter types, wrapped into a
* {@link ReflectMethod}.
* @param mojName the Mojang mapped name of the method.
* @param mojParametersType the list of parameters of the method.
* Each parameter type must be an instance of one of the following type:
* {@link NMSTypeWrapper}, {@link Class}, {@link ReflectClass} or {@link ClassMapping}.
* @return the actual runtime Method that has the provided mojang name and parameter types, wrapped into a
* {@link ReflectMethod}.
* @throws IllegalArgumentException if one of the parameter has an invalid type
* @throws NullPointerException if one of the parameter is null, or if there is no mapping for the provided Mojang mapped method.
* @throws ClassNotFoundException if there is no runtime class to represent one of the provided parametersType.
* @throws NoSuchMethodException if there is no runtime method to represent the provided method.
*/
public ReflectMethod<?> mojMethod(String mojName, Object... mojParametersType) throws ClassNotFoundException, NoSuchMethodException {
MethodId mId = new MethodId(mojName, NMSTypeWrapper.toTypeList(Arrays.asList(mojParametersType)));
MemberMapping<MethodId, ReflectMethod<?>> mm = methodsByMoj.get(mId);
Objects.requireNonNull(mm, "Unable to find the Mojang mapped method " + mId);
try {
return mm.getReflectMember();
} catch (ReflectiveOperationException e) {
if (e instanceof ClassNotFoundException cnfe)
throw cnfe;
if (e instanceof NoSuchMethodException nsme)
throw nsme;
// should not have another exception
throw new RuntimeException(e);
}
}
/**
* Returns the actual runtime Field that has the provided mojang name, wrapped into a {@link ReflectField}.
* @param mojName the Mojang mapped name of the field.
* @return the actual runtime Field that has the provided mojang name, wrapped into a {@link ReflectField}.
* @throws NullPointerException if there is no mapping for the provided Mojang mapped field.
* @throws NoSuchFieldException if there is no runtime field to represent the provided mojang field.
*/
public ReflectField<?> mojField(String mojName) throws NoSuchFieldException {
MemberMapping<String, ReflectField<?>> fm = fieldsByMoj.get(mojName);
Objects.requireNonNull(fm, "Unable to find the Mojang mapped field '" + mojName + "'");
try {
return fm.getReflectMember();
} catch (ReflectiveOperationException e) {
if (e instanceof NoSuchFieldException nsfe)
throw nsfe;
// should not have another exception
throw new RuntimeException(e);
}
}
/* package */ String toClickableHTML(boolean isObfClass) {
String classToPrint = isObfClass ? obfName : mojName;
String classSimpleName = classToPrint.substring(classToPrint.lastIndexOf('.') + 1);
String htmlTitle = classSimpleName.equals(classToPrint) ? "" : (" title='" + classToPrint + "'");
return "<a href='#c" + id + "'" + htmlTitle + " class='cl'>" + classSimpleName + "</a>";
}
/* package */ NMSTypeWrapper toType(boolean obf) {
return new NMSTypeWrapper(obf ? obfName : mojName, 0);
}
private void printHTML(PrintStream out) {
String modifiersHTML = classModifiersToHTML(runtimeClass());
out.println("<tr id='c" + id + "'><th>" + modifiersHTML + "</th><th>" + nameToHTML(true) + "</th><th>" + nameToHTML(false) + "</th></tr>");
fieldsByObf.values().stream().filter(MemberMapping::isStatic).forEach(f -> f.printHTML(out));
methodsByObf.values().stream().filter(MemberMapping::isStatic).forEach(m -> m.printHTML(out));
printConstructorsHTML(out);
fieldsByObf.values().stream().filter(mm -> !mm.isStatic()).forEach(f -> f.printHTML(out));
methodsByObf.values().stream().filter(mm -> !mm.isStatic()).forEach(m -> m.printHTML(out));
}
private String nameToHTML(boolean obf) {
String classToPrint = obf ? obfName : mojName;
int packageSep = classToPrint.lastIndexOf('.');
String classSimpleName = classToPrint.substring(packageSep + 1);
String classPackages = classToPrint.substring(0, Math.max(packageSep, 0));
String classHTML = (packageSep >= 0 ? (classPackages + ".") : "") + "<b class='cl'>" + classSimpleName + "</b>";
NMSTypeWrapper superClass = superClass(obf);
String superClassHTML = superClass == null ? "" : (" <span class='kw'>extends</span> " + superClass.toHTML(obf));
List<NMSTypeWrapper> superInterfaces = superInterfaces(obf);
String superInterfacesHTML = superInterfaces.isEmpty() ? ""
: (" <span class='kw'>implements</span> " + superInterfaces.stream().map(t -> t.toHTML(obf)).collect(Collectors.joining(", ")));
return classHTML + superClassHTML + superInterfacesHTML;
}
private NMSTypeWrapper superClass(boolean obf) {
Class<?> superClass = runtimeClass().getSuperclass();
if (superClass == null || superClass.equals(Object.class) || superClass.equals(Enum.class) || superClass.equals(Record.class))
return null;
ClassMapping cm = (IS_SERVER_OBFUSCATED ? CLASSES_BY_OBF : CLASSES_BY_MOJ).get(superClass.getName());
return (cm != null) ? cm.toType(obf) : NMSTypeWrapper.of(superClass);
}
private List<NMSTypeWrapper> superInterfaces(boolean obf) {
Class<?>[] interfaces = runtimeClass().getInterfaces();
List<NMSTypeWrapper> types = new ArrayList<>(interfaces.length);
for (Class<?> interfce : interfaces) {
ClassMapping cm = (IS_SERVER_OBFUSCATED ? CLASSES_BY_OBF : CLASSES_BY_MOJ).get(interfce.getName());
types.add((cm != null) ? cm.toType(obf) : NMSTypeWrapper.of(interfce));
}
return types;
}
private void printConstructorsHTML(PrintStream out) {
String classObfSimpleName = obfName.substring(obfName.lastIndexOf('.') + 1);
String classMojSimpleName = mojName.substring(mojName.lastIndexOf('.') + 1);
for (Constructor<?> ct : runtimeClass().getDeclaredConstructors()) {
List<NMSTypeWrapper> obfParams = new ArrayList<>();
List<NMSTypeWrapper> mojParams = new ArrayList<>();
for (Class<?> param : ct.getParameterTypes()) {
ClassMapping cm = (IS_SERVER_OBFUSCATED ? CLASSES_BY_OBF : CLASSES_BY_MOJ).get(param.getName());
if (cm == null) {
NMSTypeWrapper t = NMSTypeWrapper.of(param);
obfParams.add(t);
mojParams.add(t);
}
else {
obfParams.add(cm.toType(true));
mojParams.add(cm.toType(false));
}
}
out.println("<tr>"
+ "<td>" + elementModifiersToHTML("c", ct.getModifiers()) + "</td>"
+ "<td><b class='mtd'>" + classObfSimpleName + "</b>(" + obfParams.stream().map(t -> t.toHTML(true)).collect(Collectors.joining(", ")) + ")</td>"
+ "<td><b class='mtd'>" + classMojSimpleName + "</b>(" + mojParams.stream().map(t -> t.toHTML(false)).collect(Collectors.joining(", ")) + ")</td>"
+ "</tr>");
}
}
}
private record MethodId(String name, List<NMSTypeWrapper> parametersType) implements Comparable<MethodId> {
@Override
public int compareTo(MethodId o) {
int cmp = name.compareTo(o.name);
if (cmp != 0)
return cmp;
return toString().compareTo(o.toString());
}
private String toHTML(boolean isObfClass, boolean isStatic, boolean isFinal) {
String paramsHTML = parametersType.stream().map(p -> p.toHTML(isObfClass)).collect(Collectors.joining(", "));
String cl = "mtd";
if (isStatic)
cl += " st";
if (isFinal)
cl += " fn";
return "<span class='" + cl + "'>" + name + "</span>(" + paramsHTML + ")";
}
public String toString() {
String paramsStr = parametersType.stream().map(NMSTypeWrapper::toString).collect(Collectors.joining(", "));
return name + "(" + paramsStr + ")";
}
}
private record MemberDesc<I extends Comparable<I>>(I identifier, NMSTypeWrapper returnType) {
private String toHTML(boolean isObfClass, boolean isStatic, boolean isFinal) {
String identifierHTML = "";
if (identifier instanceof MethodId mId)
identifierHTML = mId.toHTML(isObfClass, isStatic, isFinal);
else if (identifier instanceof String n) {
String cl = "fld";
if (isStatic)
cl += " st";
if (isFinal)
cl += " fn";
identifierHTML = "<span class='" + cl + "'>" + n + "</span>";
}
return returnType.toHTML(isObfClass) + " " + identifierHTML;
}
private static MemberDesc<MethodId> of(MappingTree.MethodMapping member, String namespace) {
String desc = member.getDesc(namespace);
try (StringReader descReader = new StringReader(desc)) {
char r = (char) descReader.read();
if (r != '(')
throw new IllegalArgumentException("Invalid method description '" + desc + "'. Must start with '('.");
List<NMSTypeWrapper> paramsType = new ArrayList<>();
while (((char) descReader.read()) != ')') {
descReader.skip(-1);
paramsType.add(NMSTypeWrapper.parse(descReader));
}
NMSTypeWrapper retType = NMSTypeWrapper.parse(descReader);
return new MemberDesc<>(new MethodId(member.getName(namespace), Collections.unmodifiableList(paramsType)), retType);
} catch (IOException e) {
throw new RuntimeException("StringReader read error", e);
}
}
private static MemberDesc<String> of(MappingTree.FieldMapping member, String namespace) {
StringReader descReader = new StringReader(member.getDesc(namespace));
return new MemberDesc<>(member.getName(namespace), NMSTypeWrapper.parse(descReader));
}
}
private static abstract class MemberMapping<I extends Comparable<I>, R extends ReflectMember<?, ?, ?, ?>> {
private final String htmlTypeChar;
/* package */ final MemberDesc<I> obfDesc, mojDesc;
/* package */ ClassMapping declaringClass;
private MemberMapping(String htmlType, MemberDesc<I> obfDesc, MemberDesc<I> mojDesc) {
htmlTypeChar = htmlType;
this.obfDesc = obfDesc;
this.mojDesc = mojDesc;
}
/* package */ void printHTML(PrintStream out) {
int mod = 0;
try {
mod = getReflectMember().getModifiers();
} catch (ReflectiveOperationException e) {
// ignore
}
boolean isStatic = Modifier.isStatic(mod);
boolean isFinal = Modifier.isFinal(mod);
out.println("<tr>"
+ "<td>" + elementModifiersToHTML(htmlTypeChar, mod) + "</td>"
+ "<td>" + obfDesc.toHTML(true, isStatic, isFinal) + "</td>"
+ "<td>" + mojDesc.toHTML(false, isStatic, isFinal) + "</td>"
+ "</tr>");
}
/* package */ MemberDesc<I> getReflectDesc() {
return (IS_SERVER_OBFUSCATED ? obfDesc : mojDesc);
}
/* package */ abstract R getReflectMember() throws ReflectiveOperationException;
/* package */ boolean isStatic() {
try {
return Modifier.isStatic(getReflectMember().getModifiers());
} catch (ReflectiveOperationException e) {
Log.severe(e);
return false;
}
}
private static MemberMapping<MethodId, ReflectMethod<?>> of(MappingTree.MethodMapping mioMapping) {
return new MemberMapping<>("", MemberDesc.of(mioMapping, OBF_NAMESPACE), MemberDesc.of(mioMapping, MOJ_NAMESPACE)) {
@Override
ReflectMethod<?> getReflectMember() throws ClassNotFoundException, NoSuchMethodException {
MethodId id = getReflectDesc().identifier;
return declaringClass.runtimeReflectClass.method(id.name, NMSTypeWrapper.toClassArray(id.parametersType));
}
};
}
private static MemberMapping<String, ReflectField<?>> of(MappingTree.FieldMapping mioMapping) {
return new MemberMapping<>("", MemberDesc.of(mioMapping, OBF_NAMESPACE), MemberDesc.of(mioMapping, MOJ_NAMESPACE)) {
@Override
ReflectField<?> getReflectMember() throws NoSuchFieldException {
String id = getReflectDesc().identifier;
return declaringClass.runtimeReflectClass.field(id);
}
};
}
}
/* package */ static String binaryClassName(String cl) {
return cl.replace('/', '.');
}
private static String classModifiersToHTML(Class<?> clazz) {
String elementHTMLType;
if (clazz.isEnum())
elementHTMLType = "E";
else if (clazz.isAnnotation())
elementHTMLType = "@";
else if (clazz.isInterface())
elementHTMLType = "I";
else if (clazz.isRecord())
elementHTMLType = "R";
else if (clazz.isPrimitive())
elementHTMLType = "";
else
elementHTMLType = "C";
return elementModifiersToHTML(elementHTMLType, clazz.getModifiers());
}
private static String elementModifiersToHTML(String elementHTMLType, int elModifiers) {
String html = "<b class='";
if (Modifier.isPublic(elModifiers))
html += "pu";
else if (Modifier.isProtected(elModifiers))
html += "pt";
else if (Modifier.isPrivate(elModifiers))
html += "pv";
else
html += "pk";
html += "'>" + elementHTMLType + "</b>";
boolean isStatic = Modifier.isStatic(elModifiers);
boolean isAbstract = Modifier.isAbstract(elModifiers);
boolean isFinal = Modifier.isFinal(elModifiers);
if (isStatic || isAbstract || isFinal) {
html += "<sup>";
if (isStatic)
html += "S";
if (isAbstract)
html += "A";
if (isFinal)
html += "F";
html += "</sup>";
}
return html;
}
// ● (field)
// ⬤ (method)
}

View File

@@ -0,0 +1,194 @@
package fr.pandacube.lib.paper.reflect;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping;
/* package */ class NMSTypeWrapper implements Comparable<NMSTypeWrapper> {
private final String type;
private final int arrayDepth;
/* package */ NMSTypeWrapper(String type, int arrayDepth) {
this.type = type;
this.arrayDepth = arrayDepth;
}
@Override
public boolean equals(Object obj) {
return obj instanceof NMSTypeWrapper ot && type.equals(ot.type) && arrayDepth == ot.arrayDepth;
}
@Override
public int hashCode() {
return type.hashCode() ^ arrayDepth;
}
@Override
public int compareTo(NMSTypeWrapper o) {
return toString().compareTo(o.toString());
}
Class<?> toClass() throws ClassNotFoundException {
Class<?> cl = switch(type) {
case "boolean" -> boolean.class;
case "byte" -> byte.class;
case "char" -> char.class;
case "double" -> double.class;
case "float" -> float.class;
case "int" -> int.class;
case "long" -> long.class;
case "short" -> short.class;
case "void" -> void.class;
default -> Class.forName(type);
};
for (int i = 0; i < arrayDepth; i++) {
cl = cl.arrayType();
}
return cl;
}
/* package */ static NMSTypeWrapper of(Class<?> cl) {
int arrayDepth = 0;
while (cl.isArray()) {
cl = cl.getComponentType();
arrayDepth++;
}
return new NMSTypeWrapper(cl.getName(), arrayDepth);
}
public static NMSTypeWrapper of(ReflectClass<?> rc) {
return arrayOf(rc, 0);
}
public static NMSTypeWrapper arrayOf(ReflectClass<?> rc, int arrayDepth) {
return new NMSTypeWrapper(rc.get().getName(), arrayDepth);
}
public static NMSTypeWrapper mojOf(ClassMapping cm) {
return arrayMojOf(cm, 0);
}
public static NMSTypeWrapper arrayMojOf(ClassMapping cm, int arrayDepth) {
return new NMSTypeWrapper(cm.mojName, arrayDepth);
}
/* package */ static NMSTypeWrapper toType(Object typeObj) {
Objects.requireNonNull(typeObj, "typeObj cannot be null");
if (typeObj instanceof Class<?> cl) {
return of(cl);
}
else if (typeObj instanceof ClassMapping cm) {
return mojOf(cm);
}
else if (typeObj instanceof ReflectClass<?> rc) {
return of(rc);
}
else if (typeObj instanceof NMSTypeWrapper t) {
return t;
}
else
throw new IllegalArgumentException("Unsupported object of type " + typeObj.getClass());
}
/* package */ String toHTML(boolean isObfClass) {
ClassMapping clMapping = (isObfClass ? NMSReflect.CLASSES_BY_OBF : NMSReflect.CLASSES_BY_MOJ).get(type);
String typeHTML;
if (clMapping != null) {
typeHTML = clMapping.toClickableHTML(isObfClass);
}
else {
String classToPrint = type;
String classSimpleName = classToPrint.substring(classToPrint.lastIndexOf('.') + 1);
String htmlTitle = classSimpleName.equals(classToPrint) ? "" : (" title='" + classToPrint + "'");
if (!htmlTitle.equals("")) {
typeHTML = "<span" + htmlTitle + " class='cl'>" + classSimpleName + "</span>";
}
else {
typeHTML = "<span class='" + (isPrimitive() ? "kw" : "cl") + "'>" + classSimpleName + "</span>";
}
}
return typeHTML + "[]".repeat(arrayDepth);
}
public String toString() {
return type + "[]".repeat(arrayDepth);
}
public boolean isPrimitive() {
try {
return toClass().isPrimitive();
} catch (ClassNotFoundException e) {
return false;
}
}
/* package */ static NMSTypeWrapper parse(StringReader desc) {
try {
int arrayDepth = 0;
char c;
while ((c = (char) desc.read()) == '[') {
arrayDepth++;
}
String type = switch(c) {
case 'Z' -> "boolean";
case 'B' -> "byte";
case 'C' -> "char";
case 'D' -> "double";
case 'F' -> "float";
case 'I' -> "int";
case 'J' -> "long";
case 'S' -> "short";
case 'L' -> {
StringBuilder sbClass = new StringBuilder();
char r;
while ((r = (char) desc.read()) != ';') {
sbClass.append(r);
}
yield NMSReflect.binaryClassName(sbClass.toString());
}
default -> "void";
};
return new NMSTypeWrapper(type, arrayDepth);
} catch (IOException e) {
throw new RuntimeException("StringReader read error", e);
}
}
/* package */ static List<NMSTypeWrapper> toTypeList(List<Object> paramsType) {
List<NMSTypeWrapper> types = new ArrayList<>(paramsType.size());
for (int i = 0; i < paramsType.size(); i++) {
Object param = paramsType.get(i);
try {
types.add(NMSTypeWrapper.toType(param));
} catch (NullPointerException|IllegalArgumentException e) {
throw new IllegalArgumentException("Invalid parameterType at index " + i, e);
}
}
return types;
}
/* package */ static Class<?>[] toClassArray(List<NMSTypeWrapper> types) throws ClassNotFoundException {
Class<?>[] classes = new Class<?>[types.size()];
for (int i = 0; i < types.size(); i++) {
classes[i] = types.get(i).toClass();
}
return classes;
}
}

View File

@@ -0,0 +1,40 @@
package fr.pandacube.lib.paper.reflect;
import org.bukkit.Bukkit;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.ReflectClass;
/**
* Provides reflection tools related to {@code org.bukkit.craftbukkit}.
*/
public class OBCReflect {
private static final String OBC_PACKAGE_PREFIX = "org.bukkit.craftbukkit.";
private static final String OBC_PACKAGE_VERSION;
static {
String name = Bukkit.getServer().getClass().getName()
.substring(OBC_PACKAGE_PREFIX.length());
name = name.substring(0, name.indexOf("."));
OBC_PACKAGE_VERSION = name;
}
/**
* Returns the OBC class that has the provided name, wrapped into a {@link ReflectClass}.
* @param obcClass the name of the class, including the subpackage in whitch the requested class is. This parameter
* will be prefixed with the {@code OBC} package and the current package version.
* @return the OBC class that has the provided name, wrapped into a {@link ReflectClass}.
* @throws ClassNotFoundException if the provided class was not found in {@code OBC} package.
*/
public static ReflectClass<?> ofClass(String obcClass) throws ClassNotFoundException {
return Reflect.ofClass(OBC_PACKAGE_PREFIX + OBC_PACKAGE_VERSION + "." + obcClass);
}
}

View File

@@ -0,0 +1,177 @@
package fr.pandacube.lib.paper.reflect;
import fr.pandacube.lib.paper.reflect.wrapper.brigadier.CommandNode;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftMapView;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftNamespacedKey;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftPlayer;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftServer;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftVector;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftWorld;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.RenderData;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.VanillaCommandWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.DetectedVersion;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.SharedConstants;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.WorldVersion;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.BlockPosArgument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.CommandSourceStack;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Commands;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.ComponentArgument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Coordinates;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.EntityArgument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.EntitySelector;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.GameProfileArgument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.ResourceLocationArgument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Vec3Argument;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.BlockPos;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.Vec3i;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.NbtIo;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.StringTag;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.Tag;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.FriendlyByteBuf;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.chat.Component;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.protocol.ClientboundCustomPayloadPacket;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.protocol.ClientboundGameEventPacket;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.protocol.Packet;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.resources.ResourceLocation;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ChunkMap;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.DedicatedPlayerList;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.DedicatedServer;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.DedicatedServerProperties;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.MinecraftServer;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerChunkCache;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerGamePacketListenerImpl;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerLevel;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerPlayer;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.Settings;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProgressListener;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.AABB;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ChunkPos;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ChunkStorage;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.DamageSource;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Entity;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Level;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.MapItemSavedData;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.SavedData;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Vec3;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.VoxelShape;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.block.BambooBlock;
import fr.pandacube.lib.paper.reflect.wrapper.netty.ByteBuf;
import fr.pandacube.lib.paper.reflect.wrapper.netty.Unpooled;
import fr.pandacube.lib.paper.reflect.wrapper.paper.AABBVoxelShape;
import fr.pandacube.lib.paper.reflect.wrapper.paper.PaperAdventure;
import fr.pandacube.lib.paper.reflect.wrapper.paper.QueuedChangesMapLong2Object;
import fr.pandacube.lib.paper.reflect.wrapper.paper.configuration.FallbackValue_Int;
import fr.pandacube.lib.paper.reflect.wrapper.paper.configuration.WorldConfiguration;
import static fr.pandacube.lib.reflect.wrapper.WrapperRegistry.initWrapper;
/**
* Initializer for all the reflect tools in {@code pandalib-paper-reflect} module.
*/
public class PandalibPaperReflect {
private static boolean isInit = false;
/**
* Initializes the reflect tools in {@code pandalib-paper-reflect} module.
*/
public static void init() {
NMSReflect.init();
synchronized (PandalibPaperReflect.class) {
if (isInit)
return;
isInit = true;
}
initWrapperClasses();
}
private static void initWrapperClasses() {
// brigadier
initWrapper(CommandNode.class, CommandNode.REFLECT.get());
// craftbukkit
initWrapper(CraftMapView.class, CraftMapView.REFLECT.get());
initWrapper(CraftNamespacedKey.class, CraftNamespacedKey.REFLECT.get());
initWrapper(CraftPlayer.class, CraftPlayer.REFLECT.get());
initWrapper(CraftServer.class, CraftServer.REFLECT.get());
initWrapper(CraftVector.class, CraftVector.REFLECT.get());
initWrapper(CraftWorld.class, CraftWorld.REFLECT.get());
initWrapper(RenderData.class, RenderData.REFLECT.get());
initWrapper(VanillaCommandWrapper.class, VanillaCommandWrapper.REFLECT.get());
// minecraft.commands
initWrapper(BlockPosArgument.class, BlockPosArgument.MAPPING.runtimeClass());
initWrapper(Commands.class, Commands.MAPPING.runtimeClass());
initWrapper(CommandSourceStack.class, CommandSourceStack.MAPPING.runtimeClass());
initWrapper(ComponentArgument.class, ComponentArgument.MAPPING.runtimeClass());
initWrapper(Coordinates.class, Coordinates.MAPPING.runtimeClass());
initWrapper(EntityArgument.class, EntityArgument.MAPPING.runtimeClass());
initWrapper(EntitySelector.class, EntitySelector.MAPPING.runtimeClass());
initWrapper(GameProfileArgument.class, GameProfileArgument.MAPPING.runtimeClass());
initWrapper(ResourceLocationArgument.class, ResourceLocationArgument.MAPPING.runtimeClass());
initWrapper(Vec3Argument.class, Vec3Argument.MAPPING.runtimeClass());
// minecraft.core
initWrapper(BlockPos.class, BlockPos.MAPPING.runtimeClass());
initWrapper(Vec3i.class, Vec3i.MAPPING.runtimeClass());
// minecraft.nbt
initWrapper(CompoundTag.class, CompoundTag.MAPPING.runtimeClass());
initWrapper(NbtIo.class, NbtIo.MAPPING.runtimeClass());
initWrapper(StringTag.class, StringTag.MAPPING.runtimeClass());
initWrapper(Tag.class, Tag.MAPPING.runtimeClass());
// minecraft.network.chat
initWrapper(Component.class, Component.MAPPING.runtimeClass());
// minecraft.network.protocol
initWrapper(ClientboundCustomPayloadPacket.class, ClientboundCustomPayloadPacket.MAPPING.runtimeClass());
initWrapper(ClientboundGameEventPacket.class, ClientboundGameEventPacket.MAPPING.runtimeClass());
initWrapper(ClientboundGameEventPacket.Type.class, ClientboundGameEventPacket.Type.MAPPING.runtimeClass());
initWrapper(Packet.class, Packet.MAPPING.runtimeClass());
// minecraft.network
initWrapper(FriendlyByteBuf.class, FriendlyByteBuf.MAPPING.runtimeClass());
// minecraft.resources
initWrapper(ResourceLocation.class, ResourceLocation.MAPPING.runtimeClass());
// minecraft.server
initWrapper(ChunkMap.class, ChunkMap.MAPPING.runtimeClass());
initWrapper(DedicatedPlayerList.class, DedicatedPlayerList.MAPPING.runtimeClass());
initWrapper(DedicatedServer.class, DedicatedServer.MAPPING.runtimeClass());
initWrapper(DedicatedServerProperties.class, DedicatedServerProperties.MAPPING.runtimeClass());
initWrapper(MinecraftServer.class, MinecraftServer.MAPPING.runtimeClass());
initWrapper(ServerChunkCache.class, ServerChunkCache.MAPPING.runtimeClass());
initWrapper(ServerGamePacketListenerImpl.class, ServerGamePacketListenerImpl.MAPPING.runtimeClass());
initWrapper(ServerLevel.class, ServerLevel.MAPPING.runtimeClass());
initWrapper(ServerPlayer.class, ServerPlayer.MAPPING.runtimeClass());
initWrapper(Settings.class, Settings.MAPPING.runtimeClass());
// minecraft.util
initWrapper(ProgressListener.class, ProgressListener.MAPPING.runtimeClass());
// minecraft.world.block
initWrapper(BambooBlock.class, BambooBlock.MAPPING.runtimeClass());
// minecraft.world
initWrapper(AABB.class, AABB.MAPPING.runtimeClass());
initWrapper(ChunkPos.class, ChunkPos.MAPPING.runtimeClass());
initWrapper(ChunkStorage.class, ChunkStorage.MAPPING.runtimeClass());
initWrapper(DamageSource.class, DamageSource.MAPPING.runtimeClass());
initWrapper(Entity.class, Entity.MAPPING.runtimeClass());
initWrapper(Level.class, Level.MAPPING.runtimeClass());
initWrapper(MapItemSavedData.class, MapItemSavedData.MAPPING.runtimeClass());
initWrapper(SavedData.class, SavedData.MAPPING.runtimeClass());
initWrapper(Vec3.class, Vec3.MAPPING.runtimeClass());
initWrapper(VoxelShape.class, VoxelShape.MAPPING.runtimeClass());
// minecraft
initWrapper(DetectedVersion.class, DetectedVersion.MAPPING.runtimeClass());
initWrapper(SharedConstants.class, SharedConstants.MAPPING.runtimeClass());
initWrapper(WorldVersion.class, WorldVersion.MAPPING.runtimeClass());
// netty
initWrapper(ByteBuf.class, ByteBuf.REFLECT.get());
initWrapper(Unpooled.class, Unpooled.REFLECT.get());
// paper.configuration
initWrapper(FallbackValue_Int.class, FallbackValue_Int.REFLECT.get());
initWrapper(WorldConfiguration.class, WorldConfiguration.REFLECT.get());
initWrapper(WorldConfiguration.Chunks.class, WorldConfiguration.Chunks.REFLECT.get());
// paper
initWrapper(AABBVoxelShape.class, AABBVoxelShape.REFLECT.get());
initWrapper(PaperAdventure.class, PaperAdventure.REFLECT.get());
initWrapper(QueuedChangesMapLong2Object.class, QueuedChangesMapLong2Object.REFLECT.get());
}
}

View File

@@ -0,0 +1,50 @@
package fr.pandacube.lib.paper.reflect.util;
import fr.pandacube.lib.paper.PandaLibPaper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.AABB;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.block.BambooBlock;
import fr.pandacube.lib.paper.reflect.wrapper.paper.AABBVoxelShape;
import fr.pandacube.lib.util.Log;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.entity.LivingEntity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.util.BoundingBox;
// simplified version of https://github.com/Camotoy/BambooCollisionFix/tree/c7d7d5327791cbb416d106de0b9eb0bf2461acbd/src/main/java/net/camotoy/bamboocollisionfix
// we remove the bamboo bounding box due to bedrock clients not having the same placement for bamboos
public final class BedrockBambooCollisionFixer implements Listener {
private final BoundingBox originalBambooBoundingBox = new BoundingBox(6.5D / 16D, 0.0D, 6.5D / 16.0D, 9.5D / 16.0D, 1D, 9.5D / 16.0D);
public BedrockBambooCollisionFixer() {
// Make the bamboo block have zero collision.
try {
BambooBlock.COLLISION_SHAPE(new AABBVoxelShape(new AABB(0.5, 0, 0.5, 0.5, 0, 0.5)));
Log.info("Bamboo block collision box removed succesfully.");
} catch (Exception e) {
Log.severe("Unable to remove the collision box of the Bamboo block.", e);
return;
}
Bukkit.getPluginManager().registerEvents(this, PandaLibPaper.getPlugin());
}
/**
* Because the bamboo has an empty bounding box, it can be placed inside players... prevent that to the best of
* our ability.
*/
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {
if (event.getBlockPlaced().getBlockData().getMaterial().equals(Material.BAMBOO)) {
BoundingBox currentBambooBoundingBox = originalBambooBoundingBox.clone().shift(event.getBlockPlaced().getLocation());
for (LivingEntity e : event.getBlock().getLocation().getNearbyLivingEntities(5)) {
if (e.getBoundingBox().overlaps(currentBambooBoundingBox)) {
// Don't place the bamboo as it intersects
event.setBuild(false);
break;
}
}
}
}
}

View File

@@ -0,0 +1,40 @@
package fr.pandacube.lib.paper.reflect.util;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftServer;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import org.bukkit.Bukkit;
import org.bukkit.plugin.Plugin;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Utility method to get the list of the primary world of the Bukkit/Paper server.
* The primary worlds are the world that are loaded by the server at the startup, that the plugins cannot unload.
*/
public class PrimaryWorlds {
/**
* An unmodifiable list containing the names of the primary worlds of this server instance, in the order they are
* loaded. This list can be accessed even if the corresponding worlds are not yet loaded, for instance in the
* {@link Plugin#onLoad()} method.
*/
public static final List<String> PRIMARY_WORLDS;
static {
List<String> primaryWorlds = new ArrayList<>(3);
String world = ReflectWrapper.wrapTyped(Bukkit.getServer(), CraftServer.class).getServer().getLevelIdName();
primaryWorlds.add(world);
if (Bukkit.getAllowNether()) primaryWorlds.add(world + "_nether");
if (Bukkit.getAllowEnd()) primaryWorlds.add(world + "_the_end");
PRIMARY_WORLDS = Collections.unmodifiableList(primaryWorlds);
}
}

View File

@@ -0,0 +1,35 @@
package fr.pandacube.lib.paper.reflect.util;
import org.bukkit.Bukkit;
import org.bukkit.World;
import fr.pandacube.lib.chat.Chat;
import fr.pandacube.lib.chat.ChatConfig.PandaTheme;
import fr.pandacube.lib.paper.modules.PerformanceAnalysisManager;
import fr.pandacube.lib.paper.reflect.wrapper.craftbukkit.CraftWorld;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ChunkMap;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
public class WorldSaveUtil {
private static ChunkMap getChunkMap(World w) {
return ReflectWrapper.wrapTyped(w, CraftWorld.class).getHandle().getChunkSource().chunkMap;
}
public static void nmsSaveFlush(World w) {
PerformanceAnalysisManager.getInstance().setAlteredTPSTitle(
Chat.text("Sauvegarde map ").color(PandaTheme.CHAT_BROWN_2_SAT).thenData(w.getName()).thenText(" ...")
);
try {
ReflectWrapper.wrapTyped(w, CraftWorld.class).getHandle().save(null, true, false);
} finally {
PerformanceAnalysisManager.getInstance().setAlteredTPSTitle(null);
}
}
public static void nmsSaveAllFlush() {
Bukkit.getWorlds().forEach(WorldSaveUtil::nmsSaveFlush);
}
}

View File

@@ -0,0 +1,22 @@
package fr.pandacube.lib.paper.reflect.wrapper.brigadier;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class CommandNode<S> extends ReflectWrapperTyped<com.mojang.brigadier.tree.CommandNode<S>> {
public static final ReflectClass<?> REFLECT = Reflect.ofClass(com.mojang.brigadier.tree.CommandNode.class);
private static final ReflectMethod<?> removeCommand = wrapEx(() -> REFLECT.method("removeCommand", String.class));
public void removeCommand(String cmd) {
wrapReflectEx(() -> removeCommand.invoke(__getRuntimeInstance(), cmd));
}
protected CommandNode(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,40 @@
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
import fr.pandacube.lib.paper.reflect.OBCReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.MapItemSavedData;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectField;
import fr.pandacube.lib.reflect.ReflectMethod;
import org.bukkit.entity.Player;
import org.bukkit.map.MapView;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class CraftMapView extends ReflectWrapperTyped<MapView> {
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("map.CraftMapView"));
public static final ReflectField<?> worldMap = wrapEx(() -> REFLECT.field("worldMap"));
public static final ReflectMethod<?> render = wrapEx(() -> REFLECT.method("render", CraftPlayer.REFLECT.get()));
protected CraftMapView(Object obj) {
super(obj);
}
public RenderData render(Player player) {
return wrap(wrapReflectEx(() -> render.invoke(__getRuntimeInstance(), player)), RenderData.class);
}
public RenderData render(CraftPlayer player) {
return render(unwrap(player));
}
public MapItemSavedData worldMap() {
return wrap(wrapReflectEx(() -> worldMap.getValue(__getRuntimeInstance())), MapItemSavedData.class);
}
public void worldMap(MapItemSavedData data) {
wrapReflectEx(() -> worldMap.setValue(__getRuntimeInstance(), unwrap(data)));
}
}

View File

@@ -0,0 +1,31 @@
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
import fr.pandacube.lib.paper.reflect.OBCReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.resources.ResourceLocation;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import fr.pandacube.lib.util.ThrowableUtil;
import org.bukkit.NamespacedKey;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class CraftNamespacedKey extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("util.CraftNamespacedKey"));
public static final ReflectMethod<?> toMinecraft = wrapEx(() -> REFLECT.method("toMinecraft", NamespacedKey.class));
public static final ReflectMethod<?> fromMinecraft = ThrowableUtil.wrapEx(() -> REFLECT.method("fromMinecraft", ResourceLocation.MAPPING.runtimeClass()));
public static ResourceLocation toMinecraft(NamespacedKey key) {
return wrap(wrapReflectEx(() -> toMinecraft.invokeStatic(key)), ResourceLocation.class);
}
public static NamespacedKey fromMinecraft(ResourceLocation key) {
return (NamespacedKey) wrapReflectEx(() -> toMinecraft.invokeStatic(unwrap(key)));
}
protected CraftNamespacedKey(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,25 @@
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
import fr.pandacube.lib.paper.reflect.OBCReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerPlayer;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import org.bukkit.entity.Player;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class CraftPlayer extends ReflectWrapperTyped<Player> {
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("entity.CraftPlayer"));
public static final ReflectMethod<?> getHandle = wrapEx(() -> REFLECT.method("getHandle"));
public ServerPlayer getHandle() {
return wrap(wrapReflectEx(() -> getHandle.invoke(__getRuntimeInstance())), ServerPlayer.class);
}
protected CraftPlayer(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,31 @@
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
import fr.pandacube.lib.paper.reflect.OBCReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.DedicatedPlayerList;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.DedicatedServer;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import org.bukkit.Server;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class CraftServer extends ReflectWrapperTyped<Server> {
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("CraftServer"));
public static final ReflectMethod<?> getServer = wrapEx(() -> REFLECT.method("getServer"));
public static final ReflectMethod<?> getHandle = wrapEx(() -> REFLECT.method("getHandle"));
public DedicatedServer getServer() {
return wrap(wrapReflectEx(() -> getServer.invoke(__getRuntimeInstance())), DedicatedServer.class);
}
public DedicatedPlayerList getHandle() {
return wrap(wrapReflectEx(() -> getHandle.invoke(__getRuntimeInstance())), DedicatedPlayerList.class);
}
protected CraftServer(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,43 @@
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
import fr.pandacube.lib.paper.reflect.OBCReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.BlockPos;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Vec3;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import fr.pandacube.lib.util.ThrowableUtil;
import org.bukkit.util.Vector;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class CraftVector extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("util.CraftVector"));
public static final ReflectMethod<?> toBukkit_Vec3 = ThrowableUtil.wrapEx(() -> REFLECT.method("toBukkit", Vec3.MAPPING.runtimeClass()));
public static final ReflectMethod<?> toBukkit_BlockPos = ThrowableUtil.wrapEx(() -> REFLECT.method("toBukkit", BlockPos.MAPPING.runtimeClass()));
public static final ReflectMethod<?> toNMS = wrapEx(() -> REFLECT.method("toNMS", Vector.class));
public static final ReflectMethod<?> toBlockPos = wrapEx(() -> REFLECT.method("toNMS", Vector.class));
public static Vector toBukkit(Vec3 nms) {
return (Vector) wrapReflectEx(() -> toBukkit_Vec3.invokeStatic(unwrap(nms)));
}
public static Vector toBukkit(BlockPos blockPos) {
return (Vector) wrapReflectEx(() -> toBukkit_BlockPos.invokeStatic(unwrap(blockPos)));
}
public static Vec3 toNMS(Vector bukkit) {
return wrap(wrapReflectEx(() -> toNMS.invokeStatic(bukkit)), Vec3.class);
}
public static BlockPos toBlockPos(Vector bukkit) {
return wrap(wrapReflectEx(() -> toBlockPos.invokeStatic(bukkit)), BlockPos.class);
}
protected CraftVector(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,25 @@
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
import fr.pandacube.lib.paper.reflect.OBCReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerLevel;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import org.bukkit.World;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class CraftWorld extends ReflectWrapperTyped<World> {
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("CraftWorld"));
public static final ReflectMethod<?> getHandle = wrapEx(() -> REFLECT.method("getHandle"));
public ServerLevel getHandle() {
return wrap(wrapReflectEx(() -> getHandle.invoke(__getRuntimeInstance())), ServerLevel.class);
}
protected CraftWorld(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,26 @@
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
import fr.pandacube.lib.paper.reflect.OBCReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class RenderData extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("map.RenderData"));
private static final ReflectField<?> buffer = wrapEx(() -> REFLECT.field("buffer"));
protected RenderData(Object obj) {
super(obj);
}
public byte[] buffer() {
return (byte[]) wrapReflectEx(() -> buffer.getValue(__getRuntimeInstance()));
}
public void buffer(byte[] buff) {
wrapReflectEx(() -> buffer.setValue(__getRuntimeInstance(), buff));
}
}

View File

@@ -0,0 +1,42 @@
package fr.pandacube.lib.paper.reflect.wrapper.craftbukkit;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import com.mojang.brigadier.tree.CommandNode;
import fr.pandacube.lib.paper.reflect.OBCReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Commands;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectConstructor;
import fr.pandacube.lib.reflect.ReflectField;
import fr.pandacube.lib.reflect.ReflectMethod;
import org.bukkit.command.CommandSender;
import org.bukkit.command.defaults.BukkitCommand;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class VanillaCommandWrapper extends ReflectWrapperTyped<BukkitCommand> {
public static final ReflectClass<?> REFLECT = wrapEx(() -> OBCReflect.ofClass("command.VanillaCommandWrapper"));
public static final ReflectConstructor<?> CONSTRUTOR = wrapEx(() -> REFLECT.constructor(Commands.MAPPING.runtimeClass(), CommandNode.class));
public static final ReflectField<?> vanillaCommand = wrapEx(() -> REFLECT.field("vanillaCommand"));
public static final ReflectMethod<?> getListener = wrapEx(() -> REFLECT.method("getListener", CommandSender.class));
public VanillaCommandWrapper(Commands dispatcher, CommandNode<BukkitBrigadierCommandSource> vanillaCommand) {
this(wrapReflectEx(() -> CONSTRUTOR.instanciate(unwrap(dispatcher), vanillaCommand)));
}
@SuppressWarnings("unchecked")
public CommandNode<BukkitBrigadierCommandSource> vanillaCommand() {
return (CommandNode<BukkitBrigadierCommandSource>) wrapReflectEx(() -> vanillaCommand.getValue(__getRuntimeInstance()));
}
public static BukkitBrigadierCommandSource getListener(CommandSender sender) {
return (BukkitBrigadierCommandSource) wrapReflectEx(() -> getListener.invokeStatic(sender));
}
protected VanillaCommandWrapper(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,14 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class DetectedVersion extends ReflectWrapper implements WorldVersion {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.DetectedVersion"));
protected DetectedVersion(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,31 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class SharedConstants extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.SharedConstants"));
private static final ReflectMethod<?> getCurrentVersion = wrapEx(() -> MAPPING.mojMethod("getCurrentVersion"));
private static final ReflectMethod<?> getProtocolVersion = wrapEx(() -> MAPPING.mojMethod("getProtocolVersion"));
public static WorldVersion getCurrentVersion() {
return wrap(wrapReflectEx(() -> getCurrentVersion.invokeStatic()), WorldVersion.class);
}
public static int getProtocolVersion() {
return (int) wrapReflectEx(() -> getProtocolVersion.invokeStatic());
}
protected SharedConstants(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,22 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping;
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
@ConcreteWrapper(WorldVersion.__concrete.class)
public interface WorldVersion extends ReflectWrapperI {
ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.WorldVersion"));
class __concrete extends ReflectWrapper implements WorldVersion {
private __concrete(Object obj) {
super(obj);
}
}
}

View File

@@ -0,0 +1,24 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.mojang.brigadier.arguments.ArgumentType;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class BlockPosArgument extends ReflectWrapperTyped<ArgumentType<?>> {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.BlockPosArgument"));
private static final ReflectMethod<?> blockPos = wrapEx(() -> MAPPING.mojMethod("blockPos"));
@SuppressWarnings("unchecked")
public static ArgumentType<Object> blockPos() {
return (ArgumentType<Object>) wrapReflectEx(() -> blockPos.invokeStatic());
}
protected BlockPosArgument(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,15 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class CommandSourceStack extends ReflectWrapperTyped<BukkitBrigadierCommandSource> {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.CommandSourceStack"));
protected CommandSourceStack(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,25 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import com.mojang.brigadier.CommandDispatcher;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class Commands extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.Commands"));
public static final ReflectField<?> dispatcher = wrapEx(() -> MAPPING.mojField("dispatcher"));
@SuppressWarnings("unchecked")
public CommandDispatcher<BukkitBrigadierCommandSource> dispatcher() {
return (CommandDispatcher<BukkitBrigadierCommandSource>) wrapReflectEx(() -> dispatcher.getValue(__getRuntimeInstance()));
}
protected Commands(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,24 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.mojang.brigadier.arguments.ArgumentType;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ComponentArgument extends ReflectWrapperTyped<ArgumentType<?>> {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.ComponentArgument"));
private static final ReflectMethod<?> textComponent = wrapEx(() -> MAPPING.mojMethod("textComponent"));
@SuppressWarnings("unchecked")
public static ArgumentType<Object> textComponent() {
return (ArgumentType<Object>) wrapReflectEx(() -> textComponent.invokeStatic());
}
protected ComponentArgument(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,36 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.core.BlockPos;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Vec3;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
import static fr.pandacube.lib.reflect.wrapper.ReflectWrapper.wrap;
@ConcreteWrapper(Coordinates.__concrete.class)
public interface Coordinates extends ReflectWrapperI {
NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Coordinates"));
ReflectMethod<?> getPosition = wrapEx(() -> MAPPING.mojMethod("getPosition", CommandSourceStack.MAPPING));
ReflectMethod<?> getBlockPos = wrapEx(() -> MAPPING.mojMethod("getBlockPos", CommandSourceStack.MAPPING));
default Vec3 getPosition(BukkitBrigadierCommandSource source) {
return wrap(wrapReflectEx(() -> getPosition.invoke(__getRuntimeInstance(), source)), Vec3.class);
}
default BlockPos getBlockPos(BukkitBrigadierCommandSource source) {
return wrap(wrapReflectEx(() -> getBlockPos.invoke(__getRuntimeInstance(), source)), BlockPos.class);
}
class __concrete extends ReflectWrapper implements Coordinates {
protected __concrete(Object obj) {
super(obj);
}
}
}

View File

@@ -0,0 +1,43 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.mojang.brigadier.arguments.ArgumentType;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class EntityArgument extends ReflectWrapperTyped<ArgumentType<?>> {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.EntityArgument"));
private static final ReflectMethod<?> entity = wrapEx(() -> MAPPING.mojMethod("entity"));
private static final ReflectMethod<?> entities = wrapEx(() -> MAPPING.mojMethod("entities"));
private static final ReflectMethod<?> player = wrapEx(() -> MAPPING.mojMethod("player"));
private static final ReflectMethod<?> players = wrapEx(() -> MAPPING.mojMethod("players"));
@SuppressWarnings("unchecked")
public static ArgumentType<Object> entity() {
return (ArgumentType<Object>) wrapReflectEx(() -> entity.invokeStatic());
}
@SuppressWarnings("unchecked")
public static ArgumentType<Object> entities() {
return (ArgumentType<Object>) wrapReflectEx(() -> entities.invokeStatic());
}
@SuppressWarnings("unchecked")
public static ArgumentType<Object> player() {
return (ArgumentType<Object>) wrapReflectEx(() -> player.invokeStatic());
}
@SuppressWarnings("unchecked")
public static ArgumentType<Object> players() {
return (ArgumentType<Object>) wrapReflectEx(() -> players.invokeStatic());
}
protected EntityArgument(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,46 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.destroystokyo.paper.brigadier.BukkitBrigadierCommandSource;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectListWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.server.ServerPlayer;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Entity;
import fr.pandacube.lib.reflect.ReflectMethod;
import java.util.List;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class EntitySelector extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.selector.EntitySelector"));
private static final ReflectMethod<?> findEntities = wrapEx(() -> MAPPING.mojMethod("findEntities", CommandSourceStack.MAPPING));
private static final ReflectMethod<?> findPlayers = wrapEx(() -> MAPPING.mojMethod("findPlayers", CommandSourceStack.MAPPING));
private static final ReflectMethod<?> findSingleEntity = wrapEx(() -> MAPPING.mojMethod("findSingleEntity", CommandSourceStack.MAPPING));
private static final ReflectMethod<?> findSinglePlayer = wrapEx(() -> MAPPING.mojMethod("findSinglePlayer", CommandSourceStack.MAPPING));
@SuppressWarnings("unchecked")
public ReflectListWrapper<Entity> findEntities(BukkitBrigadierCommandSource source) {
return wrapList((List<Object>) wrapReflectEx(() -> findEntities.invoke(__getRuntimeInstance(), source)), Entity.class);
}
public Entity findSingleEntity(BukkitBrigadierCommandSource source) {
return wrap(wrapReflectEx(() -> findSingleEntity.invoke(__getRuntimeInstance(), source)), Entity.class);
}
@SuppressWarnings("unchecked")
public ReflectListWrapper<ServerPlayer> findPlayers(BukkitBrigadierCommandSource source) {
return wrapList((List<Object>) wrapReflectEx(() -> findPlayers.invoke(__getRuntimeInstance(), source)), ServerPlayer.class);
}
public ServerPlayer findSinglePlayer(BukkitBrigadierCommandSource source) {
return wrap(wrapReflectEx(() -> findSinglePlayer.invoke(__getRuntimeInstance(), source)), ServerPlayer.class);
}
protected EntitySelector(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,24 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.mojang.brigadier.arguments.ArgumentType;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class GameProfileArgument extends ReflectWrapperTyped<ArgumentType<?>> {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.GameProfileArgument"));
private static final ReflectMethod<?> gameProfile = wrapEx(() -> MAPPING.mojMethod("gameProfile"));
@SuppressWarnings("unchecked")
public static ArgumentType<Object> gameProfile() {
return (ArgumentType<Object>) wrapReflectEx(() -> gameProfile.invokeStatic());
}
protected GameProfileArgument(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,24 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.mojang.brigadier.arguments.ArgumentType;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ResourceLocationArgument extends ReflectWrapperTyped<ArgumentType<?>> {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.ResourceLocationArgument"));
private static final ReflectMethod<?> id = wrapEx(() -> MAPPING.mojMethod("id"));
@SuppressWarnings("unchecked")
public static ArgumentType<Object> id() {
return (ArgumentType<Object>) wrapReflectEx(() -> id.invokeStatic());
}
protected ResourceLocationArgument(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,25 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands;
import com.mojang.brigadier.arguments.ArgumentType;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperTyped;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class Vec3Argument extends ReflectWrapperTyped<ArgumentType<?>> {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.commands.arguments.coordinates.Vec3Argument"));
private static final ReflectMethod<?> vec3 = wrapEx(() -> MAPPING.mojMethod("vec3", boolean.class));
@SuppressWarnings("unchecked")
public static ArgumentType<Object> vec3(boolean centerIntegers) {
return (ArgumentType<Object>) wrapReflectEx(() -> vec3.invokeStatic(centerIntegers));
}
protected Vec3Argument(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,13 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.core;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class BlockPos extends Vec3i {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.core.BlockPos"));
protected BlockPos(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,31 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.core;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class Vec3i extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.core.Vec3i"));
public static final ReflectMethod<?> getX = wrapEx(() -> MAPPING.mojMethod("getX"));
public static final ReflectMethod<?> getY = wrapEx(() -> MAPPING.mojMethod("getY"));
public static final ReflectMethod<?> getZ = wrapEx(() -> MAPPING.mojMethod("getZ"));
public int getX() {
return (int) wrapReflectEx(() -> getX.invoke(__getRuntimeInstance()));
}
public int getY() {
return (int) wrapReflectEx(() -> getY.invoke(__getRuntimeInstance()));
}
public int getZ() {
return (int) wrapReflectEx(() -> getZ.invoke(__getRuntimeInstance()));
}
protected Vec3i(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,169 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import fr.pandacube.lib.reflect.ReflectMethod;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
public class CompoundTag extends ReflectWrapper implements Tag {
public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.nbt.CompoundTag"));
private static final ReflectMethod<?> putBoolean = wrapEx(() -> MAPPING.mojMethod("putBoolean", String.class, boolean.class));
private static final ReflectMethod<?> putByte = wrapEx(() -> MAPPING.mojMethod("putByte", String.class, byte.class));
private static final ReflectMethod<?> putByteArray = wrapEx(() -> MAPPING.mojMethod("putByteArray", String.class, byte[].class));
private static final ReflectMethod<?> putByteArray_List = wrapEx(() -> MAPPING.mojMethod("putByteArray", String.class, List.class));
private static final ReflectMethod<?> putDouble = wrapEx(() -> MAPPING.mojMethod("putDouble", String.class, double.class));
private static final ReflectMethod<?> putFloat = wrapEx(() -> MAPPING.mojMethod("putFloat", String.class, float.class));
private static final ReflectMethod<?> putInt = wrapEx(() -> MAPPING.mojMethod("putInt", String.class, int.class));
private static final ReflectMethod<?> putIntArray = wrapEx(() -> MAPPING.mojMethod("putIntArray", String.class, int[].class));
private static final ReflectMethod<?> putIntArray_List = wrapEx(() -> MAPPING.mojMethod("putIntArray", String.class, List.class));
private static final ReflectMethod<?> putString = wrapEx(() -> MAPPING.mojMethod("putString", String.class, String.class));
private static final ReflectMethod<?> putUUID = wrapEx(() -> MAPPING.mojMethod("putUUID", String.class, UUID.class));
private static final ReflectMethod<?> putLong = wrapEx(() -> MAPPING.mojMethod("putLong", String.class, long.class));
private static final ReflectMethod<?> putLongArray = wrapEx(() -> MAPPING.mojMethod("putLongArray", String.class, long[].class));
private static final ReflectMethod<?> putLongArray_List = wrapEx(() -> MAPPING.mojMethod("putLongArray", String.class, List.class));
private static final ReflectMethod<?> putShort = wrapEx(() -> MAPPING.mojMethod("putShort", String.class, short.class));
private static final ReflectMethod<?> put = wrapEx(() -> MAPPING.mojMethod("put", String.class, Tag.MAPPING));
private static final ReflectMethod<?> getTagType = wrapEx(() -> MAPPING.mojMethod("getTagType", String.class));
private static final ReflectMethod<?> getByte = wrapEx(() -> MAPPING.mojMethod("getByte", String.class));
private static final ReflectMethod<?> getShort = wrapEx(() -> MAPPING.mojMethod("getShort", String.class));
private static final ReflectMethod<?> getInt = wrapEx(() -> MAPPING.mojMethod("getInt", String.class));
private static final ReflectMethod<?> getLong = wrapEx(() -> MAPPING.mojMethod("getLong", String.class));
private static final ReflectMethod<?> getFloat = wrapEx(() -> MAPPING.mojMethod("getFloat", String.class));
private static final ReflectMethod<?> getDouble = wrapEx(() -> MAPPING.mojMethod("getDouble", String.class));
private static final ReflectMethod<?> getString = wrapEx(() -> MAPPING.mojMethod("getString", String.class));
private static final ReflectMethod<?> getByteArray = wrapEx(() -> MAPPING.mojMethod("getByteArray", String.class));
private static final ReflectMethod<?> getIntArray = wrapEx(() -> MAPPING.mojMethod("getIntArray", String.class));
private static final ReflectMethod<?> getLongArray = wrapEx(() -> MAPPING.mojMethod("getLongArray", String.class));
private static final ReflectMethod<?> getCompound = wrapEx(() -> MAPPING.mojMethod("getCompound", String.class));
private static final ReflectMethod<?> getBoolean = wrapEx(() -> MAPPING.mojMethod("getBoolean", String.class));
private static final ReflectMethod<?> get = wrapEx(() -> MAPPING.mojMethod("get", String.class));
private static final ReflectMethod<?> getAllKeys = wrapEx(() -> MAPPING.mojMethod("getAllKeys"));
private static final ReflectMethod<?> entries = wrapEx(() -> MAPPING.mojMethod("entries"));
private static final ReflectMethod<?> size = wrapEx(() -> MAPPING.mojMethod("size"));
private static final ReflectMethod<?> contains = wrapEx(() -> MAPPING.mojMethod("contains", String.class));
public CompoundTag(Object nms) {
super(nms);
}
public void putBoolean(String key, boolean value) {
wrapReflectEx(() -> putBoolean.invoke(__getRuntimeInstance(), key, value));
}
public void putByte(String key, byte value) {
wrapReflectEx(() -> putByte.invoke(__getRuntimeInstance(), key, value));
}
public void putByteArray(String key, byte[] value) {
wrapReflectEx(() -> putByteArray.invoke(__getRuntimeInstance(), key, value));
}
public void putByteArray(String key, List<Byte> value) {
wrapReflectEx(() -> putByteArray_List.invoke(__getRuntimeInstance(), key, value));
}
public void putDouble(String key, double value) {
wrapReflectEx(() -> putDouble.invoke(__getRuntimeInstance(), key, value));
}
public void putFloat(String key, float value) {
wrapReflectEx(() -> putFloat.invoke(__getRuntimeInstance(), key, value));
}
public void putInt(String key, int value) {
wrapReflectEx(() -> putInt.invoke(__getRuntimeInstance(), key, value));
}
public void putIntArray(String key, int[] value) {
wrapReflectEx(() -> putIntArray.invoke(__getRuntimeInstance(), key, value));
}
public void putIntArray(String key, List<Integer> value) {
wrapReflectEx(() -> putIntArray_List.invoke(__getRuntimeInstance(), key, value));
}
public void putString(String key, String value) {
wrapReflectEx(() -> putString.invoke(__getRuntimeInstance(), key, value));
}
public void putUUID(String key, UUID value) {
wrapReflectEx(() -> putUUID.invoke(__getRuntimeInstance(), key, value));
}
public void putLong(String key, long value) {
wrapReflectEx(() -> putLong.invoke(__getRuntimeInstance(), key, value));
}
public void putLongArray(String key, long[] value) {
wrapReflectEx(() -> putLongArray.invoke(__getRuntimeInstance(), key, value));
}
public void putLongArray(String key, List<Long> value) {
wrapReflectEx(() -> putLongArray_List.invoke(__getRuntimeInstance(), key, value));
}
public void putShort(String key, short value) {
wrapReflectEx(() -> putShort.invoke(__getRuntimeInstance(), key, value));
}
public void put(String key, Tag value) {
wrapReflectEx(() -> put.invoke(__getRuntimeInstance(), key, unwrap(value)));
}
public byte getTagType(String key) {
return (byte) wrapReflectEx(() -> getTagType.invoke(__getRuntimeInstance(), key));
}
public byte getByte(String key) {
return (byte) wrapReflectEx(() -> getByte.invoke(__getRuntimeInstance(), key));
}
public short getShort(String key) {
return (short) wrapReflectEx(() -> getShort.invoke(__getRuntimeInstance(), key));
}
public int getInt(String key) {
return (int) wrapReflectEx(() -> getInt.invoke(__getRuntimeInstance(), key));
}
public long getLong(String key) {
return (long) wrapReflectEx(() -> getLong.invoke(__getRuntimeInstance(), key));
}
public float getFloat(String key) {
return (float) wrapReflectEx(() -> getFloat.invoke(__getRuntimeInstance(), key));
}
public double getDouble(String key) {
return (double) wrapReflectEx(() -> getDouble.invoke(__getRuntimeInstance(), key));
}
public String getString(String key) {
return (String) wrapReflectEx(() -> getString.invoke(__getRuntimeInstance(), key));
}
public byte[] getByteArray(String key) {
return (byte[]) wrapReflectEx(() -> getByteArray.invoke(__getRuntimeInstance(), key));
}
public int[] getIntArray(String key) {
return (int[]) wrapReflectEx(() -> getIntArray.invoke(__getRuntimeInstance(), key));
}
public long[] getLongArray(String key) {
return (long[]) wrapReflectEx(() -> getLongArray.invoke(__getRuntimeInstance(), key));
}
public CompoundTag getCompound(String key) {
return wrap(wrapReflectEx(() -> getCompound.invoke(__getRuntimeInstance(), key)), CompoundTag.class);
}
public boolean getBoolean(String key) {
return (boolean) wrapReflectEx(() -> getBoolean.invoke(__getRuntimeInstance(), key));
}
public Tag get(String key) {
return wrap(wrapReflectEx(() -> get.invoke(__getRuntimeInstance(), key)), Tag.class);
}
@SuppressWarnings("unchecked")
public Set<String> getAllKeys() {
return (Set<String>) wrapReflectEx(() -> getAllKeys.invoke(__getRuntimeInstance()));
}
/**
* The values in the returned Map are not wrapped.
*/
@SuppressWarnings("unchecked")
public Map<String, ?> entries() {
// we cannot easily wrap every value of the map without being able to synch the returned map with the wrapped map
return (Map<String, ?>) wrapReflectEx(() -> entries.invoke(__getRuntimeInstance()));
}
public int size() {
return (int) wrapReflectEx(() -> size.invoke(__getRuntimeInstance()));
}
public boolean contains(String key) {
return (boolean) wrapReflectEx(() -> contains.invoke(__getRuntimeInstance(), key));
}
}

View File

@@ -0,0 +1,30 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import java.io.File;
import fr.pandacube.lib.reflect.ReflectMethod;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
public class NbtIo extends ReflectWrapper {
public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.nbt.NbtIo"));
private static final ReflectMethod<?> readCompressed = wrapEx(() -> MAPPING.mojMethod("readCompressed", File.class));
private static final ReflectMethod<?> writeCompressed = wrapEx(() -> MAPPING.mojMethod("writeCompressed", CompoundTag.MAPPING, File.class));
private NbtIo(Object obj) {
super(obj);
}
public static CompoundTag readCompressed(File f) {
return new CompoundTag(wrapEx(() -> readCompressed.invokeStatic(f)));
}
public static void writeCompressed(CompoundTag tag, File f) {
Object nmsTag = ReflectWrapper.unwrap(tag);
wrapEx(() -> writeCompressed.invokeStatic(nmsTag, f));
}
}

View File

@@ -0,0 +1,17 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
public class StringTag extends ReflectWrapper implements Tag {
public static final ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.nbt.StringTag"));
public StringTag(Object nms) {
super(nms);
}
}

View File

@@ -0,0 +1,31 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
import fr.pandacube.lib.reflect.ReflectMethod;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.NMSReflect.ClassMapping;
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
@ConcreteWrapper(Tag.__concrete.class)
public interface Tag extends ReflectWrapperI {
ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.nbt.Tag"));
ReflectMethod<?> getAsString = wrapEx(() -> MAPPING.mojMethod("getAsString"));
default String getAsString() {
return wrapReflectEx(() -> (String) getAsString.invoke(__getRuntimeInstance()));
}
class __concrete extends ReflectWrapper implements Tag {
private __concrete(Object obj) {
super(obj);
}
}
}

View File

@@ -0,0 +1,27 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.network;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.wrapper.netty.ByteBuf;
import fr.pandacube.lib.reflect.ReflectConstructor;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class FriendlyByteBuf extends ByteBuf {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.FriendlyByteBuf"));
private static final ReflectConstructor<?> CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor(ByteBuf.REFLECT.get()));
private static final ReflectMethod<?> writeUtf = wrapEx(() -> MAPPING.mojMethod("writeUtf", String.class));
public FriendlyByteBuf(ByteBuf parent) {
this(wrapReflectEx(() -> CONSTRUCTOR.instanciate(unwrap(parent))));
}
public FriendlyByteBuf writeUtf(String string) {
return wrap(wrapReflectEx(() -> writeUtf.invoke(__getRuntimeInstance(), string)), FriendlyByteBuf.class);
}
protected FriendlyByteBuf(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,20 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.chat;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
@ConcreteWrapper(Component.__concrete.class)
public interface Component extends ReflectWrapperI {
NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.chat.Component"));
class __concrete extends ReflectWrapper implements Component {
protected __concrete(Object obj) {
super(obj);
}
}
}

View File

@@ -0,0 +1,29 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.protocol;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.FriendlyByteBuf;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.resources.ResourceLocation;
import fr.pandacube.lib.reflect.ReflectConstructor;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ClientboundCustomPayloadPacket extends ReflectWrapper implements Packet {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket"));
private static final ReflectConstructor<?> CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor(ResourceLocation.MAPPING.runtimeClass(), FriendlyByteBuf.MAPPING.runtimeClass()));
private static final ReflectField<?> FIELD_BRAND = wrapEx(() -> MAPPING.mojField("BRAND"));
public static ResourceLocation BRAND() {
return wrap(wrapReflectEx(FIELD_BRAND::getStaticValue), ResourceLocation.class);
}
protected ClientboundCustomPayloadPacket(Object obj) {
super(obj);
}
public ClientboundCustomPayloadPacket(ResourceLocation res, FriendlyByteBuf buff) {
this(wrapReflectEx(() -> CONSTRUCTOR.instanciate(unwrap(res), unwrap(buff))));
}
}

View File

@@ -0,0 +1,40 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.protocol;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectConstructor;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ClientboundGameEventPacket extends ReflectWrapper implements Packet {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.protocol.game.ClientboundGameEventPacket"));
private static final ReflectConstructor<?> CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor(Type.MAPPING.runtimeClass(), float.class));
private static final ReflectField<?> FIELD_RAIN_LEVEL_CHANGE = wrapEx(() -> MAPPING.mojField("RAIN_LEVEL_CHANGE"));
private static final ReflectField<?> FIELD_THUNDER_LEVEL_CHANGE = wrapEx(() -> MAPPING.mojField("THUNDER_LEVEL_CHANGE"));
public static Type RAIN_LEVEL_CHANGE() {
return wrap(wrapReflectEx(FIELD_RAIN_LEVEL_CHANGE::getStaticValue), Type.class);
}
public static Type THUNDER_LEVEL_CHANGE() {
return wrap(wrapReflectEx(FIELD_THUNDER_LEVEL_CHANGE::getStaticValue), Type.class);
}
public ClientboundGameEventPacket(Type type, float value) {
this(wrapReflectEx(() -> CONSTRUCTOR.instanciate(unwrap(type), value)));
}
protected ClientboundGameEventPacket(Object obj) {
super(obj);
}
public static class Type extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.protocol.game.ClientboundGameEventPacket$Type"));
protected Type(Object obj) {
super(obj);
}
}
}

View File

@@ -0,0 +1,19 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.protocol;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
@ConcreteWrapper(Packet.__concrete.class)
public interface Packet extends ReflectWrapperI {
NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.network.protocol.Packet"));
class __concrete extends ReflectWrapper implements Packet {
protected __concrete(Object obj) {
super(obj);
}
}
}

View File

@@ -0,0 +1,15 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.resources;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class ResourceLocation extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.resources.ResourceLocation"));
protected ResourceLocation(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,21 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.ChunkStorage;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ChunkMap extends ChunkStorage {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.level.ChunkMap"));
private static final ReflectField<?> FIELD_level = wrapEx(() -> MAPPING.mojField("level"));
public final ServerLevel level;
protected ChunkMap(Object obj) {
super(obj);
level = wrap(wrapReflectEx(() -> FIELD_level.getValue(obj)), ServerLevel.class);
}
}

View File

@@ -0,0 +1,14 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class DedicatedPlayerList extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.dedicated.DedicatedPlayerList"));
protected DedicatedPlayerList(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,25 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class DedicatedServer extends MinecraftServer {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.dedicated.DedicatedServer"));
private static final ReflectMethod<?> getLevelIdName = wrapEx(() -> MAPPING.mojMethod("getLevelIdName"));
private static final ReflectMethod<?> getProperties = wrapEx(() -> MAPPING.mojMethod("getProperties"));
public String getLevelIdName() {
return (String) wrapReflectEx(() -> getLevelIdName.invoke(__getRuntimeInstance()));
}
public DedicatedServerProperties getProperties() {
return wrap(wrapReflectEx(() -> getProperties.invoke(__getRuntimeInstance())), DedicatedServerProperties.class);
}
protected DedicatedServer(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,13 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class DedicatedServerProperties extends Settings {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.dedicated.DedicatedServerProperties"));
protected DedicatedServerProperties(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,22 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.commands.Commands;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class MinecraftServer extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.MinecraftServer"));
private static final ReflectField<?> vanillaCommandDispatcher = wrapEx(() -> MAPPING.runtimeReflect().field("vanillaCommandDispatcher"));
public Commands vanillaCommandDispatcher() {
return wrap(wrapReflectEx(() -> vanillaCommandDispatcher.getValue(__getRuntimeInstance())), Commands.class);
}
protected MinecraftServer(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,21 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ServerChunkCache extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.level.ServerChunkCache"));
private static final ReflectField<?> FIELD_chunkMap = wrapEx(() -> MAPPING.mojField("chunkMap"));
public final ChunkMap chunkMap;
protected ServerChunkCache(Object obj) {
super(obj);
chunkMap = wrap(wrapReflectEx(() -> FIELD_chunkMap.getValue(obj)), ChunkMap.class);
}
}

View File

@@ -0,0 +1,22 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.protocol.Packet;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ServerGamePacketListenerImpl extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.network.ServerGamePacketListenerImpl"));
public static final ReflectMethod<?> send = wrapEx(() -> MAPPING.mojMethod("send", Packet.MAPPING));
public void send(Packet packet) {
wrapReflectEx(() -> send.invoke(__getRuntimeInstance(), unwrap(packet)));
}
protected ServerGamePacketListenerImpl(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,29 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.util.ProgressListener;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Level;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ServerLevel extends Level {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.level.ServerLevel"));
public static final ReflectMethod<?> save = wrapEx(() -> MAPPING.mojMethod("save", ProgressListener.MAPPING, boolean.class, boolean.class));
public static final ReflectMethod<?> getChunkSource = wrapEx(() -> MAPPING.mojMethod("getChunkSource"));
public ServerChunkCache getChunkSource() {
return wrap(wrapReflectEx(() -> getChunkSource.invoke(__getRuntimeInstance())), ServerChunkCache.class);
}
public void save(ProgressListener listener, boolean flush, boolean savingDisabled) {
wrapReflectEx(() -> save.invoke(__getRuntimeInstance(), unwrap(listener), flush, savingDisabled));
}
protected ServerLevel(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,45 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import org.bukkit.entity.Player;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.DamageSource;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.Entity;
import fr.pandacube.lib.reflect.ReflectField;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ServerPlayer extends Entity { // in NMS, ServerPlayer is not a direct subclass of Entity
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.level.ServerPlayer"));
public static final ReflectField<?> connection = wrapEx(() -> MAPPING.mojField("connection"));
public static final ReflectMethod<?> hurt = wrapEx(() -> MAPPING.mojMethod("hurt", DamageSource.MAPPING, float.class));
public static final ReflectMethod<?> isTextFilteringEnabled = wrapEx(() -> MAPPING.mojMethod("isTextFilteringEnabled"));
public static final ReflectMethod<?> allowsListing = wrapEx(() -> MAPPING.mojMethod("allowsListing"));
public boolean hurt(DamageSource source, float amount) {
return (boolean) wrapReflectEx(() -> hurt.invoke(__getRuntimeInstance(), unwrap(source), amount));
}
public boolean isTextFilteringEnabled() {
return (boolean) wrapReflectEx(() -> isTextFilteringEnabled.invoke(__getRuntimeInstance()));
}
public boolean allowsListing() {
return (boolean) wrapReflectEx(() -> allowsListing.invoke(__getRuntimeInstance()));
}
public ServerGamePacketListenerImpl connection() {
return wrap(wrapReflectEx(() -> connection.getValue(__getRuntimeInstance())), ServerGamePacketListenerImpl.class);
}
@Override
public Player getBukkitEntity() {
return (Player) super.getBukkitEntity();
}
protected ServerPlayer(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,23 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.server;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectField;
import java.util.Properties;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class Settings extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.server.dedicated.Settings"));
public static final ReflectField<?> properties = wrapEx(() -> MAPPING.mojField("properties"));
public Properties properties() {
return (Properties) wrapReflectEx(() -> properties.getValue(__getRuntimeInstance()));
}
protected Settings(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,20 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.util;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ConcreteWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapperI;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
@ConcreteWrapper(ProgressListener.__concrete.class)
public interface ProgressListener extends ReflectWrapperI {
NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.util.ProgressListener"));
class __concrete extends ReflectWrapper implements ProgressListener {
protected __concrete(Object obj) {
super(obj);
}
}
}

View File

@@ -0,0 +1,21 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectConstructor;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class AABB extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.phys.AABB"));
private static final ReflectConstructor<?> CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor(double.class, double.class, double.class, double.class, double.class, double.class));
public AABB(double x1, double y1, double z1, double x2, double y2, double z2) {
this(wrapReflectEx(() -> CONSTRUCTOR.instanciate(x1, y1, z1, x2, y2, z2)));
}
protected AABB(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,21 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectConstructor;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ChunkPos extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.level.ChunkPos"));
public static final ReflectConstructor<?> CONSTRUCTOR = wrapEx(() -> MAPPING.runtimeReflect().constructor(int.class, int.class));
public ChunkPos(int x, int z) {
this(wrapReflectEx(() -> CONSTRUCTOR.instanciate(x, z)));
}
protected ChunkPos(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,31 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.nbt.CompoundTag;
import fr.pandacube.lib.reflect.ReflectMethod;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class ChunkStorage extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.level.chunk.storage.ChunkStorage"));
private static final ReflectMethod<?> readSync = wrapEx(() -> MAPPING.runtimeReflect().method("readSync", ChunkPos.MAPPING.runtimeReflect().get())); // spigot/paper method
public CompoundTag readSync(ChunkPos pos) {
return wrap(wrapReflectEx(() -> readSync.invoke(__getRuntimeInstance(), unwrap(pos))), CompoundTag.class);
}
public CompletableFuture<Optional<CompoundTag>> read(ChunkPos pos) {
@SuppressWarnings("unchecked")
CompletableFuture<Optional<?>> nmsFuture = (CompletableFuture<Optional<?>>) wrapReflectEx(() -> readSync.invoke(__getRuntimeInstance(), unwrap(pos)));
return nmsFuture.thenApply(o -> o.map(c -> wrap(c, CompoundTag.class)));
}
protected ChunkStorage(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,21 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class DamageSource extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.damagesource.DamageSource"));
private static final ReflectField<?> FIELD_OUT_OF_WORLD = wrapEx(() -> MAPPING.mojField("OUT_OF_WORLD"));
public static DamageSource OUT_OF_WORLD() {
return wrap(wrapReflectEx(FIELD_OUT_OF_WORLD::getStaticValue), DamageSource.class);
}
protected DamageSource(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,21 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class Entity extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.entity.Entity"));
public static final ReflectMethod<?> getBukkitEntity = wrapEx(() -> MAPPING.runtimeReflect().method("getBukkitEntity")); // spigot field
public org.bukkit.entity.Entity getBukkitEntity() {
return (org.bukkit.entity.Entity) wrapReflectEx(() -> getBukkitEntity.invoke(__getRuntimeInstance()));
}
protected Entity(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,32 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.paper.configuration.WorldConfiguration;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class Level extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.level.Level"));
public static final ReflectMethod<?> getGameTime = wrapEx(() -> MAPPING.mojMethod("getGameTime"));
public static final ReflectMethod<?> getFreeMapId = wrapEx(() -> MAPPING.mojMethod("getFreeMapId"));
public static final ReflectMethod<?> paperConfig = wrapEx(() -> MAPPING.runtimeReflect().method("paperConfig")); // paper method
public long getGameTime() {
return (long) wrapReflectEx(() -> getGameTime.invoke(__getRuntimeInstance()));
}
public int getFreeMapId() {
return (int) wrapReflectEx(() -> getFreeMapId.invoke(__getRuntimeInstance()));
}
public WorldConfiguration paperConfig() {
return wrap(wrapReflectEx(() -> paperConfig.invoke(__getRuntimeInstance())), WorldConfiguration.class);
}
protected Level(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,33 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class MapItemSavedData extends SavedData {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.level.saveddata.maps.MapItemSavedData"));
public static final ReflectField<?> colors = wrapEx(() -> MAPPING.mojField("colors"));
public static final ReflectField<?> locked = wrapEx(() -> MAPPING.mojField("locked"));
protected MapItemSavedData(Object obj) {
super(obj);
}
public boolean locked() {
return (boolean) wrapReflectEx(() -> locked.getValue(__getRuntimeInstance()));
}
public void locked(boolean l) {
wrapReflectEx(() -> locked.setValue(__getRuntimeInstance(), l));
}
public byte[] colors() {
return (byte[]) wrapReflectEx(() -> colors.getValue(__getRuntimeInstance()));
}
public void colors(byte[] c) {
wrapReflectEx(() -> colors.setValue(__getRuntimeInstance(), c));
}
}

View File

@@ -0,0 +1,21 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class SavedData extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.level.saveddata.SavedData"));
private static final ReflectMethod<?> setDirty = wrapEx(() -> MAPPING.mojMethod("setDirty"));
protected SavedData(Object obj) {
super(obj);
}
public void setDirty() {
wrapReflectEx(() -> setDirty.invoke(__getRuntimeInstance()));
}
}

View File

@@ -0,0 +1,14 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class Vec3 extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.phys.Vec3"));
protected Vec3(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,14 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class VoxelShape extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.phys.shapes.VoxelShape"));
protected VoxelShape(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,26 @@
package fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.block;
import fr.pandacube.lib.paper.reflect.NMSReflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.VoxelShape;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class BambooBlock extends ReflectWrapper {
public static final NMSReflect.ClassMapping MAPPING = wrapEx(() -> NMSReflect.mojClass("net.minecraft.world.level.block.BambooBlock"));
public static final ReflectField<?> COLLISION_SHAPE = wrapEx(() -> MAPPING.mojField("COLLISION_SHAPE"));
public static VoxelShape COLLISION_SHAPE() {
return wrap(wrapReflectEx(COLLISION_SHAPE::getStaticValue), VoxelShape.class);
}
public static void COLLISION_SHAPE(VoxelShape shape) {
wrapReflectEx(() -> COLLISION_SHAPE.setStaticValue(unwrap(shape)));
}
protected BambooBlock(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,17 @@
package fr.pandacube.lib.paper.reflect.wrapper.netty;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectClass;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
public class ByteBuf extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.netty.buffer.ByteBuf"));
protected ByteBuf(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,25 @@
package fr.pandacube.lib.paper.reflect.wrapper.netty;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class Unpooled extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.netty.buffer.Unpooled"));
private static final ReflectMethod<?> buffer = wrapEx(() -> REFLECT.method("buffer"));
public static ByteBuf buffer() {
return wrap(wrapReflectEx(() -> buffer.invokeStatic()), ByteBuf.class);
}
protected Unpooled(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,23 @@
package fr.pandacube.lib.paper.reflect.wrapper.paper;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.AABB;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.world.VoxelShape;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectConstructor;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class AABBVoxelShape extends VoxelShape {
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.voxel.AABBVoxelShape"));
private static final ReflectConstructor<?> CONSTRUCTOR = wrapEx(() -> REFLECT.constructor(AABB.MAPPING.runtimeClass()));
public AABBVoxelShape(AABB aabb) {
this(wrapReflectEx(() -> CONSTRUCTOR.instanciate(unwrap(aabb))));
}
protected AABBVoxelShape(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,26 @@
package fr.pandacube.lib.paper.reflect.wrapper.paper;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.paper.reflect.wrapper.minecraft.network.chat.Component;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class PaperAdventure extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.adventure.PaperAdventure"));
private static final ReflectMethod<?> asAdventure = wrapEx(() -> REFLECT.method("asAdventure", Component.MAPPING.runtimeClass()));
public static net.kyori.adventure.text.Component asAdventure(Component component) {
return (net.kyori.adventure.text.Component) wrapReflectEx(() -> asAdventure.invokeStatic(unwrap(component)));
}
protected PaperAdventure(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,25 @@
package fr.pandacube.lib.paper.reflect.wrapper.paper;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class QueuedChangesMapLong2Object extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("com.destroystokyo.paper.util.map.QueuedChangesMapLong2Object"));
public static final ReflectMethod<?> getVisibleMap = wrapEx(() -> REFLECT.method("getVisibleMap"));
/** The entries in the returned value are not mapped */
public Long2ObjectLinkedOpenHashMap<?> getVisibleMap() {
return (Long2ObjectLinkedOpenHashMap<?>) wrapReflectEx(() -> getVisibleMap.invoke(__getRuntimeInstance()));
}
protected QueuedChangesMapLong2Object(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,22 @@
package fr.pandacube.lib.paper.reflect.wrapper.paper.configuration;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectMethod;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class FallbackValue_Int extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.configuration.type.fallback.FallbackValue$Int"));
public static final ReflectMethod<?> value = wrapEx(() -> REFLECT.method("value"));
public int value() {
return (int) wrapReflectEx(() -> value.invoke(__getRuntimeInstance()));
}
protected FallbackValue_Int(Object obj) {
super(obj);
}
}

View File

@@ -0,0 +1,35 @@
package fr.pandacube.lib.paper.reflect.wrapper.paper.configuration;
import fr.pandacube.lib.reflect.Reflect;
import fr.pandacube.lib.reflect.wrapper.ReflectWrapper;
import fr.pandacube.lib.reflect.ReflectClass;
import fr.pandacube.lib.reflect.ReflectField;
import static fr.pandacube.lib.util.ThrowableUtil.wrapEx;
import static fr.pandacube.lib.util.ThrowableUtil.wrapReflectEx;
public class WorldConfiguration extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.configuration.WorldConfiguration"));
public static final ReflectField<?> chunks = wrapEx(() -> REFLECT.field("chunks"));
public Chunks chunks() {
return wrap(wrapReflectEx(() -> chunks.getValue(__getRuntimeInstance())), Chunks.class);
}
protected WorldConfiguration(Object obj) {
super(obj);
}
public static class Chunks extends ReflectWrapper {
public static final ReflectClass<?> REFLECT = wrapEx(() -> Reflect.ofClass("io.papermc.paper.configuration.WorldConfiguration$Chunks"));
public static final ReflectField<?> autoSavePeriod = wrapEx(() -> REFLECT.field("autoSaveInterval"));
public FallbackValue_Int autoSavePeriod() {
return wrap(wrapReflectEx(() -> autoSavePeriod.getValue(__getRuntimeInstance())), FallbackValue_Int.class);
}
protected Chunks(Object obj) {
super(obj);
}
}
}