-
Notifications
You must be signed in to change notification settings - Fork 253
feat: add new NETMSG_DEDIMSG for private comms to game server #2957
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,6 +49,7 @@ | |
| #include "System/FileSystem/SimpleParser.h" | ||
| #include "System/Net/Connection.h" | ||
| #include "System/Net/LocalConnection.h" | ||
| #include "System/Net/PackPacket.h" | ||
| #include "System/Net/UnpackPacket.h" | ||
| #include "System/LoadSave/DemoRecorder.h" | ||
| #include "System/LoadSave/DemoReader.h" | ||
|
|
@@ -191,6 +192,7 @@ void CGameServer::Initialize() | |
| { | ||
| netPingTimings.fill(spring_notime); | ||
| mapDrawTimings.fill({spring_notime, 0}); | ||
| dediMsgTimings.fill({spring_notime, 0}); | ||
| chatMutedFlags.fill({false, false}); | ||
| aiControlFlags.fill(true); | ||
|
|
||
|
|
@@ -1350,6 +1352,56 @@ void CGameServer::ProcessPacket(const unsigned playerNum, std::shared_ptr<const | |
| } | ||
| } break; | ||
|
|
||
| case NETMSG_DEDIMSG: { | ||
| // Private channel for clients to talk to the server/autohost without | ||
| // leaving a replay trace. Never broadcast, never demoed. | ||
| try { | ||
| // wire: <u8 cmd><u16 size><u8 playerNum><u16 header><u8[] payload> | ||
| netcode::UnpackPacket pckt(packet, sizeof(uint8_t) + sizeof(uint16_t)); | ||
| uint8_t playerNum; | ||
| uint16_t header; | ||
|
|
||
| pckt >> playerNum; | ||
| pckt >> header; | ||
|
|
||
| if (playerNum != a) { | ||
| Message(spring::format(WrongPlayer, msgCode, a, (unsigned)playerNum)); | ||
| break; | ||
| } | ||
|
Comment on lines
+1367
to
+1370
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. playerNum is redundant |
||
|
|
||
| // these packets shouldn't even exist in a demo | ||
| // but lets skip parsing them anyways if so | ||
| if (demoReader != nullptr) | ||
| break; | ||
|
|
||
| // per-player rate limit: 64 KiB/sec window. | ||
| constexpr uint32_t kBytesPerSecond = 64 * 1024; | ||
| constexpr int kWindowMs = 1000; | ||
|
|
||
| constexpr size_t kFrameOverhead = | ||
| sizeof(uint8_t) + sizeof(uint16_t) + sizeof(uint8_t); | ||
| const size_t payloadLen = packet->length - kFrameOverhead; | ||
|
|
||
| const spring_time now = spring_gettime(); | ||
| auto& [windowStart, bytesInWindow] = dediMsgTimings[a]; | ||
|
|
||
| if (!windowStart.isTime() || spring_diffmsecs(now, windowStart) >= kWindowMs) { | ||
| windowStart = now; | ||
| bytesInWindow = 0; | ||
| } | ||
|
|
||
| if (bytesInWindow + payloadLen > kBytesPerSecond) { | ||
| LOG_L(L_WARNING, "[GameServer::NETMSG_DEDIMSG] dropped payload from player %u (rate limit)", (unsigned)playerNum); | ||
| break; | ||
| } | ||
| bytesInWindow += static_cast<uint32_t>(payloadLen); | ||
|
|
||
| // DO SOMETHING in future PR | ||
| } catch (const netcode::UnpackPacketException& ex) { | ||
| Message(spring::format("[GameServer::%s][NETMSG_DEDIMSG] exception \"%s\" from player \"%s\"", __func__, ex.what(), players[a].name.c_str())); | ||
| } | ||
| } break; | ||
|
|
||
|
|
||
| case NETMSG_SYNCRESPONSE: { | ||
| #ifdef SYNCCHECK | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -449,6 +449,20 @@ PacketType CBaseNetProtocol::SendLuaMsg(uint8_t playerNum, uint16_t script, uint | |
| return PacketType(packet); | ||
| } | ||
|
|
||
| PacketType CBaseNetProtocol::SendDediMsg(uint8_t playerNum, uint16_t header, const std::vector<uint8_t>& payload) | ||
| { | ||
| const uint32_t payloadSize = sizeof(playerNum) + sizeof(header) + payload.size(); | ||
| const uint32_t frameSize = sizeof(uint8_t) + sizeof(uint16_t); | ||
| const uint32_t packetSize = frameSize + payloadSize; | ||
|
|
||
| if (packetSize >= (1 << (sizeof(uint16_t) * 8))) | ||
| throw netcode::PackPacketException("[BaseNetProto::SendDediMsg] maximum packet-size exceeded"); | ||
|
|
||
| PackPacket* packet = new PackPacket(packetSize, NETMSG_DEDIMSG); | ||
| *packet << static_cast<uint16_t>(packetSize) << playerNum << header << payload; | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. putting packetSize into the packet is probably redundant |
||
| return PacketType(packet); | ||
| } | ||
|
|
||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. xref #2712 (comment)
This is a possible, more flexible but more complex alternative implementation. LMK what you think. |
||
|
|
||
| PacketType CBaseNetProtocol::SendGiveAwayEverything(uint8_t playerNum, uint8_t giveToTeam, uint8_t takeFromTeam) | ||
| { | ||
|
|
@@ -672,6 +686,7 @@ CBaseNetProtocol::CBaseNetProtocol() | |
| proto->AddType(NETMSG_AI_STATE_CHANGED, 4); | ||
| proto->AddType(NETMSG_GAME_FRAME_PROGRESS, 5); | ||
| proto->AddType(NETMSG_PING, 1 + (1 + 1 + 4)); | ||
| proto->AddType(NETMSG_DEDIMSG, -2); | ||
|
|
||
| #ifdef SYNCDEBUG | ||
| proto->AddType(NETMSG_SD_CHKREQUEST, 5); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -96,6 +96,8 @@ enum NETMSG { | |
|
|
||
| NETMSG_PING = 78, // uint8_t playerNum, uint8_t pingTag, float localTime | ||
|
|
||
| NETMSG_DEDIMSG = 79, // /* uint16_t messageSize */, uint8_t playerNum, uint16_t header, std::vector<uint8_t> payload | ||
|
|
||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. im sure there is a better name than dedimsg... but im ironing out use cases right now. open to suggestions
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. HOSTMSG? |
||
| NETMSG_LAST //max types of netmessages, internal only | ||
| }; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what does the header do? what do its numerical values mean? why does the engine reserve 0-4095?