Some tweaks to anchor (#6166)

This commit is contained in:
Garrett Cox
2026-01-18 22:38:48 -06:00
committed by GitHub
parent a2245f7a47
commit d7981bf03f
5 changed files with 87 additions and 85 deletions

View File

@@ -93,8 +93,8 @@ void Anchor::OnIncomingJson(nlohmann::json payload) {
std::string packetType = payload["type"].get<std::string>(); std::string packetType = payload["type"].get<std::string>();
// Ignore packets from mismatched clients, except for ALL_CLIENT_STATE or UPDATE_CLIENT_STATE // Ignore packets from mismatched clients, except for ALL_CLIENT_STATE, UPDATE_CLIENT_STATE, and PLAYER_UPDATE
if (packetType != ALL_CLIENT_STATE && packetType != UPDATE_CLIENT_STATE) { if (packetType != ALL_CLIENT_STATE && packetType != UPDATE_CLIENT_STATE && packetType != PLAYER_UPDATE) {
if (payload.contains("clientId")) { if (payload.contains("clientId")) {
uint32_t clientId = payload["clientId"].get<uint32_t>(); uint32_t clientId = payload["clientId"].get<uint32_t>();
if (clients.contains(clientId) && clients[clientId].clientVersion != clientVersion) { if (clients.contains(clientId) && clients[clientId].clientVersion != clientVersion) {
@@ -103,12 +103,6 @@ void Anchor::OnIncomingJson(nlohmann::json payload) {
} }
} }
// Handle PLAYER_UPDATE packets immediately, no need to queue
if (packetType == PLAYER_UPDATE) {
HandlePacket_PlayerUpdate(payload);
return;
}
// Queue all packets to be processed on the game thread // Queue all packets to be processed on the game thread
std::lock_guard<std::mutex> lock(incomingPacketQueueMutex); std::lock_guard<std::mutex> lock(incomingPacketQueueMutex);
incomingPacketQueue.push(payload); incomingPacketQueue.push(payload);
@@ -131,6 +125,7 @@ void Anchor::ProcessIncomingPacketQueue() {
isProcessingIncomingPacket = true; isProcessingIncomingPacket = true;
try {
// packetType here is a string so we can't use a switch statement // packetType here is a string so we can't use a switch statement
if (packetType == ALL_CLIENT_STATE) if (packetType == ALL_CLIENT_STATE)
HandlePacket_AllClientState(payload); HandlePacket_AllClientState(payload);
@@ -146,6 +141,8 @@ void Anchor::ProcessIncomingPacketQueue() {
HandlePacket_GiveItem(payload); HandlePacket_GiveItem(payload);
else if (packetType == OCARINA_SFX) else if (packetType == OCARINA_SFX)
HandlePacket_OcarinaSfx(payload); HandlePacket_OcarinaSfx(payload);
else if (packetType == PLAYER_UPDATE)
HandlePacket_PlayerUpdate(payload);
else if (packetType == PLAYER_SFX) else if (packetType == PLAYER_SFX)
HandlePacket_PlayerSfx(payload); HandlePacket_PlayerSfx(payload);
else if (packetType == UPDATE_TEAM_STATE) else if (packetType == UPDATE_TEAM_STATE)
@@ -172,6 +169,10 @@ void Anchor::ProcessIncomingPacketQueue() {
HandlePacket_UpdateRoomState(payload); HandlePacket_UpdateRoomState(payload);
else if (packetType == UPDATE_DUNGEON_ITEMS) else if (packetType == UPDATE_DUNGEON_ITEMS)
HandlePacket_UpdateDungeonItems(payload); HandlePacket_UpdateDungeonItems(payload);
} catch (const std::exception& e) {
SPDLOG_ERROR("[Anchor] Exception while processing incoming packet {}", e.what());
SPDLOG_ERROR("[Anchor] Packet: {}", payload.dump());
}
isProcessingIncomingPacket = false; isProcessingIncomingPacket = false;
} }

View File

@@ -110,7 +110,7 @@ class Anchor : public Network {
public: public:
uint32_t ownClientId; uint32_t ownClientId;
inline static const std::string clientVersion = (char*)gBuildVersion; inline static const std::string clientVersion = (char*)gGitCommitHash;
// Packet types // // Packet types //
inline static const std::string ALL_CLIENT_STATE = "ALL_CLIENT_STATE"; inline static const std::string ALL_CLIENT_STATE = "ALL_CLIENT_STATE";

View File

@@ -52,18 +52,18 @@ inline void from_json(const json& j, PosRot& posRot) {
} }
inline void from_json(const json& j, AnchorClient& client) { inline void from_json(const json& j, AnchorClient& client) {
j.contains("clientId") ? j.at("clientId").get_to(client.clientId) : client.clientId = 0; client.clientId = j.value("clientId", (u32)0);
j.contains("name") ? j.at("name").get_to(client.name) : client.name = "???"; client.name = j.value("name", "???");
j.contains("color") ? j.at("color").get_to(client.color) : client.color = { 255, 255, 255 }; client.color = j.value("color", Color_RGB8{ 255, 255, 255 });
j.contains("clientVersion") ? j.at("clientVersion").get_to(client.clientVersion) : client.clientVersion = "???"; client.clientVersion = j.value("clientVersion", "???");
j.contains("teamId") ? j.at("teamId").get_to(client.teamId) : client.teamId = "default"; client.teamId = j.value("teamId", "default");
j.contains("online") ? j.at("online").get_to(client.online) : client.online = false; client.online = j.value("online", false);
j.contains("seed") ? j.at("seed").get_to(client.seed) : client.seed = 0; client.seed = j.value("seed", (u32)0);
j.contains("isSaveLoaded") ? j.at("isSaveLoaded").get_to(client.isSaveLoaded) : client.isSaveLoaded = false; client.isSaveLoaded = j.value("isSaveLoaded", false);
j.contains("isGameComplete") ? j.at("isGameComplete").get_to(client.isGameComplete) : client.isGameComplete = false; client.isGameComplete = j.value("isGameComplete", false);
j.contains("sceneNum") ? j.at("sceneNum").get_to(client.sceneNum) : client.sceneNum = SCENE_ID_MAX; client.sceneNum = j.value("sceneNum", (s16)SCENE_ID_MAX);
j.contains("entranceIndex") ? j.at("entranceIndex").get_to(client.entranceIndex) : client.entranceIndex = 0; client.entranceIndex = j.value("entranceIndex", (s32)0);
j.contains("self") ? j.at("self").get_to(client.self) : client.self = false; client.self = j.value("self", false);
} }
inline void to_json(json& j, const Inventory& inventory) { inline void to_json(json& j, const Inventory& inventory) {

View File

@@ -67,5 +67,5 @@ void Anchor::HandlePacket_AllClientState(nlohmann::json payload) {
clients.erase(clientId); clients.erase(clientId);
} }
RefreshClientActors(); shouldRefreshActors = true;
} }

View File

@@ -83,35 +83,36 @@ void Anchor::HandlePacket_PlayerUpdate(nlohmann::json payload) {
if (clients.contains(clientId)) { if (clients.contains(clientId)) {
auto& client = clients[clientId]; auto& client = clients[clientId];
if (client.linkAge != payload["linkAge"].get<s32>()) { if (client.linkAge != payload.value("linkAge", (s32)LINK_AGE_ADULT)) {
shouldRefreshActors = true; shouldRefreshActors = true;
} }
client.sceneNum = payload["sceneNum"].get<s16>(); client.sceneNum = payload.value("sceneNum", (s16)SCENE_ID_MAX);
client.entranceIndex = payload["entranceIndex"].get<s32>(); client.entranceIndex = payload.value("entranceIndex", (s32)0);
client.linkAge = payload["linkAge"].get<s32>(); client.linkAge = payload.value("linkAge", (s32)LINK_AGE_ADULT);
client.posRot = payload["posRot"].get<PosRot>(); client.posRot = payload.value("posRot", PosRot{ 0 });
std::vector<int> jointArray = payload["jointTable"]; std::vector<int> jointArray = payload.value("jointTable", std::vector<int>{});
jointArray.resize(24 * 3); // Ensure it has enough elements, in case of missing data
for (int i = 0; i < 24; i++) { for (int i = 0; i < 24; i++) {
client.jointTable[i].x = jointArray[i * 3]; client.jointTable[i].x = jointArray[i * 3];
client.jointTable[i].y = jointArray[i * 3 + 1]; client.jointTable[i].y = jointArray[i * 3 + 1];
client.jointTable[i].z = jointArray[i * 3 + 2]; client.jointTable[i].z = jointArray[i * 3 + 2];
} }
client.movementFlags = payload["movementFlags"].get<u8>(); client.movementFlags = payload.value("movementFlags", (u8)0);
client.prevTransl = payload["prevTransl"].get<Vec3s>(); client.prevTransl = payload.value("prevTransl", Vec3s{ 0 });
client.upperLimbRot = payload["upperLimbRot"].get<Vec3s>(); client.upperLimbRot = payload.value("upperLimbRot", Vec3s{ 0 });
client.currentBoots = payload["currentBoots"].get<s8>(); client.currentBoots = payload.value("currentBoots", (s8)0);
client.currentShield = payload["currentShield"].get<s8>(); client.currentShield = payload.value("currentShield", (s8)0);
client.currentTunic = payload["currentTunic"].get<s8>(); client.currentTunic = payload.value("currentTunic", (s8)0);
client.stateFlags1 = payload["stateFlags1"].get<u32>(); client.stateFlags1 = payload.value("stateFlags1", (u32)0);
client.stateFlags2 = payload["stateFlags2"].get<u32>(); client.stateFlags2 = payload.value("stateFlags2", (u32)0);
client.buttonItem0 = payload["buttonItem0"].get<u8>(); client.buttonItem0 = payload.value("buttonItem0", (u8)0);
client.itemAction = payload["itemAction"].get<s8>(); client.itemAction = payload.value("itemAction", (s8)0);
client.heldItemAction = payload["heldItemAction"].get<s8>(); client.heldItemAction = payload.value("heldItemAction", (s8)0);
client.modelGroup = payload["modelGroup"].get<u8>(); client.modelGroup = payload.value("modelGroup", (u8)0);
client.invincibilityTimer = payload["invincibilityTimer"].get<s8>(); client.invincibilityTimer = payload.value("invincibilityTimer", (s8)0);
client.unk_862 = payload["unk_862"].get<s16>(); client.unk_862 = payload.value("unk_862", (s16)0);
client.unk_85C = payload["unk_85C"].get<f32>(); client.unk_85C = payload.value("unk_85C", (f32)0);
client.actionVar1 = payload["actionVar1"].get<s8>(); client.actionVar1 = payload.value("actionVar1", (s8)0);
} }
} }