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.
This commit is contained in:
Techjar 2018-07-09 16:45:52 -04:00
parent 31d9ca34e3
commit f68dbed535
3 changed files with 49 additions and 33 deletions

View file

@ -334,9 +334,13 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
case NP_MSG_PAD_DATA: case NP_MSG_PAD_DATA:
{ {
PadMapping map = 0; while (!packet.endOfPacket())
{
PadMapping map;
packet >> map;
GCPadStatus pad; GCPadStatus pad;
packet >> map >> pad.button >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >> packet >> pad.button >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >>
pad.substickX >> pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected; pad.substickX >> pad.substickY >> pad.triggerLeft >> pad.triggerRight >> pad.isConnected;
// Trusting server for good map value (>=0 && <4) // Trusting server for good map value (>=0 && <4)
@ -344,6 +348,7 @@ unsigned int NetPlayClient::OnData(sf::Packet& packet)
m_pad_buffer.at(map).Push(pad); m_pad_buffer.at(map).Push(pad);
m_gc_pad_event.Set(); m_gc_pad_event.Set();
} }
}
break; break;
case NP_MSG_WIIMOTE_DATA: case NP_MSG_WIIMOTE_DATA:
@ -778,15 +783,12 @@ void NetPlayClient::SendChatMessage(const std::string& msg)
} }
// called from ---CPU--- thread // 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<MessageId>(NP_MSG_PAD_DATA);
packet << static_cast<PadMapping>(in_game_pad); packet << static_cast<PadMapping>(in_game_pad);
packet << pad.button << pad.analogA << pad.analogB << pad.stickX << pad.stickY << pad.substickX packet << pad.button << pad.analogA << pad.analogB << pad.stickX << pad.stickY << pad.substickX
<< pad.substickY << pad.triggerLeft << pad.triggerRight << pad.isConnected; << pad.substickY << pad.triggerLeft << pad.triggerRight << pad.isConnected;
SendAsync(std::move(packet));
} }
// called from ---CPU--- thread // called from ---CPU--- thread
@ -1000,6 +1002,10 @@ bool NetPlayClient::GetNetPads(const int pad_nb, GCPadStatus* pad_status)
// clients. // clients.
if (IsFirstInGamePad(pad_nb)) if (IsFirstInGamePad(pad_nb))
{ {
sf::Packet packet;
packet << static_cast<MessageId>(NP_MSG_PAD_DATA);
bool send_packet = false;
const int num_local_pads = NumLocalPads(); const int num_local_pads = NumLocalPads();
for (int local_pad = 0; local_pad < num_local_pads; local_pad++) 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 // add to buffer
m_pad_buffer[ingame_pad].Push(*pad_status); m_pad_buffer[ingame_pad].Push(*pad_status);
// send // add to packet
SendPadState(ingame_pad, *pad_status); 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 // Now, we either use the data pushed earlier, or wait for the

View file

@ -159,7 +159,7 @@ private:
void SendStopGamePacket(); void SendStopGamePacket();
void UpdateDevices(); 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); void SendWiimoteState(int in_game_pad, const NetWiimote& nw);
unsigned int OnData(sf::Packet& packet); unsigned int OnData(sf::Packet& packet);
void Send(const sf::Packet& packet); void Send(const sf::Packet& packet);

View file

@ -526,10 +526,13 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
if (player.current_game != m_current_game) if (player.current_game != m_current_game)
break; break;
PadMapping map = 0; sf::Packet spac;
GCPadStatus pad; spac << static_cast<MessageId>(NP_MSG_PAD_DATA);
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;
// If the data is not from the correct player, // If the data is not from the correct player,
// then disconnect them. // then disconnect them.
@ -538,12 +541,15 @@ unsigned int NetPlayServer::OnData(sf::Packet& packet, Client& player)
return 1; return 1;
} }
// Relay to clients GCPadStatus pad;
sf::Packet spac; packet >> pad.button >> pad.analogA >> pad.analogB >> pad.stickX >> pad.stickY >>
spac << (MessageId)NP_MSG_PAD_DATA; 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 spac << map << pad.button << pad.analogA << pad.analogB << pad.stickX << pad.stickY
<< pad.substickX << pad.substickY << pad.triggerLeft << pad.triggerRight << pad.substickX << pad.substickY << pad.triggerLeft << pad.triggerRight
<< pad.isConnected; << pad.isConnected;
}
SendToClients(spac, player.pid); SendToClients(spac, player.pid);
} }