pull in project-slippi/Ishiiruka/commit/9ed8bbc1f3d113808150de97ffb0a78afcd1df4d and project-slippi/Ishiiruka/commit/e6b5286f08088ea029c1c1c8ca58d117bde26b93

This commit is contained in:
Nikhil Narayana 2022-05-29 23:58:26 -07:00
commit cf793e5560
3 changed files with 93 additions and 35 deletions

View file

@ -177,7 +177,6 @@ private:
void handleSendInputs(u8* payload); void handleSendInputs(u8* payload);
void handleCaptureSavestate(u8* payload); void handleCaptureSavestate(u8* payload);
void handleLoadSavestate(u8* payload); void handleLoadSavestate(u8* payload);
void handleNameEntryAutoComplete(u8* payload);
void handleNameEntryLoad(u8* payload); void handleNameEntryLoad(u8* payload);
void startFindMatch(u8* payload); void startFindMatch(u8* payload);
void prepareOnlineMatchState(); void prepareOnlineMatchState();

View file

@ -125,6 +125,12 @@ SlippiNetplayClient::SlippiNetplayClient(std::vector<std::string> addrs, std::ve
ENetPeer* peer = enet_host_connect(m_client, &addr, 3, 0); ENetPeer* peer = enet_host_connect(m_client, &addr, 3, 0);
m_server.push_back(peer); m_server.push_back(peer);
// Store this connection
std::stringstream keyStrm;
keyStrm << addr.host << "-" << addr.port;
activeConnections[keyStrm.str()][peer] = true;
INFO_LOG_FMT(SLIPPI_ONLINE, "New connection (constr): {}", keyStrm.str().c_str());
if (peer == nullptr) if (peer == nullptr)
{ {
PanicAlertT("Couldn't create peer."); PanicAlertT("Couldn't create peer.");
@ -466,15 +472,18 @@ void SlippiNetplayClient::Disconnect()
{ {
ENetEvent netEvent; ENetEvent netEvent;
slippiConnectStatus = SlippiConnectStatus::NET_CONNECT_STATUS_DISCONNECTED; slippiConnectStatus = SlippiConnectStatus::NET_CONNECT_STATUS_DISCONNECTED;
if (!m_server.empty()) if (activeConnections.empty())
for (int i = 0; i < m_server.size(); i++)
{
INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Disconnecting peer {}", m_server[i]->address.port);
enet_peer_disconnect(m_server[i], 0);
}
else
return; return;
for (auto conn : activeConnections)
{
for (auto peer : conn.second)
{
INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Disconnecting peer {}", peer.first->address.port);
enet_peer_disconnect(peer.first, 0);
}
}
while (enet_host_service(m_client, &netEvent, 3000) > 0) while (enet_host_service(m_client, &netEvent, 3000) > 0)
{ {
switch (netEvent.type) switch (netEvent.type)
@ -491,10 +500,14 @@ void SlippiNetplayClient::Disconnect()
} }
} }
// didn't disconnect gracefully force disconnect // didn't disconnect gracefully force disconnect
for (int i = 0; i < m_server.size(); i++) for (auto conn : activeConnections)
{ {
enet_peer_reset(m_server[i]); for (auto peer : conn.second)
{
enet_peer_reset(peer.first);
}
} }
activeConnections.clear();
m_server.clear(); m_server.clear();
SLIPPI_NETPLAY = nullptr; SLIPPI_NETPLAY = nullptr;
} }
@ -539,8 +552,8 @@ void SlippiNetplayClient::ThreadFunc()
INFO_LOG(SLIPPI_ONLINE, "[Netplay] got receive event with nil peer"); INFO_LOG(SLIPPI_ONLINE, "[Netplay] got receive event with nil peer");
continue; continue;
} }
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got receive event with peer addr {}:{}", INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got receive event with peer addr {}:{}",
netEvent.peer->address.host, netEvent.peer->address.port); netEvent.peer->address.host, netEvent.peer->address.port);
rpac.append(netEvent.packet->data, netEvent.packet->dataLength); rpac.append(netEvent.packet->data, netEvent.packet->dataLength);
OnData(rpac, netEvent.peer); OnData(rpac, netEvent.peer);
@ -566,6 +579,11 @@ void SlippiNetplayClient::ThreadFunc()
continue; continue;
} }
std::stringstream keyStrm;
keyStrm << netEvent.peer->address.host << "-" << netEvent.peer->address.port;
activeConnections[keyStrm.str()][netEvent.peer] = true;
INFO_LOG_FMT(SLIPPI_ONLINE, "New connection (early): {}", keyStrm.str().c_str());
INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got connect event with peer addr {}:{}", INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] got connect event with peer addr {}:{}",
netEvent.peer->address.host, netEvent.peer->address.port); netEvent.peer->address.host, netEvent.peer->address.port);
@ -586,7 +604,7 @@ void SlippiNetplayClient::ThreadFunc()
// Don't add this person again if they are already connected. Not doing this can cause one // Don't add this person again if they are already connected. Not doing this can cause one
// person to take up 2 or more spots, denying one or more players from connecting and thus // person to take up 2 or more spots, denying one or more players from connecting and thus
// getting stuck on the "Waiting" step // getting stuck on the "Waiting" step
ERROR_LOG(SLIPPI_ONLINE, "Already connected!"); INFO_LOG(SLIPPI_ONLINE, "Already connected!");
break; // Breaks out of case break; // Breaks out of case
} }
@ -639,7 +657,7 @@ void SlippiNetplayClient::ThreadFunc()
{ {
INFO_LOG_FMT(SLIPPI_ONLINE, "m_client peer {} state: {}", i, m_client->peers[i].state); INFO_LOG_FMT(SLIPPI_ONLINE, "m_client peer {} state: {}", i, m_client->peers[i].state);
} }
WARN_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Not yet connected. Res: {}, Type: {}", net, INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Not yet connected. Res: {}, Type: {}", net,
netEvent.type); netEvent.type);
// Time out after enough time has passed // Time out after enough time has passed
@ -728,35 +746,74 @@ void SlippiNetplayClient::ThreadFunc()
if (net > 0) if (net > 0)
{ {
sf::Packet rpac; sf::Packet rpac;
bool isConnectedClient = false;
switch (netEvent.type) switch (netEvent.type)
{ {
case ENET_EVENT_TYPE_RECEIVE: case ENET_EVENT_TYPE_RECEIVE:
rpac.append(netEvent.packet->data, netEvent.packet->dataLength); {
OnData(rpac, netEvent.peer); int oppIdx = 0;
for (int i = 0; i < m_server.size(); i++)
enet_packet_destroy(netEvent.packet);
break;
case ENET_EVENT_TYPE_DISCONNECT:
for (int i = 0; i < m_remotePlayerCount; i++)
{ {
if (remoteAddrs[i].host == netEvent.peer->address.host && if (netEvent.peer->address.host == m_server[i]->address.host &&
remoteAddrs[i].port == netEvent.peer->address.port) netEvent.peer->address.port == m_server[i]->address.port)
{ {
isConnectedClient = true; oppIdx = i;
break; break;
} }
} }
ERROR_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Disconnected Event detected: {}",
isConnectedClient ? "connected client" : "superfluous client"); // Here we check if we have more than 1 connection for a specific player, this can happen
// because both players try to connect to each other at the same time to increase the odds
// that one direction might work and for hole punching. That said there's no point in
// keeping more than 1 connection alive. I think they might use bandwidth with keep alives
// or something. Only the lower port player will initiate the disconnect
std::stringstream keyStrm;
keyStrm << netEvent.peer->address.host << "-" << netEvent.peer->address.port;
if (activeConnections[keyStrm.str()].size() > 1 && m_player_idx <= oppIdx)
{
m_server[oppIdx] = netEvent.peer;
INFO_LOG(SLIPPI_ONLINE, "Multiple connections detected for single peer. Initiating "
"process to disconnect superfluous connections.");
for (auto peer : activeConnections[keyStrm.str()])
{
if (peer.first == netEvent.peer)
continue;
enet_peer_disconnect(peer.first, 0);
}
}
rpac.append(netEvent.packet->data, netEvent.packet->dataLength);
OnData(rpac, netEvent.peer);
enet_packet_destroy(netEvent.packet);
break;
}
case ENET_EVENT_TYPE_DISCONNECT:
{
std::stringstream keyStrm;
keyStrm << netEvent.peer->address.host << "-" << netEvent.peer->address.port;
activeConnections[keyStrm.str()].erase(netEvent.peer);
/*INFO_LOG_FMT(SLIPPI_ONLINE, "[Netplay] Disconnect late {}:{}. {}. Remaining connections:
{}", netEvent.peer->address.host, netEvent.peer->address.port, netEvent.peer,
activeConnections[keyStrm.str()].size());*/
// If the disconnect event doesn't come from the client we are actually listening to, // If the disconnect event doesn't come from the client we are actually listening to,
// it can be safely ignored // it can be safely ignored
if (isConnectedClient) if (activeConnections[keyStrm.str()].empty())
{ {
INFO_LOG(SLIPPI_ONLINE, "[Netplay] Final disconnect received for a client.");
m_do_loop.Clear(); // Stop the loop, will trigger a disconnect m_do_loop.Clear(); // Stop the loop, will trigger a disconnect
} }
break; break;
}
case ENET_EVENT_TYPE_CONNECT:
{
std::stringstream keyStrm;
keyStrm << netEvent.peer->address.host << "-" << netEvent.peer->address.port;
activeConnections[keyStrm.str()][netEvent.peer] = true;
INFO_LOG_FMT(SLIPPI_ONLINE, "New connection (late): {}", keyStrm.str().c_str());
break;
}
default: default:
break; break;
} }
@ -857,14 +914,14 @@ void SlippiNetplayClient::SendSlippiPad(std::unique_ptr<SlippiPad> pad)
if (lastFrameAcked[i] < minAckFrame) if (lastFrameAcked[i] < minAckFrame)
minAckFrame = lastFrameAcked[i]; minAckFrame = lastFrameAcked[i];
} }
INFO_LOG_FMT(SLIPPI_ONLINE, /*INFO_LOG_FMT(SLIPPI_ONLINE,
"Checking to drop local inputs, oldest frame: {} | minAckFrame: {} | {}, {}, {}", "Checking to drop local inputs, oldest frame: {} | minAckFrame: {} | {}, {}, {}",
localPadQueue.back()->frame, minAckFrame, lastFrameAcked[0], lastFrameAcked[1], localPadQueue.back()->frame, minAckFrame, lastFrameAcked[0], lastFrameAcked[1],
lastFrameAcked[2]); lastFrameAcked[2]);*/
while (!localPadQueue.empty() && localPadQueue.back()->frame < minAckFrame) while (!localPadQueue.empty() && localPadQueue.back()->frame < minAckFrame)
{ {
INFO_LOG_FMT(SLIPPI_ONLINE, "Dropping local input for frame {} from queue", /*INFO_LOG_FMT(SLIPPI_ONLINE, "Dropping local input for frame {} from queue",
localPadQueue.back()->frame); localPadQueue.back()->frame);*/
localPadQueue.pop_back(); localPadQueue.pop_back();
} }
@ -997,12 +1054,12 @@ void SlippiNetplayClient::DropOldRemoteInputs(int32_t curFrame)
for (int i = 0; i < m_remotePlayerCount; i++) for (int i = 0; i < m_remotePlayerCount; i++)
{ {
INFO_LOG_FMT(SLIPPI_ONLINE, "remotePadQueue[{}] size: {}", i, remotePadQueue[i].size()); // INFO_LOG_FMT(SLIPPI_ONLINE, "remotePadQueue[{}] size: {}", i, remotePadQueue[i].size());
while (remotePadQueue[i].size() > 1 && remotePadQueue[i].back()->frame < lowestCommonFrame && while (remotePadQueue[i].size() > 1 && remotePadQueue[i].back()->frame < lowestCommonFrame &&
remotePadQueue[i].back()->frame < curFrame) remotePadQueue[i].back()->frame < curFrame)
{ {
INFO_LOG_FMT(SLIPPI_ONLINE, "Popping inputs for frame {} from back of player {} queue", /*INFO_LOG_FMT(SLIPPI_ONLINE, "Popping inputs for frame {} from back of player {} queue",
remotePadQueue[i].back()->frame, i); remotePadQueue[i].back()->frame, i);*/
remotePadQueue[i].pop_back(); remotePadQueue[i].pop_back();
} }
} }

View file

@ -194,6 +194,8 @@ protected:
bool hasGameStarted = false; bool hasGameStarted = false;
u8 m_player_idx = 0; u8 m_player_idx = 0;
std::unordered_map<std::string, std::map<ENetPeer*, bool>> activeConnections;
std::deque<std::unique_ptr<SlippiPad>> localPadQueue; // most recent inputs at start of deque std::deque<std::unique_ptr<SlippiPad>> localPadQueue; // 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 remotePadQueue[SLIPPI_REMOTE_PLAYER_MAX]; // most recent inputs at start of deque