From 8865194e47b0c40392e1b40f158bd1bfeb7e6134 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Tue, 10 Mar 2026 21:59:51 +0100 Subject: [PATCH 01/22] uninitialized data --- Minecraft.Client/Platform/Common/UI/UIGroup.cpp | 5 +++-- debug.sh | 7 +++++++ run.sh | 7 +++++++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100755 debug.sh create mode 100755 run.sh diff --git a/Minecraft.Client/Platform/Common/UI/UIGroup.cpp b/Minecraft.Client/Platform/Common/UI/UIGroup.cpp index fbf76d20e..996d1f94d 100644 --- a/Minecraft.Client/Platform/Common/UI/UIGroup.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIGroup.cpp @@ -10,6 +10,9 @@ UIGroup::UIGroup(EUIGroup group, int iPad) m_bContainerMenuDisplayed = false; m_bIgnoreAutosaveMenuDisplayed = false; m_bIgnorePlayerJoinMenuDisplayed = false; + // 4jcraft, moved this to the top + // initialized memory was read. + m_viewportType = C4JRender::VIEWPORT_TYPE_FULLSCREEN; m_updateFocusStateCountdown = 0; @@ -39,8 +42,6 @@ UIGroup::UIGroup(EUIGroup group, int iPad) m_pressStartToPlay = (UIComponent_PressStartToPlay *)m_layers[(int)eUILayer_Tooltips]->addComponent(0, eUIComponent_PressStartToPlay); } - m_viewportType = C4JRender::VIEWPORT_TYPE_FULLSCREEN; - // 4J Stu - Pre-allocate this for cached rendering in scenes. It's horribly slow to do dynamically, but we should only need one // per group as we will only be displaying one of these types of scenes at a time m_commandBufferList = MemoryTracker::genLists(1); diff --git a/debug.sh b/debug.sh new file mode 100755 index 000000000..e2d2bc292 --- /dev/null +++ b/debug.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +meson setup build -Db_sanitize=address,leak,undefined -Dcpp_args=-fno-sanitize-recover=all -Dc_args=-fno-sanitize-recover=all && \ +meson compile -C build && \ +cd build/Minecraft.Client/ && \ +gdb -tui ./Minecraft.Client && \ +cd ../.. diff --git a/run.sh b/run.sh new file mode 100755 index 000000000..bd0a0c27b --- /dev/null +++ b/run.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +meson setup build -Db_sanitize=address,leak,undefined -Dcpp_args=-fno-sanitize-recover=all -Dc_args=-fno-sanitize-recover=all && \ +meson compile -C build && \ +cd build/Minecraft.Client/ && \ +UBSAN_OPTIONS=print_stacktrace=1 ./Minecraft.Client && \ +cd ../.. From a006cc5aa08aac20abb766ea433214c5515588c5 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Tue, 10 Mar 2026 23:22:34 +0100 Subject: [PATCH 02/22] uninitialized vptr the vptr to isSolidRender() is not known before contruction of the Tile. Its true by default. if false, need to pass false. that is what i did. i verfied what isSolidRender() is in every file. and did exactly what isSolidRender() would return --- Minecraft.Client/Platform/Common/UI/UIGroup.cpp | 2 +- Minecraft.World/Blocks/AnvilTile.cpp | 4 ++-- Minecraft.World/Blocks/BedTile.cpp | 4 ++-- Minecraft.World/Blocks/BrewingStandTile.cpp | 4 ++-- Minecraft.World/Blocks/ButtonTile.cpp | 2 +- Minecraft.World/Blocks/CactusTile.cpp | 2 +- Minecraft.World/Blocks/CakeTile.cpp | 4 ++-- Minecraft.World/Blocks/CauldronTile.cpp | 4 ++-- Minecraft.World/Blocks/ChestTile.cpp | 2 +- Minecraft.World/Blocks/CocoaTile.cpp | 4 ++-- Minecraft.World/Blocks/DiodeTile.cpp | 2 +- Minecraft.World/Blocks/DoorTile.cpp | 2 +- Minecraft.World/Blocks/EggTile.cpp | 4 ++-- Minecraft.World/Blocks/EnchantmentTableTile.cpp | 2 +- Minecraft.World/Blocks/EnderChestTile.cpp | 2 +- Minecraft.World/Blocks/FarmTile.cpp | 2 +- Minecraft.World/Blocks/FenceGateTile.cpp | 4 ++-- Minecraft.World/Blocks/FenceTile.cpp | 4 ++-- Minecraft.World/Blocks/FireTile.cpp | 2 +- Minecraft.World/Blocks/FlowerPotTile.cpp | 4 ++-- Minecraft.World/Blocks/HalfTransparentTile.cpp | 4 ++-- Minecraft.World/Blocks/LadderTile.cpp | 4 ++-- Minecraft.World/Blocks/LeafTile.cpp | 6 +++++- Minecraft.World/Blocks/LeverTile.cpp | 2 +- Minecraft.World/Blocks/LiquidTile.cpp | 2 +- Minecraft.World/Blocks/MobSpawnerTile.cpp | 4 ++-- Minecraft.World/Blocks/PistonBaseTile.cpp | 2 +- Minecraft.World/Blocks/PistonExtensionTile.cpp | 4 ++-- Minecraft.World/Blocks/PistonMovingTileEntity.cpp | 2 +- Minecraft.World/Blocks/PlantTile.cpp | 4 ++-- Minecraft.World/Blocks/PressurePlateTile.cpp | 4 ++-- Minecraft.World/Blocks/RailTile.cpp | 6 ++++-- Minecraft.World/Blocks/RedStoneDustTile.cpp | 2 +- Minecraft.World/Blocks/ReedTile.cpp | 2 +- Minecraft.World/Blocks/SignTile.cpp | 4 ++-- Minecraft.World/Blocks/SkullTile.cpp | 4 ++-- Minecraft.World/Blocks/StairTile.cpp | 2 +- Minecraft.World/Blocks/TheEndPortalFrameTile.cpp | 2 +- Minecraft.World/Blocks/TheEndPortalTile.cpp | 2 +- Minecraft.World/Blocks/ThinFenceTile.cpp | 2 +- Minecraft.World/Blocks/TopSnowTile.cpp | 2 +- Minecraft.World/Blocks/TorchTile.cpp | 2 +- Minecraft.World/Blocks/TrapDoorTile.cpp | 4 ++-- Minecraft.World/Blocks/TripWireSourceTile.cpp | 2 +- Minecraft.World/Blocks/TripWireTile.cpp | 2 +- Minecraft.World/Blocks/VineTile.cpp | 2 +- Minecraft.World/Blocks/WallTile.cpp | 2 +- Minecraft.World/Blocks/WoolCarpetTile.cpp | 2 +- 48 files changed, 74 insertions(+), 68 deletions(-) diff --git a/Minecraft.Client/Platform/Common/UI/UIGroup.cpp b/Minecraft.Client/Platform/Common/UI/UIGroup.cpp index 996d1f94d..7226ceb1c 100644 --- a/Minecraft.Client/Platform/Common/UI/UIGroup.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIGroup.cpp @@ -11,7 +11,7 @@ UIGroup::UIGroup(EUIGroup group, int iPad) m_bIgnoreAutosaveMenuDisplayed = false; m_bIgnorePlayerJoinMenuDisplayed = false; // 4jcraft, moved this to the top - // initialized memory was read. + // uninitialized memory was read. m_viewportType = C4JRender::VIEWPORT_TYPE_FULLSCREEN; m_updateFocusStateCountdown = 0; diff --git a/Minecraft.World/Blocks/AnvilTile.cpp b/Minecraft.World/Blocks/AnvilTile.cpp index 176f2de83..9b15e16fa 100644 --- a/Minecraft.World/Blocks/AnvilTile.cpp +++ b/Minecraft.World/Blocks/AnvilTile.cpp @@ -17,7 +17,7 @@ std::wstring AnvilTile::TEXTURE_DAMAGE_NAMES[ANVIL_NAMES_LENGTH] = { L"anvil_top", L"anvil_top_damaged_1", L"anvil_top_damaged_2" }; -AnvilTile::AnvilTile(int id) : HeavyTile(id, Material::heavyMetal, isSolidRender() ) +AnvilTile::AnvilTile(int id) : HeavyTile(id, Material::heavyMetal, false) { part = PART_BASE; setLightBlock(0); @@ -114,4 +114,4 @@ void AnvilTile::onLand(Level *level, int xt, int yt, int zt, int data) bool AnvilTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face) { return true; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/BedTile.cpp b/Minecraft.World/Blocks/BedTile.cpp index 5731310ff..527dd80c7 100644 --- a/Minecraft.World/Blocks/BedTile.cpp +++ b/Minecraft.World/Blocks/BedTile.cpp @@ -12,7 +12,7 @@ int BedTile::HEAD_DIRECTION_OFFSETS[4][2] = { 0, 1 }, { -1, 0 }, { 0, -1 }, { 1, 0 } }; -BedTile::BedTile(int id) : DirectionalTile(id, Material::cloth, isSolidRender()) +BedTile::BedTile(int id) : DirectionalTile(id, Material::cloth, false) { setShape(); @@ -329,4 +329,4 @@ int BedTile::getPistonPushReaction() int BedTile::cloneTileId(Level *level, int x, int y, int z) { return Item::bed_Id; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/BrewingStandTile.cpp b/Minecraft.World/Blocks/BrewingStandTile.cpp index 61119d164..e29eb4509 100644 --- a/Minecraft.World/Blocks/BrewingStandTile.cpp +++ b/Minecraft.World/Blocks/BrewingStandTile.cpp @@ -8,7 +8,7 @@ const std::wstring BrewingStandTile::TEXTURE_BASE = L"brewingStand_base"; -BrewingStandTile::BrewingStandTile(int id) : EntityTile(id, Material::metal, isSolidRender()) +BrewingStandTile::BrewingStandTile(int id) : EntityTile(id, Material::metal, false) { random = new Random(); iconBase = NULL; @@ -133,4 +133,4 @@ void BrewingStandTile::registerIcons(IconRegister *iconRegister) Icon *BrewingStandTile::getBaseTexture() { return iconBase; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/ButtonTile.cpp b/Minecraft.World/Blocks/ButtonTile.cpp index f388243d0..d228b343d 100644 --- a/Minecraft.World/Blocks/ButtonTile.cpp +++ b/Minecraft.World/Blocks/ButtonTile.cpp @@ -6,7 +6,7 @@ #include "ButtonTile.h" #include "../Util/SoundTypes.h" -ButtonTile::ButtonTile(int id, bool sensitive) : Tile(id, Material::decoration,isSolidRender()) +ButtonTile::ButtonTile(int id, bool sensitive) : Tile(id, Material::decoration, false) { this->setTicking(true); this->sensitive = sensitive; diff --git a/Minecraft.World/Blocks/CactusTile.cpp b/Minecraft.World/Blocks/CactusTile.cpp index 6c499e6bd..92f26b745 100644 --- a/Minecraft.World/Blocks/CactusTile.cpp +++ b/Minecraft.World/Blocks/CactusTile.cpp @@ -8,7 +8,7 @@ #include "../Headers/net.minecraft.world.h" #include "CactusTile.h" -CactusTile::CactusTile(int id) : Tile(id, Material::cactus,isSolidRender()) +CactusTile::CactusTile(int id) : Tile(id, Material::cactus, false) { setTicking(true); iconTop = NULL; diff --git a/Minecraft.World/Blocks/CakeTile.cpp b/Minecraft.World/Blocks/CakeTile.cpp index 95889f512..48ebb85de 100644 --- a/Minecraft.World/Blocks/CakeTile.cpp +++ b/Minecraft.World/Blocks/CakeTile.cpp @@ -9,7 +9,7 @@ #include "CakeTile.h" -CakeTile::CakeTile(int id) : Tile(id, Material::cake,isSolidRender()) +CakeTile::CakeTile(int id) : Tile(id, Material::cake, false) { setTicking(true); @@ -148,4 +148,4 @@ int CakeTile::getResource(int data, Random *random, int playerBonusLevel) int CakeTile::cloneTileId(Level *level, int x, int y, int z) { return Item::cake_Id; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/CauldronTile.cpp b/Minecraft.World/Blocks/CauldronTile.cpp index b4df52e9d..7b664b16f 100644 --- a/Minecraft.World/Blocks/CauldronTile.cpp +++ b/Minecraft.World/Blocks/CauldronTile.cpp @@ -11,7 +11,7 @@ const std::wstring CauldronTile::TEXTURE_INSIDE = L"cauldron_inner"; const std::wstring CauldronTile::TEXTURE_BOTTOM = L"cauldron_bottom"; -CauldronTile::CauldronTile(int id) : Tile(id, Material::metal, isSolidRender()) +CauldronTile::CauldronTile(int id) : Tile(id, Material::metal, false) { iconInner = NULL; iconTop = NULL; @@ -174,4 +174,4 @@ int CauldronTile::getResource(int data, Random *random, int playerBonusLevel) int CauldronTile::cloneTileId(Level *level, int x, int y, int z) { return Item::cauldron_Id; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/ChestTile.cpp b/Minecraft.World/Blocks/ChestTile.cpp index eb95e8f1a..1f4a87570 100644 --- a/Minecraft.World/Blocks/ChestTile.cpp +++ b/Minecraft.World/Blocks/ChestTile.cpp @@ -10,7 +10,7 @@ #include "../Util/Facing.h" #include "../Entities/Mobs/Ocelot.h" -ChestTile::ChestTile(int id) : EntityTile(id, Material::wood, isSolidRender() ) +ChestTile::ChestTile(int id) : EntityTile(id, Material::wood, false) { random = new Random(); diff --git a/Minecraft.World/Blocks/CocoaTile.cpp b/Minecraft.World/Blocks/CocoaTile.cpp index 6133be114..126994b7f 100644 --- a/Minecraft.World/Blocks/CocoaTile.cpp +++ b/Minecraft.World/Blocks/CocoaTile.cpp @@ -8,7 +8,7 @@ const std::wstring CocoaTile::TEXTURE_AGES[] = { L"cocoa_0", L"cocoa_1", L"cocoa_2"}; -CocoaTile::CocoaTile(int id) : DirectionalTile(id, Material::plant, isSolidRender() ) +CocoaTile::CocoaTile(int id) : DirectionalTile(id, Material::plant, false) { setTicking(true); } @@ -173,4 +173,4 @@ void CocoaTile::registerIcons(IconRegister *iconRegister) { icons[i] = iconRegister->registerIcon(TEXTURE_AGES[i]); } -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/DiodeTile.cpp b/Minecraft.World/Blocks/DiodeTile.cpp index 91ddbec31..8b857f4fb 100644 --- a/Minecraft.World/Blocks/DiodeTile.cpp +++ b/Minecraft.World/Blocks/DiodeTile.cpp @@ -9,7 +9,7 @@ const double DiodeTile::DELAY_RENDER_OFFSETS[4] = { -1.0f / 16.0f, 1.0f / 16.0f, 3.0f / 16.0f, 5.0f / 16.0f }; const int DiodeTile::DELAYS[4] = { 1, 2, 3, 4 }; -DiodeTile::DiodeTile(int id, bool on) : DirectionalTile(id, Material::decoration,isSolidRender()) +DiodeTile::DiodeTile(int id, bool on) : DirectionalTile(id, Material::decoration, false) { this->on = on; updateDefaultShape(); diff --git a/Minecraft.World/Blocks/DoorTile.cpp b/Minecraft.World/Blocks/DoorTile.cpp index c29dee295..203ec2175 100644 --- a/Minecraft.World/Blocks/DoorTile.cpp +++ b/Minecraft.World/Blocks/DoorTile.cpp @@ -10,7 +10,7 @@ const std::wstring DoorTile::TEXTURES[] = { L"doorWood_lower", L"doorWood_upper", L"doorIron_lower", L"doorIron_upper" }; -DoorTile::DoorTile(int id, Material *material) : Tile(id, material,isSolidRender()) +DoorTile::DoorTile(int id, Material *material) : Tile(id, material, false) { icons = NULL; diff --git a/Minecraft.World/Blocks/EggTile.cpp b/Minecraft.World/Blocks/EggTile.cpp index d108bb473..705ef05fb 100644 --- a/Minecraft.World/Blocks/EggTile.cpp +++ b/Minecraft.World/Blocks/EggTile.cpp @@ -4,7 +4,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "../Headers/net.minecraft.world.entity.item.h" -EggTile::EggTile(int id) : Tile(id, Material::egg, isSolidRender()) +EggTile::EggTile(int id) : Tile(id, Material::egg, false) { } @@ -170,4 +170,4 @@ void EggTile::generateTeleportParticles(Level *level,int xt,int yt, int zt,int d bool EggTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face) { return true; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/EnchantmentTableTile.cpp b/Minecraft.World/Blocks/EnchantmentTableTile.cpp index fc8485886..0ab63578f 100644 --- a/Minecraft.World/Blocks/EnchantmentTableTile.cpp +++ b/Minecraft.World/Blocks/EnchantmentTableTile.cpp @@ -9,7 +9,7 @@ const std::wstring EnchantmentTableTile::TEXTURE_SIDE = L"enchantment_side"; const std::wstring EnchantmentTableTile::TEXTURE_TOP = L"enchantment_top"; const std::wstring EnchantmentTableTile::TEXTURE_BOTTOM = L"enchantment_bottom"; -EnchantmentTableTile::EnchantmentTableTile(int id) : EntityTile(id, Material::stone, isSolidRender()) +EnchantmentTableTile::EnchantmentTableTile(int id) : EntityTile(id, Material::stone, false) { updateDefaultShape(); setLightBlock(0); diff --git a/Minecraft.World/Blocks/EnderChestTile.cpp b/Minecraft.World/Blocks/EnderChestTile.cpp index 650d2b538..2c2d77c84 100644 --- a/Minecraft.World/Blocks/EnderChestTile.cpp +++ b/Minecraft.World/Blocks/EnderChestTile.cpp @@ -7,7 +7,7 @@ #include "../Headers/net.minecraft.h" #include "EnderChestTile.h" -EnderChestTile::EnderChestTile(int id) : EntityTile(id, Material::stone, isSolidRender()) +EnderChestTile::EnderChestTile(int id) : EntityTile(id, Material::stone, false) { updateDefaultShape(); } diff --git a/Minecraft.World/Blocks/FarmTile.cpp b/Minecraft.World/Blocks/FarmTile.cpp index 582f3b41d..053529664 100644 --- a/Minecraft.World/Blocks/FarmTile.cpp +++ b/Minecraft.World/Blocks/FarmTile.cpp @@ -6,7 +6,7 @@ #include "FarmTile.h" -FarmTile::FarmTile(int id) : Tile(id, Material::dirt,isSolidRender()) +FarmTile::FarmTile(int id) : Tile(id, Material::dirt, false) { iconWet = NULL; iconDry = NULL; diff --git a/Minecraft.World/Blocks/FenceGateTile.cpp b/Minecraft.World/Blocks/FenceGateTile.cpp index 1dac0aca2..ac358dc98 100644 --- a/Minecraft.World/Blocks/FenceGateTile.cpp +++ b/Minecraft.World/Blocks/FenceGateTile.cpp @@ -5,7 +5,7 @@ #include "../Headers/net.minecraft.h" #include "../Level/Events/LevelEvent.h" -FenceGateTile::FenceGateTile(int id) : DirectionalTile(id, Material::wood, isSolidRender() ) +FenceGateTile::FenceGateTile(int id) : DirectionalTile(id, Material::wood, false) { } @@ -144,4 +144,4 @@ void FenceGateTile::registerIcons(IconRegister *iconRegister) bool FenceGateTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face) { return true; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/FenceTile.cpp b/Minecraft.World/Blocks/FenceTile.cpp index 2c974ba9d..7aa1e37e3 100644 --- a/Minecraft.World/Blocks/FenceTile.cpp +++ b/Minecraft.World/Blocks/FenceTile.cpp @@ -4,7 +4,7 @@ #include "../Headers/net.minecraft.world.h" #include "FenceTile.h" -FenceTile::FenceTile(int id, const std::wstring &texture, Material *material) : Tile( id, material, isSolidRender()) +FenceTile::FenceTile(int id, const std::wstring &texture, Material *material) : Tile( id, material, false) { this->texture = texture; } @@ -129,4 +129,4 @@ void FenceTile::registerIcons(IconRegister *iconRegister) bool FenceTile::shouldRenderFace(LevelSource *level, int x, int y, int z, int face) { return true; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/FireTile.cpp b/Minecraft.World/Blocks/FireTile.cpp index 614d9bcfa..fd422fa6a 100644 --- a/Minecraft.World/Blocks/FireTile.cpp +++ b/Minecraft.World/Blocks/FireTile.cpp @@ -16,7 +16,7 @@ const std::wstring FireTile::TEXTURE_FIRST = L"fire_0"; const std::wstring FireTile::TEXTURE_SECOND = L"fire_1"; -FireTile::FireTile(int id) : Tile(id, Material::fire,isSolidRender()) +FireTile::FireTile(int id) : Tile(id, Material::fire, false) { flameOdds = new int[256]; memset( flameOdds,0,sizeof(int)*256); diff --git a/Minecraft.World/Blocks/FlowerPotTile.cpp b/Minecraft.World/Blocks/FlowerPotTile.cpp index 45123e04a..aecac7d13 100644 --- a/Minecraft.World/Blocks/FlowerPotTile.cpp +++ b/Minecraft.World/Blocks/FlowerPotTile.cpp @@ -5,7 +5,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "FlowerPotTile.h" -FlowerPotTile::FlowerPotTile(int id) : Tile(id, Material::decoration, isSolidRender() ) +FlowerPotTile::FlowerPotTile(int id) : Tile(id, Material::decoration, false) { updateDefaultShape(); sendTileData(); @@ -189,4 +189,4 @@ int FlowerPotTile::getTypeFromItem(std::shared_ptr item) } return 0; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/HalfTransparentTile.cpp b/Minecraft.World/Blocks/HalfTransparentTile.cpp index 71580b08a..aad08fa5f 100644 --- a/Minecraft.World/Blocks/HalfTransparentTile.cpp +++ b/Minecraft.World/Blocks/HalfTransparentTile.cpp @@ -3,7 +3,7 @@ #include "../Headers/net.minecraft.world.h" #include "HalfTransparentTile.h" -HalfTransparentTile::HalfTransparentTile(int id, const std::wstring &tex, Material *material, bool allowSame) : Tile(id,material,isSolidRender()) +HalfTransparentTile::HalfTransparentTile(int id, const std::wstring &tex, Material *material, bool allowSame) : Tile(id,material, false) { this->allowSame = allowSame; this->texture = tex; @@ -29,4 +29,4 @@ bool HalfTransparentTile::blocksLight() void HalfTransparentTile::registerIcons(IconRegister *iconRegister) { icon = iconRegister->registerIcon(texture); -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/LadderTile.cpp b/Minecraft.World/Blocks/LadderTile.cpp index 89a26220a..6651e49a5 100644 --- a/Minecraft.World/Blocks/LadderTile.cpp +++ b/Minecraft.World/Blocks/LadderTile.cpp @@ -3,7 +3,7 @@ #include "LadderTile.h" -LadderTile::LadderTile(int id) : Tile(id, Material::decoration,isSolidRender()) +LadderTile::LadderTile(int id) : Tile(id, Material::decoration, false) { } @@ -109,4 +109,4 @@ void LadderTile::neighborChanged(Level *level, int x, int y, int z, int type) int LadderTile::getResourceCount(Random* random) { return 1; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/LeafTile.cpp b/Minecraft.World/Blocks/LeafTile.cpp index 82c9f42ed..fb235da5e 100644 --- a/Minecraft.World/Blocks/LeafTile.cpp +++ b/Minecraft.World/Blocks/LeafTile.cpp @@ -15,7 +15,11 @@ const unsigned int LeafTile::LEAF_NAMES[LEAF_NAMES_LENGTH] = { IDS_TILE_LEAVES_O const std::wstring LeafTile::TEXTURES[2][4] = { {L"leaves", L"leaves_spruce", L"leaves", L"leaves_jungle"}, {L"leaves_opaque", L"leaves_spruce_opaque", L"leaves_opaque", L"leaves_jungle_opaque"},}; -LeafTile::LeafTile(int id) : TransparentTile(id, Material::leaves, false, isSolidRender()) +// 4jcraft, this is the unitinialized vpointer fiassco of isSolidRender() +// isSolidRender() returns !allowSame if !isServerLevel, else true +// scince allowSame for TransparentTile right here is set to false +// setting isSolidRender to true by default totally correct. +LeafTile::LeafTile(int id) : TransparentTile(id, Material::leaves, false, true) { checkBuffer = NULL; fancyTextureSet = 0; diff --git a/Minecraft.World/Blocks/LeverTile.cpp b/Minecraft.World/Blocks/LeverTile.cpp index 235d8088e..57ac6936b 100644 --- a/Minecraft.World/Blocks/LeverTile.cpp +++ b/Minecraft.World/Blocks/LeverTile.cpp @@ -4,7 +4,7 @@ #include "LeverTile.h" #include "../Util/SoundTypes.h" -LeverTile::LeverTile(int id) : Tile(id, Material::decoration,isSolidRender()) +LeverTile::LeverTile(int id) : Tile(id, Material::decoration, false) { } diff --git a/Minecraft.World/Blocks/LiquidTile.cpp b/Minecraft.World/Blocks/LiquidTile.cpp index d90256c15..e460e757a 100644 --- a/Minecraft.World/Blocks/LiquidTile.cpp +++ b/Minecraft.World/Blocks/LiquidTile.cpp @@ -12,7 +12,7 @@ const std::wstring LiquidTile::TEXTURE_WATER_STILL = L"water"; const std::wstring LiquidTile::TEXTURE_WATER_FLOW = L"water_flow"; const std::wstring LiquidTile::TEXTURE_LAVA_FLOW = L"lava_flow"; -LiquidTile::LiquidTile(int id, Material *material) : Tile(id, material,isSolidRender()) +LiquidTile::LiquidTile(int id, Material *material) : Tile(id, material, false) { float yo = 0; float e = 0; diff --git a/Minecraft.World/Blocks/MobSpawnerTile.cpp b/Minecraft.World/Blocks/MobSpawnerTile.cpp index 5c645df9b..2ba906ffe 100644 --- a/Minecraft.World/Blocks/MobSpawnerTile.cpp +++ b/Minecraft.World/Blocks/MobSpawnerTile.cpp @@ -3,7 +3,7 @@ #include "../Headers/net.minecraft.world.level.tile.entity.h" #include "MobSpawnerTile.h" -MobSpawnerTile::MobSpawnerTile(int id) : EntityTile(id, Material::stone, isSolidRender() ) +MobSpawnerTile::MobSpawnerTile(int id) : EntityTile(id, Material::stone, false) { } @@ -46,4 +46,4 @@ void MobSpawnerTile::spawnResources(Level *level, int x, int y, int z, int data, int MobSpawnerTile::cloneTileId(Level *level, int x, int y, int z) { return 0; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/PistonBaseTile.cpp b/Minecraft.World/Blocks/PistonBaseTile.cpp index 786ee7069..5d75a398d 100644 --- a/Minecraft.World/Blocks/PistonBaseTile.cpp +++ b/Minecraft.World/Blocks/PistonBaseTile.cpp @@ -36,7 +36,7 @@ void PistonBaseTile::ignoreUpdate(bool set) TlsSetValue(tlsIdx,(LPVOID)(intptr_t)(set?1:0)); } -PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, isSolidRender() ) +PistonBaseTile::PistonBaseTile(int id, bool isSticky) : Tile(id, Material::piston, false) { // 4J - added initialiser ignoreUpdate(false); diff --git a/Minecraft.World/Blocks/PistonExtensionTile.cpp b/Minecraft.World/Blocks/PistonExtensionTile.cpp index 4a05ae127..3302ad75f 100644 --- a/Minecraft.World/Blocks/PistonExtensionTile.cpp +++ b/Minecraft.World/Blocks/PistonExtensionTile.cpp @@ -4,7 +4,7 @@ #include "../Util/Facing.h" #include "../Headers/net.minecraft.world.level.h" -PistonExtensionTile::PistonExtensionTile(int id) : Tile(id, Material::piston,isSolidRender() ) +PistonExtensionTile::PistonExtensionTile(int id) : Tile(id, Material::piston, false) { // 4J added initialiser overrideTopTexture = NULL; @@ -207,4 +207,4 @@ int PistonExtensionTile::getFacing(int data) int PistonExtensionTile::cloneTileId(Level *level, int x, int y, int z) { return 0; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp index 77e176d62..452669097 100644 --- a/Minecraft.World/Blocks/PistonMovingTileEntity.cpp +++ b/Minecraft.World/Blocks/PistonMovingTileEntity.cpp @@ -6,7 +6,7 @@ #include "../Util/Facing.h" #include "../Util/AABB.h" -PistonMovingPiece::PistonMovingPiece(int id) : EntityTile(id, Material::piston, isSolidRender() ) +PistonMovingPiece::PistonMovingPiece(int id) : EntityTile(id, Material::piston, false ) { setDestroyTime(INDESTRUCTIBLE_DESTROY_TIME); } diff --git a/Minecraft.World/Blocks/PlantTile.cpp b/Minecraft.World/Blocks/PlantTile.cpp index 0ecf94884..eb4d2dfca 100644 --- a/Minecraft.World/Blocks/PlantTile.cpp +++ b/Minecraft.World/Blocks/PlantTile.cpp @@ -9,12 +9,12 @@ void Bush::_init() updateDefaultShape(); } -Bush::Bush(int id, Material *material) : Tile(id, material, isSolidRender()) +Bush::Bush(int id, Material *material) : Tile(id, material, false) { _init(); } -Bush::Bush(int id) : Tile(id, Material::plant, isSolidRender()) +Bush::Bush(int id) : Tile(id, Material::plant, false) { _init(); } diff --git a/Minecraft.World/Blocks/PressurePlateTile.cpp b/Minecraft.World/Blocks/PressurePlateTile.cpp index 014e6330d..9f383b474 100644 --- a/Minecraft.World/Blocks/PressurePlateTile.cpp +++ b/Minecraft.World/Blocks/PressurePlateTile.cpp @@ -7,7 +7,7 @@ #include "PressurePlateTile.h" #include "../Util/SoundTypes.h" -PressurePlateTile::PressurePlateTile(int id, const std::wstring &tex, Material *material, Sensitivity sensitivity) : Tile(id, material, isSolidRender()) +PressurePlateTile::PressurePlateTile(int id, const std::wstring &tex, Material *material, Sensitivity sensitivity) : Tile(id, material, false) { this->sensitivity = sensitivity; this->setTicking(true); @@ -208,4 +208,4 @@ int PressurePlateTile::getPistonPushReaction() void PressurePlateTile::registerIcons(IconRegister *iconRegister) { icon = iconRegister->registerIcon(texture); -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/RailTile.cpp b/Minecraft.World/Blocks/RailTile.cpp index d89be45ac..67709722a 100644 --- a/Minecraft.World/Blocks/RailTile.cpp +++ b/Minecraft.World/Blocks/RailTile.cpp @@ -363,7 +363,9 @@ bool RailTile::isRail(int id) return id == Tile::rail_Id || id == Tile::goldenRail_Id || id == Tile::detectorRail_Id; } -RailTile::RailTile(int id, bool usesDataBit) : Tile(id, Material::decoration, isSolidRender()) +// 4jcraft, changed from isSolidRender() to false, _init was changed by 4jstudios +// to take in a bool to avoid calling isSolidRender before the vptr is set, +RailTile::RailTile(int id, bool usesDataBit) : Tile(id, Material::decoration, false) { this->usesDataBit = usesDataBit; this->setShape(0, 0, 0, 1, 2 / 16.0f, 1); @@ -673,4 +675,4 @@ void RailTile::registerIcons(IconRegister *iconRegister) { iconTurn = iconRegister->registerIcon(L"rail_turn"); } -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/RedStoneDustTile.cpp b/Minecraft.World/Blocks/RedStoneDustTile.cpp index 64d01ec2d..6133ac039 100644 --- a/Minecraft.World/Blocks/RedStoneDustTile.cpp +++ b/Minecraft.World/Blocks/RedStoneDustTile.cpp @@ -16,7 +16,7 @@ const std::wstring RedStoneDustTile::TEXTURE_LINE = L"redstoneDust_line"; const std::wstring RedStoneDustTile::TEXTURE_CROSS_OVERLAY = L"redstoneDust_cross_overlay"; const std::wstring RedStoneDustTile::TEXTURE_LINE_OVERLAY = L"redstoneDust_line_overlay"; -RedStoneDustTile::RedStoneDustTile(int id) : Tile(id, Material::decoration,isSolidRender()) +RedStoneDustTile::RedStoneDustTile(int id) : Tile(id, Material::decoration, false) { shouldSignal = true; diff --git a/Minecraft.World/Blocks/ReedTile.cpp b/Minecraft.World/Blocks/ReedTile.cpp index e4bca404a..287470757 100644 --- a/Minecraft.World/Blocks/ReedTile.cpp +++ b/Minecraft.World/Blocks/ReedTile.cpp @@ -6,7 +6,7 @@ #include "../Headers/net.minecraft.world.phys.h" #include "ReedTile.h" -ReedTile::ReedTile(int id) : Tile( id, Material::plant,isSolidRender() ) +ReedTile::ReedTile(int id) : Tile( id, Material::plant, false) { this->updateDefaultShape(); this->setTicking(true); diff --git a/Minecraft.World/Blocks/SignTile.cpp b/Minecraft.World/Blocks/SignTile.cpp index 0320b519e..8046b7df6 100644 --- a/Minecraft.World/Blocks/SignTile.cpp +++ b/Minecraft.World/Blocks/SignTile.cpp @@ -5,7 +5,7 @@ #include "TileEntities/SignTileEntity.h" #include "SignTile.h" -SignTile::SignTile(int id, eINSTANCEOF clas, bool onGround) : EntityTile(id, Material::wood, isSolidRender()) +SignTile::SignTile(int id, eINSTANCEOF clas, bool onGround) : EntityTile(id, Material::wood, false) { this->onGround = onGround; this->clas = clas; @@ -126,4 +126,4 @@ int SignTile::cloneTileId(Level *level, int x, int y, int z) void SignTile::registerIcons(IconRegister *iconRegister) { // None -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/SkullTile.cpp b/Minecraft.World/Blocks/SkullTile.cpp index 77d6711bd..bc17db5e6 100644 --- a/Minecraft.World/Blocks/SkullTile.cpp +++ b/Minecraft.World/Blocks/SkullTile.cpp @@ -5,7 +5,7 @@ #include "../Headers/net.minecraft.h" #include "SkullTile.h" -SkullTile::SkullTile(int id) : EntityTile(id, Material::decoration, isSolidRender() ) +SkullTile::SkullTile(int id) : EntityTile(id, Material::decoration, false) { setShape(4.0f / 16.0f, 0, 4.0f / 16.0f, 12.0f / 16.0f, .5f, 12.0f / 16.0f); } @@ -267,4 +267,4 @@ std::wstring SkullTile::getTileItemIconName() { return L""; //return SkullItem::ICON_NAMES[0]; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/StairTile.cpp b/Minecraft.World/Blocks/StairTile.cpp index dfefeb44a..eaf6ba2fe 100644 --- a/Minecraft.World/Blocks/StairTile.cpp +++ b/Minecraft.World/Blocks/StairTile.cpp @@ -10,7 +10,7 @@ int StairTile::DEAD_SPACES[8][2] = { {0, 4}, {1, 5}, {0, 1}, {4, 5} }; -StairTile::StairTile(int id, Tile *base,int basedata) : Tile(id, base->material, isSolidRender()) +StairTile::StairTile(int id, Tile *base,int basedata) : Tile(id, base->material, false) { this->base = base; this->basedata = basedata; diff --git a/Minecraft.World/Blocks/TheEndPortalFrameTile.cpp b/Minecraft.World/Blocks/TheEndPortalFrameTile.cpp index b574b902d..49c036865 100644 --- a/Minecraft.World/Blocks/TheEndPortalFrameTile.cpp +++ b/Minecraft.World/Blocks/TheEndPortalFrameTile.cpp @@ -6,7 +6,7 @@ const std::wstring TheEndPortalFrameTile::TEXTURE_EYE = L"endframe_eye"; -TheEndPortalFrameTile::TheEndPortalFrameTile(int id) : Tile(id, Material::glass, isSolidRender() ) +TheEndPortalFrameTile::TheEndPortalFrameTile(int id) : Tile(id, Material::glass, false ) { iconTop = NULL; iconEye = NULL; diff --git a/Minecraft.World/Blocks/TheEndPortalTile.cpp b/Minecraft.World/Blocks/TheEndPortalTile.cpp index 967acae3d..3d94380eb 100644 --- a/Minecraft.World/Blocks/TheEndPortalTile.cpp +++ b/Minecraft.World/Blocks/TheEndPortalTile.cpp @@ -21,7 +21,7 @@ void TheEndPortal::allowAnywhere(bool set) TlsSetValue(tlsIdx,(LPVOID)(intptr_t)(set?1:0)); } -TheEndPortal::TheEndPortal(int id, Material *material) : EntityTile(id, material, isSolidRender()) +TheEndPortal::TheEndPortal(int id, Material *material) : EntityTile(id, material, false) { this->setLightEmission(1.0f); } diff --git a/Minecraft.World/Blocks/ThinFenceTile.cpp b/Minecraft.World/Blocks/ThinFenceTile.cpp index 5e2fe3c50..4ca3dbb78 100644 --- a/Minecraft.World/Blocks/ThinFenceTile.cpp +++ b/Minecraft.World/Blocks/ThinFenceTile.cpp @@ -3,7 +3,7 @@ #include "../Headers/net.minecraft.world.level.h" #include "../Headers/net.minecraft.world.h" -ThinFenceTile::ThinFenceTile(int id, const std::wstring &tex, const std::wstring &edgeTex, Material *material, bool dropsResources) : Tile(id, material,isSolidRender()) +ThinFenceTile::ThinFenceTile(int id, const std::wstring &tex, const std::wstring &edgeTex, Material *material, bool dropsResources) : Tile(id, material, false) { iconSide = NULL; edgeTexture = edgeTex; diff --git a/Minecraft.World/Blocks/TopSnowTile.cpp b/Minecraft.World/Blocks/TopSnowTile.cpp index 9f0d9dbfa..e067cd0a2 100644 --- a/Minecraft.World/Blocks/TopSnowTile.cpp +++ b/Minecraft.World/Blocks/TopSnowTile.cpp @@ -13,7 +13,7 @@ const int TopSnowTile::MAX_HEIGHT = 6; const int TopSnowTile::HEIGHT_MASK = 7; // max 8 steps -TopSnowTile::TopSnowTile(int id) : Tile(id, Material::topSnow,isSolidRender()) +TopSnowTile::TopSnowTile(int id) : Tile(id, Material::topSnow, false) { setShape(0, 0, 0, 1, 2 / 16.0f, 1); setTicking(true); diff --git a/Minecraft.World/Blocks/TorchTile.cpp b/Minecraft.World/Blocks/TorchTile.cpp index d259a4916..8ab8e7f63 100644 --- a/Minecraft.World/Blocks/TorchTile.cpp +++ b/Minecraft.World/Blocks/TorchTile.cpp @@ -4,7 +4,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "TorchTile.h" -TorchTile::TorchTile(int id) : Tile(id, Material::decoration,isSolidRender()) +TorchTile::TorchTile(int id) : Tile(id, Material::decoration, false) { this->setTicking(true); } diff --git a/Minecraft.World/Blocks/TrapDoorTile.cpp b/Minecraft.World/Blocks/TrapDoorTile.cpp index 5af824b57..969d77092 100644 --- a/Minecraft.World/Blocks/TrapDoorTile.cpp +++ b/Minecraft.World/Blocks/TrapDoorTile.cpp @@ -6,7 +6,7 @@ #include "TrapDoorTile.h" -TrapDoorTile::TrapDoorTile(int id, Material *material) : Tile(id, material,isSolidRender()) +TrapDoorTile::TrapDoorTile(int id, Material *material) : Tile(id, material, false) { float r = 0.5f; float h = 1.0f; @@ -206,4 +206,4 @@ bool TrapDoorTile::attachesTo(int id) Tile *tile = Tile::tiles[id]; return tile != NULL && (tile->material->isSolidBlocking() && tile->isCubeShaped()) || tile == Tile::lightGem || (dynamic_cast(tile) != NULL) || (dynamic_cast(tile) != NULL); -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/TripWireSourceTile.cpp b/Minecraft.World/Blocks/TripWireSourceTile.cpp index 6550549a3..45e7f2d17 100644 --- a/Minecraft.World/Blocks/TripWireSourceTile.cpp +++ b/Minecraft.World/Blocks/TripWireSourceTile.cpp @@ -4,7 +4,7 @@ #include "../Headers/net.minecraft.world.level.tile.h" #include "TripWireSourceTile.h" -TripWireSourceTile::TripWireSourceTile(int id) : Tile(id, Material::decoration, isSolidRender()) +TripWireSourceTile::TripWireSourceTile(int id) : Tile(id, Material::decoration, false) { this->setTicking(true); } diff --git a/Minecraft.World/Blocks/TripWireTile.cpp b/Minecraft.World/Blocks/TripWireTile.cpp index 80242a0a7..54916674f 100644 --- a/Minecraft.World/Blocks/TripWireTile.cpp +++ b/Minecraft.World/Blocks/TripWireTile.cpp @@ -5,7 +5,7 @@ #include "../Headers/net.minecraft.world.phys.h" #include "TripWireTile.h" -TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, isSolidRender()) +TripWireTile::TripWireTile(int id) : Tile(id, Material::decoration, false) { setShape(0, 0, 0, 1, 2.5f / 16.0f, 1); this->setTicking(true); diff --git a/Minecraft.World/Blocks/VineTile.cpp b/Minecraft.World/Blocks/VineTile.cpp index 6674fd2fe..9c5cf77e7 100644 --- a/Minecraft.World/Blocks/VineTile.cpp +++ b/Minecraft.World/Blocks/VineTile.cpp @@ -8,7 +8,7 @@ #include "../Headers/net.minecraft.stats.h" #include "../Headers/net.minecraft.world.level.biome.h" -VineTile::VineTile(int id) : Tile(id, Material::replaceable_plant, isSolidRender() ) +VineTile::VineTile(int id) : Tile(id, Material::replaceable_plant, false) { setTicking(true); } diff --git a/Minecraft.World/Blocks/WallTile.cpp b/Minecraft.World/Blocks/WallTile.cpp index 5e75576e0..9389ec9e3 100644 --- a/Minecraft.World/Blocks/WallTile.cpp +++ b/Minecraft.World/Blocks/WallTile.cpp @@ -15,7 +15,7 @@ const unsigned int WallTile::COBBLE_NAMES[2] = { IDS_TILE_COBBLESTONE_WALL, IDS_TILE_COBBLESTONE_WALL_MOSSY, }; -WallTile::WallTile(int id, Tile *baseTile) : Tile(id, baseTile->material, isSolidRender()) +WallTile::WallTile(int id, Tile *baseTile) : Tile(id, baseTile->material, false) { setDestroyTime(baseTile->destroySpeed); setExplodeable(baseTile->explosionResistance / 3); diff --git a/Minecraft.World/Blocks/WoolCarpetTile.cpp b/Minecraft.World/Blocks/WoolCarpetTile.cpp index 14f8847ce..e3ff5cde1 100644 --- a/Minecraft.World/Blocks/WoolCarpetTile.cpp +++ b/Minecraft.World/Blocks/WoolCarpetTile.cpp @@ -4,7 +4,7 @@ #include "../Util/SharedConstants.h" #include "WoolCarpetTile.h" -WoolCarpetTile::WoolCarpetTile(int id) : Tile(id, Material::clothDecoration, isSolidRender() ) +WoolCarpetTile::WoolCarpetTile(int id) : Tile(id, Material::clothDecoration, false) { setShape(0, 0, 0, 1, 1 / 16.0f, 1); setTicking(true); From dfb200d037c7518694946040bd10a1915933b5f5 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 00:26:31 +0100 Subject: [PATCH 03/22] integer oferflow, shift of negative value --- Minecraft.World/Recipes/Recipes.cpp | 2 +- Minecraft.World/Recipes/ShapedRecipy.cpp | 8 ++++++-- Minecraft.World/Recipes/ShapelessRecipy.cpp | 5 +++-- Minecraft.World/Util/Random.cpp | 4 +++- 4 files changed, 13 insertions(+), 6 deletions(-) diff --git a/Minecraft.World/Recipes/Recipes.cpp b/Minecraft.World/Recipes/Recipes.cpp index 206b62ef3..66eab96cd 100644 --- a/Minecraft.World/Recipes/Recipes.cpp +++ b/Minecraft.World/Recipes/Recipes.cpp @@ -1217,4 +1217,4 @@ void Recipes::buildRecipeIngredientsArray(void) Recipy::INGREDIENTS_REQUIRED *Recipes::getRecipeIngredientsArray(void) { return m_pRecipeIngredientsRequired; -} \ No newline at end of file +} diff --git a/Minecraft.World/Recipes/ShapedRecipy.cpp b/Minecraft.World/Recipes/ShapedRecipy.cpp index 65a1c7d68..b33d10153 100644 --- a/Minecraft.World/Recipes/ShapedRecipy.cpp +++ b/Minecraft.World/Recipes/ShapedRecipy.cpp @@ -141,11 +141,14 @@ void ShapedRecipy::requires(INGREDIENTS_REQUIRED *pIngReq) TempIngReq.iIngC=0; TempIngReq.iType = ((width>2) ||(height>2))?RECIPE_TYPE_3x3:RECIPE_TYPE_2x2; // 3x3 // 3x3 + // 4jcraft, genuinly what is this garbage code TempIngReq.uiGridA = new unsigned int [9]; TempIngReq.iIngIDA= new int [9]; TempIngReq.iIngValA = new int [9]; TempIngReq.iIngAuxValA = new int [9]; + // 4jcraft,yes, yes!! + // use winapi and inbetween use a cstd function u could have used! ZeroMemory(TempIngReq.iIngIDA,sizeof(int)*9); ZeroMemory(TempIngReq.iIngValA,sizeof(int)*9); memset(TempIngReq.iIngAuxValA,Recipes::ANY_AUX_VALUE,sizeof(int)*9); @@ -162,7 +165,8 @@ void ShapedRecipy::requires(INGREDIENTS_REQUIRED *pIngReq) if (expected!=NULL) { int iAuxVal = expected->getAuxValue(); - TempIngReq.uiGridA[x+y*3]=expected->id | iAuxVal<<24; + //4jcraft, added cast to uint (shift of negativ num, undefined) + TempIngReq.uiGridA[x+y*3]=expected->id | (unsigned int) iAuxVal<<24; bFound=false; for(j=0;jgetAuxValue(); - TempIngReq.uiGridA[iCount++]=expected->id | iAuxVal<<24; + //4jcraft, added cast to uint, shift of negative int is undefined + TempIngReq.uiGridA[iCount++]=expected->id | (unsigned int) iAuxVal<<24; // 4J-PB - put the ingredients in boxes 1,2,4,5 so we can see them in a 2x2 crafting screen if(iCount==2) iCount=3; bFound=false; @@ -179,4 +180,4 @@ void ShapelessRecipy::requires(INGREDIENTS_REQUIRED *pIngReq) delete [] TempIngReq.iIngValA; delete [] TempIngReq.iIngAuxValA; delete [] TempIngReq.uiGridA; -} \ No newline at end of file +} diff --git a/Minecraft.World/Util/Random.cpp b/Minecraft.World/Util/Random.cpp index 5be1d53d3..00c4403aa 100644 --- a/Minecraft.World/Util/Random.cpp +++ b/Minecraft.World/Util/Random.cpp @@ -33,7 +33,9 @@ void Random::setSeed(__int64 s) int Random::next(int bits) { - seed = (seed * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); + // 4jcraft, cast to uint64_t for modulo arithmethic + // overflow of int undefined, and its guaranteed here. + seed = ((uint64_t) seed * 0x5DEECE66DLL + 0xBLL) & ((1LL << 48) - 1); return (int)(seed >> (48 - bits)); } From e76ec32824a425c2cb590beda67f74db1485b0ad Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 03:24:46 +0100 Subject: [PATCH 04/22] dangerous alignment issues the processDLCData() fn, was constantly casting a raw byte pointer to scalars/structs, replaced those calls with memcpy, also optimized and improved the guards for __linux__ at the top of the file --- .../Platform/Common/DLC/DLCManager.cpp | 148 ++++++++++++------ 1 file changed, 104 insertions(+), 44 deletions(-) diff --git a/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp b/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp index f4f74fb4c..030030ddb 100644 --- a/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp +++ b/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp @@ -7,25 +7,50 @@ #include "../../Minecraft.Client/Minecraft.h" #include "../../Minecraft.Client/Textures/Packs/TexturePackRepository.h" -#ifdef __linux__ -#include -static const size_t DLC_WCHAR_BINARY = 2; -static std::wstring dlc_read_wstring(const void *data) +// 4jcraft, this is the size of wchar_t on disk +// the DLC was created on windows, with wchar_t beeing 2 bytes and UTF-16 +static const size_t DLC_WCHAR_BIN_SIZE = 2; + +#if WCHAR_MAX > 0xFFFF +// than sizeof(WCHAR) != DLC_WCHAR_BIN_SIZE +// e.g. Linux and all Posix/Unix systems with wchar_t beeing 4B/32bit +static_assert( sizeof(wchar_t) == 4, "wchar_t is not 4bytes but larger than 2bytes ???"); + +static inline std::wstring dlc_read_wstring(const void *data) { - const uint16_t *p = (const uint16_t *)data; - std::wstring s; - while (*p) s += (wchar_t)*p++; - return s; + const uint16_t* p = (const uint16_t *)data; + // find the end (nullterminated) + const uint16_t* end = p; + while(*end) { + ++end; + } + + size_t len = end - p; + + // allocate wstring with length len + // it will be nullterminated internally, do not worry. + std::wstring out(len, 0); + + // and copy them into thje string + for(size_t i = 0; i < len; ++i) { + out[i] = (wchar_t) p[i]; + } + + return out; } + #define DLC_WSTRING(ptr) dlc_read_wstring(ptr) -#define DLC_PARAM_ADV(n) (sizeof(C4JStorage::DLC_FILE_PARAM) + (n) * DLC_WCHAR_BINARY) -#define DLC_DETAIL_ADV(n) (sizeof(C4JStorage::DLC_FILE_DETAILS) + (n) * DLC_WCHAR_BINARY) + #else -#define DLC_WSTRING(ptr) std::wstring((WCHAR *)(ptr)) -#define DLC_PARAM_ADV(n) (sizeof(C4JStorage::DLC_FILE_PARAM) + sizeof(WCHAR) * (n)) -#define DLC_DETAIL_ADV(n) (sizeof(C4JStorage::DLC_FILE_DETAILS) + sizeof(WCHAR) * (n)) +// just in case. +static_assert( sizeof(wchar_t) == 2, "How did we get here? wide char smaller than 2 bytes"); +// perfectly fine scince wchar_t will be 2 bytes (UCS-2/UTF-16) +#define DLC_WSTRING(ptr) std::wstring((wchar_t*)(ptr)) #endif +#define DLC_PARAM_ADV(n) (sizeof(C4JStorage::DLC_FILE_PARAM) + (n) * DLC_WCHAR_BIN_SIZE) +#define DLC_DETAIL_ADV(n) (sizeof(C4JStorage::DLC_FILE_DETAILS) + (n) * DLC_WCHAR_BIN_SIZE) + const WCHAR *DLCManager::wchTypeNamesA[]= { L"DISPLAYNAME", @@ -385,6 +410,18 @@ bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const std::string &pat return processDLCDataFile(dwFilesProcessed, pbData, bytesRead, pack); } +// a bunch of makros to reduce memcpy and offset boilerplate +#define DLC_READ_DWORD(buf, off) ({ DWORD _temp; memcpy(&_temp, (buf) + (off), sizeof(DWORD)); _temp; }) + +#define DLC_READ_PARAM(out, buf, off) memcpy((out), (buf) + (off), sizeof(C4JStorage::DLC_FILE_PARAM)) + +#define DLC_READ_DETAIL(out, buf, off) memcpy((out), (buf) + (off), sizeof(C4JStorage::DLC_FILE_DETAILS)) + +// for details, read below in the function below +#define DLC_PARAM_WSTR(buf, off) DLC_WSTRING((buf) + (off) + offsetof(C4JStorage::DLC_FILE_PARAM, wchData)) + +#define DLC_DETAIL_WSTR(buf, off) DLC_WSTRING((buf) + (off) + offsetof(C4JStorage::DLC_FILE_DETAILS, wchFile)) + bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dwLength, DLCPack *pack) { std::unordered_map parameterMapping; @@ -401,6 +438,22 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD // // unsigned long, p = number of parameters // // p * DLC_FILE_PARAM describing each parameter for this file // // ulFileSize bytes of data blob of the file added + + // 4jcraft, some parts of this code changed, specifically: + // instead of casting a goddamn raw byte pointer and dereferencing it + // use memcpy, and access WSTRING with propper offset + // (scince bufferoffset after advancing by variable string length is not + // guaranteed to be properly aligned, so casting to a scalar/struct is UB) + + // those casts are dangerous and will crash on ARM cpus when the pointers are + // not properly aligned at the offset. this includes for casting into the storage + // structs and casting into an unsigned integer + // everything else is aquivalent. i did not concern myself with the fact that + // EOF was not checked a single time. the lion doesnt bother with making code safe. + + // WHO TF USES HUNGARIAN NOTATION + + // safe, offset 0, aligned unsigned int uiVersion=*(unsigned int *)pbData; uiCurrentByte+=sizeof(int); @@ -411,40 +464,45 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD return false; } pack->SetDataPointer(pbData); + // safe, offset 4, aligned unsigned int uiParameterCount=*(unsigned int *)&pbData[uiCurrentByte]; uiCurrentByte+=sizeof(int); - C4JStorage::DLC_FILE_PARAM *pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; + + C4JStorage::DLC_FILE_PARAM parBuf; + DLC_READ_PARAM(&parBuf, pbData, uiCurrentByte); //DWORD dwwchCount=0; for(unsigned int i=0;iwchData); + std::wstring parameterName = DLC_PARAM_WSTR(pbData, uiCurrentByte); DLCManager::EDLCParameterType type = DLCManager::getParameterType(parameterName); if( type != DLCManager::e_DLCParamType_Invalid ) { - parameterMapping[pParams->dwType] = type; + parameterMapping[parBuf.dwType] = type; } - uiCurrentByte+= DLC_PARAM_ADV(pParams->dwWchCount); - pParams = (C4JStorage::DLC_FILE_PARAM *)&pbData[uiCurrentByte]; + uiCurrentByte+= DLC_PARAM_ADV(parBuf.dwWchCount); + DLC_READ_PARAM(&parBuf, pbData, uiCurrentByte); } //ulCurrentByte+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM); - unsigned int uiFileCount=*(unsigned int *)&pbData[uiCurrentByte]; + unsigned int uiFileCount = DLC_READ_DWORD(pbData, uiCurrentByte); uiCurrentByte+=sizeof(int); - C4JStorage::DLC_FILE_DETAILS *pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte]; + + C4JStorage::DLC_FILE_DETAILS fileBuf; + DLC_READ_DETAIL(&fileBuf, pbData, uiCurrentByte); DWORD dwTemp=uiCurrentByte; for(unsigned int i=0;idwWchCount); - pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[dwTemp]; + dwTemp+=DLC_DETAIL_ADV(fileBuf.dwWchCount); + DLC_READ_DETAIL(&fileBuf, pbData, dwTemp); } - PBYTE pbTemp=((PBYTE )pFile);//+ sizeof(C4JStorage::DLC_FILE_DETAILS)*ulFileCount; - pFile = (C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte]; + PBYTE pbTemp=&pbData[dwTemp];//+ sizeof(C4JStorage::DLC_FILE_DETAILS)*ulFileCount; + DLC_READ_DETAIL(&fileBuf, pbData, uiCurrentByte); for(unsigned int i=0;idwType; + DLCManager::EDLCType type = (DLCManager::EDLCType)fileBuf.dwType; DLCFile *dlcFile = NULL; DLCPack *dlcTexturePack = NULL; @@ -455,40 +513,41 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD } else if(type != e_DLCType_PackConfig) { - dlcFile = pack->addFile(type, DLC_WSTRING(pFile->wchFile)); + dlcFile = pack->addFile(type, DLC_DETAIL_WSTR(pbData, uiCurrentByte)); } // Params - uiParameterCount=*(unsigned int *)pbTemp; + unsigned int uiParamCount = DLC_READ_DWORD(pbTemp, 0); pbTemp+=sizeof(int); - pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; - for(unsigned int j=0;jdwType )); + AUTO_VAR(it, parameterMapping.find( parBuf.dwType )); if(it != parameterMapping.end() ) { if(type == e_DLCType_PackConfig) { - pack->addParameter(it->second, DLC_WSTRING(pParams->wchData)); + pack->addParameter(it->second, DLC_PARAM_WSTR(pbTemp, 0)); } else { - if(dlcFile != NULL) dlcFile->addParameter(it->second, DLC_WSTRING(pParams->wchData)); - else if(dlcTexturePack != NULL) dlcTexturePack->addParameter(it->second, DLC_WSTRING(pParams->wchData)); + if(dlcFile != NULL) dlcFile->addParameter(it->second, DLC_PARAM_WSTR(pbTemp, 0)); + else if(dlcTexturePack != NULL) dlcTexturePack->addParameter(it->second, DLC_PARAM_WSTR(pbTemp, 0)); } } - pbTemp+=DLC_PARAM_ADV(pParams->dwWchCount); - pParams = (C4JStorage::DLC_FILE_PARAM *)pbTemp; + pbTemp+=DLC_PARAM_ADV(parBuf.dwWchCount); + DLC_READ_PARAM(&parBuf, pbTemp, 0); } //pbTemp+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM); if(dlcTexturePack != NULL) { DWORD texturePackFilesProcessed = 0; - bool validPack = processDLCDataFile(texturePackFilesProcessed,pbTemp,pFile->uiFileSize,dlcTexturePack); + bool validPack = processDLCDataFile(texturePackFilesProcessed,pbTemp,fileBuf.uiFileSize,dlcTexturePack); pack->SetDataPointer(NULL); // If it's a child pack, it doesn't own the data if(!validPack || texturePackFilesProcessed == 0) { @@ -509,13 +568,13 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD else if(dlcFile != NULL) { // Data - dlcFile->addData(pbTemp,pFile->uiFileSize); + dlcFile->addData(pbTemp,fileBuf.uiFileSize); // TODO - 4J Stu Remove the need for this vSkinNames vector, or manage it differently - switch(pFile->dwType) + switch(fileBuf.dwType) { case DLCManager::e_DLCType_Skin: - app.vSkinNames.push_back(DLC_WSTRING(pFile->wchFile)); + app.vSkinNames.push_back(DLC_DETAIL_WSTR(pbData, uiCurrentByte)); break; } @@ -523,10 +582,10 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD } // Move the pointer to the start of the next files data; - pbTemp+=pFile->uiFileSize; - uiCurrentByte+=DLC_DETAIL_ADV(pFile->dwWchCount); + pbTemp+=fileBuf.uiFileSize; + uiCurrentByte+=DLC_DETAIL_ADV(fileBuf.dwWchCount); - pFile=(C4JStorage::DLC_FILE_DETAILS *)&pbData[uiCurrentByte]; + DLC_READ_DETAIL(&fileBuf, pbData, uiCurrentByte); } if( pack->getDLCItemsCount(DLCManager::e_DLCType_GameRules) > 0 @@ -565,7 +624,8 @@ DWORD DLCManager::retrievePackIDFromDLCDataFile(const std::string &path, DLCPack return 0; } - DWORD bytesRead,dwFileSize = GetFileSize(file,NULL); + DWORD bytesRead; + DWORD dwFileSize = GetFileSize(file,NULL); PBYTE pbData = (PBYTE) new BYTE[dwFileSize]; BOOL bSuccess = ReadFile(file,pbData,dwFileSize,&bytesRead,NULL); if(bSuccess==FALSE) @@ -688,4 +748,4 @@ DWORD DLCManager::retrievePackID(PBYTE pbData, DWORD dwLength, DLCPack *pack) parameterMapping.clear(); return packId; -} \ No newline at end of file +} From caadcfe9db9b9d791ac3babeb1298eee3c72d2a4 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 03:45:56 +0100 Subject: [PATCH 05/22] faulty casts of templated classes --- .../Common/GameRules/ConsoleSchematicFile.cpp | 23 ++++++++++++------- .../TileEntities/BrewingStandTileEntity.cpp | 9 ++++---- .../Blocks/TileEntities/ChestTileEntity.cpp | 10 +++++--- .../Blocks/TileEntities/FurnaceTileEntity.cpp | 9 +++++--- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index f8af5039a..c4111da11 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -109,13 +109,15 @@ void ConsoleSchematicFile::load(DataInputStream *dis) } // READ TAGS // + // 4jcraft, fixed cast of templated List to get the tag list + // and cast it to CompoundTag inside the loop CompoundTag *tag = NbtIo::read(dis); - ListTag *tileEntityTags = (ListTag *) tag->getList(L"TileEntities"); + ListTag *tileEntityTags = tag->getList(L"TileEntities"); if (tileEntityTags != NULL) { for (int i = 0; i < tileEntityTags->size(); i++) { - CompoundTag *teTag = tileEntityTags->get(i); + CompoundTag *teTag = (CompoundTag*) tileEntityTags->get(i); std::shared_ptr te = TileEntity::loadStatic(teTag); if(te == NULL) @@ -131,18 +133,23 @@ void ConsoleSchematicFile::load(DataInputStream *dis) } } } - ListTag *entityTags = (ListTag *) tag->getList(L"Entities"); + + // 4jcraft, fixed cast of templated List to get the tag list + // and cast it to CompoundTag inside the loop + ListTag *entityTags = tag->getList(L"Entities"); if (entityTags != NULL) { for (int i = 0; i < entityTags->size(); i++) { - CompoundTag *eTag = entityTags->get(i); + CompoundTag *eTag = (CompoundTag*) entityTags->get(i); eINSTANCEOF type = EntityIO::getType(eTag->getString(L"id")); - ListTag *pos = (ListTag *) eTag->getList(L"Pos"); - double x = pos->get(0)->data; - double y = pos->get(1)->data; - double z = pos->get(2)->data; + // 4jcraft, same here + ListTag *pos = eTag->getList(L"Pos"); + + double x = ((DoubleTag*) pos->get(0))->data; + double y = ((DoubleTag*) pos->get(1))->data; + double z = ((DoubleTag*) pos->get(2))->data; if( type == eTYPE_PAINTING || type == eTYPE_ITEM_FRAME ) { diff --git a/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.cpp index c035176d7..9a9971b25 100644 --- a/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/BrewingStandTileEntity.cpp @@ -283,12 +283,13 @@ void BrewingStandTileEntity::load(CompoundTag *base) { TileEntity::load(base); - ListTag *inventoryList = (ListTag *) base->getList(L"Items"); - delete [] items.data; + ListTag *inventoryList = base->getList(L"Items"); + + delete [] items.data; items = ItemInstanceArray(getContainerSize()); for (int i = 0; i < inventoryList->size(); i++) { - CompoundTag *tag = inventoryList->get(i); + CompoundTag *tag = (CompoundTag*) inventoryList->get(i); int slot = tag->getByte(L"Slot"); if (slot >= 0 && slot < items.length) items[slot] = ItemInstance::fromTag(tag); } @@ -430,4 +431,4 @@ std::shared_ptr BrewingStandTileEntity::clone() } } return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp index 834ff4ed5..820aa482d 100644 --- a/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/ChestTileEntity.cpp @@ -95,7 +95,11 @@ int ChestTileEntity::getName() void ChestTileEntity::load(CompoundTag *base) { TileEntity::load(base); - ListTag *inventoryList = (ListTag *) base->getList(L"Items"); + + // 4jcraft, fixed cast of templated List to get the tag list + // and cast it to CompoundTag inside the loop + ListTag *inventoryList = base->getList(L"Items"); + if( items ) { delete [] items->data; @@ -104,7 +108,7 @@ void ChestTileEntity::load(CompoundTag *base) items = new ItemInstanceArray(getContainerSize()); for (int i = 0; i < inventoryList->size(); i++) { - CompoundTag *tag = inventoryList->get(i); + CompoundTag *tag = (CompoundTag*) inventoryList->get(i); unsigned int slot = tag->getByte(L"Slot") & 0xff; if (slot >= 0 && slot < items->length) (*items)[slot] = ItemInstance::fromTag(tag); } @@ -286,4 +290,4 @@ std::shared_ptr ChestTileEntity::clone() } } return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.cpp b/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.cpp index 879f13237..39aa67b5b 100644 --- a/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.cpp +++ b/Minecraft.World/Blocks/TileEntities/FurnaceTileEntity.cpp @@ -100,11 +100,14 @@ int FurnaceTileEntity::getName() void FurnaceTileEntity::load(CompoundTag *base) { TileEntity::load(base); - ListTag *inventoryList = (ListTag *) base->getList(L"Items"); + // 4jcraft, fixed cast of templated List to get the tag list + // and cast it to CompoundTag inside the loop + ListTag *inventoryList = base->getList(L"Items"); + items = new ItemInstanceArray(getContainerSize()); for (int i = 0; i < inventoryList->size(); i++) { - CompoundTag *tag = inventoryList->get(i); + CompoundTag *tag = (CompoundTag*) inventoryList->get(i); unsigned int slot = tag->getByte(L"Slot"); if (slot >= 0 && slot < items->length) (*items)[slot] = ItemInstance::fromTag(tag); } @@ -347,4 +350,4 @@ std::shared_ptr FurnaceTileEntity::clone() } } return result; -} \ No newline at end of file +} From 56955ad935078ace5a65251e2bbb2f014878f492 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 03:59:41 +0100 Subject: [PATCH 06/22] shift of negative values, added casts --- Minecraft.Client/Textures/Texture.cpp | 9 +++++---- Minecraft.Client/Textures/Textures.cpp | 11 ++++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Minecraft.Client/Textures/Texture.cpp b/Minecraft.Client/Textures/Texture.cpp index 7b568f402..b5d9625b9 100644 --- a/Minecraft.Client/Textures/Texture.cpp +++ b/Minecraft.Client/Textures/Texture.cpp @@ -660,10 +660,11 @@ void Texture::transferFromImage(BufferedImage *image) int c3 = data[level - 1]->getInt(((x * 2 + 0) + (y * 2 + 1) * ow) * 4); #ifndef _XBOX // 4J - convert our RGBA texels to ARGB that crispBlend is expecting - c0 = ( ( c0 >> 8 ) & 0x00ffffff ) | ( c0 << 24 ); - c1 = ( ( c1 >> 8 ) & 0x00ffffff ) | ( c1 << 24 ); - c2 = ( ( c2 >> 8 ) & 0x00ffffff ) | ( c2 << 24 ); - c3 = ( ( c3 >> 8 ) & 0x00ffffff ) | ( c3 << 24 ); + // 4jcraft, added uint cast to pervent shift of neg int + c0 = ( ( c0 >> 8 ) & 0x00ffffff ) | ( (unsigned int) c0 << 24 ); + c1 = ( ( c1 >> 8 ) & 0x00ffffff ) | ( (unsigned int) c1 << 24 ); + c2 = ( ( c2 >> 8 ) & 0x00ffffff ) | ( (unsigned int) c2 << 24 ); + c3 = ( ( c3 >> 8 ) & 0x00ffffff ) | ( (unsigned int) c3 << 24 ); #endif int col = crispBlend(crispBlend(c0, c1), crispBlend(c2, c3)); // 4J - and back from ARGB -> RGBA diff --git a/Minecraft.Client/Textures/Textures.cpp b/Minecraft.Client/Textures/Textures.cpp index 0974a3f66..83cb97d44 100644 --- a/Minecraft.Client/Textures/Textures.cpp +++ b/Minecraft.Client/Textures/Textures.cpp @@ -626,15 +626,16 @@ void Textures::loadTexture(BufferedImage *img, int id, bool blur, bool clamp) int c3 = pixels->getInt(((x * 2 + 0) + (y * 2 + 1) * ow) * 4); #ifndef _XBOX // 4J - convert our RGBA texels to ARGB that crispBlend is expecting - c0 = ( ( c0 >> 8 ) & 0x00ffffff ) | ( c0 << 24 ); - c1 = ( ( c1 >> 8 ) & 0x00ffffff ) | ( c1 << 24 ); - c2 = ( ( c2 >> 8 ) & 0x00ffffff ) | ( c2 << 24 ); - c3 = ( ( c3 >> 8 ) & 0x00ffffff ) | ( c3 << 24 ); + // 4jcraft, added uint cast to pervent shift of neg int + c0 = ( ( c0 >> 8 ) & 0x00ffffff ) | ( (unsigned int) c0 << 24 ); + c1 = ( ( c1 >> 8 ) & 0x00ffffff ) | ( (unsigned int) c1 << 24 ); + c2 = ( ( c2 >> 8 ) & 0x00ffffff ) | ( (unsigned int) c2 << 24 ); + c3 = ( ( c3 >> 8 ) & 0x00ffffff ) | ( (unsigned int) c3 << 24 ); #endif int col = Texture::crispBlend(Texture::crispBlend(c0, c1), Texture::crispBlend(c2, c3)); #ifndef _XBOX // 4J - and back from ARGB -> RGBA - col = ( col << 8 ) | (( col >> 24 ) & 0xff); + col = ( (unsigned int) col << 8 ) | (( col >> 24 ) & 0xff); #endif tempData[x + y * ww] = col; } From 142e41e1ca04a77239e9f14647eb2caa2d82873c Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 04:08:40 +0100 Subject: [PATCH 07/22] fix sort function --- .../Platform/Common/Consoles_App.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index c226ca016..a89d59f90 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -5861,7 +5861,21 @@ Random *CMinecraftApp::TipRandom = new Random(); int CMinecraftApp::TipsSortFunction(const void* a, const void* b) { - return ((TIPSTRUCT*)a)->iSortValue - ((TIPSTRUCT*)b)->iSortValue; + // 4jcraft, scince the sortvalues can be negative, i changed it + // to a three way comparison, + // scince subtracting of signed integers can cause overflow. + + int s1 = ((TIPSTRUCT*)a)->iSortValue; + int s2 = ((TIPSTRUCT*)b)->iSortValue; + + if(s1 > s2) { + return 1; + + } else if (s1 == s2) { + return 0; + } + + return -1; } void CMinecraftApp::InitialiseTips() From 63e4b9b18a339440dbd0b052c0952e9497f9b5c1 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 12:32:59 +0100 Subject: [PATCH 08/22] next little patch of ub, unallocated variable, s int overflow --- .../Network/PlatformNetworkManagerStub.cpp | 2 + Minecraft.World/WorldGen/Layers/Layer.cpp | 43 ++++++++++--------- Minecraft.World/WorldGen/Layers/Layer.h | 2 +- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/Minecraft.Client/Platform/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Platform/Common/Network/PlatformNetworkManagerStub.cpp index f9d4ae1b6..9dfc45a17 100644 --- a/Minecraft.Client/Platform/Common/Network/PlatformNetworkManagerStub.cpp +++ b/Minecraft.Client/Platform/Common/Network/PlatformNetworkManagerStub.cpp @@ -119,6 +119,7 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa m_pGameNetworkManager = pGameNetworkManager; m_flagIndexSize = flagIndexSize; g_pPlatformNetworkManager = this; + m_pIQNet = new IQNet(); for( int i = 0; i < XUSER_MAX_COUNT; i++ ) { playerChangedCallback[ i ] = NULL; @@ -154,6 +155,7 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa void CPlatformNetworkManagerStub::Terminate() { + //TODO: 4jcraft, no release of ressources } int CPlatformNetworkManagerStub::GetJoiningReadyPercentage() diff --git a/Minecraft.World/WorldGen/Layers/Layer.cpp b/Minecraft.World/WorldGen/Layers/Layer.cpp index 1718172a2..286fd3827 100644 --- a/Minecraft.World/WorldGen/Layers/Layer.cpp +++ b/Minecraft.World/WorldGen/Layers/Layer.cpp @@ -111,38 +111,41 @@ Layer::Layer(__int64 seedMixup) { parent = nullptr; + // 4jcraft added all those calls abecause of signed int overflow this->seedMixup = seedMixup; - this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; - this->seedMixup += seedMixup; - this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; - this->seedMixup += seedMixup; - this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l; - this->seedMixup += seedMixup; + this->seedMixup *= (uint64_t) this->seedMixup * 6364136223846793005l + 1442695040888963407l; + this->seedMixup = (uint64_t) this->seedMixup + seedMixup; + this->seedMixup *= (uint64_t) this->seedMixup * 6364136223846793005l + 1442695040888963407l; + this->seedMixup = (uint64_t) this->seedMixup + seedMixup; + this->seedMixup *= (uint64_t) this->seedMixup * 6364136223846793005l + 1442695040888963407l; + this->seedMixup = (uint64_t) this->seedMixup + seedMixup; } void Layer::init(__int64 seed) { this->seed = seed; if (parent != NULL) parent->init(seed); - this->seed *= this->seed * 6364136223846793005l + 1442695040888963407l; - this->seed += seedMixup; - this->seed *= this->seed * 6364136223846793005l + 1442695040888963407l; - this->seed += seedMixup; - this->seed *= this->seed * 6364136223846793005l + 1442695040888963407l; - this->seed += seedMixup; + // 4jcraft added all those calls abecause of signed int overflow + this->seed *= (uint64_t) this->seed * 6364136223846793005l + 1442695040888963407l; + this->seed = (uint64_t) this->seed + seedMixup; + this->seed *= (uint64_t) this->seed * 6364136223846793005l + 1442695040888963407l; + this->seed = (uint64_t) this->seed + seedMixup; + this->seed *= (uint64_t) this->seed * 6364136223846793005l + 1442695040888963407l; + this->seed = (uint64_t) this->seed + seedMixup; } void Layer::initRandom(__int64 x, __int64 y) { rval = seed; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += x; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += y; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += x; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += y; + // 4jcraft added all those calls abecause of signed int overflow + rval *= (uint64_t) rval * 6364136223846793005l + 1442695040888963407l; + rval += (uint64_t) x; + rval *= (uint64_t) rval * 6364136223846793005l + 1442695040888963407l; + rval += (uint64_t) y; + rval *= (uint64_t) rval * 6364136223846793005l + 1442695040888963407l; + rval += (uint64_t) x; + rval *= (uint64_t) rval * 6364136223846793005l + 1442695040888963407l; + rval += (uint64_t) y; } int Layer::nextRandom(int max) diff --git a/Minecraft.World/WorldGen/Layers/Layer.h b/Minecraft.World/WorldGen/Layers/Layer.h index 2104d219d..ec1598b4f 100644 --- a/Minecraft.World/WorldGen/Layers/Layer.h +++ b/Minecraft.World/WorldGen/Layers/Layer.h @@ -4,7 +4,7 @@ class LevelType; -#ifndef _CONTENT_PACAKGE +#ifndef _CONTENT_PACKAGE #define _BIOME_OVERRIDE #endif From 8395277c0c71d5df9f1d98b85a7aa308d0a37971 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 13:33:49 +0100 Subject: [PATCH 09/22] shift of signed int, s int overflow --- .../Common/GameRules/ConsoleSchematicFile.cpp | 9 ++--- .../GameRules/LevelGenerationOptions.cpp | 6 ++-- .../IO/Files/ConsoleSaveFileSplit.cpp | 2 +- Minecraft.World/Level/LevelChunk.cpp | 33 ++++++++++--------- Minecraft.World/Level/RandomLevelSource.cpp | 5 +-- .../Level/Storage/McRegionChunkStorage.cpp | 4 ++- Minecraft.World/Util/Random.cpp | 6 ++-- .../WorldGen/Biomes/BiomeCache.cpp | 5 +-- .../WorldGen/Features/LargeFeature.cpp | 6 ++-- .../WorldGen/Features/StrongholdFeature.cpp | 4 +-- .../WorldGen/Features/StructureFeature.cpp | 4 +-- .../WorldGen/Features/VillageFeature.cpp | 3 +- .../WorldGen/Layers/FuzzyZoomLayer.cpp | 11 ++++--- Minecraft.World/WorldGen/Layers/Layer.cpp | 11 ++++--- .../WorldGen/Layers/VoronoiZoom.cpp | 19 ++++++----- Minecraft.World/WorldGen/Layers/ZoomLayer.cpp | 11 ++++--- .../WorldGen/Structures/MineShaftStart.cpp | 5 +-- 17 files changed, 79 insertions(+), 65 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index c4111da11..da54f7194 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -194,14 +194,15 @@ void ConsoleSchematicFile::save_tags(DataOutputStream *dos) __int64 ConsoleSchematicFile::applyBlocksAndData(LevelChunk *chunk, AABB *chunkBox, AABB *destinationBox, ESchematicRotation rot) { int xStart = std::max(destinationBox->x0, (double)chunk->x*16); - int xEnd = std::min(destinationBox->x1, (double)((xStart>>4)<<4) + 16); + // 4jcraft added cast to u + int xEnd = std::min(destinationBox->x1, (double)((unsigned) (xStart>>4)<<4) + 16); int yStart = destinationBox->y0; int yEnd = destinationBox->y1; if(yEnd > Level::maxBuildHeight) yEnd = Level::maxBuildHeight; int zStart = std::max(destinationBox->z0, (double)chunk->z*16); - int zEnd = std::min(destinationBox->z1, (double)((zStart>>4)<<4) + 16); + int zEnd = std::min(destinationBox->z1, (double)(((unsigned) zStart>>4)<<4) + 16); #ifdef _DEBUG app.DebugPrintf("Range is (%d,%d,%d) to (%d,%d,%d)\n",xStart,yStart,zStart,xEnd-1,yEnd-1,zEnd-1); @@ -333,14 +334,14 @@ __int64 ConsoleSchematicFile::applyBlocksAndData(LevelChunk *chunk, AABB *chunkB __int64 ConsoleSchematicFile::applyLighting(LevelChunk *chunk, AABB *chunkBox, AABB *destinationBox, ESchematicRotation rot) { int xStart = std::max(destinationBox->x0, (double)chunk->x*16); - int xEnd = std::min(destinationBox->x1, (double)((xStart>>4)<<4) + 16); + int xEnd = std::min(destinationBox->x1, (double)(((unsigned) xStart>>4)<<4) + 16); int yStart = destinationBox->y0; int yEnd = destinationBox->y1; if(yEnd > Level::maxBuildHeight) yEnd = Level::maxBuildHeight; int zStart = std::max(destinationBox->z0, (double)chunk->z*16); - int zEnd = std::min(destinationBox->z1, (double)((zStart>>4)<<4) + 16); + int zEnd = std::min(destinationBox->z1, (double)(((unsigned) zStart>>4)<<4) + 16); int rowBlocksIncluded = (yEnd-yStart)*(zEnd-zStart); int blocksIncluded = (xEnd-xStart)*rowBlocksIncluded; diff --git a/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp b/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp index b6bf2a390..b7f0bcaf0 100644 --- a/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.cpp @@ -244,8 +244,8 @@ void LevelGenerationOptions::processSchematics(LevelChunk *chunk) rule->processSchematic(chunkBox, chunk); } - int cx = (chunk->x << 4); - int cz = (chunk->z << 4); + int cx = ((unsigned)chunk->x << 4); + int cz = ((unsigned)chunk->z << 4); for( AUTO_VAR(it, m_structureRules.begin()); it != m_structureRules.end(); it++ ) { @@ -511,4 +511,4 @@ bool LevelGenerationOptions::getuseFlatWorld() { return m_useFlatWorld; } bool LevelGenerationOptions::requiresGameRules() { return m_bRequiresGameRules; } void LevelGenerationOptions::setRequiredGameRules(LevelRuleset *rules) { m_requiredGameRules = rules; m_bRequiresGameRules = true; } -LevelRuleset *LevelGenerationOptions::getRequiredGameRules() { return m_requiredGameRules; } \ No newline at end of file +LevelRuleset *LevelGenerationOptions::getRequiredGameRules() { return m_requiredGameRules; } diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp index 5b088f628..645d2c13e 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp +++ b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp @@ -1221,7 +1221,7 @@ bool ConsoleSaveFileSplit::GetNumericIdentifierFromName(const std::wstring &file swscanf_s(body, L"%d.%d.mcr", &x, &z ); // Pack full id - id |= ( ( x << 8 ) & 0x0000ff00 ); + id |= ( ( (unsigned int) x << 8 ) & 0x0000ff00 ); id |= ( z & 0x000000ff ); *idOut = id; diff --git a/Minecraft.World/Level/LevelChunk.cpp b/Minecraft.World/Level/LevelChunk.cpp index 2658be342..cc0aa626e 100644 --- a/Minecraft.World/Level/LevelChunk.cpp +++ b/Minecraft.World/Level/LevelChunk.cpp @@ -459,7 +459,7 @@ bool LevelChunk::isAt(int x, int z) int LevelChunk::getHeightmap(int x, int z) { - return heightmap[z << 4 | x] & 0xff; + return heightmap[(unsigned) z << 4 | x] & 0xff; } int LevelChunk::getHighestSectionPosition() @@ -492,12 +492,12 @@ void LevelChunk::recalcHeightmapOnly() for (int x = 0; x < 16; x++) for (int z = 0; z < 16; z++) { - rainHeights[x + (z << 4)] = 255; // 4J - changed from int to unsigned char & this special value changed from -999 to 255 + rainHeights[x + ((unsigned) z << 4)] = 255; // 4J - changed from int to unsigned char & this special value changed from -999 to 255 int y = Level::maxBuildHeight - 1; // int p = x << level->depthBitsPlusFour | z << level->depthBits; // 4J - removed #ifdef __PSVITA__ - int Index = ( x << 11 ) + ( z << 7 ); + int Index = ( (unsigned) x << 11 ) + ( (unsigned) z << 7 ); int offset = Level::COMPRESSED_CHUNK_SECTION_TILES; y = 127; while (y > 0 && Tile::lightBlock[blockData[Index + offset + (y - 1)]] == 0) // 4J - was blocks->get() was blocks[p + y - 1] @@ -525,7 +525,7 @@ void LevelChunk::recalcHeightmapOnly() blocks = (y-1) >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT?upperBlocks : lowerBlocks; } #endif - heightmap[z << 4 | x] = (uint8_t) y; + heightmap[(unsigned) z << 4 | x] = (uint8_t) y; if (y < min) min = y; } @@ -553,7 +553,7 @@ void LevelChunk::recalcHeightmap() // int p = x << level->depthBitsPlusFour | z << level->depthBits; // 4J - removed #ifdef __PSVITA__ - int Index = ( x << 11 ) + ( z << 7 ); + int Index = ( (unsigned) x << 11 ) + ( (unsigned) z << 7 ); int offset = Level::COMPRESSED_CHUNK_SECTION_TILES; y = 127; while (y > 0 && Tile::lightBlock[blockData[Index + offset + (y - 1)]] == 0) // 4J - was blocks->get() was blocks[p + y - 1] @@ -581,7 +581,7 @@ void LevelChunk::recalcHeightmap() blocks = (y-1) >= Level::COMPRESSED_CHUNK_SECTION_HEIGHT?upperBlocks : lowerBlocks; } #endif - heightmap[z << 4 | x] = (uint8_t) y; + heightmap[(unsigned) z << 4 | x] = (uint8_t) y; if (y < min) min = y; if (!level->dimension->hasCeiling) @@ -788,7 +788,7 @@ void LevelChunk::lightGap(int x, int z, int y1, int y2) void LevelChunk::recalcHeight(int x, int yStart, int z) { - int yOld = heightmap[z << 4 | x] & 0xff; + int yOld = heightmap[(unsigned) z << 4 | x] & 0xff; int y = yOld; if (yStart > yOld) y = yStart; @@ -803,7 +803,7 @@ void LevelChunk::recalcHeight(int x, int yStart, int z) if (y == yOld) return; // level->lightColumnChanged(x, z, y, yOld); // 4J - this call moved below & corrected - see comment further down - heightmap[z << 4 | x] = (uint8_t) y; + heightmap[(unsigned) z << 4 | x] = (uint8_t) y; if (y < minHeight) { @@ -815,7 +815,7 @@ void LevelChunk::recalcHeight(int x, int yStart, int z) for (int _x = 0; _x < 16; _x++) for (int _z = 0; _z < 16; _z++) { - if ((heightmap[_z << 4 | _x] & 0xff) < min) min = (heightmap[_z << 4 | _x] & 0xff); + if ((heightmap[(unsigned) _z << 4 | _x] & 0xff) < min) min = (heightmap[(unsigned) _z << 4 | _x] & 0xff); } this->minHeight = min; } @@ -865,7 +865,7 @@ void LevelChunk::recalcHeight(int x, int yStart, int z) level->lightColumnChanged(xOffs, zOffs, y, yOld); // 4J - lighting changes brought forward from 1.8.2 - int height = heightmap[z << 4 | x]; + int height = heightmap[(unsigned) z << 4 | x]; int y1 = yOld; int y2 = height; if (y2 < y1) @@ -913,7 +913,7 @@ bool LevelChunk::setTileAndData(int x, int y, int z, int _tile, int _data) uint8_t tile = (uint8_t) _tile; // Optimisation brought forward from 1.8.2, change from int to unsigned char & this special value changed from -999 to 255 - int slot = z << 4 | x; + int slot = (unsigned) z << 4 | x; if (y >= ((int)rainHeights[slot]) - 1) { @@ -1246,7 +1246,7 @@ void LevelChunk::removeEntity(std::shared_ptr e, int yc) bool LevelChunk::isSkyLit(int x, int y, int z) { - return y >= (heightmap[z << 4 | x] & 0xff); + return y >= (heightmap[(unsigned) z << 4 | x] & 0xff); } void LevelChunk::skyBrightnessChanged() @@ -1979,12 +1979,13 @@ bool LevelChunk::isYSpaceEmpty(int y1, int y2) Biome *LevelChunk::getBiome(int x, int z, BiomeSource *biomeSource) { - int value = biomes[(z << 4) | x] & 0xff; + int value = biomes[((unsigned) z << 4) | x] & 0xff; if (value == 0xff) { - Biome *biome = biomeSource->getBiome((this->x << 4) + x, (this->z << 4) + z); + // 4jcraft added casts to u + Biome *biome = biomeSource->getBiome(((unsigned) this->x << 4) + x, ((unsigned) this->z << 4) + z); value = biome->id; - biomes[(z << 4) | x] = (uint8_t) (value & 0xff); + biomes[((unsigned) z << 4) | x] = (uint8_t) (value & 0xff); } if (Biome::biomes[value] == NULL) { @@ -2007,7 +2008,7 @@ void LevelChunk::setBiomes(byteArray biomes) // 4J - optimisation brought forward from 1.8.2 int LevelChunk::getTopRainBlock(int x, int z) { - int slot = x | (z << 4); + int slot = x | ((unsigned) z << 4); int h = rainHeights[slot]; if (h == 255) diff --git a/Minecraft.World/Level/RandomLevelSource.cpp b/Minecraft.World/Level/RandomLevelSource.cpp index e7f055b13..b18278516 100644 --- a/Minecraft.World/Level/RandomLevelSource.cpp +++ b/Minecraft.World/Level/RandomLevelSource.cpp @@ -144,7 +144,7 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, byteArray blocks) for (int x = 0; x < CHUNK_WIDTH; x++) { - int offs = (x + xc * CHUNK_WIDTH) << Level::genDepthBitsPlusFour | (0 + zc * CHUNK_WIDTH) << Level::genDepthBits | (yc * CHUNK_HEIGHT + y); + int offs = (unsigned) (x + (unsigned) xc * CHUNK_WIDTH) << Level::genDepthBitsPlusFour | ((unsigned) zc * CHUNK_WIDTH) << Level::genDepthBits | (yc * CHUNK_HEIGHT + y); int step = 1 << Level::genDepthBits; offs -= step; double zStep = 1 / (double) CHUNK_WIDTH; @@ -654,7 +654,8 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) pprandom->setSeed(level->getSeed()); __int64 xScale = pprandom->nextLong() / 2 * 2 + 1; __int64 zScale = pprandom->nextLong() / 2 * 2 + 1; - pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); + // 4jcraft added casts to u, holy moly, the getSeed is 64 bit and the result is 32... + pprandom->setSeed((((uint64_t)(int64_t)xt * (uint64_t)(int64_t)xScale) + ((uint64_t)(int64_t)zt * (uint64_t)(int64_t)zScale)) ^ level->getSeed()); bool hasVillage = false; diff --git a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp index b13f1c221..e31fab3c5 100644 --- a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp @@ -78,7 +78,9 @@ LevelChunk *McRegionChunkStorage::load(Level *level, int x, int z) // If we can't find the chunk in the save file, then we should remove any entities we might have for that chunk if(regionChunkInputStream == NULL) { - __int64 index = ((__int64)(x) << 32) | (((__int64)(z))&0x00000000FFFFFFFF); + // 4jcraft fixed cast from int to int64 and taking the mask of the upper bits + // and cast to unsigned + __int64 index = ((uint64_t)(uint32_t)(x) << 32) | (((uint64_t)(uint32_t)(z))); AUTO_VAR(it, m_entityData.find(index)); if(it != m_entityData.end()) diff --git a/Minecraft.World/Util/Random.cpp b/Minecraft.World/Util/Random.cpp index 00c4403aa..10f58d938 100644 --- a/Minecraft.World/Util/Random.cpp +++ b/Minecraft.World/Util/Random.cpp @@ -88,7 +88,8 @@ int Random::nextInt(int n) if ((n & -n) == n) // i.e., n is a power of 2 - return (int)(((__int64)next(31) * n) >> 31); // 4J Stu - Made __int64 instead of long + // 4jcraft added casts to unsigned + return (unsigned int)(((__uint64)next(31) * n) >> 31); // 4J Stu - Made __int64 instead of long int bits, val; do @@ -106,7 +107,8 @@ float Random::nextFloat() __int64 Random::nextLong() { - return ((__int64)next(32) << 32) + next(32); + // 4jcraft added casts to unsigned + return (__uint64)((__uint64)next(32) << 32) + next(32); } bool Random::nextBoolean() diff --git a/Minecraft.World/WorldGen/Biomes/BiomeCache.cpp b/Minecraft.World/WorldGen/Biomes/BiomeCache.cpp index 3fc2d7bc5..0e6f91eb0 100644 --- a/Minecraft.World/WorldGen/Biomes/BiomeCache.cpp +++ b/Minecraft.World/WorldGen/Biomes/BiomeCache.cpp @@ -18,7 +18,8 @@ BiomeCache::Block::Block(int x, int z, BiomeCache *parent) // parent->source->getTemperatureBlock(temps, x << ZONE_SIZE_BITS, z << ZONE_SIZE_BITS, ZONE_SIZE, ZONE_SIZE); // parent->source->getDownfallBlock(downfall, x << ZONE_SIZE_BITS, z << ZONE_SIZE_BITS, ZONE_SIZE, ZONE_SIZE); // parent->source->getBiomeBlock(biomes, x << ZONE_SIZE_BITS, z << ZONE_SIZE_BITS, ZONE_SIZE, ZONE_SIZE, false); - parent->source->getBiomeIndexBlock(biomeIndices, x << ZONE_SIZE_BITS, z << ZONE_SIZE_BITS, ZONE_SIZE, ZONE_SIZE, false); + // 4jcraft added cast to unsigned + parent->source->getBiomeIndexBlock(biomeIndices, (unsigned) x << ZONE_SIZE_BITS, (unsigned) z << ZONE_SIZE_BITS, ZONE_SIZE, ZONE_SIZE, false); } @@ -162,4 +163,4 @@ BiomeArray BiomeCache::getBiomeBlockAt(int x, int z) byteArray BiomeCache::getBiomeIndexBlockAt(int x, int z) { return getBlockAt(x, z)->biomeIndices; -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Features/LargeFeature.cpp b/Minecraft.World/WorldGen/Features/LargeFeature.cpp index e1cda1982..187ec5dd1 100644 --- a/Minecraft.World/WorldGen/Features/LargeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/LargeFeature.cpp @@ -28,10 +28,10 @@ void LargeFeature::apply(ChunkSource *ChunkSource, Level *level, int xOffs, int { for (int z = zOffs - r; z <= zOffs + r; z++) { - __int64 xx = x * xScale; - __int64 zz = z * zScale; + __int64 xx = (uint64_t) x * xScale; + __int64 zz = (uint64_t) z * zScale; random->setSeed(xx ^ zz ^ level->getSeed()); addFeature(level, x, z, xOffs, zOffs, blocks); } } -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Features/StrongholdFeature.cpp b/Minecraft.World/WorldGen/Features/StrongholdFeature.cpp index 52ee3d0c3..1c6a69d51 100644 --- a/Minecraft.World/WorldGen/Features/StrongholdFeature.cpp +++ b/Minecraft.World/WorldGen/Features/StrongholdFeature.cpp @@ -98,7 +98,7 @@ bool StrongholdFeature::isFeatureChunk(int x, int z,bool bIsSuperflat) int selectedX = (int) (Math::round(cos(angle) * dist)); int selectedZ = (int) (Math::round(sin(angle) * dist)); - TilePos *position = level->getBiomeSource()->findBiome((selectedX << 4) + 8, (selectedZ << 4) + 8, 7 << 4, allowedBiomes, &random); + TilePos *position = level->getBiomeSource()->findBiome(((unsigned int) selectedX << 4) + 8, ((unsigned int) selectedZ << 4) + 8, 7 << 4, allowedBiomes, &random); if (position != NULL) { selectedX = position->x >> 4; @@ -221,4 +221,4 @@ StrongholdFeature::StrongholdStart::StrongholdStart(Level *level, Random *random calculateBoundingBox(); moveBelowSeaLevel(level, random, 10); -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Features/StructureFeature.cpp b/Minecraft.World/WorldGen/Features/StructureFeature.cpp index 2f274e691..dfb98b0c6 100644 --- a/Minecraft.World/WorldGen/Features/StructureFeature.cpp +++ b/Minecraft.World/WorldGen/Features/StructureFeature.cpp @@ -42,8 +42,8 @@ bool StructureFeature::postProcess(Level *level, Random *random, int chunkX, int // Normal feature generation offsets generation by half a chunk to ensure that it can generate the entire feature in chunks already created // Structure features don't need this, as the PlaceBlock function only places blocks inside the BoundingBox specified, and parts // of a struture piece can be added in more than one post-process call - int cx = (chunkX << 4); // + 8; - int cz = (chunkZ << 4); // + 8; + int cx = ((unsigned) chunkX << 4); // + 8; + int cz = ((unsigned)chunkZ << 4); // + 8; bool intersection = false; for( AUTO_VAR(it, cachedStructures.begin()); it != cachedStructures.end(); it++ ) diff --git a/Minecraft.World/WorldGen/Features/VillageFeature.cpp b/Minecraft.World/WorldGen/Features/VillageFeature.cpp index 7d9dd0ea6..ab3755071 100644 --- a/Minecraft.World/WorldGen/Features/VillageFeature.cpp +++ b/Minecraft.World/WorldGen/Features/VillageFeature.cpp @@ -91,7 +91,8 @@ VillageFeature::VillageStart::VillageStart(Level *level, Random *random, int chu std::list *pieceSet = VillagePieces::createPieceSet(random, villageSizeModifier); - VillagePieces::StartPiece *startRoom = new VillagePieces::StartPiece(level->getBiomeSource(), 0, random, (chunkX << 4) + 2, (chunkZ << 4) + 2, pieceSet, villageSizeModifier, level); + // 4jcraft added casts to u + VillagePieces::StartPiece *startRoom = new VillagePieces::StartPiece(level->getBiomeSource(), 0, random, ((unsigned) chunkX << 4) + 2, ((unsigned) chunkZ << 4) + 2, pieceSet, villageSizeModifier, level); pieces.push_back(startRoom); startRoom->addChildren(startRoom, &pieces, random); diff --git a/Minecraft.World/WorldGen/Layers/FuzzyZoomLayer.cpp b/Minecraft.World/WorldGen/Layers/FuzzyZoomLayer.cpp index 9b117e887..70fb06100 100644 --- a/Minecraft.World/WorldGen/Layers/FuzzyZoomLayer.cpp +++ b/Minecraft.World/WorldGen/Layers/FuzzyZoomLayer.cpp @@ -15,17 +15,18 @@ intArray FuzzyZoomLayer::getArea(int xo, int yo, int w, int h) int ph = (h >> 1) + 3; intArray p = parent->getArea(px, py, pw, ph); + // 4jcraft added casts to unsigned to prevent shift of neg value intArray tmp = IntCache::allocate((pw * 2) * (ph * 2)); - int ww = (pw << 1); + int ww = ((unsigned int) pw << 1); for (int y = 0; y < ph - 1; y++) { - int ry = y << 1; + int ry = (unsigned int) y << 1; int pp = ry * ww; int ul = p[(0 + 0) + (y + 0) * pw]; int dl = p[(0 + 0) + (y + 1) * pw]; for (int x = 0; x < pw - 1; x++) { - initRandom((x + px) << 1, (y + py) << 1); + initRandom((unsigned int) (x + px) << 1, (unsigned int) (y + py) << 1); int ur = p[(x + 1) + (y + 0) * pw]; int dr = p[(x + 1) + (y + 1) * pw]; @@ -41,7 +42,7 @@ intArray FuzzyZoomLayer::getArea(int xo, int yo, int w, int h) intArray result = IntCache::allocate(w * h); for (int y = 0; y < h; y++) { - System::arraycopy(tmp, (y + (yo & 1)) * (pw << 1) + (xo & 1), &result, y * w, w); + System::arraycopy(tmp, (y + (yo & 1)) * ((unsigned int) pw << 1) + (xo & 1), &result, y * w, w); } return result; @@ -69,4 +70,4 @@ std::shared_ptrFuzzyZoomLayer::zoom(__int64 seed, std::shared_ptrs result = std::shared_ptr(new FuzzyZoomLayer(seed + i, result)); } return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Layers/Layer.cpp b/Minecraft.World/WorldGen/Layers/Layer.cpp index 286fd3827..454ec8d5f 100644 --- a/Minecraft.World/WorldGen/Layers/Layer.cpp +++ b/Minecraft.World/WorldGen/Layers/Layer.cpp @@ -111,7 +111,7 @@ Layer::Layer(__int64 seedMixup) { parent = nullptr; - // 4jcraft added all those calls abecause of signed int overflow + // 4jcraft added casts to prevent signed int overflow this->seedMixup = seedMixup; this->seedMixup *= (uint64_t) this->seedMixup * 6364136223846793005l + 1442695040888963407l; this->seedMixup = (uint64_t) this->seedMixup + seedMixup; @@ -125,7 +125,7 @@ void Layer::init(__int64 seed) { this->seed = seed; if (parent != NULL) parent->init(seed); - // 4jcraft added all those calls abecause of signed int overflow + // 4jcraft added casts to prevent signed int overflow this->seed *= (uint64_t) this->seed * 6364136223846793005l + 1442695040888963407l; this->seed = (uint64_t) this->seed + seedMixup; this->seed *= (uint64_t) this->seed * 6364136223846793005l + 1442695040888963407l; @@ -137,7 +137,7 @@ void Layer::init(__int64 seed) void Layer::initRandom(__int64 x, __int64 y) { rval = seed; - // 4jcraft added all those calls abecause of signed int overflow + // 4jcraft added casts to prevent signed int overflow rval *= (uint64_t) rval * 6364136223846793005l + 1442695040888963407l; rval += (uint64_t) x; rval *= (uint64_t) rval * 6364136223846793005l + 1442695040888963407l; @@ -196,7 +196,8 @@ int Layer::nextRandom(int max) #endif if (result < 0) result += max; - rval *= rval * 6364136223846793005l + 1442695040888963407l; - rval += seed; + // 4jcraft added cast to unsigned + rval *= (uint64_t) rval * 6364136223846793005l + 1442695040888963407l; + rval += (uint64_t) seed; return result; } diff --git a/Minecraft.World/WorldGen/Layers/VoronoiZoom.cpp b/Minecraft.World/WorldGen/Layers/VoronoiZoom.cpp index 7c0e57a7c..85154ecd4 100644 --- a/Minecraft.World/WorldGen/Layers/VoronoiZoom.cpp +++ b/Minecraft.World/WorldGen/Layers/VoronoiZoom.cpp @@ -19,8 +19,9 @@ intArray VoronoiZoom::getArea(int xo, int yo, int w, int h) int ph = (h >> bits) + 3; intArray p = parent->getArea(px, py, pw, ph); - int ww = pw << bits; - int hh = ph << bits; + // 4jcraft added all those casts to unsigned + int ww = (unsigned) pw << bits; + int hh = (unsigned) ph << bits; intArray tmp = IntCache::allocate(ww * hh); for (int y = 0; y < ph - 1; y++) { @@ -29,16 +30,16 @@ intArray VoronoiZoom::getArea(int xo, int yo, int w, int h) for (int x = 0; x < pw - 1; x++) { double s = ss * 0.9; - initRandom((x + px) << bits, (y + py) << bits); + initRandom((unsigned) (x + px) << bits, (unsigned) (y + py) << bits); double x0 = (nextRandom(1024) / 1024.0 - 0.5) * s; double y0 = (nextRandom(1024) / 1024.0 - 0.5) * s; - initRandom((x + px + 1) << bits, (y + py) << bits); + initRandom((unsigned) (x + px + 1) << bits, (unsigned) (y + py) << bits); double x1 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss; double y1 = (nextRandom(1024) / 1024.0 - 0.5) * s; - initRandom((x + px) << bits, (y + py + 1) << bits); + initRandom((unsigned) (x + px) << bits, (unsigned) (y + py + 1) << bits); double x2 = (nextRandom(1024) / 1024.0 - 0.5) * s; double y2 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss; - initRandom((x + px + 1) << bits, (y + py + 1) << bits); + initRandom((unsigned) (x + px + 1) << bits, (unsigned) (y + py + 1) << bits); double x3 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss; double y3 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss; @@ -47,7 +48,7 @@ intArray VoronoiZoom::getArea(int xo, int yo, int w, int h) for (int yy = 0; yy < ss; yy++) { - int pp = ((y << bits) + yy) * ww + ((x << bits)); + int pp = ((unsigned) (y << bits) + yy) * ww + ((unsigned) (x << bits)); for (int xx = 0; xx < ss; xx++) { double d0 = ((yy - y0) * (yy - y0) + (xx - x0) * (xx - x0)); @@ -81,7 +82,7 @@ intArray VoronoiZoom::getArea(int xo, int yo, int w, int h) intArray result = IntCache::allocate(w * h); for (int y = 0; y < h; y++) { - System::arraycopy(tmp, (y + (yo & (ss - 1))) * (pw << bits) + (xo & (ss - 1)), &result, y * w, w); + System::arraycopy(tmp, (y + (yo & (ss - 1))) * ((unsigned) pw << bits) + (xo & (ss - 1)), &result, y * w, w); } return result; } @@ -119,4 +120,4 @@ int VoronoiZoom::random(int a, int b, int c, int d) if (s == 1) return b; if (s == 2) return c; return d; -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Layers/ZoomLayer.cpp b/Minecraft.World/WorldGen/Layers/ZoomLayer.cpp index b0e5d6d79..3f7cbf5f9 100644 --- a/Minecraft.World/WorldGen/Layers/ZoomLayer.cpp +++ b/Minecraft.World/WorldGen/Layers/ZoomLayer.cpp @@ -16,16 +16,17 @@ intArray ZoomLayer::getArea(int xo, int yo, int w, int h) intArray p = parent->getArea(px, py, pw, ph); intArray tmp = IntCache::allocate((pw * 2) * (ph * 2)); - int ww = (pw << 1); + // 4jcraft added casts to unsigned + int ww = ((unsigned int) pw << 1); for (int y = 0; y < ph - 1; y++) { - int ry = y << 1; + int ry = (unsigned int) y << 1; int pp = ry * ww; int ul = p[(0 + 0) + (y + 0) * pw]; int dl = p[(0 + 0) + (y + 1) * pw]; for (int x = 0; x < pw - 1; x++) { - initRandom((x + px) << 1, (y + py) << 1); + initRandom((unsigned int) (x + px) << 1, (unsigned int) (y + py) << 1); int ur = p[(x + 1) + (y + 0) * pw]; int dr = p[(x + 1) + (y + 1) * pw]; @@ -41,7 +42,7 @@ intArray ZoomLayer::getArea(int xo, int yo, int w, int h) intArray result = IntCache::allocate(w * h); for (int y = 0; y < h; y++) { - System::arraycopy(tmp, (y + (yo & 1)) * (pw << 1) + (xo & 1), &result, y * w, w); + System::arraycopy(tmp, (y + (yo & 1)) * (unsigned int) (pw << 1) + (xo & 1), &result, y * w, w); } return result; } @@ -89,4 +90,4 @@ std::shared_ptrZoomLayer::zoom(__int64 seed, std::shared_ptr sup, result = std::shared_ptr(new ZoomLayer(seed + i, result)); } return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Structures/MineShaftStart.cpp b/Minecraft.World/WorldGen/Structures/MineShaftStart.cpp index f15f0b952..8e905916d 100644 --- a/Minecraft.World/WorldGen/Structures/MineShaftStart.cpp +++ b/Minecraft.World/WorldGen/Structures/MineShaftStart.cpp @@ -3,10 +3,11 @@ MineShaftStart::MineShaftStart(Level *level, Random *random, int chunkX, int chunkZ) { - MineShaftPieces::MineShaftRoom *mineShaftRoom = new MineShaftPieces::MineShaftRoom(0, random, (chunkX << 4) + 2, (chunkZ << 4) + 2); + // 4jcraft added to unsigned + MineShaftPieces::MineShaftRoom *mineShaftRoom = new MineShaftPieces::MineShaftRoom(0, random, ((unsigned) chunkX << 4) + 2, ((unsigned) chunkZ << 4) + 2); pieces.push_back(mineShaftRoom); mineShaftRoom->addChildren(mineShaftRoom, &pieces, random); calculateBoundingBox(); moveBelowSeaLevel(level, random, 10); -} \ No newline at end of file +} From 5aef20e37e73fa5d4d31e2681662e7648b0e7c77 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 14:13:32 +0100 Subject: [PATCH 10/22] fixed rounding, mb --- .../Platform/Common/GameRules/ConsoleSchematicFile.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index da54f7194..88ed4d6b1 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -194,15 +194,15 @@ void ConsoleSchematicFile::save_tags(DataOutputStream *dos) __int64 ConsoleSchematicFile::applyBlocksAndData(LevelChunk *chunk, AABB *chunkBox, AABB *destinationBox, ESchematicRotation rot) { int xStart = std::max(destinationBox->x0, (double)chunk->x*16); - // 4jcraft added cast to u - int xEnd = std::min(destinationBox->x1, (double)((unsigned) (xStart>>4)<<4) + 16); + // 4jcraft changed from (xStart>>4)<<4 to (xStart & ~15) + int xEnd = std::min(destinationBox->x1, (double)((xStart & ~15) + 16)); int yStart = destinationBox->y0; int yEnd = destinationBox->y1; if(yEnd > Level::maxBuildHeight) yEnd = Level::maxBuildHeight; int zStart = std::max(destinationBox->z0, (double)chunk->z*16); - int zEnd = std::min(destinationBox->z1, (double)(((unsigned) zStart>>4)<<4) + 16); + int zEnd = std::min(destinationBox->z1, (double)(zStart & ~15) + 16); #ifdef _DEBUG app.DebugPrintf("Range is (%d,%d,%d) to (%d,%d,%d)\n",xStart,yStart,zStart,xEnd-1,yEnd-1,zEnd-1); @@ -334,14 +334,14 @@ __int64 ConsoleSchematicFile::applyBlocksAndData(LevelChunk *chunk, AABB *chunkB __int64 ConsoleSchematicFile::applyLighting(LevelChunk *chunk, AABB *chunkBox, AABB *destinationBox, ESchematicRotation rot) { int xStart = std::max(destinationBox->x0, (double)chunk->x*16); - int xEnd = std::min(destinationBox->x1, (double)(((unsigned) xStart>>4)<<4) + 16); + int xEnd = std::min(destinationBox->x1, (double)((xStart>>4)<<4) + 16); int yStart = destinationBox->y0; int yEnd = destinationBox->y1; if(yEnd > Level::maxBuildHeight) yEnd = Level::maxBuildHeight; int zStart = std::max(destinationBox->z0, (double)chunk->z*16); - int zEnd = std::min(destinationBox->z1, (double)(((unsigned) zStart>>4)<<4) + 16); + int zEnd = std::min(destinationBox->z1, (double)((zStart>>4)<<4) + 16); int rowBlocksIncluded = (yEnd-yStart)*(zEnd-zStart); int blocksIncluded = (xEnd-xStart)*rowBlocksIncluded; From a24f9f5a5e8d72501d62bceed01afe7396a929d7 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 14:21:04 +0100 Subject: [PATCH 11/22] better rounding and s int overflow --- .../Platform/Common/GameRules/ConsoleSchematicFile.cpp | 5 +++-- Minecraft.World/Level/TickNextTickData.cpp | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index 88ed4d6b1..0a7987b1b 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -334,14 +334,15 @@ __int64 ConsoleSchematicFile::applyBlocksAndData(LevelChunk *chunk, AABB *chunkB __int64 ConsoleSchematicFile::applyLighting(LevelChunk *chunk, AABB *chunkBox, AABB *destinationBox, ESchematicRotation rot) { int xStart = std::max(destinationBox->x0, (double)chunk->x*16); - int xEnd = std::min(destinationBox->x1, (double)((xStart>>4)<<4) + 16); + // 4jcraft changed >>4<<4 to & ~15 + int xEnd = std::min(destinationBox->x1, (double)(xStart & ~15) + 16); int yStart = destinationBox->y0; int yEnd = destinationBox->y1; if(yEnd > Level::maxBuildHeight) yEnd = Level::maxBuildHeight; int zStart = std::max(destinationBox->z0, (double)chunk->z*16); - int zEnd = std::min(destinationBox->z1, (double)((zStart>>4)<<4) + 16); + int zEnd = std::min(destinationBox->z1, (double)(zStart & ~15) + 16); int rowBlocksIncluded = (yEnd-yStart)*(zEnd-zStart); int blocksIncluded = (xEnd-xStart)*rowBlocksIncluded; diff --git a/Minecraft.World/Level/TickNextTickData.cpp b/Minecraft.World/Level/TickNextTickData.cpp index 4baacd7ad..292fea72e 100644 --- a/Minecraft.World/Level/TickNextTickData.cpp +++ b/Minecraft.World/Level/TickNextTickData.cpp @@ -30,7 +30,8 @@ bool TickNextTickData::equals(const void *o) const int TickNextTickData::hashCode() const { - return (((x * 1024 * 1024) + (z * 1024) + y) * 256) + tileId; + // 4jcraft added cast to unsigned + return ((((unsigned) x * 1024 * 1024) + ((unsigned) z * 1024) + (unsigned) y) * 256) + tileId; } TickNextTickData *TickNextTickData::delay(__int64 l) @@ -66,4 +67,4 @@ int TickNextTickData::hash_fnct(const TickNextTickData &k) bool TickNextTickData::eq_test(const TickNextTickData &x, const TickNextTickData &y) { return ( x.x == y.x ) && ( x.y == y.y ) && ( x.z == y.z ) && ( x.tileId == y.tileId ); -} \ No newline at end of file +} From ed13020cf3cb41d2a30d4b4f67c62195a02dc9cb Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 16:10:48 +0100 Subject: [PATCH 12/22] s integer overflow, unsafe cast --- Minecraft.Client/Level/ServerLevel.cpp | 6 ++--- .../Containers/MerchantRecipeList.cpp | 6 ++--- Minecraft.World/Entities/Entity.cpp | 24 ++++++++++--------- Minecraft.World/Level/RandomLevelSource.cpp | 4 ++-- .../Level/Storage/McRegionChunkStorage.cpp | 5 ++-- .../Sources/HellRandomLevelSource.cpp | 3 ++- .../Sources/TheEndLevelRandomLevelSource.cpp | 3 ++- 7 files changed, 28 insertions(+), 23 deletions(-) diff --git a/Minecraft.Client/Level/ServerLevel.cpp b/Minecraft.Client/Level/ServerLevel.cpp index 6d56be34e..f4e5d5aeb 100644 --- a/Minecraft.Client/Level/ServerLevel.cpp +++ b/Minecraft.Client/Level/ServerLevel.cpp @@ -631,9 +631,9 @@ std::vector *ServerLevel::fetchTicksInChunk(LevelChunk *chunk, std::vector *results = new std::vector; ChunkPos *pos = chunk->getPos(); - int west = pos->x << 4; + int west = (unsigned) pos->x << 4; int east = west + 16; - int north = pos->z << 4; + int north =(unsigned) pos->z << 4; int south = north + 16; delete pos; @@ -1461,4 +1461,4 @@ void ServerLevel::flagEntitiesToBeRemoved(unsigned int *flags, bool *removedFoun { chunkMap->flagEntitiesToBeRemoved(flags, removedFound); } -} \ No newline at end of file +} diff --git a/Minecraft.World/Containers/MerchantRecipeList.cpp b/Minecraft.World/Containers/MerchantRecipeList.cpp index e8eb3ba35..f08225bbb 100644 --- a/Minecraft.World/Containers/MerchantRecipeList.cpp +++ b/Minecraft.World/Containers/MerchantRecipeList.cpp @@ -135,11 +135,11 @@ MerchantRecipeList *MerchantRecipeList::createFromStream(DataInputStream *stream void MerchantRecipeList::load(CompoundTag *tag) { - ListTag *list = (ListTag *) tag->getList(L"Recipes"); + ListTag *list = tag->getList(L"Recipes"); for (int i = 0; i < list->size(); i++) { - CompoundTag *recipeTag = list->get(i); + CompoundTag *recipeTag = (CompoundTag*) list->get(i); m_recipes.push_back(new MerchantRecipe(recipeTag)); } } @@ -192,4 +192,4 @@ size_t MerchantRecipeList::size() bool MerchantRecipeList::empty() { return m_recipes.empty(); -} \ No newline at end of file +} diff --git a/Minecraft.World/Entities/Entity.cpp b/Minecraft.World/Entities/Entity.cpp index 9c88a00e2..b47749604 100644 --- a/Minecraft.World/Entities/Entity.cpp +++ b/Minecraft.World/Entities/Entity.cpp @@ -1342,13 +1342,15 @@ void Entity::saveWithoutId(CompoundTag *entityTag) void Entity::load(CompoundTag *tag) { - ListTag *pos = (ListTag *) tag->getList(L"Pos"); - ListTag *motion = (ListTag *) tag->getList(L"Motion"); - ListTag *rotation = (ListTag *) tag->getList(L"Rotation"); + // 4jcraft changed c style cast of templated class + // to getting the actual type and casting when needed + ListTag *pos = tag->getList(L"Pos"); + ListTag *motion = tag->getList(L"Motion"); + ListTag *rotation = tag->getList(L"Rotation"); - xd = motion->get(0)->data; - yd = motion->get(1)->data; - zd = motion->get(2)->data; + xd = ((DoubleTag*)motion->get(0))->data; + yd = ((DoubleTag*)motion->get(1))->data; + zd = ((DoubleTag*)motion->get(2))->data; if (abs(xd) > 10.0) { @@ -1363,12 +1365,12 @@ void Entity::load(CompoundTag *tag) zd = 0; } - xo = xOld = x = pos->get(0)->data; - yo = yOld = y = pos->get(1)->data; - zo = zOld = z = pos->get(2)->data; + xo = xOld = x = ((DoubleTag*)pos->get(0))->data; + yo = yOld = y = ((DoubleTag*)pos->get(1))->data; + zo = zOld = z = ((DoubleTag*)pos->get(2))->data; - yRotO = yRot = rotation->get(0)->data; - xRotO = xRot = rotation->get(1)->data; + yRotO = yRot = ((FloatTag*)rotation->get(0))->data; + xRotO = xRot = ((FloatTag*)rotation->get(1))->data; fallDistance = tag->getFloat(L"FallDistance"); onFire = tag->getShort(L"Fire"); diff --git a/Minecraft.World/Level/RandomLevelSource.cpp b/Minecraft.World/Level/RandomLevelSource.cpp index b18278516..0dad9dd00 100644 --- a/Minecraft.World/Level/RandomLevelSource.cpp +++ b/Minecraft.World/Level/RandomLevelSource.cpp @@ -654,8 +654,8 @@ void RandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) pprandom->setSeed(level->getSeed()); __int64 xScale = pprandom->nextLong() / 2 * 2 + 1; __int64 zScale = pprandom->nextLong() / 2 * 2 + 1; - // 4jcraft added casts to u, holy moly, the getSeed is 64 bit and the result is 32... - pprandom->setSeed((((uint64_t)(int64_t)xt * (uint64_t)(int64_t)xScale) + ((uint64_t)(int64_t)zt * (uint64_t)(int64_t)zScale)) ^ level->getSeed()); + // 4jcraft added casts to a higher int and unsigned + pprandom->setSeed((((uint64_t)xt * (uint64_t)xScale) + ((uint64_t)zt * (uint64_t)zScale)) ^ level->getSeed()); bool hasVillage = false; diff --git a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp index e31fab3c5..a0c8c2d75 100644 --- a/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp +++ b/Minecraft.World/Level/Storage/McRegionChunkStorage.cpp @@ -80,7 +80,7 @@ LevelChunk *McRegionChunkStorage::load(Level *level, int x, int z) { // 4jcraft fixed cast from int to int64 and taking the mask of the upper bits // and cast to unsigned - __int64 index = ((uint64_t)(uint32_t)(x) << 32) | (((uint64_t)(uint32_t)(z))); + uint64_t index = ((uint64_t)(uint32_t)(x) << 32) | (((uint64_t)(uint32_t)(z))); AUTO_VAR(it, m_entityData.find(index)); if(it != m_entityData.end()) @@ -237,7 +237,8 @@ void McRegionChunkStorage::saveEntities(Level *level, LevelChunk *levelChunk) { #ifdef SPLIT_SAVES PIXBeginNamedEvent(0,"Saving entities"); - __int64 index = ((__int64)(levelChunk->x) << 32) | (((__int64)(levelChunk->z))&0x00000000FFFFFFFF); + // 4j added cast to unsigned and changed index to u + uint64_t index = ((uint64_t)(uint32_t)(levelChunk->x) << 32) | (((uint64_t)(uint32_t)(levelChunk->z))); delete m_entityData[index].data; diff --git a/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp b/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp index 4af91f84d..8b3864211 100644 --- a/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/HellRandomLevelSource.cpp @@ -432,7 +432,8 @@ void HellRandomLevelSource::postProcess(ChunkSource *parent, int xt, int zt) pprandom->setSeed(level->getSeed()); __int64 xScale = pprandom->nextLong() / 2 * 2 + 1; __int64 zScale = pprandom->nextLong() / 2 * 2 + 1; - pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); + // 4jcraft added casts to a higher int and unsigned + pprandom->setSeed((((uint64_t)xt * (uint64_t)xScale) + ((uint64_t)zt * (uint64_t)zScale)) ^ level->getSeed()); netherBridgeFeature->postProcess(level, pprandom, xt, zt); diff --git a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp index 7280ea617..5e095e4e7 100644 --- a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp @@ -375,7 +375,8 @@ void TheEndLevelRandomLevelSource::postProcess(ChunkSource *parent, int xt, int pprandom->setSeed(level->getSeed()); __int64 xScale = pprandom->nextLong() / 2 * 2 + 1; __int64 zScale = pprandom->nextLong() / 2 * 2 + 1; - pprandom->setSeed(((xt * xScale) + (zt * zScale)) ^ level->getSeed()); + // 4jcraft added cast to higher int and unsigned + pprandom->setSeed((((uint64_t)xt * xScale) + ((uint64_t)zt * zScale)) ^ level->getSeed()); Biome *biome = level->getBiome(xo + 16, zo + 16); biome->decorate(level, pprandom, xo, zo); // 4J - passing pprandom rather than level->random here to make this consistent with our parallel world generation From 69a8ce84b9ca0e4aec202d1438ab50cd4da1857a Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 17:28:13 +0100 Subject: [PATCH 13/22] giant batch BOOOOM --- Minecraft.Client/Level/MultiPlayerLevel.cpp | 12 ++++++------ Minecraft.Client/Level/ServerLevel.cpp | 6 ++++-- .../Platform/Common/Tutorial/Tutorial.cpp | 5 ++++- Minecraft.Client/Player/ServerPlayer.cpp | 5 ++++- Minecraft.World/AI/Navigation/Node.cpp | 5 +++-- .../Network/Packets/ChunkTilesUpdatePacket.cpp | 5 +++-- Minecraft.World/Util/JavaIntHash.h | 7 ++++--- Minecraft.World/Util/Random.cpp | 5 +++-- 8 files changed, 31 insertions(+), 19 deletions(-) diff --git a/Minecraft.Client/Level/MultiPlayerLevel.cpp b/Minecraft.Client/Level/MultiPlayerLevel.cpp index 0ed7f1b16..dc901fef7 100644 --- a/Minecraft.Client/Level/MultiPlayerLevel.cpp +++ b/Minecraft.Client/Level/MultiPlayerLevel.cpp @@ -702,12 +702,12 @@ void MultiPlayerLevel::animateTickDoWork() for( AUTO_VAR(it, chunksToAnimate.begin()); it != chunksToAnimate.end(); it++ ) { int packed = *it; - int cx = ( packed << 8 ) >> 24; - int cy = ( packed << 16 ) >> 24; - int cz = ( packed << 24 ) >> 24; - cx <<= 3; - cy <<= 3; - cz <<= 3; + // 4jcraft changed the extraction logic to be safe + // constantly shifting a signed integer + int cx = (int8_t)(packed >> 16) * 8; + int cy = (int8_t)(packed >> 8) * 8; + int cz = (int8_t)packed * 8; + int x = cx + random->nextInt(8); int y = cy + random->nextInt(8); int z = cz + random->nextInt(8); diff --git a/Minecraft.Client/Level/ServerLevel.cpp b/Minecraft.Client/Level/ServerLevel.cpp index f4e5d5aeb..ae949c831 100644 --- a/Minecraft.Client/Level/ServerLevel.cpp +++ b/Minecraft.Client/Level/ServerLevel.cpp @@ -475,7 +475,8 @@ void ServerLevel::tickTiles() // 4J - changes here brought forrward from 1.2.3 if (random->nextInt(16) == 0) { - randValue = randValue * 3 + addend; + //4jcraft added cast to unsigned + randValue = (unsigned)randValue * 3 + (unsigned)addend; int val = (randValue >> 2); int x = (val & 15); int z = ((val >> 8) & 15); @@ -1414,7 +1415,8 @@ int ServerLevel::runUpdate(void* lpParam) for (int j = 0; j < 80; j++) { - m_randValue[iLev] = m_randValue[iLev] * 3 + m_level[iLev]->addend; + // 4jcraft added cast to unsigned + m_randValue[iLev] = (unsigned) m_randValue[iLev] * 3 + (unsigned) m_level[iLev]->addend; int val = (m_randValue[iLev] >> 2); int x = (val & 15); if( ( x < minx ) || ( x > maxx ) ) continue; diff --git a/Minecraft.Client/Platform/Common/Tutorial/Tutorial.cpp b/Minecraft.Client/Platform/Common/Tutorial/Tutorial.cpp index 28cac32c2..9d44b000d 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/Tutorial.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/Tutorial.cpp @@ -343,6 +343,9 @@ Tutorial::Tutorial(int iPad, bool isFullTutorial /*= false*/) : m_iPad( iPad ) m_bHasTickedOnce = false; m_firstTickTime = 0; + // 4jcraft added, not initialized + m_bSceneIsSplitscreen = false; + m_lastMessage = NULL; lastMessageTime = 0; @@ -1258,7 +1261,7 @@ void Tutorial::tick() else { // if we've changed mode, we may need to change scene - if(m_bSceneIsSplitscreen!=(app.GetLocalPlayerCount()>1)) + if(m_bSceneIsSplitscreen != (app.GetLocalPlayerCount() > 1)) { #ifdef _XBOX app.TutorialSceneNavigateBack(m_iPad); diff --git a/Minecraft.Client/Player/ServerPlayer.cpp b/Minecraft.Client/Player/ServerPlayer.cpp index d7eae5841..9f7081106 100644 --- a/Minecraft.Client/Player/ServerPlayer.cpp +++ b/Minecraft.Client/Player/ServerPlayer.cpp @@ -45,6 +45,9 @@ ServerPlayer::ServerPlayer(MinecraftServer *server, Level *level, const std::wst m_enteredEndExitPortal = false; lastCarried = ItemInstanceArray(5); viewDistance = 10; + + // 4jcraft added (0 initialized) + m_lastDamageSource = eTelemetryChallenges_Unknown; // gameMode->player = this; // 4J - removed to avoid use of shared_from_this in ctor, now set up externally this->gameMode = gameMode; @@ -540,7 +543,7 @@ void ServerPlayer::doTickB(bool ignorePortal) if (getHealth() != lastSentHealth || lastSentFood != foodData.getFoodLevel() || ((foodData.getSaturationLevel() == 0) != lastFoodSaturationZero)) { - // 4J Stu - Added m_lastDamageSource for telemetry + // 4J Stu - Added m_lastDamageSource for telemetry //4jcraft, nice but you never initialized it connection->send( std::shared_ptr( new SetHealthPacket(getHealth(), foodData.getFoodLevel(), foodData.getSaturationLevel(), m_lastDamageSource) ) ); lastSentHealth = getHealth(); lastSentFood = foodData.getFoodLevel(); diff --git a/Minecraft.World/AI/Navigation/Node.cpp b/Minecraft.World/AI/Navigation/Node.cpp index 061471362..a9c24caab 100644 --- a/Minecraft.World/AI/Navigation/Node.cpp +++ b/Minecraft.World/AI/Navigation/Node.cpp @@ -30,7 +30,8 @@ hash(createHash(x, y, z)) int Node::createHash(const int x, const int y, const int z) { - return (y & 0xff) | ((x & 0x7fff) << 8) | ((z & 0x7fff) << 24) | ((x < 0) ? 0x0080000000 : 0) | ((z < 0) ? 0x0000008000 : 0); + // 4jcraft added cast to higher value to be representable after shift + return (y & 0xff) | (((int64_t)x & 0x7fff) << 8) | (((int64_t)z & 0x7fff) << 24) | ((x < 0) ? 0x0080000000 : 0) | ((z < 0) ? 0x0000008000 : 0); } float Node::distanceTo(Node *to) @@ -72,4 +73,4 @@ bool Node::inOpenSet() std::wstring Node::toString() { return _toString(x) + L", " + _toString(y) + L", " + _toString(z); -} \ No newline at end of file +} diff --git a/Minecraft.World/Network/Packets/ChunkTilesUpdatePacket.cpp b/Minecraft.World/Network/Packets/ChunkTilesUpdatePacket.cpp index 48ecbf33a..d1e6cdae2 100644 --- a/Minecraft.World/Network/Packets/ChunkTilesUpdatePacket.cpp +++ b/Minecraft.World/Network/Packets/ChunkTilesUpdatePacket.cpp @@ -54,8 +54,9 @@ void ChunkTilesUpdatePacket::read(DataInputStream *dis) //throws IOException #ifdef _LARGE_WORLDS xc = dis->readShort(); zc = dis->readShort(); - xc = ( xc << 16 ) >> 16; - zc = ( zc << 16 ) >> 16; + // 4jcraft changed shift back and forth to a down cast + xc = (int16_t) xc; + zc = (int16_t) zc; #else xc = dis->read(); zc = dis->read(); diff --git a/Minecraft.World/Util/JavaIntHash.h b/Minecraft.World/Util/JavaIntHash.h index 7a1ba7710..ca79c038f 100644 --- a/Minecraft.World/Util/JavaIntHash.h +++ b/Minecraft.World/Util/JavaIntHash.h @@ -9,11 +9,12 @@ struct IntKeyHash { int operator() (const int &k) const { - int h = k; + // 4jcraft added h to be unsigned, to not cast it later + unsigned int h = k; h += ~(h << 9); - h ^= (((unsigned int)h) >> 14); + h ^= (h >> 14); h += (h << 4); - h ^= (((unsigned int)h) >> 10); + h ^= (h >> 10); return h; } }; diff --git a/Minecraft.World/Util/Random.cpp b/Minecraft.World/Util/Random.cpp index 10f58d938..509189a8f 100644 --- a/Minecraft.World/Util/Random.cpp +++ b/Minecraft.World/Util/Random.cpp @@ -88,7 +88,7 @@ int Random::nextInt(int n) if ((n & -n) == n) // i.e., n is a power of 2 - // 4jcraft added casts to unsigned + // 4jcraft added casts to unsigned (and uint64) return (unsigned int)(((__uint64)next(31) * n) >> 31); // 4J Stu - Made __int64 instead of long int bits, val; @@ -96,7 +96,8 @@ int Random::nextInt(int n) { bits = next(31); val = bits % n; - } while(bits - val + (n-1) < 0); + // 4jcraft added a cast to prevent overflow + } while((int64_t) bits - val + (n-1) < 0); return val; } From b763a92f8e5de957b4815fad64675b1802680680 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 17:42:03 +0100 Subject: [PATCH 14/22] I FOUND I FOUND IT OMG --- Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp index 645d2c13e..ffb873643 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp +++ b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp @@ -794,6 +794,15 @@ BOOL ConsoleSaveFileSplit::zeroFile(FileEntry *file, DWORD nNumberOfBytesToWrite return 0; } + // 4jcraft added: memset(NULL + 0, 0, 0); was called + // no bytes need to be written, hence there you go + if(nNumberOfBytesToWrite == 0) { + if(lpNumberOfBytesWritten) { + *lpNumberOfBytesWritten = 0; + } + return 1; + } + LockSaveAccess(); if( file->isRegionFile() ) From cc65f7ee29ed6d9c5640088234dd79365f536229 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 18:01:00 +0100 Subject: [PATCH 15/22] FINALLY LOADS IN, crashes when clicking :( --- .../Rendering/EntityRenderers/TileRenderer.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp index 30d05c2b3..4b248d31e 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp @@ -3582,9 +3582,10 @@ bool TileRenderer::tesselateCrossInWorld( Tile* tt, int x, int y, int z ) if (tt == Tile::tallgrass) { - __int64 seed = (x * 3129871) ^ (z * 116129781l) ^ (y); - seed = seed * seed * 42317861 + seed * 11; - + // 4jcraft add a bunch of casts to prevent overflow (i pray to god) + int64_t seed = ((int64_t)x * 3129871) ^ ((int64_t)z * 116129781L) ^ ((int64_t)y); + seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 42317861ULL) + ((uint64_t)seed * 11ULL)); + xt += ((((seed >> 16) & 0xf) / 15.0f) - 0.5f) * 0.5f; yt += ((((seed >> 20) & 0xf) / 15.0f) - 1.0f) * 0.2f; zt += ((((seed >> 24) & 0xf) / 15.0f) - 0.5f) * 0.5f; From faa4a989ce4ee94a1088770614a9e9e20ced2df8 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 18:49:36 +0100 Subject: [PATCH 16/22] new blob --- Minecraft.Client/Platform/Common/App_enums.h | 5 +++-- .../Platform/Common/UI/UIComponent_TutorialPopup.cpp | 6 ++++++ .../Rendering/EntityRenderers/MinecartRenderer.cpp | 7 ++++--- .../Rendering/EntityRenderers/TileRenderer.cpp | 6 +++--- Minecraft.Client/UI/Font.cpp | 3 ++- Minecraft.World/Level/Level.cpp | 2 +- 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Minecraft.Client/Platform/Common/App_enums.h b/Minecraft.Client/Platform/Common/App_enums.h index d4f639e05..7f6c6de19 100644 --- a/Minecraft.Client/Platform/Common/App_enums.h +++ b/Minecraft.Client/Platform/Common/App_enums.h @@ -809,7 +809,8 @@ enum EControllerActions ACTION_MENU_OK, ACTION_MENU_CANCEL, - ACTION_MAX_MENU = ACTION_MENU_CANCEL, + // 4jcraft added, off by one + ACTION_MAX_MENU = ACTION_MENU_CANCEL + 1, MINECRAFT_ACTION_JUMP, MINECRAFT_ACTION_FORWARD, @@ -911,4 +912,4 @@ enum eMCLang eMCLang_elGR, eMCLang_nnNO, eMCLang_skSK, -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Platform/Common/UI/UIComponent_TutorialPopup.cpp b/Minecraft.Client/Platform/Common/UI/UIComponent_TutorialPopup.cpp index 333e5dd95..dceb0f831 100644 --- a/Minecraft.Client/Platform/Common/UI/UIComponent_TutorialPopup.cpp +++ b/Minecraft.Client/Platform/Common/UI/UIComponent_TutorialPopup.cpp @@ -23,6 +23,9 @@ UIComponent_TutorialPopup::UIComponent_TutorialPopup(int iPad, void *initData, U m_bSplitscreenGamertagVisible = false; m_labelDescription.init(L""); + + // 4jcraft added + m_tutorial = NULL; } std::wstring UIComponent_TutorialPopup::getMoviePath() @@ -69,6 +72,9 @@ void UIComponent_TutorialPopup::SetTutorialDescription(TutorialPopupInfo *info) { m_interactScene = info->interactScene; + // 4jcraft added + m_tutorial = info->tutorial; + std::wstring parsed = _SetIcon(info->icon, info->iAuxVal, info->isFoil, info->desc); parsed = _SetImage( parsed ); parsed = ParseDescription(m_iPad, parsed); diff --git a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp index 9948ab907..e5928f55b 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/MinecartRenderer.cpp @@ -17,8 +17,9 @@ void MinecartRenderer::render(std::shared_ptr _cart, double x, double y, glPushMatrix(); - __int64 seed = cart->entityId * 493286711l; - seed = seed * seed * 4392167121l + seed * 98761; + // 4jcraft added a bunch of casts to prever overflow + int64_t seed = (int64_t)((uint64_t)cart->entityId * 493286711ULL); + seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 4392167121ULL) + ((uint64_t)seed * 98761ULL)); float xo = ((((seed >> 16) & 0x7) + 0.5f) / 8.0f - 0.5f) * 0.004f; float yo = ((((seed >> 20) & 0x7) + 0.5f) / 8.0f - 0.5f) * 0.004f; @@ -103,4 +104,4 @@ void MinecartRenderer::render(std::shared_ptr _cart, double x, double y, model->render(cart, 0, 0, -0.1f, 0, 0, 1 / 16.0f, true); glPopMatrix(); -} \ No newline at end of file +} diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp index 4b248d31e..a5961ab02 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp @@ -3822,9 +3822,9 @@ bool TileRenderer::tesselateLilypadInWorld(Tile *tt, int x, int y, int z) float u1 = tex->getU1(true); float v1 = tex->getV1(true); - __int64 seed = (x * 3129871) ^ (z * 116129781l) ^ (y); - seed = seed * seed * 42317861 + seed * 11; - + // 4jcraft add a bunch of casts to prevent overflow (i pray to god) + int64_t seed = ((int64_t)x * 3129871) ^ ((int64_t)z * 116129781L) ^ ((int64_t)y); + seed = (int64_t)(((uint64_t)seed * (uint64_t)seed * 42317861ULL) + ((uint64_t)seed * 11ULL)); int dir = (int) ((seed >> 16) & 0x3); diff --git a/Minecraft.Client/UI/Font.cpp b/Minecraft.Client/UI/Font.cpp index 3ece2e8bb..096e548a3 100644 --- a/Minecraft.Client/UI/Font.cpp +++ b/Minecraft.Client/UI/Font.cpp @@ -258,7 +258,8 @@ void Font::draw(const std::wstring& str, int x, int y, int color, bool dropShado // if not set if (dropShadow) // divide RGB by 4, preserve alpha - color = (color & 0xfcfcfc) >> 2 | (color & (-1 << 24)); + // 4jcraft changed -1 << 24 to the value of 1 (0xFF FF FF FF) + color = (color & 0xfcfcfc) >> 2 | (color & (0xFFFFFFFF << 24)); glColor4f((color >> 16 & 255) / 255.0F, (color >> 8 & 255) / 255.0F, (color & 255) / 255.0F, (color >> 24 & 255) / 255.0F); diff --git a/Minecraft.World/Level/Level.cpp b/Minecraft.World/Level/Level.cpp index c09680f92..536703187 100644 --- a/Minecraft.World/Level/Level.cpp +++ b/Minecraft.World/Level/Level.cpp @@ -3228,7 +3228,7 @@ void Level::tickClientSideTiles(int xo, int zo, LevelChunk *lc) if (delayUntilNextMoodSound == 0) { - randValue = randValue * 3 + addend; + randValue = (unsigned) randValue * 3 + (unsigned) addend; int val = (randValue >> 2); int x = (val & 15); int z = ((val >> 8) & 15); From 1712cd4f471ade0649c234db92ee4167cd6c24ad Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 19:04:02 +0100 Subject: [PATCH 17/22] the tutorial does not crash --- Minecraft.World/IO/NBT/CompoundTag.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Minecraft.World/IO/NBT/CompoundTag.h b/Minecraft.World/IO/NBT/CompoundTag.h index 45b840538..e41a7ce8f 100644 --- a/Minecraft.World/IO/NBT/CompoundTag.h +++ b/Minecraft.World/IO/NBT/CompoundTag.h @@ -194,8 +194,11 @@ public: ListTag *getList(const wchar_t * name) { - if (tags.find(name) == tags.end()) return new ListTag(name); - return (ListTag *) tags[name]; + // 4jcraft changed this function to not do a c style cast + // of a templated class + auto it = tags.find(name); + if(it == tags.end()) return new ListTag(name); + return dynamic_cast*>(it->second); } bool getBoolean(const wchar_t *string) From ec82ee1ea12eee0ce633556c72dc7598fb53869a Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 19:22:28 +0100 Subject: [PATCH 18/22] final commit --- Minecraft.Client/Rendering/Tesselator.cpp | 9 +++++---- Minecraft.World/Util/I18n.cpp | 3 ++- Minecraft.World/Util/I18n.h | 4 ++-- Minecraft.World/Util/Language.cpp | 12 +++++++++--- Minecraft.World/Util/Language.h | 4 ++-- debug.sh | 7 ------- run.sh | 7 ------- 7 files changed, 20 insertions(+), 26 deletions(-) delete mode 100755 debug.sh delete mode 100755 run.sh diff --git a/Minecraft.Client/Rendering/Tesselator.cpp b/Minecraft.Client/Rendering/Tesselator.cpp index 821ec037b..fafea37ef 100644 --- a/Minecraft.Client/Rendering/Tesselator.cpp +++ b/Minecraft.Client/Rendering/Tesselator.cpp @@ -1049,9 +1049,10 @@ void Tesselator::normal(float x, float y, float z) int8_t zz = (int8_t) (z * 127); _normal = (xx & 0xff) | ((yy & 0xff) << 8) | ((zz & 0xff) << 16); #else - uint8_t xx = (uint8_t) (x * 127); - uint8_t yy = (uint8_t) (y * 127); - uint8_t zz = (uint8_t) (z * 127); + // 4jcraft copied the PSVITA branch, read comment above + int8_t xx = (int8_t) (x * 127); + int8_t yy = (int8_t) (y * 127); + int8_t zz = (int8_t) (z * 127); _normal = (xx & 0xff) | ((yy & 0xff) << 8) | ((zz & 0xff) << 16); #endif } @@ -1086,4 +1087,4 @@ bool Tesselator::hasMaxVertices() #else return false; #endif -} \ No newline at end of file +} diff --git a/Minecraft.World/Util/I18n.cpp b/Minecraft.World/Util/I18n.cpp index f0ec08b73..1d45ab5fb 100644 --- a/Minecraft.World/Util/I18n.cpp +++ b/Minecraft.World/Util/I18n.cpp @@ -3,7 +3,8 @@ #include "I18n.h" Language *I18n::lang = Language::getInstance(); -std::wstring I18n::get(const std::wstring& id, ...) +// 4jcraft const & into va_start is ub +std::wstring I18n::get(std::wstring id, ...) { #ifdef __PSVITA__ // 4J - vita doesn't like having a reference type as the last parameter passed to va_start - we shouldn't need this method anyway return L""; diff --git a/Minecraft.World/Util/I18n.h b/Minecraft.World/Util/I18n.h index 601070039..02fc0bc80 100644 --- a/Minecraft.World/Util/I18n.h +++ b/Minecraft.World/Util/I18n.h @@ -10,6 +10,6 @@ private: static Language *lang; public: - static std::wstring get(const std::wstring& id, ...); + static std::wstring get(std::wstring id, ...); static std::wstring get(const std::wstring& id, va_list args); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Util/Language.cpp b/Minecraft.World/Util/Language.cpp index 3dbe7cfa6..9ffbf4c2f 100644 --- a/Minecraft.World/Util/Language.cpp +++ b/Minecraft.World/Util/Language.cpp @@ -3,7 +3,7 @@ // 4J - TODO - properly implement -Language *Language::singleton = new Language(); +Language *Language::singleton = nullptr; Language::Language() { @@ -11,6 +11,11 @@ Language::Language() Language *Language::getInstance() { + // 4jcraft, fixes static init fiassco in I18n.cpp + if(singleton == nullptr) { + singleton = new Language(); + } + return singleton; } @@ -20,7 +25,8 @@ std::wstring Language::getElement(const std::wstring& elementId) return elementId; } */ -std::wstring Language::getElement(const std::wstring& elementId, ...) +// 4jcraft changed, again const reference into va_start, std forbids +std::wstring Language::getElement(std::wstring elementId, ...) { #ifdef __PSVITA__ // 4J - vita doesn't like having a reference type as the last parameter passed to va_start - we shouldn't need this method anyway return L""; @@ -45,4 +51,4 @@ std::wstring Language::getElementName(const std::wstring& elementId) std::wstring Language::getElementDescription(const std::wstring& elementId) { return elementId; -} \ No newline at end of file +} diff --git a/Minecraft.World/Util/Language.h b/Minecraft.World/Util/Language.h index 3720258b4..b04ede3d1 100644 --- a/Minecraft.World/Util/Language.h +++ b/Minecraft.World/Util/Language.h @@ -7,8 +7,8 @@ private: public: Language(); static Language *getInstance(); - std::wstring getElement(const std::wstring& elementId, ...); + std::wstring getElement(std::wstring elementId, ...); std::wstring getElement(const std::wstring& elementId, va_list args); std::wstring getElementName(const std::wstring& elementId); std::wstring getElementDescription(const std::wstring& elementId); -}; \ No newline at end of file +}; diff --git a/debug.sh b/debug.sh deleted file mode 100755 index e2d2bc292..000000000 --- a/debug.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -meson setup build -Db_sanitize=address,leak,undefined -Dcpp_args=-fno-sanitize-recover=all -Dc_args=-fno-sanitize-recover=all && \ -meson compile -C build && \ -cd build/Minecraft.Client/ && \ -gdb -tui ./Minecraft.Client && \ -cd ../.. diff --git a/run.sh b/run.sh deleted file mode 100755 index bd0a0c27b..000000000 --- a/run.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash - -meson setup build -Db_sanitize=address,leak,undefined -Dcpp_args=-fno-sanitize-recover=all -Dc_args=-fno-sanitize-recover=all && \ -meson compile -C build && \ -cd build/Minecraft.Client/ && \ -UBSAN_OPTIONS=print_stacktrace=1 ./Minecraft.Client && \ -cd ../.. From c0198bb8a7d81a29ca49988ab2145ebc7c8463b1 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 19:41:31 +0100 Subject: [PATCH 19/22] missed one error with clang --- Minecraft.World/Util/JavaMath.cpp | 17 +++++++++++++++-- Minecraft.World/Util/Mth.cpp | 6 +++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Minecraft.World/Util/JavaMath.cpp b/Minecraft.World/Util/JavaMath.cpp index 3037d5a57..21389bb2b 100644 --- a/Minecraft.World/Util/JavaMath.cpp +++ b/Minecraft.World/Util/JavaMath.cpp @@ -36,7 +36,20 @@ double Math::random() //the value of the argument rounded to the nearest long value. __int64 Math::round( double d ) { - return (__int64)floor( d + 0.5 ); + // 4jcraft fixes the fact that if double is a huge + // number than the cast of d to int64_t overflows + + d = floor( d + 0.5 ); + + // if smaller or bigger than representable int64 than return the max + if(d >= (double)INT64_MAX) { + return INT64_MAX; + + } else if (d <= (double)INT64_MIN) { + return INT64_MIN; + } + + return (int64_t) d; } int Math::_max(int a, int b) @@ -73,4 +86,4 @@ double Math::wrapDegrees(double input) if (input >= 180.0) input -= 360.0; if (input < -180.0) input += 360.0; return input; -} \ No newline at end of file +} diff --git a/Minecraft.World/Util/Mth.cpp b/Minecraft.World/Util/Mth.cpp index 8dd22cc72..54f7fb605 100644 --- a/Minecraft.World/Util/Mth.cpp +++ b/Minecraft.World/Util/Mth.cpp @@ -25,13 +25,13 @@ void Mth::init() float Mth::sin(float i) { if(_sin == NULL) init(); // 4J - added - return _sin[(int) (i * sinScale) & 65535]; + return _sin[(int)fmodf(i * sinScale, 65536.0f) & 65535]; } float Mth::cos(float i) { if(_sin == NULL) init(); // 4J - added - return _sin[(int) (i * sinScale + 65536 / 4) & 65535]; + return _sin[(int)fmodf(i * sinScale + 16384.0f, 65536.0f) & 65535]; } float Mth::sqrt(float x) @@ -169,4 +169,4 @@ double Mth::wrapDegrees(double input) bool Mth::almostEquals( double double1, double double2, double precision) { return (std::abs(double1 - double2) <= precision); -} \ No newline at end of file +} From 5d88fa9cf50880e1923d93c4621167e0d83b3858 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Wed, 11 Mar 2026 20:02:11 +0100 Subject: [PATCH 20/22] add explanation --- Minecraft.World/Util/Mth.cpp | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/Minecraft.World/Util/Mth.cpp b/Minecraft.World/Util/Mth.cpp index 54f7fb605..b290b5877 100644 --- a/Minecraft.World/Util/Mth.cpp +++ b/Minecraft.World/Util/Mth.cpp @@ -10,13 +10,16 @@ const float Mth::RADDEG = 180.0f / PI; float *Mth::_sin = NULL; +// 4jcraft for clarity +constexpr size_t SIN_TAB_CNT = 65536; + const float Mth::sinScale = 65536.0f / (float) (PI * 2); // 4J - added - was in static constructor void Mth::init() { - _sin = new float[65536]; - for (int i = 0; i < 65536; i++) + _sin = new float[SIN_TAB_CNT]; + for (int i = 0; i < SIN_TAB_CNT; i++) { _sin[i] = (float) ::sin(i * PI * 2 / 65536.0f); } @@ -24,16 +27,27 @@ void Mth::init() float Mth::sin(float i) { + if(_sin == NULL) init(); // 4J - added - return _sin[(int)fmodf(i * sinScale, 65536.0f) & 65535]; + + // 4jcraft changed, what ever this was, it was not safe + // fmodf returns between -65536 and 65536 (casted) + // last end is there to shift it into 0 to 65535 + + return _sin[(int32_t) fmodf(i * sinScale, (float) SIN_TAB_CNT) & (SIN_TAB_CNT - 1)]; } float Mth::cos(float i) { if(_sin == NULL) init(); // 4J - added - return _sin[(int)fmodf(i * sinScale + 16384.0f, 65536.0f) & 65535]; + // 4jcraft same thing as ::sin but shift by SIN_TAB_CNT / 4 + // which is aquivalent to shift by pi / 2 + // and again the same modulo logic to cramp and map it onto the computed table + + return _sin[(int32_t) fmodf(i * sinScale + ((float) SIN_TAB_CNT / 4), (float)SIN_TAB_CNT) & (SIN_TAB_CNT - 1)]; } + float Mth::sqrt(float x) { return (float) ::sqrt(x); From 6d952e24f5e76940dfa2c504c845634d8a562aa7 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Thu, 12 Mar 2026 16:42:36 +0100 Subject: [PATCH 21/22] revising everything --- Minecraft.Client/Level/ServerLevel.cpp | 1 + .../Platform/Common/DLC/DLCManager.cpp | 26 +++++++++---------- .../GameRules/LevelGenerationOptions.cpp | 1 + .../Network/PlatformNetworkManagerStub.cpp | 1 + .../IO/Files/ConsoleSaveFileSplit.cpp | 1 + Minecraft.World/Util/Mth.cpp | 4 +-- Minecraft.World/Util/Random.cpp | 6 ++--- .../WorldGen/Features/LargeFeature.cpp | 4 +-- 8 files changed, 24 insertions(+), 20 deletions(-) diff --git a/Minecraft.Client/Level/ServerLevel.cpp b/Minecraft.Client/Level/ServerLevel.cpp index ae949c831..9657a3511 100644 --- a/Minecraft.Client/Level/ServerLevel.cpp +++ b/Minecraft.Client/Level/ServerLevel.cpp @@ -632,6 +632,7 @@ std::vector *ServerLevel::fetchTicksInChunk(LevelChunk *chunk, std::vector *results = new std::vector; ChunkPos *pos = chunk->getPos(); + // 4jcraft added cast to unsigned int west = (unsigned) pos->x << 4; int east = west + 16; int north =(unsigned) pos->z << 4; diff --git a/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp b/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp index 030030ddb..c87d2b85a 100644 --- a/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp +++ b/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp @@ -411,13 +411,13 @@ bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const std::string &pat } // a bunch of makros to reduce memcpy and offset boilerplate -#define DLC_READ_DWORD(buf, off) ({ DWORD _temp; memcpy(&_temp, (buf) + (off), sizeof(DWORD)); _temp; }) +#define DLC_READ_UINT(out, buf, off) memcpy(out, (buf) + (off), sizeof(unsigned int)) #define DLC_READ_PARAM(out, buf, off) memcpy((out), (buf) + (off), sizeof(C4JStorage::DLC_FILE_PARAM)) #define DLC_READ_DETAIL(out, buf, off) memcpy((out), (buf) + (off), sizeof(C4JStorage::DLC_FILE_DETAILS)) -// for details, read below in the function below +// for details, read in the function below #define DLC_PARAM_WSTR(buf, off) DLC_WSTRING((buf) + (off) + offsetof(C4JStorage::DLC_FILE_PARAM, wchData)) #define DLC_DETAIL_WSTR(buf, off) DLC_WSTRING((buf) + (off) + offsetof(C4JStorage::DLC_FILE_DETAILS, wchFile)) @@ -445,16 +445,13 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD // (scince bufferoffset after advancing by variable string length is not // guaranteed to be properly aligned, so casting to a scalar/struct is UB) - // those casts are dangerous and will crash on ARM cpus when the pointers are - // not properly aligned at the offset. this includes for casting into the storage - // structs and casting into an unsigned integer - // everything else is aquivalent. i did not concern myself with the fact that - // EOF was not checked a single time. the lion doesnt bother with making code safe. + // those casts coult be dangerous on e.g. ARM, because it doesnt handle + // missaligned loads, like x86/x64, so it would crash // WHO TF USES HUNGARIAN NOTATION - // safe, offset 0, aligned - unsigned int uiVersion=*(unsigned int *)pbData; + unsigned int uiVersion; + DLC_READ_UINT(&uiVersion, pbData, uiCurrentByte); uiCurrentByte+=sizeof(int); if(uiVersion < CURRENT_DLC_VERSION_NUM) @@ -465,7 +462,8 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD } pack->SetDataPointer(pbData); // safe, offset 4, aligned - unsigned int uiParameterCount=*(unsigned int *)&pbData[uiCurrentByte]; + unsigned int uiParameterCount; + DLC_READ_UINT(&uiParameterCount, pbData, uiCurrentByte); uiCurrentByte+=sizeof(int); C4JStorage::DLC_FILE_PARAM parBuf; @@ -485,7 +483,8 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD } //ulCurrentByte+=ulParameterCount * sizeof(C4JStorage::DLC_FILE_PARAM); - unsigned int uiFileCount = DLC_READ_DWORD(pbData, uiCurrentByte); + unsigned int uiFileCount; + DLC_READ_UINT(&uiFileCount, pbData, uiCurrentByte); uiCurrentByte+=sizeof(int); C4JStorage::DLC_FILE_DETAILS fileBuf; @@ -497,7 +496,7 @@ bool DLCManager::processDLCDataFile(DWORD &dwFilesProcessed, PBYTE pbData, DWORD dwTemp+=DLC_DETAIL_ADV(fileBuf.dwWchCount); DLC_READ_DETAIL(&fileBuf, pbData, dwTemp); } - PBYTE pbTemp=&pbData[dwTemp];//+ sizeof(C4JStorage::DLC_FILE_DETAILS)*ulFileCount; + PBYTE pbTemp = &pbData[dwTemp];//+ sizeof(C4JStorage::DLC_FILE_DETAILS)*ulFileCount; DLC_READ_DETAIL(&fileBuf, pbData, uiCurrentByte); for(unsigned int i=0;iprocessSchematic(chunkBox, chunk); } + // 4jcraft added cast to unsigned int cx = ((unsigned)chunk->x << 4); int cz = ((unsigned)chunk->z << 4); diff --git a/Minecraft.Client/Platform/Common/Network/PlatformNetworkManagerStub.cpp b/Minecraft.Client/Platform/Common/Network/PlatformNetworkManagerStub.cpp index 9dfc45a17..5e366e190 100644 --- a/Minecraft.Client/Platform/Common/Network/PlatformNetworkManagerStub.cpp +++ b/Minecraft.Client/Platform/Common/Network/PlatformNetworkManagerStub.cpp @@ -119,6 +119,7 @@ bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkMa m_pGameNetworkManager = pGameNetworkManager; m_flagIndexSize = flagIndexSize; g_pPlatformNetworkManager = this; + // 4jcraft added this, as it was never called m_pIQNet = new IQNet(); for( int i = 0; i < XUSER_MAX_COUNT; i++ ) { diff --git a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp index ffb873643..90778f02c 100644 --- a/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp +++ b/Minecraft.World/IO/Files/ConsoleSaveFileSplit.cpp @@ -1230,6 +1230,7 @@ bool ConsoleSaveFileSplit::GetNumericIdentifierFromName(const std::wstring &file swscanf_s(body, L"%d.%d.mcr", &x, &z ); // Pack full id + // 4jcraft added cast to unsigned id |= ( ( (unsigned int) x << 8 ) & 0x0000ff00 ); id |= ( z & 0x000000ff ); diff --git a/Minecraft.World/Util/Mth.cpp b/Minecraft.World/Util/Mth.cpp index b290b5877..752986135 100644 --- a/Minecraft.World/Util/Mth.cpp +++ b/Minecraft.World/Util/Mth.cpp @@ -21,7 +21,7 @@ void Mth::init() _sin = new float[SIN_TAB_CNT]; for (int i = 0; i < SIN_TAB_CNT; i++) { - _sin[i] = (float) ::sin(i * PI * 2 / 65536.0f); + _sin[i] = (float) ::sin(i * PI * 2 / (float) SIN_TAB_CNT); } } @@ -44,7 +44,7 @@ float Mth::cos(float i) // which is aquivalent to shift by pi / 2 // and again the same modulo logic to cramp and map it onto the computed table - return _sin[(int32_t) fmodf(i * sinScale + ((float) SIN_TAB_CNT / 4), (float)SIN_TAB_CNT) & (SIN_TAB_CNT - 1)]; + return _sin[(int32_t) fmodf(i * sinScale + ((float) SIN_TAB_CNT / 4), (float) SIN_TAB_CNT) & (SIN_TAB_CNT - 1)]; } diff --git a/Minecraft.World/Util/Random.cpp b/Minecraft.World/Util/Random.cpp index 509189a8f..20c92c588 100644 --- a/Minecraft.World/Util/Random.cpp +++ b/Minecraft.World/Util/Random.cpp @@ -88,8 +88,8 @@ int Random::nextInt(int n) if ((n & -n) == n) // i.e., n is a power of 2 - // 4jcraft added casts to unsigned (and uint64) - return (unsigned int)(((__uint64)next(31) * n) >> 31); // 4J Stu - Made __int64 instead of long + // 4jcraft added casts to unsigned (and uint64_t) + return (int)(((uint64_t)next(31) * n) >> 31); // 4J Stu - Made __int64 instead of long int bits, val; do @@ -109,7 +109,7 @@ float Random::nextFloat() __int64 Random::nextLong() { // 4jcraft added casts to unsigned - return (__uint64)((__uint64)next(32) << 32) + next(32); + return (int64_t)((uint64_t) next(32) << 32) + next(32); } bool Random::nextBoolean() diff --git a/Minecraft.World/WorldGen/Features/LargeFeature.cpp b/Minecraft.World/WorldGen/Features/LargeFeature.cpp index 187ec5dd1..caf3d040e 100644 --- a/Minecraft.World/WorldGen/Features/LargeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/LargeFeature.cpp @@ -28,8 +28,8 @@ void LargeFeature::apply(ChunkSource *ChunkSource, Level *level, int xOffs, int { for (int z = zOffs - r; z <= zOffs + r; z++) { - __int64 xx = (uint64_t) x * xScale; - __int64 zz = (uint64_t) z * zScale; + int64_t xx = (uint64_t) x * xScale; + int64_t zz = (uint64_t) z * zScale; random->setSeed(xx ^ zz ^ level->getSeed()); addFeature(level, x, z, xOffs, zOffs, blocks); } From 99c763e68a0b8c192d26d23c88ee527bc86bea79 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Thu, 12 Mar 2026 17:33:55 +0100 Subject: [PATCH 22/22] typo --- Minecraft.Client/Platform/Common/DLC/DLCManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp b/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp index c87d2b85a..7eaaffb51 100644 --- a/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp +++ b/Minecraft.Client/Platform/Common/DLC/DLCManager.cpp @@ -411,7 +411,7 @@ bool DLCManager::readDLCDataFile(DWORD &dwFilesProcessed, const std::string &pat } // a bunch of makros to reduce memcpy and offset boilerplate -#define DLC_READ_UINT(out, buf, off) memcpy(out, (buf) + (off), sizeof(unsigned int)) +#define DLC_READ_UINT(out, buf, off) memcpy((out), (buf) + (off), sizeof(unsigned int)) #define DLC_READ_PARAM(out, buf, off) memcpy((out), (buf) + (off), sizeof(C4JStorage::DLC_FILE_PARAM))