diff --git a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp index 544fedc0f..04852e97d 100644 --- a/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp +++ b/Minecraft.Client/Common/UI/IUIScene_CreativeMenu.cpp @@ -1098,7 +1098,15 @@ void IUIScene_CreativeMenu::handleAdditionalKeyPress(int iAction) } break; case ACTION_MENU_OTHER_STICK_DOWN: - ++m_tabPage[m_curTab]; + { + int pageStep = TabSpec::rows; +#ifdef _WINDOWS64 + if (g_KBMInput.WasMouseWheelConsumed()) + { + pageStep = 1; + } +#endif + m_tabPage[m_curTab] += pageStep; if(m_tabPage[m_curTab] >= specs[m_curTab]->getPageCount()) { m_tabPage[m_curTab] = specs[m_curTab]->getPageCount() - 1; @@ -1107,9 +1115,18 @@ void IUIScene_CreativeMenu::handleAdditionalKeyPress(int iAction) { switchTab(m_curTab); } + } break; case ACTION_MENU_OTHER_STICK_UP: - --m_tabPage[m_curTab]; + { + int pageStep = TabSpec::rows; +#ifdef _WINDOWS64 + if (g_KBMInput.WasMouseWheelConsumed()) + { + pageStep = 1; + } +#endif + m_tabPage[m_curTab] -= pageStep; if(m_tabPage[m_curTab] < 0) { m_tabPage[m_curTab] = 0; @@ -1118,6 +1135,7 @@ void IUIScene_CreativeMenu::handleAdditionalKeyPress(int iAction) { switchTab(m_curTab); } + } break; } } diff --git a/Minecraft.Client/Input.cpp b/Minecraft.Client/Input.cpp index 5e41da299..4d931d3e6 100644 --- a/Minecraft.Client/Input.cpp +++ b/Minecraft.Client/Input.cpp @@ -104,7 +104,7 @@ void Input::tick(LocalPlayer *player) } } - // Left Ctrl + forward = sprint (hold to sprint) + // Ctrl + forward = sprint (hold to sprint) if (!player->abilities.flying) { bool ctrlHeld = g_KBMInput.IsKeyDown(KeyboardMouseInput::KEY_SPRINT); diff --git a/Minecraft.Client/LivingEntityRenderer.cpp b/Minecraft.Client/LivingEntityRenderer.cpp index 89d656142..757948a37 100644 --- a/Minecraft.Client/LivingEntityRenderer.cpp +++ b/Minecraft.Client/LivingEntityRenderer.cpp @@ -487,11 +487,11 @@ void LivingEntityRenderer::renderNameTag(shared_ptr mob, const wst Font *font = getFont(); - float size = 1.60f; - float s = 1 / 60.0f * size; + constexpr float size = 1.60f; + constexpr float s = 1 / 60.0f * size; glPushMatrix(); - glTranslatef((float) x + 0, (float) y + 2.3f, (float) z); + glTranslatef(static_cast(x) + 0, static_cast(y) + mob->bbHeight + 0.5f, static_cast(z)); glNormal3f(0, 1, 0); glRotatef(-this->entityRenderDispatcher->playerRotY, 0, 1, 0); diff --git a/Minecraft.Client/MinecraftServer.cpp b/Minecraft.Client/MinecraftServer.cpp index a81bce592..af9e226bc 100644 --- a/Minecraft.Client/MinecraftServer.cpp +++ b/Minecraft.Client/MinecraftServer.cpp @@ -31,6 +31,9 @@ #include "..\Minecraft.World\net.minecraft.world.item.h" #include "..\Minecraft.World\net.minecraft.world.item.enchantment.h" #include "..\Minecraft.World\net.minecraft.world.damagesource.h" +#ifdef _WINDOWS64 +#include "Windows64\Network\WinsockNetLayer.h" +#endif #include #ifdef SPLIT_SAVES #include "..\Minecraft.World\ConsoleSaveFileSplit.h" @@ -83,6 +86,30 @@ bool MinecraftServer::s_slowQueuePacketSent = false; unordered_map MinecraftServer::ironTimers; +static bool ShouldUseDedicatedServerProperties() +{ +#ifdef _WINDOWS64 + return g_Win64DedicatedServer; +#else + return false; +#endif +} + +static int GetDedicatedServerInt(Settings *settings, const wchar_t *key, int defaultValue) +{ + return (ShouldUseDedicatedServerProperties() && settings != NULL) ? settings->getInt(key, defaultValue) : defaultValue; +} + +static bool GetDedicatedServerBool(Settings *settings, const wchar_t *key, bool defaultValue) +{ + return (ShouldUseDedicatedServerProperties() && settings != NULL) ? settings->getBoolean(key, defaultValue) : defaultValue; +} + +static wstring GetDedicatedServerString(Settings *settings, const wchar_t *key, const wstring &defaultValue) +{ + return (ShouldUseDedicatedServerProperties() && settings != NULL) ? settings->getString(key, defaultValue) : defaultValue; +} + static void PrintConsoleLine(const wchar_t *prefix, const wstring &message) { wprintf(L"%ls%ls\n", prefix, message.c_str()); @@ -589,14 +616,14 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW #endif settings = new Settings(new File(L"server.properties")); - app.SetGameHostOption(eGameHostOption_Difficulty, settings->getInt(L"difficulty", app.GetGameHostOption(eGameHostOption_Difficulty))); - app.SetGameHostOption(eGameHostOption_GameType, settings->getInt(L"gamemode", app.GetGameHostOption(eGameHostOption_GameType))); - app.SetGameHostOption(eGameHostOption_Structures, settings->getBoolean(L"generate-structures", app.GetGameHostOption(eGameHostOption_Structures) > 0) ? 1 : 0); - app.SetGameHostOption(eGameHostOption_BonusChest, settings->getBoolean(L"bonus-chest", app.GetGameHostOption(eGameHostOption_BonusChest) > 0) ? 1 : 0); - app.SetGameHostOption(eGameHostOption_PvP, settings->getBoolean(L"pvp", app.GetGameHostOption(eGameHostOption_PvP) > 0) ? 1 : 0); - app.SetGameHostOption(eGameHostOption_TrustPlayers, settings->getBoolean(L"trust-players", app.GetGameHostOption(eGameHostOption_TrustPlayers) > 0) ? 1 : 0); - app.SetGameHostOption(eGameHostOption_FireSpreads, settings->getBoolean(L"fire-spreads", app.GetGameHostOption(eGameHostOption_FireSpreads) > 0) ? 1 : 0); - app.SetGameHostOption(eGameHostOption_TNT, settings->getBoolean(L"tnt", app.GetGameHostOption(eGameHostOption_TNT) > 0) ? 1 : 0); + app.SetGameHostOption(eGameHostOption_Difficulty, GetDedicatedServerInt(settings, L"difficulty", app.GetGameHostOption(eGameHostOption_Difficulty))); + app.SetGameHostOption(eGameHostOption_GameType, GetDedicatedServerInt(settings, L"gamemode", app.GetGameHostOption(eGameHostOption_GameType))); + app.SetGameHostOption(eGameHostOption_Structures, GetDedicatedServerBool(settings, L"generate-structures", app.GetGameHostOption(eGameHostOption_Structures) > 0) ? 1 : 0); + app.SetGameHostOption(eGameHostOption_BonusChest, GetDedicatedServerBool(settings, L"bonus-chest", app.GetGameHostOption(eGameHostOption_BonusChest) > 0) ? 1 : 0); + app.SetGameHostOption(eGameHostOption_PvP, GetDedicatedServerBool(settings, L"pvp", app.GetGameHostOption(eGameHostOption_PvP) > 0) ? 1 : 0); + app.SetGameHostOption(eGameHostOption_TrustPlayers, GetDedicatedServerBool(settings, L"trust-players", app.GetGameHostOption(eGameHostOption_TrustPlayers) > 0) ? 1 : 0); + app.SetGameHostOption(eGameHostOption_FireSpreads, GetDedicatedServerBool(settings, L"fire-spreads", app.GetGameHostOption(eGameHostOption_FireSpreads) > 0) ? 1 : 0); + app.SetGameHostOption(eGameHostOption_TNT, GetDedicatedServerBool(settings, L"tnt", app.GetGameHostOption(eGameHostOption_TNT) > 0) ? 1 : 0); app.DebugPrintf("\n*** SERVER SETTINGS ***\n"); app.DebugPrintf("ServerSettings: host-friends-only is %s\n",(app.GetGameHostOption(eGameHostOption_FriendsOfFriends)>0)?"on":"off"); @@ -615,13 +642,13 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW //motd = settings->getString(L"motd", L"A Minecraft Server"); //motd.replace('�', '$'); - setAnimals(settings->getBoolean(L"spawn-animals", true)); - setNpcsEnabled(settings->getBoolean(L"spawn-npcs", true)); + setAnimals(GetDedicatedServerBool(settings, L"spawn-animals", true)); + setNpcsEnabled(GetDedicatedServerBool(settings, L"spawn-npcs", true)); setPvpAllowed(app.GetGameHostOption( eGameHostOption_PvP )>0?true:false); // 4J Stu - We should never have hacked clients flying when they shouldn't be like the PC version, so enable flying always // Fix for #46612 - TU5: Code: Multiplayer: A client can be banned for flying when accidentaly being blown by dynamite - setFlightAllowed(settings->getBoolean(L"allow-flight", true)); + setFlightAllowed(GetDedicatedServerBool(settings, L"allow-flight", true)); // 4J Stu - Enabling flight to stop it kicking us when we use it #ifdef _DEBUG_MENUS_ENABLED @@ -667,7 +694,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW __int64 levelNanoTime = System::nanoTime(); - wstring levelName = (initData && !initData->levelName.empty()) ? initData->levelName : settings->getString(L"level-name", L"world"); + wstring levelName = (initData && !initData->levelName.empty()) ? initData->levelName : GetDedicatedServerString(settings, L"level-name", L"world"); wstring levelTypeString; bool gameRuleUseFlatWorld = false; @@ -677,11 +704,11 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW } if(gameRuleUseFlatWorld || app.GetGameHostOption(eGameHostOption_LevelType)>0) { - levelTypeString = settings->getString(L"level-type", L"flat"); + levelTypeString = GetDedicatedServerString(settings, L"level-type", L"flat"); } else { - levelTypeString = settings->getString(L"level-type",L"default"); + levelTypeString = GetDedicatedServerString(settings, L"level-type",L"default"); } LevelType *pLevelType = LevelType::getLevelType(levelTypeString); @@ -702,7 +729,7 @@ bool MinecraftServer::initServer(__int64 seed, NetworkGameInitData *initData, DW #endif } - setMaxBuildHeight(settings->getInt(L"max-build-height", Level::maxBuildHeight)); + setMaxBuildHeight(GetDedicatedServerInt(settings, L"max-build-height", Level::maxBuildHeight)); setMaxBuildHeight(((getMaxBuildHeight() + 8) / 16) * 16); setMaxBuildHeight(Mth::clamp(getMaxBuildHeight(), 64, Level::maxBuildHeight)); //settings->setProperty(L"max-build-height", maxBuildHeight); @@ -851,7 +878,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring // 4J TODO - free levels here if there are already some? levels = ServerLevelArray(3); - int gameTypeId = settings->getInt(L"gamemode", app.GetGameHostOption(eGameHostOption_GameType));//LevelSettings::GAMETYPE_SURVIVAL); + int gameTypeId = GetDedicatedServerInt(settings, L"gamemode", app.GetGameHostOption(eGameHostOption_GameType));//LevelSettings::GAMETYPE_SURVIVAL); GameType *gameType = LevelSettings::validateGameType(gameTypeId); app.DebugPrintf("Default game type: %d\n" , gameTypeId); @@ -950,7 +977,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring #if DEBUG_SERVER_DONT_SPAWN_MOBS levels[i]->setSpawnSettings(false, false); #else - levels[i]->setSpawnSettings(settings->getBoolean(L"spawn-monsters", true), animals); + levels[i]->setSpawnSettings(GetDedicatedServerBool(settings, L"spawn-monsters", true), animals); #endif levels[i]->getLevelData()->setGameType(gameType); @@ -1038,7 +1065,7 @@ bool MinecraftServer::loadLevel(LevelStorageSource *storageSource, const wstring for (int i = 0; i < levels.length ; i++) { // logger.info("Preparing start region for level " + i); - if (i == 0 || settings->getBoolean(L"allow-nether", true)) + if (i == 0 || GetDedicatedServerBool(settings, L"allow-nether", true)) { ServerLevel *level = levels[i]; if(levelChunksNeedConverted) @@ -1780,7 +1807,7 @@ void MinecraftServer::run(__int64 seed, void *lpParameter) MinecraftServer::setTimeOfDayAtEndOfTick = false; for (unsigned int i = 0; i < levels.length; i++) { - if (i == 0 || settings->getBoolean(L"allow-nether", true)) + if (i == 0 || GetDedicatedServerBool(settings, L"allow-nether", true)) { ServerLevel *level = levels[i]; level->setDayTime( MinecraftServer::setTimeOfDay ); diff --git a/Minecraft.Client/PlayerList.cpp b/Minecraft.Client/PlayerList.cpp index 3cf47a1cf..0de0c36be 100644 --- a/Minecraft.Client/PlayerList.cpp +++ b/Minecraft.Client/PlayerList.cpp @@ -53,14 +53,12 @@ PlayerList::PlayerList(MinecraftServer *server) //int viewDistance = server->settings->getInt(L"view-distance", 10); - maxPlayers = server->settings->getInt(L"max-players", 20); - doWhiteList = false; - #ifdef _WINDOWS64 maxPlayers = MINECRAFT_NET_MAX_PLAYERS; #else maxPlayers = server->settings->getInt(L"max-players", 20); #endif + doWhiteList = false; InitializeCriticalSection(&m_kickPlayersCS); InitializeCriticalSection(&m_closePlayersCS); } diff --git a/Minecraft.Client/Windows64/KeyboardMouseInput.cpp b/Minecraft.Client/Windows64/KeyboardMouseInput.cpp index 7ab99a719..6206db87e 100644 --- a/Minecraft.Client/Windows64/KeyboardMouseInput.cpp +++ b/Minecraft.Client/Windows64/KeyboardMouseInput.cpp @@ -12,6 +12,21 @@ extern HWND g_hWnd; // Forward declaration static void ClipCursorToWindow(HWND hWnd); +static bool IsModifierKeyDown(const bool* keyState, int vkCode) +{ + switch (vkCode) + { + case VK_SHIFT: + return keyState[VK_LSHIFT] || keyState[VK_RSHIFT]; + case VK_CONTROL: + return keyState[VK_LCONTROL] || keyState[VK_RCONTROL]; + case VK_MENU: + return keyState[VK_LMENU] || keyState[VK_RMENU]; + default: + return false; + } +} + void KeyboardMouseInput::Init() { memset(m_keyDown, 0, sizeof(m_keyDown)); @@ -33,6 +48,7 @@ void KeyboardMouseInput::Init() m_mouseDeltaAccumX = 0; m_mouseDeltaAccumY = 0; m_mouseWheelAccum = 0; + m_mouseWheelConsumed = false; m_mouseGrabbed = false; m_cursorHiddenForUI = false; m_windowFocused = true; @@ -67,6 +83,7 @@ void KeyboardMouseInput::ClearAllState() m_mouseDeltaAccumX = 0; m_mouseDeltaAccumY = 0; m_mouseWheelAccum = 0; + m_mouseWheelConsumed = false; } void KeyboardMouseInput::Tick() @@ -88,6 +105,7 @@ void KeyboardMouseInput::Tick() m_mouseDeltaY = m_mouseDeltaAccumY; m_mouseDeltaAccumX = 0; m_mouseDeltaAccumY = 0; + m_mouseWheelConsumed = false; m_hasInput = (m_mouseDeltaX != 0 || m_mouseDeltaY != 0 || m_mouseWheelAccum != 0); if (!m_hasInput) @@ -172,6 +190,8 @@ void KeyboardMouseInput::OnMouseWheel(int delta) int KeyboardMouseInput::GetMouseWheel() { int val = m_mouseWheelAccum; + if (val != 0) + m_mouseWheelConsumed = true; m_mouseWheelAccum = 0; return val; } @@ -184,6 +204,9 @@ void KeyboardMouseInput::OnRawMouseDelta(int dx, int dy) bool KeyboardMouseInput::IsKeyDown(int vkCode) const { + if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU) + return IsModifierKeyDown(m_keyDown, vkCode); + if (vkCode >= 0 && vkCode < MAX_KEYS) return m_keyDown[vkCode]; return false; @@ -191,6 +214,9 @@ bool KeyboardMouseInput::IsKeyDown(int vkCode) const bool KeyboardMouseInput::IsKeyPressed(int vkCode) const { + if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU) + return IsModifierKeyDown(m_keyPressed, vkCode); + if (vkCode >= 0 && vkCode < MAX_KEYS) return m_keyPressed[vkCode]; return false; @@ -198,6 +224,9 @@ bool KeyboardMouseInput::IsKeyPressed(int vkCode) const bool KeyboardMouseInput::IsKeyReleased(int vkCode) const { + if (vkCode == VK_SHIFT || vkCode == VK_CONTROL || vkCode == VK_MENU) + return IsModifierKeyDown(m_keyReleased, vkCode); + if (vkCode >= 0 && vkCode < MAX_KEYS) return m_keyReleased[vkCode]; return false; diff --git a/Minecraft.Client/Windows64/KeyboardMouseInput.h b/Minecraft.Client/Windows64/KeyboardMouseInput.h index f098ccabd..89a028b10 100644 --- a/Minecraft.Client/Windows64/KeyboardMouseInput.h +++ b/Minecraft.Client/Windows64/KeyboardMouseInput.h @@ -20,7 +20,7 @@ public: static const int KEY_RIGHT = 'D'; static const int KEY_JUMP = VK_SPACE; static const int KEY_SNEAK = VK_LSHIFT; - static const int KEY_SPRINT = VK_LCONTROL; + static const int KEY_SPRINT = VK_CONTROL; static const int KEY_INVENTORY = 'E'; static const int KEY_DROP = 'Q'; static const int KEY_CRAFTING = 'C'; @@ -59,7 +59,8 @@ public: int GetMouseWheel(); int PeekMouseWheel() const { return m_mouseWheelAccum; } - void ConsumeMouseWheel() { m_mouseWheelAccum = 0; } + void ConsumeMouseWheel() { if (m_mouseWheelAccum != 0) m_mouseWheelConsumed = true; m_mouseWheelAccum = 0; } + bool WasMouseWheelConsumed() const { return m_mouseWheelConsumed; } // Per-frame delta consumption for low-latency mouse look. // Reads and clears the raw accumulators (not the per-tick snapshot). @@ -114,6 +115,7 @@ private: int m_mouseDeltaAccumY; int m_mouseWheelAccum; + bool m_mouseWheelConsumed; bool m_mouseGrabbed;