mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2025-01-05 16:08:06 +01:00
parent
a0bb11e1bd
commit
97972acee8
@ -1017,6 +1017,17 @@ public class PacketContainer implements Serializable {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for Game State IDs in 1.16+
|
||||
* @return The Structure Modifier
|
||||
*/
|
||||
public StructureModifier<Integer> getGameStateIDs() {
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getGameStateClass(),
|
||||
BukkitConverters.getGameStateConverter()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the Map class.
|
||||
* @param keyConverter Converter for map keys
|
||||
|
@ -1856,6 +1856,16 @@ public class MinecraftReflection {
|
||||
return getArrayClass(getMultiBlockChangeInfoClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the PacketPlayOutGameStateChange.a class, aka GameState in 1.16
|
||||
* @return The GameState class
|
||||
*/
|
||||
public static Class<?> getGameStateClass() {
|
||||
// it's called "a" so there's not a whole lot we can do to identify it
|
||||
Class<?> packetClass = PacketType.Play.Server.GAME_STATE_CHANGE.getPacketClass();
|
||||
return packetClass.getClasses()[0];
|
||||
}
|
||||
|
||||
public static boolean signUpdateExists() {
|
||||
try {
|
||||
return getMinecraftClass("PacketPlayOutUpdateSign") != null;
|
||||
|
@ -17,10 +17,7 @@
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
@ -42,6 +39,7 @@ import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
@ -1461,4 +1459,73 @@ public class BukkitConverters {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static Field gameStateMapField;
|
||||
private static Field gameStateIdField;
|
||||
|
||||
public static EquivalentConverter<Integer> getGameStateConverter() {
|
||||
return new EquivalentConverter<Integer>() {
|
||||
@Override
|
||||
public Object getGeneric(Integer specific) {
|
||||
if (specific == null) {
|
||||
specific = 0;
|
||||
}
|
||||
|
||||
if (MinecraftVersion.NETHER_UPDATE.atOrAbove()) {
|
||||
if (gameStateMapField == null) {
|
||||
Class<?> stateClass = MinecraftReflection.getGameStateClass();
|
||||
gameStateMapField = FuzzyReflection
|
||||
.fromClass(stateClass, true)
|
||||
.getField(FuzzyFieldContract
|
||||
.newBuilder()
|
||||
.typeDerivedOf(Map.class)
|
||||
.build());
|
||||
gameStateMapField.setAccessible(true);
|
||||
}
|
||||
|
||||
try {
|
||||
Map<Integer, Object> map = (Map<Integer, Object>) gameStateMapField.get(null);
|
||||
return map.get(specific);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
} else {
|
||||
return specific;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getSpecific(Object generic) {
|
||||
if (generic == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (MinecraftVersion.NETHER_UPDATE.atOrAbove()) {
|
||||
if (gameStateIdField == null) {
|
||||
Class<?> stateClass = MinecraftReflection.getGameStateClass();
|
||||
gameStateIdField = FuzzyReflection
|
||||
.fromClass(stateClass, true)
|
||||
.getField(FuzzyFieldContract
|
||||
.newBuilder()
|
||||
.typeExact(int.class)
|
||||
.build());
|
||||
gameStateIdField.setAccessible(true);
|
||||
}
|
||||
|
||||
try {
|
||||
return (Integer) gameStateIdField.get(generic);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
} else {
|
||||
return (Integer) generic;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<Integer> getSpecificType() {
|
||||
return Integer.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -565,6 +565,14 @@ public class PacketContainerTest {
|
||||
assertNotSame(clone, packet);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGameStateChange() {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Server.GAME_STATE_CHANGE);
|
||||
assertTrue(packet.getGameStateIDs().read(0) == 0);
|
||||
packet.getGameStateIDs().write(0, 2);
|
||||
assertTrue(packet.getGameStateIDs().read(0) == 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions from the outbound Boss packet. Used for testing generic enums.
|
||||
* @author dmulloy2
|
||||
|
Loading…
Reference in New Issue
Block a user