2222package com .cryptomorin .xseries ;
2323
2424import org .bukkit .Chunk ;
25+ import org .bukkit .DyeColor ;
2526import org .bukkit .Location ;
2627import org .bukkit .Material ;
2728import org .bukkit .block .Block ;
4445 * All the parameters are non-null.
4546 *
4647 * @author Crypto Morin
47- * @version 5.2.1
48+ * @version 5.3.0
4849 */
4950public final class NMSExtras {
5051 public static final MethodHandle EXP_PACKET ;
@@ -62,7 +63,8 @@ public final class NMSExtras {
6263 public static final MethodHandle PLAY_BLOCK_ACTION ;
6364 public static final MethodHandle GET_BUKKIT_ENTITY ;
6465 public static final MethodHandle GET_BLOCK_TYPE ;
65- public static final MethodHandle GET_BLOCK , GET_IBLOCK_DATA , SANITIZE_LINES , TILE_ENTITY_SIGN , TILE_ENTITY_SIGN__GET_UPDATE_PACKET , TILE_ENTITY_SIGN__SET_LINE ;
66+ public static final MethodHandle GET_BLOCK , GET_IBLOCK_DATA , SANITIZE_LINES , TILE_ENTITY_SIGN ,
67+ TILE_ENTITY_SIGN__GET_UPDATE_PACKET , TILE_ENTITY_SIGN__SET_LINE , SIGN_TEXT ;
6668
6769 public static final Class <?>
6870 MULTI_BLOCK_CHANGE_INFO_CLASS = null , // getNMSClass("PacketPlayOutMultiBlockChange$MultiBlockChangeInfo")
@@ -89,7 +91,7 @@ public final class NMSExtras {
8991 MethodHandle getBlock = null ;
9092 MethodHandle getIBlockData = null ;
9193 MethodHandle sanitizeLines = null ;
92- MethodHandle tileEntitySign = null , tileEntitySign_getUpdatePacket = null , tileEntitySign_setLine = null ;
94+ MethodHandle tileEntitySign = null , tileEntitySign_getUpdatePacket = null , tileEntitySign_setLine = null , signText = null ;
9395
9496 MethodHandle playOutMultiBlockChange = null , multiBlockChangeInfo = null , chunkWrapper = null , chunkWrapperSet = null ,
9597 shortsOrInfo = null , setBlockData = null ;
@@ -200,7 +202,9 @@ public final class NMSExtras {
200202 getBlock = lookup .findVirtual (BLOCK_DATA , v (18 , "b" ).orElse ("getBlock" ), MethodType .methodType (block ));
201203 playBlockAction = lookup .findVirtual (world , v (18 , "a" ).orElse ("playBlockAction" ), MethodType .methodType (void .class , blockPos , block , int .class , int .class ));
202204
203- signEditorPacket = lookup .findConstructor (signOpenPacket , MethodType .methodType (void .class , blockPos ));
205+ signEditorPacket = lookup .findConstructor (signOpenPacket ,
206+ v (20 , MethodType .methodType (void .class , blockPos , boolean .class ))
207+ .orElse (MethodType .methodType (void .class , blockPos )));
204208 if (supports (17 )) {
205209 packetPlayOutBlockChange = lookup .findConstructor (packetPlayOutBlockChangeClass , MethodType .methodType (void .class , blockPos , BLOCK_DATA ));
206210 getIBlockData = lookup .findStatic (CraftMagicNumbers , "getBlock" , MethodType .methodType (BLOCK_DATA , Material .class , byte .class ));
@@ -209,9 +213,24 @@ public final class NMSExtras {
209213
210214 tileEntitySign = lookup .findConstructor (TileEntitySign , MethodType .methodType (void .class , blockPos , BLOCK_DATA ));
211215 tileEntitySign_getUpdatePacket = lookup .findVirtual (TileEntitySign ,
212- v (19 , "f" ).v (18 , "c" ).orElse ("getUpdatePacket" ),
216+ v (20 , "j" ). v ( 19 , "f" ).v (18 , "c" ).orElse ("getUpdatePacket" ),
213217 MethodType .methodType (PacketPlayOutTileEntityData ));
214- tileEntitySign_setLine = lookup .findVirtual (TileEntitySign , "a" , MethodType .methodType (void .class , int .class , IChatBaseComponent , IChatBaseComponent ));
218+
219+ if (supports (20 )) {
220+ Class <?> SignText = getNMSClass ("world.level.block.entity.SignText" );
221+ // public boolean a(SignText signtext, boolean flag) {
222+ // return flag ? this.c(signtext) : this.b(signtext);
223+ // }
224+ tileEntitySign_setLine = lookup .findVirtual (TileEntitySign , "a" , MethodType .methodType (boolean .class , SignText , boolean .class ));
225+
226+ // public SignText(net.minecraft.network.chat.IChatBaseComponent[] var0, IChatBaseComponent[] var1,
227+ // EnumColor var2, boolean var3) {
228+ Class <?> EnumColor = getNMSClass ("world.item.EnumColor" );
229+ signText = lookup .findConstructor (SignText , MethodType .methodType (void .class ,
230+ IChatBaseComponent .arrayType (), IChatBaseComponent .arrayType (), EnumColor , boolean .class ));
231+ } else {
232+ tileEntitySign_setLine = lookup .findVirtual (TileEntitySign , "a" , MethodType .methodType (void .class , int .class , IChatBaseComponent , IChatBaseComponent ));
233+ }
215234 }
216235 } catch (NoSuchMethodException | IllegalAccessException | NoSuchFieldException ex ) {
217236 ex .printStackTrace ();
@@ -247,6 +266,7 @@ public final class NMSExtras {
247266 CHUNK_WRAPPER_SET = chunkWrapperSet ;
248267 SHORTS_OR_INFO = shortsOrInfo ;
249268 SET_BLOCK_DATA = setBlockData ;
269+ SIGN_TEXT = signText ;
250270 }
251271
252272 private NMSExtras () {
@@ -387,7 +407,7 @@ protected static void sendBlockChange(Player player, Chunk chunk, Map<WorldlessB
387407 /**
388408 * Currently only supports 1.17
389409 */
390- public static void openSign (Player player , String [] lines ) {
410+ public static void openSign (Player player , DyeColor textColor , String [] lines , boolean frontSide ) {
391411 try {
392412 Location loc = player .getLocation ();
393413 Object position = BLOCK_POSITION .invoke (loc .getBlockX (), 1 , loc .getBlockY ());
@@ -396,13 +416,32 @@ public static void openSign(Player player, String[] lines) {
396416
397417 Object components = SANITIZE_LINES .invoke ((Object []) lines );
398418 Object tileSign = TILE_ENTITY_SIGN .invoke (position , signBlockData );
399- for (int i = 0 ; i < lines .length ; i ++) {
400- Object component = java .lang .reflect .Array .get (components , i );
401- TILE_ENTITY_SIGN__SET_LINE .invoke (tileSign , i , component , component );
419+ if (supports (20 )) {
420+ // When can we use this without blocks... player.openSign();
421+ Class <?> EnumColor = ReflectionUtils .getNMSClass ("world.item.EnumColor" );
422+ Object enumColor = null ;
423+ for (Field field : EnumColor .getFields ()) {
424+ Object color = field .get (null );
425+ String colorName = (String ) EnumColor .getDeclaredMethod ("b" ).invoke (color ); // gets its name
426+ if (textColor .name ().equalsIgnoreCase (colorName )) {
427+ enumColor = color ;
428+ break ;
429+ }
430+ }
431+
432+ Object signText = SIGN_TEXT .invoke (components , components , enumColor , frontSide );
433+ TILE_ENTITY_SIGN__SET_LINE .invoke (signText , true );
434+ } else {
435+ for (int i = 0 ; i < lines .length ; i ++) {
436+ Object component = java .lang .reflect .Array .get (components , i );
437+ TILE_ENTITY_SIGN__SET_LINE .invoke (tileSign , i , component , component );
438+ }
402439 }
403440 Object signLinesUpdatePacket = TILE_ENTITY_SIGN__GET_UPDATE_PACKET .invoke (tileSign );
404441
405- Object signPacket = PACKET_PLAY_OUT_OPEN_SIGN_EDITOR .invoke (position );
442+ Object signPacket =
443+ v (20 , PACKET_PLAY_OUT_OPEN_SIGN_EDITOR .invoke (position , true ))
444+ .orElse (PACKET_PLAY_OUT_OPEN_SIGN_EDITOR .invoke (position ));
406445
407446 sendPacket (player , blockChangePacket , signLinesUpdatePacket , signPacket );
408447 } catch (Throwable x ) {
0 commit comments