mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-08-20 09:57:09 +00:00
Ghost/shadow player fix
When player 2 joined, player 1's connection received an AddPlayerPacket and created a RemotePlayer shadow in the world. The existing XUID deduplication check never fired on Windows64 (XUIDs are always INVALID_XUID). Added a Windows64-specific check that matches by IQNet-derived XUID (0xe000d45248242f2e + smallId), which is set up before the connection loop, making it race-free.
This commit is contained in:
parent
e513d6b8c5
commit
a2a0837fbd
|
|
@ -168,9 +168,9 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||||
PlayerUID OnlineXuid;
|
PlayerUID OnlineXuid;
|
||||||
ProfileManager.GetXUID(m_userIndex,&OnlineXuid,true); // online xuid
|
ProfileManager.GetXUID(m_userIndex,&OnlineXuid,true); // online xuid
|
||||||
MOJANG_DATA *pMojangData = NULL;
|
MOJANG_DATA *pMojangData = NULL;
|
||||||
|
|
||||||
if(!g_NetworkManager.IsLocalGame())
|
if(!g_NetworkManager.IsLocalGame())
|
||||||
{
|
{
|
||||||
pMojangData=app.GetMojangDataForXuid(OnlineXuid);
|
pMojangData=app.GetMojangDataForXuid(OnlineXuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -222,7 +222,7 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||||
// check the file is not already in
|
// check the file is not already in
|
||||||
bRes=app.IsFileInMemoryTextures(wstr);
|
bRes=app.IsFileInMemoryTextures(wstr);
|
||||||
if(!bRes)
|
if(!bRes)
|
||||||
{
|
{
|
||||||
#ifdef _XBOX
|
#ifdef _XBOX
|
||||||
C4JStorage::ETMSStatus eTMSStatus;
|
C4JStorage::ETMSStatus eTMSStatus;
|
||||||
eTMSStatus=StorageManager.ReadTMSFile(iUserID,C4JStorage::eGlobalStorage_Title,C4JStorage::eTMS_FileType_Graphic,pMojangData->wchSkin,&pBuffer, &dwSize);
|
eTMSStatus=StorageManager.ReadTMSFile(iUserID,C4JStorage::eGlobalStorage_Title,C4JStorage::eTMS_FileType_Graphic,pMojangData->wchSkin,&pBuffer, &dwSize);
|
||||||
|
|
@ -234,17 +234,17 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||||
if(bRes)
|
if(bRes)
|
||||||
{
|
{
|
||||||
app.AddMemoryTextureFile(wstr,pBuffer,dwSize);
|
app.AddMemoryTextureFile(wstr,pBuffer,dwSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// a cloak?
|
// a cloak?
|
||||||
if(pMojangData->wchCape[0]!=0L)
|
if(pMojangData->wchCape[0]!=0L)
|
||||||
{
|
{
|
||||||
wstring wstr=pMojangData->wchCape;
|
wstring wstr=pMojangData->wchCape;
|
||||||
// check the file is not already in
|
// check the file is not already in
|
||||||
bRes=app.IsFileInMemoryTextures(wstr);
|
bRes=app.IsFileInMemoryTextures(wstr);
|
||||||
if(!bRes)
|
if(!bRes)
|
||||||
{
|
{
|
||||||
#ifdef _XBOX
|
#ifdef _XBOX
|
||||||
C4JStorage::ETMSStatus eTMSStatus;
|
C4JStorage::ETMSStatus eTMSStatus;
|
||||||
eTMSStatus=StorageManager.ReadTMSFile(iUserID,C4JStorage::eGlobalStorage_Title,C4JStorage::eTMS_FileType_Graphic,pMojangData->wchCape,&pBuffer, &dwSize);
|
eTMSStatus=StorageManager.ReadTMSFile(iUserID,C4JStorage::eGlobalStorage_Title,C4JStorage::eTMS_FileType_Graphic,pMojangData->wchCape,&pBuffer, &dwSize);
|
||||||
|
|
@ -302,7 +302,7 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||||
app.DebugPrintf("ClientConnection - DIFFICULTY --- %d\n",packet->difficulty);
|
app.DebugPrintf("ClientConnection - DIFFICULTY --- %d\n",packet->difficulty);
|
||||||
level->difficulty = packet->difficulty; // 4J Added
|
level->difficulty = packet->difficulty; // 4J Added
|
||||||
level->isClientSide = true;
|
level->isClientSide = true;
|
||||||
minecraft->setLevel(level);
|
minecraft->setLevel(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
minecraft->player->setPlayerIndex( packet->m_playerIndex );
|
minecraft->player->setPlayerIndex( packet->m_playerIndex );
|
||||||
|
|
@ -362,7 +362,7 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||||
// 4J Stu - At time of writing ProfileManager.GetGamertag() does not always return the correct name,
|
// 4J Stu - At time of writing ProfileManager.GetGamertag() does not always return the correct name,
|
||||||
// if sign-ins are turned off while the player signed in. Using the qnetPlayer instead.
|
// if sign-ins are turned off while the player signed in. Using the qnetPlayer instead.
|
||||||
// need to have a level before create extra local player
|
// need to have a level before create extra local player
|
||||||
MultiPlayerLevel *levelpassedin=(MultiPlayerLevel *)level;
|
MultiPlayerLevel *levelpassedin=(MultiPlayerLevel *)level;
|
||||||
player = minecraft->createExtraLocalPlayer(m_userIndex, networkPlayer->GetOnlineName(), m_userIndex, packet->dimension, this,levelpassedin);
|
player = minecraft->createExtraLocalPlayer(m_userIndex, networkPlayer->GetOnlineName(), m_userIndex, packet->dimension, this,levelpassedin);
|
||||||
|
|
||||||
// need to have a player before the setlevel
|
// need to have a player before the setlevel
|
||||||
|
|
@ -384,7 +384,7 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||||
player->setPlayerIndex( packet->m_playerIndex );
|
player->setPlayerIndex( packet->m_playerIndex );
|
||||||
player->setCustomSkin( app.GetPlayerSkinId(m_userIndex) );
|
player->setCustomSkin( app.GetPlayerSkinId(m_userIndex) );
|
||||||
player->setCustomCape( app.GetPlayerCapeId(m_userIndex) );
|
player->setCustomCape( app.GetPlayerCapeId(m_userIndex) );
|
||||||
|
|
||||||
|
|
||||||
BYTE networkSmallId = getSocket()->getSmallId();
|
BYTE networkSmallId = getSocket()->getSmallId();
|
||||||
app.UpdatePlayerInfo(networkSmallId, packet->m_playerIndex, packet->m_uiGamePrivileges);
|
app.UpdatePlayerInfo(networkSmallId, packet->m_playerIndex, packet->m_uiGamePrivileges);
|
||||||
|
|
@ -396,21 +396,21 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||||
|
|
||||||
displayPrivilegeChanges(minecraft->localplayers[m_userIndex],startingPrivileges);
|
displayPrivilegeChanges(minecraft->localplayers[m_userIndex],startingPrivileges);
|
||||||
}
|
}
|
||||||
|
|
||||||
maxPlayers = packet->maxPlayers;
|
maxPlayers = packet->maxPlayers;
|
||||||
|
|
||||||
// need to have a player before the setLocalCreativeMode
|
// need to have a player before the setLocalCreativeMode
|
||||||
shared_ptr<MultiplayerLocalPlayer> lastPlayer = minecraft->player;
|
shared_ptr<MultiplayerLocalPlayer> lastPlayer = minecraft->player;
|
||||||
minecraft->player = minecraft->localplayers[m_userIndex];
|
minecraft->player = minecraft->localplayers[m_userIndex];
|
||||||
((MultiPlayerGameMode *)minecraft->localgameModes[m_userIndex])->setLocalMode(GameType::byId(packet->gameType));
|
((MultiPlayerGameMode *)minecraft->localgameModes[m_userIndex])->setLocalMode(GameType::byId(packet->gameType));
|
||||||
minecraft->player = lastPlayer;
|
minecraft->player = lastPlayer;
|
||||||
|
|
||||||
// make sure the UI offsets for this player are set correctly
|
// make sure the UI offsets for this player are set correctly
|
||||||
if(iUserID!=-1)
|
if(iUserID!=-1)
|
||||||
{
|
{
|
||||||
ui.UpdateSelectedItemPos(iUserID);
|
ui.UpdateSelectedItemPos(iUserID);
|
||||||
}
|
}
|
||||||
|
|
||||||
TelemetryManager->RecordLevelStart(m_userIndex, eSen_FriendOrMatch_Playing_With_Invited_Friends, eSen_CompeteOrCoop_Coop_and_Competitive, Minecraft::GetInstance()->getLevel(packet->dimension)->difficulty, app.GetLocalPlayerCount(), g_NetworkManager.GetOnlinePlayerCount());
|
TelemetryManager->RecordLevelStart(m_userIndex, eSen_FriendOrMatch_Playing_With_Invited_Friends, eSen_CompeteOrCoop_Coop_and_Competitive, Minecraft::GetInstance()->getLevel(packet->dimension)->difficulty, app.GetLocalPlayerCount(), g_NetworkManager.GetOnlinePlayerCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -448,7 +448,7 @@ void ClientConnection::handleAddEntity(shared_ptr<AddEntityPacket> packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (owner != NULL && owner->instanceof(eTYPE_PLAYER))
|
if (owner != NULL && owner->instanceof(eTYPE_PLAYER))
|
||||||
{
|
{
|
||||||
shared_ptr<Player> player = dynamic_pointer_cast<Player>(owner);
|
shared_ptr<Player> player = dynamic_pointer_cast<Player>(owner);
|
||||||
|
|
@ -574,7 +574,7 @@ void ClientConnection::handleAddEntity(shared_ptr<AddEntityPacket> packet)
|
||||||
}
|
}
|
||||||
packet->data = 0;
|
packet->data = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (packet->type == AddEntityPacket::ARROW) e = shared_ptr<Entity>( new Arrow(level, x, y, z) );
|
if (packet->type == AddEntityPacket::ARROW) e = shared_ptr<Entity>( new Arrow(level, x, y, z) );
|
||||||
if (packet->type == AddEntityPacket::SNOWBALL) e = shared_ptr<Entity>( new Snowball(level, x, y, z) );
|
if (packet->type == AddEntityPacket::SNOWBALL) e = shared_ptr<Entity>( new Snowball(level, x, y, z) );
|
||||||
if (packet->type == AddEntityPacket::THROWN_ENDERPEARL) e = shared_ptr<Entity>( new ThrownEnderpearl(level, x, y, z) );
|
if (packet->type == AddEntityPacket::THROWN_ENDERPEARL) e = shared_ptr<Entity>( new ThrownEnderpearl(level, x, y, z) );
|
||||||
|
|
@ -620,19 +620,22 @@ void ClientConnection::handleAddEntity(shared_ptr<AddEntityPacket> packet)
|
||||||
e->yRotp = packet->yRot;
|
e->yRotp = packet->yRot;
|
||||||
e->xRotp = packet->xRot;
|
e->xRotp = packet->xRot;
|
||||||
|
|
||||||
if (setRot)
|
if (setRot)
|
||||||
{
|
{
|
||||||
e->yRot = 0.0f;
|
e->yRot = 0.0f;
|
||||||
e->xRot = 0.0f;
|
e->xRot = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<shared_ptr<Entity> > *subEntities = e->getSubEntities();
|
vector<shared_ptr<Entity> > *subEntities = e->getSubEntities();
|
||||||
if (subEntities)
|
if (subEntities != NULL)
|
||||||
{
|
{
|
||||||
int offs = packet->id - e->entityId;
|
int offs = packet->id - e->entityId;
|
||||||
for ( auto it : *subEntities )
|
//for (int i = 0; i < subEntities.length; i++)
|
||||||
{
|
for(AUTO_VAR(it, subEntities->begin()); it != subEntities->end(); ++it)
|
||||||
it->entityId += offs;
|
{
|
||||||
|
(*it)->entityId += offs;
|
||||||
|
//subEntities[i].entityId += offs;
|
||||||
|
//System.out.println(subEntities[i].entityId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -682,10 +685,10 @@ void ClientConnection::handleAddEntity(shared_ptr<AddEntityPacket> packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
e->lerpMotion(packet->xa / 8000.0, packet->ya / 8000.0, packet->za / 8000.0);
|
e->lerpMotion(packet->xa / 8000.0, packet->ya / 8000.0, packet->za / 8000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4J: Check our deferred entity link packets
|
// 4J: Check our deferred entity link packets
|
||||||
checkDeferredEntityLinkPackets(e->entityId);
|
checkDeferredEntityLinkPackets(e->entityId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -760,32 +763,28 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
// Win64 keeps local-player identity separate from network smallId; also guard against creating
|
// On Windows64 ProfileManager.GetXUID always returns INVALID_XUID so the check above
|
||||||
// a duplicate remote player for a local slot by checking the username directly.
|
// never fires. Instead compare packet->xuid against the IQNetPlayer-derived XUID for
|
||||||
for (unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
|
// every locally-registered controller slot. This check is race-free: the IQNet slot is
|
||||||
|
// populated by AddLocalPlayerByUserIndex *before* the connection loop starts, so
|
||||||
|
// GetLocalPlayerByUserIndex is valid long before handleAddPlayer runs.
|
||||||
{
|
{
|
||||||
if (minecraft->localplayers[idx] != NULL && minecraft->localplayers[idx]->name == packet->name)
|
const PlayerUID WIN64_XUID_BASE = (PlayerUID)0xe000d45248242f2e;
|
||||||
|
for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
|
||||||
{
|
{
|
||||||
app.DebugPrintf("AddPlayerPacket received for local player name %ls\n", packet->name.c_str());
|
INetworkPlayer *localNetPlayer = g_NetworkManager.GetLocalPlayerByUserIndex(idx);
|
||||||
return;
|
if(localNetPlayer != NULL)
|
||||||
|
{
|
||||||
|
PlayerUID localXuid = WIN64_XUID_BASE + localNetPlayer->GetSmallId();
|
||||||
|
if(localXuid == packet->xuid)
|
||||||
|
{
|
||||||
|
app.DebugPrintf("AddPlayerPacket received for local controller %d (xuid match), skipping RemotePlayer creation\n", idx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*#ifdef _WINDOWS64
|
|
||||||
// On Windows64 all XUIDs are INVALID_XUID so the XUID check above never fires.
|
|
||||||
// packet->m_playerIndex is the server-assigned sequential index (set via LoginPacket),
|
|
||||||
// NOT the controller slot — so we must scan all local player slots and match by
|
|
||||||
// their stored server index rather than using it directly as an array subscript.
|
|
||||||
for(unsigned int idx = 0; idx < XUSER_MAX_COUNT; ++idx)
|
|
||||||
{
|
|
||||||
if(minecraft->localplayers[idx] != NULL &&
|
|
||||||
minecraft->localplayers[idx]->getPlayerIndex() == packet->m_playerIndex)
|
|
||||||
{
|
|
||||||
app.DebugPrintf("AddPlayerPacket received for local player (controller %d, server index %d), skipping RemotePlayer creation\n", idx, packet->m_playerIndex);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif*/
|
|
||||||
|
|
||||||
double x = packet->x / 32.0;
|
double x = packet->x / 32.0;
|
||||||
double y = packet->y / 32.0;
|
double y = packet->y / 32.0;
|
||||||
|
|
@ -812,50 +811,22 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
|
||||||
|
|
||||||
#ifdef _WINDOWS64
|
#ifdef _WINDOWS64
|
||||||
{
|
{
|
||||||
IQNetPlayer* matchedQNetPlayer = NULL;
|
|
||||||
PlayerUID pktXuid = player->getXuid();
|
PlayerUID pktXuid = player->getXuid();
|
||||||
const PlayerUID WIN64_XUID_BASE = (PlayerUID)0xe000d45248242f2e;
|
const PlayerUID WIN64_XUID_BASE = (PlayerUID)0xe000d45248242f2e;
|
||||||
// Legacy compatibility path for peers still using embedded smallId XUIDs.
|
|
||||||
if (pktXuid >= WIN64_XUID_BASE && pktXuid < WIN64_XUID_BASE + MINECRAFT_NET_MAX_PLAYERS)
|
if (pktXuid >= WIN64_XUID_BASE && pktXuid < WIN64_XUID_BASE + MINECRAFT_NET_MAX_PLAYERS)
|
||||||
{
|
{
|
||||||
BYTE smallId = (BYTE)(pktXuid - WIN64_XUID_BASE);
|
BYTE smallId = (BYTE)(pktXuid - WIN64_XUID_BASE);
|
||||||
INetworkPlayer* np = g_NetworkManager.GetPlayerBySmallId(smallId);
|
INetworkPlayer* np = g_NetworkManager.GetPlayerBySmallId(smallId);
|
||||||
if (np != NULL)
|
if (np != NULL)
|
||||||
{
|
{
|
||||||
NetworkPlayerXbox* npx = (NetworkPlayerXbox*)np;
|
|
||||||
matchedQNetPlayer = npx->GetQNetPlayer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Current Win64 path: identify QNet player by name and attach packet XUID.
|
|
||||||
if (matchedQNetPlayer == NULL)
|
|
||||||
{
|
|
||||||
for (BYTE smallId = 0; smallId < MINECRAFT_NET_MAX_PLAYERS; ++smallId)
|
|
||||||
{
|
|
||||||
INetworkPlayer* np = g_NetworkManager.GetPlayerBySmallId(smallId);
|
|
||||||
if (np == NULL)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
NetworkPlayerXbox* npx = (NetworkPlayerXbox*)np;
|
NetworkPlayerXbox* npx = (NetworkPlayerXbox*)np;
|
||||||
IQNetPlayer* qp = npx->GetQNetPlayer();
|
IQNetPlayer* qp = npx->GetQNetPlayer();
|
||||||
if (qp != NULL && _wcsicmp(qp->m_gamertag, packet->name.c_str()) == 0)
|
if (qp != NULL && qp->m_gamertag[0] == 0)
|
||||||
{
|
{
|
||||||
matchedQNetPlayer = qp;
|
wcsncpy_s(qp->m_gamertag, 32, packet->name.c_str(), _TRUNCATE);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matchedQNetPlayer != NULL)
|
|
||||||
{
|
|
||||||
// Store packet-authoritative XUID on this network slot so later lookups by XUID
|
|
||||||
// (e.g. remove player, display mapping) work for both legacy and uid.dat clients.
|
|
||||||
matchedQNetPlayer->m_resolvedXuid = pktXuid;
|
|
||||||
if (matchedQNetPlayer->m_gamertag[0] == 0)
|
|
||||||
{
|
|
||||||
wcsncpy_s(matchedQNetPlayer->m_gamertag, 32, packet->name.c_str(), _TRUNCATE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
@ -876,7 +847,7 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
|
||||||
player->setCustomSkin( packet->m_skinId );
|
player->setCustomSkin( packet->m_skinId );
|
||||||
player->setCustomCape( packet->m_capeId );
|
player->setCustomCape( packet->m_capeId );
|
||||||
player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges);
|
player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges);
|
||||||
|
|
||||||
if(!player->customTextureUrl.empty() && player->customTextureUrl.substr(0,3).compare(L"def") != 0 && !app.IsFileInMemoryTextures(player->customTextureUrl))
|
if(!player->customTextureUrl.empty() && player->customTextureUrl.substr(0,3).compare(L"def") != 0 && !app.IsFileInMemoryTextures(player->customTextureUrl))
|
||||||
{
|
{
|
||||||
if( minecraft->addPendingClientTextureRequest(player->customTextureUrl) )
|
if( minecraft->addPendingClientTextureRequest(player->customTextureUrl) )
|
||||||
|
|
@ -893,7 +864,7 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
app.DebugPrintf("Custom skin for player %ls is %ls\n",player->name.c_str(),player->customTextureUrl.c_str());
|
app.DebugPrintf("Custom skin for player %ls is %ls\n",player->name.c_str(),player->customTextureUrl.c_str());
|
||||||
|
|
||||||
if(!player->customTextureUrl2.empty() && player->customTextureUrl2.substr(0,3).compare(L"def") != 0 && !app.IsFileInMemoryTextures(player->customTextureUrl2))
|
if(!player->customTextureUrl2.empty() && player->customTextureUrl2.substr(0,3).compare(L"def") != 0 && !app.IsFileInMemoryTextures(player->customTextureUrl2))
|
||||||
{
|
{
|
||||||
if( minecraft->addPendingClientTextureRequest(player->customTextureUrl2) )
|
if( minecraft->addPendingClientTextureRequest(player->customTextureUrl2) )
|
||||||
|
|
@ -1025,8 +996,6 @@ void ClientConnection::handleRemoveEntity(shared_ptr<RemoveEntitiesPacket> packe
|
||||||
qp->m_smallId = 0;
|
qp->m_smallId = 0;
|
||||||
qp->m_isRemote = false;
|
qp->m_isRemote = false;
|
||||||
qp->m_isHostPlayer = false;
|
qp->m_isHostPlayer = false;
|
||||||
// Clear resolved id to avoid stale XUID -> player matches after disconnect.
|
|
||||||
qp->m_resolvedXuid = INVALID_XUID;
|
|
||||||
qp->m_gamertag[0] = 0;
|
qp->m_gamertag[0] = 0;
|
||||||
qp->SetCustomDataValue(0);
|
qp->SetCustomDataValue(0);
|
||||||
}
|
}
|
||||||
|
|
@ -1073,7 +1042,7 @@ void ClientConnection::handleMovePlayer(shared_ptr<MovePlayerPacket> packet)
|
||||||
packet->yView = player->y;
|
packet->yView = player->y;
|
||||||
connection->send(packet);
|
connection->send(packet);
|
||||||
if (!started)
|
if (!started)
|
||||||
{
|
{
|
||||||
|
|
||||||
if(!g_NetworkManager.IsHost() )
|
if(!g_NetworkManager.IsHost() )
|
||||||
{
|
{
|
||||||
|
|
@ -1089,7 +1058,7 @@ void ClientConnection::handleMovePlayer(shared_ptr<MovePlayerPacket> packet)
|
||||||
|
|
||||||
started = true;
|
started = true;
|
||||||
minecraft->setScreen(NULL);
|
minecraft->setScreen(NULL);
|
||||||
|
|
||||||
// Fix for #105852 - TU12: Content: Gameplay: Local splitscreen Players are spawned at incorrect places after re-joining previously saved and loaded "Mass Effect World".
|
// Fix for #105852 - TU12: Content: Gameplay: Local splitscreen Players are spawned at incorrect places after re-joining previously saved and loaded "Mass Effect World".
|
||||||
// Move this check from Minecraft::createExtraLocalPlayer
|
// Move this check from Minecraft::createExtraLocalPlayer
|
||||||
// 4J-PB - can't call this when this function is called from the qnet thread (GetGameStarted will be false)
|
// 4J-PB - can't call this when this function is called from the qnet thread (GetGameStarted will be false)
|
||||||
|
|
@ -1163,7 +1132,7 @@ void ClientConnection::handleChunkTilesUpdate(shared_ptr<ChunkTilesUpdatePacket>
|
||||||
// Don't bother setting this to dirty if it isn't going to visually change - we get a lot of
|
// Don't bother setting this to dirty if it isn't going to visually change - we get a lot of
|
||||||
// water changing from static to dynamic for instance
|
// water changing from static to dynamic for instance
|
||||||
if(!( ( ( prevTile == Tile::water_Id ) && ( tile == Tile::calmWater_Id ) ) ||
|
if(!( ( ( prevTile == Tile::water_Id ) && ( tile == Tile::calmWater_Id ) ) ||
|
||||||
( ( prevTile == Tile::calmWater_Id ) && ( tile == Tile::water_Id ) ) ||
|
( ( prevTile == Tile::calmWater_Id ) && ( tile == Tile::water_Id ) ) ||
|
||||||
( ( prevTile == Tile::lava_Id ) && ( tile == Tile::calmLava_Id ) ) ||
|
( ( prevTile == Tile::lava_Id ) && ( tile == Tile::calmLava_Id ) ) ||
|
||||||
( ( prevTile == Tile::calmLava_Id ) && ( tile == Tile::calmLava_Id ) ) ||
|
( ( prevTile == Tile::calmLava_Id ) && ( tile == Tile::calmLava_Id ) ) ||
|
||||||
( ( prevTile == Tile::calmLava_Id ) && ( tile == Tile::lava_Id ) ) ) )
|
( ( prevTile == Tile::calmLava_Id ) && ( tile == Tile::lava_Id ) ) ) )
|
||||||
|
|
@ -1292,7 +1261,7 @@ void ClientConnection::handleDisconnect(shared_ptr<DisconnectPacket> packet)
|
||||||
{
|
{
|
||||||
connection->close(DisconnectPacket::eDisconnect_Kicked);
|
connection->close(DisconnectPacket::eDisconnect_Kicked);
|
||||||
done = true;
|
done = true;
|
||||||
|
|
||||||
Minecraft *pMinecraft = Minecraft::GetInstance();
|
Minecraft *pMinecraft = Minecraft::GetInstance();
|
||||||
pMinecraft->connectionDisconnected( m_userIndex , packet->reason );
|
pMinecraft->connectionDisconnected( m_userIndex , packet->reason );
|
||||||
app.SetDisconnectReason( packet->reason );
|
app.SetDisconnectReason( packet->reason );
|
||||||
|
|
@ -1376,7 +1345,7 @@ void ClientConnection::handleTakeItemEntity(shared_ptr<TakeItemEntityPacket> pac
|
||||||
|
|
||||||
if (from != NULL)
|
if (from != NULL)
|
||||||
{
|
{
|
||||||
// If this is a local player, then we only want to do processing for it if this connection is associated with the player it is for. In
|
// If this is a local player, then we only want to do processing for it if this connection is associated with the player it is for. In
|
||||||
// particular, we don't want to remove the item entity until we are processing it for the right connection, or else we won't have a valid
|
// particular, we don't want to remove the item entity until we are processing it for the right connection, or else we won't have a valid
|
||||||
// "from" reference if we've already removed the item for an earlier processed connection
|
// "from" reference if we've already removed the item for an earlier processed connection
|
||||||
if( isLocalPlayer )
|
if( isLocalPlayer )
|
||||||
|
|
@ -1441,9 +1410,6 @@ void ClientConnection::handleChat(shared_ptr<ChatPacket> packet)
|
||||||
|
|
||||||
switch(packet->m_messageType)
|
switch(packet->m_messageType)
|
||||||
{
|
{
|
||||||
case ChatPacket::e_ChatCustom:
|
|
||||||
message = (packet->m_stringArgs.size() >= 1) ? packet->m_stringArgs[0] : L"";
|
|
||||||
break;
|
|
||||||
case ChatPacket::e_ChatBedOccupied:
|
case ChatPacket::e_ChatBedOccupied:
|
||||||
message = app.GetString(IDS_TILE_BED_OCCUPIED);
|
message = app.GetString(IDS_TILE_BED_OCCUPIED);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1464,7 +1430,7 @@ void ClientConnection::handleChat(shared_ptr<ChatPacket> packet)
|
||||||
case ChatPacket::e_ChatBedMeSleep:
|
case ChatPacket::e_ChatBedMeSleep:
|
||||||
message=app.GetString(IDS_TILE_BED_MESLEEP);
|
message=app.GetString(IDS_TILE_BED_MESLEEP);
|
||||||
break;
|
break;
|
||||||
case ChatPacket::e_ChatPlayerJoinedGame:
|
case ChatPacket::e_ChatPlayerJoinedGame:
|
||||||
message=app.GetString(IDS_PLAYER_JOINED);
|
message=app.GetString(IDS_PLAYER_JOINED);
|
||||||
iPos=message.find(L"%s");
|
iPos=message.find(L"%s");
|
||||||
message.replace(iPos,2,playerDisplayName);
|
message.replace(iPos,2,playerDisplayName);
|
||||||
|
|
@ -1579,7 +1545,7 @@ void ClientConnection::handleChat(shared_ptr<ChatPacket> packet)
|
||||||
replaceEntitySource = true;
|
replaceEntitySource = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case ChatPacket::e_ChatDeathFellAccidentLadder:
|
case ChatPacket::e_ChatDeathFellAccidentLadder:
|
||||||
message=app.GetString(IDS_DEATH_FELL_ACCIDENT_LADDER);
|
message=app.GetString(IDS_DEATH_FELL_ACCIDENT_LADDER);
|
||||||
replacePlayer = true;
|
replacePlayer = true;
|
||||||
|
|
@ -1744,7 +1710,7 @@ void ClientConnection::handleChat(shared_ptr<ChatPacket> packet)
|
||||||
message=app.GetString(IDS_MAX_WOLVES_BRED);
|
message=app.GetString(IDS_MAX_WOLVES_BRED);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// can't shear the mooshroom
|
// can't shear the mooshroom
|
||||||
case ChatPacket::e_ChatPlayerCantShearMooshroom:
|
case ChatPacket::e_ChatPlayerCantShearMooshroom:
|
||||||
message=app.GetString(IDS_CANT_SHEAR_MOOSHROOM);
|
message=app.GetString(IDS_CANT_SHEAR_MOOSHROOM);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1752,16 +1718,16 @@ void ClientConnection::handleChat(shared_ptr<ChatPacket> packet)
|
||||||
// Paintings/Item Frames
|
// Paintings/Item Frames
|
||||||
case ChatPacket::e_ChatPlayerMaxHangingEntities:
|
case ChatPacket::e_ChatPlayerMaxHangingEntities:
|
||||||
message=app.GetString(IDS_MAX_HANGINGENTITIES);
|
message=app.GetString(IDS_MAX_HANGINGENTITIES);
|
||||||
break;
|
break;
|
||||||
// Enemy spawn eggs in peaceful
|
// Enemy spawn eggs in peaceful
|
||||||
case ChatPacket::e_ChatPlayerCantSpawnInPeaceful:
|
case ChatPacket::e_ChatPlayerCantSpawnInPeaceful:
|
||||||
message=app.GetString(IDS_CANT_SPAWN_IN_PEACEFUL);
|
message=app.GetString(IDS_CANT_SPAWN_IN_PEACEFUL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Enemy spawn eggs in peaceful
|
// Enemy spawn eggs in peaceful
|
||||||
case ChatPacket::e_ChatPlayerMaxBoats:
|
case ChatPacket::e_ChatPlayerMaxBoats:
|
||||||
message=app.GetString(IDS_MAX_BOATS);
|
message=app.GetString(IDS_MAX_BOATS);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ChatPacket::e_ChatCommandTeleportSuccess:
|
case ChatPacket::e_ChatCommandTeleportSuccess:
|
||||||
message=app.GetString(IDS_COMMAND_TELEPORT_SUCCESS);
|
message=app.GetString(IDS_COMMAND_TELEPORT_SUCCESS);
|
||||||
|
|
@ -1893,7 +1859,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
BOOL isAtLeastOneFriend = g_NetworkManager.IsHost();
|
BOOL isAtLeastOneFriend = g_NetworkManager.IsHost();
|
||||||
BOOL isFriendsWithHost = TRUE;
|
BOOL isFriendsWithHost = TRUE;
|
||||||
BOOL cantPlayContentRestricted = FALSE;
|
BOOL cantPlayContentRestricted = FALSE;
|
||||||
|
|
||||||
if(!g_NetworkManager.IsHost())
|
if(!g_NetworkManager.IsHost())
|
||||||
{
|
{
|
||||||
// set the game host settings
|
// set the game host settings
|
||||||
|
|
@ -1927,7 +1893,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
}
|
}
|
||||||
if( playerXuid != INVALID_XUID )
|
if( playerXuid != INVALID_XUID )
|
||||||
{
|
{
|
||||||
// Is this user friends with the host player?
|
// Is this user friends with the host player?
|
||||||
BOOL result;
|
BOOL result;
|
||||||
DWORD error;
|
DWORD error;
|
||||||
error = XUserAreUsersFriends(idx,&packet->m_playerXuids[packet->m_hostIndex],1,&result,NULL);
|
error = XUserAreUsersFriends(idx,&packet->m_playerXuids[packet->m_hostIndex],1,&result,NULL);
|
||||||
|
|
@ -1957,7 +1923,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
}
|
}
|
||||||
if( playerXuid != INVALID_XUID )
|
if( playerXuid != INVALID_XUID )
|
||||||
{
|
{
|
||||||
// Is this user friends with the host player?
|
// Is this user friends with the host player?
|
||||||
BOOL result;
|
BOOL result;
|
||||||
DWORD error;
|
DWORD error;
|
||||||
error = XUserAreUsersFriends(m_userIndex,&packet->m_playerXuids[packet->m_hostIndex],1,&result,NULL);
|
error = XUserAreUsersFriends(m_userIndex,&packet->m_playerXuids[packet->m_hostIndex],1,&result,NULL);
|
||||||
|
|
@ -2072,7 +2038,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
|
|
||||||
if(m_userIndex == ProfileManager.GetPrimaryPad() )
|
if(m_userIndex == ProfileManager.GetPrimaryPad() )
|
||||||
{
|
{
|
||||||
// Is this user friends with the host player?
|
// Is this user friends with the host player?
|
||||||
bool isFriend = true;
|
bool isFriend = true;
|
||||||
unsigned int friendCount = 0;
|
unsigned int friendCount = 0;
|
||||||
#ifdef __PS3__
|
#ifdef __PS3__
|
||||||
|
|
@ -2102,7 +2068,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
requestParam.offset = 0;
|
requestParam.offset = 0;
|
||||||
requestParam.userInfo.userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad());
|
requestParam.userInfo.userId = ProfileManager.getUserID(ProfileManager.GetPrimaryPad());
|
||||||
|
|
||||||
int ret = sce::Toolkit::NP::Friends::Interface::getFriendslist(&friendList, &requestParam, false);
|
int ret = sce::Toolkit::NP::Friends::Interface::getFriendslist(&friendList, &requestParam, false);
|
||||||
if( ret == 0 )
|
if( ret == 0 )
|
||||||
{
|
{
|
||||||
if( friendList.hasResult() )
|
if( friendList.hasResult() )
|
||||||
|
|
@ -2112,7 +2078,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if( ret == 0 )
|
if( ret == 0 )
|
||||||
{
|
{
|
||||||
isFriend = false;
|
isFriend = false;
|
||||||
SceNpId npid;
|
SceNpId npid;
|
||||||
for( unsigned int i = 0; i < friendCount; i++ )
|
for( unsigned int i = 0; i < friendCount; i++ )
|
||||||
|
|
@ -2195,7 +2161,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
isAtLeastOneFriend = true;
|
isAtLeastOneFriend = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
app.DebugPrintf("ClientConnection::handlePreLogin: User has at least one friend? %s\n", isAtLeastOneFriend ? "Yes" : "No");
|
app.DebugPrintf("ClientConnection::handlePreLogin: User has at least one friend? %s\n", isAtLeastOneFriend ? "Yes" : "No");
|
||||||
|
|
@ -2237,8 +2203,8 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
DisconnectPacket::eDisconnectReason reason = DisconnectPacket::eDisconnect_NoUGC_Remote;
|
DisconnectPacket::eDisconnectReason reason = DisconnectPacket::eDisconnect_NoUGC_Remote;
|
||||||
#else
|
#else
|
||||||
DisconnectPacket::eDisconnectReason reason = DisconnectPacket::eDisconnect_None;
|
DisconnectPacket::eDisconnectReason reason = DisconnectPacket::eDisconnect_None;
|
||||||
#endif
|
#endif
|
||||||
if(m_userIndex == ProfileManager.GetPrimaryPad())
|
if(m_userIndex == ProfileManager.GetPrimaryPad())
|
||||||
{
|
{
|
||||||
if(!isFriendsWithHost) reason = DisconnectPacket::eDisconnect_NotFriendsWithHost;
|
if(!isFriendsWithHost) reason = DisconnectPacket::eDisconnect_NotFriendsWithHost;
|
||||||
else if(!isAtLeastOneFriend) reason = DisconnectPacket::eDisconnect_NoFriendsInGame;
|
else if(!isAtLeastOneFriend) reason = DisconnectPacket::eDisconnect_NoFriendsInGame;
|
||||||
|
|
@ -2250,7 +2216,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_ExitWorld,(void *)TRUE);
|
app.SetAction(ProfileManager.GetPrimaryPad(),eAppAction_ExitWorld,(void *)TRUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!isFriendsWithHost) reason = DisconnectPacket::eDisconnect_NotFriendsWithHost;
|
if(!isFriendsWithHost) reason = DisconnectPacket::eDisconnect_NotFriendsWithHost;
|
||||||
else if(!canPlayLocal) reason = DisconnectPacket::eDisconnect_NoUGC_Single_Local;
|
else if(!canPlayLocal) reason = DisconnectPacket::eDisconnect_NoUGC_Single_Local;
|
||||||
else if(cantPlayContentRestricted) reason = DisconnectPacket::eDisconnect_ContentRestricted_Single_Local;
|
else if(cantPlayContentRestricted) reason = DisconnectPacket::eDisconnect_ContentRestricted_Single_Local;
|
||||||
|
|
@ -2263,7 +2229,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
|
|
||||||
app.SetDisconnectReason( reason );
|
app.SetDisconnectReason( reason );
|
||||||
|
|
||||||
// 4J-PB - this locks up on the read and write threads not closing down, because they are trying to lock the incoming critsec when it's already locked by this thread
|
// 4J-PB - this locks up on the read and write threads not closing down, because they are trying to lock the incoming critsec when it's already locked by this thread
|
||||||
// Minecraft::GetInstance()->connectionDisconnected( m_userIndex , reason );
|
// Minecraft::GetInstance()->connectionDisconnected( m_userIndex , reason );
|
||||||
// done = true;
|
// done = true;
|
||||||
// connection->flush();
|
// connection->flush();
|
||||||
|
|
@ -2320,7 +2286,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// On PS3, all non-signed in players (even guests) can get a useful offlineXUID
|
// On PS3, all non-signed in players (even guests) can get a useful offlineXUID
|
||||||
#if !(defined __PS3__ || defined _DURANGO )
|
#if !(defined __PS3__ || defined _DURANGO )
|
||||||
if( !ProfileManager.IsGuest( m_userIndex ) )
|
if( !ProfileManager.IsGuest( m_userIndex ) )
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
|
@ -2329,7 +2295,7 @@ void ClientConnection::handlePreLogin(shared_ptr<PreLoginPacket> packet)
|
||||||
}
|
}
|
||||||
BOOL allAllowed, friendsAllowed;
|
BOOL allAllowed, friendsAllowed;
|
||||||
ProfileManager.AllowedPlayerCreatedContent(m_userIndex,true,&allAllowed,&friendsAllowed);
|
ProfileManager.AllowedPlayerCreatedContent(m_userIndex,true,&allAllowed,&friendsAllowed);
|
||||||
send( shared_ptr<LoginPacket>( new LoginPacket(minecraft->user->name, SharedConstants::NETWORK_PROTOCOL_VERSION, offlineXUID, onlineXUID, (allAllowed!=TRUE && friendsAllowed==TRUE),
|
send( shared_ptr<LoginPacket>( new LoginPacket(minecraft->user->name, SharedConstants::NETWORK_PROTOCOL_VERSION, offlineXUID, onlineXUID, (allAllowed!=TRUE && friendsAllowed==TRUE),
|
||||||
packet->m_ugcPlayersVersion, app.GetPlayerSkinId(m_userIndex), app.GetPlayerCapeId(m_userIndex), ProfileManager.IsGuest( m_userIndex ))));
|
packet->m_ugcPlayersVersion, app.GetPlayerSkinId(m_userIndex), app.GetPlayerCapeId(m_userIndex), ProfileManager.IsGuest( m_userIndex ))));
|
||||||
|
|
||||||
if(!g_NetworkManager.IsHost() )
|
if(!g_NetworkManager.IsHost() )
|
||||||
|
|
@ -2387,12 +2353,14 @@ void ClientConnection::handleAddMob(shared_ptr<AddMobPacket> packet)
|
||||||
mob->xRotp = packet->xRot;
|
mob->xRotp = packet->xRot;
|
||||||
|
|
||||||
vector<shared_ptr<Entity> > *subEntities = mob->getSubEntities();
|
vector<shared_ptr<Entity> > *subEntities = mob->getSubEntities();
|
||||||
if (subEntities)
|
if (subEntities != NULL)
|
||||||
{
|
{
|
||||||
int offs = packet->id - mob->entityId;
|
int offs = packet->id - mob->entityId;
|
||||||
for (auto& it : *subEntities )
|
//for (int i = 0; i < subEntities.length; i++)
|
||||||
{
|
for(AUTO_VAR(it, subEntities->begin()); it != subEntities->end(); ++it)
|
||||||
it->entityId += offs;
|
{
|
||||||
|
//subEntities[i].entityId += offs;
|
||||||
|
(*it)->entityId += offs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2478,7 +2446,7 @@ void ClientConnection::handleEntityLinkPacket(shared_ptr<SetEntityLinkPacket> pa
|
||||||
minecraft.gui.setOverlayMessage(I18n.get("mount.onboard", Options.getTranslatedKeyMessage(options.keySneak.key)), false);
|
minecraft.gui.setOverlayMessage(I18n.get("mount.onboard", Options.getTranslatedKeyMessage(options.keySneak.key)), false);
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
else if (packet->type == SetEntityLinkPacket::LEASH)
|
else if (packet->type == SetEntityLinkPacket::LEASH)
|
||||||
{
|
{
|
||||||
if ( (sourceEntity != NULL) && sourceEntity->instanceof(eTYPE_MOB) )
|
if ( (sourceEntity != NULL) && sourceEntity->instanceof(eTYPE_MOB) )
|
||||||
|
|
@ -2548,7 +2516,7 @@ void ClientConnection::handleTexture(shared_ptr<TexturePacket> packet)
|
||||||
wprintf(L"Client received request for custom texture %ls\n",packet->textureName.c_str());
|
wprintf(L"Client received request for custom texture %ls\n",packet->textureName.c_str());
|
||||||
#endif
|
#endif
|
||||||
PBYTE pbData=NULL;
|
PBYTE pbData=NULL;
|
||||||
DWORD dwBytes=0;
|
DWORD dwBytes=0;
|
||||||
app.GetMemFileDetails(packet->textureName,&pbData,&dwBytes);
|
app.GetMemFileDetails(packet->textureName,&pbData,&dwBytes);
|
||||||
|
|
||||||
if(dwBytes!=0)
|
if(dwBytes!=0)
|
||||||
|
|
@ -2580,7 +2548,7 @@ void ClientConnection::handleTextureAndGeometry(shared_ptr<TextureAndGeometryPac
|
||||||
wprintf(L"Client received request for custom texture and geometry %ls\n",packet->textureName.c_str());
|
wprintf(L"Client received request for custom texture and geometry %ls\n",packet->textureName.c_str());
|
||||||
#endif
|
#endif
|
||||||
PBYTE pbData=NULL;
|
PBYTE pbData=NULL;
|
||||||
DWORD dwBytes=0;
|
DWORD dwBytes=0;
|
||||||
app.GetMemFileDetails(packet->textureName,&pbData,&dwBytes);
|
app.GetMemFileDetails(packet->textureName,&pbData,&dwBytes);
|
||||||
DLCSkinFile *pDLCSkinFile = app.m_dlcManager.getSkinFile(packet->textureName);
|
DLCSkinFile *pDLCSkinFile = app.m_dlcManager.getSkinFile(packet->textureName);
|
||||||
|
|
||||||
|
|
@ -2614,9 +2582,9 @@ void ClientConnection::handleTextureAndGeometry(shared_ptr<TextureAndGeometryPac
|
||||||
// Add the texture data
|
// Add the texture data
|
||||||
app.AddMemoryTextureFile(packet->textureName,packet->pbData,packet->dwTextureBytes);
|
app.AddMemoryTextureFile(packet->textureName,packet->pbData,packet->dwTextureBytes);
|
||||||
// Add the geometry data
|
// Add the geometry data
|
||||||
if(packet->dwBoxC!=0)
|
if(packet->dwBoxC!=0)
|
||||||
{
|
{
|
||||||
app.SetAdditionalSkinBoxes(packet->dwSkinID,packet->BoxDataA,packet->dwBoxC);
|
app.SetAdditionalSkinBoxes(packet->dwSkinID,packet->BoxDataA,packet->dwBoxC);
|
||||||
}
|
}
|
||||||
// Add the anim override
|
// Add the anim override
|
||||||
app.SetAnimOverrideBitmask(packet->dwSkinID,packet->uiAnimOverrideBitmask);
|
app.SetAnimOverrideBitmask(packet->dwSkinID,packet->uiAnimOverrideBitmask);
|
||||||
|
|
@ -2662,7 +2630,7 @@ void ClientConnection::handleTextureChange(shared_ptr<TextureChangePacket> packe
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!packet->path.empty() && packet->path.substr(0,3).compare(L"def") != 0 && !app.IsFileInMemoryTextures(packet->path))
|
if(!packet->path.empty() && packet->path.substr(0,3).compare(L"def") != 0 && !app.IsFileInMemoryTextures(packet->path))
|
||||||
{
|
{
|
||||||
if( minecraft->addPendingClientTextureRequest(packet->path) )
|
if( minecraft->addPendingClientTextureRequest(packet->path) )
|
||||||
|
|
@ -2734,10 +2702,6 @@ void ClientConnection::handleRespawn(shared_ptr<RespawnPacket> packet)
|
||||||
int oldDimension = minecraft->localplayers[m_userIndex]->dimension;
|
int oldDimension = minecraft->localplayers[m_userIndex]->dimension;
|
||||||
started = false;
|
started = false;
|
||||||
|
|
||||||
// Stop any streaming music (e.g. jukebox) when changing dimensions
|
|
||||||
// so it doesn't leak into the new dimension
|
|
||||||
level->playStreamingMusic(L"", 0, 0, 0);
|
|
||||||
|
|
||||||
// Remove client connection from this level
|
// Remove client connection from this level
|
||||||
level->removeClientConnection(this, false);
|
level->removeClientConnection(this, false);
|
||||||
|
|
||||||
|
|
@ -2768,7 +2732,7 @@ void ClientConnection::handleRespawn(shared_ptr<RespawnPacket> packet)
|
||||||
level->removeEntity( shared_ptr<Entity>(minecraft->localplayers[m_userIndex]) );
|
level->removeEntity( shared_ptr<Entity>(minecraft->localplayers[m_userIndex]) );
|
||||||
|
|
||||||
level = dimensionLevel;
|
level = dimensionLevel;
|
||||||
|
|
||||||
// Whilst calling setLevel, make sure that minecraft::player is set up to be correct for this
|
// Whilst calling setLevel, make sure that minecraft::player is set up to be correct for this
|
||||||
// connection
|
// connection
|
||||||
shared_ptr<MultiplayerLocalPlayer> lastPlayer = minecraft->player;
|
shared_ptr<MultiplayerLocalPlayer> lastPlayer = minecraft->player;
|
||||||
|
|
@ -2777,7 +2741,7 @@ void ClientConnection::handleRespawn(shared_ptr<RespawnPacket> packet)
|
||||||
minecraft->player = lastPlayer;
|
minecraft->player = lastPlayer;
|
||||||
|
|
||||||
TelemetryManager->RecordLevelExit(m_userIndex, eSen_LevelExitStatus_Succeeded);
|
TelemetryManager->RecordLevelExit(m_userIndex, eSen_LevelExitStatus_Succeeded);
|
||||||
|
|
||||||
//minecraft->player->dimension = packet->dimension;
|
//minecraft->player->dimension = packet->dimension;
|
||||||
minecraft->localplayers[m_userIndex]->dimension = packet->dimension;
|
minecraft->localplayers[m_userIndex]->dimension = packet->dimension;
|
||||||
//minecraft->setScreen(new ReceivingLevelScreen(this));
|
//minecraft->setScreen(new ReceivingLevelScreen(this));
|
||||||
|
|
@ -2828,12 +2792,12 @@ void ClientConnection::handleRespawn(shared_ptr<RespawnPacket> packet)
|
||||||
{
|
{
|
||||||
ui.NavigateToScene(m_userIndex, eUIScene_ConnectingProgress, param);
|
ui.NavigateToScene(m_userIndex, eUIScene_ConnectingProgress, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
app.SetAction( m_userIndex, eAppAction_WaitForDimensionChangeComplete);
|
app.SetAction( m_userIndex, eAppAction_WaitForDimensionChangeComplete);
|
||||||
}
|
}
|
||||||
|
|
||||||
//minecraft->respawnPlayer(minecraft->player->GetXboxPad(),true, packet->dimension);
|
//minecraft->respawnPlayer(minecraft->player->GetXboxPad(),true, packet->dimension);
|
||||||
|
|
||||||
// Wrap respawnPlayer call up in code to set & restore the player/gamemode etc. as some things
|
// Wrap respawnPlayer call up in code to set & restore the player/gamemode etc. as some things
|
||||||
// in there assume that we are set up for the player that the respawn is coming in for
|
// in there assume that we are set up for the player that the respawn is coming in for
|
||||||
int oldIndex = minecraft->getLocalPlayerIdx();
|
int oldIndex = minecraft->getLocalPlayerIdx();
|
||||||
|
|
@ -2858,7 +2822,7 @@ void ClientConnection::handleExplosion(shared_ptr<ExplodePacket> packet)
|
||||||
MultiPlayerLevel *mpLevel = (MultiPlayerLevel *)minecraft->level;
|
MultiPlayerLevel *mpLevel = (MultiPlayerLevel *)minecraft->level;
|
||||||
mpLevel->enableResetChanges(false);
|
mpLevel->enableResetChanges(false);
|
||||||
// 4J - now directly pass a pointer to the toBlow array in the packet rather than copying around
|
// 4J - now directly pass a pointer to the toBlow array in the packet rather than copying around
|
||||||
e->finalizeExplosion(true, &packet->toBlow);
|
e->finalizeExplosion(true, &packet->toBlow);
|
||||||
mpLevel->enableResetChanges(true);
|
mpLevel->enableResetChanges(true);
|
||||||
PIXEndNamedEvent();
|
PIXEndNamedEvent();
|
||||||
PIXEndNamedEvent();
|
PIXEndNamedEvent();
|
||||||
|
|
@ -2904,7 +2868,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2918,7 +2882,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2932,7 +2896,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2947,7 +2911,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2962,7 +2926,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2977,7 +2941,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -2989,7 +2953,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -3001,7 +2965,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -3015,7 +2979,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -3030,7 +2994,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -3042,7 +3006,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -3065,7 +3029,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -3077,7 +3041,7 @@ void ClientConnection::handleContainerOpen(shared_ptr<ContainerOpenPacket> packe
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
failed = true;
|
failed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
@ -3155,7 +3119,7 @@ void ClientConnection::handleContainerAck(shared_ptr<ContainerAckPacket> packet)
|
||||||
void ClientConnection::handleContainerContent(shared_ptr<ContainerSetContentPacket> packet)
|
void ClientConnection::handleContainerContent(shared_ptr<ContainerSetContentPacket> packet)
|
||||||
{
|
{
|
||||||
shared_ptr<MultiplayerLocalPlayer> player = minecraft->localplayers[m_userIndex];
|
shared_ptr<MultiplayerLocalPlayer> player = minecraft->localplayers[m_userIndex];
|
||||||
if (packet->containerId == AbstractContainerMenu::CONTAINER_ID_INVENTORY)
|
if (packet->containerId == AbstractContainerMenu::CONTAINER_ID_INVENTORY)
|
||||||
{
|
{
|
||||||
player->inventoryMenu->setAll(&packet->items);
|
player->inventoryMenu->setAll(&packet->items);
|
||||||
}
|
}
|
||||||
|
|
@ -3235,7 +3199,7 @@ void ClientConnection::handleTileEntityData(shared_ptr<TileEntityDataPacket> pac
|
||||||
else if (packet->type == TileEntityDataPacket::TYPE_BEACON && dynamic_pointer_cast<BeaconTileEntity>(te) != NULL)
|
else if (packet->type == TileEntityDataPacket::TYPE_BEACON && dynamic_pointer_cast<BeaconTileEntity>(te) != NULL)
|
||||||
{
|
{
|
||||||
dynamic_pointer_cast<BeaconTileEntity>(te)->load(packet->tag);
|
dynamic_pointer_cast<BeaconTileEntity>(te)->load(packet->tag);
|
||||||
}
|
}
|
||||||
else if (packet->type == TileEntityDataPacket::TYPE_SKULL && dynamic_pointer_cast<SkullTileEntity>(te) != NULL)
|
else if (packet->type == TileEntityDataPacket::TYPE_SKULL && dynamic_pointer_cast<SkullTileEntity>(te) != NULL)
|
||||||
{
|
{
|
||||||
dynamic_pointer_cast<SkullTileEntity>(te)->load(packet->tag);
|
dynamic_pointer_cast<SkullTileEntity>(te)->load(packet->tag);
|
||||||
|
|
@ -3313,7 +3277,7 @@ void ClientConnection::handleGameEvent(shared_ptr<GameEventPacket> gameEventPack
|
||||||
else if (event == GameEventPacket::WIN_GAME)
|
else if (event == GameEventPacket::WIN_GAME)
|
||||||
{
|
{
|
||||||
ui.SetWinUserIndex( (BYTE)gameEventPacket->param );
|
ui.SetWinUserIndex( (BYTE)gameEventPacket->param );
|
||||||
|
|
||||||
#ifdef _XBOX
|
#ifdef _XBOX
|
||||||
|
|
||||||
// turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen
|
// turn off the gamertags in splitscreen for the primary player, since they are about to be made fullscreen
|
||||||
|
|
@ -3553,7 +3517,7 @@ void ClientConnection::displayPrivilegeChanges(shared_ptr<MultiplayerLocalPlayer
|
||||||
case Player::ePlayerGamePrivilege_Invulnerable:
|
case Player::ePlayerGamePrivilege_Invulnerable:
|
||||||
if(privOn) message = app.GetString(IDS_PRIV_INVULNERABLE_TOGGLE_ON);
|
if(privOn) message = app.GetString(IDS_PRIV_INVULNERABLE_TOGGLE_ON);
|
||||||
else message = app.GetString(IDS_PRIV_INVULNERABLE_TOGGLE_OFF);
|
else message = app.GetString(IDS_PRIV_INVULNERABLE_TOGGLE_OFF);
|
||||||
break;
|
break;
|
||||||
case Player::ePlayerGamePrivilege_CanToggleInvisible:
|
case Player::ePlayerGamePrivilege_CanToggleInvisible:
|
||||||
if(privOn) message = app.GetString(IDS_PRIV_CAN_INVISIBLE_TOGGLE_ON);
|
if(privOn) message = app.GetString(IDS_PRIV_CAN_INVISIBLE_TOGGLE_ON);
|
||||||
else message = app.GetString(IDS_PRIV_CAN_INVISIBLE_TOGGLE_OFF);
|
else message = app.GetString(IDS_PRIV_CAN_INVISIBLE_TOGGLE_OFF);
|
||||||
|
|
@ -3627,7 +3591,7 @@ void ClientConnection::handleCustomPayload(shared_ptr<CustomPayloadPacket> custo
|
||||||
UIScene_TradingMenu *screen = (UIScene_TradingMenu *)scene;
|
UIScene_TradingMenu *screen = (UIScene_TradingMenu *)scene;
|
||||||
trader = screen->getMerchant();
|
trader = screen->getMerchant();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
MerchantRecipeList *recipeList = MerchantRecipeList::createFromStream(&input);
|
MerchantRecipeList *recipeList = MerchantRecipeList::createFromStream(&input);
|
||||||
trader->overrideOffers(recipeList);
|
trader->overrideOffers(recipeList);
|
||||||
}
|
}
|
||||||
|
|
@ -3714,7 +3678,7 @@ int ClientConnection::HostDisconnectReturned(void *pParam,int iPad,C4JStorage::E
|
||||||
|
|
||||||
DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack();
|
DLCPack *pDLCPack=pDLCTexPack->getDLCInfoParentPack();//tPack->getDLCPack();
|
||||||
if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" ))
|
if(!pDLCPack->hasPurchasedFile( DLCManager::e_DLCType_Texture, L"" ))
|
||||||
{
|
{
|
||||||
// no upsell, we're about to quit
|
// no upsell, we're about to quit
|
||||||
MinecraftServer::getInstance()->setSaveOnExit( false );
|
MinecraftServer::getInstance()->setSaveOnExit( false );
|
||||||
// flag a app action of exit game
|
// flag a app action of exit game
|
||||||
|
|
@ -3768,7 +3732,7 @@ int ClientConnection::HostDisconnectReturned(void *pParam,int iPad,C4JStorage::E
|
||||||
int ClientConnection::ExitGameAndSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
|
int ClientConnection::ExitGameAndSaveReturned(void *pParam,int iPad,C4JStorage::EMessageResult result)
|
||||||
{
|
{
|
||||||
// results switched for this dialog
|
// results switched for this dialog
|
||||||
if(result==C4JStorage::EMessage_ResultDecline)
|
if(result==C4JStorage::EMessage_ResultDecline)
|
||||||
{
|
{
|
||||||
//INT saveOrCheckpointId = 0;
|
//INT saveOrCheckpointId = 0;
|
||||||
//bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId);
|
//bool validSave = StorageManager.GetSaveUniqueNumber(&saveOrCheckpointId);
|
||||||
|
|
@ -3787,7 +3751,7 @@ int ClientConnection::ExitGameAndSaveReturned(void *pParam,int iPad,C4JStorage::
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
wstring ClientConnection::GetDisplayNameByGamertag(wstring gamertag)
|
wstring ClientConnection::GetDisplayNameByGamertag(wstring gamertag)
|
||||||
{
|
{
|
||||||
#ifdef _DURANGO
|
#ifdef _DURANGO
|
||||||
|
|
@ -3932,31 +3896,31 @@ void ClientConnection::handleUpdateAttributes(shared_ptr<UpdateAttributesPacket>
|
||||||
if ( !entity->instanceof(eTYPE_LIVINGENTITY) )
|
if ( !entity->instanceof(eTYPE_LIVINGENTITY) )
|
||||||
{
|
{
|
||||||
// Entity is not a living entity!
|
// Entity is not a living entity!
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseAttributeMap *attributes = (dynamic_pointer_cast<LivingEntity>(entity))->getAttributes();
|
BaseAttributeMap *attributes = (dynamic_pointer_cast<LivingEntity>(entity))->getAttributes();
|
||||||
unordered_set<UpdateAttributesPacket::AttributeSnapshot *> attributeSnapshots = packet->getValues();
|
unordered_set<UpdateAttributesPacket::AttributeSnapshot *> attributeSnapshots = packet->getValues();
|
||||||
for ( UpdateAttributesPacket::AttributeSnapshot *attribute : attributeSnapshots )
|
for (AUTO_VAR(it,attributeSnapshots.begin()); it != attributeSnapshots.end(); ++it)
|
||||||
{
|
{
|
||||||
|
UpdateAttributesPacket::AttributeSnapshot *attribute = *it;
|
||||||
AttributeInstance *instance = attributes->getInstance(attribute->getId());
|
AttributeInstance *instance = attributes->getInstance(attribute->getId());
|
||||||
|
|
||||||
if (instance)
|
if (instance == NULL)
|
||||||
{
|
{
|
||||||
// 4J - TODO: revisit, not familiar with the attribute system, why are we passing in MIN_NORMAL (Java's smallest non-zero value conforming to IEEE Standard 754 (?)) and MAX_VALUE
|
// 4J - TODO: revisit, not familiar with the attribute system, why are we passing in MIN_NORMAL (Java's smallest non-zero value conforming to IEEE Standard 754 (?)) and MAX_VALUE
|
||||||
instance = attributes->registerAttribute(new RangedAttribute(attribute->getId(), 0, Double::MIN_NORMAL, Double::MAX_VALUE));
|
instance = attributes->registerAttribute(new RangedAttribute(attribute->getId(), 0, Double::MIN_NORMAL, Double::MAX_VALUE));
|
||||||
instance->setBaseValue(attribute->getBase());
|
}
|
||||||
instance->removeModifiers();
|
|
||||||
|
|
||||||
unordered_set<AttributeModifier *> *modifiers = attribute->getModifiers();
|
|
||||||
|
|
||||||
if ( modifiers )
|
instance->setBaseValue(attribute->getBase());
|
||||||
{
|
instance->removeModifiers();
|
||||||
for ( AttributeModifier* modifier : *modifiers )
|
|
||||||
{
|
unordered_set<AttributeModifier *> *modifiers = attribute->getModifiers();
|
||||||
instance->addModifier(new AttributeModifier(modifier->getId(), modifier->getAmount(), modifier->getOperation()));
|
|
||||||
}
|
for (AUTO_VAR(it2,modifiers->begin()); it2 != modifiers->end(); ++it2)
|
||||||
}
|
{
|
||||||
|
AttributeModifier* modifier = *it2;
|
||||||
|
instance->addModifier(new AttributeModifier(modifier->getId(), modifier->getAmount(), modifier->getOperation() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue