Back-port fixes from holiday build (#6060)

This commit is contained in:
Garrett Cox
2025-12-31 17:08:30 -06:00
committed by GitHub
parent 8cc02fd235
commit 7ca93e93be
8 changed files with 69 additions and 10 deletions

View File

@@ -40,6 +40,26 @@ void Anchor::OnDisconnected() {
RegisterHooks(); RegisterHooks();
} }
void Anchor::ProcessOutgoingPackets() {
// Copy all queued packets while holding the lock, then send them after releasing
std::queue<nlohmann::json> packetsToSend;
{
std::lock_guard<std::mutex> lock(outgoingPacketQueueMutex);
packetsToSend.swap(outgoingPacketQueue);
}
// Send packets without holding the lock
while (!packetsToSend.empty()) {
nlohmann::json payload = packetsToSend.front();
packetsToSend.pop();
if (!payload.contains("quiet")) {
SPDLOG_DEBUG("[Anchor] Sending payload:\n{}", payload.dump());
}
Network::SendJsonToRemote(payload);
}
}
void Anchor::SendJsonToRemote(nlohmann::json payload) { void Anchor::SendJsonToRemote(nlohmann::json payload) {
if (!isConnected) { if (!isConnected) {
return; return;
@@ -47,9 +67,17 @@ void Anchor::SendJsonToRemote(nlohmann::json payload) {
payload["clientId"] = ownClientId; payload["clientId"] = ownClientId;
if (!payload.contains("quiet")) { if (!payload.contains("quiet")) {
SPDLOG_DEBUG("[Anchor] Sending payload:\n{}", payload.dump()); SPDLOG_DEBUG("[Anchor] Queuing payload:\n{}", payload.dump());
} }
if (payload["type"] == HANDSHAKE) {
Network::SendJsonToRemote(payload); Network::SendJsonToRemote(payload);
return;
}
// Queue the packet to be sent on the network thread
std::lock_guard<std::mutex> lock(outgoingPacketQueueMutex);
outgoingPacketQueue.push(payload);
} }
void Anchor::OnIncomingJson(nlohmann::json payload) { void Anchor::OnIncomingJson(nlohmann::json payload) {
@@ -87,11 +115,17 @@ void Anchor::OnIncomingJson(nlohmann::json payload) {
} }
void Anchor::ProcessIncomingPacketQueue() { void Anchor::ProcessIncomingPacketQueue() {
// Copy all queued packets while holding the lock, then process them after releasing
std::queue<nlohmann::json> packetsToProcess;
{
std::lock_guard<std::mutex> lock(incomingPacketQueueMutex); std::lock_guard<std::mutex> lock(incomingPacketQueueMutex);
packetsToProcess.swap(incomingPacketQueue);
}
while (!incomingPacketQueue.empty()) { // Process packets without holding the lock
nlohmann::json payload = incomingPacketQueue.front(); while (!packetsToProcess.empty()) {
incomingPacketQueue.pop(); nlohmann::json payload = packetsToProcess.front();
packetsToProcess.pop();
std::string packetType = payload["type"].get<std::string>(); std::string packetType = payload["type"].get<std::string>();

View File

@@ -76,6 +76,8 @@ class Anchor : public Network {
bool isProcessingIncomingPacket = false; bool isProcessingIncomingPacket = false;
std::queue<nlohmann::json> incomingPacketQueue; std::queue<nlohmann::json> incomingPacketQueue;
std::mutex incomingPacketQueueMutex; std::mutex incomingPacketQueueMutex;
std::queue<nlohmann::json> outgoingPacketQueue;
std::mutex outgoingPacketQueueMutex;
nlohmann::json PrepClientState(); nlohmann::json PrepClientState();
nlohmann::json PrepRoomState(); nlohmann::json PrepRoomState();
@@ -143,6 +145,7 @@ class Anchor : public Network {
void OnIncomingJson(nlohmann::json payload); void OnIncomingJson(nlohmann::json payload);
void OnConnected(); void OnConnected();
void OnDisconnected(); void OnDisconnected();
void ProcessOutgoingPackets();
void DrawMenu(); void DrawMenu();
void ProcessIncomingPacketQueue(); void ProcessIncomingPacketQueue();
void SendJsonToRemote(nlohmann::json packet); void SendJsonToRemote(nlohmann::json packet);

View File

@@ -158,13 +158,13 @@ void DummyPlayer_Update(Actor* actor, PlayState* play) {
player->actor.world.pos.y += diff.y * player->actor.scale.y; player->actor.world.pos.y += diff.y * player->actor.scale.y;
} }
if (player->modelGroup != Player_ActionToModelGroup(player, player->itemAction)) { if (player->modelGroup != client.modelGroup) {
// Hack to account for usage of gSaveContext // Hack to account for usage of gSaveContext
s32 originalAge = gSaveContext.linkAge; s32 originalAge = gSaveContext.linkAge;
gSaveContext.linkAge = client.linkAge; gSaveContext.linkAge = client.linkAge;
u8 originalButtonItem0 = gSaveContext.equips.buttonItems[0]; u8 originalButtonItem0 = gSaveContext.equips.buttonItems[0];
gSaveContext.equips.buttonItems[0] = client.buttonItem0; gSaveContext.equips.buttonItems[0] = client.buttonItem0;
Player_SetModelGroup(player, Player_ActionToModelGroup(player, player->itemAction)); Player_SetModelGroup(player, client.modelGroup);
gSaveContext.linkAge = originalAge; gSaveContext.linkAge = originalAge;
gSaveContext.equips.buttonItems[0] = originalButtonItem0; gSaveContext.equips.buttonItems[0] = originalButtonItem0;
} }

View File

@@ -58,7 +58,7 @@ void Anchor::SendPacket_PlayerUpdate() {
payload["currentShield"] = player->currentShield; payload["currentShield"] = player->currentShield;
payload["currentTunic"] = player->currentTunic; payload["currentTunic"] = player->currentTunic;
payload["stateFlags1"] = player->stateFlags1; payload["stateFlags1"] = player->stateFlags1;
payload["stateFlags2"] = player->stateFlags2; payload["stateFlags2"] = player->stateFlags2 & ~PLAYER_STATE2_DISABLE_DRAW;
payload["buttonItem0"] = gSaveContext.equips.buttonItems[0]; payload["buttonItem0"] = gSaveContext.equips.buttonItems[0];
payload["itemAction"] = player->itemAction; payload["itemAction"] = player->itemAction;
payload["heldItemAction"] = player->heldItemAction; payload["heldItemAction"] = player->heldItemAction;

View File

@@ -4,6 +4,8 @@
#include "soh/Enhancements/game-interactor/GameInteractor.h" #include "soh/Enhancements/game-interactor/GameInteractor.h"
#include "soh/OTRGlobals.h" #include "soh/OTRGlobals.h"
static bool isResultOfHandling = false;
/** /**
* SET_CHECK_STATUS * SET_CHECK_STATUS
* *
@@ -11,7 +13,7 @@
*/ */
void Anchor::SendPacket_SetCheckStatus(RandomizerCheck rc) { void Anchor::SendPacket_SetCheckStatus(RandomizerCheck rc) {
if (!IsSaveLoaded() || isProcessingIncomingPacket || !roomState.syncItemsAndFlags) { if (!IsSaveLoaded() || isResultOfHandling) {
return; return;
} }
@@ -40,12 +42,16 @@ void Anchor::HandlePacket_SetCheckStatus(nlohmann::json payload) {
RandomizerCheckStatus status = payload["status"].get<RandomizerCheckStatus>(); RandomizerCheckStatus status = payload["status"].get<RandomizerCheckStatus>();
bool skipped = payload["skipped"].get<bool>(); bool skipped = payload["skipped"].get<bool>();
isResultOfHandling = true;
if (randoContext->GetItemLocation(rc)->GetCheckStatus() != status) { if (randoContext->GetItemLocation(rc)->GetCheckStatus() != status) {
randoContext->GetItemLocation(rc)->SetCheckStatus(status); randoContext->GetItemLocation(rc)->SetCheckStatus(status);
} }
if (randoContext->GetItemLocation(rc)->GetIsSkipped() != skipped) { if (randoContext->GetItemLocation(rc)->GetIsSkipped() != skipped) {
randoContext->GetItemLocation(rc)->SetIsSkipped(skipped); randoContext->GetItemLocation(rc)->SetIsSkipped(skipped);
} }
CheckTracker::RecalculateAllAreaTotals(); CheckTracker::RecalculateAllAreaTotals();
CheckTracker::RecalculateAvailableChecks(); CheckTracker::RecalculateAvailableChecks();
isResultOfHandling = false;
} }

View File

@@ -291,6 +291,7 @@ void Anchor::HandlePacket_UpdateTeamState(nlohmann::json payload) {
} }
if (payload.contains("queue")) { if (payload.contains("queue")) {
std::lock_guard<std::mutex> lock(incomingPacketQueueMutex);
for (auto& item : payload["queue"]) { for (auto& item : payload["queue"]) {
nlohmann::json itemPayload = nlohmann::json::parse(item.get<std::string>()); nlohmann::json itemPayload = nlohmann::json::parse(item.get<std::string>());
incomingPacketQueue.push(itemPayload); incomingPacketQueue.push(itemPayload);

View File

@@ -46,6 +46,9 @@ void Network::OnConnected() {
void Network::OnDisconnected() { void Network::OnDisconnected() {
} }
void Network::ProcessOutgoingPackets() {
}
void Network::SendDataToRemote(const char* payload) { void Network::SendDataToRemote(const char* payload) {
#ifdef ENABLE_REMOTE_CONTROL #ifdef ENABLE_REMOTE_CONTROL
SPDLOG_DEBUG("[Network] Sending data: {}", payload); SPDLOG_DEBUG("[Network] Sending data: {}", payload);
@@ -68,6 +71,7 @@ void Network::ReceiveFromServer() {
if (networkSocket) { if (networkSocket) {
isConnected = true; isConnected = true;
receivedData.clear();
SPDLOG_INFO("[Network] Connection to server established!"); SPDLOG_INFO("[Network] Connection to server established!");
OnConnected(); OnConnected();
@@ -90,7 +94,11 @@ void Network::ReceiveFromServer() {
break; break;
} }
// Always process outgoing packets
ProcessOutgoingPackets();
if (socketsReady == 0) { if (socketsReady == 0) {
// No incoming data
continue; continue;
} }
@@ -119,9 +127,15 @@ void Network::ReceiveFromServer() {
} }
} }
if (socketSet) {
SDLNet_FreeSocketSet(socketSet);
}
if (isConnected) { if (isConnected) {
SDLNet_TCP_Close(networkSocket); SDLNet_TCP_Close(networkSocket);
networkSocket = nullptr;
isConnected = false; isConnected = false;
receivedData.clear();
OnDisconnected(); OnDisconnected();
SPDLOG_INFO("[Network] Ending receiving thread..."); SPDLOG_INFO("[Network] Ending receiving thread...");
} }

View File

@@ -44,6 +44,7 @@ class Network {
virtual void OnIncomingJson(nlohmann::json payload); virtual void OnIncomingJson(nlohmann::json payload);
virtual void OnConnected(); virtual void OnConnected();
virtual void OnDisconnected(); virtual void OnDisconnected();
virtual void ProcessOutgoingPackets();
void SendDataToRemote(const char* payload); void SendDataToRemote(const char* payload);
virtual void SendJsonToRemote(nlohmann::json packet); virtual void SendJsonToRemote(nlohmann::json packet);
}; };