finished read through of SlippiMatchmaking.cpp

This commit is contained in:
Nikhil Narayana 2023-08-20 16:56:33 -07:00
commit d86b22a50e
No known key found for this signature in database
GPG key ID: 1B34839FA8D6245E
3 changed files with 179 additions and 188 deletions

View file

@ -1760,7 +1760,7 @@ void CEXISlippi::startFindMatch(u8* payload)
// TODO: Make this work so we dont have to pass shiftJis to mm server // TODO: Make this work so we dont have to pass shiftJis to mm server
// search.connect_code = SHIFTJISToUTF8(shift_jis_code).c_str(); // search.connect_code = SHIFTJISToUTF8(shift_jis_code).c_str();
search.connectCode = shift_jis_code; search.connect_code = shift_jis_code;
// Store this search so we know what was queued for // Store this search so we know what was queued for
last_search = search; last_search = search;

View file

@ -32,7 +32,7 @@ SlippiMatchmaking::SlippiMatchmaking(SlippiUser* user)
{ {
m_user = user; m_user = user;
m_state = ProcessState::IDLE; m_state = ProcessState::IDLE;
m_errorMsg = ""; m_error_msg = "";
m_client = nullptr; m_client = nullptr;
m_server = nullptr; m_server = nullptr;
@ -46,25 +46,25 @@ SlippiMatchmaking::~SlippiMatchmaking()
{ {
is_mm_terminated = true; is_mm_terminated = true;
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Matchmaking shut down"; m_error_msg = "Matchmaking shut down";
if (m_matchmakeThread.joinable()) if (m_matchmake_thread.joinable())
m_matchmakeThread.join(); m_matchmake_thread.join();
terminateMmConnection(); terminateMmConnection();
} }
void SlippiMatchmaking::FindMatch(MatchSearchSettings settings) void SlippiMatchmaking::FindMatch(MatchSearchSettings settings)
{ {
isMmConnected = false; is_mm_connected = false;
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Starting matchmaking..."); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Starting matchmaking...");
m_searchSettings = settings; m_search_settings = settings;
m_errorMsg = ""; m_error_msg = "";
m_state = ProcessState::INITIALIZING; m_state = ProcessState::INITIALIZING;
m_matchmakeThread = std::thread(&SlippiMatchmaking::MatchmakeThread, this); m_matchmake_thread = std::thread(&SlippiMatchmaking::MatchmakeThread, this);
} }
SlippiMatchmaking::ProcessState SlippiMatchmaking::GetMatchmakeState() SlippiMatchmaking::ProcessState SlippiMatchmaking::GetMatchmakeState()
@ -74,17 +74,17 @@ SlippiMatchmaking::ProcessState SlippiMatchmaking::GetMatchmakeState()
std::string SlippiMatchmaking::GetErrorMessage() std::string SlippiMatchmaking::GetErrorMessage()
{ {
return m_errorMsg; return m_error_msg;
} }
bool SlippiMatchmaking::IsSearching() bool SlippiMatchmaking::IsSearching()
{ {
return searchingStates.count(m_state) != 0; return searching_states.count(m_state) != 0;
} }
std::unique_ptr<SlippiNetplayClient> SlippiMatchmaking::GetNetplayClient() std::unique_ptr<SlippiNetplayClient> SlippiMatchmaking::GetNetplayClient()
{ {
return std::move(m_netplayClient); return std::move(m_netplay_client);
} }
bool SlippiMatchmaking::IsFixedRulesMode(SlippiMatchmaking::OnlinePlayMode mode) bool SlippiMatchmaking::IsFixedRulesMode(SlippiMatchmaking::OnlinePlayMode mode)
@ -96,44 +96,44 @@ bool SlippiMatchmaking::IsFixedRulesMode(SlippiMatchmaking::OnlinePlayMode mode)
void SlippiMatchmaking::sendMessage(json msg) void SlippiMatchmaking::sendMessage(json msg)
{ {
enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE; enet_uint32 flags = ENET_PACKET_FLAG_RELIABLE;
u8 channelId = 0; u8 channel_id = 0;
std::string msgContents = msg.dump(); std::string msgContents = msg.dump();
ENetPacket* epac = enet_packet_create(msgContents.c_str(), msgContents.length(), flags); ENetPacket* epac = enet_packet_create(msgContents.c_str(), msgContents.length(), flags);
enet_peer_send(m_server, channelId, epac); enet_peer_send(m_server, channel_id, epac);
} }
int SlippiMatchmaking::receiveMessage(json& msg, int timeoutMs) int SlippiMatchmaking::receiveMessage(json& msg, int timeout_ms)
{ {
int hostServiceTimeoutMs = 250; int host_service_timeout_ms = 250;
// Make sure loop runs at least once // Make sure loop runs at least once
if (timeoutMs < hostServiceTimeoutMs) if (timeout_ms < host_service_timeout_ms)
timeoutMs = hostServiceTimeoutMs; timeout_ms = host_service_timeout_ms;
// This is not a perfect way to timeout but hopefully it's close enough? // This is not a perfect way to timeout but hopefully it's close enough?
int maxAttempts = timeoutMs / hostServiceTimeoutMs; int max_attempts = timeout_ms / host_service_timeout_ms;
for (int i = 0; i < maxAttempts; i++) for (int i = 0; i < max_attempts; i++)
{ {
ENetEvent netEvent; ENetEvent net_event;
int net = enet_host_service(m_client, &netEvent, hostServiceTimeoutMs); int net = enet_host_service(m_client, &net_event, host_service_timeout_ms);
if (net <= 0) if (net <= 0)
continue; continue;
switch (netEvent.type) switch (net_event.type)
{ {
case ENET_EVENT_TYPE_RECEIVE: case ENET_EVENT_TYPE_RECEIVE:
{ {
std::vector<u8> buf; std::vector<u8> buf;
buf.insert(buf.end(), netEvent.packet->data, buf.insert(buf.end(), net_event.packet->data,
netEvent.packet->data + netEvent.packet->dataLength); net_event.packet->data + net_event.packet->dataLength);
std::string str(buf.begin(), buf.end()); std::string str(buf.begin(), buf.end());
msg = json::parse(str, nullptr, false); msg = json::parse(str, nullptr, false);
enet_packet_destroy(netEvent.packet); enet_packet_destroy(net_event.packet);
return 0; return 0;
} }
case ENET_EVENT_TYPE_DISCONNECT: case ENET_EVENT_TYPE_DISCONNECT:
@ -174,20 +174,20 @@ void SlippiMatchmaking::MatchmakeThread()
void SlippiMatchmaking::disconnectFromServer() void SlippiMatchmaking::disconnectFromServer()
{ {
isMmConnected = false; is_mm_connected = false;
if (m_server) if (m_server)
enet_peer_disconnect(m_server, 0); enet_peer_disconnect(m_server, 0);
else else
return; return;
ENetEvent netEvent; ENetEvent net_event;
while (enet_host_service(m_client, &netEvent, 3000) > 0) while (enet_host_service(m_client, &net_event, 3000) > 0)
{ {
switch (netEvent.type) switch (net_event.type)
{ {
case ENET_EVENT_TYPE_RECEIVE: case ENET_EVENT_TYPE_RECEIVE:
enet_packet_destroy(netEvent.packet); enet_packet_destroy(net_event.packet);
break; break;
case ENET_EVENT_TYPE_DISCONNECT: case ENET_EVENT_TYPE_DISCONNECT:
m_server = nullptr; m_server = nullptr;
@ -262,8 +262,8 @@ static enet_uint32 getLocalAddress(ENetAddress* mm_address)
return 0; return 0;
} }
ENetAddress enetAddress; ENetAddress enet_address;
if (enet_socket_get_address(socket, &enetAddress) == -1) if (enet_socket_get_address(socket, &enet_address) == -1)
{ {
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to get local address: socket get address"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to get local address: socket get address");
enet_socket_destroy(socket); enet_socket_destroy(socket);
@ -271,7 +271,7 @@ static enet_uint32 getLocalAddress(ENetAddress* mm_address)
} }
enet_socket_destroy(socket); enet_socket_destroy(socket);
return enetAddress.host; return enet_address.host;
} }
void SlippiMatchmaking::startMatchmaking() void SlippiMatchmaking::startMatchmaking()
@ -280,9 +280,9 @@ void SlippiMatchmaking::startMatchmaking()
// same value // same value
m_client = nullptr; m_client = nullptr;
int retryCount = 0; int retry_count = 0;
auto userInfo = m_user->GetUserInfo(); auto user_info = m_user->GetUserInfo();
while (m_client == nullptr && retryCount < 15) while (m_client == nullptr && retry_count < 15)
{ {
if (Config::Get(Config::SLIPPI_FORCE_NETPLAY_PORT)) if (Config::Get(Config::SLIPPI_FORCE_NETPLAY_PORT))
m_host_port = Config::Get(Config::SLIPPI_NETPLAY_PORT); m_host_port = Config::Get(Config::SLIPPI_NETPLAY_PORT);
@ -293,19 +293,19 @@ void SlippiMatchmaking::startMatchmaking()
// We are explicitly setting the client address because we are trying to utilize our connection // We are explicitly setting the client address because we are trying to utilize our connection
// to the matchmaking service in order to hole punch. This port will end up being the port // to the matchmaking service in order to hole punch. This port will end up being the port
// we listen on when we start our server // we listen on when we start our server
ENetAddress clientAddr; ENetAddress client_addr;
clientAddr.host = ENET_HOST_ANY; client_addr.host = ENET_HOST_ANY;
clientAddr.port = m_host_port; client_addr.port = m_host_port;
m_client = enet_host_create(&clientAddr, 1, 3, 0, 0); m_client = enet_host_create(&client_addr, 1, 3, 0, 0);
retryCount++; retry_count++;
} }
if (m_client == nullptr) if (m_client == nullptr)
{ {
// Failed to create client // Failed to create client
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Failed to create mm client"; m_error_msg = "Failed to create mm client";
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to create client..."); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to create client...");
return; return;
} }
@ -320,35 +320,35 @@ void SlippiMatchmaking::startMatchmaking()
{ {
// Failed to connect to server // Failed to connect to server
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Failed to start connection to mm server"; m_error_msg = "Failed to start connection to mm server";
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to start connection to mm server..."); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to start connection to mm server...");
return; return;
} }
// Before we can request a ticket, we must wait for connection to be successful // Before we can request a ticket, we must wait for connection to be successful
int connectAttemptCount = 0; int connect_attempt_count = 0;
while (!isMmConnected) while (!is_mm_connected)
{ {
ENetEvent netEvent; ENetEvent net_event;
int net = enet_host_service(m_client, &netEvent, 500); int net = enet_host_service(m_client, &net_event, 500);
if (net <= 0 || netEvent.type != ENET_EVENT_TYPE_CONNECT) if (net <= 0 || net_event.type != ENET_EVENT_TYPE_CONNECT)
{ {
// Not yet connected, will retry // Not yet connected, will retry
connectAttemptCount++; connect_attempt_count++;
if (connectAttemptCount >= 20) if (connect_attempt_count >= 20)
{ {
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to connect to mm server..."); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to connect to mm server...");
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Failed to connect to mm server"; m_error_msg = "Failed to connect to mm server";
return; return;
} }
continue; continue;
} }
netEvent.peer->data = &userInfo.display_name; net_event.peer->data = &user_info.display_name;
m_client->intercept = ENetUtil::InterceptCallback; m_client->intercept = ENetUtil::InterceptCallback;
isMmConnected = true; is_mm_connected = true;
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Connected to mm server..."); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Connected to mm server...");
} }
@ -358,20 +358,15 @@ void SlippiMatchmaking::startMatchmaking()
{ {
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Must be logged in to queue"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Must be logged in to queue");
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Must be logged in to queue. Go back to menu"; m_error_msg = "Must be logged in to queue. Go back to menu";
return; return;
}*/ }*/
// Determine local IP address. We can attempt to connect to our opponent via // Determine local IP address. We can attempt to connect to our opponent via
// LAN IP can be tried in order to establish a connection in the case where the players
// local IP address if we have the same external IP address. The following // local IP address if we have the same external IP address. The following
// don't have NAT loopback which allows that type of connection.
// scenarios can cause us to have the same external IP address: // scenarios can cause us to have the same external IP address:
// Right now though, the logic would replace the WAN IP with the LAN IP and if the LAN
// - we are connected to the same LAN // - we are connected to the same LAN
// IP connection didn't work but WAN would have, the players can no longer connect.
// - we are connected to the same VPN node // - we are connected to the same VPN node
// Two things need to happen to improtve this logic:
// - we are behind the same CGNAT // - we are behind the same CGNAT
char lan_addr[30]{}; char lan_addr[30]{};
@ -420,41 +415,41 @@ void SlippiMatchmaking::startMatchmaking()
WARN_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Sending LAN address: {}", lan_addr); WARN_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Sending LAN address: {}", lan_addr);
std::vector<u8> connectCodeBuf; std::vector<u8> connect_code_buf;
connectCodeBuf.insert(connectCodeBuf.end(), m_searchSettings.connectCode.begin(), connect_code_buf.insert(connect_code_buf.end(), m_search_settings.connect_code.begin(),
m_searchSettings.connectCode.end()); m_search_settings.connect_code.end());
// Send message to server to create ticket // Send message to server to create ticket
json request; json request;
request["type"] = MmMessageType::CREATE_TICKET; request["type"] = MmMessageType::CREATE_TICKET;
request["user"] = {{"uid", userInfo.uid}, request["user"] = {{"uid", user_info.uid},
{"playKey", userInfo.play_key}, {"playKey", user_info.play_key},
{"connectCode", userInfo.connect_code}, {"connectCode", user_info.connect_code},
{"displayName", userInfo.display_name}}; {"displayName", user_info.display_name}};
request["search"] = {{"mode", m_searchSettings.mode}, {"connectCode", connectCodeBuf}}; request["search"] = {{"mode", m_search_settings.mode}, {"connectCode", connect_code_buf}};
request["appVersion"] = Common::GetSemVerStr(); request["appVersion"] = Common::GetSemVerStr();
request["ipAddressLan"] = lan_addr; request["ipAddressLan"] = lan_addr;
sendMessage(request); sendMessage(request);
// Get response from server // Get response from server
json response; json response;
int rcvRes = receiveMessage(response, 5000); int rcv_res = receiveMessage(response, 5000);
if (rcvRes != 0) if (rcv_res != 0)
{ {
ERROR_LOG_FMT(SLIPPI_ONLINE, ERROR_LOG_FMT(SLIPPI_ONLINE,
"[Matchmaking] Did not receive response from server for create ticket"); "[Matchmaking] Did not receive response from server for create ticket");
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Failed to join mm queue"; m_error_msg = "Failed to join mm queue";
return; return;
} }
std::string respType = response["type"]; std::string resp_type = response["type"];
if (respType != MmMessageType::CREATE_TICKET_RESP) if (resp_type != MmMessageType::CREATE_TICKET_RESP)
{ {
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Received incorrect response for create ticket"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Received incorrect response for create ticket");
ERROR_LOG_FMT(SLIPPI_ONLINE, "{}", response.dump().c_str()); ERROR_LOG_FMT(SLIPPI_ONLINE, "{}", response.dump().c_str());
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Invalid response when joining mm queue"; m_error_msg = "Invalid response when joining mm queue";
return; return;
} }
@ -463,7 +458,7 @@ void SlippiMatchmaking::startMatchmaking()
{ {
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Received error from server for create ticket"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Received error from server for create ticket");
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = err; m_error_msg = err;
return; return;
} }
@ -478,93 +473,90 @@ void SlippiMatchmaking::handleMatchmaking()
return; return;
// Get response from server // Get response from server
json getResp; json get_resp;
int rcvRes = receiveMessage(getResp, 2000); int rcv_res = receiveMessage(get_resp, 2000);
if (rcvRes == -1) if (rcv_res == -1)
{ {
INFO_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Have not yet received assignment"); INFO_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Have not yet received assignment");
return; return;
} }
else if (rcvRes != 0) else if (rcv_res != 0)
{ {
// Right now the only other code is -2 meaning the server died probably? // Right now the only other code is -2 meaning the server died probably?
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Lost connection to the mm server"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Lost connection to the mm server");
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Lost connection to the mm server"; m_error_msg = "Lost connection to the mm server";
return; return;
} }
std::string respType = getResp["type"]; std::string resp_type = get_resp["type"];
if (respType != MmMessageType::GET_TICKET_RESP) if (resp_type != MmMessageType::GET_TICKET_RESP)
{ {
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Received incorrect response for get ticket"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Received incorrect response for get ticket");
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Invalid response when getting mm status"; m_error_msg = "Invalid response when getting mm status";
return; return;
} }
std::string err = getResp.value("error", ""); std::string err = get_resp.value("error", "");
std::string latestVersion = getResp.value("latestVersion", ""); std::string latestVersion = get_resp.value("latestVersion", "");
if (err.length() > 0) if (err.length() > 0)
{ {
if (latestVersion != "") if (latestVersion != "")
{ {
// Update version number when the mm server tells us our version is outdated // Update version number when the mm server tells us our version is outdated
m_user->OverwriteLatestVersion( // for people whose file updates dont work
latestVersion); // Force latest version for people whose file updates dont work m_user->OverwriteLatestVersion(latestVersion);
} }
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Received error from server for get ticket"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Received error from server for get ticket");
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = err; m_error_msg = err;
return; return;
} }
m_isSwapAttempt = false; m_is_swap_attempt = false;
m_netplayClient = nullptr; m_netplay_client = nullptr;
// Clear old users // Clear old users
m_remoteIps.clear(); m_remote_ips.clear();
m_playerInfo.clear(); m_player_info.clear();
std::string matchId = getResp.value("matchId", ""); std::string match_id = get_resp.value("matchId", "");
WARN_LOG_FMT(SLIPPI_ONLINE, "Match ID: {}", matchId);
std::string match_id = getResp.value("matchId", "");
WARN_LOG_FMT(SLIPPI_ONLINE, "Match ID: {}", match_id); WARN_LOG_FMT(SLIPPI_ONLINE, "Match ID: {}", match_id);
auto queue = getResp["players"]; auto queue = get_resp["players"];
if (queue.is_array()) if (queue.is_array())
{ {
std::string localExternalIp = ""; std::string local_external_ip = "";
for (json::iterator it = queue.begin(); it != queue.end(); ++it) for (json::iterator it = queue.begin(); it != queue.end(); ++it)
{ {
json el = *it; json el = *it;
SlippiUser::UserInfo playerInfo; SlippiUser::UserInfo player_info;
bool isLocal = el.value("isLocalPlayer", false); bool is_local = el.value("isLocalPlayer", false);
playerInfo.uid = el.value("uid", ""); player_info.uid = el.value("uid", "");
playerInfo.display_name = el.value("displayName", ""); player_info.display_name = el.value("displayName", "");
playerInfo.connect_code = el.value("connectCode", ""); player_info.connect_code = el.value("connectCode", "");
playerInfo.port = el.value("port", 0); player_info.port = el.value("port", 0);
playerInfo.chat_messages = SlippiUser::default_chat_messages; player_info.chat_messages = SlippiUser::default_chat_messages;
if (el["chatMessages"].is_array()) if (el["chatMessages"].is_array())
{ {
playerInfo.chat_messages = el.value("chatMessages", SlippiUser::default_chat_messages); player_info.chat_messages = el.value("chatMessages", SlippiUser::default_chat_messages);
if (playerInfo.chat_messages.size() != 16) if (player_info.chat_messages.size() != 16)
{ {
playerInfo.chat_messages = SlippiUser::default_chat_messages; player_info.chat_messages = SlippiUser::default_chat_messages;
} }
} }
m_playerInfo.push_back(playerInfo); m_player_info.push_back(player_info);
if (isLocal) if (is_local)
{ {
std::vector<std::string> localIpParts; std::vector<std::string> local_ip_parts;
localIpParts = SplitString(el.value("ipAddress", "1.1.1.1:123"), ':'); local_ip_parts = SplitString(el.value("ipAddress", "1.1.1.1:123"), ':');
localExternalIp = localIpParts[0]; local_external_ip = local_ip_parts[0];
m_localPlayerIndex = playerInfo.port - 1; m_local_player_idx = player_info.port - 1;
} }
}; };
@ -573,96 +565,95 @@ void SlippiMatchmaking::handleMatchmaking()
{ {
json el = *it; json el = *it;
if (el.value("port", 0) - 1 == m_localPlayerIndex) if (el.value("port", 0) - 1 == m_local_player_idx)
continue; continue;
auto extIp = el.value("ipAddress", "1.1.1.1:123"); auto ext_ip = el.value("ipAddress", "1.1.1.1:123");
std::vector<std::string> exIpParts; std::vector<std::string> ext_ip_parts = SplitString(ext_ip, ':');
exIpParts = SplitString(extIp, ':');
auto lanIp = el.value("ipAddressLan", "1.1.1.1:123"); auto lanIp = el.value("ipAddressLan", "1.1.1.1:123");
WARN_LOG_FMT(SLIPPI_ONLINE, "LAN IP: {}", lanIp.c_str()); WARN_LOG_FMT(SLIPPI_ONLINE, "LAN IP: {}", lanIp.c_str());
if (exIpParts[0] != localExternalIp || lanIp.empty()) if (ext_ip_parts[0] != local_external_ip || lanIp.empty())
{ {
// If external IPs are different, just use that address // If external IPs are different, just use that address
m_remoteIps.push_back(extIp); m_remote_ips.push_back(ext_ip);
continue; continue;
} }
// TODO: Instead of using one or the other, it might be better to try both // TODO: Instead of using one or the other, it might be better to try both
// If external IPs are the same, try using LAN IPs // If external IPs are the same, try using LAN IPs
m_remoteIps.push_back(lanIp); m_remote_ips.push_back(lanIp);
} }
} }
m_isHost = getResp.value("isHost", false); m_is_host = get_resp.value("isHost", false);
// Get allowed stages. For stage select modes like direct and teams, this will only impact the // Get allowed stages. For stage select modes like direct and teams, this will only impact the
// first map selected // first map selected
m_allowedStages.clear(); m_allowed_stages.clear();
auto stages = getResp["stages"]; auto stages = get_resp["stages"];
if (stages.is_array()) if (stages.is_array())
{ {
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 stage_id = el.get<int>(); auto stage_id = el.get<int>();
m_allowedStages.push_back(stage_id); m_allowed_stages.push_back(stage_id);
} }
} }
if (m_allowedStages.empty()) if (m_allowed_stages.empty())
{ {
// Default case, shouldn't ever really be hit but it's here just in case // Default case, shouldn't ever really be hit but it's here just in case
m_allowedStages.push_back(0x3); // Pokemon m_allowed_stages.push_back(0x3); // Pokemon
m_allowedStages.push_back(0x8); // Yoshi's Story m_allowed_stages.push_back(0x8); // Yoshi's Story
m_allowedStages.push_back(0x1C); // Dream Land m_allowed_stages.push_back(0x1C); // Dream Land
m_allowedStages.push_back(0x1F); // Battlefield m_allowed_stages.push_back(0x1F); // Battlefield
m_allowedStages.push_back(0x20); // Final Destination m_allowed_stages.push_back(0x20); // Final Destination
// Add FoD if singles // Add FoD if singles
if (m_playerInfo.size() == 2) if (m_player_info.size() == 2)
{ {
m_allowedStages.push_back(0x2); // FoD m_allowed_stages.push_back(0x2); // FoD
} }
} }
m_mm_result.id = match_id; m_mm_result.id = match_id;
m_mm_result.players = m_playerInfo; m_mm_result.players = m_player_info;
m_mm_result.stages = m_allowedStages; m_mm_result.stages = m_allowed_stages;
// Disconnect and destroy enet client to mm server // Disconnect and destroy enet client to mm server
terminateMmConnection(); terminateMmConnection();
m_state = ProcessState::OPPONENT_CONNECTING; m_state = ProcessState::OPPONENT_CONNECTING;
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Opponent found. is_decider: {}", ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Opponent found. is_decider: {}",
m_isHost ? "true" : "false"); m_is_host ? "true" : "false");
} }
int SlippiMatchmaking::LocalPlayerIndex() int SlippiMatchmaking::LocalPlayerIndex()
{ {
return m_localPlayerIndex; return m_local_player_idx;
} }
std::vector<SlippiUser::UserInfo> SlippiMatchmaking::GetPlayerInfo() std::vector<SlippiUser::UserInfo> SlippiMatchmaking::GetPlayerInfo()
{ {
return m_playerInfo; return m_player_info;
} }
std::vector<u16> SlippiMatchmaking::GetStages() std::vector<u16> SlippiMatchmaking::GetStages()
{ {
return m_allowedStages; return m_allowed_stages;
} }
std::string SlippiMatchmaking::GetPlayerName(u8 port) std::string SlippiMatchmaking::GetPlayerName(u8 port)
{ {
if (port >= m_playerInfo.size()) if (port >= m_player_info.size())
{ {
return ""; return "";
} }
return m_playerInfo[port].display_name; return m_player_info[port].display_name;
} }
SlippiMatchmaking::MatchmakeResult SlippiMatchmaking::GetMatchmakeResult() SlippiMatchmaking::MatchmakeResult SlippiMatchmaking::GetMatchmakeResult()
@ -672,44 +663,44 @@ SlippiMatchmaking::MatchmakeResult SlippiMatchmaking::GetMatchmakeResult()
u8 SlippiMatchmaking::RemotePlayerCount() u8 SlippiMatchmaking::RemotePlayerCount()
{ {
if (m_playerInfo.size() == 0) if (m_player_info.size() == 0)
return 0; return 0;
return (u8)m_playerInfo.size() - 1; return (u8)m_player_info.size() - 1;
} }
void SlippiMatchmaking::handleConnecting() void SlippiMatchmaking::handleConnecting()
{ {
auto userInfo = m_user->GetUserInfo(); auto user_info = m_user->GetUserInfo();
m_isSwapAttempt = false; m_is_swap_attempt = false;
m_netplayClient = nullptr; m_netplay_client = nullptr;
u8 remotePlayerCount = (u8)m_remoteIps.size(); u8 remote_player_count = (u8)m_remote_ips.size();
std::vector<std::string> remoteParts; std::vector<std::string> remote_parts;
std::vector<std::string> addrs; std::vector<std::string> addrs;
std::vector<u16> ports; std::vector<u16> ports;
for (int i = 0; i < m_remoteIps.size(); i++) for (int i = 0; i < m_remote_ips.size(); i++)
{ {
remoteParts.clear(); remote_parts.clear();
remoteParts = SplitString(m_remoteIps[i], ':'); remote_parts = SplitString(m_remote_ips[i], ':');
addrs.push_back(remoteParts[0]); addrs.push_back(remote_parts[0]);
ports.push_back(std::stoi(remoteParts[1])); ports.push_back(std::stoi(remote_parts[1]));
} }
std::stringstream ipLog; std::stringstream ip_log;
ipLog << "Remote player IPs: "; ip_log << "Remote player IPs: ";
for (int i = 0; i < m_remoteIps.size(); i++) for (int i = 0; i < m_remote_ips.size(); i++)
{ {
ipLog << m_remoteIps[i] << ", "; ip_log << m_remote_ips[i] << ", ";
} }
// INFO_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] My port: {} || {}", m_host_port, ipLog.str()); // INFO_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] My port: {} || {}", m_host_port, ip_log.str());
// Is host is now used to specify who the decider is // Is host is now used to specify who the decider is
auto client = std::make_unique<SlippiNetplayClient>(addrs, ports, remotePlayerCount, m_host_port, auto client = std::make_unique<SlippiNetplayClient>(addrs, ports, remote_player_count,
m_isHost, m_localPlayerIndex); m_host_port, m_is_host, m_local_player_idx);
while (!m_netplayClient) while (!m_netplay_client)
{ {
auto status = client->GetSlippiConnectStatus(); auto status = client->GetSlippiConnectStatus();
if (status == SlippiNetplayClient::SlippiConnectStatus::NET_CONNECT_STATUS_INITIATED) if (status == SlippiNetplayClient::SlippiConnectStatus::NET_CONNECT_STATUS_INITIATED)
@ -724,29 +715,29 @@ void SlippiMatchmaking::handleConnecting()
continue; continue;
} }
else if (status == SlippiNetplayClient::SlippiConnectStatus::NET_CONNECT_STATUS_FAILED && else if (status == SlippiNetplayClient::SlippiConnectStatus::NET_CONNECT_STATUS_FAILED &&
m_searchSettings.mode == SlippiMatchmaking::OnlinePlayMode::TEAMS) m_search_settings.mode == SlippiMatchmaking::OnlinePlayMode::TEAMS)
{ {
// If we failed setting up a connection in teams mode, show a detailed error about who we had // If we failed setting up a connection in teams mode, show a detailed error about who we had
// issues connecting to. // issues connecting to.
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to connect to players"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Failed to connect to players");
m_state = ProcessState::ERROR_ENCOUNTERED; m_state = ProcessState::ERROR_ENCOUNTERED;
m_errorMsg = "Timed out waiting for other players to connect"; m_error_msg = "Timed out waiting for other players to connect";
auto failedConns = client->GetFailedConnections(); auto failed_conns = client->GetFailedConnections();
if (!failedConns.empty()) if (!failed_conns.empty())
{ {
std::stringstream err; std::stringstream err;
err << "Could not connect to players: "; err << "Could not connect to players: ";
for (int i = 0; i < failedConns.size(); i++) for (int i = 0; i < failed_conns.size(); i++)
{ {
int p = failedConns[i]; int p = failed_conns[i];
if (p >= m_localPlayerIndex) if (p >= m_local_player_idx)
p++; p++;
err << m_playerInfo[p].display_name; err << m_player_info[p].display_name;
if (i < failedConns.size() - 1) if (i < failed_conns.size() - 1)
err << ", "; err << ", ";
} }
m_errorMsg = err.str(); m_error_msg = err.str();
} }
return; return;
@ -757,7 +748,7 @@ void SlippiMatchmaking::handleConnecting()
"[Matchmaking] Connection attempt failed, looking for someone else."); "[Matchmaking] Connection attempt failed, looking for someone else.");
// Return to the start to get a new ticket to find someone else we can hopefully connect with // Return to the start to get a new ticket to find someone else we can hopefully connect with
m_netplayClient = nullptr; m_netplay_client = nullptr;
m_state = ProcessState::INITIALIZING; m_state = ProcessState::INITIALIZING;
return; return;
} }
@ -765,7 +756,7 @@ void SlippiMatchmaking::handleConnecting()
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Connection success!"); ERROR_LOG_FMT(SLIPPI_ONLINE, "[Matchmaking] Connection success!");
// Successful connection // Successful connection
m_netplayClient = std::move(client); m_netplay_client = std::move(client);
} }
// Connection success, our work is done // Connection success, our work is done

