mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-04-27 17:36:26 +00:00
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.
This commit is contained in:
parent
00d1d23cca
commit
75eb646bec
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -747,10 +747,14 @@ public:
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"";
|
||||
|
|
|
|||
Loading…
Reference in a new issue