Skip to content

Commit 0c3b021

Browse files
committed
v9.6.1
1 parent 4caa694 commit 0c3b021

File tree

6 files changed

+517
-281
lines changed

6 files changed

+517
-281
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
<groupId>com.github.cryptomorin</groupId>
88
<artifactId>XSeries</artifactId>
9-
<version>9.6.0</version>
9+
<version>9.6.1</version>
1010

1111
<name>XSeries</name>
1212
<description>A set of utilities for Minecraft plugins</description>

src/main/java/com/cryptomorin/xseries/NMSExtras.java

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,16 @@
4545
* All the parameters are non-null.
4646
*
4747
* @author Crypto Morin
48-
* @version 5.3.0
48+
* @version 5.3.1
4949
*/
5050
public final class NMSExtras {
51+
public static final Class<?> EntityLivingClass = getNMSClass("world.entity", "EntityLiving");
5152
public static final MethodHandle EXP_PACKET;
5253
public static final MethodHandle ENTITY_PACKET;
5354
public static final MethodHandle WORLD_HANDLE, ENTITY_HANDLE;
5455
public static final MethodHandle LIGHTNING_ENTITY;
5556
public static final MethodHandle VEC3D;
57+
public static final MethodHandle GET_DATA_WATCHER, DATA_WATCHER_GET_ITEM, DATA_WATCHER_SET_ITEM;
5658
public static final MethodHandle PACKET_PLAY_OUT_OPEN_SIGN_EDITOR, PACKET_PLAY_OUT_BLOCK_CHANGE;
5759

5860
public static final MethodHandle ANIMATION_PACKET, ANIMATION_TYPE, ANIMATION_ENTITY_ID;
@@ -94,7 +96,7 @@ public final class NMSExtras {
9496
MethodHandle tileEntitySign = null, tileEntitySign_getUpdatePacket = null, tileEntitySign_setLine = null, signText = null;
9597

9698
MethodHandle playOutMultiBlockChange = null, multiBlockChangeInfo = null, chunkWrapper = null, chunkWrapperSet = null,
97-
shortsOrInfo = null, setBlockData = null;
99+
shortsOrInfo = null, setBlockData = null, getDataWatcher = null, dataWatcherGetItem = null, dataWatcherSetItem = null;
98100

99101
try {
100102
Class<?> nmsEntityType = getNMSClass("world.entity", "EntityTypes");
@@ -109,6 +111,13 @@ public final class NMSExtras {
109111
Class<?> IChatBaseComponent = getNMSClass("network.chat", "IChatBaseComponent");
110112
Class<?> TileEntitySign = getNMSClass("world.level.block.entity", "TileEntitySign");
111113
Class<?> PacketPlayOutTileEntityData = getNMSClass("network.protocol.game", "PacketPlayOutTileEntityData");
114+
Class<?> DataWatcherClass = getNMSClass("network.syncher", "DataWatcher");
115+
Class<?> DataWatcherItemClass = getNMSClass("network.syncher", "DataWatcher$Item");
116+
Class<?> DataWatcherObjectClass = getNMSClass("network.syncher", "DataWatcherObject");
117+
118+
// getDataWatcher = lookup.findVirtual(EntityLivingClass, "al", MethodType.methodType(DataWatcherClass));
119+
// dataWatcherGetItem = lookup.findVirtual(DataWatcherClass, "b", MethodType.methodType(Object.class, DataWatcherObjectClass)); // private <T> Item<T> c(DataWatcherObject<T> datawatcherobject)
120+
// dataWatcherSetItem = lookup.findVirtual(DataWatcherClass, "b", MethodType.methodType(void.class, DataWatcherItemClass, Object.class)); // private <T> Item<T> c(DataWatcherObject<T> datawatcherobject)
112121

113122
getBukkitEntity = lookup.findVirtual(nmsEntity, "getBukkitEntity", MethodType.methodType(craftEntity));
114123
entityHandle = lookup.findVirtual(craftEntity, "getHandle", MethodType.methodType(nmsEntity));
@@ -236,6 +245,9 @@ public final class NMSExtras {
236245
ex.printStackTrace();
237246
}
238247

248+
GET_DATA_WATCHER = getDataWatcher;
249+
DATA_WATCHER_GET_ITEM = dataWatcherGetItem;
250+
DATA_WATCHER_SET_ITEM = dataWatcherSetItem;
239251
EXP_PACKET = expPacket;
240252
ENTITY_PACKET = entityPacket;
241253
WORLD_HANDLE = worldHandle;
@@ -327,6 +339,67 @@ public static void lightning(Collection<Player> players, Location location, bool
327339
}
328340
}
329341

342+
public static void getData(LivingEntity entity, DataWatcherItemType id) {
343+
try {
344+
Object dataWatcher = GET_DATA_WATCHER.invoke(entity);
345+
DATA_WATCHER_GET_ITEM.invoke(dataWatcher, id);
346+
} catch (Throwable e) {
347+
throw new RuntimeException(e);
348+
}
349+
}
350+
351+
public static Object setData(LivingEntity entity, DataWatcherItemType id, Object value) {
352+
try {
353+
Object dataWatcher = GET_DATA_WATCHER.invoke(entity);
354+
return DATA_WATCHER_SET_ITEM.invoke(dataWatcher, id, value);
355+
} catch (Throwable e) {
356+
throw new RuntimeException(e);
357+
}
358+
}
359+
360+
public static Object getStaticField(Class<?> clazz, String name) {
361+
try {
362+
Field field = clazz.getDeclaredField(name);
363+
field.setAccessible(true);
364+
return field.get(null);
365+
} catch (Throwable e) {
366+
throw new RuntimeException(e);
367+
}
368+
}
369+
370+
public enum DataWatcherItemType {
371+
// protected static final DataWatcherObject<Byte> DATA_LIVING_ENTITY_FLAGS = DataWatcher.defineId(EntityLiving.class, DataWatcherRegistry.BYTE);
372+
DATA_LIVING_ENTITY_FLAGS(getStaticField(EntityLivingClass, "t"));
373+
374+
private final Object id;
375+
376+
DataWatcherItemType(Object DataWatcherObject) {
377+
try {
378+
// public int a() { return this.a; }
379+
// Method idMethod = DataWatcherObject.getClass().getMethod("a");
380+
this.id = DataWatcherObject;
381+
} catch (Throwable e) {
382+
throw new RuntimeException(e);
383+
}
384+
}
385+
386+
public Object getId() {
387+
return id;
388+
}
389+
}
390+
391+
public static void spinEntity(LivingEntity entity, float ticks) {
392+
// https://wiki.vg/Entity_metadata#Living_Entity
393+
// Referenced as "Riptiding" or "AutoSpinAttack" modes in code.
394+
// EntityLiving.r(int ticks) doesn't exist in newer versions.
395+
// EntityLiving entityLiv = ((CraftPlayer) entity).getHandle();
396+
// DataWatcher dataWatcher = entityLiv.al();
397+
// dataWatcher.b((DataWatcherObject<Byte>) DataWatcherItemType.DATA_LIVING_ENTITY_FLAGS.getId(), (byte) 0x04);
398+
}
399+
400+
/**
401+
* For the trident riptide animation use {@link #spinEntity(LivingEntity, float)} instead.
402+
*/
330403
public static void animation(Collection<? extends Player> players, LivingEntity entity, Animation animation) {
331404
try {
332405
// https://wiki.vg/Protocol#Entity_Animation_.28clientbound.29

src/main/java/com/cryptomorin/xseries/SkullUtils.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import javax.annotation.Nullable;
3838
import java.lang.invoke.MethodHandle;
3939
import java.lang.invoke.MethodHandles;
40+
import java.lang.invoke.MethodType;
4041
import java.lang.reflect.Field;
4142
import java.lang.reflect.Method;
4243
import java.util.Base64;
@@ -58,15 +59,15 @@
5859
* either by ID, name or encoded textures URL property.
5960
*
6061
* @author Crypto Morin
61-
* @version 4.0.1
62+
* @version 4.0.2
6263
* @see XMaterial
6364
* @see ReflectionUtils
6465
* @see SkullCacheListener
6566
*/
6667
public class SkullUtils {
6768
protected static final MethodHandle
6869
CRAFT_META_SKULL_PROFILE_GETTER, CRAFT_META_SKULL_PROFILE_SETTER,
69-
CRAFT_META_SKULL_BLOCK_SETTER;
70+
CRAFT_META_SKULL_BLOCK_SETTER, PROPERTY_GETVALUE;
7071

7172
/**
7273
* Some people use this without quotes surrounding the keys, not sure what that'd work.
@@ -97,7 +98,7 @@ public class SkullUtils {
9798

9899
static {
99100
MethodHandles.Lookup lookup = MethodHandles.lookup();
100-
MethodHandle profileSetter = null, profileGetter = null, blockSetter = null;
101+
MethodHandle profileSetter = null, profileGetter = null, blockSetter = null, propGetval = null;
101102

102103
try {
103104
Class<?> CraftMetaSkull = ReflectionUtils.getCraftClass("inventory.CraftMetaSkull");
@@ -113,7 +114,7 @@ public class SkullUtils {
113114
} catch (NoSuchMethodException e) {
114115
profileSetter = lookup.unreflectSetter(profile);
115116
}
116-
} catch (NoSuchFieldException | IllegalAccessException e) {
117+
} catch (Throwable e) {
117118
e.printStackTrace();
118119
}
119120

@@ -127,6 +128,15 @@ public class SkullUtils {
127128
e.printStackTrace();
128129
}
129130

131+
if (!ReflectionUtils.supports(20, 2)) {
132+
try {
133+
propGetval = lookup.findVirtual(Property.class, "getValue", MethodType.methodType(String.class));
134+
} catch (Throwable ex) {
135+
ex.printStackTrace();
136+
}
137+
}
138+
139+
PROPERTY_GETVALUE = propGetval;
130140
CRAFT_META_SKULL_PROFILE_SETTER = profileSetter;
131141
CRAFT_META_SKULL_PROFILE_GETTER = profileGetter;
132142
CRAFT_META_SKULL_BLOCK_SETTER = blockSetter;
@@ -308,12 +318,11 @@ public static String getSkinValue(@Nonnull ItemMeta skull) {
308318
* @since 4.0.1
309319
*/
310320
private static String getPropertyValue(Property property) {
311-
if (ReflectionUtils.supports(12, 2)) {
321+
if (ReflectionUtils.supports(20, 2)) {
312322
return property.value();
313323
} else {
314324
try {
315-
//noinspection JavaReflectionMemberAccess
316-
return (String) Property.class.getMethod("getValue").invoke(property);
325+
return (String) PROPERTY_GETVALUE.invoke(property);
317326
} catch (Throwable e) {
318327
throw new RuntimeException(e);
319328
}

0 commit comments

Comments
 (0)