Skip to content

Commit 73c71e0

Browse files
committed
Update to Minecraft 1.15
1 parent bb305fd commit 73c71e0

21 files changed

+528
-255
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
<project.fullVersion>${project.version}</project.fullVersion>
1818

1919
<powermock.version>2.0.4</powermock.version>
20-
<spigot.version>1.14.4-R0.1-SNAPSHOT</spigot.version>
20+
<spigot.version>1.15-R0.1-SNAPSHOT</spigot.version>
2121
</properties>
2222

2323
<build>

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

Lines changed: 85 additions & 85 deletions
Large diffs are not rendered by default.

src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
import com.comphenix.protocol.reflect.VolatileField;
3131
import com.comphenix.protocol.reflect.accessors.Accessors;
3232
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
33-
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
3433
import com.comphenix.protocol.utility.MinecraftFields;
3534
import com.comphenix.protocol.utility.MinecraftMethods;
3635
import com.comphenix.protocol.utility.MinecraftProtocolVersion;
@@ -49,6 +48,8 @@
4948
import org.bukkit.Bukkit;
5049
import org.bukkit.entity.Player;
5150

51+
import java.lang.reflect.InvocationTargetException;
52+
import java.lang.reflect.Method;
5253
import java.net.Socket;
5354
import java.net.SocketAddress;
5455
import java.util.*;
@@ -86,8 +87,8 @@ public class ChannelInjector extends ByteToMessageDecoder implements Injector {
8687
}
8788

8889
// Saved accessors
89-
private static MethodAccessor DECODE_BUFFER;
90-
private static MethodAccessor ENCODE_BUFFER;
90+
private static Method DECODE_BUFFER;
91+
private static Method ENCODE_BUFFER;
9192
private static FieldAccessor ENCODER_TYPE_MATCHER;
9293

