From a2d1f04c58c6f8892ead659e3671f6621b270528 Mon Sep 17 00:00:00 2001 From: "Echo J." Date: Mon, 9 Mar 2026 16:52:33 +0200 Subject: [PATCH 01/17] CI: Split debug build into a independent job This also means the bundle isn't being packaged for that build (as I don't think it's important) --- .github/workflows/build-linux.yml | 128 ++++++++++++++++-------------- 1 file changed, 67 insertions(+), 61 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index 42cb25d20..d4799065f 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -25,9 +25,6 @@ on: jobs: build-linux: runs-on: ubuntu-latest - concurrency: - group: build-linux-${{ github.ref }} - cancel-in-progress: true steps: - name: Checkout repository uses: actions/checkout@v4 @@ -77,16 +74,6 @@ jobs: export CCACHE_DIR="$CCACHE_DIR" meson setup build_meson --wipe --buildtype=release - - name: Configure Meson (debug) - env: - CC: "ccache clang" - CXX: "ccache clang++" - CCACHE_DIR: ${{ runner.temp }}/ccache - run: | - mkdir -p "$CCACHE_DIR" - export CCACHE_DIR="$CCACHE_DIR" - meson setup build_debug --wipe --buildtype=debug - - name: Build with Ninja env: CC: "ccache clang" @@ -97,15 +84,6 @@ jobs: # Use all available cores for faster parallel builds ninja -C build_meson -j$(nproc) -v - - name: Build Debug with Ninja - env: - CC: "ccache clang" - CXX: "ccache clang++" - CCACHE_DIR: ${{ runner.temp }}/ccache - run: | - export CCACHE_DIR="${{ runner.temp }}/ccache" - ninja -C build_debug -j$(nproc) -v - - name: Install patchelf run: sudo apt-get install -y patchelf @@ -185,47 +163,75 @@ jobs: echo "Bundle ready: $BUNDLE" ls -lh "$BUNDLE" "$BUNDLE/lib" - - name: Bundle debug executable + libraries - env: - GITHUB_SHA: ${{ github.sha }} - run: | - set -euo pipefail - EXE_PATH=build_debug/Minecraft.Client/Minecraft.Client - if [ ! -f "$EXE_PATH" ]; then - echo "ERROR: expected debug executable at $EXE_PATH" >&2 - ls -la build_debug || true - exit 1 - fi - - SHORT_SHA=$(echo "$GITHUB_SHA" | cut -c1-8) - BUNDLE=out/minecraft-client-linux-${SHORT_SHA}-debug - mkdir -p "$BUNDLE/lib" - - # Copy the binary - cp "$EXE_PATH" "$BUNDLE/Minecraft.Client.debug" - - # Collect non-system shared library dependencies and copy them in. - ldd "$EXE_PATH" \ - | awk '/=>/ { print $3 }' \ - | grep -v '^(' \ - | grep -Ev '/(libc|libm|libdl|libpthread|librt|libgcc_s|libstdc\+\+|ld-linux)[^/]*\.so' \ - | sort -u \ - | while read -r lib; do - [ -f "$lib" ] && cp "$lib" "$BUNDLE/lib/" || true - done - - # Patch the binary RPATH so it finds libs in ./lib at runtime - patchelf --set-rpath '$ORIGIN/lib' "$BUNDLE/Minecraft.Client.debug" - - # Keep a copy of the unstripped debug binary (symbols are already present in debug build) - echo "Debug bundle ready: $BUNDLE" - ls -lh "$BUNDLE" "$BUNDLE/lib" - - name: Upload artifact uses: actions/upload-artifact@v4 with: name: minecraft-client-linux-${{ github.sha }} - path: | - out/minecraft-client-linux-*/ - out/minecraft-client-linux-*-debug/ + path: out/minecraft-client-linux-*/ + retention-days: 7 + build-linux-debug: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install system dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential python3 python3-pip python3-setuptools libgl1-mesa-dev libglu1-mesa-dev libglfw3-dev libpng-dev pkg-config clang lld ccache libssl-dev + # Set a reasonable ccache size + ccache -M 5G || true + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + + - name: Cache pip packages + uses: actions/cache@v4 + with: + path: ~/.cache/pip + key: ${{ runner.os }}-pip-${{ hashFiles('.github/workflows/build-linux.yml') }} + + - name: Install Meson and Ninja (pip) + run: | + python -m pip install --upgrade pip + pip install meson ninja + + - name: Restore ccache + uses: actions/cache@v4 + with: + path: ~/.ccache + key: ${{ runner.os }}-ccache-debug-${{ hashFiles('**/meson.build') }} + + - name: Restore meson cache + uses: actions/cache@v4 + with: + path: ~/.cache/meson + key: ${{ runner.os }}-meson-debug-${{ hashFiles('**/meson.build') }} + + - name: Configure Meson (debug) + env: + CC: "ccache clang" + CXX: "ccache clang++" + CCACHE_DIR: ${{ runner.temp }}/ccache + run: | + mkdir -p "$CCACHE_DIR" + export CCACHE_DIR="$CCACHE_DIR" + meson setup build_debug --wipe --buildtype=debug + + - name: Build Debug with Ninja + env: + CC: "ccache clang" + CXX: "ccache clang++" + CCACHE_DIR: ${{ runner.temp }}/ccache + run: | + export CCACHE_DIR="${{ runner.temp }}/ccache" + ninja -C build_debug -j$(nproc) -v + + - name: Upload debug executable + uses: actions/upload-artifact@v4 + with: + name: minecraft-client-linux-debug_exe-${{ github.sha }} + path: build_debug/Minecraft.Client/Minecraft.Client retention-days: 7 From 4eaf02bfd086efa5a1f79413dcfe18fa46e9c91d Mon Sep 17 00:00:00 2001 From: "Echo J." Date: Mon, 9 Mar 2026 17:16:35 +0200 Subject: [PATCH 02/17] CI: Compile the client directly with Meson I'm not sure why Ninja had to be called here --- .github/workflows/build-linux.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index d4799065f..1a3896803 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -74,7 +74,7 @@ jobs: export CCACHE_DIR="$CCACHE_DIR" meson setup build_meson --wipe --buildtype=release - - name: Build with Ninja + - name: Build with Meson env: CC: "ccache clang" CXX: "ccache clang++" @@ -82,7 +82,7 @@ jobs: run: | export CCACHE_DIR="${{ runner.temp }}/ccache" # Use all available cores for faster parallel builds - ninja -C build_meson -j$(nproc) -v + meson compile -C build_meson -j $(nproc) -v Minecraft.Client - name: Install patchelf run: sudo apt-get install -y patchelf @@ -220,14 +220,15 @@ jobs: export CCACHE_DIR="$CCACHE_DIR" meson setup build_debug --wipe --buildtype=debug - - name: Build Debug with Ninja + - name: Build Debug with Meson env: CC: "ccache clang" CXX: "ccache clang++" CCACHE_DIR: ${{ runner.temp }}/ccache run: | export CCACHE_DIR="${{ runner.temp }}/ccache" - ninja -C build_debug -j$(nproc) -v + # Use all available cores for faster parallel builds + meson compile -C build_debug -j $(nproc) -v Minecraft.Client - name: Upload debug executable uses: actions/upload-artifact@v4 From fb39f1afde6c7f1ec531218fa498366a2d50425a Mon Sep 17 00:00:00 2001 From: "Echo J." Date: Mon, 9 Mar 2026 17:29:57 +0200 Subject: [PATCH 03/17] Remove an unused CI file This was effectively replaced by the build-linux.yml script --- .github/workflows/ci.yml | 49 ---------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index bcfa32d7d..000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,49 +0,0 @@ -name: CI Build - -on: - push: - branches: [ main, master ] - pull_request: - branches: [ main, master ] - -jobs: - build: - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Setup Python - uses: actions/setup-python@v4 - with: - python-version: '3.x' - - - name: Install system dependencies - run: | - sudo apt-get update - sudo apt-get install -y build-essential pkg-config ca-certificates curl git \ - libgl1-mesa-dev libglu1-mesa-dev libglfw3-dev libpng-dev libx11-dev \ - libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libudev-dev - - - name: Install Meson and Ninja (pip) - run: | - python -m pip install --upgrade pip - pip install meson ninja - - - name: Configure Meson - run: | - meson setup build_meson --wipe --buildtype=release - - - name: Build with Ninja - run: | - ninja -C build_meson -v - - - name: Package build output - run: | - tar -czf minecraft-binaries.tar.gz -C build_meson . - - - name: Upload artifact - uses: actions/upload-artifact@v4 - with: - name: minecraft-binaries - path: minecraft-binaries.tar.gz From 81e9256b7a49193eec4c95c722f5abb32076acb3 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Mon, 9 Mar 2026 17:22:15 +0100 Subject: [PATCH 04/17] added asan for debug builds --- meson.build | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 3cc9b0c41..357396709 100644 --- a/meson.build +++ b/meson.build @@ -12,6 +12,9 @@ pymod = import('python') python = pymod.find_installation('python3', required: true) cc = meson.get_compiler('cpp') +buildtype = get_option('buildtype') +#langs cant sadly be set before calling project +langs = ['cpp', 'c'] # system deps gl_dep = dependency('gl') @@ -21,6 +24,19 @@ png_dep = dependency('libpng') thread_dep = dependency('threads') dl_dep = cc.find_library('dl') +if buildtype.startswith('debug') + strAsan = '-fsanitize=address' + strLsan = '-fsanitize=leak' + if cc.has_argument(strAsan) + add_project_arguments(strAsan, language: langs) + add_project_link_arguments(strAsan, language: langs) + endif + if cc.has_argument(strLsan) + add_project_arguments(strLsan, language: langs) + add_project_link_arguments(strLsan, language: langs) + endif +endif + # compile flags (chagne ts juicey) global_cpp_args = [ '-fpermissive', @@ -52,4 +68,4 @@ subdir('4J.Profile') subdir('4J.Storage') subdir('Minecraft.Assets') subdir('Minecraft.World') -subdir('Minecraft.Client') \ No newline at end of file +subdir('Minecraft.Client') From 5265eef7595f24b433c7d8aabedc3e4a6929d16f Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Mon, 9 Mar 2026 21:54:43 +0100 Subject: [PATCH 05/17] first patch of UB --- .../Platform/Common/Consoles_App.cpp | 2 +- .../Textures/Stitching/StitchedTexture.cpp | 18 +++++++++++++----- .../Textures/Stitching/StitchedTexture.h | 2 +- Minecraft.Client/Textures/TextureManager.cpp | 2 +- Minecraft.Client/Utils/MemoryTracker.h | 1 - Minecraft.World/Util/Icon.h | 2 ++ debug.sh | 6 ++++++ run.sh | 6 ++++++ 8 files changed, 30 insertions(+), 9 deletions(-) create mode 100755 debug.sh create mode 100755 run.sh diff --git a/Minecraft.Client/Platform/Common/Consoles_App.cpp b/Minecraft.Client/Platform/Common/Consoles_App.cpp index 5268792f2..4207fe362 100644 --- a/Minecraft.Client/Platform/Common/Consoles_App.cpp +++ b/Minecraft.Client/Platform/Common/Consoles_App.cpp @@ -4111,7 +4111,7 @@ void CMinecraftApp::loadStringTable() { byteArray locFile = m_mediaArchive->getFile(localisationFile); m_stringTable = new StringTable(locFile.data, locFile.length); - delete locFile.data; + delete[] locFile.data; } else { diff --git a/Minecraft.Client/Textures/Stitching/StitchedTexture.cpp b/Minecraft.Client/Textures/Stitching/StitchedTexture.cpp index 86eb37577..77e0a6ba9 100644 --- a/Minecraft.Client/Textures/Stitching/StitchedTexture.cpp +++ b/Minecraft.Client/Textures/Stitching/StitchedTexture.cpp @@ -60,11 +60,19 @@ void StitchedTexture::freeFrameTextures() StitchedTexture::~StitchedTexture() { - for(AUTO_VAR(it, frames->begin()); it != frames->end(); ++it) - { - delete *it; + // 4jcraft added null check, in PreStitchedTextures::stitch(), than ::loadUVs() + // all new SimpleIcons deriving from StitchedIcons are calling the + // constructor which does frames = NULL + // so the program breaks on delete oldClock in ::loadUVs() + // but scince "frames" is never allocated (StitchedTexture::init()) + // not called, frames was never called (only the constructor) + if(frames) { + for(AUTO_VAR(it, frames->begin()); it != frames->end(); ++it) + { + delete *it; + } + delete frames; } - delete frames; } void StitchedTexture::initUVs(float U0, float V0, float U1, float V1) @@ -351,4 +359,4 @@ int StitchedTexture::getFlags() const bool StitchedTexture::hasOwnData() { return true; -} \ No newline at end of file +} diff --git a/Minecraft.Client/Textures/Stitching/StitchedTexture.h b/Minecraft.Client/Textures/Stitching/StitchedTexture.h index edb3c3c05..306ffd1b7 100644 --- a/Minecraft.Client/Textures/Stitching/StitchedTexture.h +++ b/Minecraft.Client/Textures/Stitching/StitchedTexture.h @@ -86,4 +86,4 @@ public: void setFlags(int flags); // 4J added virtual void freeFrameTextures(); // 4J added virtual bool hasOwnData(); // 4J Added -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Textures/TextureManager.cpp b/Minecraft.Client/Textures/TextureManager.cpp index 6fd3813fa..546bdc17f 100644 --- a/Minecraft.Client/Textures/TextureManager.cpp +++ b/Minecraft.Client/Textures/TextureManager.cpp @@ -193,4 +193,4 @@ Texture *TextureManager::createTexture(const std::wstring &name, int mode, int w // 4J Stu - Don't clamp as it causes issues with how we signal non-mipmmapped textures to the pixel shader //return createTexture(name, mode, width, height, Texture::WM_CLAMP, format, Texture::TFLT_NEAREST, Texture::TFLT_NEAREST, mipmap, NULL); return createTexture(name, mode, width, height, Texture::WM_WRAP, format, Texture::TFLT_NEAREST, Texture::TFLT_NEAREST, mipmap, NULL); -} \ No newline at end of file +} diff --git a/Minecraft.Client/Utils/MemoryTracker.h b/Minecraft.Client/Utils/MemoryTracker.h index 8bf103be5..8492aae28 100644 --- a/Minecraft.Client/Utils/MemoryTracker.h +++ b/Minecraft.Client/Utils/MemoryTracker.h @@ -1,5 +1,4 @@ #pragma once -#include "MemoryTracker.h" class ByteBuffer; class IntBuffer; class FloatBuffer; diff --git a/Minecraft.World/Util/Icon.h b/Minecraft.World/Util/Icon.h index fa606ff48..c77fba2c9 100644 --- a/Minecraft.World/Util/Icon.h +++ b/Minecraft.World/Util/Icon.h @@ -16,6 +16,8 @@ public: static const int IS_ALPHA_CUT_OUT = 4; #endif + virtual ~Icon() {} // added by 4jcraft, needed for abstract class + virtual int getX() const = 0; virtual int getY() const = 0; virtual int getWidth() const = 0; diff --git a/debug.sh b/debug.sh new file mode 100755 index 000000000..63f1c0541 --- /dev/null +++ b/debug.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +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..f4ac7e7f3 --- /dev/null +++ b/run.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +meson compile -C build && \ +cd build/Minecraft.Client/ && \ +./Minecraft.Client && \ +cd ../.. From 66b31669c3cb3fcb9cae3409cb2c869b25ed0eb7 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Mon, 9 Mar 2026 22:48:36 +0100 Subject: [PATCH 06/17] new batch of delete operator missmatch --- .../Platform/Common/GameRules/ConsoleSchematicFile.cpp | 4 ++-- .../Platform/Common/Tutorial/LookAtTileHint.h | 2 +- Minecraft.Client/Platform/Common/Tutorial/TakeItemHint.h | 2 +- Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h | 2 +- .../Rendering/EntityRenderers/TileRenderer.cpp | 2 +- Minecraft.World/IO/Streams/BufferedOutputStream.cpp | 6 +++++- Minecraft.World/Items/MapItem.cpp | 2 +- Minecraft.World/Level/Storage/MapItemSavedData.cpp | 2 +- Minecraft.World/Network/Packets/AwardStatPacket.cpp | 9 +++++++-- Minecraft.World/Network/Packets/RemoveEntitiesPacket.cpp | 2 +- Minecraft.World/Util/AABB.cpp | 4 ++-- Minecraft.World/WorldGen/Biomes/BiomeSource.cpp | 4 ++-- .../WorldGen/Sources/TheEndLevelRandomLevelSource.cpp | 3 ++- 13 files changed, 27 insertions(+), 17 deletions(-) diff --git a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp index 586e29997..f8af5039a 100644 --- a/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp +++ b/Minecraft.Client/Platform/Common/GameRules/ConsoleSchematicFile.cpp @@ -285,12 +285,12 @@ __int64 ConsoleSchematicFile::applyBlocksAndData(LevelChunk *chunk, AABB *chunkB PIXBeginNamedEvent(0,"Setting Block data"); chunk->setBlockData(blockData); PIXEndNamedEvent(); - delete blockData.data; + delete[] blockData.data; //4jcraft changed to array delete chunk->recalcHeightmapOnly(); PIXBeginNamedEvent(0,"Setting Data data"); chunk->setDataData(dataData); PIXEndNamedEvent(); - delete dataData.data; + delete[] dataData.data; //4jcraft, same here // A basic pass through to roughly do the lighting. At this point of post-processing, we don't have all the neighbouring chunks loaded in, // so any lighting here should be things that won't propagate out of this chunk. diff --git a/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.h b/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.h index 856dbb63f..1c03e08d6 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.h @@ -19,4 +19,4 @@ public: ~LookAtTileHint(); virtual bool onLookAt(int id, int iData=0); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Platform/Common/Tutorial/TakeItemHint.h b/Minecraft.Client/Platform/Common/Tutorial/TakeItemHint.h index a7641f64b..fe2744f36 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/TakeItemHint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/TakeItemHint.h @@ -16,4 +16,4 @@ public: ~TakeItemHint(); virtual bool onTake( std::shared_ptr item ); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h b/Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h index 191b021f3..f114392c7 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h @@ -50,4 +50,4 @@ public: virtual bool onLookAtEntity(eINSTANCEOF type); virtual int tick(); virtual bool allowFade() { return m_allowFade; } -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp index a84a13eeb..30d05c2b3 100644 --- a/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp +++ b/Minecraft.Client/Rendering/EntityRenderers/TileRenderer.cpp @@ -160,7 +160,7 @@ TileRenderer::TileRenderer( LevelSource* level, int xMin, int yMin, int zMin, un TileRenderer::~TileRenderer() { - delete cache; + delete[] cache; //4jcraft, changed to [] } TileRenderer::TileRenderer( LevelSource* level ) diff --git a/Minecraft.World/IO/Streams/BufferedOutputStream.cpp b/Minecraft.World/IO/Streams/BufferedOutputStream.cpp index 4e1051a7c..379686138 100644 --- a/Minecraft.World/IO/Streams/BufferedOutputStream.cpp +++ b/Minecraft.World/IO/Streams/BufferedOutputStream.cpp @@ -15,7 +15,11 @@ BufferedOutputStream::BufferedOutputStream(OutputStream *out, int size) BufferedOutputStream::~BufferedOutputStream() { - delete buf.data; + //4jcraft, changed to [], deallocates internal buffer + //TODO: ArrayWithLength.h doesnt have a destructor. + //this wouldnt need to be done manually. + //but for some reason the destructor is commented out in the source code? + delete[] buf.data; } //Flushes this buffered output stream. This forces any buffered output bytes to be written out to the underlying output stream. diff --git a/Minecraft.World/Items/MapItem.cpp b/Minecraft.World/Items/MapItem.cpp index 292320b27..908d0f776 100644 --- a/Minecraft.World/Items/MapItem.cpp +++ b/Minecraft.World/Items/MapItem.cpp @@ -342,6 +342,6 @@ std::shared_ptr MapItem::getUpdatePacket(std::shared_ptr i if (data.data == NULL || data.length == 0) return nullptr; std::shared_ptr retval = std::shared_ptr(new ComplexItemDataPacket((short) Item::map->id, (short) itemInstance->getAuxValue(), data)); - delete data.data; + delete[] data.data; //4jcraft, changed to [] return retval; } diff --git a/Minecraft.World/Level/Storage/MapItemSavedData.cpp b/Minecraft.World/Level/Storage/MapItemSavedData.cpp index c0ee9b024..ae98d8698 100644 --- a/Minecraft.World/Level/Storage/MapItemSavedData.cpp +++ b/Minecraft.World/Level/Storage/MapItemSavedData.cpp @@ -123,7 +123,7 @@ charArray MapItemSavedData::HoldingPlayer::nextUpdatePacket(std::shared_ptr servPlayer = std::dynamic_pointer_cast(player); for (int d = 0; d < 10; d++) diff --git a/Minecraft.World/Network/Packets/AwardStatPacket.cpp b/Minecraft.World/Network/Packets/AwardStatPacket.cpp index efa503b9b..576cead1b 100644 --- a/Minecraft.World/Network/Packets/AwardStatPacket.cpp +++ b/Minecraft.World/Network/Packets/AwardStatPacket.cpp @@ -16,7 +16,12 @@ AwardStatPacket::AwardStatPacket(int statId, int count) { this->statId = statId; - this->m_paramData.data = (uint8_t *) new int(count); + // 4jcraft, changed from new int(count); to new int[1]; + // and initializing the array with count + // reason: .data needs to be delete with delete[] but its + // allocated with new, not new T[] + this->m_paramData.data = (uint8_t *) new int[1]; + ((int*)this->m_paramData.data)[0] = count; this->m_paramData.length = sizeof(int); } @@ -30,7 +35,7 @@ AwardStatPacket::~AwardStatPacket() { if (m_paramData.data != NULL) { - delete [] m_paramData.data; + delete[] m_paramData.data; m_paramData.data = NULL; } } diff --git a/Minecraft.World/Network/Packets/RemoveEntitiesPacket.cpp b/Minecraft.World/Network/Packets/RemoveEntitiesPacket.cpp index a007849a2..9207ca8bf 100644 --- a/Minecraft.World/Network/Packets/RemoveEntitiesPacket.cpp +++ b/Minecraft.World/Network/Packets/RemoveEntitiesPacket.cpp @@ -16,7 +16,7 @@ RemoveEntitiesPacket::RemoveEntitiesPacket(intArray ids) RemoveEntitiesPacket::~RemoveEntitiesPacket() { - delete ids.data; + delete[] ids.data; //4jcraft, changed to [] } void RemoveEntitiesPacket::read(DataInputStream *dis) //throws IOException diff --git a/Minecraft.World/Util/AABB.cpp b/Minecraft.World/Util/AABB.cpp index b768f76f6..3dc459497 100644 --- a/Minecraft.World/Util/AABB.cpp +++ b/Minecraft.World/Util/AABB.cpp @@ -12,14 +12,14 @@ AABB::ThreadStorage *AABB::tlsDefault = NULL; AABB::ThreadStorage::ThreadStorage() { - pool = new AABB[POOL_SIZE]; + pool = new AABB[POOL_SIZE]; //4jcraft, needs to be deleted with delete[] poolPointer = 0; } AABB::ThreadStorage::~ThreadStorage() { - delete pool; + delete[] pool; //4jcraft, changed to [] } void AABB::CreateNewThreadStorage() diff --git a/Minecraft.World/WorldGen/Biomes/BiomeSource.cpp b/Minecraft.World/WorldGen/Biomes/BiomeSource.cpp index f5c142e12..3a77b436d 100644 --- a/Minecraft.World/WorldGen/Biomes/BiomeSource.cpp +++ b/Minecraft.World/WorldGen/Biomes/BiomeSource.cpp @@ -218,7 +218,7 @@ void BiomeSource::getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h, { BiomeArray tmp = cache->getBiomeBlockAt(x, z); System::arraycopy(tmp, 0, &biomes, 0, w * h); - delete tmp.data; // MGH - added, the caching creates this array from the indices now. + delete[] tmp.data; // MGH - added, the caching creates this array from the indices now. //4jcraft made it array delete //return biomes; } @@ -635,4 +635,4 @@ bool BiomeSource::getIsMatch(float *frac) // Consider as suitable if we've got all the critical ones, and in total 9 or more - currently there's 8 critical so this just forces at least 1 more others return ( typeCount >= 9 ); -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp index 63bfa9837..7280ea617 100644 --- a/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp +++ b/Minecraft.World/WorldGen/Sources/TheEndLevelRandomLevelSource.cpp @@ -188,7 +188,8 @@ LevelChunk *TheEndLevelRandomLevelSource::getChunk(int xOffs, int zOffs) levelChunk->recalcHeightmap(); //delete blocks.data; // Don't delete the blocks as the array data is actually owned by the chunk now - delete biomes.data; + //4jcraft changed to [] + delete[] biomes.data; return levelChunk; } From 0047a442a3240820efe32df6395f29354afe6946 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Mon, 9 Mar 2026 23:06:45 +0100 Subject: [PATCH 07/17] hide the files --- debug.sh | 6 ------ run.sh | 6 ------ 2 files changed, 12 deletions(-) delete mode 100755 debug.sh delete mode 100755 run.sh diff --git a/debug.sh b/debug.sh deleted file mode 100755 index 63f1c0541..000000000 --- a/debug.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -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 f4ac7e7f3..000000000 --- a/run.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -meson compile -C build && \ -cd build/Minecraft.Client/ && \ -./Minecraft.Client && \ -cd ../.. From 2ae8ac3b80b523078381d175571edbaec9003b33 Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Mon, 9 Mar 2026 23:15:34 +0100 Subject: [PATCH 08/17] fix typos in comment --- .../Textures/Stitching/StitchedTexture.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/Minecraft.Client/Textures/Stitching/StitchedTexture.cpp b/Minecraft.Client/Textures/Stitching/StitchedTexture.cpp index 77e0a6ba9..124c7207f 100644 --- a/Minecraft.Client/Textures/Stitching/StitchedTexture.cpp +++ b/Minecraft.Client/Textures/Stitching/StitchedTexture.cpp @@ -60,12 +60,10 @@ void StitchedTexture::freeFrameTextures() StitchedTexture::~StitchedTexture() { - // 4jcraft added null check, in PreStitchedTextures::stitch(), than ::loadUVs() - // all new SimpleIcons deriving from StitchedIcons are calling the - // constructor which does frames = NULL - // so the program breaks on delete oldClock in ::loadUVs() - // but scince "frames" is never allocated (StitchedTexture::init()) - // not called, frames was never called (only the constructor) + // 4jcraft, added null check + // the constructor does not allocate the frames vector. + // in some scenarios the destructor/delete is called + // without ever calling ::init() if(frames) { for(AUTO_VAR(it, frames->begin()); it != frames->end(); ++it) { From c6ab0e1177c72d2ad356af7488221dcf662377fb Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Tue, 10 Mar 2026 00:12:26 +0100 Subject: [PATCH 09/17] unhide files --- .gitignore | 2 +- debug.sh | 6 ++++++ run.sh | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100755 debug.sh create mode 100755 run.sh diff --git a/.gitignore b/.gitignore index ffdd21a84..0c9c8e1f4 100644 --- a/.gitignore +++ b/.gitignore @@ -29,7 +29,7 @@ meson-logs/ *.out *.d compile_commands.json - +.clangd # ----- Scratch / legacy ----- diff --git a/debug.sh b/debug.sh new file mode 100755 index 000000000..b5a3c173d --- /dev/null +++ b/debug.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +CC=clang CXX=clang++ 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..d261f892b --- /dev/null +++ b/run.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +CC=clang CXX=clang++ meson compile -C build && \ +cd build/Minecraft.Client/ && \ +./Minecraft.Client && \ +cd ../.. From 021c2809f452ac8b52f0cc13038dd4c74c5ae46f Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Tue, 10 Mar 2026 02:13:56 +0100 Subject: [PATCH 10/17] purged -Wdelete-non-abstract-non-virtual-dtor --- Minecraft.Client/Input/ConsoleInputSource.h | 1 + Minecraft.Client/Input/Input.h | 3 ++- .../Platform/Common/GameRules/GameRuleDefinition.h | 1 + .../Platform/Common/GameRules/LevelGenerationOptions.h | 1 + .../Platform/Common/Tutorial/LookAtEntityHint.h | 5 +++-- .../Platform/Common/Tutorial/LookAtTileHint.cpp | 3 ++- Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.h | 3 ++- Minecraft.Client/Platform/Common/Tutorial/TakeItemHint.h | 3 ++- Minecraft.Client/Platform/Common/Tutorial/Tutorial.h | 2 +- Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h | 1 + Minecraft.Client/Player/MultiPlayerGameMode.h | 3 ++- Minecraft.Client/Rendering/Models/Model.h | 1 + Minecraft.Client/Textures/MemTextureProcessor.h | 3 ++- Minecraft.Client/Textures/Packs/DLCTexturePack.h | 2 +- Minecraft.Client/Textures/Packs/TexturePack.h | 1 + Minecraft.World/AI/Control/JumpControl.h | 4 +++- Minecraft.World/AI/Control/LookControl.h | 3 ++- Minecraft.World/AI/Control/MoveControl.h | 3 ++- Minecraft.World/Containers/Container.h | 3 ++- Minecraft.World/Containers/CraftingContainer.h | 4 ++-- Minecraft.World/Containers/Merchant.h | 3 ++- Minecraft.World/Containers/ResultContainer.h | 3 ++- Minecraft.World/Items/ItemInstance.h | 4 ++-- Minecraft.World/Level/Dimensions/Dimension.h | 2 +- Minecraft.World/Level/LevelChunk.h | 2 +- Minecraft.World/Level/LevelData.h | 1 + Minecraft.World/Level/Storage/LevelStorage.h | 1 + Minecraft.World/Level/Storage/PlayerIO.h | 2 +- Minecraft.World/Level/Storage/SavedData.h | 3 ++- Minecraft.World/Network/Packets/Packet.h | 5 +++-- Minecraft.World/Network/Packets/PacketListener.h | 1 + Minecraft.World/WorldGen/Biomes/BiomeDecorator.h | 4 +++- Minecraft.World/WorldGen/Biomes/BiomeSource.h | 2 +- Minecraft.World/WorldGen/Features/HouseFeature.cpp | 6 +++--- Minecraft.World/WorldGen/Features/LakeFeature.cpp | 5 +++-- Minecraft.World/WorldGen/Features/LargeFeature.h | 4 ++-- Minecraft.World/WorldGen/Features/TreeFeature.h | 2 +- Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp | 4 ++-- Minecraft.World/WorldGen/Layers/Layer.h | 3 ++- Minecraft.World/WorldGen/Noise/Synth.h | 1 + Minecraft.World/WorldGen/Structures/StrongholdPieces.h | 1 + 41 files changed, 70 insertions(+), 39 deletions(-) diff --git a/Minecraft.Client/Input/ConsoleInputSource.h b/Minecraft.Client/Input/ConsoleInputSource.h index 7d79c0941..391d12916 100644 --- a/Minecraft.Client/Input/ConsoleInputSource.h +++ b/Minecraft.Client/Input/ConsoleInputSource.h @@ -3,6 +3,7 @@ class ConsoleInputSource { public: + virtual ~ConsoleInputSource(){} virtual void info(const std::wstring& string) = 0; virtual void warn(const std::wstring& string) = 0; virtual std::wstring getConsoleName() = 0; diff --git a/Minecraft.Client/Input/Input.h b/Minecraft.Client/Input/Input.h index 0a44d7656..daac8bf6d 100644 --- a/Minecraft.Client/Input/Input.h +++ b/Minecraft.Client/Input/Input.h @@ -12,6 +12,7 @@ public: bool sneaking; Input(); // 4J - added + virtual ~Input(){} virtual void tick(LocalPlayer *player); @@ -19,4 +20,4 @@ private: bool lReset; bool rReset; -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Platform/Common/GameRules/GameRuleDefinition.h b/Minecraft.Client/Platform/Common/GameRules/GameRuleDefinition.h index d41e1aea7..289734428 100644 --- a/Minecraft.Client/Platform/Common/GameRules/GameRuleDefinition.h +++ b/Minecraft.Client/Platform/Common/GameRules/GameRuleDefinition.h @@ -27,6 +27,7 @@ protected: public: GameRuleDefinition(); + virtual ~GameRuleDefinition(){} virtual ConsoleGameRules::EGameRuleType getActionType() = 0; diff --git a/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.h b/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.h index d81436bee..11970a555 100644 --- a/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.h +++ b/Minecraft.Client/Platform/Common/GameRules/LevelGenerationOptions.h @@ -22,6 +22,7 @@ public: // was being mixed in with all the game information as they have // completely different lifespans. + virtual ~GrSource(){} virtual bool requiresTexturePack()=0; virtual UINT getRequiredTexturePackId()=0; virtual std::wstring getDefaultSaveName()=0; diff --git a/Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h b/Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h index a30701a37..a8c389c37 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h @@ -14,7 +14,8 @@ private: public: LookAtEntityHint(eTutorial_Hint id, Tutorial *tutorial, int descriptionId, int titleId, eINSTANCEOF type); - ~LookAtEntityHint(); + //TODO: LEAK LEKAFDSAKFDJ;SALKDJF;ASLKFJ ITS NEVER IMPLEMENTED + ~LookAtEntityHint(){}; virtual bool onLookAtEntity(eINSTANCEOF type); -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp b/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp index 5d03960c9..c9ef4ce0e 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp @@ -10,6 +10,7 @@ LookAtTileHint::LookAtTileHint(eTutorial_Hint id, Tutorial *tutorial, int tiles[ { m_iTilesCount = tilesLength; + //TODO LEAK LEAK LEAK LEAKS EVERY WHERE AAAAAAAAAAAAAAAAH m_iTiles= new int [m_iTilesCount]; for(unsigned int i=0;i item ); }; diff --git a/Minecraft.Client/Platform/Common/Tutorial/Tutorial.h b/Minecraft.Client/Platform/Common/Tutorial/Tutorial.h index 3f06df12f..5e9aaaad1 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/Tutorial.h +++ b/Minecraft.Client/Platform/Common/Tutorial/Tutorial.h @@ -123,7 +123,7 @@ public: bool m_isFullTutorial; public: Tutorial(int iPad, bool isFullTutorial = false); - ~Tutorial(); + virtual ~Tutorial(); void tick(); int getPad() { return m_iPad; } diff --git a/Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h b/Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h index f114392c7..e40759841 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/TutorialHint.h @@ -37,6 +37,7 @@ protected: public: TutorialHint(eTutorial_Hint id, Tutorial *tutorial, int descriptionId, eHintType type, bool allowFade = true); + virtual ~TutorialHint(){} eTutorial_Hint getId() { return m_id; } diff --git a/Minecraft.Client/Player/MultiPlayerGameMode.h b/Minecraft.Client/Player/MultiPlayerGameMode.h index 19ef46af6..34396aebd 100644 --- a/Minecraft.Client/Player/MultiPlayerGameMode.h +++ b/Minecraft.Client/Player/MultiPlayerGameMode.h @@ -23,6 +23,7 @@ protected: public: MultiPlayerGameMode(Minecraft *minecraft, ClientConnection *connection); + virtual ~MultiPlayerGameMode(){} static void creativeDestroyBlock(Minecraft *minecraft, MultiPlayerGameMode *gameMode, int x, int y, int z, int face); void adjustPlayer(std::shared_ptr player); bool isCutScene(); @@ -64,4 +65,4 @@ public: virtual bool isInputAllowed(int mapping) { return true; } virtual bool isTutorial() { return false; } virtual Tutorial *getTutorial() { return NULL; } -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Rendering/Models/Model.h b/Minecraft.Client/Rendering/Models/Model.h index 104e6ce27..c80f9e8f6 100644 --- a/Minecraft.Client/Rendering/Models/Model.h +++ b/Minecraft.Client/Rendering/Models/Model.h @@ -19,6 +19,7 @@ public: int texHeight; Model(); // 4J added + virtual ~Model(){} virtual void render(std::shared_ptr entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) {} virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, unsigned int uiBitmaskOverrideAnim=0) {} virtual void prepareMobModel(std::shared_ptr mob, float time, float r, float a) {} diff --git a/Minecraft.Client/Textures/MemTextureProcessor.h b/Minecraft.Client/Textures/MemTextureProcessor.h index 8e945e1d5..56590d428 100644 --- a/Minecraft.Client/Textures/MemTextureProcessor.h +++ b/Minecraft.Client/Textures/MemTextureProcessor.h @@ -4,5 +4,6 @@ class BufferedImage; class MemTextureProcessor { public: + virtual ~MemTextureProcessor(){} virtual BufferedImage *process(BufferedImage *read) = 0; -}; \ No newline at end of file +}; diff --git a/Minecraft.Client/Textures/Packs/DLCTexturePack.h b/Minecraft.Client/Textures/Packs/DLCTexturePack.h index 375c8cafe..f69eb0258 100644 --- a/Minecraft.Client/Textures/Packs/DLCTexturePack.h +++ b/Minecraft.Client/Textures/Packs/DLCTexturePack.h @@ -23,7 +23,7 @@ public: using AbstractTexturePack::getResource; DLCTexturePack(DWORD id, DLCPack *pack, TexturePack *fallback); - ~DLCTexturePack(); + ~DLCTexturePack(){}; virtual std::wstring getResource(const std::wstring& name); virtual DLCPack * getDLCPack(); diff --git a/Minecraft.Client/Textures/Packs/TexturePack.h b/Minecraft.Client/Textures/Packs/TexturePack.h index edbabc796..781fbe474 100644 --- a/Minecraft.Client/Textures/Packs/TexturePack.h +++ b/Minecraft.Client/Textures/Packs/TexturePack.h @@ -12,6 +12,7 @@ class TexturePack public: TexturePack() { m_bHasAudio=false;} + virtual ~TexturePack(){} virtual bool hasData() = 0; virtual bool hasAudio() { return m_bHasAudio;} virtual void setHasAudio(bool bVal) {m_bHasAudio=bVal;} diff --git a/Minecraft.World/AI/Control/JumpControl.h b/Minecraft.World/AI/Control/JumpControl.h index b33648c7e..4ff9cfce7 100644 --- a/Minecraft.World/AI/Control/JumpControl.h +++ b/Minecraft.World/AI/Control/JumpControl.h @@ -12,7 +12,9 @@ private: public: JumpControl(Mob *mob); + virtual ~JumpControl(){} void jump(); + //genuinly, why tf is this VIRTUAL virtual void tick(); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/AI/Control/LookControl.h b/Minecraft.World/AI/Control/LookControl.h index fe182e7c7..3f9dabb2e 100644 --- a/Minecraft.World/AI/Control/LookControl.h +++ b/Minecraft.World/AI/Control/LookControl.h @@ -15,6 +15,7 @@ private: public: LookControl(Mob *mob); + virtual ~LookControl(){} void setLookAt(std::shared_ptr target, float yMax, float xMax); void setLookAt(double x, double y, double z, float yMax, float xMax); @@ -30,4 +31,4 @@ public: double getWantedX(); double getWantedY(); double getWantedZ(); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/AI/Control/MoveControl.h b/Minecraft.World/AI/Control/MoveControl.h index 4138280e0..89ac8162b 100644 --- a/Minecraft.World/AI/Control/MoveControl.h +++ b/Minecraft.World/AI/Control/MoveControl.h @@ -22,6 +22,7 @@ private: public: MoveControl(Mob *mob); + virtual ~MoveControl(){} bool hasWanted(); float getSpeed(); @@ -31,4 +32,4 @@ public: private: float rotlerp(float a, float b, float max); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Containers/Container.h b/Minecraft.World/Containers/Container.h index 46444696f..06ee42a28 100644 --- a/Minecraft.World/Containers/Container.h +++ b/Minecraft.World/Containers/Container.h @@ -7,6 +7,7 @@ class Player; class Container { public: + virtual ~Container(){} static const int LARGE_MAX_STACK_SIZE = 64; virtual unsigned int getContainerSize() = 0; @@ -20,4 +21,4 @@ public: virtual bool stillValid(std::shared_ptr player) = 0; virtual void startOpen() = 0; virtual void stopOpen() = 0; -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Containers/CraftingContainer.h b/Minecraft.World/Containers/CraftingContainer.h index 5ef82ea20..e912c0957 100644 --- a/Minecraft.World/Containers/CraftingContainer.h +++ b/Minecraft.World/Containers/CraftingContainer.h @@ -13,7 +13,7 @@ private: public: CraftingContainer(AbstractContainerMenu *menu, unsigned int w, unsigned int h); - ~CraftingContainer(); + virtual ~CraftingContainer(); virtual unsigned int getContainerSize(); virtual std::shared_ptr getItem(unsigned int slot); @@ -29,4 +29,4 @@ public: void startOpen() { } // TODO Auto-generated method stub void stopOpen() { } // TODO Auto-generated method stub -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Containers/Merchant.h b/Minecraft.World/Containers/Merchant.h index ad7ab1fcb..6c700c7ff 100644 --- a/Minecraft.World/Containers/Merchant.h +++ b/Minecraft.World/Containers/Merchant.h @@ -7,6 +7,7 @@ class Player; class Merchant { public: + virtual ~Merchant(){} virtual void setTradingPlayer(std::shared_ptr player) = 0; virtual std::shared_ptr getTradingPlayer() = 0; virtual MerchantRecipeList *getOffers(std::shared_ptr forPlayer) = 0; @@ -14,4 +15,4 @@ public: virtual void notifyTrade(MerchantRecipe *activeRecipe) = 0; virtual void notifyTradeUpdated(std::shared_ptr item) = 0; virtual int getDisplayName() = 0; -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Containers/ResultContainer.h b/Minecraft.World/Containers/ResultContainer.h index 1b030d810..8f83543d6 100644 --- a/Minecraft.World/Containers/ResultContainer.h +++ b/Minecraft.World/Containers/ResultContainer.h @@ -10,6 +10,7 @@ private: public: // 4J Stu Added a ctor to init items ResultContainer(); + virtual ~ResultContainer(){} virtual unsigned int getContainerSize(); virtual std::shared_ptr getItem(unsigned int slot); @@ -23,4 +24,4 @@ public: void startOpen() { } // TODO Auto-generated method stub void stopOpen() { } // TODO Auto-generated method stub -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Items/ItemInstance.h b/Minecraft.World/Items/ItemInstance.h index 465ee1ec0..6a706d0ad 100644 --- a/Minecraft.World/Items/ItemInstance.h +++ b/Minecraft.World/Items/ItemInstance.h @@ -63,7 +63,7 @@ private: ItemInstance() { _init(-1,0,0); } public: - ~ItemInstance(); + virtual ~ItemInstance(); std::shared_ptr remove(int count); Item *getItem() const; @@ -151,4 +151,4 @@ public: int getBaseRepairCost(); void setRepairCost(int cost); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Level/Dimensions/Dimension.h b/Minecraft.World/Level/Dimensions/Dimension.h index 752ed0df4..9d79c990f 100644 --- a/Minecraft.World/Level/Dimensions/Dimension.h +++ b/Minecraft.World/Level/Dimensions/Dimension.h @@ -28,7 +28,7 @@ protected: public: Dimension(); - ~Dimension(); + virtual ~Dimension(); virtual ChunkSource *createRandomLevelSource() const; virtual ChunkSource *createFlatLevelSource() const; virtual ChunkStorage *createStorage(File dir); diff --git a/Minecraft.World/Level/LevelChunk.h b/Minecraft.World/Level/LevelChunk.h index f7d208273..72aeb04f2 100644 --- a/Minecraft.World/Level/LevelChunk.h +++ b/Minecraft.World/Level/LevelChunk.h @@ -152,7 +152,7 @@ public: LevelChunk(Level *level, int x, int z); LevelChunk(Level *level, byteArray blocks, int x, int z); LevelChunk(Level *level, int x, int z, LevelChunk *lc); - ~LevelChunk(); + virtual ~LevelChunk(); virtual bool isAt(int x, int z); diff --git a/Minecraft.World/Level/LevelData.h b/Minecraft.World/Level/LevelData.h index ac5148164..8e8cb77a8 100644 --- a/Minecraft.World/Level/LevelData.h +++ b/Minecraft.World/Level/LevelData.h @@ -71,6 +71,7 @@ protected: virtual void setTagData(CompoundTag *tag); // 4J - removed CompoundTag *playerTag public: + virtual ~LevelData(){} virtual __int64 getSeed(); virtual int getXSpawn(); virtual int getYSpawn(); diff --git a/Minecraft.World/Level/Storage/LevelStorage.h b/Minecraft.World/Level/Storage/LevelStorage.h index 4212eaf32..1ed3f5b34 100644 --- a/Minecraft.World/Level/Storage/LevelStorage.h +++ b/Minecraft.World/Level/Storage/LevelStorage.h @@ -18,6 +18,7 @@ public: static const std::wstring NETHER_FOLDER; static const std::wstring ENDER_FOLDER; + virtual ~LevelStorage(){} virtual LevelData *prepareLevel() = 0; virtual void checkSession() = 0; virtual ChunkStorage *createChunkStorage(Dimension *dimension) = 0; diff --git a/Minecraft.World/Level/Storage/PlayerIO.h b/Minecraft.World/Level/Storage/PlayerIO.h index 2de00aeeb..141fb6b0a 100644 --- a/Minecraft.World/Level/Storage/PlayerIO.h +++ b/Minecraft.World/Level/Storage/PlayerIO.h @@ -19,4 +19,4 @@ public: virtual void saveMapIdLookup() = 0; virtual void deleteMapFilesForPlayer(std::shared_ptr player) = 0; virtual void saveAllCachedData() = 0; -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Level/Storage/SavedData.h b/Minecraft.World/Level/Storage/SavedData.h index b81956cd4..37e9f2579 100644 --- a/Minecraft.World/Level/Storage/SavedData.h +++ b/Minecraft.World/Level/Storage/SavedData.h @@ -15,6 +15,7 @@ private: public: SavedData(const std::wstring& id); + virtual ~SavedData(){} virtual void load(CompoundTag *tag) = 0; virtual void save(CompoundTag *tag) = 0; @@ -22,4 +23,4 @@ public: void setDirty(); void setDirty(bool dirty); bool isDirty(); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Network/Packets/Packet.h b/Minecraft.World/Network/Packets/Packet.h index 57e420d3d..20a3bfb04 100644 --- a/Minecraft.World/Network/Packets/Packet.h +++ b/Minecraft.World/Network/Packets/Packet.h @@ -32,7 +32,7 @@ public: const int id; public: - PacketStatistics(int id) : id( id ), count( 0 ), totalSize( 0 ), samplesPos( 0 ), firstSampleTime( 0 ) { countSamples[0] = 0; sizeSamples[0] = 0; } + PacketStatistics(int id) : count( 0 ), totalSize( 0 ), samplesPos( 0 ), firstSampleTime( 0 ), id( id ) { countSamples[0] = 0; sizeSamples[0] = 0; } void addPacket(int bytes); int getCount(); double getAverageSize(); @@ -61,6 +61,7 @@ public: const __int64 createTime; Packet(); + virtual ~Packet(){} static std::shared_ptr getPacket(int id); @@ -110,4 +111,4 @@ public: protected: static void writeNbt(CompoundTag *tag, DataOutputStream *dos); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/Network/Packets/PacketListener.h b/Minecraft.World/Network/Packets/PacketListener.h index 1fb81e19d..766e96f58 100644 --- a/Minecraft.World/Network/Packets/PacketListener.h +++ b/Minecraft.World/Network/Packets/PacketListener.h @@ -106,6 +106,7 @@ class GameCommandPacket; class PacketListener { public: + virtual ~PacketListener(){} virtual bool isServerPacketListener() = 0; virtual void handleBlockRegionUpdate(std::shared_ptr packet); virtual void onUnhandledPacket(std::shared_ptr packet); diff --git a/Minecraft.World/WorldGen/Biomes/BiomeDecorator.h b/Minecraft.World/WorldGen/Biomes/BiomeDecorator.h index 01560045a..480def9dd 100644 --- a/Minecraft.World/WorldGen/Biomes/BiomeDecorator.h +++ b/Minecraft.World/WorldGen/Biomes/BiomeDecorator.h @@ -24,6 +24,8 @@ protected: public: BiomeDecorator(Biome *biome); + virtual ~BiomeDecorator(){} + void decorate(Level *level, Random *random, int xo, int zo); @@ -72,4 +74,4 @@ protected: void decorateDepthSpan(int count, Feature *feature, int y0, int y1); void decorateDepthAverage(int count, Feature *feature, int yMid, int ySpan); void decorateOres(); -}; \ No newline at end of file +}; diff --git a/Minecraft.World/WorldGen/Biomes/BiomeSource.h b/Minecraft.World/WorldGen/Biomes/BiomeSource.h index 550531fa9..a85908934 100644 --- a/Minecraft.World/WorldGen/Biomes/BiomeSource.h +++ b/Minecraft.World/WorldGen/Biomes/BiomeSource.h @@ -40,7 +40,7 @@ public: #else static __int64 findSeed(LevelType *generator); // 4J added #endif - ~BiomeSource(); + virtual ~BiomeSource(); public: std::vector getPlayerSpawnBiomes() { return playerSpawnBiomes; } diff --git a/Minecraft.World/WorldGen/Features/HouseFeature.cpp b/Minecraft.World/WorldGen/Features/HouseFeature.cpp index 8fb59910a..dc72d33d8 100644 --- a/Minecraft.World/WorldGen/Features/HouseFeature.cpp +++ b/Minecraft.World/WorldGen/Features/HouseFeature.cpp @@ -7,9 +7,9 @@ bool HouseFeature::place(Level *level, Random *random, int x, int y, int z) { - while (y > 0 && !level->getMaterial(x, y - 1, z)->blocksMotion()) + while (y > 0 && !level->getMaterial(x, y - 1, z)->blocksMotion()) { y--; - + } int w = random->nextInt(7) + 7; int h = 4 + random->nextInt(3) / 2; int d = random->nextInt(7) + 7; @@ -190,4 +190,4 @@ bool HouseFeature::place(Level *level, Random *random, int x, int y, int z) return true; -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Features/LakeFeature.cpp b/Minecraft.World/WorldGen/Features/LakeFeature.cpp index c70939596..ad07da9d4 100644 --- a/Minecraft.World/WorldGen/Features/LakeFeature.cpp +++ b/Minecraft.World/WorldGen/Features/LakeFeature.cpp @@ -13,8 +13,9 @@ bool LakeFeature::place(Level *level, Random *random, int x, int y, int z) { x -= 8; z -= 8; - while (y > 5 && level->isEmptyTile(x, y, z)) + while (y > 5 && level->isEmptyTile(x, y, z)) { y--; + } if (y <= 4) { return false; @@ -172,4 +173,4 @@ bool LakeFeature::place(Level *level, Random *random, int x, int y, int z) } return true; -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Features/LargeFeature.h b/Minecraft.World/WorldGen/Features/LargeFeature.h index 0bbce2c92..b35fc566b 100644 --- a/Minecraft.World/WorldGen/Features/LargeFeature.h +++ b/Minecraft.World/WorldGen/Features/LargeFeature.h @@ -14,10 +14,10 @@ protected: public: LargeFeature(); - ~LargeFeature(); + virtual ~LargeFeature(); virtual void apply(ChunkSource *ChunkSource, Level *level, int xOffs, int zOffs, byteArray blocks); protected: virtual void addFeature(Level *level, int x, int z, int xOffs, int zOffs, byteArray blocks) {} -}; \ No newline at end of file +}; diff --git a/Minecraft.World/WorldGen/Features/TreeFeature.h b/Minecraft.World/WorldGen/Features/TreeFeature.h index e29c0b0c3..c58f72d9e 100644 --- a/Minecraft.World/WorldGen/Features/TreeFeature.h +++ b/Minecraft.World/WorldGen/Features/TreeFeature.h @@ -5,9 +5,9 @@ class TreeFeature : public Feature { private: const int baseHeight; - const bool addJungleFeatures; const int trunkType; const int leafType; + const bool addJungleFeatures; public: TreeFeature(bool doUpdate); diff --git a/Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp b/Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp index 436cdc5ae..eefe26b4d 100644 --- a/Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp +++ b/Minecraft.World/WorldGen/Layers/BiomeOverrideLayer.cpp @@ -22,7 +22,7 @@ BiomeOverrideLayer::BiomeOverrideLayer(int seedMixup) : Layer(seedMixup) #endif if( file == INVALID_HANDLE_VALUE ) { - DWORD error = GetLastError(); + // DWORD error = GetLastError(); //assert(false); app.DebugPrintf("Biome override not found, using plains as default\n"); @@ -78,4 +78,4 @@ intArray BiomeOverrideLayer::getArea(int xo, int yo, int w, int h) } } return result; -} \ No newline at end of file +} diff --git a/Minecraft.World/WorldGen/Layers/Layer.h b/Minecraft.World/WorldGen/Layers/Layer.h index 3afe13acc..2104d219d 100644 --- a/Minecraft.World/WorldGen/Layers/Layer.h +++ b/Minecraft.World/WorldGen/Layers/Layer.h @@ -24,6 +24,7 @@ public: static LayerArray getDefaultLayers(__int64 seed, LevelType *levelType); Layer(__int64 seedMixup); + virtual ~Layer(){} virtual void init(__int64 seed); virtual void initRandom(__int64 x, __int64 y); @@ -33,4 +34,4 @@ protected: public: virtual intArray getArea(int xo, int yo, int w, int h) = 0; -}; \ No newline at end of file +}; diff --git a/Minecraft.World/WorldGen/Noise/Synth.h b/Minecraft.World/WorldGen/Noise/Synth.h index 74e686342..033632cf4 100644 --- a/Minecraft.World/WorldGen/Noise/Synth.h +++ b/Minecraft.World/WorldGen/Noise/Synth.h @@ -3,6 +3,7 @@ class Synth { public: virtual double getValue(double x, double y) = 0; + virtual ~Synth(){} doubleArray create(int width, int height); }; diff --git a/Minecraft.World/WorldGen/Structures/StrongholdPieces.h b/Minecraft.World/WorldGen/Structures/StrongholdPieces.h index b73a89e12..d9779d6a8 100644 --- a/Minecraft.World/WorldGen/Structures/StrongholdPieces.h +++ b/Minecraft.World/WorldGen/Structures/StrongholdPieces.h @@ -39,6 +39,7 @@ private: int maxPlaceCount; PieceWeight(EPieceClass pieceClass, int weight, int maxPlaceCount); + virtual ~PieceWeight(){} virtual bool doPlace(int depth); bool isValid(); }; From 6be6aadf0e5f92f01ba541b25471116243d9b45c Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Tue, 10 Mar 2026 02:27:16 +0100 Subject: [PATCH 11/17] another delete operator missmatch --- Minecraft.Client/Network/PlayerChunkMap.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Minecraft.Client/Network/PlayerChunkMap.cpp b/Minecraft.Client/Network/PlayerChunkMap.cpp index 8bedd4d6e..0f86fc0bf 100644 --- a/Minecraft.Client/Network/PlayerChunkMap.cpp +++ b/Minecraft.Client/Network/PlayerChunkMap.cpp @@ -33,7 +33,7 @@ PlayerChunkMap::PlayerChunk::PlayerChunk(int x, int z, PlayerChunkMap *pcm) : po PlayerChunkMap::PlayerChunk::~PlayerChunk() { - delete changedTiles.data; + delete[] changedTiles.data; //4jcraft, changed to [] } // 4J added - construct an an array of flags that indicate which entities are still waiting to have network packets sent out to say that they have been removed @@ -797,4 +797,4 @@ void PlayerChunkMap::setRadius(int newRadius) assert(radius >= MIN_VIEW_DISTANCE); this->radius = newRadius; } -} \ No newline at end of file +} From 5406648692a51a05949df58ffd119a757f18d01a Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Tue, 10 Mar 2026 11:16:42 -0500 Subject: [PATCH 12/17] fix: implement `CConsoleMinecraftApp::FatalLoadError` on linux --- Minecraft.Client/Platform/Linux/Linux_App.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Minecraft.Client/Platform/Linux/Linux_App.cpp b/Minecraft.Client/Platform/Linux/Linux_App.cpp index 5fcd8017e..a9520f211 100644 --- a/Minecraft.Client/Platform/Linux/Linux_App.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_App.cpp @@ -32,6 +32,8 @@ void CConsoleMinecraftApp::ExitGame() } void CConsoleMinecraftApp::FatalLoadError() { + app.DebugPrintf("CConsoleMinecraftApp::FatalLoadError - asserting 0 and dying...\n"); + assert(0); } void CConsoleMinecraftApp::CaptureSaveThumbnail() From 8a8280b24299ad69efabc7187feb25b406b91f55 Mon Sep 17 00:00:00 2001 From: "Echo J." Date: Tue, 10 Mar 2026 20:00:07 +0200 Subject: [PATCH 13/17] GameNetworkManager: Fix incorrect infinity value redefinition WaitForSingleObject() uses the maximum 32-bit value for specifying infinite timeout (while INFINITY might overflow that sized value back to 0) which caused the server wait event to not actually wait when compiled with Clang (and the game to be forever stuck on a black screen due to abnormal server state) --- .../Platform/Common/Network/GameNetworkManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp index 5fa598f74..a62be6143 100644 --- a/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Platform/Common/Network/GameNetworkManager.cpp @@ -1108,7 +1108,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc( void* lpParam ) app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE); // wait for the server to be in a non-ticking state - pServer->m_serverPausedEvent->WaitForSignal(INFINITY); + pServer->m_serverPausedEvent->WaitForSignal(INFINITE); #if defined(__PS3__) || defined(__ORBIS__) || defined __PSVITA__ // Swap these two messages around as one is too long to display at 480 @@ -1926,7 +1926,7 @@ void CGameNetworkManager::ServerReadyWait() { if (m_hServerReadyEvent != NULL) { - m_hServerReadyEvent->WaitForSignal(INFINITY); + m_hServerReadyEvent->WaitForSignal(INFINITE); } else { @@ -1990,7 +1990,7 @@ void CGameNetworkManager::ServerStoppedWait() { if (m_hServerStoppedEvent != NULL) { - m_hServerStoppedEvent->WaitForSignal(INFINITY); + m_hServerStoppedEvent->WaitForSignal(INFINITE); } else { From af16088015842705bddbab2366d67dbcd00ac5df Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Tue, 10 Mar 2026 20:13:01 +0100 Subject: [PATCH 14/17] improved a change --- Minecraft.World/Network/Packets/AwardStatPacket.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Minecraft.World/Network/Packets/AwardStatPacket.cpp b/Minecraft.World/Network/Packets/AwardStatPacket.cpp index 576cead1b..3ec3113a0 100644 --- a/Minecraft.World/Network/Packets/AwardStatPacket.cpp +++ b/Minecraft.World/Network/Packets/AwardStatPacket.cpp @@ -16,12 +16,13 @@ AwardStatPacket::AwardStatPacket(int statId, int count) { this->statId = statId; - // 4jcraft, changed from new int(count); to new int[1]; - // and initializing the array with count - // reason: .data needs to be delete with delete[] but its - // allocated with new, not new T[] - this->m_paramData.data = (uint8_t *) new int[1]; - ((int*)this->m_paramData.data)[0] = count; + // 4jcraft, changed from (uint8_t*) new int(count); to: + // new uint8_t[sizeof(int)]; + // and memcpy of the integer into the array + // reason: operator missmatch, array is deleted with delete[] + // and typesafety + this->m_paramData.data = new uint8_t[sizeof(int)]; + memcpy(this->m_paramData.data, &count, sizeof(int)); this->m_paramData.length = sizeof(int); } From da3d69b5bde6edd2b73f7430ae1861bd07f6702a Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Tue, 10 Mar 2026 20:27:11 +0100 Subject: [PATCH 15/17] final commit, removed scripts and reset meson.build --- debug.sh | 6 ------ meson.build | 16 ---------------- run.sh | 6 ------ 3 files changed, 28 deletions(-) delete mode 100755 debug.sh delete mode 100755 run.sh diff --git a/debug.sh b/debug.sh deleted file mode 100755 index b5a3c173d..000000000 --- a/debug.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -CC=clang CXX=clang++ meson compile -C build && \ -cd build/Minecraft.Client/ && \ -gdb -tui ./Minecraft.Client && \ -cd ../.. diff --git a/meson.build b/meson.build index 357396709..418d35a0b 100644 --- a/meson.build +++ b/meson.build @@ -12,9 +12,6 @@ pymod = import('python') python = pymod.find_installation('python3', required: true) cc = meson.get_compiler('cpp') -buildtype = get_option('buildtype') -#langs cant sadly be set before calling project -langs = ['cpp', 'c'] # system deps gl_dep = dependency('gl') @@ -24,19 +21,6 @@ png_dep = dependency('libpng') thread_dep = dependency('threads') dl_dep = cc.find_library('dl') -if buildtype.startswith('debug') - strAsan = '-fsanitize=address' - strLsan = '-fsanitize=leak' - if cc.has_argument(strAsan) - add_project_arguments(strAsan, language: langs) - add_project_link_arguments(strAsan, language: langs) - endif - if cc.has_argument(strLsan) - add_project_arguments(strLsan, language: langs) - add_project_link_arguments(strLsan, language: langs) - endif -endif - # compile flags (chagne ts juicey) global_cpp_args = [ '-fpermissive', diff --git a/run.sh b/run.sh deleted file mode 100755 index d261f892b..000000000 --- a/run.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -CC=clang CXX=clang++ meson compile -C build && \ -cd build/Minecraft.Client/ && \ -./Minecraft.Client && \ -cd ../.. From 0ff6f767e5ae91d50169fcab0e34656b902b2abc Mon Sep 17 00:00:00 2001 From: Nikita Edel Date: Tue, 10 Mar 2026 20:30:31 +0100 Subject: [PATCH 16/17] formailize comments --- Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h | 2 +- Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp | 2 +- Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.h | 2 +- Minecraft.Client/Platform/Common/Tutorial/TakeItemHint.h | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h b/Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h index a8c389c37..035a88e68 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h +++ b/Minecraft.Client/Platform/Common/Tutorial/LookAtEntityHint.h @@ -14,7 +14,7 @@ private: public: LookAtEntityHint(eTutorial_Hint id, Tutorial *tutorial, int descriptionId, int titleId, eINSTANCEOF type); - //TODO: LEAK LEKAFDSAKFDJ;SALKDJF;ASLKFJ ITS NEVER IMPLEMENTED + //TODO: 4jcraft added, this was not implemented ~LookAtEntityHint(){}; virtual bool onLookAtEntity(eINSTANCEOF type); diff --git a/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp b/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp index c9ef4ce0e..760d5b54f 100644 --- a/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp +++ b/Minecraft.Client/Platform/Common/Tutorial/LookAtTileHint.cpp @@ -10,7 +10,7 @@ LookAtTileHint::LookAtTileHint(eTutorial_Hint id, Tutorial *tutorial, int tiles[ { m_iTilesCount = tilesLength; - //TODO LEAK LEAK LEAK LEAKS EVERY WHERE AAAAAAAAAAAAAAAAH + //TODO: 4jcraft: allocating but never freeing mem, leak m_iTiles= new int [m_iTilesCount]; for(unsigned int i=0;i item ); From 12ede0691aa4baa214ceb49e71e8e74fb23ae0e0 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+tropicaaal@users.noreply.github.com> Date: Tue, 10 Mar 2026 15:22:37 -0500 Subject: [PATCH 17/17] fix: remove unused console-only asset archive imports --- Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp index 4ab22f581..38717792f 100644 --- a/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp +++ b/Minecraft.Client/Platform/Linux/Linux_Minecraft.cpp @@ -699,10 +699,6 @@ ProfileManager.Initialise(TITLEID_MINECRAFT, &app.uiGameDefinedDataChangedBitmask ); -byteArray baOptionsIcon = app.getArchiveFile(L"DefaultOptionsImage228x128.png"); -byteArray baSaveThumbnail = app.getArchiveFile(L"DefaultSaveThumbnail64x64.png"); -byteArray baSaveImage = app.getArchiveFile(L"DefaultSaveImage228x128.png"); - // set a function to be called when there's a sign in change, so we can exit a level if the primary player signs out ProfileManager.SetSignInChangeCallback(&CConsoleMinecraftApp::SignInChangeCallback,(LPVOID)&app);