mirror of
https://github.com/neoStudiosLCE/neoLegacy.git
synced 2026-06-09 02:02:59 +00:00
feat: festive DLCs
This commit is contained in:
parent
128a862b92
commit
7cc9ae857a
454
1429.patch
454
1429.patch
|
|
@ -1,454 +0,0 @@
|
|||
From 00d1d23cca2d407a26d7c9fd4b4e257d7b200bda Mon Sep 17 00:00:00 2001
|
||||
From: itsRevela <rexmarek@gmail.com>
|
||||
Date: Thu, 26 Mar 2026 22:25:40 -0500
|
||||
Subject: [PATCH 1/3] Fix player list not showing all players on dedicated
|
||||
servers
|
||||
|
||||
Register remote players in the client's IQNet array when their
|
||||
AddPlayerPacket arrives, so they appear in the Tab player list.
|
||||
Previously only the host and local player were registered.
|
||||
|
||||
Also filter the dedicated server's phantom host entry (slot 0, empty
|
||||
gamertag) from the UI, fix tick() to update entries by smallId instead
|
||||
of sequential index, and fix player removal to use gamertag matching
|
||||
since XUIDs are 0 on dedicated servers.
|
||||
---
|
||||
Minecraft.Client/ClientConnection.cpp | 45 +++++++++++++++----
|
||||
.../Common/UI/UIScene_InGameInfoMenu.cpp | 39 ++++++++++++----
|
||||
2 files changed, 67 insertions(+), 17 deletions(-)
|
||||
|
||||
diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp
|
||||
index a80af5d2c9..df2ee62736 100644
|
||||
--- a/Minecraft.Client/ClientConnection.cpp
|
||||
+++ b/Minecraft.Client/ClientConnection.cpp
|
||||
@@ -917,6 +917,36 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
|
||||
}
|
||||
}
|
||||
|
||||
+ // Client-side registration: if we still have no IQNet entry for this remote
|
||||
+ // player, create one so they appear in the Tab player list.
|
||||
+ // Find the first available IQNet slot (customData == 0, skip slot 0 which
|
||||
+ // is the host). We can't use packet->m_playerIndex directly because on
|
||||
+ // dedicated servers the game-level player index starts at 0 for real
|
||||
+ // players, conflicting with the IQNet host slot.
|
||||
+ if (matchedQNetPlayer == nullptr)
|
||||
+ {
|
||||
+ for (int s = 1; s < MINECRAFT_NET_MAX_PLAYERS; ++s)
|
||||
+ {
|
||||
+ IQNetPlayer* qp = &IQNet::m_player[s];
|
||||
+ if (qp->GetCustomDataValue() == 0 && qp->m_gamertag[0] == 0)
|
||||
+ {
|
||||
+ BYTE smallId = static_cast<BYTE>(s);
|
||||
+ qp->m_smallId = smallId;
|
||||
+ qp->m_isRemote = true;
|
||||
+ qp->m_isHostPlayer = false;
|
||||
+ qp->m_resolvedXuid = pktXuid;
|
||||
+ wcsncpy_s(qp->m_gamertag, 32, packet->name.c_str(), _TRUNCATE);
|
||||
+ if (smallId >= IQNet::s_playerCount)
|
||||
+ IQNet::s_playerCount = smallId + 1;
|
||||
+
|
||||
+ extern CPlatformNetworkManagerStub* g_pPlatformNetworkManager;
|
||||
+ g_pPlatformNetworkManager->NotifyPlayerJoined(qp);
|
||||
+ matchedQNetPlayer = qp;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (matchedQNetPlayer != nullptr)
|
||||
{
|
||||
// Store packet-authoritative XUID on this network slot so later lookups by XUID
|
||||
@@ -1088,28 +1118,27 @@ void ClientConnection::handleRemoveEntity(shared_ptr<RemoveEntitiesPacket> packe
|
||||
for (int i = 0; i < packet->ids.length; i++)
|
||||
{
|
||||
shared_ptr<Entity> entity = getEntity(packet->ids[i]);
|
||||
- if (entity != nullptr && entity->GetType() == eTYPE_PLAYER)
|
||||
+ if (entity != nullptr)
|
||||
{
|
||||
shared_ptr<Player> player = dynamic_pointer_cast<Player>(entity);
|
||||
if (player != nullptr)
|
||||
{
|
||||
- PlayerUID xuid = player->getXuid();
|
||||
- INetworkPlayer* np = g_NetworkManager.GetPlayerByXuid(xuid);
|
||||
- if (np != nullptr)
|
||||
+ // Match by gamertag in the IQNet array (XUID may be 0 on dedicated servers)
|
||||
+ for (int s = 1; s < MINECRAFT_NET_MAX_PLAYERS; ++s)
|
||||
{
|
||||
- NetworkPlayerXbox* npx = (NetworkPlayerXbox*)np;
|
||||
- IQNetPlayer* qp = npx->GetQNetPlayer();
|
||||
- if (qp != nullptr)
|
||||
+ IQNetPlayer* qp = &IQNet::m_player[s];
|
||||
+ if (qp->GetCustomDataValue() != 0 &&
|
||||
+ _wcsicmp(qp->m_gamertag, player->getName().c_str()) == 0)
|
||||
{
|
||||
extern CPlatformNetworkManagerStub* g_pPlatformNetworkManager;
|
||||
g_pPlatformNetworkManager->NotifyPlayerLeaving(qp);
|
||||
qp->m_smallId = 0;
|
||||
qp->m_isRemote = 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->SetCustomDataValue(0);
|
||||
+ break;
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp b/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp
|
||||
index 338d1905cd..b8e1844456 100644
|
||||
--- a/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp
|
||||
+++ b/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp
|
||||
@@ -27,8 +27,15 @@ UIScene_InGameInfoMenu::UIScene_InGameInfoMenu(int iPad, void *initData, UILayer
|
||||
{
|
||||
PlayerInfo *info = BuildPlayerInfo(player);
|
||||
|
||||
+ // Skip the dedicated server's phantom host entry (slot 0, empty name)
|
||||
+ if (info->m_smallId == 0 && info->m_name.empty())
|
||||
+ {
|
||||
+ delete info;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
m_players.push_back(info);
|
||||
- m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus);
|
||||
+ m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,8 +181,15 @@ void UIScene_InGameInfoMenu::handleReload()
|
||||
{
|
||||
PlayerInfo *info = BuildPlayerInfo(player);
|
||||
|
||||
+ // Skip the dedicated server's phantom host entry (slot 0, empty name)
|
||||
+ if (info->m_smallId == 0 && info->m_name.empty())
|
||||
+ {
|
||||
+ delete info;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
m_players.push_back(info);
|
||||
- m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus);
|
||||
+ m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,23 +216,22 @@ void UIScene_InGameInfoMenu::tick()
|
||||
{
|
||||
UIScene::tick();
|
||||
|
||||
- // Update players by index
|
||||
+ // Update players by their stored smallId (not sequential index, which can mismatch
|
||||
+ // when entries like the dedicated server host are filtered from the UI list)
|
||||
for(DWORD i = 0; i < m_players.size(); ++i)
|
||||
{
|
||||
- INetworkPlayer *player = g_NetworkManager.GetPlayerByIndex( i );
|
||||
+ INetworkPlayer *player = g_NetworkManager.GetPlayerBySmallId( m_players[i]->m_smallId );
|
||||
|
||||
if(player != nullptr)
|
||||
{
|
||||
PlayerInfo *info = BuildPlayerInfo(player);
|
||||
|
||||
- m_players[i]->m_smallId = info->m_smallId;
|
||||
-
|
||||
if(info->m_voiceStatus != m_players[i]->m_voiceStatus)
|
||||
{
|
||||
m_players[i]->m_voiceStatus = info->m_voiceStatus;
|
||||
m_playerList.setVOIPIcon(i, info->m_voiceStatus);
|
||||
}
|
||||
-
|
||||
+
|
||||
if(info->m_colorState != m_players[i]->m_colorState)
|
||||
{
|
||||
m_players[i]->m_colorState = info->m_colorState;
|
||||
@@ -424,11 +437,19 @@ void UIScene_InGameInfoMenu::OnPlayerChanged(void *callbackParam, INetworkPlayer
|
||||
// If the player is joining
|
||||
if(!leaving)
|
||||
{
|
||||
+ PlayerInfo *info = scene->BuildPlayerInfo(pPlayer);
|
||||
+
|
||||
+ // Skip the dedicated server's phantom host entry (slot 0, empty name)
|
||||
+ if (pPlayer->GetSmallId() == 0 && info->m_name.empty())
|
||||
+ {
|
||||
+ delete info;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
app.DebugPrintf("<UIScene_InGameInfoMenu::OnPlayerChanged> Player \"%ls\" not found, adding\n", pPlayer->GetOnlineName());
|
||||
|
||||
- PlayerInfo *info = scene->BuildPlayerInfo(pPlayer);
|
||||
scene->m_players.push_back(info);
|
||||
-
|
||||
+
|
||||
// Note that the tick updates buttons every tick so it's only really important that we
|
||||
// add the button (not the order or content)
|
||||
scene->m_playerList.addItem(info->m_name, info->m_colorState, info->m_voiceStatus);
|
||||
|
||||
From 75eb646becfbae8090f76b44dd690b88194a4ce6 Mon Sep 17 00:00:00 2001
|
||||
From: itsRevela <rexmarek@gmail.com>
|
||||
Date: Thu, 26 Mar 2026 22:25:58 -0500
|
||||
Subject: [PATCH 2/3] Fix player list map icon colors to match map markers
|
||||
|
||||
The tab player list and teleport menu now show the correct map marker
|
||||
color for each player. The icon is computed using the same hash as the
|
||||
map renderer (getRandomPlayerMapIcon) and stored by player name,
|
||||
bypassing the unreliable small-ID lookup that produced wrong colors
|
||||
on dedicated servers.
|
||||
---
|
||||
Minecraft.Client/ClientConnection.cpp | 27 +++++++++++++++
|
||||
Minecraft.Client/Common/Consoles_App.cpp | 34 +++++++++++++++++++
|
||||
Minecraft.Client/Common/Consoles_App.h | 4 +++
|
||||
.../Common/UI/UIScene_InGameInfoMenu.cpp | 2 +-
|
||||
.../Common/UI/UIScene_TeleportMenu.cpp | 4 +--
|
||||
5 files changed, 68 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Minecraft.Client/ClientConnection.cpp b/Minecraft.Client/ClientConnection.cpp
|
||||
index df2ee62736..7116f311cf 100644
|
||||
--- a/Minecraft.Client/ClientConnection.cpp
|
||||
+++ b/Minecraft.Client/ClientConnection.cpp
|
||||
@@ -66,6 +66,30 @@
|
||||
#include "..\Minecraft.World\GenericStats.h"
|
||||
#endif
|
||||
|
||||
+namespace
|
||||
+{
|
||||
+ char mapIconToFrame(char iconSlot)
|
||||
+ {
|
||||
+ if (iconSlot >= 8) return iconSlot - 4;
|
||||
+ return iconSlot;
|
||||
+ }
|
||||
+
|
||||
+ // Same hash as getRandomPlayerMapIcon in MapItemSavedData.cpp, returning
|
||||
+ // the Iggy/SWF frame index (0-7) instead of the raw icon slot.
|
||||
+ char computePlayerMapFrame(int entityId, int playerIndex)
|
||||
+ {
|
||||
+ static const char PLAYER_MAP_ICON_SLOTS[] = { 0, 1, 2, 3, 8, 9, 10, 11 };
|
||||
+ unsigned int seed = static_cast<unsigned int>(entityId);
|
||||
+ seed ^= static_cast<unsigned int>(playerIndex * 0x9E3779B9u);
|
||||
+ seed ^= (seed >> 16);
|
||||
+ seed *= 0x7FEB352Du;
|
||||
+ seed ^= (seed >> 15);
|
||||
+ seed *= 0x846CA68Bu;
|
||||
+ seed ^= (seed >> 16);
|
||||
+ return mapIconToFrame(PLAYER_MAP_ICON_SLOTS[seed % 8]);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
ClientConnection::ClientConnection(Minecraft *minecraft, const wstring& ip, int port)
|
||||
{
|
||||
// 4J Stu - No longer used as we use the socket version below.
|
||||
@@ -377,6 +401,7 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||
|
||||
BYTE networkSmallId = getSocket()->getSmallId();
|
||||
app.UpdatePlayerInfo(networkSmallId, packet->m_playerIndex, packet->m_uiGamePrivileges);
|
||||
+ app.SetPlayerMapIcon(minecraft->player->getName().c_str(), computePlayerMapFrame(packet->clientVersion, packet->m_playerIndex));
|
||||
minecraft->player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges);
|
||||
|
||||
// Assume all privileges are on, so that the first message we see only indicates things that have been turned off
|
||||
@@ -447,6 +472,7 @@ void ClientConnection::handleLogin(shared_ptr<LoginPacket> packet)
|
||||
|
||||
BYTE networkSmallId = getSocket()->getSmallId();
|
||||
app.UpdatePlayerInfo(networkSmallId, packet->m_playerIndex, packet->m_uiGamePrivileges);
|
||||
+ app.SetPlayerMapIcon(player->getName().c_str(), computePlayerMapFrame(packet->clientVersion, packet->m_playerIndex));
|
||||
player->setPlayerGamePrivilege(Player::ePlayerGamePrivilege_All, packet->m_uiGamePrivileges);
|
||||
|
||||
// Assume all privileges are on, so that the first message we see only indicates things that have been turned off
|
||||
@@ -976,6 +1002,7 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
|
||||
player->setPlayerIndex( packet->m_playerIndex );
|
||||
player->setCustomSkin( packet->m_skinId );
|
||||
player->setCustomCape( packet->m_capeId );
|
||||
+ app.SetPlayerMapIcon(packet->name.c_str(), computePlayerMapFrame(packet->id, packet->m_playerIndex));
|
||||
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))
|
||||
diff --git a/Minecraft.Client/Common/Consoles_App.cpp b/Minecraft.Client/Common/Consoles_App.cpp
|
||||
index 0a2fd159a4..c98837890d 100644
|
||||
--- a/Minecraft.Client/Common/Consoles_App.cpp
|
||||
+++ b/Minecraft.Client/Common/Consoles_App.cpp
|
||||
@@ -187,6 +187,7 @@ CMinecraftApp::CMinecraftApp()
|
||||
#endif
|
||||
|
||||
ZeroMemory(m_playerColours,MINECRAFT_NET_MAX_PLAYERS);
|
||||
+ ZeroMemory(m_playerMapIcons,MINECRAFT_NET_MAX_PLAYERS);
|
||||
|
||||
m_iDLCOfferC=0;
|
||||
m_bAllDLCContentRetrieved=true;
|
||||
@@ -8463,6 +8464,39 @@ short CMinecraftApp::GetPlayerColour(BYTE networkSmallId)
|
||||
return index;
|
||||
}
|
||||
|
||||
+void CMinecraftApp::SetPlayerMapIcon(const wchar_t* name, char icon)
|
||||
+{
|
||||
+ if (name == nullptr) return;
|
||||
+ // Update existing entry or use first empty slot
|
||||
+ int emptySlot = -1;
|
||||
+ for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
|
||||
+ {
|
||||
+ if (m_playerMapIcons[i].name[0] != 0 && _wcsicmp(m_playerMapIcons[i].name, name) == 0)
|
||||
+ {
|
||||
+ m_playerMapIcons[i].icon = icon;
|
||||
+ return;
|
||||
+ }
|
||||
+ if (emptySlot < 0 && m_playerMapIcons[i].name[0] == 0)
|
||||
+ emptySlot = i;
|
||||
+ }
|
||||
+ if (emptySlot >= 0)
|
||||
+ {
|
||||
+ wcsncpy_s(m_playerMapIcons[emptySlot].name, 32, name, _TRUNCATE);
|
||||
+ m_playerMapIcons[emptySlot].icon = icon;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+char CMinecraftApp::GetPlayerMapIconByName(const wchar_t* name)
|
||||
+{
|
||||
+ if (name == nullptr) return 0;
|
||||
+ for (int i = 0; i < MINECRAFT_NET_MAX_PLAYERS; ++i)
|
||||
+ {
|
||||
+ if (m_playerMapIcons[i].name[0] != 0 && _wcsicmp(m_playerMapIcons[i].name, name) == 0)
|
||||
+ return m_playerMapIcons[i].icon;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
|
||||
unsigned int CMinecraftApp::GetPlayerPrivileges(BYTE networkSmallId)
|
||||
{
|
||||
diff --git a/Minecraft.Client/Common/Consoles_App.h b/Minecraft.Client/Common/Consoles_App.h
|
||||
index 0c1c261efd..ff7aa8e88d 100644
|
||||
--- a/Minecraft.Client/Common/Consoles_App.h
|
||||
+++ b/Minecraft.Client/Common/Consoles_App.h
|
||||
@@ -747,10 +747,14 @@ class CMinecraftApp
|
||||
private:
|
||||
BYTE m_playerColours[MINECRAFT_NET_MAX_PLAYERS]; // An array of QNet small-id's
|
||||
unsigned int m_playerGamePrivileges[MINECRAFT_NET_MAX_PLAYERS];
|
||||
+ struct PlayerMapIconEntry { wchar_t name[32]; char icon; };
|
||||
+ PlayerMapIconEntry m_playerMapIcons[MINECRAFT_NET_MAX_PLAYERS];
|
||||
|
||||
public:
|
||||
void UpdatePlayerInfo(BYTE networkSmallId, SHORT playerColourIndex, unsigned int playerGamePrivileges);
|
||||
short GetPlayerColour(BYTE networkSmallId);
|
||||
+ void SetPlayerMapIcon(const wchar_t* name, char icon);
|
||||
+ char GetPlayerMapIconByName(const wchar_t* name);
|
||||
unsigned int GetPlayerPrivileges(BYTE networkSmallId);
|
||||
|
||||
wstring getEntityName(eINSTANCEOF type);
|
||||
diff --git a/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp b/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp
|
||||
index b8e1844456..d3a149df59 100644
|
||||
--- a/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp
|
||||
+++ b/Minecraft.Client/Common/UI/UIScene_InGameInfoMenu.cpp
|
||||
@@ -512,7 +512,7 @@ UIScene_InGameInfoMenu::PlayerInfo *UIScene_InGameInfoMenu::BuildPlayerInfo(INet
|
||||
}
|
||||
|
||||
info->m_voiceStatus = voiceStatus;
|
||||
- info->m_colorState = app.GetPlayerColour(info->m_smallId);
|
||||
+ info->m_colorState = app.GetPlayerMapIconByName(player->GetOnlineName());
|
||||
info->m_name = playerName;
|
||||
|
||||
return info;
|
||||
diff --git a/Minecraft.Client/Common/UI/UIScene_TeleportMenu.cpp b/Minecraft.Client/Common/UI/UIScene_TeleportMenu.cpp
|
||||
index 017af93ef6..d8390d3734 100644
|
||||
--- a/Minecraft.Client/Common/UI/UIScene_TeleportMenu.cpp
|
||||
+++ b/Minecraft.Client/Common/UI/UIScene_TeleportMenu.cpp
|
||||
@@ -193,12 +193,12 @@ void UIScene_TeleportMenu::tick()
|
||||
{
|
||||
m_players[i] = player->GetSmallId();
|
||||
|
||||
- short icon = app.GetPlayerColour( m_players[i] );
|
||||
+ short icon = static_cast<short>(app.GetPlayerMapIconByName(player->GetOnlineName()));
|
||||
|
||||
if(icon != m_playersColourState[i])
|
||||
{
|
||||
m_playersColourState[i] = icon;
|
||||
- m_playerList.setPlayerIcon( i, (int)app.GetPlayerColour( m_players[i] ) );
|
||||
+ m_playerList.setPlayerIcon( i, (int)icon );
|
||||
}
|
||||
|
||||
wstring playerName = L"";
|
||||
|
||||
From 898d4352a3eedb9788d20f8ec03fcbfa0b192f6b Mon Sep 17 00:00:00 2001
|
||||
From: itsRevela <rexmarek@gmail.com>
|
||||
Date: Thu, 26 Mar 2026 23:54:51 -0500
|
||||
Subject: [PATCH 3/3] Send AddPlayerPacket for all players on join and
|
||||
RemoveEntitiesPacket on disconnect
|
||||
|
||||
Players now appear in each other's Tab list immediately on join,
|
||||
regardless of render distance. Previously, players only appeared when
|
||||
they entered entity tracking range because AddPlayerPacket was only
|
||||
sent through the TrackedEntity system.
|
||||
|
||||
On disconnect, a RemoveEntitiesPacket is broadcast to all clients so
|
||||
players added via the join broadcast are properly cleaned up, not just
|
||||
those within tracking range.
|
||||
---
|
||||
Minecraft.Client/PlayerList.cpp | 52 +++++++++++++++++++++++++++++++++
|
||||
1 file changed, 52 insertions(+)
|
||||
|
||||
diff --git a/Minecraft.Client/PlayerList.cpp b/Minecraft.Client/PlayerList.cpp
|
||||
index ba82ec6acd..8a6b531a57 100644
|
||||
--- a/Minecraft.Client/PlayerList.cpp
|
||||
+++ b/Minecraft.Client/PlayerList.cpp
|
||||
@@ -496,6 +496,50 @@ void PlayerList::add(shared_ptr<ServerPlayer> player)
|
||||
}
|
||||
}
|
||||
|
||||
+ // Send AddPlayerPackets so all players appear in each other's Tab list
|
||||
+ // regardless of render distance. The entity tracking system will send
|
||||
+ // another AddPlayerPacket when they enter range, which is handled
|
||||
+ // gracefully by putEntity replacing the old entity.
|
||||
+ {
|
||||
+ PlayerUID xuid = INVALID_XUID;
|
||||
+ PlayerUID onlineXuid = INVALID_XUID;
|
||||
+#ifndef MINECRAFT_SERVER_BUILD
|
||||
+ xuid = player->getXuid();
|
||||
+ onlineXuid = player->getOnlineXuid();
|
||||
+#endif
|
||||
+ int xp = Mth::floor(player->x * 32.0);
|
||||
+ int yp = Mth::floor(player->y * 32.0);
|
||||
+ int zp = Mth::floor(player->z * 32.0);
|
||||
+ int yRotp = Mth::floor(player->yRot * 256.0f / 360.0f);
|
||||
+ int xRotp = Mth::floor(player->xRot * 256.0f / 360.0f);
|
||||
+ int yHeadRotp = Mth::floor(player->yHeadRot * 256.0f / 360.0f);
|
||||
+
|
||||
+ // Broadcast the new player to all existing players
|
||||
+ broadcastAll(std::make_shared<AddPlayerPacket>(player, xuid, onlineXuid, xp, yp, zp, yRotp, xRotp, yHeadRotp));
|
||||
+
|
||||
+ // Send all existing players to the new player
|
||||
+ for (size_t i = 0; i < players.size(); i++)
|
||||
+ {
|
||||
+ shared_ptr<ServerPlayer> op = players.at(i);
|
||||
+ if (op != player && op->connection->getNetworkPlayer())
|
||||
+ {
|
||||
+ PlayerUID opXuid = INVALID_XUID;
|
||||
+ PlayerUID opOnlineXuid = INVALID_XUID;
|
||||
+#ifndef MINECRAFT_SERVER_BUILD
|
||||
+ opXuid = op->getXuid();
|
||||
+ opOnlineXuid = op->getOnlineXuid();
|
||||
+#endif
|
||||
+ int oxp = Mth::floor(op->x * 32.0);
|
||||
+ int oyp = Mth::floor(op->y * 32.0);
|
||||
+ int ozp = Mth::floor(op->z * 32.0);
|
||||
+ int oyRotp = Mth::floor(op->yRot * 256.0f / 360.0f);
|
||||
+ int oxRotp = Mth::floor(op->xRot * 256.0f / 360.0f);
|
||||
+ int oyHeadRotp = Mth::floor(op->yHeadRot * 256.0f / 360.0f);
|
||||
+ player->connection->send(std::make_shared<AddPlayerPacket>(op, opXuid, opOnlineXuid, oxp, oyp, ozp, oyRotp, oxRotp, oyHeadRotp));
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if(level->isAtLeastOnePlayerSleeping())
|
||||
{
|
||||
shared_ptr<ServerPlayer> firstSleepingPlayer = nullptr;
|
||||
@@ -528,6 +572,14 @@ if (player->riding != nullptr)
|
||||
level->removeEntityImmediately(player->riding);
|
||||
app.DebugPrintf("removing player mount");
|
||||
}
|
||||
+ // Notify all clients to remove this player entity, not just those who
|
||||
+ // had the player in tracking range. This ensures players added to the
|
||||
+ // Tab list via the AddPlayerPacket broadcast are properly cleaned up.
|
||||
+ {
|
||||
+ intArray ids(1);
|
||||
+ ids[0] = player->entityId;
|
||||
+ broadcastAll(std::make_shared<RemoveEntitiesPacket>(ids));
|
||||
+ }
|
||||
level->getTracker()->removeEntity(player);
|
||||
level->removeEntity(player);
|
||||
level->getChunkMap()->remove(player);
|
||||
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/Festive.mcs
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/Festive.mcs
Normal file
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/GameRules.grf
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/GameRules.grf
Normal file
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/flake.ogg
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/flake.ogg
Normal file
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/kyoto.ogg
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/kyoto.ogg
Normal file
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/media.arc
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/media.arc
Normal file
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/nether3xmas.ogg
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/nether3xmas.ogg
Normal file
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/nether4xmas.ogg
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/nether4xmas.ogg
Normal file
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/x16Data.pck
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/Data/x16Data.pck
Normal file
Binary file not shown.
Binary file not shown.
BIN
Minecraft.Client/Windows64Media/DLC/Festive/TexturePack.pck
Normal file
BIN
Minecraft.Client/Windows64Media/DLC/Festive/TexturePack.pck
Normal file
Binary file not shown.
Loading…
Reference in a new issue