9394
// For retrieving the protocol
@@ -211,17 +212,30 @@ public boolean inject() {
211212
throw new IllegalArgumentException("Unable to find vanilla encoder in " + originalChannel.pipeline());
212213
patchEncoder(vanillaEncoder);
213214

214-
if (DECODE_BUFFER == null)
215-
DECODE_BUFFER = Accessors.getMethodAccessor(vanillaDecoder.getClass(),
216-
"decode", ChannelHandlerContext.class, ByteBuf.class, List.class);
217-
if (ENCODE_BUFFER == null)
218-
ENCODE_BUFFER = Accessors.getMethodAccessor(vanillaEncoder.getClass(),
219-
"encode", ChannelHandlerContext.class, Object.class, ByteBuf.class);
215+
if (DECODE_BUFFER == null) {
216+
try {
217+
DECODE_BUFFER = vanillaDecoder.getClass().getDeclaredMethod("decode",
218+
ChannelHandlerContext.class, ByteBuf.class, List.class);
219+
DECODE_BUFFER.setAccessible(true);
220+
} catch (NoSuchMethodException ex) {
221+
throw new IllegalArgumentException("Unable to find decode method in " + vanillaDecoder.getClass());
222+
}
223+
}
224+
225+
if (ENCODE_BUFFER == null) {
226+
try {
227+
ENCODE_BUFFER = vanillaEncoder.getClass().getDeclaredMethod("encode",
228+
ChannelHandlerContext.class, Object.class, ByteBuf.class);
229+
ENCODE_BUFFER.setAccessible(true);
230+
} catch (NoSuchMethodException ex) {
231+
throw new IllegalArgumentException("Unable to find encode method in " + vanillaEncoder.getClass());
232+
}
233+
}
220234

221235
// Intercept sent packets
222236
MessageToByteEncoder<Object> protocolEncoder = new MessageToByteEncoder<Object>() {
223237
@Override
224-
protected void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) {
238+
protected void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) throws Exception {
225239
if (packet instanceof WirePacket) {
226240
// Special case for wire format
227241
ChannelInjector.this.encodeWirePacket((WirePacket) packet, output);
@@ -396,7 +410,7 @@ private void encodeWirePacket(WirePacket packet, ByteBuf output) {
396410
* @param packet - the packet to encode to a byte array.
397411
* @param output - the output byte array.
398412
*/
399-
private void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) {
413+
private void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) throws Exception {
400414
NetworkMarker marker = null;
401415
PacketEvent event = currentEvent;
402416

@@ -415,7 +429,6 @@ private void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) {
415429
// Delay the packet
416430
scheduleMainThread(packet);
417431
packet = null;
418-
419432
} else {
420433
event = processSending(packet);
421434

@@ -446,9 +459,13 @@ private void encode(ChannelHandlerContext ctx, Object packet, ByteBuf output) {
446459
// Sent listeners?
447460
finalEvent = event;
448461
}
462+
} catch (InvocationTargetException ex) {
463+
if (ex.getCause() instanceof Exception) {
464+
throw (Exception) ex.getCause();
465+
}
449466
} catch (Exception e) {
450467
channelListener.getReporter().reportDetailed(this,
451-
Report.newBuilder(REPORT_CANNOT_INTERCEPT_SERVER_PACKET).callerParam(packet).error(e).build());
468+
Report.newBuilder(REPORT_CANNOT_INTERCEPT_SERVER_PACKET).callerParam(packet).error(e).build());
452469
} finally {
453470
// Attempt to handle the packet nevertheless
454471
if (packet != null) {
@@ -483,10 +500,10 @@ private void scheduleMainThread(final Object packetCopy) {
483500
}
484501

485502
@Override
486-
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuffer, List<Object> packets) {
487-
DECODE_BUFFER.invoke(vanillaDecoder, ctx, byteBuffer, packets);
488-
503+
protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuffer, List<Object> packets) throws Exception {
489504
try {
505+
DECODE_BUFFER.invoke(vanillaDecoder, ctx, byteBuffer, packets);
506+
490507
// Reset queue
491508
finishQueue.clear();
492509

@@ -499,8 +516,10 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuffer, List<Object
499516
handleLogin(packetClass, input);
500517

501518
if (channelListener.includeBuffer(packetClass)) {
502-
byteBuffer.resetReaderIndex();
503-
marker = new NettyNetworkMarker(ConnectionSide.CLIENT_SIDE, getBytes(byteBuffer));
519+
if (byteBuffer.readableBytes() != 0) {
520+
byteBuffer.resetReaderIndex();
521+
marker = new NettyNetworkMarker(ConnectionSide.CLIENT_SIDE, getBytes(byteBuffer));
522+
}
504523
}
505524

506525
PacketEvent output = channelListener.onPacketReceiving(this, input, marker);
@@ -518,6 +537,10 @@ protected void decode(ChannelHandlerContext ctx, ByteBuf byteBuffer, List<Object
518537
}
519538
}
520539
}
540+
} catch (InvocationTargetException ex) {
541+
if (ex.getCause() instanceof Exception) {
542+
throw (Exception) ex.getCause();
543+
}
521544
} catch (Exception e) {
522545
channelListener.getReporter().reportDetailed(this,
523546
Report.newBuilder(REPORT_CANNOT_INTERCEPT_CLIENT_PACKET).callerParam(byteBuffer).error(e).build());

src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolRegistry.java

Lines changed: 115 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,21 @@
1616
*/
1717
package com.comphenix.protocol.injector.netty;
1818

19-
import java.util.Arrays;
19+
import java.lang.reflect.Field;
20+
import java.lang.reflect.Modifier;
21+
import java.util.HashMap;
2022
import java.util.Map;
2123
import java.util.Map.Entry;
2224

2325
import com.comphenix.protocol.PacketType;
24-
import com.comphenix.protocol.ProtocolLogger;
2526
import com.comphenix.protocol.PacketType.Protocol;
2627
import com.comphenix.protocol.PacketType.Sender;
27-
import com.comphenix.protocol.injector.netty.ProtocolRegistry;
28+
import com.comphenix.protocol.ProtocolLogger;
2829
import com.comphenix.protocol.injector.packet.MapContainer;
30+
import com.comphenix.protocol.reflect.FuzzyReflection;
2931
import com.comphenix.protocol.reflect.StructureModifier;
32+
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
33+
import com.comphenix.protocol.utility.MinecraftVersion;
3034
import com.google.common.collect.Maps;
3135

3236
/**
@@ -41,6 +45,11 @@ public NettyProtocolRegistry() {
4145

4246
@Override
4347
protected synchronized void initialize() {
48+
if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.BEE_UPDATE)) {
49+
initializeNew();
50+
return;
51+
}
52+
4453
Object[] protocols = enumProtocol.getEnumConstants();
4554

4655
// ID to Packet class maps
@@ -68,11 +77,11 @@ protected synchronized void initialize() {
6877
}
6978

7079
// Maps we have to occasionally check have changed
71-
for (Map<Integer, Class<?>> map : serverMaps.values()) {
80+
for (Object map : serverMaps.values()) {
7281
result.containers.add(new MapContainer(map));
7382
}
7483

75-
for (Map<Integer, Class<?>> map : clientMaps.values()) {
84+
for (Object map : clientMaps.values()) {
7685
result.containers.add(new MapContainer(map));
7786
}
7887

@@ -91,6 +100,107 @@ protected synchronized void initialize() {
91100
this.register = result;
92101
}
93102

103+
@SuppressWarnings("unchecked")
104+
private synchronized void initializeNew() {
105+
Object[] protocols = enumProtocol.getEnumConstants();
106+
107+
// ID to Packet class maps
108+
Map<Object, Map<Class<?>, Integer>> serverMaps = Maps.newLinkedHashMap();
109+
Map<Object, Map<Class<?>, Integer>> clientMaps = Maps.newLinkedHashMap();
110+
111+
Register result = new Register();
112+
Field mainMapField = null;
113+
Field packetMapField = null;
114+
115+
// Iterate through the protocols
116+
for (Object protocol : protocols) {
117+
if (mainMapField == null) {
118+
FuzzyReflection fuzzy = FuzzyReflection.fromClass(protocol.getClass(), true);
119+
mainMapField = fuzzy.getField(FuzzyFieldContract.newBuilder()
120+
.banModifier(Modifier.STATIC)
121+
.requireModifier(Modifier.FINAL)
122+
.typeDerivedOf(Map.class)
123+
.build());
124+
mainMapField.setAccessible(true);
125+
}
126+
127+
Map<Object, Object> directionMap;
128+
129+
try {
130+
directionMap = (Map<Object, Object>) mainMapField.get(protocol);
131+
} catch (ReflectiveOperationException ex) {
132+
throw new RuntimeException("Failed to access packet map", ex);
133+
}
134+
135+
for (Entry<Object, Object> entry : directionMap.entrySet()) {
136+
Object holder = entry.getValue();
137+
if (packetMapField == null) {
138+
FuzzyReflection fuzzy = FuzzyReflection.fromClass(holder.getClass(), true);
139+
packetMapField = fuzzy.getField(FuzzyFieldContract.newBuilder()
140+
.banModifier(Modifier.STATIC)
141+
.requireModifier(Modifier.FINAL)
142+
.typeDerivedOf(Map.class)
143+
.build());
144+
packetMapField.setAccessible(true);
145+
}
146+
147+
Map<Class<?>, Integer> packetMap;
148+
149+
try {
150+
packetMap = (Map<Class<?>, Integer>) packetMapField.get(holder);
151+
} catch (ReflectiveOperationException ex) {
152+
throw new RuntimeException("Failed to access packet map", ex);
153+
}
154+
155+
String direction = entry.getKey().toString();
156+
if (direction.contains("CLIENTBOUND")) { // Sent by Server
157+
serverMaps.put(protocol, packetMap);
158+
} else if (direction.contains("SERVERBOUND")) { // Sent by Client
159+
clientMaps.put(protocol, packetMap);
160+
}
161+
}
162+
}
163+
164+
// Maps we have to occasionally check have changed
165+
// TODO: Find equivalent in Object2IntMap
166+
167+
/* for (Object map : serverMaps.values()) {
168+
result.containers.add(new MapContainer(map));
169+
}
170+
171+
for (Object map : clientMaps.values()) {
172+
result.containers.add(new MapContainer(map));
173+
} */
174+
175+
for (Object protocol : protocols) {
176+
Enum<?> enumProtocol = (Enum<?>) protocol;
177+
Protocol equivalent = Protocol.fromVanilla(enumProtocol);
178+
179+
// Associate known types
180+
if (serverMaps.containsKey(protocol)) {
181+
associatePackets(result, reverse(serverMaps.get(protocol)), equivalent, Sender.SERVER);
182+
}
183+
if (clientMaps.containsKey(protocol)) {
184+
associatePackets(result, reverse(clientMaps.get(protocol)), equivalent, Sender.CLIENT);
185+
}
186+
}
187+
188+
// Exchange (thread safe, as we have only one writer)
189+
this.register = result;
190+
}
191+
192+
/**
193+
* Reverses a key->value map to value->key
194+
* Non-deterministic behavior when multiple keys are mapped to the same value
195+
*/
196+
private <K, V> Map<V, K> reverse(Map<K, V> map) {
197+
Map<V, K> newMap = new HashMap<>(map.size());
198+
for (Entry<K, V> entry : map.entrySet()) {
199+
newMap.put(entry.getValue(), entry.getKey());
200+
}
201+
return newMap;
202+
}
203+
94204
@Override
95205
protected void associatePackets(Register register, Map<Integer, Class<?>> lookup, Protocol protocol, Sender sender) {
96206
for (Entry<Integer, Class<?>> entry : lookup.entrySet()) {

src/main/java/com/comphenix/protocol/utility/Constants.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,13 @@
2121
*/
2222

2323
public final class Constants {
24-
public static final String PACKAGE_VERSION = "v1_14_R1";
24+
public static final String PACKAGE_VERSION = "v1_15_R1";
2525
public static final String NMS = "net.minecraft.server." + PACKAGE_VERSION;
2626
public static final String OBC = "org.bukkit.craftbukkit." + PACKAGE_VERSION;
27+
public static final MinecraftVersion CURRENT_VERSION = MinecraftVersion.BEE_UPDATE;
28+
29+
public static void init() {
30+
MinecraftReflection.setMinecraftPackage(NMS, OBC);
31+
MinecraftVersion.setCurrentVersion(CURRENT_VERSION);
32+
}
2733
}

src/main/java/com/comphenix/protocol/utility/MinecraftVersion.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ public class MinecraftVersion implements Comparable<MinecraftVersion>, Serializa
4444
*/
4545
private static final Pattern VERSION_PATTERN = Pattern.compile(".*\\(.*MC.\\s*([a-zA-z0-9\\-.]+).*");
4646

47+
/**
48+
* Version 1.15 - the bee upate
49+
*/
50+
public static final MinecraftVersion BEE_UPDATE = new MinecraftVersion("1.15");
51+
4752
/**
4853
* Version 1.14 - village and pillage update.
4954
*/
@@ -258,6 +263,10 @@ public SnapshotVersion getSnapshot() {
258263
public boolean isSnapshot() {
259264
return snapshot != null;
260265
}
266+
267+
public boolean atOrAbove() {
268+
return MinecraftVersion.getCurrentVersion().isAtLeast(this);
269+
}
261270

262271
/**
263272
* Retrieve the version String (major.minor.build) only.

src/main/java/com/comphenix/protocol/wrappers/BukkitConverters.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,6 @@
4949
import com.google.common.collect.ImmutableMap;
5050
import com.google.common.collect.Lists;
5151

52-
import net.minecraft.server.v1_14_R1.EntityTypes;
53-
5452
import org.bukkit.Material;
5553
import org.bukkit.Sound;
5654
import org.bukkit.World;

0 commit comments

Comments
 (0)