Merge pull request #137 from Ingrim4/feat/support-1.21
Add support for 1.20.6/1.21
This commit is contained in:
4 files changed
+65
-36
No files matched your search
@@ -42,7 +42,7 @@
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.20.6-R0.1-SNAPSHOT</version>
|
||||
<version>1.21.1-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
<dependency>
|
||||
<groupId>org.bstats</groupId>
|
||||
<artifactId>bstats-bukkit</artifactId>
|
||||
<version>3.0.2</version>
|
||||
<version>3.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- https://central.sonatype.com/artifact/net.luckperms/api -->
|
||||
@@ -103,17 +103,17 @@
|
||||
|
||||
<!-- https://jitpack.io/com/github/TownyAdvanced/towny/ -->
|
||||
<dependency>
|
||||
<groupId>com.github.TownyAdvanced</groupId>
|
||||
<groupId>com.github.TownyAdvanced.Towny</groupId>
|
||||
<artifactId>towny</artifactId>
|
||||
<version>0.100.2.11</version>
|
||||
<version>0.100.4.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- https://jitpack.io/com/github/Angeschossen/LandsAPI/ -->
|
||||
<dependency>
|
||||
<groupId>com.github.angeschossen</groupId>
|
||||
<groupId>com.github.Angeschossen</groupId>
|
||||
<artifactId>LandsAPI</artifactId>
|
||||
<version>7.1.12</version>
|
||||
<version>7.9.17</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>24.1.0</version>
|
||||
<version>26.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
@@ -2,17 +2,30 @@ package io.josemmo.bukkit.plugin.packets;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.injector.StructureCache;
|
||||
import com.comphenix.protocol.reflect.ExactReflection;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import io.josemmo.bukkit.plugin.utils.Internals;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.Optional;
|
||||
|
||||
public class MapDataPacket extends PacketContainer {
|
||||
private static final int LOCKED_INDEX;
|
||||
private static final @Nullable Constructor<?> MAP_ID_CONSTRUCTOR;
|
||||
private @Nullable StructureModifier<?> mapDataModifier;
|
||||
|
||||
static {
|
||||
LOCKED_INDEX = (Internals.MINECRAFT_VERSION < 17) ? 1 : 0;
|
||||
if (Internals.MINECRAFT_VERSION < 20.5) {
|
||||
MAP_ID_CONSTRUCTOR = null;
|
||||
} else {
|
||||
Class<?> mapIdClass = MinecraftReflection.getNullableNMS("world.level.saveddata.maps.MapId");
|
||||
MAP_ID_CONSTRUCTOR = ExactReflection.fromClass(mapIdClass, true).findConstructor(int.class);
|
||||
}
|
||||
}
|
||||
|
||||
public MapDataPacket() {
|
||||
@@ -20,18 +33,34 @@ public class MapDataPacket extends PacketContainer {
|
||||
getModifier().writeDefaults();
|
||||
|
||||
if (Internals.MINECRAFT_VERSION < 17) {
|
||||
// Disable tracking position
|
||||
getBooleans().write(0, false);
|
||||
} else {
|
||||
// Create modifier for map data instance
|
||||
getBooleans().write(0, false); // Disable tracking position
|
||||
} else if (Internals.MINECRAFT_VERSION < 20.5) {
|
||||
Class<?> mapDataType = getModifier().getField(4).getType();
|
||||
Object mapDataInstance = getModifier().read(4);
|
||||
mapDataModifier = new StructureModifier<>(mapDataType).withTarget(mapDataInstance);
|
||||
} else {
|
||||
ParameterizedType genericType = (ParameterizedType) getModifier().getField(4).getGenericType();
|
||||
Class<?> mapDataType = (Class<?>) genericType.getActualTypeArguments()[0];
|
||||
Object mapDataInstance = StructureCache.newInstance(mapDataType);
|
||||
getModifier().write(3, Optional.empty());
|
||||
getModifier().write(4, Optional.of(mapDataInstance));
|
||||
mapDataModifier = new StructureModifier<>(mapDataType).withTarget(mapDataInstance);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public @NotNull MapDataPacket setId(int id) {
|
||||
getIntegers().write(0, id);
|
||||
if (MAP_ID_CONSTRUCTOR == null) {
|
||||
getIntegers().write(0, id);
|
||||
} else {
|
||||
try {
|
||||
Class<?> mapIdClass = MAP_ID_CONSTRUCTOR.getDeclaringClass();
|
||||
Object mapIdInstance = MAP_ID_CONSTRUCTOR.newInstance(id);
|
||||
((StructureModifier) getSpecificModifier(mapIdClass)).write(0, mapIdInstance);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to instantiate MapId for map #" + id);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
@@ -88,7 +88,11 @@ public abstract class FakeEntity {
|
||||
if (NETWORK_MANAGER_INJECTOR == null) { // Use single-threaded packet sending if reflection failed
|
||||
CONNECTION.sendServerPacket(player, packet);
|
||||
} else { // Use non-blocking packet sending if available (faster, the expected case)
|
||||
NETWORK_MANAGER_INJECTOR.getInjector(player).sendClientboundPacket(packet, null, false);
|
||||
NETWORK_MANAGER_INJECTOR.getInjector(player).sendClientboundPacket(
|
||||
packet.getHandle(),
|
||||
null,
|
||||
false
|
||||
);
|
||||
}
|
||||
} catch (IllegalStateException e) {
|
||||
// Server is shutting down and cannot send the packet, ignore
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package io.josemmo.bukkit.plugin.utils;
|
||||
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
||||
public class Internals {
|
||||
public static final float MINECRAFT_VERSION;
|
||||
@@ -28,28 +30,22 @@ public class Internals {
|
||||
Class<?> obcClass = obcInstance.getClass();
|
||||
|
||||
// Get "net.minecraft.server.MinecraftServer" references
|
||||
Object nmsInstance = obcClass.getDeclaredMethod("getServer").invoke(obcInstance);
|
||||
Class<?> nmsClass = nmsInstance.getClass().getSuperclass();
|
||||
Object nmsServerInstance = obcClass.getDeclaredMethod("getServer").invoke(obcInstance);
|
||||
|
||||
if (MINECRAFT_VERSION >= 20.5) {
|
||||
// Get "net.minecraft.commands.Commands" references
|
||||
Object nmsCommandsInstance = nmsClass.getDeclaredMethod("getCommands").invoke(nmsInstance);
|
||||
Class<?> nmsCommandsClass = nmsCommandsInstance.getClass();
|
||||
// Get "net.minecraft.server.CommandDispatcher" references
|
||||
Class<?> nmsDispatcherClass = MinecraftReflection.getMinecraftClass(
|
||||
"CommandDispatcher", // Spigot <1.17
|
||||
"commands.CommandDispatcher", // Spigot >=1.17
|
||||
"commands.Commands" // PaperMC
|
||||
);
|
||||
Object nmsDispatcherInstance = FuzzyReflection.fromObject(nmsServerInstance, true)
|
||||
.getMethodByReturnTypeAndParameters("getDispatcher", nmsDispatcherClass)
|
||||
.invoke(nmsServerInstance);
|
||||
|
||||
// Get "com.mojang.brigadier.CommandDispatcher" instance
|
||||
Field nmsDispatcherField = nmsCommandsClass.getDeclaredField("dispatcher");
|
||||
nmsDispatcherField.setAccessible(true);
|
||||
DISPATCHER = (CommandDispatcher<?>) nmsDispatcherField.get(nmsCommandsInstance);
|
||||
} else {
|
||||
// Get "net.minecraft.server.CommandDispatcher" references
|
||||
Object nmsDispatcherInstance = nmsClass.getDeclaredField("vanillaCommandDispatcher").get(nmsInstance);
|
||||
Class<?> nmsDispatcherClass = nmsDispatcherInstance.getClass();
|
||||
|
||||
// Get "com.mojang.brigadier.CommandDispatcher" instance
|
||||
Method getDispatcherMethod = nmsDispatcherClass.getDeclaredMethod("a");
|
||||
getDispatcherMethod.setAccessible(true);
|
||||
DISPATCHER = (CommandDispatcher<?>) getDispatcherMethod.invoke(nmsDispatcherInstance);
|
||||
}
|
||||
// Get "com.mojang.brigadier.CommandDispatcher" instance
|
||||
DISPATCHER = (CommandDispatcher<?>) FuzzyReflection.fromObject(nmsDispatcherInstance, true)
|
||||
.getMethodByReturnTypeAndParameters("getDispatcher", CommandDispatcher.class)
|
||||
.invoke(nmsDispatcherInstance);
|
||||
|
||||
// Get command map instance
|
||||
Field commandMapField = obcClass.getDeclaredField("commandMap");
|
||||
|
||||
Reference in new issue
Block a user