Skip to content

Commit 90a38cc

Browse files
authored
Restore backwards compatibility (#1235)
* Remove usages of net.minecraft and craftbukkit * Restore packet type backward compatibility (tested on 1.8) * Re-add last removed packets * Fix sub class naming for newer minecraft versions
1 parent 76930ae commit 90a38cc

File tree

10 files changed

+215
-78
lines changed

10 files changed

+215
-78
lines changed

src/main/java/com/comphenix/protocol/PacketType.java

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ public static class Server extends PacketTypeEnum {
143143
public static final PacketType LOGIN = new PacketType(PROTOCOL, SENDER, 0x26, "Login", "SPacketJoinGame");
144144
public static final PacketType MAP = new PacketType(PROTOCOL, SENDER, 0x27, "Map", "SPacketMaps");
145145
public static final PacketType OPEN_WINDOW_MERCHANT = new PacketType(PROTOCOL, SENDER, 0x28, "OpenWindowMerchant");
146-
public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x29, "Entity$PacketPlayOutRelEntityMove");
147-
public static final PacketType REL_ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x2A, "Entity$PacketPlayOutRelEntityMoveLook");
148-
public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x2B, "Entity$PacketPlayOutEntityLook");
146+
public static final PacketType REL_ENTITY_MOVE = new PacketType(PROTOCOL, SENDER, 0x29, "Entity$PacketPlayOutRelEntityMove", "Entity$RelEntityMove");
147+
public static final PacketType REL_ENTITY_MOVE_LOOK = new PacketType(PROTOCOL, SENDER, 0x2A, "Entity$PacketPlayOutRelEntityMoveLook", "Entity$RelEntityMoveLook");
148+
public static final PacketType ENTITY_LOOK = new PacketType(PROTOCOL, SENDER, 0x2B, "Entity$PacketPlayOutEntityLook", "Entity$EntityLook");
149149
public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x2C, "VehicleMove", "SPacketMoveVehicle");
150150
public static final PacketType OPEN_BOOK = new PacketType(PROTOCOL, SENDER, 0x2D, "OpenBook");
151151
public static final PacketType OPEN_WINDOW = new PacketType(PROTOCOL, SENDER, 0x2E, "OpenWindow", "SPacketOpenWindow");
@@ -267,7 +267,7 @@ public static class Server extends PacketTypeEnum {
267267
* @deprecated Removed in 1.14
268268
*/
269269
@Deprecated
270-
public static final PacketType BED = new PacketType(PROTOCOL, SENDER, 0x33, "Bed", "SPacketUseBed");
270+
public static final PacketType BED = new PacketType(PROTOCOL, SENDER, 251, "Bed", "SPacketUseBed");
271271

272272
/**
273273
* @deprecated Renamed to {@link #BED}
@@ -279,25 +279,37 @@ public static class Server extends PacketTypeEnum {
279279
* @deprecated Removed in 1.16
280280
*/
281281
@Deprecated
282-
public static final PacketType SPAWN_ENTITY_WEATHER = new PacketType(PROTOCOL, SENDER, 0x02, "SpawnEntityWeather", "SPacketSpawnGlobalEntity");
282+
public static final PacketType SPAWN_ENTITY_WEATHER = new PacketType(PROTOCOL, SENDER, 250, "SpawnEntityWeather", "SPacketSpawnGlobalEntity");
283283

284284
/**
285285
* @deprecated Removed in 1.17, split into separate packets
286286
*/
287287
@Deprecated
288-
public static final PacketType TITLE = new PacketType(PROTOCOL, SENDER, 0x00, "Title");
288+
public static final PacketType TITLE = new PacketType(PROTOCOL, SENDER, 249, "Title");
289289

290290
/**
291291
* @deprecated Removed in 1.17, split into separate packets
292292
*/
293293
@Deprecated
294-
public static final PacketType WORLD_BORDER = new PacketType(PROTOCOL, SENDER, 0x00, "WorldBorder");
294+
public static final PacketType WORLD_BORDER = new PacketType(PROTOCOL, SENDER, 248, "WorldBorder");
295295

296296
/**
297297
* @deprecated Removed in 1.17, split into separate packets
298298
*/
299299
@Deprecated
300-
public static final PacketType COMBAT_EVENT = new PacketType(PROTOCOL, SENDER, 0x00, "CombatEvent");
300+
public static final PacketType COMBAT_EVENT = new PacketType(PROTOCOL, SENDER, 247, "CombatEvent");
301+
302+
/**
303+
* @deprecated Removed in 1.17
304+
*/
305+
@Deprecated
306+
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 246, "Transaction", "SPacketConfirmTransaction");
307+
308+
/**
309+
* @deprecated Made abstract in 1.17, no actual packet anymore
310+
*/
311+
@Deprecated
312+
public static final PacketType ENTITY = new PacketType(PROTOCOL, SENDER, 245, "Entity", "SPacketEntity");
301313

302314
private final static Server INSTANCE = new Server();
303315

@@ -336,18 +348,18 @@ public static class Client extends PacketTypeEnum {
336348
public static final PacketType JIGSAW_GENERATE = new PacketType(PROTOCOL, SENDER, 0x0E, "JigsawGenerate");
337349
public static final PacketType KEEP_ALIVE = new PacketType(PROTOCOL, SENDER, 0x0F, "KeepAlive", "CPacketKeepAlive");
338350
public static final PacketType DIFFICULTY_LOCK = new PacketType(PROTOCOL, SENDER, 0x10, "DifficultyLock");
339-
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x11, "Flying$PacketPlayInPosition");
340-
public static final PacketType POSITION_LOOK = new PacketType(PROTOCOL, SENDER, 0x12, "Flying$PacketPlayInPositionLook");
341-
public static final PacketType LOOK = new PacketType(PROTOCOL, SENDER, 0x13, "Flying$PacketPlayInLook");
342-
public static final PacketType GROUND = new PacketType(PROTOCOL, SENDER, 0x14, "Flying$d");
351+
public static final PacketType POSITION = new PacketType(PROTOCOL, SENDER, 0x11, "Flying$PacketPlayInPosition", "Flying$Position", "CPacketPlayer$Position");
352+
public static final PacketType POSITION_LOOK = new PacketType(PROTOCOL, SENDER, 0x12, "Flying$PacketPlayInPositionLook", "Flying$PositionLook", "CPacketPlayer$PositionRotation");
353+
public static final PacketType LOOK = new PacketType(PROTOCOL, SENDER, 0x13, "Flying$PacketPlayInLook", "Flying$Look", "CPacketPlayer$Rotation");
354+
public static final PacketType GROUND = new PacketType(PROTOCOL, SENDER, 0x14, "Flying$d", "Flying", "CPacketPlayer");
343355
public static final PacketType VEHICLE_MOVE = new PacketType(PROTOCOL, SENDER, 0x15, "VehicleMove", "CPacketVehicleMove");
344356
public static final PacketType BOAT_MOVE = new PacketType(PROTOCOL, SENDER, 0x16, "BoatMove", "CPacketSteerBoat");
345357
public static final PacketType PICK_ITEM = new PacketType(PROTOCOL, SENDER, 0x17, "PickItem");
346358
public static final PacketType AUTO_RECIPE = new PacketType(PROTOCOL, SENDER, 0x18, "AutoRecipe", "CPacketPlaceRecipe");
347359
public static final PacketType ABILITIES = new PacketType(PROTOCOL, SENDER, 0x19, "Abilities", "CPacketPlayerAbilities");
348360
public static final PacketType BLOCK_DIG = new PacketType(PROTOCOL, SENDER, 0x1A, "BlockDig", "CPacketPlayerDigging");
349361
public static final PacketType ENTITY_ACTION = new PacketType(PROTOCOL, SENDER, 0x1B, "EntityAction", "CPacketEntityAction");
350-
public static final PacketType STEER_VEHICLE = new PacketType(PROTOCOL, SENDER, 0x1C, "SteerVehicle");
362+
public static final PacketType STEER_VEHICLE = new PacketType(PROTOCOL, SENDER, 0x1C, "SteerVehicle", "CPacketInput");
351363
public static final PacketType PONG = new PacketType(PROTOCOL, SENDER, 0x1D, "Pong", "ServerboundPongPacket");
352364
public static final PacketType RECIPE_SETTINGS = new PacketType(PROTOCOL, SENDER, 0x1E, "RecipeSettings");
353365
public static final PacketType RECIPE_DISPLAYED = new PacketType(PROTOCOL, SENDER, 0x1F, "RecipeDisplayed", "CPacketRecipeInfo");
@@ -368,6 +380,12 @@ public static class Client extends PacketTypeEnum {
368380
public static final PacketType USE_ITEM = new PacketType(PROTOCOL, SENDER, 0x2E, "UseItem", "CPacketPlayerTryUseItemOnBlock");
369381
public static final PacketType BLOCK_PLACE = new PacketType(PROTOCOL, SENDER, 0x2F, "BlockPlace", "CPacketPlayerTryUseItem");
370382

383+
/**
384+
* @deprecated Removed in 1.17
385+
*/
386+
@Deprecated
387+
public static final PacketType TRANSACTION = new PacketType(PROTOCOL, SENDER, 255, "Transaction", "CPacketConfirmTransaction");
388+
371389
private final static Client INSTANCE = new Client();
372390

373391
// Prevent accidental construction

src/main/java/com/comphenix/protocol/events/PacketContainer.java

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,22 @@
1717

1818
package com.comphenix.protocol.events;
1919

20-
import java.io.*;
20+
import java.io.IOException;
21+
import java.io.ObjectInputStream;
22+
import java.io.ObjectOutputStream;
23+
import java.io.Serializable;
2124
import java.lang.reflect.Array;
2225
import java.lang.reflect.InvocationTargetException;
2326
import java.lang.reflect.Method;
2427
import java.lang.reflect.Modifier;
25-
import java.util.*;
28+
import java.util.Collection;
29+
import java.util.List;
30+
import java.util.Map;
31+
import java.util.Optional;
32+
import java.util.Set;
33+
import java.util.UUID;
2634
import java.util.concurrent.ConcurrentMap;
35+
2736
import javax.annotation.Nonnull;
2837
import javax.annotation.Nullable;
2938

@@ -34,8 +43,6 @@
3443
import com.comphenix.protocol.reflect.cloning.*;
3544
import com.comphenix.protocol.reflect.cloning.AggregateCloner.BuilderParameters;
3645
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
37-
import com.comphenix.protocol.reflect.instances.DefaultInstances;
38-
import com.comphenix.protocol.reflect.instances.InstanceProvider;
3946
import com.comphenix.protocol.utility.MinecraftMethods;
4047
import com.comphenix.protocol.utility.MinecraftReflection;
4148
import com.comphenix.protocol.utility.MinecraftVersion;
@@ -45,6 +52,7 @@
4552
import com.comphenix.protocol.wrappers.nbt.NbtBase;
4653
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
4754
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
55+
4856
import com.google.common.base.Function;
4957
import com.google.common.base.Preconditions;
5058
import com.google.common.collect.Maps;
@@ -53,7 +61,6 @@
5361
import io.netty.buffer.ByteBuf;
5462
import io.netty.buffer.UnpooledByteBufAllocator;
5563

56-
import net.minecraft.network.PacketDataSerializer;
5764
import org.bukkit.Material;
5865
import org.bukkit.Sound;
5966
import org.bukkit.World;
@@ -1247,18 +1254,20 @@ private void readObject(ObjectInputStream input) throws ClassNotFoundException,
12471254

12481255
// Create a default instance of the packet
12491256
if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
1250-
PacketDataSerializer serializer = new PacketDataSerializer(buffer);
1257+
Object serializer = MinecraftReflection.getPacketDataSerializer(buffer);
12511258

12521259
try {
1253-
handle = type.getPacketClass().getConstructor(PacketDataSerializer.class).newInstance(serializer);
1260+
handle = type.getPacketClass()
1261+
.getConstructor(MinecraftReflection.getPacketDataSerializerClass())
1262+
.newInstance(serializer);
12541263
} catch (ReflectiveOperationException ex) {
12551264
// they might have a static method to create them instead
12561265
Method method = FuzzyReflection.fromClass(type.getPacketClass(), true)
12571266
.getMethod(FuzzyMethodContract
12581267
.newBuilder()
12591268
.requireModifier(Modifier.STATIC)
12601269
.returnTypeExact(type.getPacketClass())
1261-
.parameterExactArray(PacketDataSerializer.class)
1270+
.parameterExactArray(MinecraftReflection.getPacketDataSerializerClass())
12621271
.build());
12631272
try {
12641273
handle = method.invoke(null, serializer);

src/main/java/com/comphenix/protocol/injector/StructureCache.java

Lines changed: 64 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,29 @@
1919

2020
import java.util.HashSet;
2121
import java.util.Set;
22+
import java.util.function.Supplier;
2223
import java.util.concurrent.ConcurrentHashMap;
2324
import java.util.concurrent.ConcurrentMap;
2425

2526
import com.comphenix.protocol.PacketType;
2627
import com.comphenix.protocol.injector.packet.PacketRegistry;
28+
import com.comphenix.protocol.reflect.accessors.Accessors;
29+
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
2730
import com.comphenix.protocol.reflect.StructureModifier;
2831
import com.comphenix.protocol.reflect.compiler.BackgroundCompiler;
2932
import com.comphenix.protocol.reflect.compiler.CompiledStructureModifier;
3033
import com.comphenix.protocol.reflect.instances.DefaultInstances;
34+
import com.comphenix.protocol.utility.ByteBuddyFactory;
35+
import com.comphenix.protocol.utility.MinecraftMethods;
3136
import com.comphenix.protocol.utility.MinecraftReflection;
3237
import com.comphenix.protocol.utility.ZeroBuffer;
33-
import com.comphenix.protocol.utility.ZeroPacketDataSerializer;
38+
39+
import io.netty.buffer.ByteBuf;
3440
import com.google.common.base.Preconditions;
35-
import net.minecraft.network.PacketDataSerializer;
41+
42+
import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
43+
import net.bytebuddy.implementation.FixedValue;
44+
import net.bytebuddy.matcher.ElementMatchers;
3645

3746
/**
3847
* Caches structure modifiers.
@@ -41,23 +50,37 @@
4150
public class StructureCache {
4251
// Structure modifiers
4352
private static final ConcurrentMap<PacketType, StructureModifier<Object>> structureModifiers = new ConcurrentHashMap<>();
53+
// invocation cache for packets
54+
private static final ConcurrentMap<Class<?>, Supplier<Object>> PACKET_INSTANCE_CREATORS = new ConcurrentHashMap<>();
55+
// packet data serializer which always returns an empty nbt tag compound
56+
private static boolean trickTried;
57+
private static ConstructorAccessor TRICKED_DATA_SERIALIZER;
4458

4559
private static final Set<PacketType> compiling = new HashSet<>();
4660

4761
public static Object newPacket(Class<?> clazz) {
4862
Object result = DefaultInstances.DEFAULT.create(clazz);
4963

50-
// TODO make these generic
5164
if (result == null) {
52-
try {
53-
return clazz.getConstructor(PacketDataSerializer.class).newInstance(new PacketDataSerializer(new ZeroBuffer()));
54-
} catch (ReflectiveOperationException ex) {
55-
try {
56-
return clazz.getConstructor(PacketDataSerializer.class).newInstance(new ZeroPacketDataSerializer());
57-
} catch (ReflectiveOperationException ex1) {
58-
throw new IllegalArgumentException("Failed to create packet: " + clazz, ex);
65+
return PACKET_INSTANCE_CREATORS.computeIfAbsent(clazz, $ -> {
66+
ConstructorAccessor accessor = Accessors.getConstructorAccessorOrNull(clazz, MinecraftReflection.getPacketDataSerializerClass());
67+
if (accessor != null) {
68+
return () -> {
69+
try {
70+
return accessor.invoke(MinecraftReflection.getPacketDataSerializer(new ZeroBuffer()));
71+
} catch (Exception exception) {
72+
// try trick nms around as they want a non-null compound in the map_chunk packet constructor
73+
ConstructorAccessor trickyDataSerializerAccessor = getTrickDataSerializerOrNull();
74+
if (trickyDataSerializerAccessor != null) {
75+
return accessor.invoke(trickyDataSerializerAccessor.invoke(new ZeroBuffer()));
76+
}
77+
// the tricks are over
78+
throw new IllegalArgumentException("Unable to create packet " + clazz, exception);
79+
}
80+
};
5981
}
60-
}
82+
throw new IllegalArgumentException("No matching constructor to create packet in class " + clazz);
83+
}).get();
6184
}
6285

6386
return result;
@@ -148,4 +171,34 @@ public static StructureModifier<Object> getStructure(final PacketType type, bool
148171
}
149172
return result;
150173
}
174+
175+
/**
176+
* Creates a packet data serializer sub-class if needed to allow the fixed read of a NbtTagCompound because of a null
177+
* check in the MapChunk packet constructor.
178+
* @return an accessor to a constructor which creates a data serializer.
179+
*/
180+
private static ConstructorAccessor getTrickDataSerializerOrNull() {
181+
if (TRICKED_DATA_SERIALIZER == null && !trickTried) {
182+
// ensure that we only try once to create the class
183+
trickTried = true;
184+
try {
185+
// create an empty instance of a nbt tag compound that we can re-use when needed
186+
Object compound = Accessors.getConstructorAccessor(MinecraftReflection.getNBTCompoundClass()).invoke();
187+
// create the method in the class to read an empty nbt tag compound (currently used for MAP_CHUNK because of null check)
188+
Class<?> generatedClass = ByteBuddyFactory.getInstance()
189+
.createSubclass(MinecraftReflection.getPacketDataSerializerClass())
190+
.name(MinecraftMethods.class.getPackage().getName() + ".ProtocolLibTricksNmsDataSerializer")
191+
.method(ElementMatchers.returns(MinecraftReflection.getNBTCompoundClass())
192+
.and(ElementMatchers.takesArguments(MinecraftReflection.getNBTReadLimiterClass())))
193+
.intercept(FixedValue.value(compound))
194+
.make()
195+
.load(ByteBuddyFactory.getInstance().getClassLoader(), ClassLoadingStrategy.Default.INJECTION)
196+
.getLoaded();
197+
TRICKED_DATA_SERIALIZER = Accessors.getConstructorAccessor(generatedClass, ByteBuf.class);
198+
} catch (Exception ignored) {
199+
// can happen if unsupported
200+
}
201+
}
202+
return TRICKED_DATA_SERIALIZER;
203+
}
151204
}

src/main/java/com/comphenix/protocol/metrics/Metrics.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
import org.bukkit.Bukkit;
44
import org.bukkit.configuration.file.YamlConfiguration;
5-
import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.tuple.Pair;
65
import org.bukkit.entity.Player;
76
import org.bukkit.plugin.Plugin;
87
import org.bukkit.plugin.RegisteredServiceProvider;

src/main/java/com/comphenix/protocol/metrics/Statistics.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import com.comphenix.protocol.utility.Util;
2525

2626
import org.bukkit.Bukkit;
27-
import org.bukkit.craftbukkit.libs.org.apache.commons.lang3.tuple.Pair;
2827

2928
import java.io.IOException;
3029
import java.util.HashMap;

0 commit comments

Comments
 (0)