From f68dbed5351c33ec975445eb832e75b5e68a6fb2 Mon Sep 17 00:00:00 2001 From: Techjar Date: Mon, 9 Jul 2018 16:45:52 -0400 Subject: [PATCH] NetPlay: Bundle multiple local pads into one packet This saves a significant amount of bandwidth with multiple controllers on one client, as most of the packet is just protocol overhead. --- Source/Core/Core/NetPlayClient.cpp | 40 +++++++++++++++++++----------- Source/Core/Core/NetPlayClient.h | 2 +- Source/Core/Core/NetPlayServer.cpp | 40 +++++++++++++++++------------- 3 files changed, 49 insertions(+), 33 deletions(-) diff --git a/Source/Core/Core/NetPlayClient.cpp b/Source/Core/Core/NetPlayClient.cpp index 99863ce273..7fa576a3ef 100644 --- a/Source/Core/Core/NetPlayClient.cpp +++ b/Source/Core/Core/NetPlayClient.cpp @@ -334,15 +334,20 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet) case NP_MSG_PAD_DATA: { - PadMapping map = 0; - GCPadStatus pad; - packet >> map >> pad.button >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >> - pad.substickX >> pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected; + while (!packet.endOfPacket()) + { + PadMapping map; + packet >> map; - // Trusting server for good map value (>=0 && <4) - // add to pad buffer - m_pad_buffer.at(map).Push(pad); - m_gc_pad_event.Set(); + GCPadStatus pad; + packet >> pad.button >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >> + pad.substickX >> pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected; + + // Trusting server for good map value (>=0 && <4) + // add to pad buffer + m_pad_buffer.at(map).Push(pad); + m_gc_pad_event.Set(); + } } break; @@ -778,15 +783,12 @@ void NetPlayClient::SendChatMessage(const std::string& msg) } // called from ---CPU--- thread -void NetPlayClient::SendPadState(const int in_game_pad, const GCPadStatus& pad) +void NetPlayClient::AddPadStateToPacket(const int in_game_pad, const GCPadStatus& pad, + sf::Packet& packet) { - sf::Packet packet; - packet << static_cast(NP_MSG_PAD_DATA); packet << static_cast(in_game_pad); packet << pad.button << pad.analogA << pad.analogB << pad.stickX << pad.stickY << pad.substickX << pad.substickY << pad.triggerLeft << pad.triggerRight << pad.isConnected; - - SendAsync(std::move(packet)); } // called from ---CPU--- thread @@ -1000,6 +1002,10 @@ bool NetPlayClient::GetNetPads(const int pad_nb, GCPadStatus* pad_status) // clients. if (IsFirstInGamePad(pad_nb)) { + sf::Packet packet; + packet << static_cast(NP_MSG_PAD_DATA); + + bool send_packet = false; const int num_local_pads = NumLocalPads(); for (int local_pad = 0; local_pad < num_local_pads; local_pad++) { @@ -1023,10 +1029,14 @@ bool NetPlayClient::GetNetPads(const int pad_nb, GCPadStatus* pad_status) // add to buffer m_pad_buffer[ingame_pad].Push(*pad_status); - // send - SendPadState(ingame_pad, *pad_status); + // add to packet + AddPadStateToPacket(ingame_pad, *pad_status, packet); + send_packet = true; } } + + if (send_packet) + SendAsync(std::move(packet)); } // Now, we either use the data pushed earlier, or wait for the diff --git a/Source/Core/Core/NetPlayClient.h b/Source/Core/Core/NetPlayClient.h index c4ababf068..464337b9ea 100644 --- a/Source/Core/Core/NetPlayClient.h +++ b/Source/Core/Core/NetPlayClient.h @@ -159,7 +159,7 @@ private: void SendStopGamePacket(); void UpdateDevices(); - void SendPadState(int in_game_pad, const GCPadStatus& np); + void AddPadStateToPacket(int in_game_pad, const GCPadStatus& np, sf::Packet& packet); void SendWiimoteState(int in_game_pad, const NetWiimote& nw); unsigned int OnData(sf::Packet& packet); void Send(const sf::Packet& packet); diff --git a/Source/Core/Core/NetPlayServer.cpp b/Source/Core/Core/NetPlayServer.cpp index 78ad81364c..1a185a6c7d 100644 --- a/Source/Core/Core/NetPlayServer.cpp +++ b/Source/Core/Core/NetPlayServer.cpp @@ -526,24 +526,30 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player) if (player.current_game != m_current_game) break; - PadMapping map = 0; - GCPadStatus pad; - packet >> map >> pad.button >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >> - pad.substickX >> pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected; - - // If the data is not from the correct player, - // then disconnect them. - if (m_pad_map.at(map) != player.pid) - { - return 1; - } - - // Relay to clients sf::Packet spac; - spac << (MessageId)NP_MSG_PAD_DATA; - spac << map << pad.button << pad.analogA << pad.analogB << pad.stickX << pad.stickY - << pad.substickX << pad.substickY << pad.triggerLeft << pad.triggerRight - << pad.isConnected; + spac << static_cast(NP_MSG_PAD_DATA); + + while (!packet.endOfPacket()) + { + PadMapping map; + packet >> map; + + // If the data is not from the correct player, + // then disconnect them. + if (m_pad_map.at(map) != player.pid) + { + return 1; + } + + GCPadStatus pad; + packet >> pad.button >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >> + pad.substickX >> pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected; + + // Add to packet for relay to clients + spac << map << pad.button << pad.analogA << pad.analogB << pad.stickX << pad.stickY + << pad.substickX << pad.substickY << pad.triggerLeft << pad.triggerRight + << pad.isConnected; + } SendToClients(spac, player.pid); }