View file

@ -44,7 +44,7 @@ public:
struct MatchSearchSettings struct MatchSearchSettings
{ {
OnlinePlayMode mode = OnlinePlayMode::RANKED; OnlinePlayMode mode = OnlinePlayMode::RANKED;
std::string connectCode = ""; std::string connect_code = "";
}; };
struct MatchmakeResult struct MatchmakeResult
@ -80,32 +80,32 @@ protected:
std::default_random_engine generator; std::default_random_engine generator;
bool isMmConnected = false; bool is_mm_connected = false;
bool is_mm_terminated = false; bool is_mm_terminated = false;
std::thread m_matchmakeThread; std::thread m_matchmake_thread;
MatchSearchSettings m_searchSettings; MatchSearchSettings m_search_settings;
ProcessState m_state; ProcessState m_state;
std::string m_errorMsg = ""; std::string m_error_msg = "";
SlippiUser* m_user; SlippiUser* m_user;
int m_isSwapAttempt = false; int m_is_swap_attempt = false;
int m_host_port; int m_host_port;
int m_localPlayerIndex; int m_local_player_idx;
std::vector<std::string> m_remoteIps; std::vector<std::string> m_remote_ips;
MatchmakeResult m_mm_result; MatchmakeResult m_mm_result;
std::vector<SlippiUser::UserInfo> m_playerInfo; std::vector<SlippiUser::UserInfo> m_player_info;
std::vector<u16> m_allowedStages; std::vector<u16> m_allowed_stages;
bool m_joinedLobby; bool m_joined_lobby;
bool m_isHost; bool m_is_host;
std::unique_ptr<SlippiNetplayClient> m_netplayClient; std::unique_ptr<SlippiNetplayClient> m_netplay_client;
const std::unordered_map<ProcessState, bool> searchingStates = { const std::unordered_map<ProcessState, bool> searching_states = {
{ProcessState::INITIALIZING, true}, {ProcessState::INITIALIZING, true},
{ProcessState::MATCHMAKING, true}, {ProcessState::MATCHMAKING, true},
{ProcessState::OPPONENT_CONNECTING, true}, {ProcessState::OPPONENT_CONNECTING, true},
@ -114,7 +114,7 @@ protected:
void disconnectFromServer(); void disconnectFromServer();
void terminateMmConnection(); void terminateMmConnection();
void sendMessage(json msg); void sendMessage(json msg);
int receiveMessage(json& msg, int maxAttempts); int receiveMessage(json& msg, int max_attempts);
void startMatchmaking(); void startMatchmaking();
void handleMatchmaking(); void handleMatchmaking();