mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-08-25 11:46:27 +00:00
finished read through of SlippiNetplay.cpp
This commit is contained in:
parent
5e61a477cf
commit
3cb9d311d4
6 changed files with 467 additions and 462 deletions
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue