Compare commits
25 Commits
feat/repla
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfcc4aa10c | ||
|
|
6c842b2854 | ||
|
|
c8a8f9dd6c | ||
|
|
b1b622c303 | ||
|
|
f216abca42 | ||
|
|
d31d261ffd | ||
|
|
f870ef2a10 | ||
|
|
ac30f09085 | ||
|
|
ac480f6745 | ||
|
|
30ecc80250 | ||
|
|
384b9f4445 | ||
|
|
31cc598b75 | ||
|
|
9b5348113c | ||
|
|
942ef7e99f | ||
|
|
540e33d787 | ||
|
|
1b0e5df27e | ||
|
|
515f91cad8 | ||
|
|
5c91c26086 | ||
|
|
b44d29b2ff | ||
|
|
a3095a7050 | ||
|
|
42bb19d490 | ||
|
|
1444581cb6 | ||
|
|
a97ee4aab1 | ||
|
|
2915044f95 | ||
|
|
6d4ce5136c |
53
.clang-format
Normal file
53
.clang-format
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
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: CaseSensitive
|
||||
SpacesInParens: Never
|
||||
SpacesInParensOptions:
|
||||
ExceptDoubleParentheses: false
|
||||
InCStyleCasts: false
|
||||
InConditionalStatements: false
|
||||
InEmptyParentheses: false
|
||||
Other: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Latest
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
16
.github/pull_request_template.md
vendored
16
.github/pull_request_template.md
vendored
@@ -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.
|
||||
<!--
|
||||
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.
|
||||
<!-- Briefly describe the changes this PR introduces. -->
|
||||
|
||||
## Changes
|
||||
|
||||
### Previous Behavior
|
||||
*Describe how the code behaved before this change.*
|
||||
<!-- 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).*
|
||||
<!-- 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.*
|
||||
<!-- Describe how the code behaves after this change. -->
|
||||
|
||||
### Fix Implementation
|
||||
*Detail exactly how the issue was resolved (specific code changes, algorithms, logic flows).*
|
||||
<!-- Detail exactly how the issue was resolved (specific code changes, algorithms, logic flows). -->
|
||||
|
||||
## Related Issues
|
||||
- Fixes #[issue-number]
|
||||
|
||||
8
.github/workflows/nightly.yml
vendored
8
.github/workflows/nightly.yml
vendored
@@ -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
|
||||
|
||||
@@ -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$<$<CONFIG:Debug>:Debug>")
|
||||
|
||||
function(configure_msvc_target target)
|
||||
target_compile_options(${target} PRIVATE
|
||||
$<$<AND:$<NOT:$<CONFIG:Release>>,$<COMPILE_LANGUAGE:C,CXX>>:/W3>
|
||||
$<$<AND:$<CONFIG:Release>,$<COMPILE_LANGUAGE:C,CXX>>:/W0>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:/MP>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:/EHsc>
|
||||
$<$<AND:$<CONFIG:Release>,$<COMPILE_LANGUAGE:C,CXX>>:/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
|
||||
$<$<NOT:$<CONFIG:Debug>>:_LARGE_WORLDS;_DEBUG_MENUS_ENABLED;_LIB;_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDOWS64>
|
||||
)
|
||||
if(MSVC)
|
||||
target_compile_options(MinecraftWorld PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:/W3>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:/MP>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:/EHsc>
|
||||
)
|
||||
configure_msvc_target(MinecraftWorld)
|
||||
endif()
|
||||
|
||||
add_executable(MinecraftClient WIN32 ${MINECRAFT_CLIENT_SOURCES})
|
||||
@@ -47,10 +56,9 @@ target_compile_definitions(MinecraftClient PRIVATE
|
||||
$<$<NOT:$<CONFIG:Debug>>:_LARGE_WORLDS;_DEBUG_MENUS_ENABLED;_CRT_NON_CONFORMING_SWPRINTFS;_CRT_SECURE_NO_WARNINGS;_WINDOWS64>
|
||||
)
|
||||
if(MSVC)
|
||||
target_compile_options(MinecraftClient PRIVATE
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:/W3>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:/MP>
|
||||
$<$<COMPILE_LANGUAGE:CXX>:/EHsc>
|
||||
configure_msvc_target(MinecraftClient)
|
||||
target_link_options(MinecraftClient PRIVATE
|
||||
$<$<CONFIG:Release>:/LTCG /INCREMENTAL:NO>
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -55,6 +55,12 @@
|
||||
#endif
|
||||
#include "DLCTexturePack.h"
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
#include "Xbox\Network\NetworkPlayerXbox.h"
|
||||
#include "Common\Network\PlatformNetworkManagerStub.h"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef _DURANGO
|
||||
#include "..\Minecraft.World\DurangoStats.h"
|
||||
#include "..\Minecraft.World\GenericStats.h"
|
||||
@@ -421,7 +427,6 @@ void ClientConnection::handleAddEntity(shared_ptr<AddEntityPacket> packet)
|
||||
{
|
||||
case AddEntityPacket::MINECART:
|
||||
e = Minecart::createMinecart(level, x, y, z, packet->data);
|
||||
break;
|
||||
case AddEntityPacket::FISH_HOOK:
|
||||
{
|
||||
// 4J Stu - Brought forward from 1.4 to be able to drop XP from fishing
|
||||
@@ -444,7 +449,7 @@ void ClientConnection::handleAddEntity(shared_ptr<AddEntityPacket> packet)
|
||||
}
|
||||
}
|
||||
|
||||
if (owner->instanceof(eTYPE_PLAYER))
|
||||
if (owner != NULL && owner->instanceof(eTYPE_PLAYER))
|
||||
{
|
||||
shared_ptr<Player> player = dynamic_pointer_cast<Player>(owner);
|
||||
shared_ptr<FishingHook> hook = shared_ptr<FishingHook>( new FishingHook(level, x, y, z, player) );
|
||||
@@ -793,7 +798,28 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
|
||||
if (networkPlayer != NULL) player->m_displayName = networkPlayer->GetDisplayName();
|
||||
#else
|
||||
// On all other platforms display name is just gamertag so don't check with the network manager
|
||||
player->m_displayName = player->name;
|
||||
player->m_displayName = player->getName();
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
{
|
||||
PlayerUID pktXuid = player->getXuid();
|
||||
const PlayerUID WIN64_XUID_BASE = (PlayerUID)0xe000d45248242f2e;
|
||||
if (pktXuid >= WIN64_XUID_BASE && pktXuid < WIN64_XUID_BASE + MINECRAFT_NET_MAX_PLAYERS)
|
||||
{
|
||||
BYTE smallId = (BYTE)(pktXuid - WIN64_XUID_BASE);
|
||||
INetworkPlayer* np = g_NetworkManager.GetPlayerBySmallId(smallId);
|
||||
if (np != NULL)
|
||||
{
|
||||
NetworkPlayerXbox* npx = (NetworkPlayerXbox*)np;
|
||||
IQNetPlayer* qp = npx->GetQNetPlayer();
|
||||
if (qp != NULL && qp->m_gamertag[0] == 0)
|
||||
{
|
||||
wcsncpy_s(qp->m_gamertag, 32, packet->name.c_str(), _TRUNCATE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// printf("\t\t\t\t%d: Add player\n",packet->id,packet->yRot);
|
||||
@@ -938,6 +964,39 @@ void ClientConnection::handleMoveEntitySmall(shared_ptr<MoveEntityPacketSmall> p
|
||||
|
||||
void ClientConnection::handleRemoveEntity(shared_ptr<RemoveEntitiesPacket> packet)
|
||||
{
|
||||
#ifdef _WINDOWS64
|
||||
if (!g_NetworkManager.IsHost())
|
||||
{
|
||||
for (int i = 0; i < packet->ids.length; i++)
|
||||
{
|
||||
shared_ptr<Entity> entity = getEntity(packet->ids[i]);
|
||||
if (entity != NULL && entity->GetType() == eTYPE_PLAYER)
|
||||
{
|
||||
shared_ptr<Player> player = dynamic_pointer_cast<Player>(entity);
|
||||
if (player != NULL)
|
||||
{
|
||||
PlayerUID xuid = player->getXuid();
|
||||
INetworkPlayer* np = g_NetworkManager.GetPlayerByXuid(xuid);
|
||||
if (np != NULL)
|
||||
{
|
||||
NetworkPlayerXbox* npx = (NetworkPlayerXbox*)np;
|
||||
IQNetPlayer* qp = npx->GetQNetPlayer();
|
||||
if (qp != NULL)
|
||||
{
|
||||
extern CPlatformNetworkManagerStub* g_pPlatformNetworkManager;
|
||||
g_pPlatformNetworkManager->NotifyPlayerLeaving(qp);
|
||||
qp->m_smallId = 0;
|
||||
qp->m_isRemote = false;
|
||||
qp->m_isHostPlayer = false;
|
||||
qp->m_gamertag[0] = 0;
|
||||
qp->SetCustomDataValue(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
for (int i = 0; i < packet->ids.length; i++)
|
||||
{
|
||||
level->removeEntity(packet->ids[i]);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
@@ -1444,7 +1445,7 @@ GDrawTexture * RADLINK UIController::TextureSubstitutionCreateCallback ( void *
|
||||
|
||||
// 4J Stu - All our flash controls that allow replacing textures use a special 64x64 symbol
|
||||
// Force this size here so that our images don't get scaled wildly
|
||||
#if (defined __ORBIS__ || defined _DURANGO )
|
||||
#if (defined __ORBIS__ || defined _DURANGO || defined _WINDOWS64 )
|
||||
*width = 96;
|
||||
*height = 96;
|
||||
#else
|
||||
|
||||
@@ -33,6 +33,11 @@ UIScene_AbstractContainerMenu::UIScene_AbstractContainerMenu(int iPad, UILayer *
|
||||
m_bHasMousePosition = false;
|
||||
m_lastMouseX = 0;
|
||||
m_lastMouseY = 0;
|
||||
|
||||
for (int btn = 0; btn < 3; btn++)
|
||||
{
|
||||
KMInput.ConsumeMousePress(btn);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -209,8 +214,8 @@ void UIScene_AbstractContainerMenu::tick()
|
||||
scrollDelta = KMInput.ConsumeScrollDelta();
|
||||
|
||||
// Convert mouse position to movie coordinates using the movie/client ratio
|
||||
float mx = (float)mouseX * ((float)m_movieWidth / (float)clientWidth);
|
||||
float my = (float)mouseY * ((float)m_movieHeight / (float)clientHeight);
|
||||
float mx = (float)mouseX * ((float)m_movieWidth / (float)clientWidth) - (float)m_controlMainPanel.getXPos();
|
||||
float my = (float)mouseY * ((float)m_movieHeight / (float)clientHeight) - (float)m_controlMainPanel.getYPos();
|
||||
|
||||
rawMouseMovieX = mx;
|
||||
rawMouseMovieY = my;
|
||||
@@ -301,8 +306,13 @@ void UIScene_AbstractContainerMenu::tick()
|
||||
// Scale mouse client coords to the Iggy display space (which was set to getRenderDimensions())
|
||||
RECT clientRect;
|
||||
GetClientRect(KMInput.GetHWnd(), &clientRect);
|
||||
x = (S32)((float)KMInput.GetMouseX() * ((float)width / (float)clientRect.right));
|
||||
y = (S32)((float)KMInput.GetMouseY() * ((float)height / (float)clientRect.bottom));
|
||||
float mouseMovieX = (float)KMInput.GetMouseX() * ((float)m_movieWidth / (float)clientRect.right);
|
||||
float mouseMovieY = (float)KMInput.GetMouseY() * ((float)m_movieHeight / (float)clientRect.bottom);
|
||||
float mouseLocalX = mouseMovieX - (float)m_controlMainPanel.getXPos();
|
||||
float mouseLocalY = mouseMovieY - (float)m_controlMainPanel.getYPos();
|
||||
|
||||
x = (S32)(mouseLocalX * ((float)width / m_movieWidth));
|
||||
y = (S32)(mouseLocalY * ((float)height / m_movieHeight));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -77,12 +77,7 @@ void EnderDragonRenderer::renderModel(shared_ptr<LivingEntity> _mob, float wp, f
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glColor4f(1, 0, 0, 0.5f);
|
||||
#ifdef __PSVITA__
|
||||
// AP - not sure that the usecompiled flag is supposed to be false. This makes it really slow on vita. Making it true still seems to look the same
|
||||
model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, true);
|
||||
#else
|
||||
model->render(mob, wp, ws, bob, headRotMinusBodyRot, headRotx, scale, false);
|
||||
#endif
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glDisable(GL_BLEND);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
|
||||
@@ -199,11 +199,10 @@ DWORD IQNetPlayer::GetSendQueueSize(IQNetPlayer * player, DWORD dwFlags) { retur
|
||||
DWORD IQNetPlayer::GetCurrentRtt() { return 0; }
|
||||
bool IQNetPlayer::IsHost() { return m_isHostPlayer; }
|
||||
bool IQNetPlayer::IsGuest() { return false; }
|
||||
bool IQNetPlayer::IsLocal() { return true; }
|
||||
bool IQNetPlayer::IsLocal() { return !m_isRemote; }
|
||||
PlayerUID IQNetPlayer::GetXuid() { return (PlayerUID)(0xe000d45248242f2e + m_smallId); } // todo: restore to INVALID_XUID once saves support this
|
||||
extern wstring g_playerName;
|
||||
LPCWSTR IQNetPlayer::GetGamertag() { return g_playerName.empty() ? L"Windows" : g_playerName.c_str(); }
|
||||
int IQNetPlayer::GetSessionIndex() { return 0; }
|
||||
LPCWSTR IQNetPlayer::GetGamertag() { return m_gamertag; }
|
||||
int IQNetPlayer::GetSessionIndex() { return m_smallId; }
|
||||
bool IQNetPlayer::IsTalking() { return false; }
|
||||
bool IQNetPlayer::IsMutedByLocalUser(DWORD dwUserIndex) { return false; }
|
||||
bool IQNetPlayer::HasVoice() { return false; }
|
||||
@@ -232,13 +231,17 @@ void Win64_SetupRemoteQNetPlayer(IQNetPlayer * player, BYTE smallId, bool isHost
|
||||
IQNet::s_playerCount = smallId + 1;
|
||||
}
|
||||
|
||||
static bool Win64_IsActivePlayer(IQNetPlayer* p, DWORD index);
|
||||
|
||||
HRESULT IQNet::AddLocalPlayerByUserIndex(DWORD dwUserIndex) { return S_OK; }
|
||||
IQNetPlayer* IQNet::GetHostPlayer() { return &m_player[0]; }
|
||||
IQNetPlayer* IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex)
|
||||
{
|
||||
if (s_isHosting)
|
||||
{
|
||||
if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS && !m_player[dwUserIndex].m_isRemote)
|
||||
if (dwUserIndex < MINECRAFT_NET_MAX_PLAYERS &&
|
||||
!m_player[dwUserIndex].m_isRemote &&
|
||||
Win64_IsActivePlayer(&m_player[dwUserIndex], dwUserIndex))
|
||||
return &m_player[dwUserIndex];
|
||||
return NULL;
|
||||
}
|
||||
@@ -246,7 +249,7 @@ IQNetPlayer* IQNet::GetLocalPlayerByUserIndex(DWORD dwUserIndex)
|
||||
return NULL;
|
||||
for (DWORD i = 0; i < s_playerCount; i++)
|
||||
{
|
||||
if (!m_player[i].m_isRemote)
|
||||
if (!m_player[i].m_isRemote && Win64_IsActivePlayer(&m_player[i], i))
|
||||
return &m_player[i];
|
||||
}
|
||||
return NULL;
|
||||
@@ -299,15 +302,28 @@ QNET_STATE IQNet::GetState() { return _iQNetStubState; }
|
||||
bool IQNet::IsHost() { return s_isHosting; }
|
||||
HRESULT IQNet::JoinGameFromInviteInfo(DWORD dwUserIndex, DWORD dwUserMask, const INVITE_INFO * pInviteInfo) { return S_OK; }
|
||||
void IQNet::HostGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = true; }
|
||||
void IQNet::ClientJoinGame() { _iQNetStubState = QNET_STATE_SESSION_STARTING; s_isHosting = false; }
|
||||
void IQNet::ClientJoinGame()
|
||||
{
|
||||
_iQNetStubState = QNET_STATE_SESSION_STARTING;
|
||||
s_isHosting = false;
|
||||
|
||||
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
|
||||
{
|
||||
m_player[i].m_smallId = (BYTE)i;
|
||||
m_player[i].m_isRemote = true;
|
||||
m_player[i].m_isHostPlayer = false;
|
||||
m_player[i].m_gamertag[0] = 0;
|
||||
m_player[i].SetCustomDataValue(0);
|
||||
}
|
||||
}
|
||||
void IQNet::EndGame()
|
||||
{
|
||||
_iQNetStubState = QNET_STATE_IDLE;
|
||||
s_isHosting = false;
|
||||
s_playerCount = 1;
|
||||
for (int i = 1; i < MINECRAFT_NET_MAX_PLAYERS; i++)
|
||||
for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; i++)
|
||||
{
|
||||
m_player[i].m_smallId = 0;
|
||||
m_player[i].m_smallId = (BYTE)i;
|
||||
m_player[i].m_isRemote = false;
|
||||
m_player[i].m_isHostPlayer = false;
|
||||
m_player[i].m_gamertag[0] = 0;
|
||||
@@ -587,7 +603,6 @@ void C_4JProfile::SetPrimaryPad(int iPad) {}
|
||||
#ifdef _DURANGO
|
||||
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; }
|
||||
|
||||
@@ -1964,8 +1964,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
|
||||
@@ -2557,13 +2557,19 @@ void LevelRenderer::cull(Culler *culler, float a)
|
||||
{
|
||||
unsigned char flags = pClipChunk->globalIdx == -1 ? 0 : globalChunkFlags[ pClipChunk->globalIdx ];
|
||||
|
||||
// Always perform frustum cull test
|
||||
bool clipres = clip(pClipChunk->aabb, fdraw);
|
||||
|
||||
if ( (flags & CHUNK_FLAG_COMPILED ) && ( ( flags & CHUNK_FLAG_EMPTYBOTH ) != CHUNK_FLAG_EMPTYBOTH ) )
|
||||
{
|
||||
bool clipres = clip(pClipChunk->aabb, fdraw);
|
||||
pClipChunk->visible = clipres;
|
||||
if( pClipChunk->visible ) vis++;
|
||||
total++;
|
||||
}
|
||||
else if (clipres)
|
||||
{
|
||||
pClipChunk->visible = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
pClipChunk->visible = false;
|
||||
@@ -2572,6 +2578,7 @@ void LevelRenderer::cull(Culler *culler, float a)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LevelRenderer::playStreamingMusic(const wstring& name, int x, int y, int z)
|
||||
{
|
||||
if (name != L"")
|
||||
|
||||
@@ -52,14 +52,16 @@ 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
|
||||
#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 +272,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];
|
||||
|
||||
@@ -1456,7 +1456,7 @@ void Minecraft::run_middle()
|
||||
if (KMInput.ConsumeKeyPress('C')) localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_CRAFTING;
|
||||
if (KMInput.ConsumeKeyPress(VK_F5)) localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_RENDER_THIRD_PERSON;
|
||||
// In flying mode, Shift held = sneak/descend
|
||||
if (localplayers[i]->abilities.flying && KMInput.IsKeyDown(VK_SHIFT))
|
||||
if (localplayers[i]->abilities.flying && KMInput.IsKeyDown(VK_SHIFT) && !ui.GetMenuDisplayed(i))
|
||||
localplayers[i]->ullButtonsPressed |= 1LL<<MINECRAFT_ACTION_SNEAK_TOGGLE;
|
||||
}
|
||||
#endif
|
||||
@@ -3618,8 +3618,6 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_RENDER_DEBUG)) )
|
||||
{
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
|
||||
options->renderDebug = !options->renderDebug;
|
||||
#ifdef _XBOX
|
||||
app.EnableDebugOverlay(options->renderDebug,iPad);
|
||||
#else
|
||||
@@ -3629,13 +3627,11 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
||||
#endif
|
||||
}
|
||||
|
||||
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_SPAWN_CREEPER)) && app.GetMobsDontAttackEnabled())
|
||||
{
|
||||
//shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(Creeper::_class->newInstance( level ));
|
||||
//shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(Wolf::_class->newInstance( level ));
|
||||
shared_ptr<Mob> mob = dynamic_pointer_cast<Mob>(shared_ptr<Spider>(new Spider( level )));
|
||||
mob->moveTo(player->x+1, player->y, player->z+1, level->random->nextFloat() * 360, 0);
|
||||
level->addEntity(mob);
|
||||
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_SPAWN_CREEPER)))
|
||||
{
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
options->renderDebug = !options->renderDebug;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -103,6 +103,7 @@ void KeyboardMouseInput::OnRawMouseInput(LPARAM lParam)
|
||||
|
||||
void KeyboardMouseInput::OnMouseButton(int button, bool down)
|
||||
{
|
||||
if (ui.IsPauseMenuDisplayed(ProfileManager.GetPrimaryPad())) { return; }
|
||||
if (button >= 0 && button < 3)
|
||||
{
|
||||
if (down && !m_mouseButtons[button]) m_mousePressedAccum[button] = true;
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
// Code implemented by LCEMP, credit if used on other repos
|
||||
// https://github.com/LCEMP/LCEMP
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
@@ -151,7 +154,7 @@ bool WinsockNetLayer::HostGame(int port)
|
||||
LeaveCriticalSection(&s_freeSmallIdLock);
|
||||
|
||||
struct addrinfo hints = {};
|
||||
struct addrinfo *result = NULL;
|
||||
struct addrinfo* result = NULL;
|
||||
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
@@ -177,7 +180,7 @@ bool WinsockNetLayer::HostGame(int port)
|
||||
}
|
||||
|
||||
int opt = 1;
|
||||
setsockopt(s_listenSocket, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof(opt));
|
||||
setsockopt(s_listenSocket, SOL_SOCKET, SO_REUSEADDR, (const char*)&opt, sizeof(opt));
|
||||
|
||||
iResult = ::bind(s_listenSocket, result->ai_addr, (int)result->ai_addrlen);
|
||||
freeaddrinfo(result);
|
||||
@@ -207,15 +210,23 @@ bool WinsockNetLayer::HostGame(int port)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinsockNetLayer::JoinGame(const char *ip, int port)
|
||||
bool WinsockNetLayer::JoinGame(const char* ip, int port)
|
||||
{
|
||||
if (!s_initialized && !Initialize()) return false;
|
||||
|
||||
s_isHost = false;
|
||||
s_hostSmallId = 0;
|
||||
s_connected = false;
|
||||
s_active = false;
|
||||
|
||||
if (s_hostConnectionSocket != INVALID_SOCKET)
|
||||
{
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
struct addrinfo hints = {};
|
||||
struct addrinfo *result = NULL;
|
||||
struct addrinfo* result = NULL;
|
||||
|
||||
hints.ai_family = AF_INET;
|
||||
hints.ai_socktype = SOCK_STREAM;
|
||||
@@ -231,37 +242,55 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port)
|
||||
return false;
|
||||
}
|
||||
|
||||
s_hostConnectionSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
|
||||
if (s_hostConnectionSocket == INVALID_SOCKET)
|
||||
bool connected = false;
|
||||
BYTE assignedSmallId = 0;
|
||||
const int maxAttempts = 12;
|
||||
|
||||
for (int attempt = 0; attempt < maxAttempts; ++attempt)
|
||||
{
|
||||
app.DebugPrintf("socket() failed: %d\n", WSAGetLastError());
|
||||
freeaddrinfo(result);
|
||||
return false;
|
||||
s_hostConnectionSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
|
||||
if (s_hostConnectionSocket == INVALID_SOCKET)
|
||||
{
|
||||
app.DebugPrintf("socket() failed: %d\n", WSAGetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
int noDelay = 1;
|
||||
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&noDelay, sizeof(noDelay));
|
||||
|
||||
iResult = connect(s_hostConnectionSocket, result->ai_addr, (int)result->ai_addrlen);
|
||||
if (iResult == SOCKET_ERROR)
|
||||
{
|
||||
int err = WSAGetLastError();
|
||||
app.DebugPrintf("connect() to %s:%d failed (attempt %d/%d): %d\n", ip, port, attempt + 1, maxAttempts, err);
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
Sleep(200);
|
||||
continue;
|
||||
}
|
||||
|
||||
BYTE assignBuf[1];
|
||||
int bytesRecv = recv(s_hostConnectionSocket, (char*)assignBuf, 1, 0);
|
||||
if (bytesRecv != 1)
|
||||
{
|
||||
app.DebugPrintf("Failed to receive small ID assignment from host (attempt %d/%d)\n", attempt + 1, maxAttempts);
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
Sleep(200);
|
||||
continue;
|
||||
}
|
||||
|
||||
assignedSmallId = assignBuf[0];
|
||||
connected = true;
|
||||
break;
|
||||
}
|
||||
|
||||
int noDelay = 1;
|
||||
setsockopt(s_hostConnectionSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
|
||||
|
||||
iResult = connect(s_hostConnectionSocket, result->ai_addr, (int)result->ai_addrlen);
|
||||
freeaddrinfo(result);
|
||||
if (iResult == SOCKET_ERROR)
|
||||
{
|
||||
app.DebugPrintf("connect() to %s:%d failed: %d\n", ip, port, WSAGetLastError());
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
|
||||
BYTE assignBuf[1];
|
||||
int bytesRecv = recv(s_hostConnectionSocket, (char *)assignBuf, 1, 0);
|
||||
if (bytesRecv != 1)
|
||||
if (!connected)
|
||||
{
|
||||
app.DebugPrintf("Failed to receive small ID assignment from host\n");
|
||||
closesocket(s_hostConnectionSocket);
|
||||
s_hostConnectionSocket = INVALID_SOCKET;
|
||||
return false;
|
||||
}
|
||||
s_localSmallId = assignBuf[0];
|
||||
s_localSmallId = assignedSmallId;
|
||||
|
||||
app.DebugPrintf("Win64 LAN: Connected to %s:%d, assigned smallId=%d\n", ip, port, s_localSmallId);
|
||||
|
||||
@@ -273,7 +302,7 @@ bool WinsockNetLayer::JoinGame(const char *ip, int port)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinsockNetLayer::SendOnSocket(SOCKET sock, const void *data, int dataSize)
|
||||
bool WinsockNetLayer::SendOnSocket(SOCKET sock, const void* data, int dataSize)
|
||||
{
|
||||
if (sock == INVALID_SOCKET || dataSize <= 0) return false;
|
||||
|
||||
@@ -289,7 +318,7 @@ bool WinsockNetLayer::SendOnSocket(SOCKET sock, const void *data, int dataSize)
|
||||
int toSend = 4;
|
||||
while (totalSent < toSend)
|
||||
{
|
||||
int sent = send(sock, (const char *)header + totalSent, toSend - totalSent, 0);
|
||||
int sent = send(sock, (const char*)header + totalSent, toSend - totalSent, 0);
|
||||
if (sent == SOCKET_ERROR || sent == 0)
|
||||
{
|
||||
LeaveCriticalSection(&s_sendLock);
|
||||
@@ -301,7 +330,7 @@ bool WinsockNetLayer::SendOnSocket(SOCKET sock, const void *data, int dataSize)
|
||||
totalSent = 0;
|
||||
while (totalSent < dataSize)
|
||||
{
|
||||
int sent = send(sock, (const char *)data + totalSent, dataSize - totalSent, 0);
|
||||
int sent = send(sock, (const char*)data + totalSent, dataSize - totalSent, 0);
|
||||
if (sent == SOCKET_ERROR || sent == 0)
|
||||
{
|
||||
LeaveCriticalSection(&s_sendLock);
|
||||
@@ -314,7 +343,7 @@ bool WinsockNetLayer::SendOnSocket(SOCKET sock, const void *data, int dataSize)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WinsockNetLayer::SendToSmallId(BYTE targetSmallId, const void *data, int dataSize)
|
||||
bool WinsockNetLayer::SendToSmallId(BYTE targetSmallId, const void* data, int dataSize)
|
||||
{
|
||||
if (!s_active) return false;
|
||||
|
||||
@@ -346,34 +375,34 @@ SOCKET WinsockNetLayer::GetSocketForSmallId(BYTE smallId)
|
||||
return INVALID_SOCKET;
|
||||
}
|
||||
|
||||
static bool RecvExact(SOCKET sock, BYTE *buf, int len)
|
||||
static bool RecvExact(SOCKET sock, BYTE* buf, int len)
|
||||
{
|
||||
int totalRecv = 0;
|
||||
while (totalRecv < len)
|
||||
{
|
||||
int r = recv(sock, (char *)buf + totalRecv, len - totalRecv, 0);
|
||||
int r = recv(sock, (char*)buf + totalRecv, len - totalRecv, 0);
|
||||
if (r <= 0) return false;
|
||||
totalRecv += r;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void WinsockNetLayer::HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsigned char *data, unsigned int dataSize)
|
||||
void WinsockNetLayer::HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsigned char* data, unsigned int dataSize)
|
||||
{
|
||||
INetworkPlayer *pPlayerFrom = g_NetworkManager.GetPlayerBySmallId(fromSmallId);
|
||||
INetworkPlayer *pPlayerTo = g_NetworkManager.GetPlayerBySmallId(toSmallId);
|
||||
INetworkPlayer* pPlayerFrom = g_NetworkManager.GetPlayerBySmallId(fromSmallId);
|
||||
INetworkPlayer* pPlayerTo = g_NetworkManager.GetPlayerBySmallId(toSmallId);
|
||||
|
||||
if (pPlayerFrom == NULL || pPlayerTo == NULL) return;
|
||||
|
||||
if (s_isHost)
|
||||
{
|
||||
::Socket *pSocket = pPlayerFrom->GetSocket();
|
||||
::Socket* pSocket = pPlayerFrom->GetSocket();
|
||||
if (pSocket != NULL)
|
||||
pSocket->pushDataToQueue(data, dataSize, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
::Socket *pSocket = pPlayerTo->GetSocket();
|
||||
::Socket* pSocket = pPlayerTo->GetSocket();
|
||||
if (pSocket != NULL)
|
||||
pSocket->pushDataToQueue(data, dataSize, true);
|
||||
}
|
||||
@@ -392,7 +421,7 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
|
||||
}
|
||||
|
||||
int noDelay = 1;
|
||||
setsockopt(clientSocket, IPPROTO_TCP, TCP_NODELAY, (const char *)&noDelay, sizeof(noDelay));
|
||||
setsockopt(clientSocket, IPPROTO_TCP, TCP_NODELAY, (const char*)&noDelay, sizeof(noDelay));
|
||||
|
||||
extern QNET_STATE _iQNetStubState;
|
||||
if (_iQNetStubState != QNET_STATE_GAME_PLAY)
|
||||
@@ -423,7 +452,7 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
|
||||
LeaveCriticalSection(&s_freeSmallIdLock);
|
||||
|
||||
BYTE assignBuf[1] = { assignedSmallId };
|
||||
int sent = send(clientSocket, (const char *)assignBuf, 1, 0);
|
||||
int sent = send(clientSocket, (const char*)assignBuf, 1, 0);
|
||||
if (sent != 1)
|
||||
{
|
||||
app.DebugPrintf("Failed to send small ID to client\n");
|
||||
@@ -444,15 +473,15 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
|
||||
|
||||
app.DebugPrintf("Win64 LAN: Client connected, assigned smallId=%d\n", assignedSmallId);
|
||||
|
||||
IQNetPlayer *qnetPlayer = &IQNet::m_player[assignedSmallId];
|
||||
IQNetPlayer* qnetPlayer = &IQNet::m_player[assignedSmallId];
|
||||
|
||||
extern void Win64_SetupRemoteQNetPlayer(IQNetPlayer *player, BYTE smallId, bool isHost, bool isLocal);
|
||||
extern void Win64_SetupRemoteQNetPlayer(IQNetPlayer * player, BYTE smallId, bool isHost, bool isLocal);
|
||||
Win64_SetupRemoteQNetPlayer(qnetPlayer, assignedSmallId, false, false);
|
||||
|
||||
extern CPlatformNetworkManagerStub *g_pPlatformNetworkManager;
|
||||
extern CPlatformNetworkManagerStub* g_pPlatformNetworkManager;
|
||||
g_pPlatformNetworkManager->NotifyPlayerJoined(qnetPlayer);
|
||||
|
||||
DWORD *threadParam = new DWORD;
|
||||
DWORD* threadParam = new DWORD;
|
||||
*threadParam = connIdx;
|
||||
HANDLE hThread = CreateThread(NULL, 0, RecvThreadProc, threadParam, 0, NULL);
|
||||
|
||||
@@ -466,8 +495,8 @@ DWORD WINAPI WinsockNetLayer::AcceptThreadProc(LPVOID param)
|
||||
|
||||
DWORD WINAPI WinsockNetLayer::RecvThreadProc(LPVOID param)
|
||||
{
|
||||
DWORD connIdx = *(DWORD *)param;
|
||||
delete (DWORD *)param;
|
||||
DWORD connIdx = *(DWORD*)param;
|
||||
delete (DWORD*)param;
|
||||
|
||||
EnterCriticalSection(&s_connectionsLock);
|
||||
if (connIdx >= (DWORD)s_connections.size())
|
||||
@@ -479,7 +508,8 @@ DWORD WINAPI WinsockNetLayer::RecvThreadProc(LPVOID param)
|
||||
BYTE clientSmallId = s_connections[connIdx].smallId;
|
||||
LeaveCriticalSection(&s_connectionsLock);
|
||||
|
||||
BYTE *recvBuf = new BYTE[WIN64_NET_RECV_BUFFER_SIZE];
|
||||
std::vector<BYTE> recvBuf;
|
||||
recvBuf.resize(WIN64_NET_RECV_BUFFER_SIZE);
|
||||
|
||||
while (s_active)
|
||||
{
|
||||
@@ -490,33 +520,47 @@ DWORD WINAPI WinsockNetLayer::RecvThreadProc(LPVOID param)
|
||||
break;
|
||||
}
|
||||
|
||||
int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
|
||||
int packetSize =
|
||||
((uint32_t)header[0] << 24) |
|
||||
((uint32_t)header[1] << 16) |
|
||||
((uint32_t)header[2] << 8) |
|
||||
((uint32_t)header[3]);
|
||||
|
||||
if (packetSize <= 0 || packetSize > WIN64_NET_RECV_BUFFER_SIZE)
|
||||
if (packetSize <= 0 || packetSize > WIN64_NET_MAX_PACKET_SIZE)
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Invalid packet size %d from client smallId=%d\n", packetSize, clientSmallId);
|
||||
app.DebugPrintf("Win64 LAN: Invalid packet size %d from client smallId=%d (max=%d)\n",
|
||||
packetSize,
|
||||
clientSmallId,
|
||||
(int)WIN64_NET_MAX_PACKET_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!RecvExact(sock, recvBuf, packetSize))
|
||||
if ((int)recvBuf.size() < packetSize)
|
||||
{
|
||||
recvBuf.resize(packetSize);
|
||||
app.DebugPrintf("Win64 LAN: Resized host recv buffer to %d bytes for client smallId=%d\n", packetSize, clientSmallId);
|
||||
}
|
||||
|
||||
if (!RecvExact(sock, &recvBuf[0], packetSize))
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Client smallId=%d disconnected (body)\n", clientSmallId);
|
||||
break;
|
||||
}
|
||||
|
||||
HandleDataReceived(clientSmallId, s_hostSmallId, recvBuf, packetSize);
|
||||
HandleDataReceived(clientSmallId, s_hostSmallId, &recvBuf[0], packetSize);
|
||||
}
|
||||
|
||||
delete[] recvBuf;
|
||||
|
||||
EnterCriticalSection(&s_connectionsLock);
|
||||
for (size_t i = 0; i < s_connections.size(); i++)
|
||||
{
|
||||
if (s_connections[i].smallId == clientSmallId)
|
||||
{
|
||||
s_connections[i].active = false;
|
||||
closesocket(s_connections[i].tcpSocket);
|
||||
s_connections[i].tcpSocket = INVALID_SOCKET;
|
||||
if (s_connections[i].tcpSocket != INVALID_SOCKET)
|
||||
{
|
||||
closesocket(s_connections[i].tcpSocket);
|
||||
s_connections[i].tcpSocket = INVALID_SOCKET;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -529,7 +573,7 @@ DWORD WINAPI WinsockNetLayer::RecvThreadProc(LPVOID param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool WinsockNetLayer::PopDisconnectedSmallId(BYTE *outSmallId)
|
||||
bool WinsockNetLayer::PopDisconnectedSmallId(BYTE* outSmallId)
|
||||
{
|
||||
bool found = false;
|
||||
EnterCriticalSection(&s_disconnectLock);
|
||||
@@ -550,9 +594,26 @@ void WinsockNetLayer::PushFreeSmallId(BYTE smallId)
|
||||
LeaveCriticalSection(&s_freeSmallIdLock);
|
||||
}
|
||||
|
||||
void WinsockNetLayer::CloseConnectionBySmallId(BYTE smallId)
|
||||
{
|
||||
EnterCriticalSection(&s_connectionsLock);
|
||||
for (size_t i = 0; i < s_connections.size(); i++)
|
||||
{
|
||||
if (s_connections[i].smallId == smallId && s_connections[i].active && s_connections[i].tcpSocket != INVALID_SOCKET)
|
||||
{
|
||||
closesocket(s_connections[i].tcpSocket);
|
||||
s_connections[i].tcpSocket = INVALID_SOCKET;
|
||||
app.DebugPrintf("Win64 LAN: Force-closed TCP connection for smallId=%d\n", smallId);
|
||||
break;
|
||||
}
|
||||
}
|
||||
LeaveCriticalSection(&s_connectionsLock);
|
||||
}
|
||||
|
||||
DWORD WINAPI WinsockNetLayer::ClientRecvThreadProc(LPVOID param)
|
||||
{
|
||||
BYTE *recvBuf = new BYTE[WIN64_NET_RECV_BUFFER_SIZE];
|
||||
std::vector<BYTE> recvBuf;
|
||||
recvBuf.resize(WIN64_NET_RECV_BUFFER_SIZE);
|
||||
|
||||
while (s_active && s_hostConnectionSocket != INVALID_SOCKET)
|
||||
{
|
||||
@@ -565,28 +626,34 @@ DWORD WINAPI WinsockNetLayer::ClientRecvThreadProc(LPVOID param)
|
||||
|
||||
int packetSize = (header[0] << 24) | (header[1] << 16) | (header[2] << 8) | header[3];
|
||||
|
||||
if (packetSize <= 0 || packetSize > WIN64_NET_RECV_BUFFER_SIZE)
|
||||
if (packetSize <= 0 || packetSize > WIN64_NET_MAX_PACKET_SIZE)
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Invalid packet size %d from host\n", packetSize);
|
||||
app.DebugPrintf("Win64 LAN: Invalid packet size %d from host (max=%d)\n",
|
||||
packetSize,
|
||||
(int)WIN64_NET_MAX_PACKET_SIZE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!RecvExact(s_hostConnectionSocket, recvBuf, packetSize))
|
||||
if ((int)recvBuf.size() < packetSize)
|
||||
{
|
||||
recvBuf.resize(packetSize);
|
||||
app.DebugPrintf("Win64 LAN: Resized client recv buffer to %d bytes\n", packetSize);
|
||||
}
|
||||
|
||||
if (!RecvExact(s_hostConnectionSocket, &recvBuf[0], packetSize))
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Disconnected from host (body)\n");
|
||||
break;
|
||||
}
|
||||
|
||||
HandleDataReceived(s_hostSmallId, s_localSmallId, recvBuf, packetSize);
|
||||
HandleDataReceived(s_hostSmallId, s_localSmallId, &recvBuf[0], packetSize);
|
||||
}
|
||||
|
||||
delete[] recvBuf;
|
||||
|
||||
s_connected = false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool WinsockNetLayer::StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer)
|
||||
bool WinsockNetLayer::StartAdvertising(int gamePort, const wchar_t* hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer)
|
||||
{
|
||||
if (s_advertising) return true;
|
||||
if (!s_initialized) return false;
|
||||
@@ -614,7 +681,7 @@ bool WinsockNetLayer::StartAdvertising(int gamePort, const wchar_t *hostName, un
|
||||
}
|
||||
|
||||
BOOL broadcast = TRUE;
|
||||
setsockopt(s_advertiseSock, SOL_SOCKET, SO_BROADCAST, (const char *)&broadcast, sizeof(broadcast));
|
||||
setsockopt(s_advertiseSock, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcast, sizeof(broadcast));
|
||||
|
||||
s_advertising = true;
|
||||
s_advertiseThread = CreateThread(NULL, 0, AdvertiseThreadProc, NULL, 0, NULL);
|
||||
@@ -669,8 +736,8 @@ DWORD WINAPI WinsockNetLayer::AdvertiseThreadProc(LPVOID param)
|
||||
Win64LANBroadcast data = s_advertiseData;
|
||||
LeaveCriticalSection(&s_advertiseLock);
|
||||
|
||||
int sent = sendto(s_advertiseSock, (const char *)&data, sizeof(data), 0,
|
||||
(struct sockaddr *)&broadcastAddr, sizeof(broadcastAddr));
|
||||
int sent = sendto(s_advertiseSock, (const char*)&data, sizeof(data), 0,
|
||||
(struct sockaddr*)&broadcastAddr, sizeof(broadcastAddr));
|
||||
|
||||
if (sent == SOCKET_ERROR && s_advertising)
|
||||
{
|
||||
@@ -696,7 +763,7 @@ bool WinsockNetLayer::StartDiscovery()
|
||||
}
|
||||
|
||||
BOOL reuseAddr = TRUE;
|
||||
setsockopt(s_discoverySock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuseAddr, sizeof(reuseAddr));
|
||||
setsockopt(s_discoverySock, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuseAddr, sizeof(reuseAddr));
|
||||
|
||||
struct sockaddr_in bindAddr;
|
||||
memset(&bindAddr, 0, sizeof(bindAddr));
|
||||
@@ -704,7 +771,7 @@ bool WinsockNetLayer::StartDiscovery()
|
||||
bindAddr.sin_port = htons(WIN64_LAN_DISCOVERY_PORT);
|
||||
bindAddr.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if (::bind(s_discoverySock, (struct sockaddr *)&bindAddr, sizeof(bindAddr)) == SOCKET_ERROR)
|
||||
if (::bind(s_discoverySock, (struct sockaddr*)&bindAddr, sizeof(bindAddr)) == SOCKET_ERROR)
|
||||
{
|
||||
app.DebugPrintf("Win64 LAN: Discovery bind failed: %d\n", WSAGetLastError());
|
||||
closesocket(s_discoverySock);
|
||||
@@ -713,7 +780,7 @@ bool WinsockNetLayer::StartDiscovery()
|
||||
}
|
||||
|
||||
DWORD timeout = 500;
|
||||
setsockopt(s_discoverySock, SOL_SOCKET, SO_RCVTIMEO, (const char *)&timeout, sizeof(timeout));
|
||||
setsockopt(s_discoverySock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout));
|
||||
|
||||
s_discovering = true;
|
||||
s_discoveryThread = CreateThread(NULL, 0, DiscoveryThreadProc, NULL, 0, NULL);
|
||||
@@ -763,7 +830,7 @@ DWORD WINAPI WinsockNetLayer::DiscoveryThreadProc(LPVOID param)
|
||||
int senderLen = sizeof(senderAddr);
|
||||
|
||||
int recvLen = recvfrom(s_discoverySock, recvBuf, sizeof(recvBuf), 0,
|
||||
(struct sockaddr *)&senderAddr, &senderLen);
|
||||
(struct sockaddr*)&senderAddr, &senderLen);
|
||||
|
||||
if (recvLen == SOCKET_ERROR)
|
||||
{
|
||||
@@ -773,7 +840,7 @@ DWORD WINAPI WinsockNetLayer::DiscoveryThreadProc(LPVOID param)
|
||||
if (recvLen < (int)sizeof(Win64LANBroadcast))
|
||||
continue;
|
||||
|
||||
Win64LANBroadcast *broadcast = (Win64LANBroadcast *)recvBuf;
|
||||
Win64LANBroadcast* broadcast = (Win64LANBroadcast*)recvBuf;
|
||||
if (broadcast->magic != WIN64_LAN_BROADCAST_MAGIC)
|
||||
continue;
|
||||
|
||||
@@ -841,4 +908,4 @@ DWORD WINAPI WinsockNetLayer::DiscoveryThreadProc(LPVOID param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,3 +1,5 @@
|
||||
// Code implemented by LCEMP, credit if used on other repos
|
||||
// https://github.com/LCEMP/LCEMP
|
||||
#pragma once
|
||||
|
||||
#ifdef _WINDOWS64
|
||||
@@ -12,6 +14,7 @@
|
||||
#define WIN64_NET_DEFAULT_PORT 25565
|
||||
#define WIN64_NET_MAX_CLIENTS 7
|
||||
#define WIN64_NET_RECV_BUFFER_SIZE 65536
|
||||
#define WIN64_NET_MAX_PACKET_SIZE (4 * 1024 * 1024)
|
||||
#define WIN64_LAN_DISCOVERY_PORT 25566
|
||||
#define WIN64_LAN_BROADCAST_MAGIC 0x4D434C4E
|
||||
|
||||
@@ -63,10 +66,10 @@ public:
|
||||
static void Shutdown();
|
||||
|
||||
static bool HostGame(int port);
|
||||
static bool JoinGame(const char *ip, int port);
|
||||
static bool JoinGame(const char* ip, int port);
|
||||
|
||||
static bool SendToSmallId(BYTE targetSmallId, const void *data, int dataSize);
|
||||
static bool SendOnSocket(SOCKET sock, const void *data, int dataSize);
|
||||
static bool SendToSmallId(BYTE targetSmallId, const void* data, int dataSize);
|
||||
static bool SendOnSocket(SOCKET sock, const void* data, int dataSize);
|
||||
|
||||
static bool IsHosting() { return s_isHost; }
|
||||
static bool IsConnected() { return s_connected; }
|
||||
@@ -77,12 +80,13 @@ public:
|
||||
|
||||
static SOCKET GetSocketForSmallId(BYTE smallId);
|
||||
|
||||
static void HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsigned char *data, unsigned int dataSize);
|
||||
static void HandleDataReceived(BYTE fromSmallId, BYTE toSmallId, unsigned char* data, unsigned int dataSize);
|
||||
|
||||
static bool PopDisconnectedSmallId(BYTE *outSmallId);
|
||||
static bool PopDisconnectedSmallId(BYTE* outSmallId);
|
||||
static void PushFreeSmallId(BYTE smallId);
|
||||
static void CloseConnectionBySmallId(BYTE smallId);
|
||||
|
||||
static bool StartAdvertising(int gamePort, const wchar_t *hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer);
|
||||
static bool StartAdvertising(int gamePort, const wchar_t* hostName, unsigned int gameSettings, unsigned int texPackId, unsigned char subTexId, unsigned short netVer);
|
||||
static void StopAdvertising();
|
||||
static void UpdateAdvertisePlayerCount(BYTE count);
|
||||
static void UpdateAdvertiseJoinable(bool joinable);
|
||||
|
||||
@@ -10,46 +10,11 @@
|
||||
#include "..\..\Minecraft.World\BiomeSource.h"
|
||||
#include "..\..\Minecraft.World\LevelType.h"
|
||||
|
||||
wstring g_playerName;
|
||||
|
||||
CConsoleMinecraftApp app;
|
||||
|
||||
static void LoadPlayerName()
|
||||
{
|
||||
if (!g_playerName.empty()) return;
|
||||
g_playerName = L"Windows";
|
||||
|
||||
char exePath[MAX_PATH] = {};
|
||||
GetModuleFileNameA(NULL, exePath, MAX_PATH);
|
||||
char *lastSlash = strrchr(exePath, '\\');
|
||||
if (lastSlash) *(lastSlash + 1) = '\0';
|
||||
char filePath[MAX_PATH] = {};
|
||||
_snprintf_s(filePath, sizeof(filePath), _TRUNCATE, "%susername.txt", exePath);
|
||||
|
||||
FILE *f = NULL;
|
||||
if (fopen_s(&f, filePath, "r") == 0 && f)
|
||||
{
|
||||
char buf[128] = {};
|
||||
if (fgets(buf, sizeof(buf), f))
|
||||
{
|
||||
int len = (int)strlen(buf);
|
||||
while (len > 0 && (buf[len-1] == '\n' || buf[len-1] == '\r' || buf[len-1] == ' '))
|
||||
buf[--len] = '\0';
|
||||
if (len > 0)
|
||||
{
|
||||
wchar_t wbuf[128] = {};
|
||||
mbstowcs(wbuf, buf, 127);
|
||||
g_playerName = wbuf;
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
CConsoleMinecraftApp::CConsoleMinecraftApp() : CMinecraftApp()
|
||||
{
|
||||
m_bShutdown = false;
|
||||
LoadPlayerName();
|
||||
}
|
||||
|
||||
void CConsoleMinecraftApp::SetRichPresenceContext(int iPad, int contextId)
|
||||
@@ -110,8 +75,8 @@ void CConsoleMinecraftApp::TemporaryCreateGameStart()
|
||||
Minecraft *pMinecraft=Minecraft::GetInstance();
|
||||
app.ReleaseSaveThumbnail();
|
||||
ProfileManager.SetLockedProfile(0);
|
||||
LoadPlayerName();
|
||||
pMinecraft->user->name = g_playerName;
|
||||
extern wchar_t g_Win64UsernameW[17];
|
||||
pMinecraft->user->name = g_Win64UsernameW;
|
||||
app.ApplyGameSettingsChanged(0);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////// From CScene_MultiGameJoinLoad::OnInit
|
||||
|
||||
@@ -85,11 +85,12 @@ 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;
|
||||
|
||||
char g_Win64Username[17] = { 0 };
|
||||
wchar_t g_Win64UsernameW[17] = { 0 };
|
||||
|
||||
// Fullscreen toggle state
|
||||
static bool g_isFullscreen = false;
|
||||
static WINDOWPLACEMENT g_wpPrev = { sizeof(g_wpPrev) };
|
||||
@@ -765,36 +766,41 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
//g_iScreenHeight = 544;
|
||||
}
|
||||
|
||||
char cmdLineA[1024];
|
||||
strncpy_s(cmdLineA, sizeof(cmdLineA), lpCmdLine, _TRUNCATE);
|
||||
// Default username will be "Windows"
|
||||
strncpy_s(g_Win64Username, sizeof(g_Win64Username), "Windows", _TRUNCATE);
|
||||
|
||||
char* nameArg = strstr(cmdLineA, "-name ");
|
||||
if (nameArg)
|
||||
char exePath[MAX_PATH] = {};
|
||||
GetModuleFileNameA(NULL, exePath, MAX_PATH);
|
||||
char* lastSlash = strrchr(exePath, '\\');
|
||||
if (lastSlash) *(lastSlash + 1) = '\0';
|
||||
|
||||
char filePath[MAX_PATH] = {};
|
||||
_snprintf_s(filePath, sizeof(filePath), _TRUNCATE, "%susername.txt", exePath);
|
||||
|
||||
FILE* f = nullptr;
|
||||
if (fopen_s(&f, filePath, "r") == 0 && f)
|
||||
{
|
||||
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);
|
||||
char buf[128] = {};
|
||||
if (fgets(buf, sizeof(buf), f))
|
||||
{
|
||||
int len = (int)strlen(buf);
|
||||
while (len > 0 && (buf[len - 1] == '\n' || buf[len - 1] == '\r' || buf[len - 1] == ' '))
|
||||
buf[--len] = '\0';
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
strncpy_s(g_Win64Username, sizeof(g_Win64Username), buf, _TRUNCATE);
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (!GetUserNameA(g_Win64Username, &sz))
|
||||
strncpy_s(g_Win64Username, 17, "Player", _TRUNCATE);
|
||||
g_Win64Username[16] = 0;
|
||||
}
|
||||
|
||||
@@ -1272,7 +1278,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
}
|
||||
}
|
||||
|
||||
// F1 toggles the HUD, F3 toggles the debug console overlay, F11 toggles fullscreen
|
||||
// F1 toggles the HUD
|
||||
if (KMInput.IsKeyPressed(VK_F1))
|
||||
{
|
||||
int primaryPad = ProfileManager.GetPrimaryPad();
|
||||
@@ -1280,21 +1286,43 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
app.SetGameSettings(primaryPad, eGameSetting_DisplayHUD, displayHud ? 0 : 1);
|
||||
app.SetGameSettings(primaryPad, eGameSetting_DisplayHand, displayHud ? 0 : 1);
|
||||
}
|
||||
|
||||
|
||||
// F3 toggles onscreen debug info
|
||||
if (KMInput.IsKeyPressed(VK_F3))
|
||||
{
|
||||
static bool s_debugConsole = false;
|
||||
s_debugConsole = !s_debugConsole;
|
||||
ui.ShowUIDebugConsole(s_debugConsole);
|
||||
if (Minecraft* pMinecraft = Minecraft::GetInstance())
|
||||
{
|
||||
if (pMinecraft->options)
|
||||
{
|
||||
pMinecraft->options->renderDebug = !pMinecraft->options->renderDebug;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_MENUS_ENABLED
|
||||
if (KMInput.IsKeyPressed(VK_F4))
|
||||
{
|
||||
ui.NavigateToScene(ProfileManager.GetPrimaryPad(), eUIScene_DebugOverlay, NULL, eUILayer_Debug);
|
||||
}
|
||||
// F4 Open debug overlay
|
||||
if (KMInput.IsKeyPressed(VK_F4))
|
||||
{
|
||||
if (Minecraft *pMinecraft = Minecraft::GetInstance())
|
||||
{
|
||||
if (pMinecraft->options &&
|
||||
app.GetGameStarted() && !ui.GetMenuDisplayed(0) && pMinecraft->screen == NULL)
|
||||
{
|
||||
ui.NavigateToScene(0, eUIScene_DebugOverlay, NULL, eUILayer_Debug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// F6 Open debug console
|
||||
if (KMInput.IsKeyPressed(VK_F6))
|
||||
{
|
||||
static bool s_debugConsole = false;
|
||||
s_debugConsole = !s_debugConsole;
|
||||
ui.ShowUIDebugConsole(s_debugConsole);
|
||||
}
|
||||
#endif
|
||||
|
||||
// F11 Toggle fullscreen
|
||||
if (KMInput.IsKeyPressed(VK_F11))
|
||||
{
|
||||
ToggleFullscreen();
|
||||
@@ -1312,33 +1340,6 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef _DEBUG_MENUS_ENABLED
|
||||
// F3 toggles onscreen debug info
|
||||
if (KMInput.IsKeyPressed(VK_F3))
|
||||
{
|
||||
if (Minecraft* pMinecraft = Minecraft::GetInstance())
|
||||
{
|
||||
if (pMinecraft->options && app.DebugSettingsOn())
|
||||
{
|
||||
pMinecraft->options->renderDebug = !pMinecraft->options->renderDebug;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// F4 opens debug overlay
|
||||
if (KMInput.IsKeyPressed(VK_F4))
|
||||
{
|
||||
if (Minecraft* pMinecraft = Minecraft::GetInstance())
|
||||
{
|
||||
if (pMinecraft->options && app.DebugSettingsOn() &&
|
||||
app.GetGameStarted() && !ui.GetMenuDisplayed(0) && pMinecraft->screen == NULL)
|
||||
{
|
||||
ui.NavigateToScene(0, eUIScene_DebugOverlay, NULL, eUILayer_Debug);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
// has the game defined profile data been changed (by a profile load)
|
||||
if(app.uiGameDefinedDataChangedBitmask!=0)
|
||||
|
||||
@@ -627,6 +627,7 @@ void Player::ride(shared_ptr<Entity> e)
|
||||
|
||||
return;
|
||||
}
|
||||
this->abilities.flying = false;
|
||||
LivingEntity::ride(e);
|
||||
}
|
||||
|
||||
|
||||
11
README.md
11
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/)
|
||||
|
||||
@@ -51,7 +45,7 @@ This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/)
|
||||
- **Sprint**: `Ctrl` (Hold) or Double-tap `W`
|
||||
- **Inventory**: `E`
|
||||
- **Drop Item**: `Q`
|
||||
- **Crafting**: `C`
|
||||
- **Crafting**: `C` Use `Q` and `E` to move through tabs (cycles Left/Right)
|
||||
- **Toggle View (FPS/TPS)**: `F5`
|
||||
- **Fullscreen**: `F11`
|
||||
- **Pause Menu**: `Esc`
|
||||
@@ -64,6 +58,7 @@ This feature is based on [LCEMP](https://github.com/LCEMP/LCEMP/)
|
||||
- **Toggle HUD**: `F1`
|
||||
- **Toggle Debug Info**: `F3`
|
||||
- **Open Debug Overlay**: `F4`
|
||||
- **Toggle Debug Console**: `F6`
|
||||
|
||||
## Build & Run
|
||||
|
||||
|
||||
Reference in New Issue
Block a user