55import net .minestom .server .instance .DynamicChunk ;
66import net .minestom .server .instance .InstanceContainer ;
77import net .minestom .server .instance .block .Block ;
8+ import net .minestom .server .instance .light .Light ;
89import org .jetbrains .annotations .NotNull ;
910import org .jetbrains .annotations .Nullable ;
1011
1112import java .lang .invoke .MethodHandle ;
1213import java .lang .invoke .MethodHandles ;
14+ import java .util .concurrent .atomic .AtomicBoolean ;
1315
1416final class UnsafeOps {
1517 private static final MethodHandle CACHE_CHUNK_HANDLE ;
1618 private static final MethodHandle NEEDS_HEIGHTMAP_REFRESH_SETTER ;
1719 private static final MethodHandle DYNAMIC_CHUNK_ENTRIES_GETTER ;
1820 private static final MethodHandle DYNAMIC_CHUNK_TICKABLE_MAP_GETTER ;
1921
22+ private static final MethodHandle BLOCK_LIGHT_CONTENT_SETTER ;
23+ private static final MethodHandle BLOCK_LIGHT_CONTENT_PROPAGATION_SETTER ;
24+ private static final MethodHandle BLOCK_LIGHT_IS_VALID_BORDERS_SETTER ;
25+ private static final MethodHandle BLOCK_LIGHT_NEEDS_SEND_GETTER ;
26+ private static final MethodHandle SKY_LIGHT_CONTENT_SETTER ;
27+ private static final MethodHandle SKY_LIGHT_CONTENT_PROPAGATION_SETTER ;
28+ private static final MethodHandle SKY_LIGHT_IS_VALID_BORDERS_SETTER ;
29+ private static final MethodHandle SKY_LIGHT_NEEDS_SEND_GETTER ;
30+
2031 static void unsafeCacheChunk (@ NotNull InstanceContainer instance , @ NotNull Chunk chunk ) {
2132 try {
2233 CACHE_CHUNK_HANDLE .invokeExact (instance , chunk );
@@ -55,6 +66,30 @@ static void unsafeSetNeedsCompleteHeightmapRefresh(@NotNull Chunk chunk, boolean
5566 } else return null ;
5667 }
5768
69+ static void unsafeUpdateBlockLightArray (@ NotNull Light light , byte [] content ) {
70+ try {
71+ BLOCK_LIGHT_CONTENT_SETTER .invoke (light , content );
72+ BLOCK_LIGHT_CONTENT_PROPAGATION_SETTER .invoke (light , content );
73+ BLOCK_LIGHT_IS_VALID_BORDERS_SETTER .invoke (light , true );
74+ var needsSend = (AtomicBoolean ) BLOCK_LIGHT_NEEDS_SEND_GETTER .invoke (light );
75+ needsSend .set (true );
76+ } catch (Throwable t ) {
77+ throw new RuntimeException (t );
78+ }
79+ }
80+
81+ static void unsafeUpdateSkyLightArray (@ NotNull Light light , byte [] content ) {
82+ try {
83+ SKY_LIGHT_CONTENT_SETTER .invoke (light , content );
84+ SKY_LIGHT_CONTENT_PROPAGATION_SETTER .invoke (light , content );
85+ SKY_LIGHT_IS_VALID_BORDERS_SETTER .invoke (light , true );
86+ var needsSend = (AtomicBoolean ) SKY_LIGHT_NEEDS_SEND_GETTER .invoke (light );
87+ needsSend .set (true );
88+ } catch (Throwable t ) {
89+ throw new RuntimeException (t );
90+ }
91+ }
92+
5893 static {
5994 try {
6095 var lookup = MethodHandles .privateLookupIn (InstanceContainer .class , MethodHandles .lookup ());
@@ -75,5 +110,26 @@ static void unsafeSetNeedsCompleteHeightmapRefresh(@NotNull Chunk chunk, boolean
75110 } catch (IllegalAccessException | NoSuchFieldException e ) {
76111 throw new RuntimeException (e );
77112 }
113+
114+ try {
115+ var blockLight = Class .forName ("net.minestom.server.instance.light.BlockLight" );
116+ var lookup = MethodHandles .privateLookupIn (blockLight , MethodHandles .lookup ());
117+ BLOCK_LIGHT_CONTENT_SETTER = lookup .unreflectSetter (blockLight .getDeclaredField ("content" ));
118+ BLOCK_LIGHT_CONTENT_PROPAGATION_SETTER = lookup .unreflectSetter (blockLight .getDeclaredField ("contentPropagation" ));
119+ BLOCK_LIGHT_IS_VALID_BORDERS_SETTER = lookup .unreflectSetter (blockLight .getDeclaredField ("isValidBorders" ));
120+ BLOCK_LIGHT_NEEDS_SEND_GETTER = lookup .unreflectGetter (blockLight .getDeclaredField ("needsSend" ));
121+ } catch (NoSuchFieldException | ClassNotFoundException | IllegalAccessException e ) {
122+ throw new RuntimeException (e );
123+ }
124+ try {
125+ var skyLight = Class .forName ("net.minestom.server.instance.light.SkyLight" );
126+ var lookup = MethodHandles .privateLookupIn (skyLight , MethodHandles .lookup ());
127+ SKY_LIGHT_CONTENT_SETTER = lookup .unreflectSetter (skyLight .getDeclaredField ("content" ));
128+ SKY_LIGHT_CONTENT_PROPAGATION_SETTER = lookup .unreflectSetter (skyLight .getDeclaredField ("contentPropagation" ));
129+ SKY_LIGHT_IS_VALID_BORDERS_SETTER = lookup .unreflectSetter (skyLight .getDeclaredField ("isValidBorders" ));
130+ SKY_LIGHT_NEEDS_SEND_GETTER = lookup .unreflectGetter (skyLight .getDeclaredField ("needsSend" ));
131+ } catch (NoSuchFieldException | ClassNotFoundException | IllegalAccessException e ) {
132+ throw new RuntimeException (e );
133+ }
78134 }
79135}
0 commit comments