add lcemp networking + ps3 support

YES I KNOW ITS GARBAGE, THATS WHY ITS NOT ON MAIN

ILL FIX IT UP IN FUTURE COMMITS THEN MERGE TO MAIN
This commit is contained in:
2026-07-31 22:08:30 +03:00
parent 51ee0d8e57
commit dbd90a75c9
50 changed files with 1958 additions and 96 deletions
@@ -3,6 +3,11 @@
#include "..\..\..\Minecraft.World\StringHelpers.h"
#include "PlatformNetworkManagerStub.h"
#include "..\..\Xbox\Network\NetworkPlayerXbox.h" // TODO - stub version of this?
#include "..\..\Minecraft.h"
#include "..\..\User.h"
#if defined _WINDOWS64 || defined __PS3__
#include "..\..\Common\Network\WinsockNetLayer.h"
#endif
CPlatformNetworkManagerStub *g_pPlatformNetworkManager;
@@ -114,10 +119,42 @@ void CPlatformNetworkManagerStub::NotifyPlayerJoined(IQNetPlayer *pQNetPlayer )
}
}
void CPlatformNetworkManagerStub::NotifyPlayerLeaving(IQNetPlayer *pQNetPlayer)
{
app.DebugPrintf("Player 0x%p \"%ls\" leaving.\n", pQNetPlayer, pQNetPlayer->GetGamertag());
INetworkPlayer *networkPlayer = getNetworkPlayer(pQNetPlayer);
if (networkPlayer == NULL)
return;
Socket *socket = networkPlayer->GetSocket();
if (socket != NULL)
{
if (m_pIQNet->IsHost())
g_NetworkManager.CloseConnection(networkPlayer);
}
if (m_pIQNet->IsHost())
{
SystemFlagRemovePlayer(networkPlayer);
}
g_NetworkManager.PlayerLeaving(networkPlayer);
for (int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
{
if (playerChangedCallback[idx] != NULL)
playerChangedCallback[idx](playerChangedCallbackParam[idx], networkPlayer, true);
}
removeNetworkPlayer(pQNetPlayer);
}
bool CPlatformNetworkManagerStub::Initialise(CGameNetworkManager *pGameNetworkManager, int flagIndexSize)
{
m_pGameNetworkManager = pGameNetworkManager;
m_flagIndexSize = flagIndexSize;
m_pIQNet = new IQNet();
g_pPlatformNetworkManager = this;
for( int i = 0; i < XUSER_MAX_COUNT; i++ )
{
@@ -174,6 +211,35 @@ bool CPlatformNetworkManagerStub::isSystemPrimaryPlayer(IQNetPlayer *pQNetPlayer
// We call this twice a frame, either side of the render call so is a good place to "tick" things
void CPlatformNetworkManagerStub::DoWork()
{
extern QNET_STATE _iQNetStubState;
if (_iQNetStubState == QNET_STATE_SESSION_STARTING && app.GetGameStarted())
{
_iQNetStubState = QNET_STATE_GAME_PLAY;
if (m_pIQNet->IsHost())
WinsockNetLayer::UpdateAdvertiseJoinable(true);
}
if (_iQNetStubState == QNET_STATE_IDLE)
TickSearch();
if (_iQNetStubState == QNET_STATE_GAME_PLAY && m_pIQNet->IsHost())
{
BYTE disconnectedSmallId;
while (WinsockNetLayer::PopDisconnectedSmallId(&disconnectedSmallId))
{
IQNetPlayer *qnetPlayer = m_pIQNet->GetPlayerBySmallId(disconnectedSmallId);
if (qnetPlayer != NULL && qnetPlayer->m_smallId == disconnectedSmallId)
{
NotifyPlayerLeaving(qnetPlayer);
qnetPlayer->m_smallId = 0;
qnetPlayer->m_isRemote = false;
qnetPlayer->m_isHostPlayer = false;
qnetPlayer->m_gamertag[0] = 0;
qnetPlayer->SetCustomDataValue(0);
WinsockNetLayer::PushFreeSmallId(disconnectedSmallId);
if (IQNet::s_playerCount > 1)
IQNet::s_playerCount--;
}
}
}
}
int CPlatformNetworkManagerStub::GetPlayerCount()
@@ -231,6 +297,7 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost)
if( m_bLeavingGame ) return true;
m_bLeavingGame = true;
WinsockNetLayer::StopAdvertising();
// If we are the host wait for the game server to end
if(m_pIQNet->IsHost() && g_NetworkManager.ServerStoppedValid())
@@ -239,6 +306,20 @@ bool CPlatformNetworkManagerStub::LeaveGame(bool bMigrateHost)
g_NetworkManager.ServerStoppedWait();
g_NetworkManager.ServerStoppedDestroy();
}
else
{
m_pIQNet->EndGame();
}
for (AUTO_VAR(it, currentNetworkPlayers.begin()); it != currentNetworkPlayers.end(); it++)
delete *it;
currentNetworkPlayers.clear();
m_machineQNetPrimaryPlayers.clear();
SystemFlagReset();
WinsockNetLayer::Shutdown();
WinsockNetLayer::Initialize();
return true;
}
@@ -262,7 +343,20 @@ void CPlatformNetworkManagerStub::HostGame(int localUsersMask, bool bOnlineGame,
m_pIQNet->HostGame();
IQNet::m_player[0].m_smallId = 0;
IQNet::m_player[0].m_isRemote = false;
IQNet::m_player[0].m_isHostPlayer = true;
IQNet::s_playerCount = 1;
_HostGame( localUsersMask, publicSlots, privateSlots );
int port = WIN64_NET_DEFAULT_PORT;
if (!WinsockNetLayer::IsActive())
WinsockNetLayer::HostGame(port);
const wchar_t *hostName = IQNet::m_player[0].m_gamertag;
unsigned int settings = app.GetGameHostOption(eGameHostOption_All);
WinsockNetLayer::StartAdvertising(port, hostName, settings, 0, 0, MINECRAFT_NET_VERSION);
//#endif
}
@@ -277,6 +371,47 @@ bool CPlatformNetworkManagerStub::_StartGame()
int CPlatformNetworkManagerStub::JoinGame(FriendSessionInfo *searchResult, int localUsersMask, int primaryUserIndex)
{
if (searchResult == NULL)
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
const char *hostIP = searchResult->data.hostIP;
int hostPort = searchResult->data.hostPort;
if (hostPort <= 0 || hostIP[0] == 0)
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
m_bLeavingGame = false;
IQNet::s_isHosting = false;
m_pIQNet->ClientJoinGame();
IQNet::m_player[0].m_smallId = 0;
IQNet::m_player[0].m_isRemote = true;
IQNet::m_player[0].m_isHostPlayer = true;
wcsncpy(IQNet::m_player[0].m_gamertag, searchResult->data.hostName, 31);
WinsockNetLayer::StopDiscovery();
if (!WinsockNetLayer::JoinGame(hostIP, hostPort))
{
app.DebugPrintf("Win64 LAN: Failed to connect to %s:%d\n", hostIP, hostPort);
return CGameNetworkManager::JOINGAME_FAIL_GENERAL;
}
BYTE localSmallId = WinsockNetLayer::GetLocalSmallId();
IQNet::m_player[localSmallId].m_smallId = localSmallId;
IQNet::m_player[localSmallId].m_isRemote = false;
IQNet::m_player[localSmallId].m_isHostPlayer = false;
Minecraft *pMinecraft = Minecraft::GetInstance();
wcsncpy(IQNet::m_player[localSmallId].m_gamertag, pMinecraft->user->name.c_str(), 32);
IQNet::s_playerCount = localSmallId + 1;
NotifyPlayerJoined(&IQNet::m_player[0]);
NotifyPlayerJoined(&IQNet::m_player[localSmallId]);
m_pGameNetworkManager->StateChange_AnyToStarting();
return CGameNetworkManager::JOINGAME_SUCCESS;
}
@@ -315,6 +450,21 @@ void CPlatformNetworkManagerStub::HandleSignInChange()
bool CPlatformNetworkManagerStub::_RunNetworkGame()
{
extern QNET_STATE _iQNetStubState;
_iQNetStubState = QNET_STATE_GAME_PLAY;
for (DWORD i = 0; i < IQNet::s_playerCount; i++)
{
if (IQNet::m_player[i].m_isRemote)
{
INetworkPlayer *pNetworkPlayer = getNetworkPlayer(&IQNet::m_player[i]);
if (pNetworkPlayer != NULL && pNetworkPlayer->GetSocket() != NULL)
{
Socket::addIncomingSocket(pNetworkPlayer->GetSocket());
}
}
}
return true;
}
@@ -503,10 +653,90 @@ wstring CPlatformNetworkManagerStub::GatherRTTStats()
void CPlatformNetworkManagerStub::TickSearch()
{
if (m_SessionsUpdatedCallback == NULL)
return;
static DWORD lastSearchTime = 0;
DWORD now = GetTickCount();
if (now - lastSearchTime < 2000)
return;
lastSearchTime = now;
SearchForGames();
}
void CPlatformNetworkManagerStub::SearchForGames()
{
std::vector<Win64LANSession> lanSessions = WinsockNetLayer::GetDiscoveredSessions();
if (g_Win64MultiplayerJoin)
{
bool alreadyPresent = false;
for (size_t i = 0; i < lanSessions.size(); i++)
{
if (strcmp(lanSessions[i].hostIP, g_Win64MultiplayerIP) == 0 &&
lanSessions[i].hostPort == g_Win64MultiplayerPort)
{
alreadyPresent = true;
break;
}
}
if (!alreadyPresent)
{
Win64LANSession manual;
memset(&manual, 0, sizeof(manual));
strncpy(manual.hostIP, g_Win64MultiplayerIP, sizeof(manual.hostIP) - 1);
manual.hostIP[sizeof(manual.hostIP) - 1] = '\0';
manual.hostPort = g_Win64MultiplayerPort;
swprintf(manual.hostName, 32, L"%hs:%d", g_Win64MultiplayerIP, g_Win64MultiplayerPort);
manual.hostName[31] = L'\0';
manual.playerCount = 0;
manual.maxPlayers = MINECRAFT_NET_MAX_PLAYERS;
manual.isJoinable = true;
manual.lastSeenTick = GetTickCount();
lanSessions.push_back(manual);
}
}
for (size_t i = 0; i < friendsSessions[0].size(); i++)
delete friendsSessions[0][i];
friendsSessions[0].clear();
for (size_t i = 0; i < lanSessions.size(); i++)
{
FriendSessionInfo *info = new FriendSessionInfo();
size_t nameLen = wcslen(lanSessions[i].hostName);
info->displayLabel = new wchar_t[nameLen + 1];
wcsncpy(info->displayLabel, lanSessions[i].hostName, nameLen);
info->displayLabel[nameLen] = L'\0';
info->displayLabelLength = (unsigned char)nameLen;
info->displayLabelViewableStartIndex = 0;
info->data.netVersion = lanSessions[i].netVersion;
info->data.m_uiGameHostSettings = lanSessions[i].gameHostSettings;
info->data.texturePackParentId = lanSessions[i].texturePackParentId;
info->data.subTexturePackId = lanSessions[i].subTexturePackId;
info->data.isReadyToJoin = lanSessions[i].isJoinable;
info->data.isJoinable = lanSessions[i].isJoinable;
strncpy(info->data.hostIP, lanSessions[i].hostIP, sizeof(info->data.hostIP) - 1);
info->data.hostIP[sizeof(info->data.hostIP) - 1] = '\0';
info->data.hostPort = lanSessions[i].hostPort;
wcsncpy(info->data.hostName, lanSessions[i].hostName, XUSER_NAME_SIZE - 1);
info->data.hostName[XUSER_NAME_SIZE - 1] = L'\0';
info->data.playerCount = lanSessions[i].playerCount;
info->data.maxPlayers = lanSessions[i].maxPlayers;
info->sessionId = (ULONGLONG)((unsigned __int64)inet_addr(lanSessions[i].hostIP) | ((unsigned __int64)lanSessions[i].hostPort << 32));
friendsSessions[0].push_back(info);
}
m_searchResultsCount[0] = (int)friendsSessions[0].size();
if (m_SessionsUpdatedCallback != NULL)
m_SessionsUpdatedCallback(m_pSearchParam);
}
int CPlatformNetworkManagerStub::SearchForGamesThreadProc( void* lpParameter )
@@ -522,7 +752,9 @@ void CPlatformNetworkManagerStub::SetSearchResultsReady(int resultCount)
vector<FriendSessionInfo *> *CPlatformNetworkManagerStub::GetSessionList(int iPad, int localPlayers, bool partyOnly)
{
vector<FriendSessionInfo *> *filteredList = new vector<FriendSessionInfo *>();;
vector<FriendSessionInfo *> *filteredList = new vector<FriendSessionInfo *>();
for (size_t i = 0; i < friendsSessions[0].size(); i++)
filteredList->push_back(friendsSessions[0][i]);
return filteredList;
}