diff --git a/CMakeLists.txt b/CMakeLists.txt index 62b92b2a..1481105b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,7 @@ target_compile_options(mcswitch PRIVATE -Wno-deprecated) target_compile_options(mcswitch PRIVATE -Wno-sign-compare) add_definitions(-D SAFETY_CHECKS) +add_definitions(-D UNUSED_DELETE) add_subdirectory(lib/zlib) target_include_directories(mcswitch PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/lib/zlib) # for zconf.h diff --git a/data/mcswitch_functions.csv b/data/mcswitch_functions.csv index dcb3e82f..d532bb29 100644 --- a/data/mcswitch_functions.csv +++ b/data/mcswitch_functions.csv @@ -13,18 +13,18 @@ Address,Quality,Size,Name 0x0000007100000278,O,000028,_ZN4AABB23UseDefaultThreadStorageEv 0x0000007100000294,O,000092,_ZN4AABB20ReleaseThreadStorageEv 0x00000071000002f0,O,000116,_ZN4AABB12newPermanentEdddddd -0x0000007100000364,U,000152,_ZN4AABB12newPermanentERK8BlockPos +0x0000007100000364,O,000152,_ZN4AABB12newPermanentERK8BlockPos 0x00000071000003fc,O,000008,_ZNK5Vec3i4getXEv 0x0000007100000404,O,000008,_ZNK5Vec3i4getYEv 0x000000710000040c,O,000008,_ZNK5Vec3i4getZEv -0x0000007100000414,U,000144,_ZN4AABB12newPermanentERK8BlockPosRK8BlockPos +0x0000007100000414,O,000144,_ZN4AABB12newPermanentERK8BlockPosS2_ 0x00000071000004a4,O,000016,_ZN4AABB12newPermanentEPKS_ 0x00000071000004b4,O,000004,_ZN4AABB9resetPoolEv 0x00000071000004b8,O,000152,_ZN4AABB7newTempEdddddd 0x0000007100000550,O,000144,_ZN4AABB3setEdddddd -0x00000071000005e0,U,000152,_ZN4AABB7newTempERK8BlockPos -0x0000007100000678,U,000144,_ZN4AABB7newTempERK8BlockPosRK8BlockPos -0x0000007100000708,U,000016,_ZN4AABB7newTempEPK4AABB +0x00000071000005e0,O,000152,_ZN4AABB7newTempERK8BlockPos +0x0000007100000678,O,000144,_ZN4AABB7newTempERK8BlockPosS2_ +0x0000007100000708,O,000016,_ZN4AABB7newTempEPKS_ 0x0000007100000718,O,000144,_ZN4AABBC1Edddddd 0x00000071000007a8,U,000076, 0x00000071000007f4,U,000152,_ZNK4AABB6equalsEPK4AABB @@ -5624,7 +5624,7 @@ Address,Quality,Size,Name 0x00000071000d6e58,U,000124,_ZN16DataOutputStream12writeVarLongEl 0x00000071000d6ed4,O,000080,_ZN26ClientboundSetBorderPacket6handleEP14PacketListener 0x00000071000d6f24,O,000016,_ZNSt3__110shared_ptrI26ClientboundSetBorderPacketED2Ev -0x00000071000d6f34,U,000248, +0x00000071000d6f34,M,000248,_ZN26ClientboundSetBorderPacket12applyChangesEP11WorldBorder 0x00000071000d702c,O,000056,_ZN26ClientboundSetCameraPacketC1Ev 0x00000071000d7064,U,000040,_ZN26ClientboundSetCameraPacketD2Ev 0x00000071000d708c,U,000036,_ZN26ClientboundSetCameraPacketD0Ev @@ -7025,7 +7025,7 @@ Address,Quality,Size,Name 0x00000071000fb46c,O,000008,_ZN9Dimension9getXZSizeEv 0x00000071000fb474,U,000076,_ZN9Dimension20getPlayerConstraintsERK8BlockPos 0x00000071000fb4c0,U,000252,_ZN9Dimension19inPlayerConstraintsERK8BlockPos -0x00000071000fb5bc,U,000104,_ZN9Dimension13containsChunkEii +0x00000071000fb5bc,O,000104,_ZN9Dimension13containsChunkEii 0x00000071000fb624,U,000028,_ZN9Dimension19getBlockLightColourEv 0x00000071000fb640,U,000004, 0x00000071000fb644,U,000004, @@ -14805,7 +14805,7 @@ Address,Quality,Size,Name 0x000000710020c078,U,000056, 0x000000710020c0b0,M,000072,_ZNSt3__113__vector_baseIP16TickNextTickDataNS_9allocatorIS2_EEED2Ev 0x000000710020c0f8,U,000188,_ZN10LevelChunk14containsPlayerEv -0x000000710020c1b4,U,000008, +0x000000710020c1b4,O,000008,_ZN10LevelChunk22DECOMP_getUnknownFieldEv 0x000000710020c1bc,U,000008,_ZN10LevelChunk11markUnsavedEv 0x000000710020c1c4,U,000860,_ZN10LevelChunk11getEntitiesENSt3__110shared_ptrI6EntityEEPK4AABBRNS0_6vectorIS3_NS0_9allocatorIS3_EEEEPK9PredicateIS3_E 0x000000710020c520,O,000020,_ZN3Mth5clampEiii @@ -14820,13 +14820,13 @@ Address,Quality,Size,Name 0x000000710020d3b0,U,000008,_ZN10LevelChunk7isEmptyEv 0x000000710020d3b8,U,000444,checkPostProcess__10LevelChunkFP11ChunkSourceP14ChunkGenerator 0x000000710020d574,U,000688,doPostProcess__10LevelChunkFP11ChunkSourceP14ChunkGenerator -0x000000710020d824,U,000012,postProcess__10LevelChunkFv +0x000000710020d824,O,000012,_ZN10LevelChunk11postProcessEv 0x000000710020d830,U,000308,flagPostProcessComplete__10LevelChunkFs 0x000000710020d964,U,000008,isLowerBlockStorageCompressed__10LevelChunkFv 0x000000710020d96c,U,000028,isLowerBlockLightStorageCompressed__10LevelChunkFv 0x000000710020d988,U,000028,isLowerDataStorageCompressed__10LevelChunkFv 0x000000710020d9a4,U,000452,checkChests__10LevelChunkFP11ChunkSourceiT2 -0x000000710020db68,U,000460, +0x000000710020db68,O,000460,_ZN10LevelChunk4tickEb 0x000000710020dd34,O,000044,_ZN10LevelChunk6getPosEv 0x000000710020dd60,U,000008, 0x000000710020dd68,U,000320,_ZN10LevelChunk8getBiomeERK8BlockPosP11BiomeSource @@ -14839,7 +14839,7 @@ Address,Quality,Size,Name 0x000000710020df68,U,000012,LevelChunk__getHeightmap 0x000000710020df74,U,000136, 0x000000710020dffc,U,000008, -0x000000710020e004,U,000012,_ZN10LevelChunk18isTerrainPopulatedEv +0x000000710020e004,O,000012,_ZN10LevelChunk18isTerrainPopulatedEv 0x000000710020e010,U,000012, 0x000000710020e01c,U,000008,setLastSaveTime__10LevelChunkFL 0x000000710020e024,U,000008, @@ -17275,9 +17275,9 @@ Address,Quality,Size,Name 0x0000007100283680,U,000020, 0x0000007100283694,U,000092, 0x00000071002836f0,U,000136, -0x0000007100283778,U,000192, -0x0000007100283838,U,000096,_ZN15OldChunkStorage22CreateNewThreadStorageEv -0x0000007100283898,U,000028, +0x0000007100283778,M,000192,_ZN15OldChunkStorage13ThreadStorageC1Ev +0x0000007100283838,M,000096,_ZN15OldChunkStorage22CreateNewThreadStorageEv +0x0000007100283898,O,000028,_ZN15OldChunkStorage23UseDefaultThreadStorageEv 0x00000071002838b4,U,000092,_ZN15OldChunkStorageC1E4Fileb 0x0000007100283910,U,000036, 0x0000007100283934,U,000488,_ZN15OldChunkStorage7getFileEii @@ -23983,7 +23983,7 @@ Address,Quality,Size,Name 0x000000710035b2ec,U,000036, 0x000000710035b310,U,000136, 0x000000710035b398,U,000032, -0x000000710035b3b8,U,000156,_ZN17SparseDataStorage4tickEv +0x000000710035b3b8,M,000156,_ZN17SparseDataStorage4tickEv 0x000000710035b454,U,000480, 0x000000710035b634,U,000032,isCompressed__17SparseDataStorageFv 0x000000710035b654,U,000376,SparseDataStorage__write @@ -24013,9 +24013,9 @@ Address,Quality,Size,Name 0x000000710035c3d0,U,000468, 0x000000710035c5a4,U,000280, 0x000000710035c6bc,U,000032, -0x000000710035c6dc,U,000156,_ZN18SparseLightStorage4tickEv +0x000000710035c6dc,M,000156,_ZN18SparseLightStorage4tickEv 0x000000710035c778,U,000408,_ZN18SparseLightStorage8compressEv -0x000000710035c910,U,000020,isCompressed__18SparseLightStorageFv +0x000000710035c910,U,000020,_ZN18SparseLightStorage12isCompressedEv 0x000000710035c924,U,000120,SparseLightStorage__write 0x000000710035c99c,U,000148, 0x000000710035ca30,U,000148,_ZN9SpawnDataC_gen @@ -26083,36 +26083,36 @@ Address,Quality,Size,Name 0x00000071003bf1dc,U,000376, 0x00000071003bf354,U,000132, 0x00000071003bf3d8,U,000052, -0x00000071003bf40c,U,000064,_ZN15WaterLevelChunkC1EP5LevelP11ChunkPrimerii +0x00000071003bf40c,O,000064,_ZN15WaterLevelChunkC1EP5LevelP11ChunkPrimerii 0x00000071003bf44c,U,000036, -0x00000071003bf470,U,000004, -0x00000071003bf474,U,000004, -0x00000071003bf478,U,000004, -0x00000071003bf47c,U,000004, -0x00000071003bf480,U,000008, -0x00000071003bf488,U,000008, -0x00000071003bf490,U,000016, -0x00000071003bf4a0,U,000004, -0x00000071003bf4a4,U,000004, -0x00000071003bf4a8,U,000004, -0x00000071003bf4ac,U,000004, -0x00000071003bf4b0,U,000008, -0x00000071003bf4b8,U,000004, -0x00000071003bf4bc,U,000004, -0x00000071003bf4c0,U,000004, -0x00000071003bf4c4,U,000004, -0x00000071003bf4c8,U,000004, -0x00000071003bf4cc,U,000008, -0x00000071003bf4d4,U,000004, -0x00000071003bf4d8,U,000004, -0x00000071003bf4dc,U,000004, -0x00000071003bf4e0,U,000008, -0x00000071003bf4e8,U,000008, -0x00000071003bf4f0,U,000064, -0x00000071003bf530,U,000008, -0x00000071003bf538,U,000144, -0x00000071003bf5c8,U,000092, -0x00000071003bf624,U,000008, +0x00000071003bf470,O,000004,_ZN15WaterLevelChunk17recalcBlockLightsEv +0x00000071003bf474,O,000004,_ZN15WaterLevelChunk19recalcHeightmapOnlyEv +0x00000071003bf478,O,000004,_ZN15WaterLevelChunk15recalcHeightmapEv +0x00000071003bf47c,O,000004,_ZN15WaterLevelChunk9lightLavaEv +0x00000071003bf480,O,000008,_ZN15WaterLevelChunk8setBlockERK8BlockPosPK10BlockState +0x00000071003bf488,O,000008,_ZN15WaterLevelChunk15setBlockAndDataEiiiiib +0x00000071003bf490,O,000016,_ZN15WaterLevelChunk7setDataEiiiiiPb +0x00000071003bf4a0,O,000004,_ZN15WaterLevelChunk13setBrightnessEN10LightLayer7varietyERK8BlockPosi +0x00000071003bf4a4,O,000004,_ZN15WaterLevelChunk9addEntityENSt3__110shared_ptrI6EntityEE +0x00000071003bf4a8,O,000004,_ZN15WaterLevelChunk12removeEntityENSt3__110shared_ptrI6EntityEE +0x00000071003bf4ac,O,000004,_ZN15WaterLevelChunk12removeEntityENSt3__110shared_ptrI6EntityEEi +0x00000071003bf4b0,O,000008,_ZN15WaterLevelChunk14getBlockEntityERK8BlockPosN10LevelChunk18EntityCreationTypeE +0x00000071003bf4b8,O,000004,_ZN15WaterLevelChunk14addBlockEntityENSt3__110shared_ptrI11BlockEntityEE +0x00000071003bf4bc,O,000004,_ZN15WaterLevelChunk14setBlockEntityERK8BlockPosNSt3__110shared_ptrI11BlockEntityEE +0x00000071003bf4c0,O,000004,_ZN15WaterLevelChunk17removeBlockEntityERK8BlockPos +0x00000071003bf4c4,O,000004,_ZN15WaterLevelChunk4loadEb +0x00000071003bf4c8,O,000004,_ZN15WaterLevelChunk6unloadEbb +0x00000071003bf4cc,O,000008,_ZN15WaterLevelChunk14containsPlayerEv +0x00000071003bf4d4,O,000004,_ZN15WaterLevelChunk11markUnsavedEv +0x00000071003bf4d8,O,000004,_ZN15WaterLevelChunk11getEntitiesENSt3__110shared_ptrI6EntityEEPK4AABBRNS0_6vectorIS3_NS0_9allocatorIS3_EEEEPK9PredicateIS3_E +0x00000071003bf4dc,O,000004,_ZN15WaterLevelChunk18getEntitiesOfClassERKSt9type_infoPK4AABBRNSt3__16vectorINS6_10shared_ptrI6EntityEENS6_9allocatorISA_EEEEPK9PredicateISA_Eb +0x00000071003bf4e0,O,000008,_ZN15WaterLevelChunk13countEntitiesEv +0x00000071003bf4e8,O,000008,_ZN15WaterLevelChunk10shouldSaveEb +0x00000071003bf4f0,U,000064,_ZN15WaterLevelChunk16setBlocksAndDataE15arrayWithLengthIhEiiiiiiib +0x00000071003bf530,O,000008,_ZN15WaterLevelChunk20testSetBlocksAndDataE15arrayWithLengthIhEiiiiiii +0x00000071003bf538,M,000144,_ZN15WaterLevelChunk9getRandomEx +0x00000071003bf5c8,O,000092,_ZN15WaterLevelChunk23setLevelChunkBrightnessEN10LightLayer7varietyEiiii +0x00000071003bf624,O,000008,_ZN15WaterLevelChunk8getBiomeERK8BlockPosP11BiomeSource 0x00000071003bf62c,O,000052,_ZN14WaterlilyBlockC1Ev 0x00000071003bf660,O,000016,_ZN14WaterlilyBlock8getShapeEPK10BlockStateP11LevelSourceRK8BlockPos 0x00000071003bf670,O,000116,_ZN14WaterlilyBlock17addCollisionAABBsEPK10BlockStateP5LevelRK8BlockPosPK4AABBPNSt3__16vectorIPS8_NSB_9allocatorISD_EEEENSB_10shared_ptrI6EntityEEb @@ -26507,32 +26507,32 @@ Address,Quality,Size,Name 0x00000071003d2830,U,000116,_ZN15WoolCarpetBlock10getTextureEPK9DirectionPK10BlockState 0x00000071003d28a4,U,000004,_ZN15WoolCarpetBlock13registerIconsEP12IconRegister 0x00000071003d28a8,O,000088,_ZN11WorldBorderC1EP5Level -0x00000071003d2900,U,000076,_ZN11WorldBorderD2Ev -0x00000071003d294c,U,000036,_ZN11WorldBorderD0Ev -0x00000071003d2970,U,000168,_ZN11WorldBorder14isWithinBoundsERK8BlockPos +0x00000071003d2900,M,000076,_ZN11WorldBorderD2Ev +0x00000071003d294c,O,000036,_ZN11WorldBorderD0Ev +0x00000071003d2970,O,000168,_ZN11WorldBorder14isWithinBoundsERK8BlockPos 0x00000071003d2a18,O,000092,_ZN11WorldBorder7getMinXEv 0x00000071003d2a74,O,000092,_ZN11WorldBorder7getMaxXEv 0x00000071003d2ad0,O,000092,_ZN11WorldBorder7getMinZEv 0x00000071003d2b2c,O,000092,_ZN11WorldBorder7getMaxZEv -0x00000071003d2b88,U,000124,_ZN11WorldBorder14isWithinBoundsEP4AABB -0x00000071003d2c04,U,000016,_ZN11WorldBorder19getDistanceToBorderENSt3__110shared_ptrI6EntityEE -0x00000071003d2c14,U,000148,_ZN11WorldBorder19getDistanceToBorderEdd +0x00000071003d2b88,O,000124,_ZN11WorldBorder14isWithinBoundsEP4AABB +0x00000071003d2c04,O,000016,_ZN11WorldBorder19getDistanceToBorderENSt3__110shared_ptrI6EntityEE +0x00000071003d2c14,O,000148,_ZN11WorldBorder19getDistanceToBorderEdd 0x00000071003d2ca8,O,000048,_ZN11WorldBorder9getStatusEv 0x00000071003d2cd8,O,000132,_ZN11WorldBorder7getSizeEv 0x00000071003d2d5c,O,000008,_ZN11WorldBorder10getCenterXEv 0x00000071003d2d64,O,000008,_ZN11WorldBorder10getCenterZEv -0x00000071003d2d6c,U,000116, +0x00000071003d2d6c,O,000116,_ZN11WorldBorder9setCenterEdd 0x00000071003d2de0,O,000008,_ZN11WorldBorder12getListenersEv -0x00000071003d2de8,U,000120,_ZN11WorldBorder7setSizeEd -0x00000071003d2e60,U,000140, -0x00000071003d2eec,U,000072,_ZN11WorldBorder11addListenerEP20BorderChangeListener -0x00000071003d2f34,U,000008, +0x00000071003d2de8,O,000120,_ZN11WorldBorder7setSizeEd +0x00000071003d2e60,O,000140,_ZN11WorldBorder15lerpSizeBetweenEddx +0x00000071003d2eec,O,000072,_ZN11WorldBorder11addListenerEP20BorderChangeListener +0x00000071003d2f34,O,000008,_ZN11WorldBorder18setAbsoluteMaxSizeEi 0x00000071003d2f3c,O,000008,_ZN11WorldBorder17getDamageSafeZoneEv -0x00000071003d2f44,U,000104, +0x00000071003d2f44,O,000104,_ZN11WorldBorder17setDamageSafeZoneEd 0x00000071003d2fac,O,000008,_ZN11WorldBorder17getDamagePerBlockEv -0x00000071003d2fb4,U,000104, -0x00000071003d301c,U,000096, -0x00000071003d307c,U,000096, +0x00000071003d2fb4,O,000104,_ZN11WorldBorder17setDamagePerBlockEd +0x00000071003d301c,O,000096,_ZN11WorldBorder14setWarningTimeEi +0x00000071003d307c,O,000096,_ZN11WorldBorder16setWarningBlocksEi 0x00000071003d30dc,U,000056,_ZN16WritableBookItemC_gen 0x00000071003d3114,U,000148,_ZN16WritableBookItem3useEP5LevelNSt3__110shared_ptrI6PlayerEEN15InteractionHand16EInteractionHandE 0x00000071003d31a8,U,000008,_ZN16WritableBookItem7TestUseEP5LevelNSt3__110shared_ptrI6PlayerEEN15InteractionHand16EInteractionHandE @@ -26936,9 +26936,9 @@ Address,Quality,Size,Name 0x00000071003da07c,U,000036,_ZN29WaterAvoidingRandomFlyingGoalD0Ev 0x00000071003da0a0,U,000052,_ZN24WaterBoundPathNavigationD2Ev 0x00000071003da0d4,U,000036,_ZN24WaterBoundPathNavigationD0Ev -0x00000071003da0f8,U,000004, -0x00000071003da0fc,U,000004, -0x00000071003da100,U,000036,_ZN15WaterLevelChunkD0Ev +0x00000071003da0f8,O,000004,_ZN15WaterLevelChunk14reSyncLightingEv +0x00000071003da0fc,O,000004,_ZN15WaterLevelChunk12dropLightingEv +0x00000071003da100,O,000036,_ZN15WaterLevelChunkD0Ev 0x00000071003da124,O,000036,_ZN14WaterlilyBlockD0Ev 0x00000071003da148,U,000036,_ZN18WaterLilyBlockItemD0Ev 0x00000071003da16c,O,000036,_ZN16WaterlilyFeatureD0Ev @@ -28634,39 +28634,39 @@ Address,Quality,Size,Name 0x000000710040d818,U,000056, 0x000000710040d850,U,000360, 0x000000710040d9b8,U,000048,_ZN28FJ_BeaconEffectButton_NormalC_gen -0x000000710040d9e8,U,000052, +0x000000710040d9e8,U,000052,_ZN28FJ_BeaconEffectButton_Normal6CreateEP13fuiRenderNode 0x000000710040da1c,U,000008, 0x000000710040da24,U,000048,_ZN27FJ_BeaconEffectButton_SmallC_gen -0x000000710040da54,U,000052, +0x000000710040da54,U,000052,_ZN27FJ_BeaconEffectButton_Small6CreateEP13fuiRenderNode 0x000000710040da88,U,000008, 0x000000710040da90,U,000048,_ZN26FJ_EnchantingButton_NormalC_gen -0x000000710040dac0,U,000052, +0x000000710040dac0,U,000052,_ZN26FJ_EnchantingButton_Normal6CreateEP13fuiRenderNode 0x000000710040daf4,U,000008, 0x000000710040dafc,U,000048,_ZN25FJ_EnchantingButton_SmallC_gen -0x000000710040db2c,U,000052, +0x000000710040db2c,U,000052,_ZN25FJ_EnchantingButton_Small6CreateEP13fuiRenderNode 0x000000710040db60,U,000008, 0x000000710040db68,U,000084,_ZN18FJ_KeyboardButtonsC_gen 0x000000710040dbbc,U,000248, 0x000000710040dcb4,U,000224, 0x000000710040dd94,U,000596, 0x000000710040dfe8,U,000056,_ZN34FJ_KeyboardButtons_Controls_NormalC_gen -0x000000710040e020,U,000052, +0x000000710040e020,U,000052,_ZN34FJ_KeyboardButtons_Controls_Normal6CreateEP13fuiRenderNode 0x000000710040e054,U,000008, 0x000000710040e05c,U,000056,_ZN33FJ_KeyboardButtons_Controls_SmallC_gen -0x000000710040e094,U,000052, +0x000000710040e094,U,000052,_ZN33FJ_KeyboardButtons_Controls_Small6CreateEP13fuiRenderNode 0x000000710040e0c8,U,000008, 0x000000710040e0d0,U,000056,_ZN30FJ_KeyboardButtons_Keys_NormalC_gen -0x000000710040e108,U,000052, +0x000000710040e108,U,000052,_ZN30FJ_KeyboardButtons_Keys_Normal6CreateEP13fuiRenderNode 0x000000710040e13c,U,000008, 0x000000710040e144,U,000056,_ZN29FJ_KeyboardButtons_Keys_SmallC_gen -0x000000710040e17c,U,000052, +0x000000710040e17c,U,000052,_ZN29FJ_KeyboardButtons_Keys_Small6CreateEP13fuiRenderNode 0x000000710040e1b0,U,000008, 0x000000710040e1b8,U,000048,_ZN15FJ_LayoutButtonC_gen -0x000000710040e1e8,U,000052, +0x000000710040e1e8,U,000052,_ZN15FJ_LayoutButton6CreateEP13fuiRenderNode 0x000000710040e21c,U,000008, 0x000000710040e224,U,000064, 0x000000710040e264,U,000048,_ZN21FJ_LayoutButton_SmallC_gen -0x000000710040e294,U,000052, +0x000000710040e294,U,000052,_ZN21FJ_LayoutButton_Small6CreateEP13fuiRenderNode 0x000000710040e2c8,U,000008, 0x000000710040e2d0,U,000064, 0x000000710040e310,U,000064,_ZN13FJ_ListButtonC_gen @@ -28680,10 +28680,10 @@ Address,Quality,Size,Name 0x000000710040e4e4,U,000020, 0x000000710040e4f8,U,000020, 0x000000710040e50c,U,000048,_ZN31FJ_ListButtonAchievement_NormalC_gen -0x000000710040e53c,U,000052, +0x000000710040e53c,U,000052,_ZN31FJ_ListButtonAchievement_Normal6CreateEP13fuiRenderNode 0x000000710040e570,U,000008, 0x000000710040e578,U,000048,_ZN30FJ_ListButtonAchievement_SmallC_gen -0x000000710040e5a8,U,000052, +0x000000710040e5a8,U,000052,_ZN30FJ_ListButtonAchievement_Small6CreateEP13fuiRenderNode 0x000000710040e5dc,U,000008, 0x000000710040e5e4,U,000084,_ZN21FJ_ListButtonCheckboxC_gen 0x000000710040e638,U,000136, @@ -28697,71 +28697,71 @@ Address,Quality,Size,Name 0x000000710040ebb8,U,000028, 0x000000710040ebd4,U,000008, 0x000000710040ebdc,U,000048,_ZN28FJ_ListButtonCheckbox_NormalC_gen -0x000000710040ec0c,U,000052, +0x000000710040ec0c,U,000052,_ZN28FJ_ListButtonCheckbox_Normal6CreateEP13fuiRenderNode 0x000000710040ec40,U,000008, 0x000000710040ec48,U,000048,_ZN27FJ_ListButtonCheckbox_SmallC_gen -0x000000710040ec78,U,000052, +0x000000710040ec78,U,000052,_ZN27FJ_ListButtonCheckbox_Small6CreateEP13fuiRenderNode 0x000000710040ecac,U,000008, 0x000000710040ecb4,U,000048,_ZN23FJ_ListButtonControllerC_gen 0x000000710040ece4,U,000088, 0x000000710040ed3c,U,000048,_ZN30FJ_ListButtonController_NormalC_gen -0x000000710040ed6c,U,000052, +0x000000710040ed6c,U,000052,_ZN30FJ_ListButtonController_Normal6CreateEP13fuiRenderNode 0x000000710040eda0,U,000008, 0x000000710040eda8,U,000048,_ZN29FJ_ListButtonController_SmallC_gen -0x000000710040edd8,U,000052, +0x000000710040edd8,U,000052,_ZN29FJ_ListButtonController_Small6CreateEP13fuiRenderNode 0x000000710040ee0c,U,000008, 0x000000710040ee14,U,000144,_ZN16FJ_ListButtonDLCC_gen 0x000000710040eea4,U,000156, 0x000000710040ef40,U,000160, 0x000000710040efe0,U,000048,_ZN23FJ_ListButtonDLC_NormalC_gen -0x000000710040f010,U,000052, +0x000000710040f010,U,000052,_ZN23FJ_ListButtonDLC_Normal6CreateEP13fuiRenderNode 0x000000710040f044,U,000008, 0x000000710040f04c,U,000048,_ZN22FJ_ListButtonDLC_SmallC_gen -0x000000710040f07c,U,000052, +0x000000710040f07c,U,000052,_ZN22FJ_ListButtonDLC_Small6CreateEP13fuiRenderNode 0x000000710040f0b0,U,000008, 0x000000710040f0b8,U,000052,_ZN21FJ_ListButtonIconLeftC_gen 0x000000710040f0ec,U,000072, 0x000000710040f134,U,000372, 0x000000710040f2a8,U,000944, 0x000000710040f658,U,000048,_ZN28FJ_ListButtonIconLeft_NormalC_gen -0x000000710040f688,U,000052, +0x000000710040f688,U,000052,_ZN28FJ_ListButtonIconLeft_Normal6CreateEP13fuiRenderNode 0x000000710040f6bc,U,000008, 0x000000710040f6c4,U,000048,_ZN27FJ_ListButtonIconLeft_SmallC_gen -0x000000710040f6f4,U,000052, +0x000000710040f6f4,U,000052,_ZN27FJ_ListButtonIconLeft_Small6CreateEP13fuiRenderNode 0x000000710040f728,U,000008, 0x000000710040f730,U,000048,_ZN30FJ_ListButtonIconX2Left_NormalC_gen -0x000000710040f760,U,000052, +0x000000710040f760,U,000052,_ZN30FJ_ListButtonIconX2Left_Normal6CreateEP13fuiRenderNode 0x000000710040f794,U,000008, 0x000000710040f79c,U,000048,_ZN29FJ_ListButtonIconX2Left_SmallC_gen -0x000000710040f7cc,U,000052, +0x000000710040f7cc,U,000052,_ZN29FJ_ListButtonIconX2Left_Small6CreateEP13fuiRenderNode 0x000000710040f800,U,000008, 0x000000710040f808,U,000048,_ZN22FJ_ListButtonLayerIconC_gen 0x000000710040f838,U,000072, 0x000000710040f880,U,000372, 0x000000710040f9f4,U,000428, 0x000000710040fba0,U,000048,_ZN29FJ_ListButtonLayerIcon_NormalC_gen -0x000000710040fbd0,U,000052, +0x000000710040fbd0,U,000052,_ZN29FJ_ListButtonLayerIcon_Normal6CreateEP13fuiRenderNode 0x000000710040fc04,U,000008, 0x000000710040fc0c,U,000048,_ZN28FJ_ListButtonLayerIcon_SmallC_gen -0x000000710040fc3c,U,000052, +0x000000710040fc3c,U,000052,_ZN28FJ_ListButtonLayerIcon_Small6CreateEP13fuiRenderNode 0x000000710040fc70,U,000008, 0x000000710040fc78,U,000328,_ZN18FJ_ListButtonLobbyC_gen 0x000000710040fdc0,U,000400, 0x000000710040ff50,U,000048,_ZN25FJ_ListButtonLobby_NormalC_gen -0x000000710040ff80,U,000052, +0x000000710040ff80,U,000052,_ZN25FJ_ListButtonLobby_Normal6CreateEP13fuiRenderNode 0x000000710040ffb4,U,000008, 0x000000710040ffbc,U,000048,_ZN24FJ_ListButtonLobby_SmallC_gen -0x000000710040ffec,U,000052, +0x000000710040ffec,U,000052,_ZN24FJ_ListButtonLobby_Small6CreateEP13fuiRenderNode 0x0000007100410020,U,000008, 0x0000007100410028,U,000192,_ZN23FJ_ListButtonPlayerListC_gen 0x00000071004100e8,U,000224, 0x00000071004101c8,U,000008, 0x00000071004101d0,U,000008, 0x00000071004101d8,U,000048,_ZN30FJ_ListButtonPlayerList_NormalC_gen -0x0000007100410208,U,000052, +0x0000007100410208,U,000052,_ZN30FJ_ListButtonPlayerList_Normal6CreateEP13fuiRenderNode 0x000000710041023c,U,000008, 0x0000007100410244,U,000048,_ZN29FJ_ListButtonPlayerList_SmallC_gen -0x0000007100410274,U,000052, +0x0000007100410274,U,000052,_ZN29FJ_ListButtonPlayerList_Small6CreateEP13fuiRenderNode 0x00000071004102a8,U,000008, 0x00000071004102b0,U,000196,_ZN23FJ_ListButtonScoreBoardC_gen 0x0000007100410374,U,000224, @@ -28776,19 +28776,19 @@ Address,Quality,Size,Name 0x0000007100410ccc,U,000052, 0x0000007100410d00,U,000104, 0x0000007100410d68,U,000052,_ZN30FJ_ListButtonScoreBoard_NormalC_gen -0x0000007100410d9c,U,000052, +0x0000007100410d9c,U,000052,_ZN30FJ_ListButtonScoreBoard_Normal6CreateEP13fuiRenderNode 0x0000007100410dd0,U,000008, 0x0000007100410dd8,U,000056,_ZN29FJ_ListButtonScoreBoard_SmallC_gen -0x0000007100410e10,U,000052, +0x0000007100410e10,U,000052,_ZN29FJ_ListButtonScoreBoard_Small6CreateEP13fuiRenderNode 0x0000007100410e44,U,000008, 0x0000007100410e4c,U,000048,_ZN20FJ_ListButton_MediumC_gen -0x0000007100410e7c,U,000052, +0x0000007100410e7c,U,000052,_ZN20FJ_ListButton_Medium6CreateEP13fuiRenderNode 0x0000007100410eb0,U,000008, 0x0000007100410eb8,U,000048,_ZN20FJ_ListButton_NormalC_gen -0x0000007100410ee8,U,000052, +0x0000007100410ee8,U,000052,_ZN20FJ_ListButton_Normal6CreateEP13fuiRenderNode 0x0000007100410f1c,U,000008, 0x0000007100410f24,U,000048,_ZN19FJ_ListButton_SmallC_gen -0x0000007100410f54,U,000052, +0x0000007100410f54,U,000052,_ZN19FJ_ListButton_Small6CreateEP13fuiRenderNode 0x0000007100410f88,U,000008, 0x0000007100410f90,U,000048,__ct__13FJ_MenuButtonFP13fuiRenderNode 0x0000007100410fc0,U,000064, @@ -28797,15 +28797,15 @@ Address,Quality,Size,Name 0x000000710041103c,M,000052,_ZN20FJ_MenuButton_Normal6CreateEP13fuiRenderNode 0x0000007100411070,U,000008, 0x0000007100411078,U,000048,_ZN19FJ_MenuButton_SmallC_gen -0x00000071004110a8,U,000052, +0x00000071004110a8,U,000052,_ZN19FJ_MenuButton_Small6CreateEP13fuiRenderNode 0x00000071004110dc,U,000008, 0x00000071004110e4,U,000068,_ZN15FJ_UpsellButtonC_gen 0x0000007100411128,U,000064, 0x0000007100411168,U,000048,_ZN22FJ_UpsellButton_NormalC_gen -0x0000007100411198,U,000052, +0x0000007100411198,U,000052,_ZN22FJ_UpsellButton_Normal6CreateEP13fuiRenderNode 0x00000071004111cc,U,000008, 0x00000071004111d4,U,000048,_ZN21FJ_UpsellButton_SmallC_gen -0x0000007100411204,U,000052, +0x0000007100411204,U,000052,_ZN21FJ_UpsellButton_Small6CreateEP13fuiRenderNode 0x0000007100411238,U,000008, 0x0000007100411240,U,000048,_ZN18FJ_CheckBox_NormalC_gen 0x0000007100411270,U,000052, @@ -29390,7 +29390,7 @@ Address,Quality,Size,Name 0x0000007100436a30,U,000008, 0x0000007100436a38,U,000108, 0x0000007100436aa4,U,000108, -0x0000007100436b10,U,000052, +0x0000007100436b10,U,000052,_ZN11FJ_IconSlot6CreateEP13fuiRenderNode 0x0000007100436b44,U,000008, 0x0000007100436b4c,U,000048,_ZN11FJ_IconSlotC_gen 0x0000007100436b7c,U,000112, @@ -29897,11 +29897,11 @@ Address,Quality,Size,Name 0x0000007100441e80,U,000492, 0x000000710044206c,U,000108, 0x00000071004420d8,U,000704, -0x0000007100442398,U,000052, +0x0000007100442398,U,000052,_ZN25FJ_LeaderboardEntryNormal6CreateEP13fuiRenderNode 0x00000071004423cc,U,000008, 0x00000071004423d4,U,000160,_ZN25FJ_LeaderboardEntryNormalC_gen 0x0000007100442474,U,000124, -0x00000071004424f0,U,000052, +0x00000071004424f0,U,000052,_ZN24FJ_LeaderboardEntrySmall6CreateEP13fuiRenderNode 0x0000007100442524,U,000008, 0x000000710044252c,U,000160,_ZN24FJ_LeaderboardEntrySmallC_gen 0x00000071004425cc,U,000124, @@ -29927,13 +29927,13 @@ Address,Quality,Size,Name 0x00000071004431bc,O,000008,_ZN13fuiRenderNode8setAlphaEf 0x00000071004431c4,U,000928, 0x0000007100443564,U,000576, -0x00000071004437a4,U,000052, +0x00000071004437a4,U,000052,_ZN26FJ_LeaderboardHeaderNormal6CreateEP13fuiRenderNode 0x00000071004437d8,U,000008, 0x00000071004437e0,U,000048,_ZN26FJ_LeaderboardHeaderNormalC_gen -0x0000007100443810,U,000052, +0x0000007100443810,U,000052,_ZN25FJ_LeaderboardHeaderSmall6CreateEP13fuiRenderNode 0x0000007100443844,U,000008, 0x000000710044384c,U,000048,_ZN25FJ_LeaderboardHeaderSmallC_gen -0x000000710044387c,U,000052, +0x000000710044387c,U,000052,_ZN18FJ_LeaderboardList6CreateEP13fuiRenderNode 0x00000071004438b0,U,000008, 0x00000071004438b8,U,000140,_ZN18FJ_LeaderboardListC_gen 0x0000007100443944,U,000180, @@ -29963,50 +29963,50 @@ Address,Quality,Size,Name 0x0000007100445010,U,000164, 0x00000071004450b4,U,000060,_ZN18FJ_List_ListButtonC_gen 0x00000071004450f0,U,000164, -0x0000007100445194,U,000052, +0x0000007100445194,U,000052,_ZN18FJ_List_ListButton6CreateEP13fuiRenderNode 0x00000071004451c8,U,000008, 0x00000071004451d0,U,000048,_ZN29FJ_List_ListButtonAchievementC_gen 0x0000007100445200,U,000152, -0x0000007100445298,U,000052, +0x0000007100445298,U,000052,_ZN29FJ_List_ListButtonAchievement6CreateEP13fuiRenderNode 0x00000071004452cc,U,000008, 0x00000071004452d4,U,000052,_ZN26FJ_List_ListButtonCheckboxC_gen 0x0000007100445308,U,000012, 0x0000007100445314,U,000272, -0x0000007100445424,U,000052, +0x0000007100445424,U,000052,_ZN26FJ_List_ListButtonCheckbox6CreateEP13fuiRenderNode 0x0000007100445458,U,000008, 0x0000007100445460,U,000052, 0x0000007100445494,U,000032, 0x00000071004454b4,U,000048,_ZN21FJ_List_ListButtonDLCC_gen 0x00000071004454e4,U,000156, -0x0000007100445580,U,000052, +0x0000007100445580,U,000052,_ZN21FJ_List_ListButtonDLC6CreateEP13fuiRenderNode 0x00000071004455b4,U,000008, 0x00000071004455bc,U,000052, 0x00000071004455f0,U,000052,_ZN26FJ_List_ListButtonIconLeftC_gen 0x0000007100445624,U,000012, 0x0000007100445630,U,000296, 0x0000007100445758,U,000120, -0x00000071004457d0,U,000052, +0x00000071004457d0,U,000052,_ZN26FJ_List_ListButtonIconLeft6CreateEP13fuiRenderNode 0x0000007100445804,U,000008, 0x000000710044580c,U,000052,_ZN27FJ_List_ListButtonLayerIconC_gen 0x0000007100445840,U,000012, 0x000000710044584c,U,000332, -0x0000007100445998,U,000052, +0x0000007100445998,U,000052,_ZN27FJ_List_ListButtonLayerIcon6CreateEP13fuiRenderNode 0x00000071004459cc,U,000008, 0x00000071004459d4,U,000060, 0x0000007100445a10,U,000120, 0x0000007100445a88,U,000048,_ZN23FJ_List_ListButtonLobbyC_gen -0x0000007100445ab8,U,000052, +0x0000007100445ab8,U,000052,_ZN23FJ_List_ListButtonLobby6CreateEP13fuiRenderNode 0x0000007100445aec,U,000008, 0x0000007100445af4,U,000048,_ZN28FJ_List_ListButtonPlayerListC_gen 0x0000007100445b24,U,000172, -0x0000007100445bd0,U,000052, +0x0000007100445bd0,U,000052,_ZN28FJ_List_ListButtonPlayerList6CreateEP13fuiRenderNode 0x0000007100445c04,U,000008, 0x0000007100445c0c,U,000052, 0x0000007100445c40,U,000052, 0x0000007100445c74,U,000080,_ZN28FJ_List_ListButtonScoreBoardC_gen 0x0000007100445cc4,U,000008, 0x0000007100445ccc,U,000216, -0x0000007100445da4,U,000052, +0x0000007100445da4,U,000052,_ZN28FJ_List_ListButtonScoreBoard6CreateEP13fuiRenderNode 0x0000007100445dd8,U,000008, 0x0000007100445de0,U,000052, 0x0000007100445e14,U,000052, @@ -30015,7 +30015,7 @@ Address,Quality,Size,Name 0x0000007100445ec0,U,000104, 0x0000007100445f28,U,000052,_ZN18FJ_List_MenuButtonC_gen 0x0000007100445f5c,U,000144,_ZN18FJ_List_MenuButton10addNewItemEv -0x0000007100445fec,U,000052, +0x0000007100445fec,U,000052,_ZN18FJ_List_MenuButton6CreateEP13fuiRenderNode 0x0000007100446020,U,000008, 0x0000007100446028,U,000052, 0x000000710044605c,U,000008, @@ -30088,7 +30088,7 @@ Address,Quality,Size,Name 0x000000710044856c,U,000144,_ZN23FJ_TexturePackList_SlotC_gen 0x00000071004485fc,U,000024, 0x0000007100448614,U,000048,_ZN19FJ_CheckpointMarkerC_gen -0x0000007100448644,U,000052, +0x0000007100448644,U,000052,_ZN19FJ_CheckpointMarker6CreateEP13fuiRenderNode 0x0000007100448678,U,000008, 0x0000007100448680,U,000008, 0x0000007100448688,U,000048,_ZN12FJ_MobEffectC_gen @@ -30762,7 +30762,6 @@ Address,Quality,Size,Name 0x0000007100495584,U,000020, 0x0000007100495598,U,000008, 0x00000071004955a0,U,000020, -0x00000071004955b4,U,000032, 0x00000071004955d4,U,000020, 0x00000071004955e8,U,000036, 0x000000710049560c,U,000080,_ZN35PodiumPlaceMostBlocksDestroyedMedalC_gen @@ -30945,7 +30944,7 @@ Address,Quality,Size,Name 0x000000710049af20,U,000024, 0x000000710049af38,U,000044, 0x000000710049af64,U,000048,_ZN14GameModePacket9EmptyDataC1Ev -0x000000710049af94,U,000008, +0x000000710049af94,O,000008,_ZN20ClientMasterGameMode21isNewLevelDataPendingEv 0x000000710049af9c,U,000120,_ZN20ClientMasterGameMode21isWaitingToTransitionEv 0x000000710049b014,U,000132,_ZN20ClientMasterGameMode13popTransitionEv 0x000000710049b098,U,000068, @@ -33228,7 +33227,7 @@ Address,Quality,Size,Name 0x00000071004e222c,U,000108, 0x00000071004e2298,U,000500, 0x00000071004e248c,O,000056,_ZNKSt3__14hashINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEclERKS6_ -0x00000071004e24c4,U,000120, +0x00000071004e24c4,O,000120,_ZNSt3__112__hash_tableINS_17__hash_value_typeINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFP10FJ_FuiNodeP13fuiRenderNodeEEENS_22__unordered_map_hasherIS7_SE_NS_4hashIS7_EELb1EEENS_21__unordered_map_equalIS7_SE_NS_8equal_toIS7_EELb1EEENS5_ISE_EEE21__construct_node_hashINS_4pairIS7_SD_EEJEEENS_10unique_ptrINS_11__hash_nodeISE_PvEENS_22__hash_node_destructorINS5_ISV_EEEEEEmOT_DpOT0_ 0x00000071004e253c,O,000228,_ZNSt3__112__hash_tableINS_17__hash_value_typeINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFP10FJ_FuiNodeP13fuiRenderNodeEEENS_22__unordered_map_hasherIS7_SE_NS_4hashIS7_EELb1EEENS_21__unordered_map_equalIS7_SE_NS_8equal_toIS7_EELb1EEENS5_ISE_EEE6rehashEm 0x00000071004e2620,O,000856,_ZNSt3__112__hash_tableINS_17__hash_value_typeINS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEPFP10FJ_FuiNodeP13fuiRenderNodeEEENS_22__unordered_map_hasherIS7_SE_NS_4hashIS7_EELb1EEENS_21__unordered_map_equalIS7_SE_NS_8equal_toIS7_EELb1EEENS5_ISE_EEE8__rehashEm 0x00000071004e2978,U,000184,_ZN7fuiFile24dumpUnresolvedReferencesEv @@ -38684,7 +38683,7 @@ Address,Quality,Size,Name 0x00000071005deec4,U,000332,_ZN17UIScene_PauseMenuC1EiPvP7UILayer 0x00000071005df010,U,001772, 0x00000071005df6fc,U,000304,_ZN17UIScene_PauseMenuD2Ev -0x00000071005df82c,U,000020, +0x00000071005df82c,U,000020,_ZN13CMinecraftApp18SetXuiServerActionEi16eXuiServerActionPv 0x00000071005df840,U,000036,_ZN17UIScene_PauseMenuD0Ev 0x00000071005df864,U,000088, 0x00000071005df8bc,U,000604,_ZN17UIScene_PauseMenu4tickEv @@ -39339,7 +39338,7 @@ Address,Quality,Size,Name 0x0000007100602db4,U,000004, 0x0000007100602db8,U,000588, 0x0000007100603004,U,000032,GetMojangDataForXuid__13CMinecraftAppF9PlayerUID -0x0000007100603024,U,000188, +0x0000007100603024,U,000188,_ZN13CMinecraftApp28EnterSaveNotificationSectionEv 0x00000071006030e0,U,001172, 0x0000007100603574,U,000080, 0x00000071006035c4,U,000012, @@ -39537,7 +39536,7 @@ Address,Quality,Size,Name 0x0000007100608e68,U,000088,_ZN20CConsoleMinecraftApp12CommerceInitEv 0x0000007100608ec0,U,000068,CConsoleMinecraftApp__DisplaySavingMessageNX 0x0000007100608f04,U,000224,_ZN20CConsoleMinecraftApp27Callback_SaveGameIncompleteEPvN10C4JStorage19ESaveIncompleteTypeE -0x0000007100608fe4,U,000196, +0x0000007100608fe4,U,000196,_ZN20CConsoleMinecraftApp45Callback_SaveGameIncompleteMessageBoxReturnedEPviN10C4JStorage14EMessageResultE 0x00000071006090a8,U,000164,_ZN20CConsoleMinecraftApp22RequestSignInUIChoicesEi 0x000000710060914c,U,000008, 0x0000007100609154,U,000292, @@ -40130,9 +40129,10 @@ Address,Quality,Size,Name 0x000000710063ee38,O,000036,_ZN5Chunk7_deleteEv 0x000000710063ee5c,O,000040,_ZN5Chunk10clearDirtyEv 0x000000710063ee84,U,000024, -0x000000710063ee9c,U,001920,__ct__16ClientChunkCacheFP5Level -0x000000710063f61c,U,000120,__ct__16ClientChunkCacheFP5LevelP12ChunkStorage -0x000000710063f694,U,000192, +0x000000710063ee9c,O,000108,_ZN16ClientChunkCacheC1EP5Level +0x000000710063ef08,M,001812,_ZN16ClientChunkCache25MultiPlayerChunkCacheInitEP5LevelP12ChunkStorage +0x000000710063f61c,O,000120,_ZN16ClientChunkCacheC1EP5LevelP12ChunkStorage +0x000000710063f694,M,000192,_ZN16ClientChunkCache17StorageThreadProcEPv 0x000000710063f754,U,000620, 0x000000710063f9c0,U,000300,_ZN16ClientChunkCacheD2Ev 0x000000710063faec,U,000072, @@ -40141,31 +40141,31 @@ Address,Quality,Size,Name 0x000000710063fbc8,U,000036,_ZN16ClientChunkCacheD0Ev 0x000000710063fbec,U,000304, 0x000000710063fd1c,U,000480, -0x000000710063fefc,U,000008, -0x000000710063ff04,U,000116, -0x000000710063ff78,U,000036, -0x000000710063ff9c,U,000020, +0x000000710063fefc,O,000008,_ZN16ClientChunkCache8hasChunkEii +0x000000710063ff04,O,000116,_ZN16ClientChunkCache14reallyHasChunkEii +0x000000710063ff78,O,000036,_ZN16ClientChunkCache8inBoundsEii +0x000000710063ff9c,O,000020,_ZN16ClientChunkCache10computeIdxEii 0x000000710063ffb0,U,000516, 0x00000071006401b4,U,000304, 0x00000071006402e4,U,000104, 0x000000710064034c,U,000268, -0x0000007100640458,U,000100, -0x00000071006404bc,U,000048, -0x00000071006404ec,U,000008, -0x00000071006404f4,U,000008, -0x00000071006404fc,U,000780, -0x0000007100640808,U,000108, -0x0000007100640874,U,000088, -0x00000071006408cc,U,000008, -0x00000071006408d4,U,001016, +0x0000007100640458,O,000100,_ZN16ClientChunkCache16getChunkIfLoadedEii +0x00000071006404bc,O,000048,_ZN16ClientChunkCache16getOrCreateChunkEiib +0x00000071006404ec,O,000008,_ZN16ClientChunkCache20getLoadedChunksCountEv +0x00000071006404f4,O,000008,_ZN16ClientChunkCache18isChunkGeneratedAtEii +0x00000071006404fc,U,000780,_ZN16ClientChunkCache6createEii +0x0000007100640808,O,000108,_ZN16ClientChunkCache8getChunkEii +0x0000007100640874,O,000088,_ZN16ClientChunkCache10getChunkAtERK8BlockPos +0x00000071006408cc,O,000008,_ZN16ClientChunkCache4saveEbP16ProgressListener +0x00000071006408d4,M,001016,_ZN16ClientChunkCache4tickEv 0x0000007100640ccc,U,000088, -0x0000007100640d24,U,000008, -0x0000007100640d2c,U,000008, -0x0000007100640d34,U,000008, -0x0000007100640d3c,U,000016, -0x0000007100640d4c,U,000004, -0x0000007100640d50,U,000152, -0x0000007100640de8,U,000080, +0x0000007100640d24,O,000008,_ZN16ClientChunkCache10shouldSaveEv +0x0000007100640d2c,O,000008,_ZN16ClientChunkCache9getMobsAtEP11MobCategoryRK8BlockPos +0x0000007100640d34,O,000008,_ZN16ClientChunkCache21findNearestMapFeatureEP5LevelRKNSt3__112basic_stringIwNS2_11char_traitsIwEENS2_9allocatorIwEEEERK8BlockPosb +0x0000007100640d3c,O,000016,_ZN16ClientChunkCache15getLoadedChunksEv +0x0000007100640d4c,O,000004,_ZN16ClientChunkCache31recreateLogicStructuresForChunkEP10LevelChunkii +0x0000007100640d50,O,000152,_ZN16ClientChunkCache11gatherStatsEv +0x0000007100640de8,O,000080,_ZN16ClientChunkCache12dataReceivedEii 0x0000007100640e38,U,000116, 0x0000007100640eac,U,000312, 0x0000007100640fe4,U,000008, @@ -40576,15 +40576,15 @@ Address,Quality,Size,Name 0x000000710065a5d8,U,000004, 0x000000710065a5dc,U,000016, 0x000000710065a5ec,U,000444, -0x000000710065a7a8,U,000052,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListenerC_gen +0x000000710065a7a8,O,000052,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListenerC1EPS_ 0x000000710065a7dc,U,000020,_ZN20BorderChangeListenerC1Ev -0x000000710065a7f0,U,000040, -0x000000710065a818,U,000064, -0x000000710065a858,U,000048, -0x000000710065a888,U,000040, -0x000000710065a8b0,U,000040, -0x000000710065a8d8,U,000040, -0x000000710065a900,U,000040, +0x000000710065a7f0,O,000040,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListener15onBorderSizeSetEP11WorldBorderd +0x000000710065a818,O,000064,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListener19onBorderSizeLerpingEP11WorldBorderddx +0x000000710065a858,O,000048,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListener17onBorderCenterSetEP11WorldBorderdd +0x000000710065a888,O,000040,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListener22onBorderSetWarningTimeEP11WorldBorderi +0x000000710065a8b0,O,000040,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListener24onBorderSetWarningBlocksEP11WorldBorderi +0x000000710065a8d8,O,000040,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListener25onBorderSetDamagePerBlockEP11WorldBorderd +0x000000710065a900,O,000040,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListener25onBorderSetDamageSafeZOneEP11WorldBorderd 0x000000710065a928,M,001388,_ZN18DispenserBootstrap10StaticCtorEv 0x000000710065ae94,U,000048, 0x000000710065aec4,U,000048, @@ -40878,7 +40878,7 @@ Address,Quality,Size,Name 0x000000710066ac08,U,000036,_ZN12ChickenModelD0Ev 0x000000710066ac2c,U,000064,_ZN12ChickenModel7getNameEv 0x000000710066ac6c,U,000036,_ZN15ChickenRendererD0Ev -0x000000710066ac90,U,000008, +0x000000710066ac90,O,000008,_ZN16ClientChunkCache8getCacheEv 0x000000710066ac98,U,000052,_ZN16ClientScoreboardD2Ev 0x000000710066accc,U,000036,_ZN16ClientScoreboardD0Ev 0x000000710066acf0,U,000036,_ZN16ClockAtlasSpriteD0Ev @@ -40911,7 +40911,7 @@ Address,Quality,Size,Name 0x000000710066b090,U,000008, 0x000000710066b098,U,000008, 0x000000710066b0a0,U,000004, -0x000000710066b0a4,U,000036,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListenerD0Ev +0x000000710066b0a4,O,000036,_ZN18DerivedServerLevel32DerivedLevelBorderChangeListenerD0Ev 0x000000710066b0c8,U,000036,_ZN18DispenserBootstrap28OptionalDispenseItemBehaviorD0Ev 0x000000710066b0ec,U,000036,_ZN18DispenserBootstrap26ShulkerBoxDispenseBehaviorD0Ev 0x000000710066b110,U,000040,_ZN18DispenserBootstrap20BoatDispenseBehaviorD2Ev @@ -43004,7 +43004,7 @@ Address,Quality,Size,Name 0x00000071006e3fb8,U,000728, 0x00000071006e4290,U,000448, 0x00000071006e4450,U,000216,_ZNSt3__120__shared_ptr_pointerIP20UpdateProgressPacketNS_14default_deleteIS1_EENS_9allocatorIS1_EEEC_gen -0x00000071006e4528,U,000124, +0x00000071006e4528,U,000124,_ZN15MinecraftServer26broadcastStartSavingPacketEv 0x00000071006e45a4,U,000216,_ZNSt3__120__shared_ptr_pointerIP26ClientboundGameEventPacketNS_14default_deleteIS1_EENS_9allocatorIS1_EEEC_gen2 0x00000071006e467c,U,000140, 0x00000071006e4708,U,000216,_ZNSt3__120__shared_ptr_pointerIP24ClientboundSetTimePacketNS_14default_deleteIS1_EENS_9allocatorIS1_EEEC_gen diff --git a/src/4JLibraries_Source/NX/Thread/C4JThreadImpl.h b/src/4JLibraries_Source/NX/Thread/C4JThreadImpl.h index ececad55..10bb710d 100644 --- a/src/4JLibraries_Source/NX/Thread/C4JThreadImpl.h +++ b/src/4JLibraries_Source/NX/Thread/C4JThreadImpl.h @@ -9,7 +9,7 @@ class C4JThreadImpl : public C4JThread { public: static unsigned long sMask; - C4JThreadImpl(int (*)(void*), void*, const char*, int); + C4JThreadImpl(int (*threadProc)(void*), void*, const char*, int); static void SetMainThreadID(); diff --git a/src/Minecraft.Client/net/minecraft/client/multiplayer/ClientChunkCache.cpp b/src/Minecraft.Client/net/minecraft/client/multiplayer/ClientChunkCache.cpp new file mode 100644 index 00000000..b4eaac24 --- /dev/null +++ b/src/Minecraft.Client/net/minecraft/client/multiplayer/ClientChunkCache.cpp @@ -0,0 +1,338 @@ +#include "net/minecraft/client/multiplayer/ClientChunkCache.h" + +#include "NX/Thread/C4JThreadImpl.h" +#include "net/minecraft/client/Compression.h" +#include "net/minecraft/client/Minecraft.h" +#include "net/minecraft/world/level/Level.h" +#include "net/minecraft/world/level/block/Blocks.h" +#include "net/minecraft/world/level/chunk/storage/OldChunkStorage.h" +#include "net/minecraft/world/level/dimension/Dimension.h" +#include "net/minecraft/world/level/dimension/DimensionType.h" +#include "net/minecraft/world/level/gamemode/ClientMasterGameMode.h" +#include "net/minecraft/world/level/levelgen/ChunkPrimer.h" +#include "net/minecraft/world/level/storage/LevelData.h" + +ClientChunkCache::ClientChunkCache(Level* lvl) : m_chunkPos({0, 0}) { + this->unk3 = nullptr; + this->m_loadedChunksSize2 = 0; + this->m_loadedChunksSize1 = 0; + this->unk11 = nullptr; + this->unk12 = nullptr; + this->unk13 = nullptr; + this->unk14 = nullptr; + this->unk16 = nullptr; + this->unk17 = nullptr; + this->unk18 = nullptr; + this->unk19 = nullptr; + this->unk20 = nullptr; + this->unk21 = nullptr; + + this->MultiPlayerChunkCacheInit(lvl, nullptr); +} + +ClientChunkCache::ClientChunkCache(Level* lvl, ChunkStorage* storage) : m_chunkPos({0, 0}) { + this->unk3 = nullptr; + this->m_loadedChunksSize2 = 0; + this->m_loadedChunksSize1 = 0; + this->unk11 = nullptr; + this->unk12 = nullptr; + this->unk13 = nullptr; + this->unk14 = nullptr; + this->unk16 = nullptr; + this->unk17 = nullptr; + this->unk18 = nullptr; + this->unk19 = nullptr; + this->unk20 = nullptr; + this->unk21 = nullptr; + + MultiPlayerChunkCacheInit(lvl, storage); +} + +// I completely missed the branch out to this, only noticed once I tried matching the second constructor +// Wii U Edition didn't do a jumpout, so the symbol and function exists +// NON_MATCHING | Difference: 11585 +void ClientChunkCache::MultiPlayerChunkCacheInit(Level* lvl, ChunkStorage* storage) { + int bounds; + + int xzSize = lvl->mDimension->getXZSize(); + if (xzSize >= 0) + bounds = xzSize; + else + bounds = xzSize + 1; + + this->m_xzBounds = xzSize; + this->m_xzApo = bounds / 2; + this->m_xzSize = xzSize; + + this->unk28 = new char[this->m_xzBounds * this->m_xzBounds]; + memset(this->unk28, 0, this->m_xzBounds * this->m_xzBounds); + + this->m_emptyChunk = new EmptyLevelChunk(lvl, 0, 0); + this->m_chunkStorage = storage; + this->unk4 = 0; + + // is there a way to force IDA to show jumpouts instead of just hiding code from me + if (storage) { + InitializeCriticalSection(&this->m_storageMutex); + this->m_storageThread = new C4JThreadImpl(StorageThreadProc, this, "MultiPlayerChunkCache", 0x100000); + this->m_storageThread->SetProcessor(1); + this->m_storageThread->Run(); + } else { + this->m_storageThread = nullptr; + } + + // If overworld + if (lvl->mDimension->getType() == DimensionType::OVERWORLD) { + arrayWithLength blocks = arrayWithLength(0x8000u, true); + arrayWithLength data = arrayWithLength(0x4000u, true); + + LevelData* dat = lvl->getLevelData(); + // If overworld is superflat + if (dat->getGeneratorType() == LevelType::FLAT) { + // from 0 to 16 chunk coords x + for (int x = 0; x != 16; x++) { + // from 0 to 128 chunk coords y (old height limit) + for (int y = 0; y != 128; y++) { + // if y is 3, which is the grass layer height on a superflat world + if (y == 3) { + // from 0 to 16 chunk coords z + for (int z = 0; z != 16; z++) { + blocks[INDEX_BLOCK_ARRAY(x, y, z)] + = Blocks::GRASS->getId(); // place a grass block + } + } else if (y > 2) { + // if y is larger than 2, but not 3, we are above the topmost layer of + // the superflat world + + // from 0 to 16 chunk coords z + for (int z = 0; z != 16; z++) { + blocks[INDEX_BLOCK_ARRAY(x, y, z)] = 0; // place an air block + } + } else { + // otherwise, y is below the grass layer + + // from 0 to 16 chunk coords z + for (int z = 0; z != 16; z++) { + blocks[INDEX_BLOCK_ARRAY(x, y, z)] = Blocks::DIRT->getId(); // place a dirt block + } + } + } + } + } else { // otherwise, we're in a normal generator (e.g. Default, Large Biomes) + for (int x = 0; x != 16; x++) // from 0 to 16 chunk coords z + { + for (int y = 0; y != 128; y++) // from 0 to 128 chunk coords y (old height limit) + { + for (int z = 0; z != 16; z++) // from 0 to 16 chunk coords x + { + int sl = lvl->getSeaLevel(); // get sea level + int id; + + // TODO can't get this to look neat without mismatching + Block* blk = Blocks::STONE; // default block is stone + + // if we are above 10 blocks below sea level, set the block to water, then check if y + // is higher than sea level if it is, we will fall through to set ID to 0, which is + // AIR otherwise, blk is now water, so we will fall through and get the ID of our + // water block + if (y > sl - 10 && (blk = Blocks::WATER, y >= sl)) + id = 0; // set block to air + else + id = blk->getId(); // set block to Water, if between sea level and 10 blocks + // below sea level, otherwise Stone. + + blocks[INDEX_BLOCK_ARRAY(x, y, z)] = id; // set the ID in the array + } + } + } + } + + ChunkPrimer primer = ChunkPrimer(false, blocks, data); + this->m_waterChunk = new WaterLevelChunk(lvl, &primer, 0, 0); + + delete blocks.data; + delete data.data; + + // sets skylight + if (dat->getGeneratorType() == LevelType::FLAT) { + for (int x = 0; x != 16; x++) { // from 0 to 16 chunk coords x + for (int y = 0; y != 128; y++) { // from 0 to 128 chunk coords y (old world height) + if (y + >= 3) { // if y is bigger or equal to 3, which is any block at or above the top block + for (int z = 0; z != 16; z++) { // from 0 to 16 chunk coords z + m_waterChunk->setLevelChunkBrightness(LightLayer::SKY, x, y, z, + 15); // set light level to 15 + } + } + } + } + } else { + for (int x = 0; x != 16; x++) { // from 0 to 16 chunk coords x + for (int y = 0; y != 128; y++) { // from 0 to 128 chunk coords y (old world height) + for (int z = 0; z != 16; z++) { // from 0 to 16 chunk coords z + int brightness = 2; // underwater/in-block brightness + + if (y >= lvl->getSeaLevel() - 1) // if we are above the sea level minus 1 + brightness = 15; // set our brightness to max, as this is skylight + + m_waterChunk->setLevelChunkBrightness(LightLayer::SKY, x, y, z, + brightness); // set the brightness + } + } + } + } + } else { + this->m_waterChunk = nullptr; // no need for a water chunk when not in the overworld + } + + this->m_level = lvl; + this->m_dimension = lvl->mDimension; + + // apparently correct? difference went down after + this->m_cache = new LevelChunk*[(this->m_xzBounds * this->m_xzBounds)]; + memset(this->m_cache, 0, sizeof(LevelChunk*) * (this->m_xzBounds * this->m_xzBounds)); + + InitializeCriticalSectionAndSpinCount(&this->m_mutex, 0); +} + +LevelChunk* ClientChunkCache::getChunkIfLoaded(int x, int z) { + if (inBounds(x, z)) { // if in bounds + const int idx = computeIdx(x, z); // get idx + return m_cache[idx]; // return chunk in cache at idx + } + + // since not in bounds, check if m_waterChunk is nullptr, if so, return empty chunk, otherwise return the + // water chunk + return !this->m_waterChunk ? *reinterpret_cast( + &this->m_emptyChunk) // why do we need this reinterpret ptrptr junk + : + *reinterpret_cast(&this->m_waterChunk); +} + +LevelChunk* ClientChunkCache::getOrCreateChunk(int x, int z, bool unk) { + LevelChunk* c = this->getChunkIfLoaded(x, z); // get chunk + if (!c) // if null, return empty chunk inst + return this->m_emptyChunk; + + return c; // return chunk otherwise since not null +} + +// NON_MATCHING | Difference: 24096 +void ClientChunkCache::tick() { + EnterCriticalSection(&this->m_mutex); + + if (this->m_chunkStorage) { + ClientMasterGameMode* gm = Minecraft::GetInstance()->GetClientMasterGameMode(); + + if (!gm->isNewLevelDataPending()) { + // TODO I'm not decompiling this garbage atm jfc + } + } + + LeaveCriticalSection(&this->m_mutex); +} + +std::wstring ClientChunkCache::gatherStats() { + EnterCriticalSection(&this->m_mutex); + const int u + = (this->m_loadedChunksSize1 - this->m_loadedChunksSize2) >> 3; // maybe this is some vector or map? + LeaveCriticalSection(&this->m_mutex); + + return L"MultiplayerChunkCache: " + std::to_wstring(u); +} + +int ClientChunkCache::getLoadedChunksCount() { + return 0; +} + +bool ClientChunkCache::isChunkGeneratedAt(int x, int z) { + return false; +} + +bool ClientChunkCache::hasChunk(int x, int z) { + return true; +} +bool ClientChunkCache::reallyHasChunk(int x, int z) { + if (!inBounds(x, z)) + return true; // if out of bounds, it returns true because the client will then fetch a + // WaterLevelChunk + + int idx = computeIdx(x, z); + if (this->m_cache[idx]) + return this->unk28[idx] != 0; + + return false; +} + +LevelChunk* ClientChunkCache::getChunk(int x, int z) { + if (inBounds(x, z)) { // if in bounds + const int idx = computeIdx(x, z); // get idx + + LevelChunk* c = m_cache[idx]; // get chunk in cache at idx + if (!c) // if nullptr + return this->m_emptyChunk; // return empty chunk + + return c; // otherwise return the chunk we fetched + } + + // if not in bounds + // check if m_waterChunk is nullptr, if so, return empty chunk, otherwise return the water chunk + return !this->m_waterChunk ? *reinterpret_cast( + &this->m_emptyChunk) // why do we need this reinterpret ptrptr junk + : + *reinterpret_cast(&this->m_waterChunk); +} + +LevelChunk* ClientChunkCache::getChunkAt(const BlockPos& pos) { + return getChunk(pos.getX(), pos.getZ()); +} + +bool ClientChunkCache::save(bool, ProgressListener*) { + return true; +} + +bool ClientChunkCache::shouldSave() { + return false; +} + +LevelChunk** ClientChunkCache::getCache() { + return this->m_cache; +} +void ClientChunkCache::dataReceived(int x, int z) { + if (!inBounds(x, z)) // if not in bounds + return; // return, don't use this chunk ig? + + int idx = computeIdx(x, z); // get idx + this->unk28[idx] = 1; // set in unk28 at idx to one? Could be a bool array +} + +std::vector* ClientChunkCache::getMobsAt(MobCategory* category, const BlockPos& pos) { + return nullptr; +} + +BlockPos* ClientChunkCache::findNearestMapFeature(Level*, const std::wstring&, const BlockPos&, bool) { + return nullptr; +} + +int ClientChunkCache::getLoadedChunks() { + return (this->m_loadedChunksSize1 - this->m_loadedChunksSize2) >> 3; +} + +void ClientChunkCache::recreateLogicStructuresForChunk(LevelChunk*, int, int) {} + +// why the fuck does this return int +int ClientChunkCache::inBounds(int x, int z) { + return this->m_dimension->containsChunk(x, z); +} + +int ClientChunkCache::computeIdx(int x, int z) { + return (this->m_xzApo + x) * this->m_xzBounds + (this->m_xzApo + z); +} + +// NON_MATCHING | Difference: 4252 +int ClientChunkCache::StorageThreadProc(void*) { + Compression::UseDefaultThreadStorage(); + OldChunkStorage::UseDefaultThreadStorage(); + AABB::CreateNewThreadStorage(); + Vec3::CreateNewThreadStorage(); +} diff --git a/src/Minecraft.Client/net/minecraft/client/multiplayer/ClientChunkCache.h b/src/Minecraft.Client/net/minecraft/client/multiplayer/ClientChunkCache.h index 31b9cb7e..2b9a6d8d 100644 --- a/src/Minecraft.Client/net/minecraft/client/multiplayer/ClientChunkCache.h +++ b/src/Minecraft.Client/net/minecraft/client/multiplayer/ClientChunkCache.h @@ -1,33 +1,101 @@ #pragma once +#include "NX/Thread/C4JThreadImpl.h" +#include "net/minecraft/world/level/chunk/ChunkPos.h" #include "net/minecraft/world/level/chunk/ChunkSource.h" +#include "net/minecraft/world/level/chunk/EmptyLevelChunk.h" +#include "net/minecraft/world/level/chunk/WaterLevelChunk.h" +#include "net/minecraft/world/level/dimension/Dimension.h" +class ClientboundBlockEntityDataPacket; class ChunkStorage; class ClientChunkCache : public ChunkSource { public: - ClientChunkCache(Level*); - ClientChunkCache(Level*, ChunkStorage*); + class QueuedAction { + public: + QueuedAction(int x, int z, const std::vector* changes); + QueuedAction(const std::shared_ptr& packet); + }; + + ClientChunkCache(Level* lvl); + ClientChunkCache(Level* lvl, ChunkStorage* storage); + + void MultiPlayerChunkCacheInit(Level* lvl, ChunkStorage* storage); ~ClientChunkCache() override; - LevelChunk* getChunkIfLoaded(int, int) override; - LevelChunk* getOrCreateChunk(int, int, bool) override; + + /** Returns a pointer to a loaded chunk at a given location, if one doesn't exist, returns m_waterChunk, + * if m_waterChunk doesn't exist, returns m_emptyChunk */ + LevelChunk* getChunkIfLoaded(int x, int z) override; + LevelChunk* getOrCreateChunk(int x, int z, bool) override; void tick() override; std::wstring gatherStats() override; int getLoadedChunksCount() override; - bool isChunkGeneratedAt(int, int) override; - bool hasChunk(int, int) override; - LevelChunk* getChunk(int, int) override; - LevelChunk* getChunkAt(const BlockPos&) override; - LevelChunk* create(int, int) override; - void save(bool, ProgressListener*) override; + bool isChunkGeneratedAt(int x, int z) override; + bool hasChunk(int x, int z) override; + bool reallyHasChunk(int x, int z) override; + LevelChunk* getChunk(int x, int z) override; + LevelChunk* getChunkAt(const BlockPos& pos) override; + LevelChunk* create(int x, int z) override; + bool save(bool, ProgressListener*) override; bool shouldSave() override; - ChunkSource* getCache() override; - std::vector* getMobsAt(MobCategory*, const BlockPos&) override; - void findNearestMapFeature(Level*, const std::wstring&, const BlockPos&, bool) override; + void load(int x, int z, LevelChunk* chunk); + LevelChunk** getCache() override; // TODO this might have been implemented in the header due to it's + // appearance being elsewhere in memory + void dataReceived(int x, int z) override; + std::vector* getMobsAt(MobCategory* category, const BlockPos& pos) override; + BlockPos* findNearestMapFeature(Level*, const std::wstring&, const BlockPos&, bool) override; int getLoadedChunks() override; - void recreateLogicStructuresForChunk(LevelChunk*, int, int) override; + void recreateLogicStructuresForChunk(LevelChunk* chunk, int x, int z) override; + + bool mustQueueBlockEntityDataPackets(); + void queueBlockEntityDataPacket(const std::shared_ptr& packet); + + // reLoad + void reLoad(int x, int z, const std::vector* changes); + void unqueueForReLoad(int x, int z); + void queueForReLoad(int x, int z, const std::vector* changes, bool); + + void BlockUntilSafeToChangeSaveData(bool); + + void dropOutsideArea(int, int, int, int, bool); + void drop(int x, int z, bool); + + int inBounds(int x, int z); + int computeIdx(int x, int z); + + static int StorageThreadProc(void*); + + EmptyLevelChunk* m_emptyChunk; + WaterLevelChunk* m_waterChunk; + + ChunkStorage* m_chunkStorage; + C4JThreadImpl* m_storageThread; + + ChunkPos m_chunkPos; -private: - char size[0x110 - sizeof(ChunkSource)]; + void* unk3; + int unk4; + int unk45; + nn::os::MutexType m_storageMutex; + unsigned long long m_loadedChunksSize2; + unsigned long long m_loadedChunksSize1; + void* unk11; + void* unk12; + void* unk13; + void* unk14; + LevelChunk** m_cache; // no clue if type is correct, just went off of vibes lmao + void* unk16; + void* unk17; + void* unk18; + void* unk19; + void* unk20; + void* unk21; + nn::os::MutexType m_mutex; + int m_xzBounds; + int m_xzApo; + char* unk28; + Level* m_level; + Dimension* m_dimension; }; diff --git a/src/Minecraft.Client/net/minecraft/client/multiplayer/MultiPlayerLevel.cpp b/src/Minecraft.Client/net/minecraft/client/multiplayer/MultiPlayerLevel.cpp index 4f3e782f..20423e74 100644 --- a/src/Minecraft.Client/net/minecraft/client/multiplayer/MultiPlayerLevel.cpp +++ b/src/Minecraft.Client/net/minecraft/client/multiplayer/MultiPlayerLevel.cpp @@ -36,7 +36,7 @@ void MultiPlayerLevel::MultiPlayerLevelInit(ClientPacketListener* packetListener mDimension->init(this); mChunkSource = createChunkSource(); mChunkCache = mChunkSource->getCache(); - mXZSize = mChunkSource->mXZSize; + mXZSize = mChunkSource->m_xzSize; if (!mLevelData->isInitialized()) { initializeLevel(levelSettings); mLevelData->setInitialized(true); diff --git a/src/Minecraft.Client/net/minecraft/client/ui/xui/eXuiAction.h b/src/Minecraft.Client/net/minecraft/client/ui/xui/eXuiAction.h new file mode 100644 index 00000000..a35eaf28 --- /dev/null +++ b/src/Minecraft.Client/net/minecraft/client/ui/xui/eXuiAction.h @@ -0,0 +1,3 @@ +#pragma once + +enum eXuiAction {}; diff --git a/src/Minecraft.Client/net/minecraft/client/ui/xui/eXuiServerAction.h b/src/Minecraft.Client/net/minecraft/client/ui/xui/eXuiServerAction.h new file mode 100644 index 00000000..72aa9818 --- /dev/null +++ b/src/Minecraft.Client/net/minecraft/client/ui/xui/eXuiServerAction.h @@ -0,0 +1,3 @@ +#pragma once + +enum eXuiServerAction {}; diff --git a/src/Minecraft.Client/net/minecraft/core/Vec3i.h b/src/Minecraft.Client/net/minecraft/core/Vec3i.h index 7f423a03..ecb9290f 100644 --- a/src/Minecraft.Client/net/minecraft/core/Vec3i.h +++ b/src/Minecraft.Client/net/minecraft/core/Vec3i.h @@ -11,6 +11,7 @@ class Vec3i { int getZ() const; double distSqr(const Vec3i&) const; +protected: int x; int y; int z; diff --git a/src/Minecraft.Client/net/minecraft/network/protocol/game/ClientboundSetBorderPacket.cpp b/src/Minecraft.Client/net/minecraft/network/protocol/game/ClientboundSetBorderPacket.cpp index 5d93fcfb..aa3171d9 100644 --- a/src/Minecraft.Client/net/minecraft/network/protocol/game/ClientboundSetBorderPacket.cpp +++ b/src/Minecraft.Client/net/minecraft/network/protocol/game/ClientboundSetBorderPacket.cpp @@ -15,69 +15,71 @@ EPacketType ClientboundSetBorderPacket::getPacketId() { } void ClientboundSetBorderPacket::read(DataInputStream* input) { - dword_28 = input->readInt(); - switch (dword_28) { - case 0: - double_40 = input->readDouble(); - break; - case 1: - double_48 = input->readDouble(); - double_40 = input->readDouble(); - qword_50 = input->readVarLong(); - break; - case 2: - double_30 = input->readDouble(); - double_38 = input->readDouble(); - break; - case 3: - double_30 = input->readDouble(); - double_38 = input->readDouble(); - double_48 = input->readDouble(); - double_40 = input->readDouble(); - qword_50 = input->readVarLong(); - dword_2c = input->readVarInt(); - dword_5c = input->readVarInt(); - dword_58 = input->readVarInt(); - break; - case 4: - dword_58 = input->readVarInt(); - break; - case 5: - dword_5c = input->readVarInt(); + m_updateType = static_cast(input->readInt()); + + switch (m_updateType) { + case Type::SET_SIZE: + m_size = input->readDouble(); + break; + case Type::LERP_SIZE: + m_newSize = input->readDouble(); + m_size = input->readDouble(); + m_lerpTime = input->readVarLong(); + break; + case Type::SET_CENTER: + m_centerX = input->readDouble(); + m_centerZ = input->readDouble(); + break; + case Type::SET_ALL: + m_centerX = input->readDouble(); + m_centerZ = input->readDouble(); + m_newSize = input->readDouble(); + m_size = input->readDouble(); + m_lerpTime = input->readVarLong(); + m_absoluteMaxSize = input->readVarInt(); + m_warningBlocks = input->readVarInt(); + m_warningTime = input->readVarInt(); + break; + case Type::SET_WARNING_TIME: + m_warningTime = input->readVarInt(); + break; + case Type::SET_WARNING_BLOCKS: + m_warningBlocks = input->readVarInt(); break; } } void ClientboundSetBorderPacket::write(DataOutputStream* output) { - output->writeInt(dword_28); - switch (dword_28) { - case 0: - output->writeDouble(double_40); - break; - case 1: - output->writeDouble(double_48); - output->writeDouble(double_40); - output->writeVarLong(qword_50); - break; - case 2: - output->writeDouble(double_30); - output->writeDouble(double_38); - break; - case 3: - output->writeDouble(double_30); - output->writeDouble(double_38); - output->writeDouble(double_48); - output->writeDouble(double_40); - output->writeVarLong(qword_50); - output->writeVarInt(dword_2c); - output->writeVarInt(dword_5c); - output->writeVarInt(dword_58); - break; - case 4: - output->writeVarInt(dword_58); - break; - case 5: - output->writeVarInt(dword_5c); + output->writeInt(static_cast(m_updateType)); + + switch (m_updateType) { + case Type::SET_SIZE: + output->writeDouble(m_size); + break; + case Type::LERP_SIZE: + output->writeDouble(m_newSize); + output->writeDouble(m_size); + output->writeVarLong(m_lerpTime); + break; + case Type::SET_CENTER: + output->writeDouble(m_centerX); + output->writeDouble(m_centerZ); + break; + case Type::SET_ALL: + output->writeDouble(m_centerX); + output->writeDouble(m_centerZ); + output->writeDouble(m_newSize); + output->writeDouble(m_size); + output->writeVarLong(m_lerpTime); + output->writeVarInt(m_absoluteMaxSize); + output->writeVarInt(m_warningBlocks); + output->writeVarInt(m_warningTime); + break; + case Type::SET_WARNING_TIME: + output->writeVarInt(m_warningTime); + break; + case Type::SET_WARNING_BLOCKS: + output->writeVarInt(m_warningBlocks); break; } } @@ -85,3 +87,35 @@ void ClientboundSetBorderPacket::write(DataOutputStream* output) { void ClientboundSetBorderPacket::handle(PacketListener* listener) { listener->handleSetBorder(shared_from_this()); } + +void ClientboundSetBorderPacket::applyChanges(WorldBorder* border) { + switch (this->m_updateType) { + case Type::SET_SIZE: + border->setSize(this->m_size); + break; + case Type::LERP_SIZE: + border->lerpSizeBetween(this->m_newSize, this->m_size, this->m_lerpTime); + break; + case Type::SET_CENTER: + border->setCenter(this->m_centerX, this->m_centerZ); + break; + case Type::SET_ALL: + border->setCenter(this->m_centerX, this->m_centerZ); + if (this->m_lerpTime < 1) { + border->setSize(this->m_size); + } else { + border->lerpSizeBetween(this->m_newSize, this->m_size, this->m_lerpTime); + } + + border->setAbsoluteMaxSize(this->m_absoluteMaxSize); + border->setWarningBlocks(this->m_warningBlocks); + border->setWarningTime(this->m_warningTime); + break; + case Type::SET_WARNING_TIME: + border->setWarningTime(this->m_warningTime); + break; + case Type::SET_WARNING_BLOCKS: + border->setWarningBlocks(this->m_warningBlocks); + break; + } +} diff --git a/src/Minecraft.Client/net/minecraft/network/protocol/game/ClientboundSetBorderPacket.h b/src/Minecraft.Client/net/minecraft/network/protocol/game/ClientboundSetBorderPacket.h index 615995de..f3fee130 100644 --- a/src/Minecraft.Client/net/minecraft/network/protocol/game/ClientboundSetBorderPacket.h +++ b/src/Minecraft.Client/net/minecraft/network/protocol/game/ClientboundSetBorderPacket.h @@ -1,6 +1,7 @@ #pragma once #include "net/minecraft/network/protocol/Packet.h" +#include "net/minecraft/world/level/border/WorldBorder.h" class Item; @@ -9,20 +10,28 @@ class ClientboundSetBorderPacket : public Packet, public: static std::shared_ptr create(); + enum class Type : int { SET_SIZE, LERP_SIZE, SET_CENTER, SET_ALL, SET_WARNING_TIME, SET_WARNING_BLOCKS }; + ClientboundSetBorderPacket(); + + // appears to not exist??? + ClientboundSetBorderPacket(WorldBorder* border, ClientboundSetBorderPacket::Type type) DELETE_UNUSED; + EPacketType getPacketId() override; void read(DataInputStream* input) override; void write(DataOutputStream* output) override; void handle(PacketListener* listener) override; + void applyChanges(WorldBorder* border); + private: - int dword_28; - int dword_2c; - double double_30; - double double_38; - double double_40; - double double_48; - long qword_50; - int dword_58; - int dword_5c; + Type m_updateType; + int m_absoluteMaxSize; + double m_centerX; + double m_centerZ; + double m_size; + double m_newSize; + long m_lerpTime; + int m_warningTime; + int m_warningBlocks; }; diff --git a/src/Minecraft.Client/net/minecraft/server/level/DerivedServerLevel.cpp b/src/Minecraft.Client/net/minecraft/server/level/DerivedServerLevel.cpp new file mode 100644 index 00000000..97160186 --- /dev/null +++ b/src/Minecraft.Client/net/minecraft/server/level/DerivedServerLevel.cpp @@ -0,0 +1,43 @@ +#include "DerivedServerLevel.h" +#include "net/minecraft/world/level/border/WorldBorder.h" + +DerivedServerLevel::DerivedLevelBorderChangeListener::DerivedLevelBorderChangeListener( + DerivedServerLevel* level) + : BorderChangeListener() { + this->m_level = level; +} + +void DerivedServerLevel::DerivedLevelBorderChangeListener::onBorderSizeSet(WorldBorder* border, + double newSize) { + this->m_level->getWorldBorder()->setSize(newSize); +} +void DerivedServerLevel::DerivedLevelBorderChangeListener::onBorderSizeLerping(WorldBorder* border, + double from, double to, + long long lerpTime) { + this->m_level->getWorldBorder()->lerpSizeBetween(from, to, lerpTime); +} + +void DerivedServerLevel::DerivedLevelBorderChangeListener::onBorderCenterSet(WorldBorder* border, double x, + double z) { + this->m_level->getWorldBorder()->setCenter(x, z); +} + +void DerivedServerLevel::DerivedLevelBorderChangeListener::onBorderSetWarningTime(WorldBorder* border, + int time) { + this->m_level->getWorldBorder()->setWarningTime(time); +} + +void DerivedServerLevel::DerivedLevelBorderChangeListener::onBorderSetWarningBlocks(WorldBorder* border, + int blocks) { + this->m_level->getWorldBorder()->setWarningBlocks(blocks); +} + +void DerivedServerLevel::DerivedLevelBorderChangeListener::onBorderSetDamagePerBlock(WorldBorder* border, + double damage) { + this->m_level->getWorldBorder()->setDamagePerBlock(damage); +} + +void DerivedServerLevel::DerivedLevelBorderChangeListener::onBorderSetDamageSafeZOne(WorldBorder* border, + double safeZone) { + this->m_level->getWorldBorder()->setDamageSafeZone(safeZone); +} diff --git a/src/Minecraft.Client/net/minecraft/server/level/DerivedServerLevel.h b/src/Minecraft.Client/net/minecraft/server/level/DerivedServerLevel.h new file mode 100644 index 00000000..65f224fc --- /dev/null +++ b/src/Minecraft.Client/net/minecraft/server/level/DerivedServerLevel.h @@ -0,0 +1,23 @@ +#pragma once + +#include "net/minecraft/server/ServerLevel.h" +#include "net/minecraft/world/level/border/BorderChangeListener.h" + +class DerivedServerLevel : public ServerLevel { +public: + class DerivedLevelBorderChangeListener : public BorderChangeListener { + public: + explicit DerivedLevelBorderChangeListener(DerivedServerLevel* level); + + void onBorderSizeSet(WorldBorder* border, double newSize) override; + void onBorderSizeLerping(WorldBorder* border, double from, double to, long long lerpTime) override; + void onBorderCenterSet(WorldBorder* border, double x, double z) override; + void onBorderSetWarningTime(WorldBorder* border, int time) override; + void onBorderSetWarningBlocks(WorldBorder* border, int blocks) override; + void onBorderSetDamagePerBlock(WorldBorder* border, double damage) override; + void onBorderSetDamageSafeZOne(WorldBorder* border, double safeZone) override; + + private: + DerivedServerLevel* m_level; + }; +}; diff --git a/src/Minecraft.Client/net/minecraft/server/level/ServerChunkCache.cpp b/src/Minecraft.Client/net/minecraft/server/level/ServerChunkCache.cpp index 5d28002b..d74fafbb 100644 --- a/src/Minecraft.Client/net/minecraft/server/level/ServerChunkCache.cpp +++ b/src/Minecraft.Client/net/minecraft/server/level/ServerChunkCache.cpp @@ -18,7 +18,7 @@ ServerChunkCache::ServerChunkCache(ServerLevel* level, ChunkStorage* storage, Ch int size = generator->getSize(); dword_bc = size / 2; dword_b8 = size; - mXZSize = size; + m_xzSize = size; byte_28 = false; mEmptyChunk = new EmptyLevelChunk(level, 0, 0); @@ -28,8 +28,8 @@ ServerChunkCache::ServerChunkCache(ServerLevel* level, ChunkStorage* storage, Ch mChunkGenerator = generator; mChunkStorage = storage; - mChunks = new LevelChunk*[dword_b8 * dword_b8]; - memset(mChunks, 0, dword_b8 * dword_b8 * sizeof(LevelChunk*)); + m_cache = new LevelChunk*[dword_b8 * dword_b8]; + memset(m_cache, 0, dword_b8 * dword_b8 * sizeof(LevelChunk*)); mUnloadedChunks = new LevelChunk*[dword_b8 * dword_b8]; memset(mUnloadedChunks, 0, dword_b8 * dword_b8 * sizeof(LevelChunk*)); @@ -45,7 +45,7 @@ ServerChunkCache::~ServerChunkCache() { delete mChunkStorage; delete mEmptyChunk; - delete mChunks; + delete m_cache; delete mChunkGenerator; for (int i = 0; i < dword_b8 * dword_b8; ++i) { @@ -64,7 +64,7 @@ ServerChunkCache::~ServerChunkCache() { LevelChunk* ServerChunkCache::getChunkIfLoaded(int chunkX, int chunkZ) { if (inBounds(chunkX, chunkZ)) { int idx = computeIdx(chunkX, chunkZ); - return mChunks[idx]; + return m_cache[idx]; } return mEmptyChunk; } @@ -84,7 +84,7 @@ int ServerChunkCache::computeIdx(int chunkX, int chunkZ) { LevelChunk* ServerChunkCache::getChunkIfLoadedOrInvalid(int chunkX, int chunkZ) { if (inBounds(chunkX, chunkZ)) { int idx = computeIdx(chunkX, chunkZ); - return mChunks[idx]; + return m_cache[idx]; } return mEmptyChunk; @@ -95,7 +95,7 @@ LevelChunk* ServerChunkCache::getChunkIfGenerated(int chunkX, int chunkZ, bool u return mEmptyChunk; int idx = computeIdx(chunkX, chunkZ); - LevelChunk* chunk = mChunks[idx]; + LevelChunk* chunk = m_cache[idx]; LevelChunk* loadedOrInvalid = getChunkIfLoadedOrInvalid(chunkX, chunkZ); if (loadedOrInvalid && loadedOrInvalid != mEmptyChunk && !loadedOrInvalid->IsInvalid()) @@ -154,7 +154,7 @@ LevelChunk* ServerChunkCache::updateCacheAndPostProcess(int chunkX, int chunkZ, int idx = computeIdx(chunkX, chunkZ); - if (InterlockedCompareExchangeRelease((volatile long*)&mChunks[idx], (long)newChunk, (long)oldChunk) + if (InterlockedCompareExchangeRelease((volatile long*)&m_cache[idx], (long)newChunk, (long)oldChunk) == (long)oldChunk) { EnterCriticalSection(&mMutex); @@ -170,21 +170,21 @@ LevelChunk* ServerChunkCache::updateCacheAndPostProcess(int chunkX, int chunkZ, } if (unk) { - if ((newChunk->mPopulatedFlags & 2) == 0 && hasChunk(chunkX + 1, chunkZ + 1) + if ((newChunk->m_populatedFlags & 2) == 0 && hasChunk(chunkX + 1, chunkZ + 1) && hasChunk(chunkX, chunkZ + 1) && hasChunk(chunkX + 1, chunkZ)) MinecraftServer::getInstance()->addPostProcessRequest(this, mChunkGenerator, chunkX, chunkZ); - if (hasChunk(chunkX - 1, chunkZ) && ((getChunk(chunkX - 1, chunkZ)->mPopulatedFlags & 2) == 0) + if (hasChunk(chunkX - 1, chunkZ) && ((getChunk(chunkX - 1, chunkZ)->m_populatedFlags & 2) == 0) && hasChunk(chunkX - 1, chunkZ + 1) && hasChunk(chunkX, chunkZ + 1) && hasChunk(chunkX - 1, chunkZ)) MinecraftServer::getInstance()->addPostProcessRequest(this, mChunkGenerator, chunkX - 1, chunkZ); - if (hasChunk(chunkX, chunkZ - 1) && ((getChunk(chunkX, chunkZ - 1)->mPopulatedFlags & 2) == 0) + if (hasChunk(chunkX, chunkZ - 1) && ((getChunk(chunkX, chunkZ - 1)->m_populatedFlags & 2) == 0) && hasChunk(chunkX + 1, chunkZ - 1) && hasChunk(chunkX, chunkZ - 1) && hasChunk(chunkX + 1, chunkZ)) MinecraftServer::getInstance()->addPostProcessRequest(this, mChunkGenerator, chunkX, chunkZ - 1); if (hasChunk(chunkX - 1, chunkZ - 1) - && ((getChunk(chunkX - 1, chunkZ - 1)->mPopulatedFlags & 2) == 0) + && ((getChunk(chunkX - 1, chunkZ - 1)->m_populatedFlags & 2) == 0) && hasChunk(chunkX - 1, chunkZ - 1) && hasChunk(chunkX, chunkZ - 1) && hasChunk(chunkX - 1, chunkZ)) MinecraftServer::getInstance()->addPostProcessRequest(this, mChunkGenerator, chunkX - 1, @@ -225,7 +225,7 @@ LevelChunk* ServerChunkCache::updateCacheAndPostProcess(int chunkX, int chunkZ, newChunk->unload(true, true); delete newChunk; } - return mChunks[idx]; + return m_cache[idx]; } return newChunk; } @@ -235,7 +235,7 @@ LevelChunk* ServerChunkCache::getOrCreateChunk(int chunkX, int chunkZ, bool unk) return mEmptyChunk; int idx = computeIdx(chunkX, chunkZ); - LevelChunk* chunk = mChunks[idx]; + LevelChunk* chunk = m_cache[idx]; LevelChunk* generatedChunk = getChunkIfGenerated(chunkX, chunkZ, unk); if (generatedChunk) return generatedChunk; @@ -258,7 +258,7 @@ bool ServerChunkCache::hasChunk(int chunkX, int chunkZ) { return true; int idx = computeIdx(chunkX, chunkZ); - LevelChunk* chunk = mChunks[idx]; + LevelChunk* chunk = m_cache[idx]; if (chunk == nullptr || chunk->IsInvalid()) return false; @@ -266,7 +266,7 @@ bool ServerChunkCache::hasChunk(int chunkX, int chunkZ) { } bool ServerChunkCache::isChunkGeneratedAt(int chunkX, int chunkZ) { - LevelChunk* chunk = mChunks[computeIdx(chunkX, chunkZ)]; + LevelChunk* chunk = m_cache[computeIdx(chunkX, chunkZ)]; if (!inBounds(chunkX, chunkZ)) { return false; @@ -292,7 +292,7 @@ LevelChunk* ServerChunkCache::create(int chunkX, int chunkZ, bool unk) { return mEmptyChunk; int idx = computeIdx(chunkX, chunkZ); - LevelChunk* chunk = mChunks[idx]; + LevelChunk* chunk = m_cache[idx]; if (chunk && chunk->mXPos == chunkX && chunk->mZPos == chunkZ && !chunk->IsInvalid()) { return chunk; @@ -335,7 +335,7 @@ void ServerChunkCache::updatePostProcessFlags(int chunkX, int chunkZ) { updatePostProcessFlag(0x100, chunkX, chunkZ, 1, 0, chunk); updatePostProcessFlag(0x200, chunkX, chunkZ, 1, -1, chunk); - if ((chunk->mPopulatedFlags & 2)) { + if ((chunk->m_populatedFlags & 2)) { flagPostProcessComplete(4, chunkX + 1, chunkZ); flagPostProcessComplete(0x10, chunkX + 1, chunkZ + 1); flagPostProcessComplete(8, chunkX, chunkZ + 1); @@ -355,7 +355,7 @@ LevelChunk* ServerChunkCache::getChunk(int chunkX, int chunkZ) { return mEmptyChunk; int idx = computeIdx(chunkX, chunkZ); - LevelChunk* chunk = mChunks[idx]; + LevelChunk* chunk = m_cache[idx]; if (chunk && !chunk->IsInvalid()) return chunk; @@ -371,7 +371,7 @@ LevelChunk* ServerChunkCache::getChunkLoadedOrUnloaded(int chunkX, int chunkZ) { return mEmptyChunk; int idx = computeIdx(chunkX, chunkZ); - LevelChunk* chunk = mChunks[idx]; + LevelChunk* chunk = m_cache[idx]; if (!chunk) { chunk = mUnloadedChunks[idx]; @@ -393,8 +393,8 @@ void ServerChunkCache::updatePostProcessFlag(short flag, int baseX, int baseZ, i int chunkZ = baseZ + offsetZ; if (hasChunk(chunkX, chunkZ)) { LevelChunk* targetChunk = getChunk(chunkX, chunkZ); - if (targetChunk == mEmptyChunk || (targetChunk->mPopulatedFlags & 2) != 0) { - chunk->mPopulatedFlags |= flag; + if (targetChunk == mEmptyChunk || (targetChunk->m_populatedFlags & 2) != 0) { + chunk->m_populatedFlags |= flag; } } } @@ -444,9 +444,9 @@ std::vector* ServerChunkCache::getMobsAt(MobCategory* cat return mChunkGenerator->getMobsAt(category, pos); } -void ServerChunkCache::findNearestMapFeature(Level* level, const std::wstring& name, const BlockPos& pos, - bool unk) { - mChunkGenerator->findNearestMapFeature(level, name, pos, unk); +BlockPos* ServerChunkCache::findNearestMapFeature(Level* level, const std::wstring& name, const BlockPos& pos, + bool unk) { + return mChunkGenerator->findNearestMapFeature(level, name, pos, unk); } void ServerChunkCache::recreateLogicStructuresForChunk(LevelChunk* chunk, int chunkX, int chunkZ) {} @@ -460,7 +460,6 @@ int ServerChunkCache::getLoadedChunks() { return list->size(); } -ChunkSource* ServerChunkCache::getCache() { - // likely wrong, but other classes require this function to return ChunkSource* - return (ChunkSource*)mChunks; +LevelChunk** ServerChunkCache::getCache() { + return m_cache; } diff --git a/src/Minecraft.Client/net/minecraft/server/level/ServerChunkCache.h b/src/Minecraft.Client/net/minecraft/server/level/ServerChunkCache.h index 2ba71da6..0dfa954c 100644 --- a/src/Minecraft.Client/net/minecraft/server/level/ServerChunkCache.h +++ b/src/Minecraft.Client/net/minecraft/server/level/ServerChunkCache.h @@ -34,12 +34,12 @@ class ServerChunkCache : public ChunkSource { LevelChunk* create(int chunkX, int chunkZ) override; LevelChunk* create(int chunkX, int chunkZ, bool unk); bool saveAllEntities() override; - void save(bool, ProgressListener*) override; + bool save(bool, ProgressListener*) override; bool shouldSave() override; - ChunkSource* getCache() override; + LevelChunk** getCache() override; std::vector* getMobsAt(MobCategory* category, const BlockPos& pos) override; - void findNearestMapFeature(Level* level, const std::wstring& name, const BlockPos& pos, - bool unk) override; + BlockPos* findNearestMapFeature(Level* level, const std::wstring& name, const BlockPos& pos, + bool unk) override; int getLoadedChunks() override; void recreateLogicStructuresForChunk(LevelChunk* chunk, int chunkX, int chunkZ) override; @@ -58,7 +58,7 @@ class ServerChunkCache : public ChunkSource { ChunkGenerator* mChunkGenerator; ChunkStorage* mChunkStorage; bool byte_28; - LevelChunk** mChunks; + LevelChunk** m_cache; std::vector mChunkList; ServerLevel* mLevel; Dimension* mDimension; diff --git a/src/Minecraft.World/net/minecraft/world/level/Level.h b/src/Minecraft.World/net/minecraft/world/level/Level.h index 189d9a2e..be7543da 100644 --- a/src/Minecraft.World/net/minecraft/world/level/Level.h +++ b/src/Minecraft.World/net/minecraft/world/level/Level.h @@ -207,6 +207,8 @@ class Level : public LevelSource { bool isFindingSpawn(); unsigned int countInstanceOf(eINSTANCEOF, bool, unsigned int*, unsigned int*); + void setBlockEntity(const BlockPos& pos, std::shared_ptr blockEntity); + int mSeaLevel = 63; nn::os::MutexType mEntityMutex; std::vector> mEntities; @@ -252,7 +254,7 @@ class Level : public LevelSource { std::vector qword_240; void* qword_258; std::vector qword_260; - ChunkSource* mChunkCache; + LevelChunk** mChunkCache; int mXZSize; nn::os::MutexType mUnkMutex; int dword_2a8; diff --git a/src/Minecraft.World/net/minecraft/world/level/border/BorderChangeListener.h b/src/Minecraft.World/net/minecraft/world/level/border/BorderChangeListener.h index a9a3a1f7..325a1b2f 100644 --- a/src/Minecraft.World/net/minecraft/world/level/border/BorderChangeListener.h +++ b/src/Minecraft.World/net/minecraft/world/level/border/BorderChangeListener.h @@ -1,8 +1,18 @@ #pragma once class Level; +class WorldBorder; class BorderChangeListener { public: - BorderChangeListener(Level*) {} + BorderChangeListener(); + + virtual ~BorderChangeListener(); + virtual void onBorderSizeSet(WorldBorder* border, double newSize) = 0; + virtual void onBorderSizeLerping(WorldBorder* border, double from, double to, long long lerpTime) = 0; + virtual void onBorderCenterSet(WorldBorder* border, double x, double z) = 0; + virtual void onBorderSetWarningTime(WorldBorder* border, int time) = 0; + virtual void onBorderSetWarningBlocks(WorldBorder* border, int) = 0; + virtual void onBorderSetDamagePerBlock(WorldBorder* border, double damage) = 0; + virtual void onBorderSetDamageSafeZOne(WorldBorder* border, double safeZone) = 0; // ZOne }; diff --git a/src/Minecraft.World/net/minecraft/world/level/border/WorldBorder.cpp b/src/Minecraft.World/net/minecraft/world/level/border/WorldBorder.cpp index 7882adb3..cf0ffd29 100644 --- a/src/Minecraft.World/net/minecraft/world/level/border/WorldBorder.cpp +++ b/src/Minecraft.World/net/minecraft/world/level/border/WorldBorder.cpp @@ -1,46 +1,88 @@ #include "net/minecraft/world/level/border/WorldBorder.h" +#include "net/minecraft/core/BlockPos.h" + #include "net/minecraft/core/System.h" +#include "net/minecraft/util/Mth.h" +#include "net/minecraft/world/entity/Entity.h" +#include "net/minecraft/world/phys/AABB.h" + +WorldBorder::WorldBorder(Level*) {} -WorldBorder::WorldBorder(Level* level) {} +// NON_MATCHING | Difference: 460 +// I can't seem to replicate what it does, this is the closest I've gotten so far tho. +WorldBorder::~WorldBorder() { + m_listeners.clear(); +} double WorldBorder::getMinX() { double max = getCenterX() + getSize() * -0.5; - if (max < (double)-mWorldSize) - max = -mWorldSize; + if (max < static_cast(-m_absoluteMaxSize)) + max = -m_absoluteMaxSize; return max; } double WorldBorder::getMaxX() { double max = getCenterX() + getSize() * 0.5; - if (max > (double)mWorldSize) - max = mWorldSize; + if (max > static_cast(m_absoluteMaxSize)) + max = m_absoluteMaxSize; return max; } double WorldBorder::getMinZ() { double max = getCenterZ() + getSize() * -0.5; - if (max < (double)-mWorldSize) - max = -mWorldSize; + if (max < static_cast(-m_absoluteMaxSize)) + max = -m_absoluteMaxSize; return max; } double WorldBorder::getMaxZ() { double max = getCenterZ() + getSize() * 0.5; - if (max > (double)mWorldSize) - max = mWorldSize; + if (max > static_cast(m_absoluteMaxSize)) + max = m_absoluteMaxSize; + return max; } +bool WorldBorder::isWithinBounds(const BlockPos& pos) { + return pos.getX() + 1 > this->getMinX() && pos.getX() < this->getMaxX() + && pos.getZ() + 1 > this->getMinZ() && pos.getZ() < this->getMaxZ(); +} + +bool WorldBorder::isWithinBounds(AABB* aabb) { + return aabb->maxX > this->getMinX() && aabb->minX < this->getMaxX() && aabb->maxZ > this->getMinZ() + && aabb->minZ < this->getMaxZ(); +} + +double WorldBorder::getDistanceToBorder(std::shared_ptr entity) { + return this->getDistanceToBorder(entity->mX, entity->mZ); +} + +double WorldBorder::getDistanceToBorder(double x, double z) { + const double nz = z - this->getMinZ(); + const double pz = this->getMaxZ() - z; + const double nx = x - this->getMinX(); + const double px = this->getMaxX() - x; + + double dist = std::min(nx, px); + dist = std::min(dist, nz); + dist = std::min(dist, pz); + + return dist; +} + +void WorldBorder::addListener(BorderChangeListener* listener) { + this->m_listeners.push_back(listener); +} BorderStatus* WorldBorder::getStatus() { - if (mNextSize < mCurrentSize) + if (m_nextSize < m_currentSize) return gBorderStatusShrinking; - if (mNextSize > mCurrentSize) + if (m_nextSize > m_currentSize) return gBorderStatusGrowing; return gBorderStatusStationary; @@ -48,32 +90,111 @@ BorderStatus* WorldBorder::getStatus() { double WorldBorder::getSize() { if (getStatus() != gBorderStatusStationary) { - double time = (float)(System::processTimeInMilliSecs() - mTime2) / (float)(mTime1 - mTime2); + double time + = (float)(System::processTimeInMilliSecs() - m_startTime) / (float)(m_finishTime - m_startTime); if (!(time >= 1.0f)) - return mCurrentSize + (time * (mNextSize - mCurrentSize)); + return m_currentSize + (time * (m_nextSize - m_currentSize)); - setSize(mNextSize); + setSize(m_nextSize); } - return mCurrentSize; + return m_currentSize; } double WorldBorder::getCenterX() { - return mCenterX; + return m_centerX; } double WorldBorder::getCenterZ() { - return mCenterZ; + return m_centerZ; +} + +std::vector& WorldBorder::getListeners() { + return m_listeners; +} + +void WorldBorder::setSize(double size) { + this->m_currentSize = size; + this->m_nextSize = size; + + const long t = System::processTimeInMilliSecs(); + this->m_finishTime = t; + this->m_startTime = t; + + std::vector& listeners = this->getListeners(); + for (auto i = listeners.begin(); i != listeners.end(); ++i) { + (*i)->onBorderSizeSet(this, size); + } +} + +void WorldBorder::setAbsoluteMaxSize(int maxSize) { + this->m_absoluteMaxSize = maxSize; } -std::vector* WorldBorder::getListeners() { - return &mListeners; +void WorldBorder::setCenter(double x, double z) { + this->m_centerX = x; + this->m_centerZ = z; + + std::vector& listeners = this->getListeners(); + for (auto i = listeners.begin(); i != listeners.end(); ++i) { + (*i)->onBorderCenterSet(this, x, z); + } +} + +void WorldBorder::setDamagePerBlock(double damage) { + this->m_damagePerBlock = damage; + + std::vector& listeners = this->getListeners(); + for (auto i = listeners.begin(); i != listeners.end(); ++i) { + (*i)->onBorderSetDamagePerBlock(this, damage); + } +} + +void WorldBorder::setDamageSafeZone(double safeZone) { + this->m_damageSafeZone = safeZone; + + std::vector& listeners = this->getListeners(); + for (auto i = listeners.begin(); i != listeners.end(); ++i) { + (*i)->onBorderSetDamageSafeZOne(this, safeZone); + } +} + +void WorldBorder::setWarningBlocks(int blocks) { + this->m_warningBlocks = blocks; + + std::vector& listeners = this->getListeners(); + for (auto i = listeners.begin(); i != listeners.end(); ++i) { + (*i)->onBorderSetWarningBlocks(this, blocks); + } +} + +void WorldBorder::setWarningTime(int time) { + this->m_warningTime = time; + + std::vector& listeners = this->getListeners(); + for (auto i = listeners.begin(); i != listeners.end(); ++i) { + (*i)->onBorderSetWarningTime(this, time); + } +} + +void WorldBorder::lerpSizeBetween(double from, double to, long long lerpTime) { + this->m_currentSize = from; + this->m_nextSize = to; + + const long t = System::processTimeInMilliSecs(); + this->m_finishTime = t + lerpTime; + this->m_startTime = t; + + std::vector& listeners = this->getListeners(); + for (auto i = listeners.begin(); i != listeners.end(); ++i) { + (*i)->onBorderSizeLerping(this, from, to, lerpTime); + } } double WorldBorder::getDamageSafeZone() { - return mDamageSafeZone; + return m_damageSafeZone; } double WorldBorder::getDamagePerBlock() { - return mDamageAmount; + return m_damagePerBlock; } diff --git a/src/Minecraft.World/net/minecraft/world/level/border/WorldBorder.h b/src/Minecraft.World/net/minecraft/world/level/border/WorldBorder.h index e6f53995..7ad100e5 100644 --- a/src/Minecraft.World/net/minecraft/world/level/border/WorldBorder.h +++ b/src/Minecraft.World/net/minecraft/world/level/border/WorldBorder.h @@ -2,7 +2,9 @@ #include "net/minecraft/world/level/border/BorderChangeListener.h" #include "net/minecraft/world/level/border/BorderStatus.h" +#include "net/minecraft/world/level/chunk/ChunkPos.h" #include "types.h" + #include #include @@ -13,38 +15,75 @@ class Level; class WorldBorder { public: - WorldBorder(Level*); + explicit WorldBorder(Level*); + virtual ~WorldBorder(); - bool isWithinBounds(const BlockPos&); double getMinX(); double getMaxX(); double getMinZ(); double getMaxZ(); - void isWithinBounds(AABB*); - double getDistanceToBorder(std::shared_ptr); - double getDistanceToBorder(double, double); - BorderStatus* getStatus(); double getSize(); + virtual double getCenterX(); virtual double getCenterZ(); - std::vector* getListeners(); - void setSize(double); - double getDamageSafeZone(); + + int getAbsoluteMaxSize() DELETE_UNUSED; + void setAbsoluteMaxSize(int maxSize); + double getDamagePerBlock(); + void setDamagePerBlock(double damage); + + double getDamageSafeZone(); + void setDamageSafeZone(double safeZone); + + BorderStatus* getStatus(); + + bool isWithinBounds(AABB* aabb); + bool isWithinBounds(ChunkPos* pos) DELETE_EXTERNAL; + bool isWithinBounds(const BlockPos& pos); + bool isWithinBounds(double x, double z) DELETE_EXTERNAL; + + int getWarningBlocks() DELETE_UNUSED; + void setWarningBlocks(int blocks); + + int getWarningTime() DELETE_UNUSED; + void setWarningTime(int time); + + long long getLerpRemainingTime() DELETE_UNUSED; + long long getLerpSpeed() DELETE_EXTERNAL; + long long getLerpTarget() DELETE_UNUSED; + + double getDistanceToBorder(std::shared_ptr entity); + double getDistanceToBorder(double x, double z); + + void addListener(BorderChangeListener* listener); + std::vector& getListeners(); + void removeListener(BorderChangeListener* listener) DELETE_EXTERNAL; + + void setSize(double size); + void setCenter(double x, double z); + void lerpSizeBetween(double from, double to, long long lerpTime); + +private: + std::vector m_listeners; + + double m_centerX = 0.0; + double m_centerZ = 0.0; + + double m_currentSize = 60000000.0; + double m_nextSize = 60000000.0; + + long m_finishTime = 0; + long m_startTime = 0; + + int m_absoluteMaxSize = 30000000; + + double m_damagePerBlock = 0.2; + double m_damageSafeZone = 5.0; - std::vector mListeners; - double mCenterX = 0.0; - double mCenterZ = 0.0; - double mCurrentSize = 60000000.0; - double mNextSize = 60000000.0; - long mTime1 = 0; - long mTime2 = 0; - int mWorldSize = 30000000; - double mDamageAmount = 0.2; - double mDamageSafeZone = 5.0; - int mWarningTime = 15; - int mWarningDistance = 5; + int m_warningTime = 15; + int m_warningBlocks = 5; }; ASSERT_SIZEOF(WorldBorder, 0x70) diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/Chunk.cpp b/src/Minecraft.World/net/minecraft/world/level/chunk/Chunk.cpp index 1fe002f9..d9ae5bf1 100644 --- a/src/Minecraft.World/net/minecraft/world/level/chunk/Chunk.cpp +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/Chunk.cpp @@ -293,7 +293,7 @@ void Chunk::rebuild() { std::vector glideRingSizes; // The Glide minigame has boost areas where the game creates fake blocks to cover them. - if (Minecraft::InMiniGame(EMiniGameId::GLIDE, 0)) { + if (Minecraft::InMiniGame(EMiniGameId::GLIDE, false)) { LevelRuleset* gameRules = CConsoleMinecraftApp::sInstance.getGameRuleDefinitions(); std::vector ringsInArea; diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/ChunkSource.cpp b/src/Minecraft.World/net/minecraft/world/level/chunk/ChunkSource.cpp index 540e9b18..1268694a 100644 --- a/src/Minecraft.World/net/minecraft/world/level/chunk/ChunkSource.cpp +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/ChunkSource.cpp @@ -20,7 +20,7 @@ bool ChunkSource::saveAllEntities() { return false; } -ChunkSource* ChunkSource::getCache() { +LevelChunk** ChunkSource::getCache() { return nullptr; } diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/ChunkSource.h b/src/Minecraft.World/net/minecraft/world/level/chunk/ChunkSource.h index 978d1578..7ba96e96 100644 --- a/src/Minecraft.World/net/minecraft/world/level/chunk/ChunkSource.h +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/ChunkSource.h @@ -13,29 +13,29 @@ class ProgressListener; class ChunkSource { public: virtual ~ChunkSource() {} - virtual LevelChunk* getChunkIfLoaded(int, int) = 0; - virtual LevelChunk* getOrCreateChunk(int, int, bool) = 0; + virtual LevelChunk* getChunkIfLoaded(int x, int z) = 0; + virtual LevelChunk* getOrCreateChunk(int x, int z, bool) = 0; virtual void tick() = 0; virtual std::wstring gatherStats() = 0; virtual int getLoadedChunksCount() = 0; virtual void flagPostProcessComplete(short, int, int); - virtual bool isChunkGeneratedAt(int, int); - virtual bool hasChunk(int, int) = 0; - virtual bool reallyHasChunk(int, int); - virtual LevelChunk* getChunk(int, int) = 0; + virtual bool isChunkGeneratedAt(int x, int z); + virtual bool hasChunk(int x, int z) = 0; + virtual bool reallyHasChunk(int x, int z); + virtual LevelChunk* getChunk(int x, int z) = 0; virtual LevelChunk* getChunkAt(const BlockPos&) = 0; - virtual LevelChunk* getChunkLoadedOrUnloaded(int, int); + virtual LevelChunk* getChunkLoadedOrUnloaded(int x, int z); virtual void lightChunk(LevelChunk*); - virtual LevelChunk* create(int, int) = 0; + virtual LevelChunk* create(int x, int z) = 0; virtual bool saveAllEntities(); - virtual void save(bool, ProgressListener*) = 0; + virtual bool save(bool, ProgressListener*) = 0; virtual bool shouldSave() = 0; - virtual ChunkSource* getCache(); + virtual LevelChunk** getCache(); virtual void dataReceived(int, int); - virtual std::vector* getMobsAt(MobCategory*, const BlockPos&) = 0; - virtual void findNearestMapFeature(Level*, const std::wstring&, const BlockPos&, bool) = 0; + virtual std::vector* getMobsAt(MobCategory* category, const BlockPos& pos) = 0; + virtual BlockPos* findNearestMapFeature(Level*, const std::wstring&, const BlockPos&, bool) = 0; virtual int getLoadedChunks() = 0; virtual void recreateLogicStructuresForChunk(LevelChunk*, int, int) = 0; - int mXZSize; + int m_xzSize; }; diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/LevelChunk.cpp b/src/Minecraft.World/net/minecraft/world/level/chunk/LevelChunk.cpp index 5b351f9c..85871d4c 100644 --- a/src/Minecraft.World/net/minecraft/world/level/chunk/LevelChunk.cpp +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/LevelChunk.cpp @@ -1,6 +1,10 @@ #include "net/minecraft/world/level/chunk/LevelChunk.h" +#include "net/minecraft/world/level/Level.h" + #include "net/minecraft/world/level/block/Block.h" +#include "net/minecraft/world/level/block/entity/BlockEntity.h" +#include "net/minecraft/world/level/dimension/Dimension.h" void LevelChunk::staticCtor() { InitializeCriticalSection(&LevelChunk::mMutex_710178c150); @@ -8,11 +12,49 @@ void LevelChunk::staticCtor() { InitializeCriticalSection(&LevelChunk::mMutex_710178c190); } +void LevelChunk::tick(bool skipRecheckGaps) { + if (this->m_tickSkylight && this->m_level->mDimension->isHasSkyLight() && !skipRecheckGaps) { + PIXBeginNamedEvent(0.0, "Check for gaps"); + this->recheckGaps(this->m_level->mIsLocal); + PIXEndNamedEvent(); + } + + this->unk11 = true; + + if (!this->m_hasPostProcessed && this->m_populatedFlags & FLAG_TERRAIN_POPULATED) { + PIXBeginNamedEvent(0.0, "postProcess"); + this->postProcess(); + PIXEndNamedEvent(); + } + + PIXBeginNamedEvent(0.0, "Process block entities"); + while (!this->m_blockEntityPosTickQueue.empty()) { + BlockPos pos = this->m_blockEntityPosTickQueue.front(); + this->m_blockEntityPosTickQueue.pop_front(); + + if (this->getBlockEntity(pos, static_cast(2)) == nullptr + && this->getBlock(pos)->isBlockEntity()) { + std::shared_ptr bl = this->createBlockEntity(pos); + this->m_level->setBlockEntity(pos, bl); + this->m_level->setBlocksDirty(pos, pos); + } + } + PIXEndNamedEvent(); +} + +void LevelChunk::postProcess() { + this->m_hasPostProcessed = true; +} + void LevelChunk::writeCompressedDataData(DataOutputStream* out) { mDataDataLower->write(out); mDataDataUpper->write(out); } +bool LevelChunk::DECOMP_getUnknownField() { + return unk8; +} + void LevelChunk::writeCompressedBlockData(DataOutputStream* out) { mBlockDataLower->write(out); mBlockDataUpper->write(out); @@ -32,6 +74,10 @@ ChunkPos LevelChunk::getPos() { return ChunkPos(this->mXPos, this->mZPos); } +bool LevelChunk::isTerrainPopulated() { + return (this->m_populatedFlags >> 8 & 0xFF) >> 2 & 1; +} + Block* LevelChunk::GetBlock(CompressedBlockStorage* storage, int x, int y, int z) { const int y0 = y < 0 ? y + 127 : y; return Block::byId(storage->get(x, y - (y0 & 0xFFFFFF80), z) & 0xFF); diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/LevelChunk.h b/src/Minecraft.World/net/minecraft/world/level/chunk/LevelChunk.h index 1d4e409b..f39bd5a8 100644 --- a/src/Minecraft.World/net/minecraft/world/level/chunk/LevelChunk.h +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/LevelChunk.h @@ -1,5 +1,7 @@ #pragma once +#include "deque" +#include "net/minecraft/core/BlockPos.h" #include "net/minecraft/core/System.h" #include "net/minecraft/world/ArrayWithLength.h" #include "net/minecraft/world/level/LightLayer.h" @@ -32,12 +34,26 @@ class LevelChunk { public: static bool touchedSky; // Name from b1.2_02 + // TODO put this somewhere better, maybe CompressedBlockStorage if used there +#define INDEX_BLOCK_ARRAY(x, y, z) y | (x << 11) | (z << 7) + + class BlockChange {}; + + enum DECOMP_HELPER PopulationFlags : int { FLAG_TERRAIN_POPULATED = 0x400 }; + LevelChunk(Level*, ChunkPrimer*, int, int); + LevelChunk(Level*, int, int); enum EntityCreationType {}; static void staticCtor(); + void tick(bool); + void recheckGaps(bool local); + void postProcess(); + + std::shared_ptr createBlockEntity(const BlockPos& pos); + static nn::os::MutexType mMutex_710178c150; static nn::os::MutexType mMutex_710178c170; static nn::os::MutexType mMutex_710178c190; @@ -67,9 +83,9 @@ class LevelChunk { virtual Block* getBlock(const BlockPos&); virtual const BlockState* getBlockState(const BlockPos&); virtual void getData(const BlockPos&); - virtual void setData(int, int, int, int, int, bool*); - virtual void setBlock(const BlockPos&, const BlockState*); - virtual void setBlockAndData(int, int, int, int, int, bool); + virtual bool setData(int, int, int, int, int, bool*); + virtual const BlockState* setBlock(const BlockPos&, const BlockState*); + virtual bool setBlockAndData(int, int, int, int, int, bool); virtual int getBrightness(LightLayer::variety, const BlockPos&); virtual void getNeighbourBrightnesses(int*, LightLayer::variety, int, int, int); virtual void setBrightness(LightLayer::variety, const BlockPos&, int); @@ -78,25 +94,26 @@ class LevelChunk { virtual void removeEntity(std::shared_ptr); virtual void removeEntity(std::shared_ptr, int); virtual bool isSkyLit(const BlockPos&); - virtual void getBlockEntity(const BlockPos&, LevelChunk::EntityCreationType); + virtual std::shared_ptr getBlockEntity(const BlockPos&, LevelChunk::EntityCreationType); virtual void addBlockEntity(std::shared_ptr); virtual void setBlockEntity(const BlockPos&, std::shared_ptr); virtual void removeBlockEntity(const BlockPos&); virtual void load(bool); virtual void unload(bool, bool); - virtual void containsPlayer(); - virtual void field_160(); + virtual bool containsPlayer(); + virtual bool + DECOMP_getUnknownField(); // NAME NOT KNOWN, don't want it to appear like it is in IDA either virtual void markUnsaved(); virtual void getEntities(std::shared_ptr, AABB const*, std::vector>&, const Predicate>*); virtual void getEntitiesOfClass(const std::type_info&, AABB const*, std::vector>&, const Predicate>*, bool); - virtual void countEntities(); + virtual int countEntities(); virtual bool shouldSave(bool); virtual void getBlocksAndData(arrayWithLength*, int, int, int, int, int, int, int, bool); virtual void setBlocksAndData(arrayWithLength, int, int, int, int, int, int, int, bool); - virtual void testSetBlocksAndData(arrayWithLength, int, int, int, int, int, int, int); - virtual void getRandom(long long); + virtual bool testSetBlocksAndData(arrayWithLength, int, int, int, int, int, int, int); + virtual Random* getRandom(long long); virtual bool isEmpty(); virtual Biome* getBiome(const BlockPos&, BiomeSource*); virtual void compressLighting(); @@ -128,7 +145,8 @@ class LevelChunk { CompressedBlockStorage* mBlockDataLower; // Y0-Y127 CompressedBlockStorage* mBlockDataUpper; // Y128-Y255 - char unk[400]; + char unk[391]; + Level* m_level; SparseDataStorage* mDataDataLower; // Y0-Y127 SparseDataStorage* mDataDataUpper; // Y128-Y255 @@ -139,11 +157,22 @@ class LevelChunk { char padding_480[24]; int mXPos; int mZPos; - char unk2[14]; + bool m_tickSkylight; // guessed, could be skylightDirty maybe? + char unk2[13]; std::unordered_map>* mBlockEntities; char unk3[32]; - short mPopulatedFlags; - char unk4[42]; + short m_populatedFlags; + char unk4[13]; + bool unk9; + bool m_hasPostProcessed; + bool unk11; + bool unk12; + bool unk6; + char unk7[25]; long mInhabitedTime; - char unk5[86]; + bool unk8; + // char unk5[85]; // 728 with 85 + char unk5[30]; + std::deque m_blockEntityPosTickQueue; + char unk13[8]; }; diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/WaterLevelChunk.cpp b/src/Minecraft.World/net/minecraft/world/level/chunk/WaterLevelChunk.cpp new file mode 100644 index 00000000..d41ee73f --- /dev/null +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/WaterLevelChunk.cpp @@ -0,0 +1,81 @@ +#include "Minecraft.World/net/minecraft/world/level/chunk/WaterLevelChunk.h" +#include "net/minecraft/core/BlockPos.h" +#include "net/minecraft/world/Random.h" +#include "net/minecraft/world/level/Level.h" + +WaterLevelChunk::WaterLevelChunk(Level* lvl, ChunkPrimer* primer, int x, int z) + : LevelChunk(lvl, primer, x, z) { + this->unk6 = true; // if I had to guess, it's m_populated + this->m_populatedFlags = 0b0000011111111110; +} + +void WaterLevelChunk::reSyncLighting() {} +void WaterLevelChunk::dropLighting() {} +void WaterLevelChunk::recalcBlockLights() {} +void WaterLevelChunk::recalcHeightmapOnly() {} +void WaterLevelChunk::recalcHeightmap() {} +void WaterLevelChunk::lightLava() {} +bool WaterLevelChunk::setData(int i, int i1, int i2, int i3, int i4, bool* p) { + *p = true; + return true; +} + +const BlockState* WaterLevelChunk::setBlock(const BlockPos& pos, const BlockState* state) { + return state; +} +bool WaterLevelChunk::setBlockAndData(int i, int i1, int i2, int i3, int i4, bool cond) { + return true; +} +void WaterLevelChunk::setBrightness(LightLayer::variety variety, const BlockPos& block_pos, int i) {} +void WaterLevelChunk::addEntity(std::shared_ptr entity) {} +void WaterLevelChunk::removeEntity(std::shared_ptr entity) {} +void WaterLevelChunk::removeEntity(std::shared_ptr entity, int i) {} +std::shared_ptr WaterLevelChunk::getBlockEntity(const BlockPos& block_pos, + LevelChunk::EntityCreationType entity_creation) { + return nullptr; +} +void WaterLevelChunk::addBlockEntity(std::shared_ptr block_entity) {} +void WaterLevelChunk::setBlockEntity(const BlockPos& block_pos, std::shared_ptr block_entity) {} +void WaterLevelChunk::removeBlockEntity(const BlockPos& block_pos) {} +void WaterLevelChunk::load(bool cond) {} +void WaterLevelChunk::unload(bool cond, bool cond1) {} +bool WaterLevelChunk::containsPlayer() { + return false; +} + +void WaterLevelChunk::markUnsaved() {} +void WaterLevelChunk::getEntities(std::shared_ptr entity, AABB const* aabb, + std::vector>& shared_ptrs, + const Predicate>* predicate) {} +void WaterLevelChunk::getEntitiesOfClass(const std::type_info& type_info, AABB const* aabb, + std::vector>& shared_ptrs, + const Predicate>* predicate, bool cond) {} +int WaterLevelChunk::countEntities() { + return 0; +} + +bool WaterLevelChunk::shouldSave(bool) { + return false; +} + +bool WaterLevelChunk::testSetBlocksAndData(arrayWithLength array_with_length, int i, int i1, + int i2, int i3, int i4, int i5, int i6) { + return false; +} + +// NON_MATCHING | Difference: 795 +Random* WaterLevelChunk::getRandom(long long i) { + return new Random((this->m_level->getSeed() + 0x5AC0DB * this->mXPos + + 0x4C1906LL * (this->mXPos * this->mXPos) + 0x5F24F * this->mZPos + + 0x4307A7LL * (this->mZPos * this->mZPos)) + ^ i); +} + +Biome* WaterLevelChunk::getBiome(const BlockPos& block_pos, BiomeSource* biome_source) { + return Biome::getBiome(Biome::EBiomeIDs::BiomeID_OCEAN); +} + +void WaterLevelChunk::setLevelChunkBrightness(LightLayer::variety variety, int x, int y, int z, + int brightness) { + LevelChunk::setBrightness(variety, BlockPos(x, y, z), brightness); +} diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/WaterLevelChunk.h b/src/Minecraft.World/net/minecraft/world/level/chunk/WaterLevelChunk.h new file mode 100644 index 00000000..86ac5a6b --- /dev/null +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/WaterLevelChunk.h @@ -0,0 +1,46 @@ +#pragma once + +#include "net/minecraft/world/level/chunk/LevelChunk.h" + +/** Immutable chunk, usually holding layers of air, water, and stone, or air, dirt, and grass. + * + * WaterLevelChunk is a bad name since this is pretty much a general purpose immutable chunk + */ +class WaterLevelChunk : public LevelChunk { +public: + WaterLevelChunk(Level* lvl, ChunkPrimer* primer, int x, int z); + + void reSyncLighting() override; + void dropLighting() override; + void recalcBlockLights() override; + void recalcHeightmapOnly() override; + void recalcHeightmap() override; + void lightLava() override; + bool setData(int, int, int, int, int, bool*) override; + const BlockState* setBlock(const BlockPos& pos, const BlockState* state) override; + bool setBlockAndData(int, int, int, int, int, bool) override; + void setBrightness(LightLayer::variety layer, const BlockPos& pos, int brightness) override; + void addEntity(std::shared_ptr) override; + void removeEntity(std::shared_ptr) override; + void removeEntity(std::shared_ptr, int) override; + std::shared_ptr getBlockEntity(const BlockPos&, LevelChunk::EntityCreationType) override; + void addBlockEntity(std::shared_ptr) override; + void setBlockEntity(const BlockPos&, std::shared_ptr) override; + void removeBlockEntity(const BlockPos&) override; + void load(bool) override; + void unload(bool, bool) override; + bool containsPlayer() override; + void markUnsaved() override; + void getEntities(std::shared_ptr, AABB const*, std::vector>&, + const Predicate>*) override; + void getEntitiesOfClass(const std::type_info&, AABB const*, std::vector>&, + const Predicate>*, bool) override; + int countEntities() override; + bool shouldSave(bool) override; + void setBlocksAndData(arrayWithLength, int, int, int, int, int, int, int, bool) override; + bool testSetBlocksAndData(arrayWithLength, int, int, int, int, int, int, int) override; + Random* getRandom(long long) override; + Biome* getBiome(const BlockPos&, BiomeSource*) override; + + void setLevelChunkBrightness(LightLayer::variety, int x, int y, int z, int brightness); +}; diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/storage/OldChunkStorage.cpp b/src/Minecraft.World/net/minecraft/world/level/chunk/storage/OldChunkStorage.cpp index 0bcb8e56..29d4dfcf 100644 --- a/src/Minecraft.World/net/minecraft/world/level/chunk/storage/OldChunkStorage.cpp +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/storage/OldChunkStorage.cpp @@ -9,6 +9,9 @@ #include "net/minecraft/world/level/block/entity/BlockEntity.h" #include "net/minecraft/world/level/tick/TickNextTickData.h" +// TODO OldChunkStorage::ThreadStorage constructor is not the same as expected +DEFINE_THREAD_STORAGE_SINGLE(OldChunkStorage) + // NON_MATCHING | Score: 42929 (lower is better) void OldChunkStorage::save(LevelChunk* chunk, Level* lvl, CompoundTag* tag) { lvl->checkSession(); @@ -52,7 +55,7 @@ void OldChunkStorage::save(LevelChunk* chunk, Level* lvl, DataOutputStream* out) // write heightmap out->write(chunk->getHeightmap()); - out->writeShort(chunk->mPopulatedFlags); + out->writeShort(chunk->m_populatedFlags); // write biomes out->write(chunk->getBiomes()); diff --git a/src/Minecraft.World/net/minecraft/world/level/chunk/storage/OldChunkStorage.h b/src/Minecraft.World/net/minecraft/world/level/chunk/storage/OldChunkStorage.h index b762fcdd..16d5ef3c 100644 --- a/src/Minecraft.World/net/minecraft/world/level/chunk/storage/OldChunkStorage.h +++ b/src/Minecraft.World/net/minecraft/world/level/chunk/storage/OldChunkStorage.h @@ -8,12 +8,10 @@ class OldChunkStorage { #define CHUNK_VERSION 11 public: + DECLARE_THREAD_STORAGE_SINGLE(OldChunkStorage) + /** Saves using the older McRegion style chunk format */ static void save(LevelChunk* chunk, Level* lvl, CompoundTag* tag); /** Saves using the new chunk format */ static void save(LevelChunk* chunk, Level* lvl, DataOutputStream* stream); - - static void CreateNewThreadStorage(); - - class ThreadStorage {}; }; diff --git a/src/Minecraft.World/net/minecraft/world/level/dimension/Dimension.cpp b/src/Minecraft.World/net/minecraft/world/level/dimension/Dimension.cpp index 194f6390..444c61c2 100644 --- a/src/Minecraft.World/net/minecraft/world/level/dimension/Dimension.cpp +++ b/src/Minecraft.World/net/minecraft/world/level/dimension/Dimension.cpp @@ -57,6 +57,12 @@ bool Dimension::isFoggyAt(int x, int z) { return false; } +bool Dimension::containsChunk(int x, int z) { + const int xzAxis = this->getXZSize() / 2; + + return (-xzAxis <= x && x < xzAxis) && (-xzAxis <= z && z < xzAxis); +} + BiomeSource* Dimension::getBiomeSource() { return mBiomeSource; } diff --git a/src/Minecraft.World/net/minecraft/world/level/dimension/Dimension.h b/src/Minecraft.World/net/minecraft/world/level/dimension/Dimension.h index 4efe8a65..200e5f14 100644 --- a/src/Minecraft.World/net/minecraft/world/level/dimension/Dimension.h +++ b/src/Minecraft.World/net/minecraft/world/level/dimension/Dimension.h @@ -42,7 +42,7 @@ class Dimension { virtual int getXZSize(); virtual AABB* getPlayerConstraints(const BlockPos&); virtual bool inPlayerConstraints(const BlockPos&); - virtual bool containsChunk(int, int); + virtual bool containsChunk(int x, int z); virtual void getBlockLightColour(); BiomeSource* getBiomeSource(); diff --git a/src/Minecraft.World/net/minecraft/world/level/gamemode/ClientMasterGameMode.cpp b/src/Minecraft.World/net/minecraft/world/level/gamemode/ClientMasterGameMode.cpp new file mode 100644 index 00000000..26fbec62 --- /dev/null +++ b/src/Minecraft.World/net/minecraft/world/level/gamemode/ClientMasterGameMode.cpp @@ -0,0 +1,5 @@ +#include "net/minecraft/world/level/gamemode/ClientMasterGameMode.h" + +bool ClientMasterGameMode::isNewLevelDataPending() { + return m_hasPendingLevelData; +} diff --git a/src/Minecraft.World/net/minecraft/world/level/gamemode/ClientMasterGameMode.h b/src/Minecraft.World/net/minecraft/world/level/gamemode/ClientMasterGameMode.h index 336663e7..e377861d 100644 --- a/src/Minecraft.World/net/minecraft/world/level/gamemode/ClientMasterGameMode.h +++ b/src/Minecraft.World/net/minecraft/world/level/gamemode/ClientMasterGameMode.h @@ -29,6 +29,8 @@ class ClientMasterGameMode : public CommonMasterGameMode { void GetLastCheckpointID(const StatsUID&) override; void OnProgressMade(const std::shared_ptr&, double) override; + bool isNewLevelDataPending(); + bool IsRoundRestarting(); unsigned char size[0x2E0 - 8]; diff --git a/src/Minecraft.World/net/minecraft/world/level/gamemode/CommonMasterGameMode.h b/src/Minecraft.World/net/minecraft/world/level/gamemode/CommonMasterGameMode.h index 3bc37d1a..3b63c759 100644 --- a/src/Minecraft.World/net/minecraft/world/level/gamemode/CommonMasterGameMode.h +++ b/src/Minecraft.World/net/minecraft/world/level/gamemode/CommonMasterGameMode.h @@ -89,7 +89,8 @@ class CommonMasterGameMode { void* qword150; void* qword158; void* qword160; - void* qword168; + int unk; + bool m_hasPendingLevelData; void* qword170; void* qword178; }; diff --git a/src/Minecraft.World/net/minecraft/world/level/storage/data/SparseDataStorage.cpp b/src/Minecraft.World/net/minecraft/world/level/storage/data/SparseDataStorage.cpp new file mode 100644 index 00000000..ab29c2b6 --- /dev/null +++ b/src/Minecraft.World/net/minecraft/world/level/storage/data/SparseDataStorage.cpp @@ -0,0 +1,18 @@ +#include "net/minecraft/world/level/storage/data/SparseDataStorage.h" + +// NON_MATCHING | Difference: 1830 +// The pseudocode is the same as CompressedBlockStorage, what's up with this? +void SparseDataStorage::tick() { + unsigned int idx = (sStackLength + 1) % 3; + XLockFreeStack* stack = &sStack[idx]; + + while (true) { + unsigned char* p = stack->Pop(); + if (!p) + break; + + free(p, 0); + } + + sStackLength = idx; +} diff --git a/src/Minecraft.World/net/minecraft/world/level/storage/data/SparseDataStorage.h b/src/Minecraft.World/net/minecraft/world/level/storage/data/SparseDataStorage.h index 1d91e534..52a1f5a3 100644 --- a/src/Minecraft.World/net/minecraft/world/level/storage/data/SparseDataStorage.h +++ b/src/Minecraft.World/net/minecraft/world/level/storage/data/SparseDataStorage.h @@ -1,10 +1,29 @@ #pragma once +#include "NX/Platform.h" +#include "XLockFreeStack.h" #include "java/io/DataOutputStream.h" class SparseDataStorage { public: + static unsigned int sStackLength; + static XLockFreeStack sStack[3]; + static unsigned int sLength; // ? + void write(DataOutputStream* out); void tick(); static void staticCtor(); + + // again???? + static void free(unsigned char* data, int len) { + XPhysicalFree(data); + sLength -= len; + } + + // 0x7100359E44 + // do they just keep copying these 2 methods everywhere??? + void* alloc(int len) { + sLength += len; + return malloc(len); + } }; diff --git a/src/Minecraft.World/net/minecraft/world/level/storage/light/SparseLightStorage.cpp b/src/Minecraft.World/net/minecraft/world/level/storage/light/SparseLightStorage.cpp new file mode 100644 index 00000000..3de280db --- /dev/null +++ b/src/Minecraft.World/net/minecraft/world/level/storage/light/SparseLightStorage.cpp @@ -0,0 +1,19 @@ +#include "net/minecraft/world/level/storage/light/SparseLightStorage.h" + +// NON_MATCHING | Difference: 2475 +// The pseudocode is the same as CompressedBlockStorage, what's up with this? +void SparseLightStorage::tick() { + unsigned int idx = (sStackLength + 1) % 3; + XLockFreeStack* stack = &sStack[idx]; + + while (true) { + unsigned char* p = stack->Pop(); + + if (!p) + break; + + free(p, 0); + } + + sStackLength = idx; +} diff --git a/src/Minecraft.World/net/minecraft/world/level/storage/light/SparseLightStorage.h b/src/Minecraft.World/net/minecraft/world/level/storage/light/SparseLightStorage.h index 19c5b031..e797e080 100644 --- a/src/Minecraft.World/net/minecraft/world/level/storage/light/SparseLightStorage.h +++ b/src/Minecraft.World/net/minecraft/world/level/storage/light/SparseLightStorage.h @@ -1,10 +1,32 @@ #pragma once +#include "XLockFreeStack.h" #include "java/io/DataOutputStream.h" class SparseLightStorage { public: + static unsigned int sStackLength; + static XLockFreeStack sStack[3]; + static unsigned int sLength; // ? + void write(DataOutputStream* out); static void staticCtor(); + void tick(); + bool isCompressed(); + + // again???? + static void free(unsigned char* data, int len) { + XPhysicalFree(data); + sLength -= len; + } + + // 0x710035BC18 + // do they just keep copying these 2 methods everywhere??? + static void* alloc(int len) { + sLength += len; + return malloc(len); + } + + std::atomic m_light; }; diff --git a/src/Minecraft.World/net/minecraft/world/phys/AABB.cpp b/src/Minecraft.World/net/minecraft/world/phys/AABB.cpp index cd18f0ce..254ba53b 100644 --- a/src/Minecraft.World/net/minecraft/world/phys/AABB.cpp +++ b/src/Minecraft.World/net/minecraft/world/phys/AABB.cpp @@ -20,11 +20,18 @@ AABB::AABB(double x1, double y1, double z1, double x2, double y2, double z2) { AABB* AABB::newPermanent(double x1, double y1, double z1, double x2, double y2, double z2) { return new AABB(x1, y1, z1, x2, y2, z2); } +AABB* AABB::newPermanent(const BlockPos& pos) { + return newPermanent(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); +} AABB* AABB::newPermanent(const AABB* other) { return newPermanent(other->minX, other->minY, other->minZ, other->maxX, other->maxY, other->maxZ); } +AABB* AABB::newPermanent(const BlockPos& lhs, const BlockPos& rhs) { + return newPermanent(lhs.getX(), lhs.getY(), lhs.getZ(), rhs.getX(), rhs.getY(), rhs.getZ()); +} + AABB* AABB::newTemp(double x1, double y1, double z1, double x2, double y2, double z2) { ThreadStorage* ts = ((ThreadStorage*)TlsGetValue(sThreadStorageIndex)); @@ -36,6 +43,18 @@ AABB* AABB::newTemp(double x1, double y1, double z1, double x2, double y2, doubl return temp; } +AABB* AABB::newTemp(const BlockPos& pos) { + return newTemp(pos.getX(), pos.getY(), pos.getZ(), pos.getX() + 1, pos.getY() + 1, pos.getZ() + 1); +} + +AABB* AABB::newTemp(const BlockPos& lhs, const BlockPos& rhs) { + return newTemp(lhs.getX(), lhs.getY(), lhs.getZ(), rhs.getX(), rhs.getY(), rhs.getZ()); +} + +AABB* AABB::newTemp(const AABB* aabb) { + return newTemp(aabb->minX, aabb->minY, aabb->minZ, aabb->maxX, aabb->maxY, aabb->maxZ); +} + AABB* AABB::set(double x1, double y1, double z1, double x2, double y2, double z2) { minX = std::min(x1, x2); minY = std::min(y1, y2); diff --git a/src/Minecraft.World/net/minecraft/world/phys/AABB.h b/src/Minecraft.World/net/minecraft/world/phys/AABB.h index 8c771aab..15749ad9 100644 --- a/src/Minecraft.World/net/minecraft/world/phys/AABB.h +++ b/src/Minecraft.World/net/minecraft/world/phys/AABB.h @@ -29,15 +29,20 @@ class AABB { static void ReleaseThreadStorage(); AABB() {} - AABB(double, double, double, double, double, double); + AABB(double x1, double y1, double z1, double x2, double y2, double z2); - static AABB* newPermanent(double, double, double, double, double, double); - static AABB* newPermanent(const AABB*); - static AABB* newTemp(double, double, double, double, double, double); + static AABB* newPermanent(double x1, double y1, double z1, double x2, double y2, double z2); + static AABB* newPermanent(const BlockPos& pos); + static AABB* newPermanent(const AABB* aabb); + static AABB* newPermanent(const BlockPos& lhs, const BlockPos& rhs); + static AABB* newTemp(double x1, double y1, double z1, double x2, double y2, double z2); + static AABB* newTemp(const BlockPos& pos); + static AABB* newTemp(const BlockPos& lhs, const BlockPos& rhs); + static AABB* newTemp(const AABB* aabb); bool containsIncludingLowerBound(Vec3*) const; AABB* set(const AABB*); - AABB* set(double, double, double, double, double, double); + AABB* set(double x1, double y1, double z1, double x2, double y2, double z2); Vec3* getCenter() const; AABB* divideInternalsBy(double); double getSize() const; @@ -46,7 +51,7 @@ class AABB { AABB* expand(double x, double y, double z) const; bool contains(Vec3* vec); bool intersects(const AABB* rhs) const; - bool intersects(double, double, double, double, double, double) const; + bool intersects(double x1, double y1, double z1, double x2, double y2, double z2) const; void resetPool(); AABB* move(const BlockPos&) const; AABB* move(double, double, double) const; diff --git a/src/types.h b/src/types.h index 8873f9d7..34c0b8c8 100644 --- a/src/types.h +++ b/src/types.h @@ -11,6 +11,20 @@ #define ASSERT_SIZEOF(Class, Size) #endif +// if a function is defined in the header but never used, it's not placed into the final binary +// this define is just an easy way to compile in the future with these missing until they're implemented +#ifdef UNUSED_DELETE +#define DELETE_EXTERNAL = delete // so we can define external methods found within Wii U Edition +#define DELETE_UNUSED = delete +#else +#define DELETE_EXTERNAL +#define DELETE_UNUSED +#endif + +// for types that don't exist in the original executable, and are simply just helpers for decomp code +// cleanliness +#define DECOMP_HELPER + template class not_null_ptr : public std::shared_ptr { public: