diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000..383e62104 --- /dev/null +++ b/.clang-format @@ -0,0 +1,55 @@ +--- +BasedOnStyle: Microsoft +AccessModifierOffset: -2 +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterExternBlock: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: false + BeforeCatch: true + BeforeElse: true + BeforeLambdaBody: false + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +ColumnLimit: 0 +IncludeBlocks: Preserve +IndentAccessModifiers: false +IndentCaseBlocks: true +IndentCaseLabels: false +IndentExportBlock: true +IndentExternBlock: AfterExternBlock +IndentGotoLabels: false +IndentPPDirectives: None +IndentWidth: 4 +InsertBraces: true +InsertNewlineAtEOF: true +NamespaceIndentation: None +PointerAlignment: Right +RemoveParentheses: Leave +RemoveSemicolon: false +SeparateDefinitionBlocks: Leave +ShortNamespaceLines: 1 +SkipMacroDefinitionBody: false +SortIncludes: + Enabled: true + IgnoreCase: false +SpacesInParens: Never +SpacesInParensOptions: + ExceptDoubleParentheses: false + InCStyleCasts: false + InConditionalStatements: false + InEmptyParentheses: false + Other: false +SpacesInSquareBrackets: false +Standard: Latest +TabWidth: 4 +UseTab: Never diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 9578777cb..a1c3e74aa 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,23 +1,23 @@ -# Pull Request - -## Note: IF YOUR PR CHANGES THE GAME BEHAVIOR VISIBLY, REMEMBER TO ATTACH A GAMEPLAY FOOTAGE (or at least a screenshot) OF YOU *ACTUALLY* PLAYING THE GAME WITH YOUR CHANGES. Untested PRs are *NOT* welcome. Please don't forget to describe what did you do in each commit in your PR. + ## Description -Briefly describe the changes this PR introduces. + ## Changes ### Previous Behavior -*Describe how the code behaved before this change.* + ### Root Cause -*Explain the core reason behind the erroneous/old behavior (e.g., bug, design flaw, missing edge case).* + ### New Behavior -*Describe how the code behaves after this change.* + ### Fix Implementation -*Detail exactly how the issue was resolved (specific code changes, algorithms, logic flows).* + ## Related Issues - Fixes #[issue-number] diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index df01b57af..4ef1274d2 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -8,6 +8,7 @@ on: paths-ignore: - '.gitignore' - '*.md' + - '.github/*.md' jobs: build: @@ -35,5 +36,8 @@ jobs: with: tag_name: nightly name: Nightly Release - body: Compiled with MSVC v14.44.35207 in Release mode with Whole Program Optimization, as well as `/O2 /Ot /Oi /Ob3 /GF`. (So far the floating point model is `/fp:strict` to avoid undefined behavior before we refactor for performance). Requires at least Windows 7 and DirectX 11 compatible GPU to run. - files: LCEWindows64.zip + body: Requires at least Windows 7 and DirectX 11 compatible GPU to run. Compiled with MSVC v14.44.35207 in Release mode with Whole Program Optimization, as well as `/O2 /Ot /Oi /Ob3 /GF /fp:precise`. + files: | + LCEWindows64.zip + ./x64/Release/Minecraft.Client.exe + ./x64/Release/Minecraft.Client.pdb diff --git a/CMakeLists.txt b/CMakeLists.txt index c3ae11260..74851754d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.24) -project(MinecraftConsoles LANGUAGES C CXX ASM_MASM) +project(MinecraftConsoles LANGUAGES C CXX RC ASM_MASM) if(NOT WIN32) message(FATAL_ERROR "This CMake build currently supports Windows only.") @@ -12,11 +12,24 @@ endif() set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$:Debug>") +function(configure_msvc_target target) + target_compile_options(${target} PRIVATE + $<$>,$>:/W3> + $<$,$>:/W0> + $<$:/MP> + $<$:/EHsc> + $<$,$>:/GL /O2 /Oi /GT /GF> + ) +endfunction() + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/WorldSources.cmake") include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/ClientSources.cmake") list(TRANSFORM MINECRAFT_WORLD_SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.World/") list(TRANSFORM MINECRAFT_CLIENT_SOURCES PREPEND "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.Client/") +list(APPEND MINECRAFT_CLIENT_SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/Minecraft.Client/Xbox/MinecraftWindows.rc" +) add_library(MinecraftWorld STATIC ${MINECRAFT_WORLD_SOURCES}) target_include_directories(MinecraftWorld PRIVATE @@ -28,11 +41,7 @@ target_compile_definitions(MinecraftWorld PRIVATE $<$>:_LARGE_WORLDS;_DEBUG_MENUS_ENABLED;_LIB;_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDOWS64> ) if(MSVC) - target_compile_options(MinecraftWorld PRIVATE - $<$:/W3> - $<$:/MP> - $<$:/EHsc> - ) + configure_msvc_target(MinecraftWorld) endif() add_executable(MinecraftClient WIN32 ${MINECRAFT_CLIENT_SOURCES}) @@ -47,10 +56,9 @@ target_compile_definitions(MinecraftClient PRIVATE $<$>:_LARGE_WORLDS;_DEBUG_MENUS_ENABLED;_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDOWS64> ) if(MSVC) - target_compile_options(MinecraftClient PRIVATE - $<$:/W3> - $<$:/MP> - $<$:/EHsc> + configure_msvc_target(MinecraftClient) + target_link_options(MinecraftClient PRIVATE + $<$:/LTCG /INCREMENTAL:NO> ) endif() diff --git a/Minecraft.Client/Common/App_enums.h b/Minecraft.Client/Common/App_enums.h index db7bf70b3..e8e0d147e 100644 --- a/Minecraft.Client/Common/App_enums.h +++ b/Minecraft.Client/Common/App_enums.h @@ -829,6 +829,7 @@ enum EControllerActions ACTION_MENU_OTHER_STICK_LEFT, ACTION_MENU_OTHER_STICK_RIGHT, ACTION_MENU_PAUSEMENU, + ACTION_MENU_QUICK_MOVE, #ifdef _DURANGO ACTION_MENU_GTC_PAUSE, diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.cpp b/Minecraft.Client/Common/Network/GameNetworkManager.cpp index b3fb5cd70..a65a61aa9 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.cpp +++ b/Minecraft.Client/Common/Network/GameNetworkManager.cpp @@ -1978,7 +1978,7 @@ bool CGameNetworkManager::AllowedToPlayMultiplayer(int playerIdx) return ProfileManager.AllowedToPlayMultiplayer(playerIdx); } -char *CGameNetworkManager::GetOnlineName(int playerIdx) +const char *CGameNetworkManager::GetOnlineName(int playerIdx) { return ProfileManager.GetGamertag(playerIdx); } diff --git a/Minecraft.Client/Common/Network/GameNetworkManager.h b/Minecraft.Client/Common/Network/GameNetworkManager.h index 01db27240..bb7633c28 100644 --- a/Minecraft.Client/Common/Network/GameNetworkManager.h +++ b/Minecraft.Client/Common/Network/GameNetworkManager.h @@ -196,7 +196,7 @@ private: int GetLockedProfile(); bool IsSignedInLive(int playerIdx); bool AllowedToPlayMultiplayer(int playerIdx); - char *GetOnlineName(int playerIdx); + const char *GetOnlineName(int playerIdx); C4JThread::Event* m_hServerStoppedEvent; C4JThread::Event* m_hServerReadyEvent; diff --git a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp index 1b76141d1..667431b2b 100644 --- a/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_AbstractContainerMenu.cpp @@ -1304,42 +1304,60 @@ bool IUIScene_AbstractContainerMenu::handleKeyDown(int iPad, int iAction, bool b #endif int buttonNum=0; // 0 = LeftMouse, 1 = RightMouse - BOOL quickKeyHeld=FALSE; // Represents shift key on PC - - BOOL validKeyPress = FALSE; + BOOL quickKeyHeld=false; // Represents shift key on PC + BOOL quickKeyDown = false; // Represents shift key on PC + BOOL validKeyPress = false; bool itemEditorKeyPress = false; // Ignore input from other players //if(pMinecraft->player->GetXboxPad()!=pInputData->UserIndex) return S_OK; - + switch(iAction) { #ifdef _DEBUG_MENUS_ENABLED case ACTION_MENU_OTHER_STICK_PRESS: itemEditorKeyPress = TRUE; break; -#endif +#endif case ACTION_MENU_A: #ifdef __ORBIS__ case ACTION_MENU_TOUCHPAD_PRESS: #endif - if(!bRepeat) + if (!bRepeat) { validKeyPress = TRUE; // Standard left click buttonNum = 0; - quickKeyHeld = FALSE; - - if( IsSectionSlotList( m_eCurrSection ) ) + if (KMInput.IsKeyDown(VK_SHIFT)) { - int currentIndex = getCurrentIndex( m_eCurrSection ) - getSectionStartOffset(m_eCurrSection); + { + validKeyPress = TRUE; - bool bSlotHasItem = !isSlotEmpty(m_eCurrSection, currentIndex); - if ( bSlotHasItem ) - ui.PlayUISFX(eSFX_Press); + // Shift and left click + buttonNum = 0; + quickKeyHeld = TRUE; + if (IsSectionSlotList(m_eCurrSection)) + { + int currentIndex = getCurrentIndex(m_eCurrSection) - getSectionStartOffset(m_eCurrSection); + + bool bSlotHasItem = !isSlotEmpty(m_eCurrSection, currentIndex); + if (bSlotHasItem) + ui.PlayUISFX(eSFX_Press); + } + } + } + else { + if (IsSectionSlotList(m_eCurrSection)) + { + int currentIndex = getCurrentIndex(m_eCurrSection) - getSectionStartOffset(m_eCurrSection); + + bool bSlotHasItem = !isSlotEmpty(m_eCurrSection, currentIndex); + if (bSlotHasItem) + ui.PlayUISFX(eSFX_Press); + } + // } - // } break; case ACTION_MENU_X: @@ -1361,6 +1379,7 @@ bool IUIScene_AbstractContainerMenu::handleKeyDown(int iPad, int iAction, bool b } } break; + case ACTION_MENU_Y: if(!bRepeat) { diff --git a/Minecraft.Client/Common/UI/UIController.cpp b/Minecraft.Client/Common/UI/UIController.cpp index 100262065..a169a4330 100644 --- a/Minecraft.Client/Common/UI/UIController.cpp +++ b/Minecraft.Client/Common/UI/UIController.cpp @@ -1012,6 +1012,7 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key) case ACTION_MENU_PAUSEMENU: kbDown = KMInput.IsKeyDown(VK_ESCAPE); kbPressed = KMInput.IsKeyPressed(VK_ESCAPE); kbReleased = KMInput.IsKeyReleased(VK_ESCAPE); break; case ACTION_MENU_LEFT_SCROLL: kbDown = KMInput.IsKeyDown('Q'); kbPressed = KMInput.IsKeyPressed('Q'); kbReleased = KMInput.IsKeyReleased('Q'); break; case ACTION_MENU_RIGHT_SCROLL: kbDown = KMInput.IsKeyDown('E'); kbPressed = KMInput.IsKeyPressed('E'); kbReleased = KMInput.IsKeyReleased('E'); break; + case ACTION_MENU_QUICK_MOVE: kbDown = KMInput.IsKeyDown(VK_SHIFT); kbPressed = KMInput.IsKeyPressed(VK_SHIFT); kbReleased = KMInput.IsKeyReleased(VK_SHIFT); break; } pressed = pressed || kbPressed; released = released || kbReleased; diff --git a/Minecraft.Client/Extrax64Stubs.cpp b/Minecraft.Client/Extrax64Stubs.cpp index 3a86cbeaf..22ad578fb 100644 --- a/Minecraft.Client/Extrax64Stubs.cpp +++ b/Minecraft.Client/Extrax64Stubs.cpp @@ -589,8 +589,21 @@ char fakeGamerTag[32] = "PlayerName"; void SetFakeGamertag(char* name) { strcpy_s(fakeGamerTag, name); } char* C_4JProfile::GetGamertag(int iPad) { return fakeGamerTag; } #else -char* C_4JProfile::GetGamertag(int iPad) { extern char g_Win64Username[17]; return g_Win64Username; } -wstring C_4JProfile::GetDisplayName(int iPad) { extern wchar_t g_Win64UsernameW[17]; return g_Win64UsernameW; } +#include + +const char* C_4JProfile::GetGamertag(int iPad) +{ + static std::string narrowName; + const wchar_t* wideName = g_playerName.c_str(); + + int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, wideName, -1, nullptr, 0, nullptr, nullptr); + + narrowName.resize(sizeNeeded); + WideCharToMultiByte(CP_UTF8, 0, wideName, -1, &narrowName[0], sizeNeeded, nullptr, nullptr); + + return narrowName.c_str(); +} +wstring C_4JProfile::GetDisplayName(int iPad) { return g_playerName; } #endif bool C_4JProfile::IsFullVersion() { return s_bProfileIsFullVersion; } void C_4JProfile::SetSignInChangeCallback(void (*Func)(LPVOID, bool, unsigned int), LPVOID lpParam) {} diff --git a/Minecraft.Client/LevelRenderer.cpp b/Minecraft.Client/LevelRenderer.cpp index 19322ce8a..4101b913c 100644 --- a/Minecraft.Client/LevelRenderer.cpp +++ b/Minecraft.Client/LevelRenderer.cpp @@ -1967,8 +1967,8 @@ bool LevelRenderer::updateDirtyChunks() { if( (!onlyRebuild) || globalChunkFlags[ pClipChunk->globalIdx ] & CHUNK_FLAG_COMPILED || - ( distSq < 20 * 20 ) ) // Always rebuild really near things or else building (say) at tower up into empty blocks when we are low on memory will not create render data - { + ( distSq < 96 * 96 ) ) // Always rebuild really near things or else building (say) at tower up into empty blocks when we are low on memory will not create render data + { // distSq adjusted from 20 * 20 to 96 * 96 - updated by detectiveren considered++; // Is this chunk nearer than our nearest? #ifdef _LARGE_WORLDS diff --git a/Minecraft.Client/LevelRenderer.h b/Minecraft.Client/LevelRenderer.h index 88280b1e4..a9e73a604 100644 --- a/Minecraft.Client/LevelRenderer.h +++ b/Minecraft.Client/LevelRenderer.h @@ -52,14 +52,18 @@ public: static const int CHUNK_SIZE = 16; #endif static const int CHUNK_Y_COUNT = Level::maxBuildHeight / CHUNK_SIZE; -#if (defined _XBOX_ONE || defined _WINDOWS64) - static const int MAX_COMMANDBUFFER_ALLOCATIONS = 2047 * 1024 * 1024; // Changed to 2047. 4J had set to 512. +#if defined _WINDOWS64 + static const int MAX_COMMANDBUFFER_ALLOCATIONS = 2047 * 1024 * 1024; // Changed to 2047. 4J had set to 512. +#elif defined _XBOX_ONE + static const int MAX_COMMANDBUFFER_ALLOCATIONS = 512 * 1024 * 1024; // 4J - added #elif defined __ORBIS__ static const int MAX_COMMANDBUFFER_ALLOCATIONS = 448 * 1024 * 1024; // 4J - added - hard limit is 512 so giving a lot of headroom here for fragmentation (have seen 16MB lost to fragmentation in multiplayer crash dump before) #elif defined __PS3__ static const int MAX_COMMANDBUFFER_ALLOCATIONS = 110 * 1024 * 1024; // 4J - added +#elif defined _WINDOWS64 + static const int MAX_COMMANDBUFFER_ALLOCATIONS = 2047 * 1024 * 1024; // added by Twest #else - static const int MAX_COMMANDBUFFER_ALLOCATIONS = 55 * 1024 * 1024; // 4J - added + static const int MAX_COMMANDBUFFER_ALLOCATIONS = 55 * 1024 * 1024; // 4J - added #endif public: LevelRenderer(Minecraft *mc, Textures *textures); @@ -270,10 +274,10 @@ public: bool dirtyChunkPresent; __int64 lastDirtyChunkFound; - static const int FORCE_DIRTY_CHUNK_CHECK_PERIOD_MS = 250; + static const int FORCE_DIRTY_CHUNK_CHECK_PERIOD_MS = 125; // decreased from 250 to 125 - updated by detectiveren #ifdef _LARGE_WORLDS - static const int MAX_CONCURRENT_CHUNK_REBUILDS = 4; + static const int MAX_CONCURRENT_CHUNK_REBUILDS = 8; // increased from 4 to 8 - updated by detectiveren static const int MAX_CHUNK_REBUILD_THREADS = MAX_CONCURRENT_CHUNK_REBUILDS - 1; static Chunk permaChunk[MAX_CONCURRENT_CHUNK_REBUILDS]; static C4JThread *rebuildThreads[MAX_CHUNK_REBUILD_THREADS]; diff --git a/Minecraft.Client/Windows64/4JLibs/inc/4J_Profile.h b/Minecraft.Client/Windows64/4JLibs/inc/4J_Profile.h index f1bd85bbe..f7718a835 100644 --- a/Minecraft.Client/Windows64/4JLibs/inc/4J_Profile.h +++ b/Minecraft.Client/Windows64/4JLibs/inc/4J_Profile.h @@ -75,7 +75,7 @@ public: // SYS int GetPrimaryPad(); void SetPrimaryPad(int iPad); - char* GetGamertag(int iPad); + const char* GetGamertag(int iPad); wstring GetDisplayName(int iPad); bool IsFullVersion(); void SetSignInChangeCallback(void ( *Func)(LPVOID, bool, unsigned int),LPVOID lpParam); diff --git a/Minecraft.Client/Windows64/Windows64_App.h b/Minecraft.Client/Windows64/Windows64_App.h index bff916ec7..32d204ad0 100644 --- a/Minecraft.Client/Windows64/Windows64_App.h +++ b/Minecraft.Client/Windows64/Windows64_App.h @@ -33,6 +33,7 @@ public: virtual void TemporaryCreateGameStart(); bool m_bShutdown; + wstring g_playerName; }; extern CConsoleMinecraftApp app; diff --git a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp index 5c05c7c7d..6199e8069 100644 --- a/Minecraft.Client/Windows64/Windows64_Minecraft.cpp +++ b/Minecraft.Client/Windows64/Windows64_Minecraft.cpp @@ -85,8 +85,6 @@ BOOL g_bWidescreen = TRUE; int g_iScreenWidth = 1920; int g_iScreenHeight = 1080; -char g_Win64Username[17] = { 0 }; -wchar_t g_Win64UsernameW[17] = { 0 }; UINT g_ScreenWidth = 1920; UINT g_ScreenHeight = 1080; @@ -764,42 +762,8 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, //g_iScreenWidth = 960; //g_iScreenHeight = 544; } - - char cmdLineA[1024]; - strncpy_s(cmdLineA, sizeof(cmdLineA), lpCmdLine, _TRUNCATE); - - char* nameArg = strstr(cmdLineA, "-name "); - if (nameArg) - { - nameArg += 6; - while (*nameArg == ' ') nameArg++; - char nameBuf[17]; - int n = 0; - while (nameArg[n] && nameArg[n] != ' ' && n < 16) { nameBuf[n] = nameArg[n]; n++; } - nameBuf[n] = 0; - strncpy_s(g_Win64Username, 17, nameBuf, _TRUNCATE); - } } - if (g_Win64Username[0] == 0) - { - DWORD sz = 17; - static bool seeded = false; - if (!seeded) - { - seeded = true; - srand((unsigned int)time(NULL)); - } - - int r = rand() % 10000; // 0�9999 - - snprintf(g_Win64Username, 17, "Player%04d", r); - - g_Win64Username[16] = 0; - } - - MultiByteToWideChar(CP_ACP, 0, g_Win64Username, -1, g_Win64UsernameW, 17); - // Initialize global strings MyRegisterClass(hInstance); @@ -971,8 +935,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance, IQNet::m_player[i].m_isHostPlayer = (i == 0); swprintf_s(IQNet::m_player[i].m_gamertag, 32, L"Player%d", i); } - extern wchar_t g_Win64UsernameW[17]; - wcscpy_s(IQNet::m_player[0].m_gamertag, 32, g_Win64UsernameW); WinsockNetLayer::Initialize(); diff --git a/README.md b/README.md index 999626e9a..bc45ef229 100644 --- a/README.md +++ b/README.md @@ -33,13 +33,7 @@ Basic LAN multiplayer is available on the Windows build - Other players on the same LAN can discover the session from the in-game Join Game menu - Game connections use TCP port `25565` by default - LAN discovery uses UDP port `25566` -- You can override your in-game username at launch with `-name` - -Example: - -```powershell -Minecraft.Client.exe -name Steve -``` +- You can override your in-game username at launch with `username.txt` This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/)