From 7ebefd95b96fa45c2eba923be8f57e6395940e09 Mon Sep 17 00:00:00 2001 From: joris <joris.dauphin@gmail.com> Date: Wed, 27 Mar 2013 00:35:01 +0100 Subject: [PATCH] Add CInitMessage(uint8_t type, uint8_t subtype) --- src/include/net_message.h | 1 + src/network/netconnect.cpp | 206 ++++++++++++++++--------------------- 2 files changed, 89 insertions(+), 118 deletions(-) diff --git a/src/include/net_message.h b/src/include/net_message.h index f255ae877..85f7a66c7 100644 --- a/src/include/net_message.h +++ b/src/include/net_message.h @@ -142,6 +142,7 @@ class CInitMessage { public: CInitMessage(); + CInitMessage(uint8_t type, uint8_t subtype); const unsigned char *Serialize() const; void Deserialize(const unsigned char *p); static size_t Size() { return 1 + 1 + 1 + 1 + 4 + 4 + 4 + 4 + 4 + 4 + std::max<size_t>(256u, std::max(CNetworkHost::Size() * PlayerMax, CServerSetup::Size())); } diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index a57f07606..e6ebb6770 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -99,7 +99,7 @@ public: void Init(); void Update(unsigned long frameCounter); - void NetworkParseMenuPacket(unsigned long frameCounter, const CInitMessage &msg, unsigned long host, int port); + void NetworkParseMenuPacket(unsigned long frameCounter, const unsigned char *buf, unsigned long host, int port); void MarkClientsAsResync(); void KickClient(int c); @@ -121,7 +121,7 @@ public: void Init(unsigned long tick); bool SetupServerAddress(const std::string &serveraddr, int port); - bool NetworkParseMenuPacket(const CInitMessage &msg, unsigned long host, int port); + bool NetworkParseMenuPacket(const unsigned char *buf, unsigned long host, int port); bool Update(unsigned long tick); void DetachFromServer(); @@ -265,23 +265,24 @@ static void NetworkSendICMessage_Log(unsigned long ip, int port, const CInitMess void CClient::NetworkSendRateLimitedClientMessage(const CInitMessage &msg, unsigned long tick, unsigned long msecs) { const unsigned long now = tick; - if (now - networkState.LastFrame >= msecs) { - networkState.LastFrame = now; - if (msg.SubType == lastMsgTypeSent) { - ++networkState.MsgCnt; - } else { - networkState.MsgCnt = 0; - lastMsgTypeSent = msg.SubType; - } - const int n = NetworkSendICMessage(serverIP, serverPort, msg); - UNUSED(n); // not used in release - if (!networkState.MsgCnt) { - DebugPrint - ("Sending Init Message (%s:%d): %d:%d(%d) %d.%d.%d.%d:%d\n" _C_ - ncconstatenames[networkState.State] _C_ networkState.MsgCnt _C_ - msg.Type _C_ msg.SubType _C_ n _C_ - NIPQUAD(ntohl(serverIP)) _C_ htons(serverPort)); - } + if (now - networkState.LastFrame < msecs) { + return; + } + networkState.LastFrame = now; + if (msg.SubType == lastMsgTypeSent) { + ++networkState.MsgCnt; + } else { + networkState.MsgCnt = 0; + lastMsgTypeSent = msg.SubType; + } + const int n = NetworkSendICMessage(serverIP, serverPort, msg); + UNUSED(n); // not used in release + if (!networkState.MsgCnt) { + DebugPrint + ("Sending Init Message (%s:%d): %d:%d(%d) %d.%d.%d.%d:%d\n" _C_ + ncconstatenames[networkState.State] _C_ networkState.MsgCnt _C_ + msg.Type _C_ msg.SubType _C_ n _C_ + NIPQUAD(ntohl(serverIP)) _C_ htons(serverPort)); } } @@ -331,10 +332,8 @@ void CClient::NetClientCheckLocalState() bool CClient::Update_disconnected() { Assert(networkState.State == ccs_disconnected); - CInitMessage message; + const CInitMessage message(MessageInit_FromClient, ICMSeeYou); - message.Type = MessageInit_FromClient; - message.SubType = ICMSeeYou; // Spew out 5 and trust in God that they arrive for (int i = 0; i < 5; ++i) { NetworkSendICMessage(serverIP, serverPort, message); @@ -348,10 +347,8 @@ bool CClient::Update_detaching(unsigned long tick) Assert(networkState.State == ccs_detaching); if (networkState.MsgCnt < 10) { // 10 retries = 1 second - CInitMessage message; + const CInitMessage message(MessageInit_FromClient, ICMGoodBye); - message.Type = MessageInit_FromClient; - message.SubType = ICMGoodBye; NetworkSendRateLimitedClientMessage(message, tick, 100); return true; } else { @@ -366,10 +363,8 @@ bool CClient::Update_connecting(unsigned long tick) Assert(networkState.State == ccs_connecting); if (networkState.MsgCnt < 48) { // 48 retries = 24 seconds - CInitMessage message; + CInitMessage message(MessageInit_FromClient, ICMHello); - message.Type = MessageInit_FromClient; - message.SubType = ICMHello; message.u.Hosts[0].SetName(Parameters::Instance.LocalPlayerName.c_str()); NetworkSendRateLimitedClientMessage(message, tick, 500); return true; @@ -385,9 +380,7 @@ bool CClient::Update_connected(unsigned long tick) Assert(networkState.State == ccs_connected); if (networkState.MsgCnt < 20) { // 20 retries - CInitMessage message; - message.Type = MessageInit_FromClient; - message.SubType = ICMWaiting; + const CInitMessage message(MessageInit_FromClient, ICMWaiting); NetworkSendRateLimitedClientMessage(message, tick, 650); return true; } else { @@ -406,9 +399,7 @@ bool CClient::Update_synced(unsigned long tick) networkState.MsgCnt = 0; return Update(tick); } - CInitMessage message; - message.Type = MessageInit_FromClient; - message.SubType = ICMWaiting; + const CInitMessage message(MessageInit_FromClient, ICMWaiting); NetworkSendRateLimitedClientMessage(message, tick, 850); return true; } @@ -418,10 +409,8 @@ bool CClient::Update_changed(unsigned long tick) Assert(networkState.State == ccs_changed); if (networkState.MsgCnt < 20) { // 20 retries - CInitMessage message; + CInitMessage message(MessageInit_FromClient, ICMState); - message.Type = MessageInit_FromClient; - message.SubType = ICMState; message.u.State = LocalSetupState; message.MapUID = Map.Info.MapUID; NetworkSendRateLimitedClientMessage(message, tick, 450); @@ -438,10 +427,8 @@ bool CClient::Update_async(unsigned long tick) Assert(networkState.State == ccs_async); if (networkState.MsgCnt < 20) { // 20 retries - CInitMessage message; + const CInitMessage message(MessageInit_FromClient, ICMResync); - message.Type = MessageInit_FromClient; - message.SubType = ICMResync; NetworkSendRateLimitedClientMessage(message, tick, 450); return true; } else { @@ -456,10 +443,9 @@ bool CClient::Update_mapinfo(unsigned long tick) Assert(networkState.State == ccs_mapinfo); if (networkState.MsgCnt < 20) { // 20 retries - CInitMessage message; + // ICMMapAck.. + CInitMessage message(MessageInit_FromClient, ICMMap); - message.Type = MessageInit_FromClient; - message.SubType = ICMMap; // ICMMapAck.. message.MapUID = Map.Info.MapUID; NetworkSendRateLimitedClientMessage(message, tick, 650); return true; @@ -475,10 +461,8 @@ bool CClient::Update_badmap(unsigned long tick) Assert(networkState.State == ccs_badmap); if (networkState.MsgCnt < 20) { // 20 retries - CInitMessage message; + CInitMessage message(MessageInit_FromClient, ICMMapUidMismatch); - message.Type = MessageInit_FromClient; - message.SubType = ICMMapUidMismatch; message.MapUID = Map.Info.MapUID; // MAP Uid doesn't match NetworkSendRateLimitedClientMessage(message, tick, 650); return true; @@ -494,10 +478,8 @@ bool CClient::Update_goahead(unsigned long tick) Assert(networkState.State == ccs_goahead); if (networkState.MsgCnt < 50) { // 50 retries - CInitMessage message; + const CInitMessage message(MessageInit_FromClient, ICMConfig); - message.Type = MessageInit_FromClient; - message.SubType = ICMConfig; NetworkSendRateLimitedClientMessage(message, tick, 250); return true; } else { @@ -512,10 +494,8 @@ bool CClient::Update_started(unsigned long tick) Assert(networkState.State == ccs_started); if (networkState.MsgCnt < 20) { // 20 retries - CInitMessage message; + const CInitMessage message(MessageInit_FromClient, ICMGo); - message.Type = MessageInit_FromClient; - message.SubType = ICMGo; NetworkSendRateLimitedClientMessage(message, tick, 250); return true; } else { @@ -589,11 +569,15 @@ void CClient::ParseMsgConfig(const CInitMessage &msg, unsigned long host, int po Hosts[HostsCount].SetName(Parameters::Instance.LocalPlayerName.c_str()); } -bool CClient::NetworkParseMenuPacket(const CInitMessage &msg, unsigned long host, int port) +bool CClient::NetworkParseMenuPacket(const unsigned char *buf, unsigned long host, int port) { + CInitMessage msg; + + msg.Deserialize(buf); if (msg.Type != MessageInit_FromServer) { return true; } + if (msg.SubType == ICMServerQuit) { // Server user canceled, should work in all states networkState.State = ccs_serverquits; // No ack here - Server will spew out a few Quit msgs, which has to be enough @@ -928,10 +912,8 @@ bool CClient::ParseStarted(const CInitMessage &msg) */ void CClient::ParseAreYouThere() { - CInitMessage message; + const CInitMessage message(MessageInit_FromClient, ICMIAH); // IAmHere - message.Type = MessageInit_FromClient; - message.SubType = ICMIAH; NetworkSendICMessage(serverIP, serverPort, message); } @@ -940,10 +922,8 @@ void CClient::ParseAreYouThere() */ bool CClient::ParseBadMap() { - CInitMessage message; + const CInitMessage message(MessageInit_FromClient, ICMSeeYou); - message.Type = MessageInit_FromClient; - message.SubType = ICMSeeYou; // Spew out 5 and trust in God that they arrive for (int i = 0; i < 5; ++i) { NetworkSendICMessage(serverIP, serverPort, message); @@ -991,7 +971,7 @@ void CServer::Init() void CServer::Update(unsigned long frameCounter) { - CInitMessage message; + const CInitMessage message(MessageInit_FromServer, ICMAYT); // AreYouThere for (int i = 1; i < PlayerMax - 1; ++i) { if (Hosts[i].PlyNr && Hosts[i].Host && Hosts[i].Port) { @@ -1000,9 +980,7 @@ void CServer::Update(unsigned long frameCounter) if (fcd > CLIENT_IS_DEAD) { KickDeadClient(i); } else if (fcd % 5 == 0) { - message.Type = MessageInit_FromServer; - message.SubType = ICMAYT; // Probe for the client - message.MapUID = 0L; + // Probe for the client const int n = NetworkSendICMessage(Hosts[i].Host, Hosts[i].Port, message); UNUSED(n); // unused in release @@ -1056,19 +1034,16 @@ int CServer::ParseHello(int h, const CInitMessage &msg, unsigned long host, int networkStates[h].State = ccs_connecting; networkStates[h].MsgCnt = 0; } else { - CInitMessage message; + // Game is full - reject connnection + const CInitMessage message(MessageInit_FromServer, ICMGameFull); - message.Type = MessageInit_FromServer; - message.SubType = ICMGameFull; // Game is full - reject connnection NetworkSendICMessage_Log(host, port, message); return -1; } } // this code path happens until client sends waiting (= has received this message) - CInitMessage message; + CInitMessage message(MessageInit_FromServer, ICMWelcome); - message.Type = MessageInit_FromServer; - message.SubType = ICMWelcome; // Acknowledge: Client is welcome message.u.Hosts[0].PlyNr = h; // Host array slot number message.u.Hosts[0].SetName(Parameters::Instance.LocalPlayerName.c_str()); // Name of server player for (int i = 1; i < PlayerMax - 1; ++i) { // Info about other clients @@ -1110,12 +1085,10 @@ void CServer::ParseResync(const int h, unsigned long host, int port) networkStates[h].MsgCnt = 0; /* Fall through */ case ccs_synced: { - CInitMessage message; - // this code path happens until client falls back to ICMWaiting // (indicating Resync has completed) - message.Type = MessageInit_FromServer; - message.SubType = ICMResync; + CInitMessage message(MessageInit_FromServer, ICMResync); + for (int i = 1; i < PlayerMax - 1; ++i) { // Info about other clients if (i != h) { if (Hosts[i].PlyNr) { @@ -1159,9 +1132,9 @@ void CServer::ParseWaiting(const int h, unsigned long host, int port) /* Fall through */ case ccs_connected: { // this code path happens until client acknowledges the map - CInitMessage message; - message.Type = MessageInit_FromServer; - message.SubType = ICMMap; // Send Map info to the client + CInitMessage message(MessageInit_FromServer, ICMMap); + + // Send Map info to the client strncpy_s(message.u.MapPath, sizeof(message.u.MapPath), NetworkMapName.c_str(), NetworkMapName.size()); message.MapUID = Map.Info.MapUID; NetworkSendICMessage_Log(host, port, message); @@ -1193,9 +1166,9 @@ void CServer::ParseWaiting(const int h, unsigned long host, int port) // this code path happens until client acknoledges the state change // by sending ICMResync - CInitMessage message; - message.Type = MessageInit_FromServer; - message.SubType = ICMState; // Send new state info to the client + CInitMessage message(MessageInit_FromServer, ICMState); + + // Send new state info to the client message.u.State = ServerSetupState; message.MapUID = Map.Info.MapUID; NetworkSendICMessage_Log(host, port, message); @@ -1230,9 +1203,9 @@ void CServer::ParseMap(const int h, unsigned long host, int port) case ccs_mapinfo: { // this code path happens until client acknoledges the state info // by falling back to ICMWaiting with prev. State synced - CInitMessage message; - message.Type = MessageInit_FromServer; - message.SubType = ICMState; // Send State info to the client + CInitMessage message(MessageInit_FromServer, ICMState); + + // Send State info to the client message.u.State = ServerSetupState; message.MapUID = Map.Info.MapUID; NetworkSendICMessage_Log(host, port, message); @@ -1282,10 +1255,9 @@ void CServer::ParseState(const int h, const CInitMessage &msg, unsigned long hos case ccs_async: { // this code path happens until client acknoledges the state change reply // by sending ICMResync - CInitMessage message; + CInitMessage message(MessageInit_FromServer, ICMState); - message.Type = MessageInit_FromServer; - message.SubType = ICMState; // Send new state info to the client + // Send new state info to the client message.u.State = ServerSetupState; message.MapUID = Map.Info.MapUID; NetworkSendICMessage_Log(host, port, message); @@ -1321,9 +1293,7 @@ void CServer::ParseGoodBye(const int h, unsigned long host, int port) case ccs_detaching: { // this code path happens until client acknoledges the GoodBye // by sending ICMSeeYou; - CInitMessage message; - message.Type = MessageInit_FromServer; - message.SubType = ICMGoodBye; + const CInitMessage message(MessageInit_FromServer, ICMGoodBye); NetworkSendICMessage_Log(host, port, message); networkStates[h].MsgCnt++; @@ -1372,9 +1342,7 @@ static int CheckVersions(const CInitMessage &msg, unsigned long host, int port) msg.Stratagus, StratagusVersion, NIPQUAD(ntohl(host)), ntohs(port)); - CInitMessage message; - message.Type = MessageInit_FromServer; - message.SubType = ICMEngineMismatch; // Stratagus engine version doesn't match + const CInitMessage message(MessageInit_FromServer, ICMEngineMismatch); NetworkSendICMessage_Log(host, port, message); return -1; } @@ -1388,24 +1356,26 @@ static int CheckVersions(const CInitMessage &msg, unsigned long host, int port) NetworkProtocolFormatArgs(NetworkProtocolVersion), NIPQUAD(ntohl(host)), ntohs(port)); - CInitMessage message; - message.Type = MessageInit_FromServer; - message.SubType = ICMProtocolMismatch; // Network protocol version doesn't match + const CInitMessage message(MessageInit_FromServer, ICMProtocolMismatch); NetworkSendICMessage_Log(host, port, message); return -1; } return 0; } -void CServer::NetworkParseMenuPacket(unsigned long frameCounter, const CInitMessage &msg, unsigned long host, int port) +void CServer::NetworkParseMenuPacket(unsigned long frameCounter, const unsigned char *buf, unsigned long host, int port) { - if (CheckVersions(msg, host, port)) { - return; - } + const unsigned char msgsubtype = buf[1]; int index = FindHostIndexBy(host, port); if (index == -1) { - if (msg.SubType == ICMHello) { + if (msgsubtype == ICMHello) { + CInitMessage msg; + + msg.Deserialize(buf); + if (CheckVersions(msg, host, port)) { + return; + } // Special case: a new client has arrived index = ParseHello(-1, msg, host, port); networkStates[index].LastFrame = frameCounter; @@ -1413,19 +1383,25 @@ void CServer::NetworkParseMenuPacket(unsigned long frameCounter, const CInitMess return; } networkStates[index].LastFrame = frameCounter; + switch (msgsubtype) { + case ICMHello: { // a new client has arrived + CInitMessage msg; - switch (msg.SubType) { - case ICMHello: // a new client has arrived + msg.Deserialize(buf); ParseHello(index, msg, host, port); break; - + } case ICMResync: ParseResync(index, host, port); break; case ICMWaiting: ParseWaiting(index, host, port); break; - case ICMMap: ParseMap(index, host, port); break; - case ICMState: ParseState(index, msg, host, port); break; + case ICMState: { + CInitMessage msg; + msg.Deserialize(buf); + ParseState(index, msg, host, port); + break; + } case ICMMapUidMismatch: case ICMGoodBye: ParseGoodBye(index, host, port); @@ -1436,7 +1412,7 @@ void CServer::NetworkParseMenuPacket(unsigned long frameCounter, const CInitMess case ICMIAH: break; default: - DebugPrint("Server: Unhandled subtype %d from host %d\n" _C_ msg.SubType _C_ index); + DebugPrint("Server: Unhandled subtype %d from host %d\n" _C_ msgsubtype _C_ index); break; } } @@ -1459,7 +1435,7 @@ int NetworkParseSetupEvent(const unsigned char *buf, int size, unsigned long hos { Assert(NetConnectRunning != 0); - const char msgtype = *buf; + const char msgtype = buf[0]; if ((msgtype == MessageInit_FromClient && NetConnectRunning != 1) || (msgtype == MessageInit_FromServer && NetConnectRunning != 2)) { if (NetConnectRunning == 2 && Client.GetNetworkState() == ccs_started) { @@ -1470,20 +1446,18 @@ int NetworkParseSetupEvent(const unsigned char *buf, int size, unsigned long hos } return 0; } - CInitMessage msg; - - msg.Deserialize(buf); + const char msgsubtype = buf[1]; DebugPrint("Received %s (%d) from %d.%d.%d.%d:%d\n" _C_ - icmsgsubtypenames[msg.SubType] _C_ msg.SubType _C_ + icmsgsubtypenames[int(msgsubtype)] _C_ msgsubtype _C_ NIPQUAD(ntohl(host)) _C_ ntohs(port)); if (NetConnectRunning == 2) { // client - if (Client.NetworkParseMenuPacket(msg, host, port) == false) { + if (Client.NetworkParseMenuPacket(buf, host, port) == false) { NetConnectRunning = 0; } } else if (NetConnectRunning == 1) { // server - Server.NetworkParseMenuPacket(FrameCounter, msg, host, port); + Server.NetworkParseMenuPacket(FrameCounter, buf, host, port); } return 1; } @@ -1687,9 +1661,7 @@ void NetworkServerStartGame() std::swap(Hosts[0], Hosts[HostsCount]); // Prepare the final config message: - CInitMessage message; - message.Type = MessageInit_FromServer; - message.SubType = ICMConfig; + CInitMessage message(MessageInit_FromServer, ICMConfig); message.HostsCount = NetPlayers; message.MapUID = Map.Info.MapUID; for (int i = 0; i < NetPlayers; ++i) { @@ -1698,9 +1670,7 @@ void NetworkServerStartGame() } // Prepare the final state message: - CInitMessage statemsg; - statemsg.Type = MessageInit_FromServer; - statemsg.SubType = ICMState; + CInitMessage statemsg(MessageInit_FromServer, ICMState); statemsg.HostsCount = NetPlayers; statemsg.u.State = ServerSetupState; statemsg.MapUID = Map.Info.MapUID;