finished read through of SlippiNetplay.cpp

This commit is contained in:
Nikhil Narayana 2023-08-20 16:36:06 -07:00
commit 3cb9d311d4
No known key found for this signature in database
GPG key ID: 1B34839FA8D6245E
6 changed files with 467 additions and 462 deletions

View file

@ -1771,15 +1771,15 @@ void CEXISlippi::startFindMatch(u8* payload)
if (SlippiMatchmaking::IsFixedRulesMode(search.mode)) if (SlippiMatchmaking::IsFixedRulesMode(search.mode))
{ {
// Character check // Character check
if (local_selections.characterId >= 26) if (local_selections.character_id >= 26)
{ {
forced_error = "The character you selected is not allowed in this mode"; forced_error = "The character you selected is not allowed in this mode";
return; return;
} }
// Stage check // Stage check
if (local_selections.isStageSelected && if (local_selections.is_stage_selected &&
std::find(allowed_stages.begin(), allowed_stages.end(), local_selections.stageId) == std::find(allowed_stages.begin(), allowed_stages.end(), local_selections.stage_id) ==
allowed_stages.end()) allowed_stages.end())
{ {
forced_error = "The stage being requested is not allowed in this mode"; forced_error = "The stage being requested is not allowed in this mode";
@ -1789,7 +1789,7 @@ void CEXISlippi::startFindMatch(u8* payload)
else if (search.mode == SlippiMatchmaking::OnlinePlayMode::TEAMS) else if (search.mode == SlippiMatchmaking::OnlinePlayMode::TEAMS)
{ {
// Some special handling for teams since it is being heavily used for unranked // Some special handling for teams since it is being heavily used for unranked
if (local_selections.characterId >= 26 && if (local_selections.character_id >= 26 &&
SConfig::GetSlippiConfig().melee_version != Melee::Version::MEX) SConfig::GetSlippiConfig().melee_version != Melee::Version::MEX)
{ {
forced_error = "The character you selected is not allowed in this mode"; forced_error = "The character you selected is not allowed in this mode";
@ -1966,7 +1966,7 @@ void CEXISlippi::prepareOnlineMatchState()
!forced_error.empty() ? error_state : matchmaking->GetMatchmakeState(); !forced_error.empty() ? error_state : matchmaking->GetMatchmakeState();
#ifdef LOCAL_TESTING #ifdef LOCAL_TESTING
if (local_selections.isCharacterSelected || is_local_connected) if (local_selections.is_character_selected || is_local_connected)
{ {
mm_state = SlippiMatchmaking::ProcessState::CONNECTION_SUCCESS; mm_state = SlippiMatchmaking::ProcessState::CONNECTION_SUCCESS;
is_local_connected = true; is_local_connected = true;
@ -1975,7 +1975,7 @@ void CEXISlippi::prepareOnlineMatchState()
m_read_queue.push_back(mm_state); // Matchmaking State m_read_queue.push_back(mm_state); // Matchmaking State
u8 local_player_ready = local_selections.isCharacterSelected; u8 local_player_ready = local_selections.is_character_selected;
u8 remote_players_ready = 0; u8 remote_players_ready = 0;
auto user_info = user->GetUserInfo(); auto user_info = user->GetUserInfo();
@ -2012,7 +2012,7 @@ void CEXISlippi::prepareOnlineMatchState()
// Clear stage pool so that when we call getRandomStage it will use full list // Clear stage pool so that when we call getRandomStage it will use full list
stage_pool.clear(); stage_pool.clear();
local_selections.stageId = getRandomStage(); local_selections.stage_id = getRandomStage();
slippi_netplay->SetMatchSelections(local_selections); slippi_netplay->SetMatchSelections(local_selections);
} }
@ -2034,7 +2034,7 @@ void CEXISlippi::prepareOnlineMatchState()
u8 remote_player_count = matchmaking->RemotePlayerCount(); u8 remote_player_count = matchmaking->RemotePlayerCount();
for (int i = 0; i < remote_player_count; i++) for (int i = 0; i < remote_player_count; i++)
{ {
if (!match_info->remotePlayerSelections[i].isCharacterSelected) if (!match_info->remote_player_selections[i].is_character_selected)
{ {
remote_players_ready = 0; remote_players_ready = 0;
} }
@ -2124,8 +2124,8 @@ void CEXISlippi::prepareOnlineMatchState()
if (sent_chat_message_id <= 0) if (sent_chat_message_id <= 0)
{ {
auto remote_message_selection = slippi_netplay->GetSlippiRemoteChatMessage(is_chat_enabled); auto remote_message_selection = slippi_netplay->GetSlippiRemoteChatMessage(is_chat_enabled);
chat_message_id = remote_message_selection.messageId; chat_message_id = remote_message_selection.message_id;
chat_message_player_idx = remote_message_selection.playerIdx; chat_message_player_idx = remote_message_selection.player_idx;
if (chat_message_id == SlippiPremadeText::CHAT_MSG_CHAT_DISABLED && !is_single_mode) if (chat_message_id == SlippiPremadeText::CHAT_MSG_CHAT_DISABLED && !is_single_mode)
{ {
// Clear remote chat messages if we are on teams and the player has chat disabled. // Clear remote chat messages if we are on teams and the player has chat disabled.
@ -2155,11 +2155,11 @@ void CEXISlippi::prepareOnlineMatchState()
auto is_decider = slippi_netplay->IsDecider(); auto is_decider = slippi_netplay->IsDecider();
u8 remote_player_count = matchmaking->RemotePlayerCount(); u8 remote_player_count = matchmaking->RemotePlayerCount();
auto match_info = slippi_netplay->GetMatchInfo(); auto match_info = slippi_netplay->GetMatchInfo();
SlippiPlayerSelections lps = match_info->localPlayerSelections; SlippiPlayerSelections lps = match_info->local_player_selections;
auto rps = match_info->remotePlayerSelections; auto rps = match_info->remote_player_selections;
#ifdef LOCAL_TESTING #ifdef LOCAL_TESTING
lps.playerIdx = 0; lps.player_idx = 0;
// By default Local testing for teams is against // By default Local testing for teams is against
// 1 RED TEAM Falco // 1 RED TEAM Falco
@ -2168,18 +2168,18 @@ void CEXISlippi::prepareOnlineMatchState()
{ {
if (i == 0) if (i == 0)
{ {
rps[i].characterColor = 1; rps[i].character_color = 1;
rps[i].teamId = 0; rps[i].team_id = 0;
} }
else else
{ {
rps[i].characterColor = 2; rps[i].character_color = 2;
rps[i].teamId = 1; rps[i].team_id = 1;
} }
rps[i].characterId = 0x14; rps[i].character_id = 0x14;
rps[i].playerIdx = i + 1; rps[i].player_idx = i + 1;
rps[i].isCharacterSelected = true; rps[i].is_character_selected = true;
} }
remote_player_count = last_search.mode == SlippiMatchmaking::OnlinePlayMode::TEAMS ? 3 : 1; remote_player_count = last_search.mode == SlippiMatchmaking::OnlinePlayMode::TEAMS ? 3 : 1;
@ -2188,16 +2188,16 @@ void CEXISlippi::prepareOnlineMatchState()
#endif #endif
// Check if someone is picking dumb characters in non-direct // Check if someone is picking dumb characters in non-direct
auto local_char_ok = lps.characterId < 26; auto local_char_ok = lps.character_id < 26;
auto remote_char_ok = true; auto remote_char_ok = true;
INFO_LOG_FMT(SLIPPI_ONLINE, "remote_player_count: {}", remote_player_count); INFO_LOG_FMT(SLIPPI_ONLINE, "remote_player_count: {}", remote_player_count);
for (int i = 0; i < remote_player_count; i++) for (int i = 0; i < remote_player_count; i++)
{ {
if (rps[i].characterId >= 26) if (rps[i].character_id >= 26)
remote_char_ok = false; remote_char_ok = false;
} }
// TODO: Ideally remotePlayerSelections would just include everyone including the local player // TODO: Ideally remote_player_selections would just include everyone including the local player
// TODO: Would also simplify some logic in the Netplay class // TODO: Would also simplify some logic in the Netplay class
// Here we are storing pointers to the player selections. That means that we can technically // Here we are storing pointers to the player selections. That means that we can technically
@ -2205,10 +2205,10 @@ void CEXISlippi::prepareOnlineMatchState()
// from the netplay class. Unfortunately, I think it might be required for the overwrite stuff // from the netplay class. Unfortunately, I think it might be required for the overwrite stuff
// to work correctly though, maybe on a tiebreak in ranked? // to work correctly though, maybe on a tiebreak in ranked?
std::vector<SlippiPlayerSelections*> ordered_selections(remote_player_count + 1); std::vector<SlippiPlayerSelections*> ordered_selections(remote_player_count + 1);
ordered_selections[lps.playerIdx] = &lps; ordered_selections[lps.player_idx] = &lps;
for (int i = 0; i < remote_player_count; i++) for (int i = 0; i < remote_player_count; i++)
{ {
ordered_selections[rps[i].playerIdx] = &rps[i]; ordered_selections[rps[i].player_idx] = &rps[i];
} }
// Overwrite selections // Overwrite selections
@ -2216,20 +2216,20 @@ void CEXISlippi::prepareOnlineMatchState()
{ {
const auto& ow = overwrite_selections[i]; const auto& ow = overwrite_selections[i];
ordered_selections[i]->characterId = ow.characterId; ordered_selections[i]->character_id = ow.character_id;
ordered_selections[i]->characterColor = ow.characterColor; ordered_selections[i]->character_color = ow.character_color;
ordered_selections[i]->stageId = ow.stageId; ordered_selections[i]->stage_id = ow.stage_id;
} }
// Overwrite stage information. Make sure everyone loads the same stage // Overwrite stage information. Make sure everyone loads the same stage
u16 stage_id = 0x1F; // Default to battlefield if there was no selection u16 stage_id = 0x1F; // Default to battlefield if there was no selection
for (const auto& selections : ordered_selections) for (const auto& selections : ordered_selections)
{ {
if (!selections->isStageSelected) if (!selections->is_stage_selected)
continue; continue;
// Stage selected by this player, use that selection // Stage selected by this player, use that selection
stage_id = selections->stageId; stage_id = selections->stage_id;
break; break;
} }
@ -2279,15 +2279,15 @@ void CEXISlippi::prepareOnlineMatchState()
} }
// Set rng offset // Set rng offset
rng_offset = is_decider ? lps.rngOffset : rps[0].rngOffset; rng_offset = is_decider ? lps.rng_offset : rps[0].rng_offset;
INFO_LOG_FMT(SLIPPI_ONLINE, "Rng Offset: {:#x}", rng_offset); INFO_LOG_FMT(SLIPPI_ONLINE, "Rng Offset: {:#x}", rng_offset);
// Check if everyone is the same color // Check if everyone is the same color
auto color = ordered_selections[0]->teamId; auto color = ordered_selections[0]->team_id;
bool are_all_same_team = true; bool are_all_same_team = true;
for (const auto& s : ordered_selections) for (const auto& s : ordered_selections)
{ {
if (s->teamId != color) if (s->team_id != color)
are_all_same_team = false; are_all_same_team = false;
} }
@ -2304,21 +2304,21 @@ void CEXISlippi::prepareOnlineMatchState()
// Overwrite player character choices // Overwrite player character choices
for (auto& s : ordered_selections) for (auto& s : ordered_selections)
{ {
if (!s->isCharacterSelected) if (!s->is_character_selected)
{ {
continue; continue;
} }
if (are_all_same_team) if (are_all_same_team)
{ {
// Overwrite teamId. Color is overwritten by ASM // Overwrite team_id. Color is overwritten by ASM
s->teamId = teamAssignments[s->playerIdx]; s->team_id = teamAssignments[s->player_idx];
} }
// Overwrite player character // Overwrite player character
online_match_block[0x60 + (s->playerIdx) * 0x24] = s->characterId; online_match_block[0x60 + (s->player_idx) * 0x24] = s->character_id;
online_match_block[0x63 + (s->playerIdx) * 0x24] = s->characterColor; online_match_block[0x63 + (s->player_idx) * 0x24] = s->character_color;
online_match_block[0x67 + (s->playerIdx) * 0x24] = 0; online_match_block[0x67 + (s->player_idx) * 0x24] = 0;
online_match_block[0x69 + (s->playerIdx) * 0x24] = s->teamId; online_match_block[0x69 + (s->player_idx) * 0x24] = s->team_id;
} }
// Handle Singles/Teams specific logic // Handle Singles/Teams specific logic
@ -2331,10 +2331,10 @@ void CEXISlippi::prepareOnlineMatchState()
online_match_block[0x61 + 3 * 0x24] = 3; online_match_block[0x61 + 3 * 0x24] = 3;
// Make one character lighter if same character, same color // Make one character lighter if same character, same color
bool is_sheik_vs_zelda = lps.characterId == 0x12 && rps[0].characterId == 0x13 || bool is_sheik_vs_zelda = lps.character_id == 0x12 && rps[0].character_id == 0x13 ||
lps.characterId == 0x13 && rps[0].characterId == 0x12; lps.character_id == 0x13 && rps[0].character_id == 0x12;
bool char_match = lps.characterId == rps[0].characterId || is_sheik_vs_zelda; bool char_match = lps.character_id == rps[0].character_id || is_sheik_vs_zelda;
bool color_match = lps.characterColor == rps[0].characterColor; bool color_match = lps.character_color == rps[0].character_color;
online_match_block[0x67 + 0x24] = char_match && color_match ? 1 : 0; online_match_block[0x67 + 0x24] = char_match && color_match ? 1 : 0;
} }
@ -2360,7 +2360,7 @@ void CEXISlippi::prepareOnlineMatchState()
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
int team_id = online_match_block[0x69 + i * 0x24]; int team_id = online_match_block[0x69 + i * 0x24];
if (team_id == lps.teamId) if (team_id == lps.team_id)
left_team_players.push_back(i); left_team_players.push_back(i);
else else
right_team_players.push_back(i); right_team_players.push_back(i);
@ -2522,26 +2522,27 @@ void CEXISlippi::setMatchSelections(u8* payload)
{ {
SlippiPlayerSelections s; SlippiPlayerSelections s;
s.teamId = payload[0]; s.team_id = payload[0];
s.characterId = payload[1]; s.character_id = payload[1];
s.characterColor = payload[2]; s.character_color = payload[2];
s.isCharacterSelected = payload[3]; s.is_character_selected = payload[3];
s.stageId = Common::swap16(&payload[4]); s.stage_id = Common::swap16(&payload[4]);
u8 stage_select_option = payload[6]; u8 stage_select_option = payload[6];
// u8 online_mode = payload[7]; // u8 online_mode = payload[7];
s.isStageSelected = stage_select_option == 1 || stage_select_option == 3; s.is_stage_selected = stage_select_option == 1 || stage_select_option == 3;
if (stage_select_option == 3) if (stage_select_option == 3)
{ {
// If stage requested is random, select a random stage // If stage requested is random, select a random stage
s.stageId = getRandomStage(); s.stage_id = getRandomStage();
} }
INFO_LOG_FMT(SLIPPI, "LPS set char: {}, iSS: {}, {}, stage: {}, team: {}", s.isCharacterSelected, INFO_LOG_FMT(SLIPPI, "LPS set char: {}, iSS: {}, {}, stage: {}, team: {}",
stage_select_option, s.isStageSelected, s.stageId, s.teamId); s.is_character_selected, stage_select_option, s.is_stage_selected, s.stage_id,
s.team_id);
s.rngOffset = generator() % 0xFFFF; s.rng_offset = generator() % 0xFFFF;
// Merge these selections // Merge these selections
local_selections.Merge(s); local_selections.Merge(s);
@ -2716,7 +2717,7 @@ void CEXISlippi::handleChatMessage(u8* payload)
auto user_info = user->GetUserInfo(); auto user_info = user->GetUserInfo();
auto packet = std::make_unique<sf::Packet>(); auto packet = std::make_unique<sf::Packet>();
// OSD::AddMessage("[Me]: "+ msg, OSD::Duration::VERY_LONG, OSD::Color::YELLOW); // OSD::AddMessage("[Me]: "+ msg, OSD::Duration::VERY_LONG, OSD::Color::YELLOW);
slippi_netplay->remoteSentChatMessageId = message_id; slippi_netplay->remote_sent_chat_message_id = message_id;
slippi_netplay->WriteChatMessageToPacket(*packet, message_id, slippi_netplay->WriteChatMessageToPacket(*packet, message_id,
slippi_netplay->LocalPlayerPort()); slippi_netplay->LocalPlayerPort());
slippi_netplay->SendAsync(std::move(packet)); slippi_netplay->SendAsync(std::move(packet));
@ -2947,12 +2948,12 @@ void CEXISlippi::handleOverwriteSelections(const SlippiExiTypes::OverwriteSelect
continue; continue;
SlippiPlayerSelections s; SlippiPlayerSelections s;
s.isCharacterSelected = true; s.is_character_selected = true;
s.characterId = query.chars[i].char_id; s.character_id = query.chars[i].char_id;
s.characterColor = query.chars[i].char_color_id; s.character_color = query.chars[i].char_color_id;
s.isStageSelected = true; s.is_stage_selected = true;
s.stageId = query.stage_id; s.stage_id = query.stage_id;
s.playerIdx = i; s.player_idx = i;
overwrite_selections.push_back(s); overwrite_selections.push_back(s);
} }

View file

@ -147,7 +147,7 @@ void handleGameInit(Game* game, uint32_t maxSize)
p.controllerPort = i; p.controllerPort = i;
p.characterId = playerInfo >> 24; p.characterId = playerInfo >> 24;
p.playerType = playerType; p.playerType = playerType;
p.characterColor = playerInfo & 0xFF; p.character_color = playerInfo & 0xFF;
p.nametag = playerNametags[i]; p.nametag = playerNametags[i];
p.displayName = playerDisplayNames[i]; p.displayName = playerDisplayNames[i];
p.connectCode = playerConnectCodes[i]; p.connectCode = playerConnectCodes[i];

View file

@ -86,7 +86,7 @@ typedef struct
{ {
// Static data // Static data
uint8_t characterId; uint8_t characterId;
uint8_t characterColor; uint8_t character_color;
uint8_t playerType; uint8_t playerType;
uint8_t controllerPort; uint8_t controllerPort;
std::array<uint16_t, NAMETAG_SIZE> nametag; std::array<uint16_t, NAMETAG_SIZE> nametag;

View file

@ -608,8 +608,8 @@ void SlippiMatchmaking::handleMatchmaking()
for (json::iterator it = stages.begin(); it != stages.end(); ++it) for (json::iterator it = stages.begin(); it != stages.end(); ++it)
{ {
json el = *it; json el = *it;
auto stageId = el.get<int>(); auto stage_id = el.get<int>();
m_allowedStages.push_back(stageId); m_allowedStages.push_back(stage_id);
} }
} }
@ -637,7 +637,7 @@ void SlippiMatchmaking::handleMatchmaking()
terminateMmConnection(); terminateMmConnection();
m_state = ProcessState::OPPONENT_CONNECTING; m_state = ProcessState::OPPONENT_CONNECTING;
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Opponent found. isDecider: {}", ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Opponent found. is_decider: {}",
m_isHost ? "true" : "false"); m_isHost ? "true" : "false");
} }

File diff suppressed because it is too large Load diff

View file

@ -15,6 +15,7 @@
#include <thread> #include <thread>
#include <unordered_map> #include <unordered_map>
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Event.h" #include "Common/Event.h"
#include "Common/Timer.h" #include "Common/Timer.h"
@ -26,8 +27,8 @@
#include <Qos2.h> #include <Qos2.h>
#endif #endif
#define SLIPPI_ONLINE_LOCKSTEP_INTERVAL \ // Number of frames to wait before attempting to time-sync
30 // Number of frames to wait before attempting to time-sync #define SLIPPI_ONLINE_LOCKSTEP_INTERVAL 30
#define SLIPPI_PING_DISPLAY_INTERVAL 60 #define SLIPPI_PING_DISPLAY_INTERVAL 60
#define SLIPPI_REMOTE_PLAYER_MAX 3 #define SLIPPI_REMOTE_PLAYER_MAX 3
#define SLIPPI_REMOTE_PLAYER_COUNT 3 #define SLIPPI_REMOTE_PLAYER_COUNT 3
@ -35,17 +36,17 @@
struct SlippiRemotePadOutput struct SlippiRemotePadOutput
{ {
int32_t latest_frame{}; int32_t latest_frame{};
s32 checksum_frame; s32 checksum_frame{};
u32 checksum; u32 checksum{};
u8 playerIdx{}; u8 player_idx{};
std::vector<u8> data; std::vector<u8> data{};
}; };
struct SlippiGamePrepStepResults struct SlippiGamePrepStepResults
{ {
u8 step_idx; u8 step_idx{};
u8 char_selection; u8 char_selection{};
u8 char_color_selection; u8 char_color_selection{};
u8 stage_selections[2]; u8 stage_selections[2];
}; };
@ -75,51 +76,51 @@ struct SlippiDesyncRecoveryResp
class SlippiPlayerSelections class SlippiPlayerSelections
{ {
public: public:
u8 playerIdx{}; u8 player_idx{};
u8 characterId{}; u8 character_id{};
u8 characterColor{}; u8 character_color{};
u8 teamId{}; u8 team_id{};
bool isCharacterSelected = false; bool is_character_selected = false;
u16 stageId{}; u16 stage_id{};
bool isStageSelected = false; bool is_stage_selected = false;
u32 rngOffset{}; u32 rng_offset{};
int messageId = 0; int message_id = 0;
bool error = false; bool error = false;
void Merge(SlippiPlayerSelections& s) void Merge(SlippiPlayerSelections& s)
{ {
this->rngOffset = s.rngOffset; this->rng_offset = s.rng_offset;
if (s.isStageSelected) if (s.is_stage_selected)
{ {
this->stageId = s.stageId; this->stage_id = s.stage_id;
this->isStageSelected = true; this->is_stage_selected = true;
} }
if (s.isCharacterSelected) if (s.is_character_selected)
{ {
this->characterId = s.characterId; this->character_id = s.character_id;
this->characterColor = s.characterColor; this->character_color = s.character_color;
this->teamId = s.teamId; this->team_id = s.team_id;
this->isCharacterSelected = true; this->is_character_selected = true;
} }
} }
void Reset() void Reset()
{ {
characterId = 0; character_id = 0;
characterColor = 0; character_color = 0;
isCharacterSelected = false; is_character_selected = false;
teamId = 0; team_id = 0;
stageId = 0; stage_id = 0;
isStageSelected = false; is_stage_selected = false;
rngOffset = 0; rng_offset = 0;
} }
}; };
@ -132,15 +133,15 @@ struct ChecksumEntry
class SlippiMatchInfo class SlippiMatchInfo
{ {
public: public:
SlippiPlayerSelections localPlayerSelections; SlippiPlayerSelections local_player_selections;
SlippiPlayerSelections remotePlayerSelections[SLIPPI_REMOTE_PLAYER_MAX]; SlippiPlayerSelections remote_player_selections[SLIPPI_REMOTE_PLAYER_MAX];
void Reset() void Reset()
{ {
localPlayerSelections.Reset(); local_player_selections.Reset();
for (int i = 0; i < SLIPPI_REMOTE_PLAYER_MAX; i++) for (int i = 0; i < SLIPPI_REMOTE_PLAYER_MAX; i++)
{ {
remotePlayerSelections[i].Reset(); remote_player_selections[i].Reset();
} }
} }
}; };
@ -151,10 +152,10 @@ public:
void ThreadFunc(); void ThreadFunc();
void SendAsync(std::unique_ptr<sf::Packet> packet); void SendAsync(std::unique_ptr<sf::Packet> packet);
SlippiNetplayClient(bool isDecider); // Make a dummy client SlippiNetplayClient(bool is_decider); // Make a dummy client
SlippiNetplayClient(std::vector<std::string> addrs, std::vector<u16> ports, SlippiNetplayClient(std::vector<std::string> addrs, std::vector<u16> ports,
const u8 remotePlayerCount, const u16 localPort, bool isDecider, const u8 remote_player_count, const u16 local_port, bool is_decider,
u8 playerIdx); u8 player_idx);
~SlippiNetplayClient(); ~SlippiNetplayClient();
// Slippi Online // Slippi Online
@ -178,24 +179,24 @@ public:
void SetMatchSelections(SlippiPlayerSelections& s); void SetMatchSelections(SlippiPlayerSelections& s);
void SendGamePrepStep(SlippiGamePrepStepResults& s); void SendGamePrepStep(SlippiGamePrepStepResults& s);
void SendSyncedGameState(SlippiSyncedGameState& s); void SendSyncedGameState(SlippiSyncedGameState& s);
bool GetGamePrepResults(u8 stepIdx, SlippiGamePrepStepResults& res); bool GetGamePrepResults(u8 step_idx, SlippiGamePrepStepResults& res);
std::unique_ptr<SlippiRemotePadOutput> GetFakePadOutput(int frame); std::unique_ptr<SlippiRemotePadOutput> GetFakePadOutput(int frame);
std::unique_ptr<SlippiRemotePadOutput> GetSlippiRemotePad(int index, int maxFrameCount); std::unique_ptr<SlippiRemotePadOutput> GetSlippiRemotePad(int index, int max_frame_count);
void DropOldRemoteInputs(int32_t finalizedFrame); void DropOldRemoteInputs(int32_t finalized_frame);
SlippiMatchInfo* GetMatchInfo(); SlippiMatchInfo* GetMatchInfo();
int32_t GetSlippiLatestRemoteFrame(int maxFrameCount); int32_t GetSlippiLatestRemoteFrame(int max_frame_count);
SlippiPlayerSelections GetSlippiRemoteChatMessage(bool isChatEnabled); SlippiPlayerSelections GetSlippiRemoteChatMessage(bool is_chat_enabled);
u8 GetSlippiRemoteSentChatMessage(bool isChatEnabled); u8 GetSlippiRemoteSentChatMessage(bool is_chat_enabled);
s32 CalcTimeOffsetUs(); s32 CalcTimeOffsetUs();
bool IsWaitingForDesyncRecovery(); bool IsWaitingForDesyncRecovery();
SlippiDesyncRecoveryResp GetDesyncRecoveryState(); SlippiDesyncRecoveryResp GetDesyncRecoveryState();
void WriteChatMessageToPacket(sf::Packet& packet, int messageId, u8 playerIdx); void WriteChatMessageToPacket(sf::Packet& packet, int message_id, u8 player_idx);
std::unique_ptr<SlippiPlayerSelections> ReadChatMessageFromPacket(sf::Packet& packet); std::unique_ptr<SlippiPlayerSelections> ReadChatMessageFromPacket(sf::Packet& packet);
std::unique_ptr<SlippiPlayerSelections> remoteChatMessageSelection = std::unique_ptr<SlippiPlayerSelections> remote_chat_message_selection =
nullptr; // most recent chat message player selection (message + player index) nullptr; // most recent chat message player selection (message + player index)
u8 remoteSentChatMessageId = 0; // most recent chat message id that current player sent u8 remote_sent_chat_message_id = 0; // most recent chat message id that current player sent
protected: protected:
struct struct
@ -211,7 +212,7 @@ protected:
ENetHost* m_client = nullptr; ENetHost* m_client = nullptr;
std::vector<ENetPeer*> m_server; std::vector<ENetPeer*> m_server;
std::thread m_thread; std::thread m_thread;
u8 m_remotePlayerCount = 0; u8 m_remote_player_count = 0;
std::string m_selected_game; std::string m_selected_game;
Common::Flag m_is_running{false}; Common::Flag m_is_running{false};
@ -224,8 +225,8 @@ protected:
// Slippi Stuff // Slippi Stuff
struct FrameTiming struct FrameTiming
{ {
int32_t frame; int32_t frame{};
u64 timeUs; u64 time_us{};
}; };
struct FrameOffsetData struct FrameOffsetData
@ -235,30 +236,30 @@ protected:
std::vector<s32> buf; std::vector<s32> buf;
}; };
bool isConnectionSelected = false; bool is_connection_selected = false;
bool isDecider = false; bool is_decider = false;
bool hasGameStarted = false; bool has_game_started = false;
u8 m_player_idx = 0; u8 m_player_idx = 0;
std::unordered_map<std::string, std::map<ENetPeer*, bool>> activeConnections; std::unordered_map<std::string, std::map<ENetPeer*, bool>> m_active_connections;
std::deque<std::unique_ptr<SlippiPad>> localPadQueue; // most recent inputs at start of deque std::deque<std::unique_ptr<SlippiPad>> m_local_pad_queue; // most recent inputs at start of deque
std::deque<std::unique_ptr<SlippiPad>> std::deque<std::unique_ptr<SlippiPad>>
remotePadQueue[SLIPPI_REMOTE_PLAYER_MAX]; // most recent inputs at start of deque m_remote_pad_queue[SLIPPI_REMOTE_PLAYER_MAX]; // most recent inputs at start of deque
bool is_desync_recovery = false; bool is_desync_recovery = false;
ChecksumEntry remote_checksums[SLIPPI_REMOTE_PLAYER_MAX]; ChecksumEntry remote_checksums[SLIPPI_REMOTE_PLAYER_MAX];
SlippiSyncedGameState remote_sync_states[SLIPPI_REMOTE_PLAYER_MAX]; SlippiSyncedGameState remote_sync_states[SLIPPI_REMOTE_PLAYER_MAX];
SlippiSyncedGameState local_sync_state; SlippiSyncedGameState local_sync_state;
std::deque<SlippiGamePrepStepResults> game_prep_step_queue; std::deque<SlippiGamePrepStepResults> game_prep_step_queue;
u64 pingUs[SLIPPI_REMOTE_PLAYER_MAX]; u64 ping_us[SLIPPI_REMOTE_PLAYER_MAX];
int32_t lastFrameAcked[SLIPPI_REMOTE_PLAYER_MAX]; int32_t last_frame_acked[SLIPPI_REMOTE_PLAYER_MAX];
FrameOffsetData frameOffsetData[SLIPPI_REMOTE_PLAYER_MAX]; FrameOffsetData frame_offset_data[SLIPPI_REMOTE_PLAYER_MAX];
FrameTiming lastFrameTiming[SLIPPI_REMOTE_PLAYER_MAX]; FrameTiming last_frame_timing[SLIPPI_REMOTE_PLAYER_MAX];
std::array<std::queue<FrameTiming>, SLIPPI_REMOTE_PLAYER_MAX> ackTimers; std::array<std::queue<FrameTiming>, SLIPPI_REMOTE_PLAYER_MAX> ack_timers;
SlippiConnectStatus slippiConnectStatus = SlippiConnectStatus::NET_CONNECT_STATUS_UNSET; SlippiConnectStatus slippi_connect_status = SlippiConnectStatus::NET_CONNECT_STATUS_UNSET;
std::vector<int> failedConnections; std::vector<int> failed_connections;
SlippiMatchInfo matchInfo; SlippiMatchInfo match_info;
bool m_is_recording = false; bool m_is_recording = false;