1414import com .reider745 .InnerCoreServer ;
1515import com .reider745 .api .hooks .annotation .Hooks ;
1616import com .reider745 .api .hooks .annotation .Inject ;
17- import com .reider745 .api .hooks .annotation .ShadowGetField ;
1817import com .reider745 .block .BlockNukkitIdConverter ;
1918import com .reider745 .block .BlockStateStorage ;
2019import com .reider745 .block .CustomBlock ;
2120import com .reider745 .block .wall .BlockWall ;
2221import it .unimi .dsi .fastutil .Hash ;
2322import it .unimi .dsi .fastutil .ints .Int2IntMap ;
2423import it .unimi .dsi .fastutil .ints .Int2IntOpenHashMap ;
24+ import it .unimi .dsi .fastutil .ints .Int2ObjectMap ;
25+ import it .unimi .dsi .fastutil .ints .Int2ObjectOpenHashMap ;
2526import it .unimi .dsi .fastutil .objects .Object2ObjectMap ;
2627import it .unimi .dsi .fastutil .objects .Object2ObjectOpenCustomHashMap ;
2728import org .cloudburstmc .nbt .NbtMap ;
@@ -38,7 +39,7 @@ public class BlockPalette {
3839 private static final Int2IntMap runtimeIdToLegacy = new Int2IntOpenHashMap ();
3940 private static final Int2IntMap stateCapacity = new Int2IntOpenHashMap ();
4041 private static final Map <String , Integer > stateIdByName = new HashMap <>();
41- private static final Map < Integer , String > nameByStateId = new HashMap <>();
42+ private static final Int2ObjectMap < String > nameByStateId = new Int2ObjectOpenHashMap <>();
4243 private static final Object2ObjectMap <NbtMap , BlockStateSnapshot > paletteMap = new Object2ObjectOpenCustomHashMap <>(new Hash .Strategy <>() {
4344 @ Override
4445 public int hashCode (NbtMap nbtMap ) {
@@ -61,6 +62,17 @@ public boolean equals(NbtMap nbtMap, NbtMap nbtMap2) {
6162 return Objects .equals (nbtMap , nbtMap2 );
6263 }
6364 });
65+ private static final Object2ObjectMap <NbtMap , Integer > levelDbRuntimeIdToData = new Object2ObjectOpenCustomHashMap <>(new Hash .Strategy <>() {
66+ @ Override
67+ public int hashCode (NbtMap nbtMap ) {
68+ return nbtMap .hashCode ();
69+ }
70+
71+ @ Override
72+ public boolean equals (NbtMap nbtMap , NbtMap nbtMap2 ) {
73+ return Objects .equals (nbtMap , nbtMap2 );
74+ }
75+ });
6476
6577 private static final cn .nukkit .level .BlockPalette blockPalette = new cn .nukkit .level .BlockPalette (LevelDBConstants .PALETTE_VERSION );
6678
@@ -167,9 +179,12 @@ public static List<JSONObject> variantGenerations(List<Integer> states) {
167179 }
168180
169181
170- public static void init () {
182+ @ Inject (className = "cn.nukkit.level.format.leveldb.NukkitLegacyMapper" )
183+ public static void registerStates (BlockStateMapping blockStateMapping ) {
171184 final long start = System .currentTimeMillis ();
172185
186+ CustomBlock .init ();
187+
173188 legacyToRuntimeId .defaultReturnValue (-1 );
174189 runtimeIdToLegacy .defaultReturnValue (-1 );
175190
@@ -215,6 +230,7 @@ public static void init() {
215230 nbt .hashCode ();
216231 BlockStateMapping .get ().registerState (runtimeId , nbt );
217232
233+ levelDbRuntimeIdToData .put (nbt , data );
218234 paletteMap .put (nbt , BlockStateSnapshot .builder ()
219235 .version (BlockStateMapping .get ().getVersion ())
220236 .vanillaState (nbt )
@@ -312,7 +328,7 @@ public static int get(int id, int meta) {
312328 runtimeId = legacyToRuntimeId .get (id << Block .DATA_BITS );
313329
314330 if (runtimeId == -1 && id != BlockID .INFO_UPDATE ) {
315- logger .error ("failed to locate state for id: " + id + ":" + meta );
331+ logger .warning ("failed to locate state for id: " + id + ":" + meta );
316332
317333 runtimeId = legacyToRuntimeId .get (BlockID .INFO_UPDATE << Block .DATA_BITS );
318334 if (runtimeId == -1 )
@@ -362,27 +378,37 @@ public static int getOrCreateRuntimeId(int legacyId) {
362378 return getOrCreateRuntimeId (ProtocolInfo .CURRENT_PROTOCOL , legacyId >> 4 , legacyId & 0xf );
363379 }
364380
365- @ ShadowGetField (className = "cn.nukkit.level.format.leveldb.BlockStateMapping" , field = "paletteMap" )
366- private static Object2ObjectMap <NbtMap , BlockStateSnapshot > getPaletteMap (BlockStateMapping self ) {throw new RuntimeException ();}
367-
368381 @ Inject (className = "cn.nukkit.level.format.leveldb.BlockStateMapping" )
369382 public static BlockStateSnapshot getStateUnsafe (BlockStateMapping self , NbtMap vanilla ) {
370- if (CustomBlock .customBlocks .containsKey (vanilla .getString ("name" ))) {
383+ String id = vanilla .getString ("name" );
384+ if (CustomBlock .customBlocks .containsKey (id )) {
371385 BlockStateSnapshot snapshot = CACHE_PALETTE .get (vanilla );
372386
373387 if (snapshot == null ) {
374388 var customVanilla = vanilla .toBuilder ();
375389 customVanilla .remove ("version" );
376- vanilla = customVanilla .build ();
377390
378391 snapshot = paletteMap .get (customVanilla .build ());
379392 if (snapshot != null ) {
380393 CACHE_PALETTE .put (vanilla , snapshot );
394+ } else {
395+ int damage = self .getState (self .updateVanillaState (vanilla )).getLegacyData ();
396+
397+ for (NbtMap key : paletteMap .keySet ()) {
398+ if (key .getString ("name" ).equals (id ) && damage == levelDbRuntimeIdToData .getOrDefault (key , 0 )) {
399+ logger .warning ("Replacing a unit with low compatibility: " + id );
400+ snapshot = paletteMap .get (key );
401+ CACHE_PALETTE .put (vanilla , snapshot );
402+ break ;
403+ }
404+ }
381405 }
382406 }
383407
384408 if (snapshot != null ) {
385409 return snapshot ;
410+ } else {
411+ logger .warning ("State not found: " + vanilla );
386412 }
387413 }
388414
0 commit comments