optimized gameuuid handling

This commit is contained in:
Matthew Toro 2026-04-04 02:17:59 -04:00
parent 6169b133ec
commit 692a1ffc8e
13 changed files with 61 additions and 45 deletions

View file

@ -877,6 +877,7 @@ void ClientConnection::handleAddPlayer(shared_ptr<AddPlayerPacket> packet)
player->yRotp = packet->yRot;
player->yHeadRot = packet->yHeadRot * 360 / 256.0f;
player->setXuid(packet->xuid);
player->setGameUUID(packet->gameUuid);
#ifdef _DURANGO
// On Durango request player display name from network manager

View file

@ -371,7 +371,10 @@ namespace ServerRuntime
}
auto whitelistManager = std::make_shared<WhitelistManager>(*current);
const WhitelistedPlayerEntry entry = { formatted, name, metadata };
WhitelistedPlayerEntry entry;
entry.xuid = formatted;
entry.name = name;
entry.metadata = metadata;
if (!whitelistManager->AddPlayer(entry))
{
return false;

View file

@ -199,6 +199,7 @@ namespace ServerRuntime
}
AccessStorageUtils::TryGetStringField(object, "name", &entry.name);
AccessStorageUtils::TryGetStringField(object, "uuid", &entry.uuid);
AccessStorageUtils::TryGetStringField(object, "created", &entry.metadata.created);
AccessStorageUtils::TryGetStringField(object, "source", &entry.metadata.source);
AccessStorageUtils::TryGetStringField(object, "expires", &entry.metadata.expires);
@ -302,6 +303,8 @@ namespace ServerRuntime
{
OrderedJson object = OrderedJson::object();
object["xuid"] = AccessStorageUtils::NormalizeXuid(entry.xuid);
if (!entry.uuid.empty())
object["uuid"] = entry.uuid;
object["name"] = entry.name;
object["created"] = entry.metadata.created;
object["source"] = entry.metadata.source;

View file

@ -22,6 +22,7 @@ namespace ServerRuntime
struct BannedPlayerEntry
{
std::string xuid;
std::string uuid;
std::string name;
BanMetadata metadata;
};

View file

@ -117,6 +117,7 @@ namespace ServerRuntime
}
AccessStorageUtils::TryGetStringField(object, "name", &entry.name);
AccessStorageUtils::TryGetStringField(object, "uuid", &entry.uuid);
AccessStorageUtils::TryGetStringField(object, "created", &entry.metadata.created);
AccessStorageUtils::TryGetStringField(object, "source", &entry.metadata.source);
NormalizeMetadata(&entry.metadata);
@ -134,6 +135,8 @@ namespace ServerRuntime
{
OrderedJson object = OrderedJson::object();
object["xuid"] = AccessStorageUtils::NormalizeXuid(entry.xuid);
if (!entry.uuid.empty())
object["uuid"] = entry.uuid;
object["name"] = entry.name;
object["created"] = entry.metadata.created;
object["source"] = entry.metadata.source;

View file

@ -16,6 +16,7 @@ namespace ServerRuntime
struct WhitelistedPlayerEntry
{
std::string xuid;
std::string uuid;
std::string name;
WhitelistMetadata metadata;
};

View file

@ -55,6 +55,7 @@ AddPlayerPacket::AddPlayerPacket(shared_ptr<Player> player, PlayerUID xuid, Play
this->xuid = xuid;
this->OnlineXuid = OnlineXuid;
this->gameUuid = player->getGameUUID();
m_playerIndex = static_cast<BYTE>(player->getPlayerIndex());
m_skinId = player->getCustomSkin();
m_capeId = player->getCustomCape();
@ -77,6 +78,8 @@ void AddPlayerPacket::read(DataInputStream *dis) //throws IOException
carriedItem = dis->readShort();
xuid = dis->readPlayerUID();
OnlineXuid = dis->readPlayerUID();
gameUuid.msb = dis->readLong();
gameUuid.lsb = dis->readLong();
m_playerIndex = dis->readByte();
INT skinId = dis->readInt();
m_skinId = *(DWORD *)&skinId;
@ -102,6 +105,8 @@ void AddPlayerPacket::write(DataOutputStream *dos) //throws IOException
dos->writeShort(carriedItem);
dos->writePlayerUID(xuid);
dos->writePlayerUID(OnlineXuid);
dos->writeLong(gameUuid.msb);
dos->writeLong(gameUuid.lsb);
dos->writeByte(m_playerIndex);
dos->writeInt(m_skinId);
dos->writeInt(m_capeId);
@ -117,7 +122,7 @@ void AddPlayerPacket::handle(PacketListener *listener)
int AddPlayerPacket::getEstimatedSize()
{
int iSize= sizeof(int) + Player::MAX_NAME_LENGTH + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(BYTE) + sizeof(BYTE) +sizeof(short) + sizeof(PlayerUID) + sizeof(PlayerUID) + sizeof(int) + sizeof(BYTE) + sizeof(unsigned int) + sizeof(byte);
int iSize= sizeof(int) + Player::MAX_NAME_LENGTH + sizeof(int) + sizeof(int) + sizeof(int) + sizeof(BYTE) + sizeof(BYTE) +sizeof(short) + sizeof(PlayerUID) + sizeof(PlayerUID) + sizeof(GameUUID) + sizeof(int) + sizeof(BYTE) + sizeof(unsigned int) + sizeof(byte);
if( entityData != nullptr )
{

View file

@ -3,6 +3,7 @@ using namespace std;
#include "Packet.h"
#include "SynchedEntityData.h"
#include "UUID.h"
class Player;
@ -21,6 +22,7 @@ public:
int carriedItem;
PlayerUID xuid; // 4J Added
PlayerUID OnlineXuid; // 4J Added
GameUUID gameUuid;
BYTE m_playerIndex; // 4J Added
DWORD m_skinId; // 4J Added
DWORD m_capeId; // 4J Added

View file

@ -111,6 +111,8 @@ void LoginPacket::read(DataInputStream *dis) //throws IOException
maxPlayers = dis->readByte();
m_offlineXuid = dis->readPlayerUID();
m_onlineXuid = dis->readPlayerUID();
m_gameUuid.msb = dis->readLong();
m_gameUuid.lsb = dis->readLong();
m_friendsOnlyUGC = dis->readBoolean();
m_ugcPlayersVersion = dis->readInt();
difficulty = dis->readByte();
@ -150,6 +152,8 @@ void LoginPacket::write(DataOutputStream *dos) //throws IOException
dos->writeByte(maxPlayers);
dos->writePlayerUID(m_offlineXuid);
dos->writePlayerUID(m_onlineXuid);
dos->writeLong(m_gameUuid.msb);
dos->writeLong(m_gameUuid.lsb);
dos->writeBoolean(m_friendsOnlyUGC);
dos->writeInt(m_ugcPlayersVersion);
dos->writeByte(difficulty);

View file

@ -2,6 +2,7 @@
using namespace std;
#include "Packet.h"
#include "UUID.h"
class LevelType;
class LoginPacket : public Packet, public enable_shared_from_this<LoginPacket>
@ -12,6 +13,7 @@ public:
int64_t seed;
char dimension;
PlayerUID m_offlineXuid, m_onlineXuid; // 4J Added
GameUUID m_gameUuid;
char difficulty; // 4J Added
bool m_friendsOnlyUGC; // 4J Added
DWORD m_ugcPlayersVersion; // 4J Added

View file

@ -762,6 +762,8 @@ unsigned int Player::getSkinAnimOverrideBitmask(DWORD skinId)
void Player::setXuid(PlayerUID xuid)
{
m_xuid = xuid;
if (m_gameUuid.isNil() && xuid != INVALID_XUID)
m_gameUuid = GameUUID::fromXuid(xuid);
#ifdef _XBOX_ONE
// 4J Stu - For XboxOne (and probably in the future all other platforms) we store a UUID for the player to use as the owner key for tamed animals
// This should just be a string version of the xuid

View file

@ -8,6 +8,7 @@ using namespace std;
#include "PlayerEnderChestContainer.h"
#include "CommandSender.h"
#include "ScoreHolder.h"
#include "UUID.h"
class AbstractContainerMenu;
class Stats;
@ -417,7 +418,8 @@ public:
PlayerUID getXuid() { return m_xuid; }
void setOnlineXuid(PlayerUID xuid) { m_OnlineXuid = xuid; }
PlayerUID getOnlineXuid() { return m_OnlineXuid; }
void setGameUUID(const GameUUID& uuid) { m_gameUuid = uuid; }
GameUUID getGameUUID() const { return m_gameUuid; }
void setPlayerIndex(DWORD dwIndex) { m_playerIndex = dwIndex; }
DWORD getPlayerIndex() { return m_playerIndex; }
@ -431,6 +433,7 @@ public:
private:
PlayerUID m_xuid;
PlayerUID m_OnlineXuid;
GameUUID m_gameUuid;
protected:
bool m_bShownOnMaps;

View file

@ -2,32 +2,37 @@
#include "UUID.h"
#include "Random.h"
#include <cstring>
static void sha1_block(uint32_t h[5], const uint8_t block[64])
{
uint32_t w[80];
for (int i = 0; i < 16; i++)
w[i] = (block[i * 4] << 24) | (block[i * 4 + 1] << 16) | (block[i * 4 + 2] << 8) | block[i * 4 + 3];
for (int i = 16; i < 80; i++) {
uint32_t x = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
w[i] = (x << 1) | (x >> 31);
}
uint32_t a = h[0], b = h[1], c = h[2], d = h[3], e = h[4];
for (int i = 0; i < 80; i++) {
uint32_t f, k;
if (i < 20) { f = (b & c) | (~b & d); k = 0x5A827999; }
else if (i < 40) { f = b ^ c ^ d; k = 0x6ED9EBA1; }
else if (i < 60) { f = (b & c) | (b & d) | (c & d); k = 0x8F1BBCDC; }
else { f = b ^ c ^ d; k = 0xCA62C1D6; }
uint32_t tmp = ((a << 5) | (a >> 27)) + f + e + k + w[i];
e = d; d = c; c = (b << 30) | (b >> 2); b = a; a = tmp;
}
h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e;
}
static void sha1(const uint8_t* data, size_t len, uint8_t out[20])
{
uint32_t h[5] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };
uint64_t bitLen = len * 8;
size_t fullBlocks = len / 64;
for (size_t blk = 0; blk < fullBlocks; blk++) {
const uint8_t* p = data + blk * 64;
uint32_t w[80];
for (int i = 0; i < 16; i++)
w[i] = (p[i * 4] << 24) | (p[i * 4 + 1] << 16) | (p[i * 4 + 2] << 8) | p[i * 4 + 3];
for (int i = 16; i < 80; i++) {
uint32_t x = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
w[i] = (x << 1) | (x >> 31);
}
uint32_t a = h[0], b = h[1], c = h[2], d = h[3], e = h[4];
for (int i = 0; i < 80; i++) {
uint32_t f, k;
if (i < 20) { f = (b & c) | (~b & d); k = 0x5A827999; }
else if (i < 40) { f = b ^ c ^ d; k = 0x6ED9EBA1; }
else if (i < 60) { f = (b & c) | (b & d) | (c & d); k = 0x8F1BBCDC; }
else { f = b ^ c ^ d; k = 0xCA62C1D6; }
uint32_t tmp = ((a << 5) | (a >> 27)) + f + e + k + w[i];
e = d; d = c; c = (b << 30) | (b >> 2); b = a; a = tmp;
}
h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e;
}
for (size_t blk = 0; blk < fullBlocks; blk++)
sha1_block(h, data + blk * 64);
uint8_t tail[128] = {};
size_t rem = len - fullBlocks * 64;
if (rem) memcpy(tail, data + fullBlocks * 64, rem);
@ -36,27 +41,8 @@ static void sha1(const uint8_t* data, size_t len, uint8_t out[20])
for (int i = 0; i < 8; i++)
tail[tailLen - 1 - i] = (uint8_t)(bitLen >> (i * 8));
for (size_t off = 0; off < tailLen; off += 64) {
uint32_t w[80];
for (int i = 0; i < 16; i++)
w[i] = (tail[off + i * 4] << 24) | (tail[off + i * 4 + 1] << 16) |
(tail[off + i * 4 + 2] << 8) | tail[off + i * 4 + 3];
for (int i = 16; i < 80; i++) {
uint32_t x = w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16];
w[i] = (x << 1) | (x >> 31);
}
uint32_t a = h[0], b = h[1], c = h[2], d = h[3], e = h[4];
for (int i = 0; i < 80; i++) {
uint32_t f, k;
if (i < 20) { f = (b & c) | (~b & d); k = 0x5A827999; }
else if (i < 40) { f = b ^ c ^ d; k = 0x6ED9EBA1; }
else if (i < 60) { f = (b & c) | (b & d) | (c & d); k = 0x8F1BBCDC; }
else { f = b ^ c ^ d; k = 0xCA62C1D6; }
uint32_t tmp = ((a << 5) | (a >> 27)) + f + e + k + w[i];
e = d; d = c; c = (b << 30) | (b >> 2); b = a; a = tmp;
}
h[0] += a; h[1] += b; h[2] += c; h[3] += d; h[4] += e;
}
for (size_t off = 0; off < tailLen; off += 64)
sha1_block(h, tail + off);
for (int i = 0; i < 5; i++) {
out[i * 4] = (uint8_t)(h[i] >> 24);