Start 1.20.4 update

This commit is contained in:
Dan Mulloy 2023-12-09 15:56:45 -06:00
parent 80a097953f
commit 8ba1dc1284
No known key found for this signature in database
GPG Key ID: 3C5AD5D866D1539A
22 changed files with 206 additions and 99 deletions

View File

@ -34,8 +34,8 @@ repositories {
dependencies {
implementation 'net.bytebuddy:byte-buddy:1.14.9'
compileOnly 'org.spigotmc:spigot-api:1.20.2-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot:1.20.2-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot-api:1.20.4-R0.1-SNAPSHOT'
compileOnly 'org.spigotmc:spigot:1.20.4-R0.1-SNAPSHOT'
compileOnly 'io.netty:netty-all:4.0.23.Final'
compileOnly 'net.kyori:adventure-text-serializer-gson:4.13.0'
compileOnly 'com.googlecode.json-simple:json-simple:1.1.1'
@ -46,7 +46,7 @@ dependencies {
testImplementation 'org.mockito:mockito-core:5.6.0'
testImplementation 'io.netty:netty-common:4.1.97.Final'
testImplementation 'io.netty:netty-transport:4.1.97.Final'
testImplementation 'org.spigotmc:spigot:1.20.2-R0.1-SNAPSHOT'
testImplementation 'org.spigotmc:spigot:1.20.4-R0.1-SNAPSHOT'
testImplementation 'net.kyori:adventure-text-serializer-gson:4.13.0'
testImplementation 'net.kyori:adventure-text-serializer-plain:4.13.1'
}

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

View File

@ -37,12 +37,12 @@ public class ProtocolLibrary {
/**
* The maximum version ProtocolLib has been tested with.
*/
public static final String MAXIMUM_MINECRAFT_VERSION = "1.20.2";
public static final String MAXIMUM_MINECRAFT_VERSION = "1.20.24";
/**
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.20.2) was released.
* The date (with ISO 8601 or YYYY-MM-DD) when the most recent version (1.20.4) was released.
*/
public static final String MINECRAFT_LAST_RELEASE_DATE = "2023-09-21";
public static final String MINECRAFT_LAST_RELEASE_DATE = "2023-12-07";
/**
* Plugins that are currently incompatible with ProtocolLib.

View File

@ -159,6 +159,37 @@ public class StructureCache {
return TRICKED_DATA_SERIALIZER_BASE.invoke(new ZeroBuffer());
}
static void initTrickDataSerializer() {
// create an empty instance of a nbt tag compound / text compound that we can re-use when needed
Object textCompound = WrappedChatComponent.fromText("").getHandle();
Object compound = Accessors.getConstructorAccessor(MinecraftReflection.getNBTCompoundClass()).invoke();
// base builder which intercepts a few methods
DynamicType.Builder<?> baseBuilder = ByteBuddyFactory.getInstance()
.createSubclass(MinecraftReflection.getPacketDataSerializerClass())
.name(MinecraftMethods.class.getPackage().getName() + ".ProtocolLibTricksNmsDataSerializerBase")
.method(ElementMatchers.takesArguments(MinecraftReflection.getNBTReadLimiterClass())
.and(ElementMatchers.returns(ElementMatchers.isSubTypeOf(MinecraftReflection.getNBTBaseClass()))))
.intercept(FixedValue.value(compound))
.method(ElementMatchers.returns(MinecraftReflection.getIChatBaseComponentClass()))
.intercept(FixedValue.value(textCompound))
.method(ElementMatchers.returns(PublicKey.class).and(ElementMatchers.takesNoArguments()))
.intercept(FixedValue.nullValue());
Class<?> serializerBase = baseBuilder.make()
.load(ByteBuddyFactory.getInstance().getClassLoader(), Default.INJECTION)
.getLoaded();
TRICKED_DATA_SERIALIZER_BASE = Accessors.getConstructorAccessor(serializerBase, ByteBuf.class);
// extended builder which intercepts the read string method as well
Class<?> withStringIntercept = baseBuilder
.name(MinecraftMethods.class.getPackage().getName() + ".ProtocolLibTricksNmsDataSerializerJson")
.method(ElementMatchers.returns(String.class).and(ElementMatchers.takesArguments(int.class)))
.intercept(FixedValue.value("{}"))
.make()
.load(ByteBuddyFactory.getInstance().getClassLoader(), Default.INJECTION)
.getLoaded();
TRICKED_DATA_SERIALIZER_JSON = Accessors.getConstructorAccessor(withStringIntercept, ByteBuf.class);
}
/**
* Creates a packet data serializer sub-class if needed to allow the fixed read of a NbtTagCompound because of a
* null check in the MapChunk packet constructor.
@ -174,43 +205,13 @@ public class StructureCache {
}
try {
// create an empty instance of a nbt tag compound / text compound that we can re-use when needed
Object textCompound = WrappedChatComponent.fromText("").getHandle();
Object compound = Accessors.getConstructorAccessor(MinecraftReflection.getNBTCompoundClass()).invoke();
// base builder which intercepts a few methods
DynamicType.Builder<?> baseBuilder = ByteBuddyFactory.getInstance()
.createSubclass(MinecraftReflection.getPacketDataSerializerClass())
.name(MinecraftMethods.class.getPackage().getName() + ".ProtocolLibTricksNmsDataSerializerBase")
.method(ElementMatchers.takesArguments(MinecraftReflection.getNBTReadLimiterClass())
.and(ElementMatchers.returns(ElementMatchers.isSubTypeOf(MinecraftReflection.getNBTBaseClass()))))
.intercept(FixedValue.value(compound))
.method(ElementMatchers.returns(MinecraftReflection.getIChatBaseComponentClass()))
.intercept(FixedValue.value(textCompound))
.method(ElementMatchers.returns(PublicKey.class).and(ElementMatchers.takesNoArguments()))
.intercept(FixedValue.nullValue());
Class<?> serializerBase = baseBuilder.make()
.load(ByteBuddyFactory.getInstance().getClassLoader(), Default.INJECTION)
.getLoaded();
TRICKED_DATA_SERIALIZER_BASE = Accessors.getConstructorAccessor(serializerBase, ByteBuf.class);
// extended builder which intercepts the read string method as well
Class<?> withStringIntercept = baseBuilder
.name(MinecraftMethods.class.getPackage().getName() + ".ProtocolLibTricksNmsDataSerializerJson")
.method(ElementMatchers.returns(String.class).and(ElementMatchers.takesArguments(int.class)))
.intercept(FixedValue.value("{}"))
.make()
.load(ByteBuddyFactory.getInstance().getClassLoader(), Default.INJECTION)
.getLoaded();
TRICKED_DATA_SERIALIZER_JSON = Accessors.getConstructorAccessor(withStringIntercept, ByteBuf.class);
// worked
initTrickDataSerializer();
return true;
} catch (Exception ignored) {
} finally {
TRICK_TRIED = true;
}
// didn't work
return false;
}
}

View File

@ -41,6 +41,12 @@ public class PacketRegistry {
// Whether or not the registry has been initialized
private static volatile boolean INITIALIZED = false;
static void reset() {
synchronized (registryLock) {
INITIALIZED = false;
}
}
/**
* Represents a register we are currently building.
* @author Kristian
@ -314,7 +320,7 @@ public class PacketRegistry {
/**
* Initializes the packet registry.
*/
private static void initialize() {
static void initialize() {
if (INITIALIZED) {
return;
}

View File

@ -1390,7 +1390,7 @@ public final class MinecraftReflection {
* @param aliases Potential aliases
* @return Optional that may contain the class
*/
private static Optional<Class<?>> getOptionalNMS(String className, String... aliases) {
public static Optional<Class<?>> getOptionalNMS(String className, String... aliases) {
if (minecraftPackage == null) {
minecraftPackage = new CachedPackage(getMinecraftPackage(), getClassSource());
}

View File

@ -36,6 +36,10 @@ import org.bukkit.Server;
* @author Kristian
*/
public final class MinecraftVersion implements Comparable<MinecraftVersion>, Serializable {
/**
* Version 1.20.4 - the decorated pot update
*/
public static final MinecraftVersion v1_20_4 = new MinecraftVersion("1.20.4");
/**
* Version 1.20.2 - the update that added the configuration protocol phase.
@ -135,7 +139,7 @@ public final class MinecraftVersion implements Comparable<MinecraftVersion>, Ser
/**
* The latest release version of minecraft.
*/
public static final MinecraftVersion LATEST = CONFIG_PHASE_PROTOCOL_UPDATE;
public static final MinecraftVersion LATEST = v1_20_4;
// used when serializing
private static final long serialVersionUID = -8695133558996459770L;

View File

@ -2,6 +2,7 @@ package com.comphenix.protocol.wrappers;
import com.google.gson.JsonObject;
import java.io.StringReader;
import java.util.Optional;
import org.bukkit.ChatColor;
@ -10,7 +11,10 @@ import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
import com.comphenix.protocol.utility.MinecraftReflection;
import com.comphenix.protocol.utility.MinecraftVersion;
import com.google.common.base.Preconditions;
import net.minecraft.network.chat.IChatBaseComponent;
/**
* Represents a chat component added in Minecraft 1.7.2
@ -20,6 +24,8 @@ public class WrappedChatComponent extends AbstractWrapper implements ClonableWra
private static final Class<?> SERIALIZER = MinecraftReflection.getChatSerializerClass();
private static final Class<?> COMPONENT = MinecraftReflection.getIChatBaseComponentClass();
private static final Class<?> GSON_CLASS = MinecraftReflection.getMinecraftGsonClass();
private static final Optional<Class<?>> MUTABLE_COMPONENT_CLASS
= MinecraftReflection.getOptionalNMS("network.chat.IChatMutableComponent");
private static Object GSON = null;
private static MethodAccessor DESERIALIZE = null;
@ -38,13 +44,18 @@ public class WrappedChatComponent extends AbstractWrapper implements ClonableWra
GSON = Accessors.getFieldAccessor(fuzzy.getFieldByType("gson", GSON_CLASS)).get(null);
try {
DESERIALIZE = Accessors.getMethodAccessor(FuzzyReflection.fromClass(MinecraftReflection.getChatDeserializer(), true)
.getMethodByReturnTypeAndParameters("deserialize", Object.class, new Class<?>[] { GSON_CLASS, String.class, Class.class, boolean.class }));
} catch (IllegalArgumentException ex) {
// We'll handle it in the ComponentParser
DESERIALIZE = null;
}
if (MinecraftVersion.v1_20_4.atOrAbove()) {
DESERIALIZE = Accessors.getMethodAccessor(FuzzyReflection.fromClass(SERIALIZER, false)
.getMethodByReturnTypeAndParameters("fromJsonLenient", MUTABLE_COMPONENT_CLASS.get(), String.class));
} else {
try {
DESERIALIZE = Accessors.getMethodAccessor(FuzzyReflection.fromClass(MinecraftReflection.getChatDeserializer(), true)
.getMethodByReturnTypeAndParameters("deserialize", Object.class, new Class<?>[] { GSON_CLASS, String.class, Class.class, boolean.class }));
} catch (IllegalArgumentException ex) {
// We'll handle it in the ComponentParser
DESERIALIZE = null;
}
}
// Get a component from a standard Minecraft message
CONSTRUCT_COMPONENT = Accessors.getMethodAccessor(MinecraftReflection.getCraftChatMessage(), "fromString", String.class, boolean.class);
@ -58,6 +69,10 @@ public class WrappedChatComponent extends AbstractWrapper implements ClonableWra
}
private static Object deserialize(String json) {
if (MinecraftVersion.v1_20_4.atOrAbove()) {
return DESERIALIZE.invoke(null, json);
}
// Should be non-null on 1.9 and up
if (DESERIALIZE != null) {
return DESERIALIZE.invoke(null, GSON, json, COMPONENT, true);

View File

@ -7,6 +7,7 @@ import java.util.stream.Collectors;
import com.comphenix.protocol.reflect.accessors.Accessors;
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
import com.comphenix.protocol.utility.MinecraftReflectionTestUtil;
import com.google.common.util.concurrent.MoreExecutors;
import net.minecraft.SharedConstants;
import net.minecraft.commands.CommandDispatcher;
@ -28,16 +29,19 @@ import net.minecraft.world.flag.FeatureFlagSet;
import net.minecraft.world.flag.FeatureFlags;
import net.minecraft.world.item.enchantment.Enchantments;
import org.apache.logging.log4j.LogManager;
import org.bukkit.*;
import org.bukkit.craftbukkit.v1_20_R2.CraftLootTable;
import org.bukkit.craftbukkit.v1_20_R2.CraftRegistry;
import org.bukkit.craftbukkit.v1_20_R2.CraftServer;
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemFactory;
import org.bukkit.craftbukkit.v1_20_R2.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_20_R2.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.v1_20_R2.util.Versioning;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.Bukkit;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.craftbukkit.v1_20_R3.CraftLootTable;
import org.bukkit.craftbukkit.v1_20_R3.CraftRegistry;
import org.bukkit.craftbukkit.v1_20_R3.CraftServer;
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemFactory;
import org.bukkit.craftbukkit.v1_20_R3.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_20_R3.util.CraftNamespacedKey;
import org.bukkit.craftbukkit.v1_20_R3.util.Versioning;
import org.spigotmc.SpigotWorldConfig;
import static org.mockito.ArgumentMatchers.any;
@ -102,12 +106,13 @@ public class BukkitInitialization {
resourcePackRepository.c() /* getAvailablePacks() */ .stream().map(ResourcePackLoader::e /* openFull() */).collect(Collectors.toList()));
LayeredRegistryAccess<RegistryLayer> layeredRegistryAccess = RegistryLayer.a(); // .createRegistryAccess()
layeredRegistryAccess = WorldLoader.b(resourceManager, layeredRegistryAccess, RegistryLayer.b /* WORLDGEN */, RegistryDataLoader.a /* WORLDGEN_REGISTRIES */); // .loadAndReplaceLayer()
IRegistryCustom.Dimension registryCustom = layeredRegistryAccess.a().c(); // .compositeAccess().freeze()
IRegistryCustom.Dimension registryCustom = layeredRegistryAccess.a().d(); // .compositeAccess().freeze()
// IRegistryCustom.Dimension registryCustom = layeredRegistryAccess.a().c(); // .compositeAccess().freeze()
DataPackResources dataPackResources = DataPackResources.a(
resourceManager,
registryCustom,
FeatureFlags.d.a() /* REGISTRY.allFlags() */,
FeatureFlagSet.a() /* REGISTRY.allFlags() */,
CommandDispatcher.ServerType.b /* DEDICATED */,
0,
MoreExecutors.directExecutor(),
@ -166,7 +171,7 @@ public class BukkitInitialization {
// Init Enchantments
Enchantments.A.getClass();
Enchantment.stopAcceptingRegistrations();
// Enchantment.stopAcceptingRegistrations();
initialized = true;
}

View File

@ -45,9 +45,9 @@ public class PacketTypeTest {
BukkitInitialization.initializeAll();
// I'm well aware this is jank, but it does in fact work correctly and give the desired result
/*PacketType.onDynamicCreate = className -> {
/* PacketType.onDynamicCreate = className -> {
throw new RuntimeException("Dynamically generated packet " + className);
};*/
}; */
}
@AfterAll
@ -342,21 +342,22 @@ public class PacketTypeTest {
}
}
@Test
public void testPacketCreation() {
boolean fail = false;
for (PacketType type : PacketType.values()) {
if (type.isSupported()) {
try {
new PacketContainer(type);
} catch (Exception ex) {
ex.printStackTrace();
fail = true;
}
}
}
assertFalse(fail, "Packet type(s) failed to instantiate");
}
@Test
public void testPacketCreation() {
List<PacketType> failed = new ArrayList<>();
for (PacketType type : PacketType.values()) {
if (!type.isSupported()) {
continue;
}
try {
new PacketContainer(type);
} catch (Exception ex) {
failed.add(type);
}
}
assertTrue(failed.isEmpty(), "Failed to create: " + failed);
}
@Test
public void testPacketBundleWriting() {
@ -365,7 +366,7 @@ public class PacketTypeTest {
List<PacketContainer> bundle = new ArrayList<>();
PacketContainer chatMessage = new PacketContainer(PacketType.Play.Server.SYSTEM_CHAT);
chatMessage.getStrings().write(0, WrappedChatComponent.fromText("Test").getJson());
chatMessage.getChatComponents().write(0, WrappedChatComponent.fromText("Test"));
chatMessage.getBooleans().write(0, false);
bundle.add(chatMessage);
bundlePacket.getPacketBundles().write(0, bundle);

View File

@ -58,6 +58,7 @@ import net.md_5.bungee.api.chat.ClickEvent;
import net.md_5.bungee.api.chat.ComponentBuilder;
import net.md_5.bungee.api.chat.HoverEvent;
import net.md_5.bungee.api.chat.hover.content.Text;
import net.minecraft.core.IRegistry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.PacketDataSerializer;
import net.minecraft.network.protocol.common.ClientboundCustomPayloadPacket;
@ -500,7 +501,8 @@ public class PacketContainerTest {
// are inner classes (which is ultimately pointless because AttributeSnapshots don't access any
// members of the packet itself)
PacketPlayOutUpdateAttributes packet = (PacketPlayOutUpdateAttributes) attribute.getHandle();
AttributeBase base = BuiltInRegistries.v.a(MinecraftKey.a("generic.max_health"));
IRegistry<AttributeBase> registry = BuiltInRegistries.u;
AttributeBase base = registry.a(MinecraftKey.a("generic.max_health"));
AttributeSnapshot snapshot = new AttributeSnapshot(base, 20.0D, modifiers);
attribute.getSpecificModifier(List.class).write(0, Lists.newArrayList(snapshot));
@ -882,6 +884,7 @@ public class PacketContainerTest {
// Make sure watchable collections can be cloned
if (type == PacketType.Play.Server.ENTITY_METADATA) {
IRegistry<CatVariant> catVariantRegistry = BuiltInRegistries.ak;
constructed.getDataValueCollectionModifier().write(0, Lists.newArrayList(
new WrappedDataValue(0, Registry.get(Byte.class), (byte) 1),
new WrappedDataValue(0, Registry.get(Float.class), 5F),
@ -895,7 +898,7 @@ public class PacketContainerTest {
0,
Registry.getItemStackSerializer(false),
BukkitConverters.getItemStackConverter().getGeneric(new ItemStack(Material.WOODEN_AXE))),
new WrappedDataValue(0, Registry.get(CatVariant.class), BuiltInRegistries.aj.e(CatVariant.e)),
new WrappedDataValue(0, Registry.get(CatVariant.class), catVariantRegistry.e(CatVariant.e)),
new WrappedDataValue(0, Registry.get(FrogVariant.class), FrogVariant.a)
));
} else if (type == PacketType.Play.Server.CHAT) {

View File

@ -12,8 +12,8 @@ import net.minecraft.server.level.PlayerChunkMap;
import net.minecraft.server.level.PlayerChunkMap.EntityTracker;
import net.minecraft.server.level.WorldServer;
import net.minecraft.world.entity.Entity;
import org.bukkit.craftbukkit.v1_20_R2.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R3.CraftWorld;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntity;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -35,7 +35,7 @@ public class EntityUtilitiesTest {
when(bukkit.getHandle()).thenReturn(world);
ChunkProviderServer provider = mock(ChunkProviderServer.class);
when(world.k()).thenReturn(provider);
when(world.l()).thenReturn(provider);
PlayerChunkMap chunkMap = mock(PlayerChunkMap.class);
Field chunkMapField = FuzzyReflection.fromClass(ChunkProviderServer.class, true)

View File

@ -0,0 +1,26 @@
package com.comphenix.protocol.injector;
import com.comphenix.protocol.BukkitInitialization;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class StructureCacheTests {
@BeforeAll
public static void beforeAll() {
BukkitInitialization.initializeAll();
}
@Test
public void testInitTrickSerializer() {
try {
StructureCache.initTrickDataSerializer();
} catch (IllegalStateException ex) {
// no exception or an already injected exception means it succeeded
assertTrue(ex.getMessage().contains("Cannot inject already loaded type"));
}
}
}

View File

@ -0,0 +1,41 @@
package com.comphenix.protocol.injector.packet;
import java.util.ArrayList;
import java.util.List;
import com.comphenix.protocol.BukkitInitialization;
import com.comphenix.protocol.PacketType;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertTrue;
public class PacketRegistryTests {
@BeforeAll
public static void beforeAll() {
BukkitInitialization.initializeAll();
}
@Test
public void testRegistryInit() {
PacketRegistry.reset();
// completing without exception
PacketRegistry.initialize();
}
@Test
public void testAllPacketsRegistered() {
List<PacketType> missing = new ArrayList<>();
for (PacketType type : PacketType.values()) {
if (type.isDeprecated()) {
continue;
}
if (!PacketRegistry.tryGetPacketClass(type).isPresent()) {
missing.add(type);
}
}
assertTrue(missing.isEmpty(), "Missing packets: " + missing);
}
}

View File

@ -28,7 +28,7 @@ public class AggregateClonerTest {
// @Test
// Usages of NonNullList were removed in 1.17.1
public void testNonNullList() {
/* public void testNonNullList() {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.WINDOW_ITEMS);
NonNullList<ItemStack> list = NonNullList.a(16, ItemStack.b);
@ -41,5 +41,5 @@ public class AggregateClonerTest {
assertEquals(list.size(), list1.size());
Assertions.assertArrayEquals(list.toArray(), list1.toArray());
}
} */
}

View File

@ -13,7 +13,7 @@ import net.minecraft.world.level.ChunkCoordIntPair;
import net.minecraft.world.level.block.state.IBlockData;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
import org.bukkit.craftbukkit.v1_20_R3.inventory.CraftItemStack;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import org.junit.jupiter.api.AfterAll;

View File

@ -2,8 +2,8 @@ package com.comphenix.protocol.utility;
public class MinecraftReflectionTestUtil {
public static final String RELEASE_TARGET = "1.20.2";
public static final String PACKAGE_VERSION = "v1_20_R2";
public static final String RELEASE_TARGET = "1.20.4";
public static final String PACKAGE_VERSION = "v1_20_R3";
public static final String NMS = "net.minecraft";
public static final String OBC = "org.bukkit.craftbukkit." + PACKAGE_VERSION;

View File

@ -48,7 +48,7 @@ class MinecraftVersionTest {
@Test
void testCurrent() {
assertEquals(MinecraftVersion.CONFIG_PHASE_PROTOCOL_UPDATE, MinecraftVersion.getCurrentVersion());
assertEquals(MinecraftVersion.v1_20_4, MinecraftVersion.getCurrentVersion());
}
@Test

View File

@ -1,5 +1,7 @@
package com.comphenix.protocol.wrappers;
import java.util.Optional;
import static com.comphenix.protocol.utility.MinecraftReflection.getMinecraftClass;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
@ -46,7 +48,8 @@ public class AutoWrapperTest {
assertTrue(nms.h());
assertTrue(nms.j());
assertFalse(nms.i());
assertEquals("test", nms.d().a());
assertTrue(nms.d().isPresent());
assertEquals("test", nms.d().get().a());
validateRawText(nms.a(), "Test123");
validateRawText(nms.b(), "Test567");
assertSame(AdvancementFrameType.b, nms.e());
@ -61,7 +64,7 @@ public class AutoWrapperTest {
(net.minecraft.world.item.ItemStack)MinecraftReflection.getMinecraftItemStack(new ItemStack(Material.ENDER_EYE)),
IChatBaseComponent.b("Test123"),
IChatBaseComponent.b("Test567"),
new net.minecraft.resources.MinecraftKey("minecraft", "test"),
Optional.of(new net.minecraft.resources.MinecraftKey("minecraft", "test")),
AdvancementFrameType.b,
true,
false,

View File

@ -8,6 +8,7 @@ import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.wrappers.WrappedAttributeModifier.Operation;
import com.google.common.collect.Lists;
import net.minecraft.core.IRegistry;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.network.protocol.game.PacketPlayOutUpdateAttributes.AttributeSnapshot;
import net.minecraft.resources.MinecraftKey;
@ -93,7 +94,8 @@ public class WrappedAttributeTest {
modifiers.add((AttributeModifier) wrapper.getHandle());
}
AttributeBase base = BuiltInRegistries.v.a(MinecraftKey.a(attribute.getAttributeKey()));
IRegistry<AttributeBase> registry = BuiltInRegistries.u;
AttributeBase base = registry.a(MinecraftKey.a(attribute.getAttributeKey()));
return new AttributeSnapshot(base, attribute.getBaseValue(), modifiers);
}

View File

@ -19,9 +19,9 @@ import net.minecraft.world.level.block.state.IBlockData;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.type.GlassPane;
import org.bukkit.craftbukkit.v1_20_R2.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R2.block.impl.CraftStainedGlassPane;
import org.bukkit.craftbukkit.v1_20_R2.util.CraftMagicNumbers;
import org.bukkit.craftbukkit.v1_20_R3.block.data.CraftBlockData;
import org.bukkit.craftbukkit.v1_20_R3.block.impl.CraftStainedGlassPane;
import org.bukkit.craftbukkit.v1_20_R3.util.CraftMagicNumbers;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
@ -56,7 +56,7 @@ public class WrappedBlockDataTest {
@Test
public void testDataCreation() {
IBlockData nmsData = CraftMagicNumbers.getBlock(Material.CYAN_STAINED_GLASS_PANE).n();
IBlockData nmsData = CraftMagicNumbers.getBlock(Material.CYAN_STAINED_GLASS_PANE).o();
GlassPane data = (GlassPane) CraftBlockData.fromData(nmsData);
data.setFace(BlockFace.EAST, true);

View File

@ -19,8 +19,8 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
import net.minecraft.world.entity.projectile.EntityEgg;
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftEgg;
import org.bukkit.craftbukkit.v1_20_R2.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEgg;
import org.bukkit.craftbukkit.v1_20_R3.entity.CraftEntity;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;