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
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
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>();
// Ignore packets from mismatched clients, except for ALL_CLIENT_STATE or UPDATE_CLIENT_STATE
if (packetType != ALL_CLIENT_STATE && packetType != 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 && packetType != PLAYER_UPDATE) {
if (payload.contains("clientId")) {
uint32_t clientId = payload["clientId"].get<uint32_t>();
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
std::lock_guard<std::mutex> lock(incomingPacketQueueMutex);
incomingPacketQueue.push(payload);
@ -131,47 +125,54 @@ void Anchor::ProcessIncomingPacketQueue() {
isProcessingIncomingPacket = true;
// packetType here is a string so we can't use a switch statement
if (packetType == ALL_CLIENT_STATE)
HandlePacket_AllClientState(payload);
else if (packetType == DAMAGE_PLAYER)
HandlePacket_DamagePlayer(payload);
else if (packetType == DISABLE_ANCHOR)
HandlePacket_DisableAnchor(payload);
else if (packetType == ENTRANCE_DISCOVERED)
HandlePacket_EntranceDiscovered(payload);
else if (packetType == GAME_COMPLETE)
HandlePacket_GameComplete(payload);
else if (packetType == GIVE_ITEM)
HandlePacket_GiveItem(payload);
else if (packetType == OCARINA_SFX)
HandlePacket_OcarinaSfx(payload);
else if (packetType == PLAYER_SFX)
HandlePacket_PlayerSfx(payload);
else if (packetType == UPDATE_TEAM_STATE)
HandlePacket_UpdateTeamState(payload);
else if (packetType == REQUEST_TEAM_STATE)
HandlePacket_RequestTeamState(payload);
else if (packetType == REQUEST_TELEPORT)
HandlePacket_RequestTeleport(payload);
else if (packetType == SERVER_MESSAGE)
HandlePacket_ServerMessage(payload);
else if (packetType == SET_CHECK_STATUS)
HandlePacket_SetCheckStatus(payload);
else if (packetType == SET_FLAG)
HandlePacket_SetFlag(payload);
else if (packetType == TELEPORT_TO)
HandlePacket_TeleportTo(payload);
else if (packetType == UNSET_FLAG)
HandlePacket_UnsetFlag(payload);
else if (packetType == UPDATE_BEANS_COUNT)
HandlePacket_UpdateBeansCount(payload);
else if (packetType == UPDATE_CLIENT_STATE)
HandlePacket_UpdateClientState(payload);
else if (packetType == UPDATE_ROOM_STATE)
HandlePacket_UpdateRoomState(payload);
else if (packetType == UPDATE_DUNGEON_ITEMS)
HandlePacket_UpdateDungeonItems(payload);
try {
// packetType here is a string so we can't use a switch statement
if (packetType == ALL_CLIENT_STATE)
HandlePacket_AllClientState(payload);
else if (packetType == DAMAGE_PLAYER)
HandlePacket_DamagePlayer(payload);
else if (packetType == DISABLE_ANCHOR)
HandlePacket_DisableAnchor(payload);
else if (packetType == ENTRANCE_DISCOVERED)
HandlePacket_EntranceDiscovered(payload);
else if (packetType == GAME_COMPLETE)
HandlePacket_GameComplete(payload);
else if (packetType == GIVE_ITEM)
HandlePacket_GiveItem(payload);
else if (packetType == OCARINA_SFX)
HandlePacket_OcarinaSfx(payload);
else if (packetType == PLAYER_UPDATE)
HandlePacket_PlayerUpdate(payload);
else if (packetType == PLAYER_SFX)
HandlePacket_PlayerSfx(payload);
else if (packetType == UPDATE_TEAM_STATE)
HandlePacket_UpdateTeamState(payload);
else if (packetType == REQUEST_TEAM_STATE)
HandlePacket_RequestTeamState(payload);
else if (packetType == REQUEST_TELEPORT)
HandlePacket_RequestTeleport(payload);
else if (packetType == SERVER_MESSAGE)
HandlePacket_ServerMessage(payload);
else if (packetType == SET_CHECK_STATUS)
HandlePacket_SetCheckStatus(payload);
else if (packetType == SET_FLAG)
HandlePacket_SetFlag(payload);
else if (packetType == TELEPORT_TO)
HandlePacket_TeleportTo(payload);
else if (packetType == UNSET_FLAG)
HandlePacket_UnsetFlag(payload);
else if (packetType == UPDATE_BEANS_COUNT)
HandlePacket_UpdateBeansCount(payload);
else if (packetType == UPDATE_CLIENT_STATE)
HandlePacket_UpdateClientState(payload);
else if (packetType == UPDATE_ROOM_STATE)
HandlePacket_UpdateRoomState(payload);
else if (packetType == UPDATE_DUNGEON_ITEMS)
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;
}

View file

@ -110,7 +110,7 @@ class Anchor : public Network {
public:
uint32_t ownClientId;
inline static const std::string clientVersion = (char*)gBuildVersion;
inline static const std::string clientVersion = (char*)gGitCommitHash;
// Packet types //
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) {
j.contains("clientId") ? j.at("clientId").get_to(client.clientId) : client.clientId = 0;
j.contains("name") ? j.at("name").get_to(client.name) : client.name = "???";
j.contains("color") ? j.at("color").get_to(client.color) : client.color = { 255, 255, 255 };
j.contains("clientVersion") ? j.at("clientVersion").get_to(client.clientVersion) : client.clientVersion = "???";
j.contains("teamId") ? j.at("teamId").get_to(client.teamId) : client.teamId = "default";
j.contains("online") ? j.at("online").get_to(client.online) : client.online = false;
j.contains("seed") ? j.at("seed").get_to(client.seed) : client.seed = 0;
j.contains("isSaveLoaded") ? j.at("isSaveLoaded").get_to(client.isSaveLoaded) : client.isSaveLoaded = false;
j.contains("isGameComplete") ? j.at("isGameComplete").get_to(client.isGameComplete) : client.isGameComplete = false;
j.contains("sceneNum") ? j.at("sceneNum").get_to(client.sceneNum) : client.sceneNum = SCENE_ID_MAX;
j.contains("entranceIndex") ? j.at("entranceIndex").get_to(client.entranceIndex) : client.entranceIndex = 0;
j.contains("self") ? j.at("self").get_to(client.self) : client.self = false;
client.clientId = j.value("clientId", (u32)0);
client.name = j.value("name", "???");
client.color = j.value("color", Color_RGB8{ 255, 255, 255 });
client.clientVersion = j.value("clientVersion", "???");
client.teamId = j.value("teamId", "default");
client.online = j.value("online", false);
client.seed = j.value("seed", (u32)0);
client.isSaveLoaded = j.value("isSaveLoaded", false);
client.isGameComplete = j.value("isGameComplete", false);
client.sceneNum = j.value("sceneNum", (s16)SCENE_ID_MAX);
client.entranceIndex = j.value("entranceIndex", (s32)0);
client.self = j.value("self", false);
}
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);
}
RefreshClientActors();
shouldRefreshActors = true;
}

View file

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