From 07f2290cf3a9500be90af9d1c0f676ade37cedee Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Sun, 17 Jun 2018 22:05:41 -0700 Subject: [PATCH 01/32] Refactor socket usage --- src/include/netconnect.h | 124 +++++++++++++++++++++ src/include/network.h | 4 +- src/network/master.cpp | 4 +- src/network/netconnect.cpp | 222 ++++++++++++++++++++++--------------- src/network/network.cpp | 148 +++++++++++++++---------- 5 files changed, 350 insertions(+), 152 deletions(-) diff --git a/src/include/netconnect.h b/src/include/netconnect.h index 9baf8e3caf..54baca405b 100644 --- a/src/include/netconnect.h +++ b/src/include/netconnect.h @@ -32,6 +32,7 @@ //@{ #include "net_message.h" +#include "network\netsockets.h" class CHost; @@ -121,4 +122,127 @@ extern void NetworkDetachFromServer(); /// Menu Loop: Client: Send GoodBye //@} +/** +** Connect state information of network systems active in current game. +*/ +struct NetworkState { + void Clear() + { + State = ccs_unused; + MsgCnt = 0; + LastFrame = 0; + } + + unsigned char State; /// Menu: ConnectState + unsigned short MsgCnt; /// Menu: Counter for state msg of same type (detect unreachable) + unsigned long LastFrame; /// Last message received + // Fill in here... +}; + +class CServer +{ +public: + void Init(const std::string &name, CServerSetup *serverSetup); + + void Update(unsigned long frameCounter); + void Parse(unsigned long frameCounter, const unsigned char *buf, const CHost &host); + + void MarkClientsAsResync(); + void KickClient(int c); + + template + void SendToSpecificClient(const CHost &host, const T &msg); + + bool HasDataToRead(int count); + + int Recv(); + +private: + int Parse_Hello(int h, const CInitMessage_Hello &msg, const CHost &host); + void Parse_Resync(const int h); + void Parse_Waiting(const int h); + void Parse_Map(const int h); + void Parse_State(const int h, const CInitMessage_State &msg); + void Parse_GoodBye(const int h); + void Parse_SeeYou(const int h); + + void Send_AreYouThere(const CNetworkHost &host); + void Send_GameFull(const CHost &host); + void Send_Welcome(const CNetworkHost &host, int hostIndex); + void Send_Resync(const CNetworkHost &host, int hostIndex); + void Send_Map(const CNetworkHost &host); + void Send_State(const CNetworkHost &host); + void Send_GoodBye(const CNetworkHost &host); + +private: + std::string name; + NetworkState networkStates[PlayerMax]; /// Client Host states + CServerSetup *serverSetup; +}; + +class CClient +{ +public: + void Init(const std::string &name, CServerSetup *serverSetup, CServerSetup *localSetup, unsigned long tick); + void SetServerHost(const CHost &host) { serverHost = host; } + + bool Parse(const unsigned char *buf, const CHost &host); + bool Update(unsigned long tick); + + void DetachFromServer(); + + int GetNetworkState() const { return networkState.State; } + +private: + bool Update_disconnected(); + bool Update_detaching(unsigned long tick); + bool Update_connecting(unsigned long tick); + bool Update_connected(unsigned long tick); + bool Update_synced(unsigned long tick); + bool Update_changed(unsigned long tick); + bool Update_async(unsigned long tick); + bool Update_mapinfo(unsigned long tick); + bool Update_badmap(unsigned long tick); + bool Update_goahead(unsigned long tick); + bool Update_started(unsigned long tick); + + void Send_Go(unsigned long tick); + void Send_Config(unsigned long tick); + void Send_MapUidMismatch(unsigned long tick); + void Send_Map(unsigned long tick); + void Send_Resync(unsigned long tick); + void Send_State(unsigned long tick); + void Send_Waiting(unsigned long tick, unsigned long msec); + void Send_Hello(unsigned long tick); + void Send_GoodBye(unsigned long tick); + + template + void SendRateLimited(const T &msg, unsigned long tick, unsigned long msecs); + + void SetConfig(const CInitMessage_Config &msg); + + void Parse_GameFull(); + void Parse_LuaMismatch(const unsigned char *buf); + void Parse_EngineMismatch(const unsigned char *buf); + void Parse_Resync(const unsigned char *buf); + void Parse_Config(const unsigned char *buf); + void Parse_State(const unsigned char *buf); + void Parse_Welcome(const unsigned char *buf); + void Parse_Map(const unsigned char *buf); + void Parse_AreYouThere(); + + template + void SendToServer(const T & msg); + void SendToServer(const CInitMessage_Header &msg); + +private: + std::string name; + CHost serverHost; /// IP:port of server to join + NetworkState networkState; + unsigned char lastMsgTypeSent; /// Subtype of last InitConfig message sent + //CUDPSocket *socket; + CServerSetup *serverSetup; + CServerSetup *localSetup; +}; + #endif // !__NETCONNECT_H__ diff --git a/src/include/network.h b/src/include/network.h index 78710e0ece..602076b094 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -66,14 +66,14 @@ class CNetworkParameter -- Variables ----------------------------------------------------------------------------*/ -extern CUDPSocket NetworkFildes; /// Network file descriptor +//extern CUDPSocket NetworkFildes; /// Network file descriptor extern bool NetworkInSync; /// Network is in sync /*---------------------------------------------------------------------------- -- Functions ----------------------------------------------------------------------------*/ -extern inline bool IsNetworkGame() { return NetworkFildes.IsValid(); } +extern inline bool IsNetworkGame(); extern void InitNetwork1(); /// Initialise network extern void ExitNetwork1(); /// Cleanup network (port) extern void NetworkOnStartGame(); /// Initialise network data for ingame communication diff --git a/src/network/master.cpp b/src/network/master.cpp index 6c8bc4d07f..7bc09d9177 100644 --- a/src/network/master.cpp +++ b/src/network/master.cpp @@ -200,14 +200,14 @@ int CMetaClient::CreateGame(std::string desc, std::string map, std::string playe if (metaSocket.IsValid() == false) { return -1; } - if (NetworkFildes.IsValid() == false) { + if (Server.IsValid() == false) { return -1; } CHost metaServerHost(metaHost.c_str(), metaPort); // Advertise an external IP address if we can unsigned long ips[1]; - int networkNumInterfaces = NetworkFildes.GetSocketAddresses(ips, 1); + int networkNumInterfaces = Server.GetSocketAddresses(ips, 1); std::string ipport = ""; if (!networkNumInterfaces || CNetworkParameter::Instance.localHost.compare("127.0.0.1")) { ipport += CNetworkParameter::Instance.localHost.c_str(); diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index aceda3af4b..e9b04f6e53 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -56,23 +56,6 @@ #define CLIENT_LIVE_BEAT 60 #define CLIENT_IS_DEAD 300 -/** -** Connect state information of network systems active in current game. -*/ -struct NetworkState { - void Clear() - { - State = ccs_unused; - MsgCnt = 0; - LastFrame = 0; - } - - unsigned char State; /// Menu: ConnectState - unsigned short MsgCnt; /// Menu: Counter for state msg of same type (detect unreachable) - unsigned long LastFrame; /// Last message received - // Fill in here... -}; - //---------------------------------------------------------------------------- // Variables //---------------------------------------------------------------------------- @@ -92,7 +75,7 @@ static int NoRandomPlacementMultiplayer = 0; /// Disable the random placement of CServerSetup ServerSetupState; // Server selection state for Multiplayer clients CServerSetup LocalSetupState; // Local selection state for Multiplayer clients -class CServer +/*class CServer { public: void Init(const std::string &name, CUDPSocket *socket, CServerSetup *serverSetup); @@ -184,7 +167,7 @@ class CClient CUDPSocket *socket; CServerSetup *serverSetup; CServerSetup *localSetup; -}; +};*/ static CServer Server; static CClient Client; @@ -200,21 +183,21 @@ static CClient Client; ** @param port Port of host to send to (network byte order). ** @param msg The message to send */ -template -static void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const T &msg) -{ - const unsigned char *buf = msg.Serialize(); - socket.Send(host, buf, msg.Size()); - delete[] buf; -} - -void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const CInitMessage_Header &msg) -{ - unsigned char *buf = new unsigned char [msg.Size()]; - msg.Serialize(buf); - socket.Send(host, buf, msg.Size()); - delete[] buf; -} +//template +//static void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const T &msg) +//{ +// const unsigned char *buf = msg.Serialize(); +// socket.Send(host, buf, msg.Size()); +// delete[] buf; +//} +// +//void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const CInitMessage_Header &msg) +//{ +// unsigned char *buf = new unsigned char [msg.Size()]; +// msg.Serialize(buf); +// socket.Send(host, buf, msg.Size()); +// delete[] buf; +//} static const char *ncconstatenames[] = { "ccs_unused", @@ -263,28 +246,28 @@ static const char *icmsgsubtypenames[] = { "IAmHere", // Client answers I am here }; -template -static void NetworkSendICMessage_Log(CUDPSocket &socket, const CHost &host, const T &msg) -{ - NetworkSendICMessage(socket, host, msg); - -#ifdef DEBUG - const std::string hostStr = host.toString(); - DebugPrint("Sending to %s -> %s\n" _C_ hostStr.c_str() - _C_ icmsgsubtypenames[msg.GetHeader().GetSubType()]); -#endif -} - -static void NetworkSendICMessage_Log(CUDPSocket &socket, const CHost &host, const CInitMessage_Header &msg) -{ - NetworkSendICMessage(socket, host, msg); - -#ifdef DEBUG - const std::string hostStr = host.toString(); - DebugPrint("Sending to %s -> %s\n" _C_ hostStr.c_str() - _C_ icmsgsubtypenames[msg.GetSubType()]); -#endif -} +//template +//static void NetworkSendICMessage_Log(CUDPSocket &socket, const CHost &host, const T &msg) +//{ +// NetworkSendICMessage(socket, host, msg); +// +//#ifdef DEBUG +// const std::string hostStr = host.toString(); +// DebugPrint("Sending to %s -> %s\n" _C_ hostStr.c_str() +// _C_ icmsgsubtypenames[msg.GetHeader().GetSubType()]); +//#endif +//} +// +//static void NetworkSendICMessage_Log(CUDPSocket &socket, const CHost &host, const CInitMessage_Header &msg) +//{ +// NetworkSendICMessage(socket, host, msg); +// +//#ifdef DEBUG +// const std::string hostStr = host.toString(); +// DebugPrint("Sending to %s -> %s\n" _C_ hostStr.c_str() +// _C_ icmsgsubtypenames[msg.GetSubType()]); +//#endif +//} /** ** Send a message to the server, but only if the last packet was a while ago @@ -308,7 +291,8 @@ void CClient::SendRateLimited(const T &msg, unsigned long tick, unsigned long ms networkState.MsgCnt = 0; lastMsgTypeSent = subtype; } - NetworkSendICMessage(*socket, serverHost, msg); + SendToServer(msg); + //NetworkSendICMessage(*socket, serverHost, msg); DebugPrint("[%s] Sending (%s:#%d)\n" _C_ ncconstatenames[networkState.State] _C_ icmsgsubtypenames[subtype] _C_ networkState.MsgCnt); @@ -329,13 +313,14 @@ void CClient::SendRateLimited(const CInitMessage_Header &ms networkState.MsgCnt = 0; lastMsgTypeSent = subtype; } - NetworkSendICMessage(*socket, serverHost, msg); + SendToServer(msg); + //NetworkSendICMessage(*socket, serverHost, msg); DebugPrint("[%s] Sending (%s:#%d)\n" _C_ ncconstatenames[networkState.State] _C_ icmsgsubtypenames[subtype] _C_ networkState.MsgCnt); } -void CClient::Init(const std::string &name, CUDPSocket *socket, CServerSetup *serverSetup, CServerSetup *localSetup, unsigned long tick) +void CClient::Init(const std::string &name, CServerSetup *serverSetup, CServerSetup *localSetup, unsigned long tick) { networkState.LastFrame = tick; networkState.State = ccs_connecting; @@ -344,7 +329,6 @@ void CClient::Init(const std::string &name, CUDPSocket *socket, CServerSetup *se this->serverSetup = serverSetup; this->localSetup = localSetup; this->name = name; - this->socket = socket; } void CClient::DetachFromServer() @@ -360,7 +344,8 @@ bool CClient::Update_disconnected() // Spew out 5 and trust in God that they arrive for (int i = 0; i < 5; ++i) { - NetworkSendICMessage(*socket, serverHost, message); + SendToServer(message); + //NetworkSendICMessage(*socket, serverHost, message); } networkState.State = ccs_usercanceled; return false; @@ -897,8 +882,24 @@ void CClient::Parse_EngineMismatch(const unsigned char *buf) void CClient::Parse_AreYouThere() { const CInitMessage_Header message(MessageInit_FromClient, ICMIAH); // IAmHere + SendToServer(message); + //NetworkSendICMessage(*socket, serverHost, message); +} - NetworkSendICMessage(*socket, serverHost, message); +template +void CClient::SendToServer(const T &msg) +{ + const unsigned char *buf = msg.Serialize(); + //socket.Send(host, buf, msg.Size()); + delete[] buf; +} + +void CClient::SendToServer(const CInitMessage_Header &msg) +{ + unsigned char *buf = new unsigned char [msg.Size()]; + msg.Serialize(buf); + //socket.Send(host, buf, msg.Size()); + delete[] buf; } // @@ -920,7 +921,7 @@ void CServer::KickClient(int c) } } -void CServer::Init(const std::string &name, CUDPSocket *socket, CServerSetup *serverSetup) +void CServer::Init(const std::string &name, CServerSetup *serverSetup) { for (int i = 0; i < PlayerMax; ++i) { networkStates[i].Clear(); @@ -928,21 +929,20 @@ void CServer::Init(const std::string &name, CUDPSocket *socket, CServerSetup *se } this->serverSetup = serverSetup; this->name = name; - this->socket = socket; } void CServer::Send_AreYouThere(const CNetworkHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMAYT); // AreYouThere - - NetworkSendICMessage(*socket, CHost(host.Host, host.Port), message); + SendToSpecificClient(CHost(host.Host, host.Port), message); + //NetworkSendICMessage(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_GameFull(const CHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMGameFull); - - NetworkSendICMessage_Log(*socket, host, message); + SendToSpecificClient(host, message); + //NetworkSendICMessage_Log(*socket, host, message); } void CServer::Send_Welcome(const CNetworkHost &host, int index) @@ -956,7 +956,8 @@ void CServer::Send_Welcome(const CNetworkHost &host, int index) message.hosts[i] = Hosts[i]; } } - NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); + SendToSpecificClient(CHost(host.Host, host.Port), message); + //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_Resync(const CNetworkHost &host, int hostIndex) @@ -968,28 +969,29 @@ void CServer::Send_Resync(const CNetworkHost &host, int hostIndex) message.hosts[i] = Hosts[i]; } } - NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); + SendToSpecificClient(CHost(host.Host, host.Port), message); + //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_Map(const CNetworkHost &host) { const CInitMessage_Map message(NetworkMapName.c_str(), Map.Info.MapUID); - - NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); + SendToSpecificClient(CHost(host.Host, host.Port), message); + //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_State(const CNetworkHost &host) { const CInitMessage_State message(MessageInit_FromServer, *serverSetup); - - NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); + SendToSpecificClient(CHost(host.Host, host.Port), message); + //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_GoodBye(const CNetworkHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMGoodBye); - - NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); + SendToSpecificClient(CHost(host.Host, host.Port), message); + //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Update(unsigned long frameCounter) @@ -1288,15 +1290,16 @@ void CServer::Parse_SeeYou(const int h) ** ** @return 0 if the versions match, -1 otherwise */ -static int CheckVersions(const CInitMessage_Hello &msg, CUDPSocket &socket, const CHost &host) +static int CheckVersions(const CInitMessage_Hello &msg, const CHost &host) { if (msg.Stratagus != StratagusVersion) { const std::string hostStr = host.toString(); fprintf(stderr, "Incompatible Stratagus version %d <-> %d from %s\n", StratagusVersion, msg.Stratagus, hostStr.c_str()); - const CInitMessage_EngineMismatch message; - NetworkSendICMessage_Log(socket, host, message); + //const CInitMessage_EngineMismatch message; + //Server.SendToSpecificHost(host, message); + //NetworkSendICMessage_Log(socket, host, message); return -1; } @@ -1307,9 +1310,10 @@ static int CheckVersions(const CInitMessage_Hello &msg, CUDPSocket &socket, cons msg.Version, hostStr.c_str()); - const CInitMessage_LuaFilesMismatch message; - NetworkSendICMessage_Log(socket, host, message); - return -1; + //const CInitMessage_LuaFilesMismatch message; + //Server.SendToSpecificHost(host, message); + //NetworkSendICMessage_Log(socket, host, message); + return -2; } return 0; } @@ -1323,8 +1327,43 @@ void CServer::Parse(unsigned long frameCounter, const unsigned char *buf, const if (msgsubtype == ICMHello) { CInitMessage_Hello msg; + + //if (msg.Stratagus != StratagusVersion) { + // const std::string hostStr = host.toString(); + // fprintf(stderr, "Incompatible Stratagus version %d <-> %d from %s\n", + // StratagusVersion, msg.Stratagus, hostStr.c_str()); + + // //const CInitMessage_EngineMismatch message; + // //Server.SendToSpecificHost(host, message); + // //NetworkSendICMessage_Log(socket, host, message); + // return -1; + //} + + //if (msg.Version != FileChecksums) { + // const std::string hostStr = host.toString(); + // fprintf(stderr, "Incompatible lua files %d <-> %d\nfrom %s\n", + // FileChecksums, + // msg.Version, + // hostStr.c_str()); + + // //const CInitMessage_LuaFilesMismatch message; + // //Server.SendToSpecificHost(host, message); + // //NetworkSendICMessage_Log(socket, host, message); + // return -2; + //} + //return 0; + + msg.Deserialize(buf); - if (CheckVersions(msg, *socket, host)) { + int versionCheck = CheckVersions(msg, host); + if (versionCheck == -1) { + const CInitMessage_EngineMismatch message; + Server.SendToSpecificClient(host, message); + return; + } + if (versionCheck == -2) { + const CInitMessage_LuaFilesMismatch message; + Server.SendToSpecificClient(host, message); return; } // Special case: a new client has arrived @@ -1461,7 +1500,7 @@ void NetworkInitClientConnect() } ServerSetupState.Clear(); LocalSetupState.Clear(); - Client.Init(Parameters::Instance.LocalPlayerName, &NetworkFildes, &ServerSetupState, &LocalSetupState, GetTicks()); + Client.Init(Parameters::Instance.LocalPlayerName, &ServerSetupState, &LocalSetupState, GetTicks()); } /** @@ -1641,17 +1680,19 @@ void NetworkServerStartGame() if (num[Hosts[i].PlyNr] == 1) { // not acknowledged yet message.clientIndex = i; - NetworkSendICMessage_Log(NetworkFildes, host, message); + Server.SendToSpecificClient(host, message); + //NetworkSendICMessage_Log(NetworkFildes, host, message); } else if (num[Hosts[i].PlyNr] == 2) { - NetworkSendICMessage_Log(NetworkFildes, host, statemsg); + Server.SendToSpecificClient(host, statemsg); + //NetworkSendICMessage_Log(NetworkFildes, host, statemsg); } } // Wait for acknowledge unsigned char buf[1024]; - while (j && NetworkFildes.HasDataToRead(1000)) { + while (j && Server.HasDataToRead(1000)) { CHost host; - const int len = NetworkFildes.Recv(buf, sizeof(buf), &host); + const int len = Server.Recv(buf, sizeof(buf), &host); if (len < 0) { #ifdef DEBUG const std::string hostStr = host.toString(); @@ -1710,7 +1751,8 @@ void NetworkServerStartGame() const CInitMessage_Header message_go(MessageInit_FromServer, ICMGo); for (int i = 0; i < HostsCount; ++i) { const CHost host(Hosts[i].Host, Hosts[i].Port); - NetworkSendICMessage_Log(NetworkFildes, host, message_go); + Server.SendToSpecificClient(host, message_go); + //NetworkSendICMessage_Log(NetworkFildes, host, message_go); } } @@ -1759,7 +1801,7 @@ void NetworkInitServerConnect(int openslots) } ServerSetupState.Clear(); LocalSetupState.Clear(); // Unused when we are server - Server.Init(Parameters::Instance.LocalPlayerName, &NetworkFildes, &ServerSetupState); + Server.Init(Parameters::Instance.LocalPlayerName, &ServerSetupState); // preset the server (initially always slot 0) Hosts[0].SetName(Parameters::Instance.LocalPlayerName.c_str()); diff --git a/src/network/network.cpp b/src/network/network.cpp index eabc20fdd8..89e7c45197 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -292,7 +292,7 @@ void CNetworkParameter::FixValues() bool NetworkInSync = true; /// Network is in sync -CUDPSocket NetworkFildes; /// Network file descriptor +//CUDPSocket NetworkFildes; /// Network file descriptor static unsigned long NetworkLastFrame[PlayerMax]; /// Last frame received packet static unsigned long NetworkLastCycle[PlayerMax]; /// Last cycle received packet @@ -303,6 +303,10 @@ static CNetworkCommandQueue NetworkIn[256][PlayerMax][MaxNetworkCommands]; /// P static std::deque CommandsIn; /// Network command input queue static std::deque MsgCommandsIn; /// Network message input queue +extern CServer Server; +extern CClient Client; + +extern inline bool IsNetworkGame() { return Server.IsValid() || Client.IsValid(); } #ifdef DEBUG class CNetworkStat @@ -324,11 +328,11 @@ class CNetworkStat static void printStatistic(const CUDPSocket::CStatistic &statistic) { DebugPrint("Sent: %d packets %d bytes (max %d bytes).\n" - _C_ statistic.sentPacketsCount _C_ statistic.sentBytesCount - _C_ statistic.biggestSentPacketSize); + _C_ statistic.sentPacketsCount _C_ statistic.sentBytesCount + _C_ statistic.biggestSentPacketSize); DebugPrint("Received: %d packets %d bytes (max %d bytes).\n" _C_ - statistic.receivedPacketsCount _C_ statistic.receivedBytesCount - _C_ statistic.biggestReceivedPacketSize); + statistic.receivedPacketsCount _C_ statistic.receivedBytesCount + _C_ statistic.biggestReceivedPacketSize); DebugPrint("Received: %d error(s).\n" _C_ statistic.receivedErrorCount); } @@ -355,16 +359,19 @@ static void NetworkBroadcast(const CNetworkPacket &packet, int numcommands, int // Send to all clients. if (NetConnectType == 1) { // server - for (int i = 0; i < HostsCount; ++i) { + Server.SendToAllClients(buf, size); + /*for (int i = 0; i < HostsCount; ++i) { const CHost host(Hosts[i].Host, Hosts[i].Port); if (Hosts[i].PlyNr == player) { continue; } NetworkFildes.Send(host, buf, size); - } - } else { // client - const CHost host(Hosts[HostsCount - 1].Host, Hosts[HostsCount - 1].Port); - NetworkFildes.Send(host, buf, size); + }*/ + } + else { // client + Client.SendToServer(buf, size); + //const CHost host(Hosts[HostsCount - 1].Host, Hosts[HostsCount - 1].Port); + //NetworkFildes.Send(host, buf, size); } delete[] buf; } @@ -407,22 +414,33 @@ void InitNetwork1() NetInit(); // machine dependent setup - // Our communication port - const int port = CNetworkParameter::Instance.localPort; - const char *NetworkAddr = NULL; // FIXME : bad use - const CHost host(NetworkAddr, port); - NetworkFildes.Open(host); - if (NetworkFildes.IsValid() == false) { - fprintf(stderr, "NETWORK: No free port %d available, aborting\n", port); - NetExit(); // machine dependent network exit - return; - } + if (NetConnectType == 1) { // server + // Our communication port + const int port = CNetworkParameter::Instance.localPort; + const char *NetworkAddr = NULL; // FIXME : bad use + const CHost host(NetworkAddr, port); + Server.Open(host); + + if (Server.IsValid() == false) { + fprintf(stderr, "NETWORK: No free port %d available, aborting\n", port); + NetExit(); // machine dependent network exit + return; + } #ifdef DEBUG - const std::string hostStr = host.toString(); - DebugPrint("My host:port %s\n" _C_ hostStr.c_str()); + const std::string hostStr = host.toString(); + DebugPrint("My host:port %s\n" _C_ hostStr.c_str()); #endif + } + else { // client + Client.Open(); + if (Client.IsValid() == false) { + fprintf(stderr, "Unable to open socket for client\n"); + NetExit(); // machine dependent network exit + return; + } + } - unsigned long ips[10]; + /*unsigned long ips[10]; int networkNumInterfaces = NetworkFildes.GetSocketAddresses(ips, 10); if (networkNumInterfaces) { DebugPrint("Num IP: %d\n" _C_ networkNumInterfaces); @@ -432,7 +450,7 @@ void InitNetwork1() } else { fprintf(stderr, "WARNING: Not connected to any external IPV4-network!\n"); return; - } + }*/ } /** @@ -450,7 +468,13 @@ void ExitNetwork1() NetworkStat.print(); #endif - NetworkFildes.Close(); + if (NetConnectType == 1) { // server + Server.Close(); + } + else { // client + Client.Close(); + } + NetExit(); // machine dependent setup NetworkInSync = true; @@ -468,8 +492,8 @@ void NetworkOnStartGame() Players[Hosts[i].PlyNr].SetName(Hosts[i].PlyName); } DebugPrint("Updates %d, Lag %d, Hosts %d\n" _C_ - CNetworkParameter::Instance.gameCyclesPerUpdate _C_ - CNetworkParameter::Instance.NetworkLag _C_ HostsCount); + CNetworkParameter::Instance.gameCyclesPerUpdate _C_ + CNetworkParameter::Instance.NetworkLag _C_ HostsCount); NetworkInSync = true; CommandsIn.clear(); @@ -525,7 +549,7 @@ void NetworkOnStartGame() ** @warning Destination and unit-type shares the same network slot. */ void NetworkSendCommand(int command, const CUnit &unit, int x, int y, - const CUnit *dest, const CUnitType *type, int status) + const CUnit *dest, const CUnitType *type, int status) { CNetworkCommandQueue ncq; @@ -568,7 +592,7 @@ void NetworkSendCommand(int command, const CUnit &unit, int x, int y, ** @param status Append command or flush old commands. */ void NetworkSendExtendedCommand(int command, int arg1, int arg2, int arg3, - int arg4, int status) + int arg4, int status) { CNetworkCommandQueue ncq; @@ -682,7 +706,7 @@ static bool IsNetworkCommandReady(unsigned long gameNetCycle) return false; } } - + return true; } @@ -729,7 +753,7 @@ static bool IsAValidCommand_Command(const CNetworkPacket &packet, int index, con const CUnit *unit = slot < UnitManager.GetUsedSlotCount() ? &UnitManager.GetSlotUnit(slot) : NULL; if (unit && (unit->Player->Index == player - || Players[player].IsTeamed(*unit) || unit->Player->Type == PlayerNeutral)) { + || Players[player].IsTeamed(*unit) || unit->Player->Type == PlayerNeutral)) { return true; } else { return false; @@ -752,15 +776,15 @@ static bool IsAValidCommand_Dismiss(const CNetworkPacket &packet, int index, con static bool IsAValidCommand(const CNetworkPacket &packet, int index, const int player) { switch (packet.Header.Type[index] & 0x7F) { - case MessageExtendedCommand: // FIXME: ensure the sender is part of the command - case MessageSync: // Sync does not matter - case MessageSelection: // FIXME: ensure it's from the right player - case MessageQuit: // FIXME: ensure it's from the right player - case MessageResend: // FIXME: ensure it's from the right player - case MessageChat: // FIXME: ensure it's from the right player - return true; - case MessageCommandDismiss: return IsAValidCommand_Dismiss(packet, index, player); - default: return IsAValidCommand_Command(packet, index, player); + case MessageExtendedCommand: // FIXME: ensure the sender is part of the command + case MessageSync: // Sync does not matter + case MessageSelection: // FIXME: ensure it's from the right player + case MessageQuit: // FIXME: ensure it's from the right player + case MessageResend: // FIXME: ensure it's from the right player + case MessageChat: // FIXME: ensure it's from the right player + return true; + case MessageCommandDismiss: return IsAValidCommand_Dismiss(packet, index, player); + default: return IsAValidCommand_Command(packet, index, player); } // FIXME: not all values in nc have been validated } @@ -826,7 +850,7 @@ static void NetworkParseInGameEvent(const unsigned char *buf, int len, const CHo } else { SetMessage(_("%s sent bad command"), Players[player].Name.c_str()); DebugPrint("%s sent bad command: 0x%x\n" _C_ Players[player].Name.c_str() - _C_ packet.Header.Type[i] & 0x7F); + _C_ packet.Header.Type[i] & 0x7F); } } for (int i = commands; i != MaxNetworkCommands; ++i) { @@ -855,7 +879,15 @@ void NetworkEvent() // Read the packet. unsigned char buf[1024]; CHost host; - int len = NetworkFildes.Recv(&buf, sizeof(buf), &host); + int len; + + if (NetConnectType == 1) { // server + Server.Recv(&buf, sizeof(buf), &host); + } else { // client + Client.Recv(&buf, sizeof(buf), &host); + } + + //int len = NetworkFildes.Recv(&buf, sizeof(buf), &host); if (len < 0) { DebugPrint("Server/Client gone?\n"); // just hope for an automatic recover right now.. @@ -915,8 +947,8 @@ static void NetworkExecCommand_Sync(const CNetworkCommandQueue &ncq) || syncHash != NetworkSyncHashs[gameNetCycle & 0xFF]) { SetMessage("%s", _("Network out of sync")); DebugPrint("\nNetwork out of sync %x!=%x! %d!=%d! Cycle %lu\n\n" _C_ - syncSeed _C_ NetworkSyncSeeds[gameNetCycle & 0xFF] _C_ - syncHash _C_ NetworkSyncHashs[gameNetCycle & 0xFF] _C_ GameCycle); + syncSeed _C_ NetworkSyncSeeds[gameNetCycle & 0xFF] _C_ + syncHash _C_ NetworkSyncHashs[gameNetCycle & 0xFF] _C_ GameCycle); } } @@ -968,7 +1000,7 @@ static void NetworkExecCommand_ExtendedCommand(const CNetworkCommandQueue &ncq) nec.Deserialize(&ncq.Data[0]); ExecExtendedCommand(nec.ExtendedType, (ncq.Type & 0x80) >> 7, - nec.Arg1, nec.Arg2, nec.Arg3, nec.Arg4); + nec.Arg1, nec.Arg2, nec.Arg3, nec.Arg4); } static void NetworkExecCommand_Command(const CNetworkCommandQueue &ncq) @@ -987,16 +1019,16 @@ static void NetworkExecCommand_Command(const CNetworkCommandQueue &ncq) static void NetworkExecCommand(const CNetworkCommandQueue &ncq) { switch (ncq.Type & 0x7F) { - case MessageSync: NetworkExecCommand_Sync(ncq); break; - case MessageSelection: NetworkExecCommand_Selection(ncq); break; - case MessageChat: NetworkExecCommand_Chat(ncq); break; - case MessageQuit: NetworkExecCommand_Quit(ncq); break; - case MessageExtendedCommand: NetworkExecCommand_ExtendedCommand(ncq); break; - case MessageNone: - // Nothing to Do, This Message Should Never be Executed - Assert(0); - break; - default: NetworkExecCommand_Command(ncq); break; + case MessageSync: NetworkExecCommand_Sync(ncq); break; + case MessageSelection: NetworkExecCommand_Selection(ncq); break; + case MessageChat: NetworkExecCommand_Chat(ncq); break; + case MessageQuit: NetworkExecCommand_Quit(ncq); break; + case MessageExtendedCommand: NetworkExecCommand_ExtendedCommand(ncq); break; + case MessageNone: + // Nothing to Do, This Message Should Never be Executed + Assert(0); + break; + default: NetworkExecCommand_Command(ncq); break; } } @@ -1030,8 +1062,8 @@ static void NetworkSendCommands(unsigned long gameNetCycle) // FIXME: we can send destoyed units over network :( if (unit.Destroyed) { DebugPrint("Sending destroyed unit %d over network!!!!!!\n" _C_ nc.Unit); - } - } + } +} #endif ncq[numcommands] = incommand; ncq[numcommands].Time = gameNetCycle; @@ -1105,7 +1137,7 @@ static void CheckPlayerThatTimeOut(int hostIndex) const int timeoutInS = CNetworkParameter::Instance.timeoutInS; if (3 <= secs && secs < timeoutInS && FrameCounter % framesPerSecond == 0) { SetMessage(_("Waiting for player \"%s\": %d:%02d"), Hosts[hostIndex].PlyName, - (timeoutInS - secs) / 60, (timeoutInS - secs) % 60); + (timeoutInS - secs) / 60, (timeoutInS - secs) % 60); } if (secs >= timeoutInS) { const unsigned int nextGameNetCycle = GameCycle / CNetworkParameter::Instance.gameCyclesPerUpdate + 1; From 3799328074bf9b4bddffdb88327366f77a4fe3ee Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Mon, 18 Jun 2018 21:17:45 -0700 Subject: [PATCH 02/32] Network changes refactoring --- src/include/netconnect.h | 49 ++++++-- src/include/network.h | 2 + src/network/master.cpp | 236 +++++++++++++++++++------------------ src/network/netconnect.cpp | 211 ++++++++++++++++++++++++++++++--- src/network/network.cpp | 44 +------ 5 files changed, 364 insertions(+), 178 deletions(-) diff --git a/src/include/netconnect.h b/src/include/netconnect.h index 54baca405b..1bbfc4e0df 100644 --- a/src/include/netconnect.h +++ b/src/include/netconnect.h @@ -144,18 +144,28 @@ class CServer public: void Init(const std::string &name, CServerSetup *serverSetup); - void Update(unsigned long frameCounter); - void Parse(unsigned long frameCounter, const unsigned char *buf, const CHost &host); + void Open(const CHost &host); - void MarkClientsAsResync(); - void KickClient(int c); + bool IsValid(); + + int HasDataToRead(int timeout); + + void SendToAllClients(const void *buf, unsigned int len); template - void SendToSpecificClient(const CHost &host, const T &msg); + void SendMessageToSpecificClient(const CHost &host, const T &msg); - bool HasDataToRead(int count); + void SendMessageToSpecificClient(const CHost &host, const CInitMessage_Header &msg); - int Recv(); + int Recv(void *buf, int len, CHost *hostFrom); + + void Close(); + + void Update(unsigned long frameCounter); + void Parse(unsigned long frameCounter, const unsigned char *buf, const CHost &host); + + void MarkClientsAsResync(); + void KickClient(int c); private: int Parse_Hello(int h, const CInitMessage_Hello &msg, const CHost &host); @@ -177,6 +187,11 @@ class CServer private: std::string name; NetworkState networkStates[PlayerMax]; /// Client Host states +#if UDP + CUDPSocket *socket = nullptr; +#else + CTCPSocket *socket = nullptr; +#endif CServerSetup *serverSetup; }; @@ -186,6 +201,18 @@ class CClient void Init(const std::string &name, CServerSetup *serverSetup, CServerSetup *localSetup, unsigned long tick); void SetServerHost(const CHost &host) { serverHost = host; } + void Open(); + + bool IsValid(); + + int HasDataToRead(int timeout); + + void SendToServer(const void *buf, unsigned int len); + + int Recv(void *buf, int len, CHost *hostFrom); + + void Close(); + bool Parse(const unsigned char *buf, const CHost &host); bool Update(unsigned long tick); @@ -240,7 +267,13 @@ class CClient CHost serverHost; /// IP:port of server to join NetworkState networkState; unsigned char lastMsgTypeSent; /// Subtype of last InitConfig message sent - //CUDPSocket *socket; + +#if UDP + CUDPSocket *socket = nullptr; +#else + CTCPSocket *socket = nullptr; +#endif + CServerSetup *serverSetup; CServerSetup *localSetup; }; diff --git a/src/include/network.h b/src/include/network.h index 602076b094..e89dd26343 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -74,6 +74,8 @@ extern bool NetworkInSync; /// Network is in sync ----------------------------------------------------------------------------*/ extern inline bool IsNetworkGame(); +extern inline int NetworkHasDataToRead(); + extern void InitNetwork1(); /// Initialise network extern void ExitNetwork1(); /// Cleanup network (port) extern void NetworkOnStartGame(); /// Initialise network data for ingame communication diff --git a/src/network/master.cpp b/src/network/master.cpp index 7bc09d9177..4ebca366eb 100644 --- a/src/network/master.cpp +++ b/src/network/master.cpp @@ -69,18 +69,18 @@ CMetaClient MetaClient; */ void CMetaClient::SetMetaServer(const std::string host, const int port) { - metaHost = host; - metaPort = port; + /*metaHost = host; + metaPort = port;*/ } CMetaClient::~CMetaClient() { - for (std::list::iterator it = events.begin(); it != events.end(); ++it) { + /*for (std::list::iterator it = events.begin(); it != events.end(); ++it) { CClientLog *log = *it; delete log; } events.clear(); - this->Close(); + this->Close();*/ } /** @@ -90,48 +90,50 @@ CMetaClient::~CMetaClient() */ int CMetaClient::Init() { - if (metaPort == -1) { - return -1; - } - - // Server socket - CHost metaServerHost(metaHost.c_str(), metaPort); - // Client socket - - // open on all interfaces, not the loopback, unless we have an override from the commandline - std::string localHost = CNetworkParameter::Instance.localHost; - if (!localHost.compare("127.0.0.1")) { - localHost = "0.0.0.0"; - } - CHost metaClientHost(localHost.c_str(), CNetworkParameter::Instance.localPort); - metaSocket.Open(metaClientHost); - if (metaSocket.IsValid() == false) { - fprintf(stderr, "METACLIENT: No free port %d available, aborting\n", metaServerHost.getPort()); - return -1; - } - if (metaSocket.Connect(metaServerHost) == false) { - fprintf(stderr, "METACLIENT: Unable to connect to host %s\n", metaServerHost.toString().c_str()); - MetaClient.Close(); - return -1; - } - - if (this->Send("PING") == -1) { // not sent - MetaClient.Close(); - return -1; - } - if (this->Recv() == -1) { // not received - MetaClient.Close(); - return -1; - } - CClientLog &log = *GetLastMessage(); - if (log.entry.find("PING_OK") != std::string::npos) { - // Everything is OK - return 0; - } else { - fprintf(stderr, "METACLIENT: inappropriate message received from %s\n", metaServerHost.toString().c_str()); - MetaClient.Close(); - return -1; - } + return -1; + + //if (metaPort == -1) { + // return -1; + //} + + //// Server socket + //CHost metaServerHost(metaHost.c_str(), metaPort); + //// Client socket + + //// open on all interfaces, not the loopback, unless we have an override from the commandline + //std::string localHost = CNetworkParameter::Instance.localHost; + //if (!localHost.compare("127.0.0.1")) { + // localHost = "0.0.0.0"; + //} + //CHost metaClientHost(localHost.c_str(), CNetworkParameter::Instance.localPort); + //metaSocket.Open(metaClientHost); + //if (metaSocket.IsValid() == false) { + // fprintf(stderr, "METACLIENT: No free port %d available, aborting\n", metaServerHost.getPort()); + // return -1; + //} + //if (metaSocket.Connect(metaServerHost) == false) { + // fprintf(stderr, "METACLIENT: Unable to connect to host %s\n", metaServerHost.toString().c_str()); + // MetaClient.Close(); + // return -1; + //} + + //if (this->Send("PING") == -1) { // not sent + // MetaClient.Close(); + // return -1; + //} + //if (this->Recv() == -1) { // not received + // MetaClient.Close(); + // return -1; + //} + //CClientLog &log = *GetLastMessage(); + //if (log.entry.find("PING_OK") != std::string::npos) { + // // Everything is OK + // return 0; + //} else { + // fprintf(stderr, "METACLIENT: inappropriate message received from %s\n", metaServerHost.toString().c_str()); + // MetaClient.Close(); + // return -1; + //} } /** @@ -141,9 +143,9 @@ int CMetaClient::Init() */ void CMetaClient::Close() { - if (metaSocket.IsValid()) { + /*if (metaSocket.IsValid()) { metaSocket.Close(); - } + }*/ } @@ -156,13 +158,15 @@ void CMetaClient::Close() */ int CMetaClient::Send(const std::string cmd) { - int ret = -1; + return -1; + + /*int ret = -1; if (metaSocket.IsValid()) { std::string mes(cmd); mes.append("\n"); ret = metaSocket.Send(mes.c_str(), mes.size()); } - return ret; + return ret;*/ } /** @@ -172,73 +176,77 @@ int CMetaClient::Send(const std::string cmd) */ int CMetaClient::Recv() { - if (metaSocket.HasDataToRead(5000) == -1) { - return -1; - } - - char buf[1024]; - memset(&buf, 0, sizeof(buf)); - int n = metaSocket.Recv(&buf, sizeof(buf)); - if (n == -1) { - return n; - } - // We know we now have the whole command. - // Convert to standard notation - std::string cmd(buf, strlen(buf)); - cmd += '\n'; - cmd += '\0'; - CClientLog *log = new CClientLog; - log->entry = cmd; - events.push_back(log); - lastRecvState = n; - return n; + return -1; + + //if (metaSocket.HasDataToRead(5000) == -1) { + // return -1; + //} + + //char buf[1024]; + //memset(&buf, 0, sizeof(buf)); + //int n = metaSocket.Recv(&buf, sizeof(buf)); + //if (n == -1) { + // return n; + //} + //// We know we now have the whole command. + //// Convert to standard notation + //std::string cmd(buf, strlen(buf)); + //cmd += '\n'; + //cmd += '\0'; + //CClientLog *log = new CClientLog; + //log->entry = cmd; + //events.push_back(log); + //lastRecvState = n; + //return n; } //@} int CMetaClient::CreateGame(std::string desc, std::string map, std::string players) { - if (metaSocket.IsValid() == false) { - return -1; - } - if (Server.IsValid() == false) { - return -1; - } - CHost metaServerHost(metaHost.c_str(), metaPort); - - // Advertise an external IP address if we can - unsigned long ips[1]; - int networkNumInterfaces = Server.GetSocketAddresses(ips, 1); - std::string ipport = ""; - if (!networkNumInterfaces || CNetworkParameter::Instance.localHost.compare("127.0.0.1")) { - ipport += CNetworkParameter::Instance.localHost.c_str(); - } else { - ipport += inet_ntoa(((struct in_addr *)ips)[0]); - } - ipport += " "; - ipport += std::to_string(CNetworkParameter::Instance.localPort); - - std::string cmd("CREATEGAME \""); - cmd += desc; - cmd += "\" \""; - cmd += map; - cmd += "\" "; - cmd += players; - cmd += " "; - cmd += ipport; - - if (this->Send(cmd.c_str()) == -1) { // not sent - return -1; - } - if (this->Recv() == -1) { // not received - return -1; - } - CClientLog &log = *GetLastMessage(); - if (log.entry.find("CREATEGAME_OK") != std::string::npos) { - // Everything is OK, let's inform metaserver of our UDP info - NetworkFildes.Send(metaServerHost, ipport.c_str(), ipport.size()); - return 0; - } else { - fprintf(stderr, "METACLIENT: failed to create game: %s\n", log.entry.c_str()); - return -1; - } + return -1; + + //if (metaSocket.IsValid() == false) { + // return -1; + //} + //if (Server.IsValid() == false) { + // return -1; + //} + //CHost metaServerHost(metaHost.c_str(), metaPort); + + //// Advertise an external IP address if we can + //unsigned long ips[1]; + //int networkNumInterfaces = Server.GetSocketAddresses(ips, 1); + //std::string ipport = ""; + //if (!networkNumInterfaces || CNetworkParameter::Instance.localHost.compare("127.0.0.1")) { + // ipport += CNetworkParameter::Instance.localHost.c_str(); + //} else { + // ipport += inet_ntoa(((struct in_addr *)ips)[0]); + //} + //ipport += " "; + //ipport += std::to_string(CNetworkParameter::Instance.localPort); + + //std::string cmd("CREATEGAME \""); + //cmd += desc; + //cmd += "\" \""; + //cmd += map; + //cmd += "\" "; + //cmd += players; + //cmd += " "; + //cmd += ipport; + + //if (this->Send(cmd.c_str()) == -1) { // not sent + // return -1; + //} + //if (this->Recv() == -1) { // not received + // return -1; + //} + //CClientLog &log = *GetLastMessage(); + //if (log.entry.find("CREATEGAME_OK") != std::string::npos) { + // // Everything is OK, let's inform metaserver of our UDP info + // NetworkFildes.Send(metaServerHost, ipport.c_str(), ipport.size()); + // return 0; + //} else { + // fprintf(stderr, "METACLIENT: failed to create game: %s\n", log.entry.c_str()); + // return -1; + //} } diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index e9b04f6e53..6e94cb938c 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -47,6 +47,7 @@ #include "settings.h" #include "version.h" #include "video.h" +#include "net_lowlevel.h" //---------------------------------------------------------------------------- // Declaration @@ -72,6 +73,9 @@ int NetPlayers; /// How many network players std::string NetworkMapName; /// Name of the map received with ICMMap static int NoRandomPlacementMultiplayer = 0; /// Disable the random placement of players in muliplayer mode +CServer Server; +CClient Client; + CServerSetup ServerSetupState; // Server selection state for Multiplayer clients CServerSetup LocalSetupState; // Local selection state for Multiplayer clients @@ -169,9 +173,6 @@ class CClient CServerSetup *localSetup; };*/ -static CServer Server; -static CClient Client; - // // CClient // @@ -329,6 +330,65 @@ void CClient::Init(const std::string &name, CServerSetup *serverSetup, CServerSe this->serverSetup = serverSetup; this->localSetup = localSetup; this->name = name; + +#ifdef UDP + socket = new CUDPSocket(); +#else + x +#endif +} + +void CClient::Open() { +#ifdef UDP + socket->Open(CHost("localhost", 6661)); +#else + x +#endif +} + +bool CClient::IsValid() { + if (socket == nullptr) { + return false; + } + +#ifdef UDP + return socket->IsValid(); +#else + x +#endif +} + +int CClient::HasDataToRead(int timeout) { +#ifdef UDP + return socket->HasDataToRead(timeout); +#else + x +#endif +} + +void CClient::SendToServer(const void *buf, unsigned int len) { +#ifdef UDP + socket->Send(serverHost, buf, len); +#else + x +#endif +} + +int CClient::Recv(void *buf, int len, CHost *hostFrom) { +#ifdef UDP + return socket->Recv(buf, len, hostFrom); +#else + x +#endif +} + +void CClient::Close() { +#ifdef UDP + return socket->Close(); + socket = nullptr; +#else + x +#endif } void CClient::DetachFromServer() @@ -929,19 +989,118 @@ void CServer::Init(const std::string &name, CServerSetup *serverSetup) } this->serverSetup = serverSetup; this->name = name; + +#ifdef UDP + this->socket = new CUDPSocket(); +#else + this->socket = new CTCPSocket(); +#endif +} + +void CServer::Open(const CHost &host) { +#ifdef UDP + socket->Open(host); +#else + x +#endif +} + +bool CServer::IsValid() { + if (socket == nullptr) { + return false; + } + +#ifdef UDP + return socket->IsValid(); +#else + x +#endif +} + +int CServer::HasDataToRead(int timeout) { +#ifdef UDP + return socket->HasDataToRead(timeout); +#else + x +#endif +} + +void CServer::SendToAllClients(const void *buf, unsigned int len) { +#ifdef UDP + for (int i = 0; i < HostsCount; ++i) { + const CHost host(Hosts[i].Host, Hosts[i].Port); + socket->Send(host, buf, len); + } +#else + x +#endif +} + + +//template +//static void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const T &msg) +//{ +// const unsigned char *buf = msg.Serialize(); +// socket.Send(host, buf, msg.Size()); +// delete[] buf; +//} + +template +void CServer::SendMessageToSpecificClient(const CHost &host, const T &msg) { + const unsigned char *buf = msg.Serialize(); + +#ifdef UDP + socket->Send(host, buf, msg.Size()); +#else + x +#endif + + delete[] buf; +} + +void CServer::SendMessageToSpecificClient(const CHost &host, const CInitMessage_Header &msg) +{ + unsigned char *buf = new unsigned char [msg.Size()]; + msg.Serialize(buf); + +#ifdef UDP + socket->Send(host, buf, msg.Size()); +#else + x +#endif + + delete[] buf; +} + +int CServer::Recv(void *buf, int len, CHost *hostFrom) { +#ifdef UDP + return socket->Recv(buf, len, hostFrom); +#else + x +#endif +} + +void CServer::Close() { +#ifdef UDP + socket->Close(); +#else + x +#endif + + socket = nullptr; } void CServer::Send_AreYouThere(const CNetworkHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMAYT); // AreYouThere - SendToSpecificClient(CHost(host.Host, host.Port), message); + SendMessageToSpecificClient(CHost(host.Host, host.Port), message); //NetworkSendICMessage(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_GameFull(const CHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMGameFull); - SendToSpecificClient(host, message); + SendMessageToSpecificClient(host, message); //NetworkSendICMessage_Log(*socket, host, message); } @@ -956,7 +1115,7 @@ void CServer::Send_Welcome(const CNetworkHost &host, int index) message.hosts[i] = Hosts[i]; } } - SendToSpecificClient(CHost(host.Host, host.Port), message); + SendMessageToSpecificClient(CHost(host.Host, host.Port), message); //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } @@ -969,28 +1128,28 @@ void CServer::Send_Resync(const CNetworkHost &host, int hostIndex) message.hosts[i] = Hosts[i]; } } - SendToSpecificClient(CHost(host.Host, host.Port), message); + SendMessageToSpecificClient(CHost(host.Host, host.Port), message); //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_Map(const CNetworkHost &host) { const CInitMessage_Map message(NetworkMapName.c_str(), Map.Info.MapUID); - SendToSpecificClient(CHost(host.Host, host.Port), message); + SendMessageToSpecificClient(CHost(host.Host, host.Port), message); //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_State(const CNetworkHost &host) { const CInitMessage_State message(MessageInit_FromServer, *serverSetup); - SendToSpecificClient(CHost(host.Host, host.Port), message); + SendMessageToSpecificClient(CHost(host.Host, host.Port), message); //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_GoodBye(const CNetworkHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMGoodBye); - SendToSpecificClient(CHost(host.Host, host.Port), message); + SendMessageToSpecificClient(CHost(host.Host, host.Port), message); //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } @@ -1358,12 +1517,12 @@ void CServer::Parse(unsigned long frameCounter, const unsigned char *buf, const int versionCheck = CheckVersions(msg, host); if (versionCheck == -1) { const CInitMessage_EngineMismatch message; - Server.SendToSpecificClient(host, message); + Server.SendMessageToSpecificClient(host, message); return; } if (versionCheck == -2) { const CInitMessage_LuaFilesMismatch message; - Server.SendToSpecificClient(host, message); + Server.SendMessageToSpecificClient(host, message); return; } // Special case: a new client has arrived @@ -1501,6 +1660,12 @@ void NetworkInitClientConnect() ServerSetupState.Clear(); LocalSetupState.Clear(); Client.Init(Parameters::Instance.LocalPlayerName, &ServerSetupState, &LocalSetupState, GetTicks()); + + Client.Open(); + if (Client.IsValid() == false) { + fprintf(stderr, "Unable to open socket for client\n"); + NetExit(); // machine dependent network exit + } } /** @@ -1680,10 +1845,10 @@ void NetworkServerStartGame() if (num[Hosts[i].PlyNr] == 1) { // not acknowledged yet message.clientIndex = i; - Server.SendToSpecificClient(host, message); + Server.SendMessageToSpecificClient(host, message); //NetworkSendICMessage_Log(NetworkFildes, host, message); } else if (num[Hosts[i].PlyNr] == 2) { - Server.SendToSpecificClient(host, statemsg); + Server.SendMessageToSpecificClient(host, statemsg); //NetworkSendICMessage_Log(NetworkFildes, host, statemsg); } } @@ -1751,7 +1916,7 @@ void NetworkServerStartGame() const CInitMessage_Header message_go(MessageInit_FromServer, ICMGo); for (int i = 0; i < HostsCount; ++i) { const CHost host(Hosts[i].Host, Hosts[i].Port); - Server.SendToSpecificClient(host, message_go); + Server.SendMessageToSpecificClient(host, message_go); //NetworkSendICMessage_Log(NetworkFildes, host, message_go); } } @@ -1809,6 +1974,22 @@ void NetworkInitServerConnect(int openslots) for (int i = openslots; i < PlayerMax - 1; ++i) { ServerSetupState.CompOpt[i] = 1; } + + // Our communication port + const int port = CNetworkParameter::Instance.localPort; + const char *NetworkAddr = NULL; // FIXME : bad use + const CHost host(NetworkAddr, port); + Server.Open(host); + + if (Server.IsValid() == false) { + fprintf(stderr, "NETWORK: No free port %d available, aborting\n", port); + NetExit(); // machine dependent network exit + return; + } +#ifdef DEBUG + const std::string hostStr = host.toString(); + DebugPrint("My host:port %s\n" _C_ hostStr.c_str()); +#endif } /** diff --git a/src/network/network.cpp b/src/network/network.cpp index 89e7c45197..6254d6b901 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -307,6 +307,7 @@ extern CServer Server; extern CClient Client; extern inline bool IsNetworkGame() { return Server.IsValid() || Client.IsValid(); } +extern inline int NetworkHasDataToRead() { return NetConnectType == 1 ? Server.HasDataToRead(0) : Client.HasDataToRead(0); } #ifdef DEBUG class CNetworkStat @@ -411,46 +412,7 @@ static void NetworkSendPacket(const CNetworkCommandQueue(&ncq)[MaxNetworkCommand void InitNetwork1() { CNetworkParameter::Instance.FixValues(); - NetInit(); // machine dependent setup - - if (NetConnectType == 1) { // server - // Our communication port - const int port = CNetworkParameter::Instance.localPort; - const char *NetworkAddr = NULL; // FIXME : bad use - const CHost host(NetworkAddr, port); - Server.Open(host); - - if (Server.IsValid() == false) { - fprintf(stderr, "NETWORK: No free port %d available, aborting\n", port); - NetExit(); // machine dependent network exit - return; - } -#ifdef DEBUG - const std::string hostStr = host.toString(); - DebugPrint("My host:port %s\n" _C_ hostStr.c_str()); -#endif - } - else { // client - Client.Open(); - if (Client.IsValid() == false) { - fprintf(stderr, "Unable to open socket for client\n"); - NetExit(); // machine dependent network exit - return; - } - } - - /*unsigned long ips[10]; - int networkNumInterfaces = NetworkFildes.GetSocketAddresses(ips, 10); - if (networkNumInterfaces) { - DebugPrint("Num IP: %d\n" _C_ networkNumInterfaces); - for (int i = 0; i < networkNumInterfaces; ++i) { - DebugPrint("IP: %d.%d.%d.%d\n" _C_ NIPQUAD(ntohl(ips[i]))); - } - } else { - fprintf(stderr, "WARNING: Not connected to any external IPV4-network!\n"); - return; - }*/ } /** @@ -462,11 +424,11 @@ void ExitNetwork1() return; } -#ifdef DEBUG +/*#ifdef DEBUG printStatistic(NetworkFildes.getStatistic()); NetworkFildes.clearStatistic(); NetworkStat.print(); -#endif +#endif*/ if (NetConnectType == 1) { // server Server.Close(); From 25d697cf8cf8c66ffed594e2e6b3e2c682e06bc9 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Mon, 18 Jun 2018 21:24:02 -0700 Subject: [PATCH 03/32] Fix video file --- src/video/sdl.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp index 5e1983b0b2..70909cc9b1 100644 --- a/src/video/sdl.cpp +++ b/src/video/sdl.cpp @@ -75,6 +75,7 @@ #ifdef USE_WIN32 #include +#include #endif #include "editor.h" @@ -91,6 +92,7 @@ #include "unit.h" #include "video.h" #include "widgets.h" +#include /*---------------------------------------------------------------------------- -- Declarations @@ -578,8 +580,10 @@ void InitVideoSdl() } if (hicon) { +#ifndef NO_ICON SendMessage(hwnd, (UINT)WM_SETICON, ICON_SMALL, (LPARAM)hicon); SendMessage(hwnd, (UINT)WM_SETICON, ICON_BIG, (LPARAM)hicon); +#endif } #endif } @@ -983,7 +987,7 @@ void WaitEventsOneFrame() // Network int s = 0; if (IsNetworkGame()) { - s = NetworkFildes.HasDataToRead(0); + s = NetworkHasDataToRead(); if (s > 0) { GetCallbacks()->NetworkEvent(); } From 918214672c77b638f7fdd1a42072529408634e03 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Mon, 18 Jun 2018 22:14:21 -0700 Subject: [PATCH 04/32] Fix last glitches --- src/network/netconnect.cpp | 6 +++--- src/network/network.cpp | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 6e94cb938c..53f04d9cf6 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -340,7 +340,7 @@ void CClient::Init(const std::string &name, CServerSetup *serverSetup, CServerSe void CClient::Open() { #ifdef UDP - socket->Open(CHost("localhost", 6661)); + socket->Open(CHost("localhost", 6662)); #else x #endif @@ -950,7 +950,7 @@ template void CClient::SendToServer(const T &msg) { const unsigned char *buf = msg.Serialize(); - //socket.Send(host, buf, msg.Size()); + SendToServer(buf, msg.Size()); delete[] buf; } @@ -958,7 +958,7 @@ void CClient::SendToServer(const CInitMessage_Header &msg) { unsigned char *buf = new unsigned char [msg.Size()]; msg.Serialize(buf); - //socket.Send(host, buf, msg.Size()); + SendToServer(buf, msg.Size()); delete[] buf; } diff --git a/src/network/network.cpp b/src/network/network.cpp index 6254d6b901..b659d04e6b 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -844,9 +844,9 @@ void NetworkEvent() int len; if (NetConnectType == 1) { // server - Server.Recv(&buf, sizeof(buf), &host); + len = Server.Recv(&buf, sizeof(buf), &host); } else { // client - Client.Recv(&buf, sizeof(buf), &host); + len = Client.Recv(&buf, sizeof(buf), &host); } //int len = NetworkFildes.Recv(&buf, sizeof(buf), &host); From 78cf7ea7cfde6a1523a10b7edb6bc6dbfffecffd Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Mon, 18 Jun 2018 23:16:43 -0700 Subject: [PATCH 05/32] Specify random port for client --- src/network/netconnect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 53f04d9cf6..50cc7c0ca1 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -340,7 +340,7 @@ void CClient::Init(const std::string &name, CServerSetup *serverSetup, CServerSe void CClient::Open() { #ifdef UDP - socket->Open(CHost("localhost", 6662)); + socket->Open(CHost("localhost", 0)); #else x #endif From 965387dd24ee11df7aa8469126a4cb6585e29c5f Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Wed, 20 Jun 2018 07:22:24 -0700 Subject: [PATCH 06/32] TCP with blocking client socket --- src/include/netconnect.h | 10 ++-- src/include/network/netsockets.h | 13 +++-- src/network/netconnect.cpp | 91 ++++++++++++++++++++++++-------- src/network/netsockets.cpp | 85 ++++++++++++++++++++++++++--- src/network/network.cpp | 9 +++- 5 files changed, 169 insertions(+), 39 deletions(-) diff --git a/src/include/netconnect.h b/src/include/netconnect.h index 1bbfc4e0df..8a8c0d4dbe 100644 --- a/src/include/netconnect.h +++ b/src/include/netconnect.h @@ -150,14 +150,14 @@ class CServer int HasDataToRead(int timeout); - void SendToAllClients(const void *buf, unsigned int len); + void SendToAllClients(const unsigned char *buf, unsigned int len); template void SendMessageToSpecificClient(const CHost &host, const T &msg); void SendMessageToSpecificClient(const CHost &host, const CInitMessage_Header &msg); - int Recv(void *buf, int len, CHost *hostFrom); + int Recv(unsigned char *buf, int len, CHost *hostFrom); void Close(); @@ -207,13 +207,13 @@ class CClient int HasDataToRead(int timeout); - void SendToServer(const void *buf, unsigned int len); + void SendToServer(const unsigned char *buf, unsigned int len); - int Recv(void *buf, int len, CHost *hostFrom); + int Recv(unsigned char *buf, int len, CHost *hostFrom); void Close(); - bool Parse(const unsigned char *buf, const CHost &host); + bool Parse(const unsigned char *buf); bool Update(unsigned long tick); void DetachFromServer(); diff --git a/src/include/network/netsockets.h b/src/include/network/netsockets.h index b2701cd437..c50a35901a 100644 --- a/src/include/network/netsockets.h +++ b/src/include/network/netsockets.h @@ -46,6 +46,7 @@ class CHost bool operator == (const CHost &rhs) const { return ip == rhs.ip && port == rhs.port; } bool operator != (const CHost &rhs) const { return !(*this == rhs); } + bool operator < (const CHost &rhs) const { return ip < rhs.ip || ip == rhs.ip && port < rhs.port; } private: unsigned long ip; int port; @@ -61,8 +62,8 @@ class CUDPSocket ~CUDPSocket(); bool Open(const CHost &host); void Close(); - void Send(const CHost &host, const void *buf, unsigned int len); - int Recv(void *buf, int len, CHost *hostFrom); + void Send(const CHost &host, const unsigned char *buf, unsigned int len); + int Recv(unsigned char *buf, int len, CHost *hostFrom); void SetNonBlocking(); // int HasDataToRead(int timeout); @@ -105,15 +106,19 @@ class CTCPSocket CTCPSocket(); ~CTCPSocket(); bool Open(const CHost &host); + int Listen(); + CTCPSocket* Accept(); void Close(); bool Connect(const CHost &host); - int Send(const void *buf, unsigned int len); - int Recv(void *buf, int len); + int Send(const unsigned char *buf, unsigned int len); + int Recv(unsigned char *buf, int len); void SetNonBlocking(); // int HasDataToRead(int timeout); bool IsValid() const; + CHost GetHost() const; private: + CTCPSocket(CTCPSocket_Impl *impl); CTCPSocket_Impl *m_impl; }; diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 50cc7c0ca1..7e5e2a338e 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -334,7 +334,7 @@ void CClient::Init(const std::string &name, CServerSetup *serverSetup, CServerSe #ifdef UDP socket = new CUDPSocket(); #else - x + socket = new CTCPSocket(); #endif } @@ -342,7 +342,9 @@ void CClient::Open() { #ifdef UDP socket->Open(CHost("localhost", 0)); #else - x + socket->Open(CHost("localhost", 0)); + socket->SetBlocking(); + socket->Connect(this->serverHost); #endif } @@ -354,7 +356,7 @@ bool CClient::IsValid() { #ifdef UDP return socket->IsValid(); #else - x + return socket->IsValid(); #endif } @@ -362,32 +364,34 @@ int CClient::HasDataToRead(int timeout) { #ifdef UDP return socket->HasDataToRead(timeout); #else - x + return socket->HasDataToRead(timeout); #endif } -void CClient::SendToServer(const void *buf, unsigned int len) { +void CClient::SendToServer(const unsigned char *buf, unsigned int len) { #ifdef UDP socket->Send(serverHost, buf, len); #else - x + socket->Send(buf, len); #endif } -int CClient::Recv(void *buf, int len, CHost *hostFrom) { +int CClient::Recv(unsigned char *buf, int len, CHost *hostFrom) { #ifdef UDP return socket->Recv(buf, len, hostFrom); #else - x + *hostFrom = serverHost; + return socket->Recv(buf, len); #endif } void CClient::Close() { #ifdef UDP - return socket->Close(); + socket->Close(); socket = nullptr; #else - x + socket->Close(); + socket = nullptr; #endif } @@ -678,7 +682,7 @@ void CClient::SetConfig(const CInitMessage_Config &msg) #endif } -bool CClient::Parse(const unsigned char *buf, const CHost &host) +bool CClient::Parse(const unsigned char *buf) { CInitMessage_Header header; header.Deserialize(buf); @@ -1001,7 +1005,9 @@ void CServer::Open(const CHost &host) { #ifdef UDP socket->Open(host); #else - x + socket->Open(host); + socket->SetNonBlocking(); + socket->Listen(); #endif } @@ -1013,26 +1019,50 @@ bool CServer::IsValid() { #ifdef UDP return socket->IsValid(); #else - x + return socket->IsValid(); #endif } +#ifndef UDP + std::map clientSockets; +#endif + int CServer::HasDataToRead(int timeout) { #ifdef UDP return socket->HasDataToRead(timeout); #else - x + const auto newClientSocket = socket->Accept(); + if (newClientSocket) + { + newClientSocket->SetBlocking(); + clientSockets[newClientSocket->GetHost()] = newClientSocket; + } + + for (auto& it : clientSockets) + { + const int read = it.second->HasDataToRead(timeout); + if(read > 0) + { + return read; + } + } + + return 0; #endif } -void CServer::SendToAllClients(const void *buf, unsigned int len) { +void CServer::SendToAllClients(const unsigned char *buf, unsigned int len) { #ifdef UDP for (int i = 0; i < HostsCount; ++i) { const CHost host(Hosts[i].Host, Hosts[i].Port); socket->Send(host, buf, len); } #else - x + for (int i = 0; i < HostsCount; ++i) { + const CHost host(Hosts[i].Host, Hosts[i].Port); + //TODO CHECK IF FAILED + clientSockets[host]->Send(buf, len); + } #endif } @@ -1052,7 +1082,7 @@ void CServer::SendMessageToSpecificClient(const CHost &host, const T &msg) { #ifdef UDP socket->Send(host, buf, msg.Size()); #else - x + clientSockets[host]->Send(buf, msg.Size()); #endif delete[] buf; @@ -1066,17 +1096,28 @@ void CServer::SendMessageToSpecificClient(const CHost &host, const CInitMessage_ #ifdef UDP socket->Send(host, buf, msg.Size()); #else - x + auto clientSocket = clientSockets[host]; + clientSocket->Send(buf, msg.Size()); #endif delete[] buf; } -int CServer::Recv(void *buf, int len, CHost *hostFrom) { +int CServer::Recv(unsigned char *buf, int len, CHost *hostFrom) { #ifdef UDP return socket->Recv(buf, len, hostFrom); #else - x + for (auto& it : clientSockets) + { + const int read = it.second->HasDataToRead(0); + if (read > 0) + { + *hostFrom = it.first; + return it.second->Recv(buf, len); + } + } + + return 0; #endif } @@ -1084,7 +1125,13 @@ void CServer::Close() { #ifdef UDP socket->Close(); #else - x + for (auto& it : clientSockets) + { + it.second->Close(); + } + + clientSockets.clear(); + socket->Close(); #endif socket = nullptr; @@ -1600,7 +1647,7 @@ int NetworkParseSetupEvent(const unsigned char *buf, int size, const CHost &host hostStr.c_str()); #endif if (NetConnectRunning == 2) { // client - if (Client.Parse(buf, host) == false) { + if (Client.Parse(buf) == false) { NetConnectRunning = 0; } } else if (NetConnectRunning == 1) { // server diff --git a/src/network/netsockets.cpp b/src/network/netsockets.cpp index 265147bf53..3aac2c111c 100644 --- a/src/network/netsockets.cpp +++ b/src/network/netsockets.cpp @@ -135,7 +135,7 @@ void CUDPSocket::Close() m_impl->Close(); } -void CUDPSocket::Send(const CHost &host, const void *buf, unsigned int len) +void CUDPSocket::Send(const CHost &host, const unsigned char *buf, unsigned int len) { #ifdef DEBUG ++m_statistic.sentPacketsCount; @@ -145,7 +145,7 @@ void CUDPSocket::Send(const CHost &host, const void *buf, unsigned int len) m_impl->Send(host, buf, len); } -int CUDPSocket::Recv(void *buf, int len, CHost *hostFrom) +int CUDPSocket::Recv(unsigned char *buf, int len, CHost *hostFrom) { const int res = m_impl->Recv(buf, len, hostFrom); #ifdef DEBUG @@ -192,21 +192,31 @@ class CTCPSocket_Impl bool Open(const CHost &host); void Close() { NetCloseTCP(socket); socket = Socket(-1); } bool Connect(const CHost &host) { return NetConnectTCP(socket, host.getIp(), host.getPort()) != -1; } + int Listen() { return NetListenTCP(socket); } + CTCPSocket_Impl* Accept(); int Send(const void *buf, unsigned int len) { return NetSendTCP(socket, buf, len); } int Recv(void *buf, int len) { int res = NetRecvTCP(socket, buf, len); return res; } + void SetBlocking() { NetSetBlocking(socket); } void SetNonBlocking() { NetSetNonBlocking(socket); } int HasDataToRead(int timeout) { return NetSocketReady(socket, timeout); } bool IsValid() const { return socket != Socket(-1); } + unsigned long ip; + int port; +private: + CTCPSocket_Impl(Socket socket, unsigned long ip, int port) : socket(socket), ip(ip), port(port) {} private: Socket socket; }; bool CTCPSocket_Impl::Open(const CHost &host) { + this->ip = host.getIp(); + this->port = host.getPort(); + char ip[24]; // 127.255.255.255:65555 memset(&ip, 0, sizeof(ip)); sprintf(ip, "%d.%d.%d.%d", NIPQUAD(ntohl(host.getIp()))); @@ -214,6 +224,19 @@ bool CTCPSocket_Impl::Open(const CHost &host) return this->socket != INVALID_SOCKET; } +CTCPSocket_Impl* CTCPSocket_Impl::Accept() +{ + unsigned long clientIp; + int clientPort; + auto clientSocket = NetAcceptTCP(socket, &clientIp, &clientPort); + if(clientSocket == INVALID_SOCKET) + { + return nullptr; + } + + return new CTCPSocket_Impl(clientSocket, clientIp, clientPort); +} + // // CTCPSocket // @@ -223,6 +246,11 @@ CTCPSocket::CTCPSocket() m_impl = new CTCPSocket_Impl(); } +CTCPSocket::CTCPSocket(CTCPSocket_Impl *impl) +{ + m_impl = impl; +} + CTCPSocket::~CTCPSocket() { delete m_impl; @@ -233,6 +261,11 @@ bool CTCPSocket::Open(const CHost &host) return m_impl->Open(host); } +int CTCPSocket::Listen() +{ + return m_impl->Listen(); +} + void CTCPSocket::Close() { m_impl->Close(); @@ -244,15 +277,49 @@ bool CTCPSocket::Connect(const CHost &host) return m_impl->Connect(host); } -int CTCPSocket::Send(const void *buf, unsigned int len) +CTCPSocket* CTCPSocket::Accept() { + auto impl = m_impl->Accept(); + if(impl == nullptr) + { + return nullptr; + } + + return new CTCPSocket(impl); +} + +int CTCPSocket::Send(const unsigned char *buf, unsigned int len) +{ + unsigned char *bufLength = new unsigned char[2]; + + bufLength[0] = len >> 8 & 0xFF; + bufLength[1] = len & 0xFF; + + m_impl->Send(bufLength, 2); return m_impl->Send(buf, len); } -int CTCPSocket::Recv(void *buf, int len) +int CTCPSocket::Recv(unsigned char *buf, int len) { - const int res = m_impl->Recv(buf, len); - return res; + int actualLen; + unsigned char *bufLength = new unsigned char[2]; + + const int resLen = m_impl->Recv(bufLength, 2); + if(resLen < 2) + { + return resLen; + } + + actualLen = bufLength[0]; + actualLen <<= 8; + actualLen |= bufLength[1]; + + return m_impl->Recv(buf, actualLen); +} + +void CTCPSocket::SetBlocking() +{ + m_impl->SetBlocking(); } void CTCPSocket::SetNonBlocking() @@ -270,4 +337,10 @@ bool CTCPSocket::IsValid() const return m_impl->IsValid(); } +CHost CTCPSocket::GetHost() const +{ + return CHost(m_impl->ip, m_impl->port); +} + + //@} diff --git a/src/network/network.cpp b/src/network/network.cpp index b659d04e6b..165a1156d6 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -844,9 +844,14 @@ void NetworkEvent() int len; if (NetConnectType == 1) { // server - len = Server.Recv(&buf, sizeof(buf), &host); + len = Server.Recv(buf, sizeof(buf), &host); } else { // client - len = Client.Recv(&buf, sizeof(buf), &host); + len = Client.Recv(buf, sizeof(buf), &host); + } + + if (len == 0) + { + return; } //int len = NetworkFildes.Recv(&buf, sizeof(buf), &host); From 44182bc40b3594b996a131118a6058def1ac64bb Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Wed, 20 Jun 2018 07:47:29 -0700 Subject: [PATCH 07/32] Fix blocking client socket --- src/include/network/netsockets.h | 1 + src/network/net_lowlevel.cpp | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/src/include/network/netsockets.h b/src/include/network/netsockets.h index c50a35901a..de7e5b499d 100644 --- a/src/include/network/netsockets.h +++ b/src/include/network/netsockets.h @@ -112,6 +112,7 @@ class CTCPSocket bool Connect(const CHost &host); int Send(const unsigned char *buf, unsigned int len); int Recv(unsigned char *buf, int len); + void SetBlocking(); void SetNonBlocking(); // int HasDataToRead(int timeout); diff --git a/src/network/net_lowlevel.cpp b/src/network/net_lowlevel.cpp index a182e8e5e1..91ef749d43 100644 --- a/src/network/net_lowlevel.cpp +++ b/src/network/net_lowlevel.cpp @@ -171,6 +171,27 @@ void NetCloseTCP(Socket sockfd) #endif // } !USE_WINSOCK +/** +** Set socket to blocking. +** +** @param sockfd Socket +** +** @return 0 for success, -1 for error +*/ +#ifdef USE_WINSOCK +int NetSetBlocking(Socket sockfd) +{ + unsigned long opt = 0; + return ioctlsocket(sockfd, FIONBIO, &opt); +} +#else +int NetSetNonBlocking(Socket sockfd) +{ + int flags = fcntl(sockfd, F_GETFL, 0); + return fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK); +} +#endif + /** ** Set socket to non-blocking. ** From 5a8addce51015bfb0d67861ae44730cc62780cef Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Wed, 20 Jun 2018 20:53:44 -0700 Subject: [PATCH 08/32] Fix naming of file --- src/network/net_lowlevel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/net_lowlevel.cpp b/src/network/net_lowlevel.cpp index 91ef749d43..73bbd7bf0b 100644 --- a/src/network/net_lowlevel.cpp +++ b/src/network/net_lowlevel.cpp @@ -185,7 +185,7 @@ int NetSetBlocking(Socket sockfd) return ioctlsocket(sockfd, FIONBIO, &opt); } #else -int NetSetNonBlocking(Socket sockfd) +int NetSetBlocking(Socket sockfd) { int flags = fcntl(sockfd, F_GETFL, 0); return fcntl(sockfd, F_SETFL, flags & ~O_NONBLOCK); From a0ea51396f726d58dbf257ec67f0588935c847eb Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Wed, 20 Jun 2018 21:00:11 -0700 Subject: [PATCH 09/32] Add extern definition --- src/include/net_lowlevel.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/include/net_lowlevel.h b/src/include/net_lowlevel.h index 42611a323e..45ca7078a7 100644 --- a/src/include/net_lowlevel.h +++ b/src/include/net_lowlevel.h @@ -141,6 +141,8 @@ extern int NetListenTCP(Socket sockfd); extern Socket NetAcceptTCP(Socket sockfd, unsigned long *clientHost, int *clientPort); +/// Set socket to blocking +extern int NetSetBlocking(Socket sockfd); /// Set socket to non-blocking extern int NetSetNonBlocking(Socket sockfd); /// Wait for socket ready. From 870f7e145ee6ed0f21290b7620baa292c0593d9d Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Thu, 21 Jun 2018 11:16:59 -0700 Subject: [PATCH 10/32] Fix HasDataToRead --- src/include/network.h | 2 +- src/network/netconnect.cpp | 2 +- src/network/network.cpp | 2 +- src/stratagus/main.cpp | 10 ++++++++++ src/video/sdl.cpp | 7 +++---- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/include/network.h b/src/include/network.h index e89dd26343..ad1da4ff43 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -74,7 +74,7 @@ extern bool NetworkInSync; /// Network is in sync ----------------------------------------------------------------------------*/ extern inline bool IsNetworkGame(); -extern inline int NetworkHasDataToRead(); +extern inline bool NetworkHasDataToRead(); extern void InitNetwork1(); /// Initialise network extern void ExitNetwork1(); /// Cleanup network (port) diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 7e5e2a338e..89e45ce716 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -1041,7 +1041,7 @@ int CServer::HasDataToRead(int timeout) { for (auto& it : clientSockets) { const int read = it.second->HasDataToRead(timeout); - if(read > 0) + if (read > 0) { return read; } diff --git a/src/network/network.cpp b/src/network/network.cpp index 165a1156d6..e311fffa92 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -307,7 +307,7 @@ extern CServer Server; extern CClient Client; extern inline bool IsNetworkGame() { return Server.IsValid() || Client.IsValid(); } -extern inline int NetworkHasDataToRead() { return NetConnectType == 1 ? Server.HasDataToRead(0) : Client.HasDataToRead(0); } +extern inline bool NetworkHasDataToRead() { return NetConnectType == 1 ? Server.HasDataToRead(0) > 0 : Client.HasDataToRead(0) > 0; } #ifdef DEBUG class CNetworkStat diff --git a/src/stratagus/main.cpp b/src/stratagus/main.cpp index 99d607c8a4..0b9865717d 100644 --- a/src/stratagus/main.cpp +++ b/src/stratagus/main.cpp @@ -32,6 +32,16 @@ #include "stratagus.h" #include "SDL.h" +#ifdef WIN32 +#include +#include + +int __stdcall WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, char*, int nShowCmd) +{ + return main(__argc, __argv); +} +#endif + int main(int argc, char **argv) { return stratagusMain(argc, argv); diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp index 70909cc9b1..bf26b1da29 100644 --- a/src/video/sdl.cpp +++ b/src/video/sdl.cpp @@ -985,15 +985,14 @@ void WaitEventsOneFrame() } // Network - int s = 0; + bool networkHasDataToRead = false; if (IsNetworkGame()) { - s = NetworkHasDataToRead(); - if (s > 0) { + if (networkHasDataToRead = NetworkHasDataToRead()) { GetCallbacks()->NetworkEvent(); } } // No more input and time for frame over: return - if (!i && s <= 0 && interrupts) { + if (!i && !networkHasDataToRead && interrupts) { break; } } From 0e16cd0ed86e63d5c726da29cf0df9e58ed93df0 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Thu, 21 Jun 2018 22:41:12 -0700 Subject: [PATCH 11/32] Works --- src/network/netconnect.cpp | 30 ++++++++++++++++++++++++++++++ src/network/netsockets.cpp | 9 ++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 89e45ce716..1681bc5cb9 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -1103,12 +1103,42 @@ void CServer::SendMessageToSpecificClient(const CHost &host, const CInitMessage_ delete[] buf; } +#ifndef UDP +int skipClient = 0; +#endif + int CServer::Recv(unsigned char *buf, int len, CHost *hostFrom) { #ifdef UDP return socket->Recv(buf, len, hostFrom); #else + int skip = skipClient; + int take = clientSockets.size(); + + skipClient = (skipClient + 1) % clientSockets.size(); + + for (auto& it : clientSockets) + { + if (skip-- > 0) + { + continue; + } + take--; + + const int read = it.second->HasDataToRead(0); + if (read > 0) + { + *hostFrom = it.first; + return it.second->Recv(buf, len); + } + } + for (auto& it : clientSockets) { + if (take-- == 0) + { + break; + } + const int read = it.second->HasDataToRead(0); if (read > 0) { diff --git a/src/network/netsockets.cpp b/src/network/netsockets.cpp index 3aac2c111c..d6f5c56ef6 100644 --- a/src/network/netsockets.cpp +++ b/src/network/netsockets.cpp @@ -314,7 +314,14 @@ int CTCPSocket::Recv(unsigned char *buf, int len) actualLen <<= 8; actualLen |= bufLength[1]; - return m_impl->Recv(buf, actualLen); + const int r1 = m_impl->Recv(buf, actualLen); + + if(r1 != actualLen) + { + DebugBreak(); + } + + return r1; } void CTCPSocket::SetBlocking() From 070e3f36756b80626ef055fd8684b3bba023c10a Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Thu, 21 Jun 2018 23:34:38 -0700 Subject: [PATCH 12/32] Cleanup code --- src/network/netconnect.cpp | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 1681bc5cb9..79fbef7ba0 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -1116,32 +1116,22 @@ int CServer::Recv(unsigned char *buf, int len, CHost *hostFrom) { skipClient = (skipClient + 1) % clientSockets.size(); - for (auto& it : clientSockets) - { - if (skip-- > 0) - { - continue; - } + for (auto& it : clientSockets) { + if (skip-- > 0) continue; take--; const int read = it.second->HasDataToRead(0); - if (read > 0) - { + if (read > 0) { *hostFrom = it.first; return it.second->Recv(buf, len); } } - for (auto& it : clientSockets) - { - if (take-- == 0) - { - break; - } + for (auto& it : clientSockets) { + if (take-- == 0) break; const int read = it.second->HasDataToRead(0); - if (read > 0) - { + if (read > 0) { *hostFrom = it.first; return it.second->Recv(buf, len); } From 6eeaf743b31416062758c9500c4e7fc1aab030ce Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Thu, 21 Jun 2018 23:38:04 -0700 Subject: [PATCH 13/32] Remove runtime check --- src/network/netsockets.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/network/netsockets.cpp b/src/network/netsockets.cpp index d6f5c56ef6..3aac2c111c 100644 --- a/src/network/netsockets.cpp +++ b/src/network/netsockets.cpp @@ -314,14 +314,7 @@ int CTCPSocket::Recv(unsigned char *buf, int len) actualLen <<= 8; actualLen |= bufLength[1]; - const int r1 = m_impl->Recv(buf, actualLen); - - if(r1 != actualLen) - { - DebugBreak(); - } - - return r1; + return m_impl->Recv(buf, actualLen); } void CTCPSocket::SetBlocking() From cb4d3f3233b3cde7338062b92f4a3f1625f8311f Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Fri, 22 Jun 2018 00:03:31 -0700 Subject: [PATCH 14/32] Fix path for linux --- src/include/netconnect.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/include/netconnect.h b/src/include/netconnect.h index 8a8c0d4dbe..8bfb4b28df 100644 --- a/src/include/netconnect.h +++ b/src/include/netconnect.h @@ -31,8 +31,12 @@ //@{ +/*---------------------------------------------------------------------------- +-- Includes +----------------------------------------------------------------------------*/ + #include "net_message.h" -#include "network\netsockets.h" +#include "network/netsockets.h" class CHost; From f258435de3fdbcbb6aab98b2fa412abb01222baf Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Fri, 22 Jun 2018 00:16:35 -0700 Subject: [PATCH 15/32] Remove winuser.h from includes --- src/video/sdl.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp index bf26b1da29..1e083baaaa 100644 --- a/src/video/sdl.cpp +++ b/src/video/sdl.cpp @@ -92,7 +92,6 @@ #include "unit.h" #include "video.h" #include "widgets.h" -#include /*---------------------------------------------------------------------------- -- Declarations From 635e76c0dbc560e04d321b3f14ac82fcab0e678e Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Fri, 22 Jun 2018 00:26:31 -0700 Subject: [PATCH 16/32] Fix unix build --- src/include/network.h | 5 +++-- src/network/netconnect.cpp | 5 +++++ src/network/network.cpp | 10 +++++++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/include/network.h b/src/include/network.h index ad1da4ff43..e73a64cfe0 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -68,16 +68,17 @@ class CNetworkParameter //extern CUDPSocket NetworkFildes; /// Network file descriptor extern bool NetworkInSync; /// Network is in sync +extern bool NetworkGame; /*---------------------------------------------------------------------------- -- Functions ----------------------------------------------------------------------------*/ -extern inline bool IsNetworkGame(); -extern inline bool NetworkHasDataToRead(); +extern inline bool IsNetworkGame() { return NetworkGame; } extern void InitNetwork1(); /// Initialise network extern void ExitNetwork1(); /// Cleanup network (port) +extern bool NetworkHasDataToRead(); extern void NetworkOnStartGame(); /// Initialise network data for ingame communication extern void NetworkEvent(); /// Handle network events extern void NetworkSync(); /// Hold in sync diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 79fbef7ba0..9bc81d92cb 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -1732,7 +1732,10 @@ void NetworkInitClientConnect() if (Client.IsValid() == false) { fprintf(stderr, "Unable to open socket for client\n"); NetExit(); // machine dependent network exit + return; } + + NetworkGame = true; } /** @@ -2057,6 +2060,8 @@ void NetworkInitServerConnect(int openslots) const std::string hostStr = host.toString(); DebugPrint("My host:port %s\n" _C_ hostStr.c_str()); #endif + + NetworkGame = true; } /** diff --git a/src/network/network.cpp b/src/network/network.cpp index e311fffa92..83d75cfe76 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -291,6 +291,7 @@ void CNetworkParameter::FixValues() } bool NetworkInSync = true; /// Network is in sync +bool NetworkGame = false; //CUDPSocket NetworkFildes; /// Network file descriptor @@ -306,9 +307,6 @@ static std::deque MsgCommandsIn; /// Network message input extern CServer Server; extern CClient Client; -extern inline bool IsNetworkGame() { return Server.IsValid() || Client.IsValid(); } -extern inline bool NetworkHasDataToRead() { return NetConnectType == 1 ? Server.HasDataToRead(0) > 0 : Client.HasDataToRead(0) > 0; } - #ifdef DEBUG class CNetworkStat { @@ -415,6 +413,11 @@ void InitNetwork1() NetInit(); // machine dependent setup } +bool NetworkHasDataToRead() +{ + return NetConnectType == 1 ? Server.HasDataToRead(0) > 0 : Client.HasDataToRead(0) > 0; +} + /** ** Cleanup network. */ @@ -440,6 +443,7 @@ void ExitNetwork1() NetExit(); // machine dependent setup NetworkInSync = true; + NetworkGame = false; NetPlayers = 0; HostsCount = 0; } From c2ba1dd2ac61955de4b7c4a858ce71120267cada Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Sun, 24 Jun 2018 22:31:46 -0700 Subject: [PATCH 17/32] Refactor connection handlers --- src/include/net_connection_handler.h | 139 ++++++++++ src/include/netconnect.h | 38 +-- src/include/network/netsockets.h | 5 +- src/include/parameters.h | 2 + src/network/net_connection_handler.cpp | 230 ++++++++++++++++ src/network/netconnect.cpp | 360 ++++++++++++++----------- src/network/netsockets.cpp | 41 +-- src/network/network.cpp | 2 +- src/stratagus/parameters.cpp | 1 + src/video/sdl.cpp | 3 +- 10 files changed, 607 insertions(+), 214 deletions(-) create mode 100644 src/include/net_connection_handler.h create mode 100644 src/network/net_connection_handler.cpp diff --git a/src/include/net_connection_handler.h b/src/include/net_connection_handler.h new file mode 100644 index 0000000000..1ede373e16 --- /dev/null +++ b/src/include/net_connection_handler.h @@ -0,0 +1,139 @@ +#ifndef __NET_CONNECTION_HANDLER_H__ +#define __NET_CONNECTION_HANDLER_H__ + +#include "network/netsockets.h" +#include +#include + +class IConnectionHandler +{ +public: + virtual ~IConnectionHandler() = default; + virtual void Open(const CHost &host) = 0; + virtual bool IsValid() = 0; + virtual int HasDataToRead(int timeout) = 0; + virtual int Recv(unsigned char *buf, int len, CHost *hostFrom) = 0; + virtual void Close() = 0; +}; + +class IServerConnectionHandler : public IConnectionHandler +{ +public: + virtual void SendToAllClients(std::vector hosts, const unsigned char *buf, unsigned int len) = 0; + virtual void SendToClient(CHost host, const unsigned char *buf, unsigned int len) = 0; +}; + +class IClientConnectionHandler : public IConnectionHandler +{ +public: + virtual void SendToServer(const unsigned char *buf, unsigned int len) = 0; +}; + +class CTCPConnectionHandler +{ +public: + CTCPConnectionHandler() = default; + CTCPConnectionHandler(CTCPSocket socket) : _socket(socket) {} + bool Open(const CHost& host); + int Listen(); + std::shared_ptr Accept(); + void Close(); + bool Connect(const CHost& host); + int Send(const unsigned char* buf, unsigned int len); + int Recv(unsigned char* buf, int len); + void SetBlocking(); + void SetNonBlocking(); + // + int HasDataToRead(int timeout); + bool IsValid() const; + CHost GetHost() const; + +private: + CTCPSocket _socket; +}; + +class CUDPConnectionHandler +{ +public: + bool Open(const CHost& host); + void Close(); + void Send(const CHost& host, const unsigned char* buf, unsigned int len); + int Recv(unsigned char* buf, int len, CHost* hostFrom); + void SetNonBlocking(); + // + int HasDataToRead(int timeout); + bool IsValid() const; + +private: + CUDPSocket _socket; +}; + +class CTCPServerConnectionHandler : public IServerConnectionHandler +{ +public: + void Open(const CHost& host) override; + bool IsValid() override { return _connectionHandler.IsValid(); } + int HasDataToRead(int timeout) override; + void SendToAllClients(std::vector hosts, const unsigned char* buf, unsigned int len) override; + void SendToClient(CHost host, const unsigned char* buf, unsigned int len) override; + int Recv(unsigned char* buf, int len, CHost* hostFrom) override; + void Close() override; + +private: + int _skipClient = 0; + CTCPConnectionHandler _connectionHandler; + std::map> _clientConnections; +}; + +class CUDPServerConnectionHandler : public IServerConnectionHandler +{ +public: + void Open(const CHost& host) override; + int HasDataToRead(int timeout) override { return _connectionHandler.HasDataToRead(timeout); } + void SendToAllClients(std::vector hosts, const unsigned char* buf, unsigned int len) override; + void SendToClient(CHost host, const unsigned char* buf, unsigned int len) override; + int Recv(unsigned char* buf, int len, CHost* hostFrom) override; + bool IsValid() override { return _connectionHandler.IsValid(); } + void Close() override { _connectionHandler.Close(); } + +private: + CUDPConnectionHandler _connectionHandler; +}; + +class CTCPClientConnectionHandler : public IClientConnectionHandler +{ +public: + CTCPClientConnectionHandler(CHost serverHost) + : _serverHost(serverHost) {} + + void Open(const CHost &host) override; + int HasDataToRead(int timeout) override { return _connectionHandler.HasDataToRead(timeout); } + void SendToServer(const unsigned char *buf, unsigned int len) override; + int Recv(unsigned char *buf, int len, CHost *hostFrom) override; + bool IsValid() override { return _connectionHandler.IsValid(); } + void Close() override { _connectionHandler.Close(); } + +private: + CHost _serverHost; + CTCPConnectionHandler _connectionHandler; +}; + +class CUDPClientConnectionHandler : public IClientConnectionHandler +{ +public: + CUDPClientConnectionHandler(CHost serverHost) + : _serverHost(serverHost) {} + + void Open(const CHost &host) override; + int HasDataToRead(int timeout) override { return _connectionHandler.HasDataToRead(timeout); } + void SendToServer(const unsigned char *buf, unsigned int len) override; + int Recv(unsigned char *buf, int len, CHost *hostFrom) override; + bool IsValid() override { return _connectionHandler.IsValid(); } + void Close() override { _connectionHandler.Close(); } + +private: + CHost _serverHost; + CUDPConnectionHandler _connectionHandler; +}; + +#endif // !__NET_CONNECTION_HANDLER_H__ \ No newline at end of file diff --git a/src/include/netconnect.h b/src/include/netconnect.h index 8bfb4b28df..53c59d7b70 100644 --- a/src/include/netconnect.h +++ b/src/include/netconnect.h @@ -36,7 +36,7 @@ ----------------------------------------------------------------------------*/ #include "net_message.h" -#include "network/netsockets.h" +#include "net_connection_handler.h" class CHost; @@ -148,20 +148,20 @@ class CServer public: void Init(const std::string &name, CServerSetup *serverSetup); - void Open(const CHost &host); + void Open(const CHost &host, bool udp); - bool IsValid(); + bool IsValid() const; - int HasDataToRead(int timeout); + int HasDataToRead(int timeout) const; - void SendToAllClients(const unsigned char *buf, unsigned int len); + void SendToAllClients(CNetworkHost hosts[], int hostCount, const unsigned char *buf, unsigned int len); template void SendMessageToSpecificClient(const CHost &host, const T &msg); void SendMessageToSpecificClient(const CHost &host, const CInitMessage_Header &msg); - int Recv(unsigned char *buf, int len, CHost *hostFrom); + int Recv(unsigned char *buf, int len, CHost *hostFrom) const; void Close(); @@ -191,11 +191,9 @@ class CServer private: std::string name; NetworkState networkStates[PlayerMax]; /// Client Host states -#if UDP - CUDPSocket *socket = nullptr; -#else - CTCPSocket *socket = nullptr; -#endif + + IServerConnectionHandler* _serverConnectionHandler = nullptr; + CServerSetup *serverSetup; }; @@ -205,9 +203,9 @@ class CClient void Init(const std::string &name, CServerSetup *serverSetup, CServerSetup *localSetup, unsigned long tick); void SetServerHost(const CHost &host) { serverHost = host; } - void Open(); + void Open(bool udp); - bool IsValid(); + bool IsValid() const; int HasDataToRead(int timeout); @@ -271,12 +269,14 @@ class CClient CHost serverHost; /// IP:port of server to join NetworkState networkState; unsigned char lastMsgTypeSent; /// Subtype of last InitConfig message sent - -#if UDP - CUDPSocket *socket = nullptr; -#else - CTCPSocket *socket = nullptr; -#endif + + IClientConnectionHandler* _clientConnectionHandler = nullptr; + +//#if UDP +// CUDPSocket *socket = nullptr; +//#else +// CTCPSocket *socket = nullptr; +//#endif CServerSetup *serverSetup; CServerSetup *localSetup; diff --git a/src/include/network/netsockets.h b/src/include/network/netsockets.h index de7e5b499d..46424a5bcc 100644 --- a/src/include/network/netsockets.h +++ b/src/include/network/netsockets.h @@ -104,7 +104,6 @@ class CTCPSocket { public: CTCPSocket(); - ~CTCPSocket(); bool Open(const CHost &host); int Listen(); CTCPSocket* Accept(); @@ -119,8 +118,8 @@ class CTCPSocket bool IsValid() const; CHost GetHost() const; private: - CTCPSocket(CTCPSocket_Impl *impl); - CTCPSocket_Impl *m_impl; + CTCPSocket(CTCPSocket_Impl* impl) : m_impl(impl) {}; + CTCPSocket_Impl* m_impl; }; //@} diff --git a/src/include/parameters.h b/src/include/parameters.h index e6c404b780..f02e46b9b0 100644 --- a/src/include/parameters.h +++ b/src/include/parameters.h @@ -48,6 +48,8 @@ class Parameters std::string luaEditorStartFilename; std::string luaScriptArguments; std::string LocalPlayerName; /// Name of local player + bool UseUDP; + private: std::string userDirectory; /// Directory containing user settings and data public: diff --git a/src/network/net_connection_handler.cpp b/src/network/net_connection_handler.cpp new file mode 100644 index 0000000000..3dd3b9703a --- /dev/null +++ b/src/network/net_connection_handler.cpp @@ -0,0 +1,230 @@ +#include "net_connection_handler.h" + +using namespace std; + +bool CTCPConnectionHandler::Open(const CHost& host) { + return _socket.Open(host); +} + +int CTCPConnectionHandler::Listen() { + return _socket.Listen(); +} + +shared_ptr CTCPConnectionHandler::Accept() { + CTCPSocket* newSocket = _socket.Accept(); + + if(newSocket == nullptr) { + return nullptr; + } + + auto newConnectionHandler = make_shared(*newSocket); + delete newSocket; + + return newConnectionHandler; +} + +void CTCPConnectionHandler::Close() { + _socket.Close(); +} + +bool CTCPConnectionHandler::Connect(const CHost& host) { + return _socket.Connect(host); +} + +int CTCPConnectionHandler::Send(const unsigned char* buf, unsigned len) { + const auto bufLength = new unsigned char[2]; + + bufLength[0] = len >> 8 & 0xFF; + bufLength[1] = len & 0xFF; + + _socket.Send(bufLength, 2); + return _socket.Send(buf, len); +} + +int CTCPConnectionHandler::Recv(unsigned char* buf, int len) { + auto* bufLength = new unsigned char[2]; + + const int resLen = _socket.Recv(bufLength, 2); + if (resLen < 2) + { + return resLen; + } + + int actualLen = bufLength[0]; + actualLen <<= 8; + actualLen |= bufLength[1]; + + return _socket.Recv(buf, actualLen); +} + +void CTCPConnectionHandler::SetBlocking() { + _socket.SetBlocking(); +} + +void CTCPConnectionHandler::SetNonBlocking() { + _socket.SetNonBlocking(); +} + +int CTCPConnectionHandler::HasDataToRead(int timeout) { + return _socket.HasDataToRead(timeout); +} + +bool CTCPConnectionHandler::IsValid() const { + return _socket.IsValid(); +} + +CHost CTCPConnectionHandler::GetHost() const { + return _socket.GetHost(); +} + +bool CUDPConnectionHandler::Open(const CHost& host) { + return _socket.Open(host); +} + +void CUDPConnectionHandler::Close() { + _socket.Close(); +} + +void CUDPConnectionHandler::Send(const CHost& host, const unsigned char* buf, unsigned len) { + _socket.Send(host, buf, len); +} + +int CUDPConnectionHandler::Recv(unsigned char* buf, int len, CHost* hostFrom) { + return _socket.Recv(buf, len, hostFrom); +} + +void CUDPConnectionHandler::SetNonBlocking() { + _socket.SetNonBlocking(); +} + +int CUDPConnectionHandler::HasDataToRead(int timeout) { + return _socket.HasDataToRead(timeout); +} + +bool CUDPConnectionHandler::IsValid() const { + return _socket.IsValid(); +} + +void CTCPServerConnectionHandler::Open(const CHost& host) { + _connectionHandler.Open(host); + _connectionHandler.SetNonBlocking(); + _connectionHandler.Listen(); +} + +int CTCPServerConnectionHandler::HasDataToRead(int timeout) { + const auto newConnectionHandler = _connectionHandler.Accept(); + if (newConnectionHandler) + { + newConnectionHandler->SetBlocking(); + // TODO make sure new connection does not override legitimate host + _clientConnections[newConnectionHandler->GetHost()] = newConnectionHandler; + } + + for (auto& it : _clientConnections) { + const int read = it.second->HasDataToRead(timeout); + if (read > 0) + { + return read; + } + } + + return 0; +} + +void CTCPServerConnectionHandler::SendToAllClients(vector hosts, const unsigned char* buf, unsigned len) { + for (auto& host : hosts) { + _clientConnections[host]->Send(buf, len); + } +} + +void CTCPServerConnectionHandler::SendToClient(CHost host, const unsigned char* buf, unsigned len) { + _clientConnections[host]->Send(buf, len); +} + +int CTCPServerConnectionHandler::Recv(unsigned char* buf, int len, CHost* hostFrom) { + // round robin across _clientSockets to avoid chatty client flooding client/server comm + + int skip = _skipClient; + int take = _clientConnections.size(); + + _skipClient = (_skipClient + 1) % _clientConnections.size(); + + for (auto& it : _clientConnections) { + if (skip-- > 0) continue; + take--; + + const int read = it.second->HasDataToRead(0); + if (read > 0) + { + *hostFrom = it.first; + return it.second->Recv(buf, len); + } + } + + for (auto& it : _clientConnections) { + if (take-- == 0) break; + + const int read = it.second->HasDataToRead(0); + if (read > 0) + { + *hostFrom = it.first; + return it.second->Recv(buf, len); + } + } + + return 0; +} + +void CTCPServerConnectionHandler::Close() { + for (auto& it : _clientConnections) { + it.second->Close(); + } + + _clientConnections.clear(); + _connectionHandler.Close(); +} + +void CUDPServerConnectionHandler::Open(const CHost& host) { + _connectionHandler.Open(host); +} + +void CUDPServerConnectionHandler::SendToAllClients(std::vector hosts, const unsigned char* buf, unsigned len) { + for (auto& host : hosts) { + _connectionHandler.Send(host, buf, len); + } +} + +void CUDPServerConnectionHandler::SendToClient(CHost host, const unsigned char* buf, unsigned len) { + _connectionHandler.Send(host, buf, len); +} + +int CUDPServerConnectionHandler::Recv(unsigned char* buf, int len, CHost* hostFrom) { + return _connectionHandler.Recv(buf, len, hostFrom); +} + +void CTCPClientConnectionHandler::Open(const CHost& host) { + _connectionHandler.Open(host); + _connectionHandler.SetBlocking(); + _connectionHandler.Connect(_serverHost); +} + +void CTCPClientConnectionHandler::SendToServer(const unsigned char* buf, unsigned len) { + _connectionHandler.Send(buf, len); +} + +int CTCPClientConnectionHandler::Recv(unsigned char* buf, int len, CHost* hostFrom) { + *hostFrom = _serverHost; + return _connectionHandler.Recv(buf, len); +} + +void CUDPClientConnectionHandler::Open(const CHost& host) { + _connectionHandler.Open(CHost("localhost", 0)); +} + +void CUDPClientConnectionHandler::SendToServer(const unsigned char* buf, unsigned len) { + _connectionHandler.Send(_serverHost, buf, len); +} + +int CUDPClientConnectionHandler::Recv(unsigned char* buf, int len, CHost* hostFrom) { + return _connectionHandler.Recv(buf, len, hostFrom); +} diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 9bc81d92cb..4ecc4f4a6d 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -49,6 +49,8 @@ #include "video.h" #include "net_lowlevel.h" +#include + //---------------------------------------------------------------------------- // Declaration //---------------------------------------------------------------------------- @@ -329,70 +331,84 @@ void CClient::Init(const std::string &name, CServerSetup *serverSetup, CServerSe lastMsgTypeSent = ICMServerQuit; this->serverSetup = serverSetup; this->localSetup = localSetup; - this->name = name; - -#ifdef UDP - socket = new CUDPSocket(); -#else - socket = new CTCPSocket(); -#endif + this->name = name; } -void CClient::Open() { -#ifdef UDP - socket->Open(CHost("localhost", 0)); -#else - socket->Open(CHost("localhost", 0)); - socket->SetBlocking(); - socket->Connect(this->serverHost); -#endif +void CClient::Open(bool udp) { + if(udp) { + _clientConnectionHandler = new CUDPClientConnectionHandler(this->serverHost); + } + else { + _clientConnectionHandler = new CTCPClientConnectionHandler(this->serverHost); + } + + _clientConnectionHandler->Open(CHost("localhost", 0)); + +//xxxxx +// socket->Open(CHost("localhost", 0)); +//#else +// socket->Open(CHost("localhost", 0)); +// socket->SetBlocking(); +// socket->Connect(this->serverHost); +//#endif } -bool CClient::IsValid() { - if (socket == nullptr) { +bool CClient::IsValid() const { + if (_clientConnectionHandler == nullptr) { return false; } -#ifdef UDP - return socket->IsValid(); -#else - return socket->IsValid(); -#endif + return _clientConnectionHandler->IsValid(); + +//xxxxx +// return socket->IsValid(); +//#else +// return socket->IsValid(); +//#endif } int CClient::HasDataToRead(int timeout) { -#ifdef UDP - return socket->HasDataToRead(timeout); -#else - return socket->HasDataToRead(timeout); -#endif + return _clientConnectionHandler->HasDataToRead(timeout); + +//xxxxx +// return socket->HasDataToRead(timeout); +//#else +// return socket->HasDataToRead(timeout); +//#endif } void CClient::SendToServer(const unsigned char *buf, unsigned int len) { -#ifdef UDP - socket->Send(serverHost, buf, len); -#else - socket->Send(buf, len); -#endif + _clientConnectionHandler->SendToServer(buf, len); +//xxxxx +// socket->Send(serverHost, buf, len); +//#else +// socket->Send(buf, len); +//#endif } int CClient::Recv(unsigned char *buf, int len, CHost *hostFrom) { -#ifdef UDP - return socket->Recv(buf, len, hostFrom); -#else - *hostFrom = serverHost; - return socket->Recv(buf, len); -#endif + return _clientConnectionHandler->Recv(buf, len, hostFrom); + +//xxxxx +// return socket->Recv(buf, len, hostFrom); +//#else +// *hostFrom = serverHost; +// return socket->Recv(buf, len); +//#endif } void CClient::Close() { -#ifdef UDP - socket->Close(); - socket = nullptr; -#else - socket->Close(); - socket = nullptr; -#endif + _clientConnectionHandler->Close(); + delete _clientConnectionHandler; + _clientConnectionHandler = nullptr; + +//xxxxx +// socket->Close(); +// socket = nullptr; +//#else +// socket->Close(); +// socket = nullptr; +//#endif } void CClient::DetachFromServer() @@ -994,76 +1010,97 @@ void CServer::Init(const std::string &name, CServerSetup *serverSetup) this->serverSetup = serverSetup; this->name = name; -#ifdef UDP - this->socket = new CUDPSocket(); -#else - this->socket = new CTCPSocket(); -#endif +//xxxxx +// this->socket = new CUDPSocket(); +//#else +// this->socket = new CTCPSocket(); +//#endif } -void CServer::Open(const CHost &host) { -#ifdef UDP - socket->Open(host); -#else - socket->Open(host); - socket->SetNonBlocking(); - socket->Listen(); -#endif +void CServer::Open(const CHost &host, bool udp) { + if (udp) { + _serverConnectionHandler = new CUDPServerConnectionHandler(); + } + else { + _serverConnectionHandler = new CTCPServerConnectionHandler(); + } + + _serverConnectionHandler->Open(host); + +//xxxxx +// socket->Open(host); +//#else +// socket->Open(host); +// socket->SetNonBlocking(); +// socket->Listen(); +//#endif } -bool CServer::IsValid() { - if (socket == nullptr) { +bool CServer::IsValid() const { + if (_serverConnectionHandler == nullptr) { return false; } -#ifdef UDP - return socket->IsValid(); -#else - return socket->IsValid(); -#endif + return _serverConnectionHandler->IsValid(); + +//xxxxx +// return socket->IsValid(); +//#else +// return socket->IsValid(); +//#endif } #ifndef UDP std::map clientSockets; #endif -int CServer::HasDataToRead(int timeout) { -#ifdef UDP - return socket->HasDataToRead(timeout); -#else - const auto newClientSocket = socket->Accept(); - if (newClientSocket) - { - newClientSocket->SetBlocking(); - clientSockets[newClientSocket->GetHost()] = newClientSocket; - } - - for (auto& it : clientSockets) - { - const int read = it.second->HasDataToRead(timeout); - if (read > 0) - { - return read; - } - } - - return 0; -#endif +int CServer::HasDataToRead(int timeout) const { + return _serverConnectionHandler->HasDataToRead(timeout); + +//xxxxx +// return socket->HasDataToRead(timeout); +//#else +// const auto newClientSocket = socket->Accept(); +// if (newClientSocket) +// { +// newClientSocket->SetBlocking(); +// clientSockets[newClientSocket->GetHost()] = newClientSocket; +// } +// +// for (auto& it : clientSockets) +// { +// const int read = it.second->HasDataToRead(timeout); +// if (read > 0) +// { +// return read; +// } +// } +// +// return 0; +//#endif } -void CServer::SendToAllClients(const unsigned char *buf, unsigned int len) { -#ifdef UDP - for (int i = 0; i < HostsCount; ++i) { - const CHost host(Hosts[i].Host, Hosts[i].Port); - socket->Send(host, buf, len); - } -#else +void CServer::SendToAllClients(CNetworkHost hosts[], int hostCount, const unsigned char *buf, unsigned int len) { + std::vector hostVector; + for (int i = 0; i < HostsCount; ++i) { const CHost host(Hosts[i].Host, Hosts[i].Port); - //TODO CHECK IF FAILED - clientSockets[host]->Send(buf, len); - } -#endif + hostVector.emplace_back(host); + } + _serverConnectionHandler->SendToAllClients(hostVector, buf, len); + +//xxxxx +// for (int i = 0; i < HostsCount; ++i) { +// const CHost host(Hosts[i].Host, Hosts[i].Port); +// socket->Send(host, buf, len); +// } +//#else +// for (int i = 0; i < HostsCount; ++i) { +// const CHost host(Hosts[i].Host, Hosts[i].Port); +// //TODO CHECK IF FAILED +// clientSockets[host]->Send(buf, len); +// } +//#endif } @@ -1078,83 +1115,92 @@ void CServer::SendToAllClients(const unsigned char *buf, unsigned int len) { template void CServer::SendMessageToSpecificClient(const CHost &host, const T &msg) { const unsigned char *buf = msg.Serialize(); + _serverConnectionHandler->SendToClient(host, buf, msg.Size()); -#ifdef UDP - socket->Send(host, buf, msg.Size()); -#else - clientSockets[host]->Send(buf, msg.Size()); -#endif +//xxxxx +// socket->Send(host, buf, msg.Size()); +//#else +// clientSockets[host]->Send(buf, msg.Size()); +//#endif delete[] buf; } void CServer::SendMessageToSpecificClient(const CHost &host, const CInitMessage_Header &msg) { - unsigned char *buf = new unsigned char [msg.Size()]; + auto buf = new unsigned char [msg.Size()]; msg.Serialize(buf); -#ifdef UDP - socket->Send(host, buf, msg.Size()); -#else - auto clientSocket = clientSockets[host]; - clientSocket->Send(buf, msg.Size()); -#endif + _serverConnectionHandler->SendToClient(host, buf, msg.Size()); + +//xxxxx +// socket->Send(host, buf, msg.Size()); +//#else +// auto clientSocket = clientSockets[host]; +// clientSocket->Send(buf, msg.Size()); +//#endif delete[] buf; } -#ifndef UDP -int skipClient = 0; -#endif - -int CServer::Recv(unsigned char *buf, int len, CHost *hostFrom) { -#ifdef UDP - return socket->Recv(buf, len, hostFrom); -#else - int skip = skipClient; - int take = clientSockets.size(); - - skipClient = (skipClient + 1) % clientSockets.size(); - - for (auto& it : clientSockets) { - if (skip-- > 0) continue; - take--; - - const int read = it.second->HasDataToRead(0); - if (read > 0) { - *hostFrom = it.first; - return it.second->Recv(buf, len); - } - } - - for (auto& it : clientSockets) { - if (take-- == 0) break; +//#ifndef UDP +//int skipClient = 0; +//#endif - const int read = it.second->HasDataToRead(0); - if (read > 0) { - *hostFrom = it.first; - return it.second->Recv(buf, len); - } - } +int CServer::Recv(unsigned char *buf, int len, CHost *hostFrom) const { + return _serverConnectionHandler->Recv(buf, len, hostFrom); - return 0; -#endif +//xxxxx +// return socket->Recv(buf, len, hostFrom); +//#else +// int skip = skipClient; +// int take = clientSockets.size(); +// +// skipClient = (skipClient + 1) % clientSockets.size(); +// +// for (auto& it : clientSockets) { +// if (skip-- > 0) continue; +// take--; +// +// const int read = it.second->HasDataToRead(0); +// if (read > 0) { +// *hostFrom = it.first; +// return it.second->Recv(buf, len); +// } +// } +// +// for (auto& it : clientSockets) { +// if (take-- == 0) break; +// +// const int read = it.second->HasDataToRead(0); +// if (read > 0) { +// *hostFrom = it.first; +// return it.second->Recv(buf, len); +// } +// } +// +// return 0; +//#endif } void CServer::Close() { -#ifdef UDP - socket->Close(); -#else - for (auto& it : clientSockets) - { - it.second->Close(); - } + _serverConnectionHandler->Close(); + _serverConnectionHandler = nullptr; - clientSockets.clear(); - socket->Close(); -#endif - socket = nullptr; +//xxxxx +// socket->Close(); +//#else +// for (auto& it : clientSockets) +// { +// it.second->Close(); +// } +// +// clientSockets.clear(); +// socket->Close(); +//#endif +// +// socket = nullptr; } void CServer::Send_AreYouThere(const CNetworkHost &host) @@ -1728,7 +1774,7 @@ void NetworkInitClientConnect() LocalSetupState.Clear(); Client.Init(Parameters::Instance.LocalPlayerName, &ServerSetupState, &LocalSetupState, GetTicks()); - Client.Open(); + Client.Open(Parameters::Instance.UseUDP); if (Client.IsValid() == false) { fprintf(stderr, "Unable to open socket for client\n"); NetExit(); // machine dependent network exit @@ -2049,7 +2095,7 @@ void NetworkInitServerConnect(int openslots) const int port = CNetworkParameter::Instance.localPort; const char *NetworkAddr = NULL; // FIXME : bad use const CHost host(NetworkAddr, port); - Server.Open(host); + Server.Open(host, Parameters::Instance.UseUDP); if (Server.IsValid() == false) { fprintf(stderr, "NETWORK: No free port %d available, aborting\n", port); diff --git a/src/network/netsockets.cpp b/src/network/netsockets.cpp index 3aac2c111c..34fb0b1e78 100644 --- a/src/network/netsockets.cpp +++ b/src/network/netsockets.cpp @@ -241,23 +241,16 @@ CTCPSocket_Impl* CTCPSocket_Impl::Accept() // CTCPSocket // -CTCPSocket::CTCPSocket() +CTCPSocket::CTCPSocket() : m_impl(nullptr) { - m_impl = new CTCPSocket_Impl(); -} - -CTCPSocket::CTCPSocket(CTCPSocket_Impl *impl) -{ - m_impl = impl; -} - -CTCPSocket::~CTCPSocket() -{ - delete m_impl; } bool CTCPSocket::Open(const CHost &host) { + if(!m_impl) { + m_impl = new CTCPSocket_Impl(); + } + return m_impl->Open(host); } @@ -269,9 +262,10 @@ int CTCPSocket::Listen() void CTCPSocket::Close() { m_impl->Close(); + delete m_impl; + m_impl = nullptr; } - bool CTCPSocket::Connect(const CHost &host) { return m_impl->Connect(host); @@ -290,31 +284,12 @@ CTCPSocket* CTCPSocket::Accept() int CTCPSocket::Send(const unsigned char *buf, unsigned int len) { - unsigned char *bufLength = new unsigned char[2]; - - bufLength[0] = len >> 8 & 0xFF; - bufLength[1] = len & 0xFF; - - m_impl->Send(bufLength, 2); return m_impl->Send(buf, len); } int CTCPSocket::Recv(unsigned char *buf, int len) { - int actualLen; - unsigned char *bufLength = new unsigned char[2]; - - const int resLen = m_impl->Recv(bufLength, 2); - if(resLen < 2) - { - return resLen; - } - - actualLen = bufLength[0]; - actualLen <<= 8; - actualLen |= bufLength[1]; - - return m_impl->Recv(buf, actualLen); + return m_impl->Recv(buf, len); } void CTCPSocket::SetBlocking() diff --git a/src/network/network.cpp b/src/network/network.cpp index 83d75cfe76..3b531e2ef3 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -358,7 +358,7 @@ static void NetworkBroadcast(const CNetworkPacket &packet, int numcommands, int // Send to all clients. if (NetConnectType == 1) { // server - Server.SendToAllClients(buf, size); + Server.SendToAllClients(Hosts, HostsCount, buf, size); /*for (int i = 0; i < HostsCount; ++i) { const CHost host(Hosts[i].Host, Hosts[i].Port); if (Hosts[i].PlyNr == player) { diff --git a/src/stratagus/parameters.cpp b/src/stratagus/parameters.cpp index a705ba21db..a4f49f104b 100644 --- a/src/stratagus/parameters.cpp +++ b/src/stratagus/parameters.cpp @@ -44,6 +44,7 @@ void Parameters::SetDefaultValues() luaStartFilename = "scripts/stratagus.lua"; luaEditorStartFilename = "scripts/editor.lua"; SetDefaultUserDirectory(); + UseUDP = false; } void Parameters::SetDefaultUserDirectory() diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp index 1e083baaaa..bd755e1026 100644 --- a/src/video/sdl.cpp +++ b/src/video/sdl.cpp @@ -986,7 +986,8 @@ void WaitEventsOneFrame() // Network bool networkHasDataToRead = false; if (IsNetworkGame()) { - if (networkHasDataToRead = NetworkHasDataToRead()) { + networkHasDataToRead = NetworkHasDataToRead(); + if (networkHasDataToRead) { GetCallbacks()->NetworkEvent(); } } From a9273116349b64479e079a74be6ba84a97ba1922 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Sun, 24 Jun 2018 22:38:30 -0700 Subject: [PATCH 18/32] Fix include --- src/include/net_connection_handler.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/include/net_connection_handler.h b/src/include/net_connection_handler.h index 1ede373e16..b48186fa49 100644 --- a/src/include/net_connection_handler.h +++ b/src/include/net_connection_handler.h @@ -2,6 +2,8 @@ #define __NET_CONNECTION_HANDLER_H__ #include "network/netsockets.h" + +#include #include #include From 6df579f633f6f5f8b2cfed5832c9aee818e6f7c2 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Sun, 24 Jun 2018 22:49:22 -0700 Subject: [PATCH 19/32] Explicitly define all destructors --- src/include/net_connection_handler.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/include/net_connection_handler.h b/src/include/net_connection_handler.h index b48186fa49..96c5ca7da5 100644 --- a/src/include/net_connection_handler.h +++ b/src/include/net_connection_handler.h @@ -21,6 +21,7 @@ class IConnectionHandler class IServerConnectionHandler : public IConnectionHandler { public: + virtual ~IServerConnectionHandler() = default; virtual void SendToAllClients(std::vector hosts, const unsigned char *buf, unsigned int len) = 0; virtual void SendToClient(CHost host, const unsigned char *buf, unsigned int len) = 0; }; @@ -28,6 +29,7 @@ class IServerConnectionHandler : public IConnectionHandler class IClientConnectionHandler : public IConnectionHandler { public: + virtual ~IClientConnectionHandler() = default; virtual void SendToServer(const unsigned char *buf, unsigned int len) = 0; }; @@ -73,6 +75,7 @@ class CUDPConnectionHandler class CTCPServerConnectionHandler : public IServerConnectionHandler { public: + virtual ~CTCPServerConnectionHandler() = default; void Open(const CHost& host) override; bool IsValid() override { return _connectionHandler.IsValid(); } int HasDataToRead(int timeout) override; @@ -90,6 +93,7 @@ class CTCPServerConnectionHandler : public IServerConnectionHandler class CUDPServerConnectionHandler : public IServerConnectionHandler { public: + virtual ~CUDPServerConnectionHandler() = default; void Open(const CHost& host) override; int HasDataToRead(int timeout) override { return _connectionHandler.HasDataToRead(timeout); } void SendToAllClients(std::vector hosts, const unsigned char* buf, unsigned int len) override; @@ -108,6 +112,7 @@ class CTCPClientConnectionHandler : public IClientConnectionHandler CTCPClientConnectionHandler(CHost serverHost) : _serverHost(serverHost) {} + virtual ~CTCPClientConnectionHandler() = default; void Open(const CHost &host) override; int HasDataToRead(int timeout) override { return _connectionHandler.HasDataToRead(timeout); } void SendToServer(const unsigned char *buf, unsigned int len) override; @@ -126,6 +131,7 @@ class CUDPClientConnectionHandler : public IClientConnectionHandler CUDPClientConnectionHandler(CHost serverHost) : _serverHost(serverHost) {} + virtual ~CUDPClientConnectionHandler() = default; void Open(const CHost &host) override; int HasDataToRead(int timeout) override { return _connectionHandler.HasDataToRead(timeout); } void SendToServer(const unsigned char *buf, unsigned int len) override; From cdb5ce6d720ed16e27640ecd0e4ed35915d25295 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Sun, 24 Jun 2018 23:27:22 -0700 Subject: [PATCH 20/32] Fix signatures --- src/network/net_connection_handler.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/network/net_connection_handler.cpp b/src/network/net_connection_handler.cpp index 3dd3b9703a..91130a77f2 100644 --- a/src/network/net_connection_handler.cpp +++ b/src/network/net_connection_handler.cpp @@ -31,7 +31,7 @@ bool CTCPConnectionHandler::Connect(const CHost& host) { return _socket.Connect(host); } -int CTCPConnectionHandler::Send(const unsigned char* buf, unsigned len) { +int CTCPConnectionHandler::Send(const unsigned char* buf, unsigned int len) { const auto bufLength = new unsigned char[2]; bufLength[0] = len >> 8 & 0xFF; @@ -85,7 +85,7 @@ void CUDPConnectionHandler::Close() { _socket.Close(); } -void CUDPConnectionHandler::Send(const CHost& host, const unsigned char* buf, unsigned len) { +void CUDPConnectionHandler::Send(const CHost& host, const unsigned char* buf, unsigned int len) { _socket.Send(host, buf, len); } @@ -131,13 +131,13 @@ int CTCPServerConnectionHandler::HasDataToRead(int timeout) { return 0; } -void CTCPServerConnectionHandler::SendToAllClients(vector hosts, const unsigned char* buf, unsigned len) { +void CTCPServerConnectionHandler::SendToAllClients(vector hosts, const unsigned char* buf, unsigned int len) { for (auto& host : hosts) { _clientConnections[host]->Send(buf, len); } } -void CTCPServerConnectionHandler::SendToClient(CHost host, const unsigned char* buf, unsigned len) { +void CTCPServerConnectionHandler::SendToClient(CHost host, const unsigned char* buf, unsigned int len) { _clientConnections[host]->Send(buf, len); } @@ -188,13 +188,13 @@ void CUDPServerConnectionHandler::Open(const CHost& host) { _connectionHandler.Open(host); } -void CUDPServerConnectionHandler::SendToAllClients(std::vector hosts, const unsigned char* buf, unsigned len) { +void CUDPServerConnectionHandler::SendToAllClients(std::vector hosts, const unsigned char* buf, unsigned int len) { for (auto& host : hosts) { _connectionHandler.Send(host, buf, len); } } -void CUDPServerConnectionHandler::SendToClient(CHost host, const unsigned char* buf, unsigned len) { +void CUDPServerConnectionHandler::SendToClient(CHost host, const unsigned char* buf, unsigned int len) { _connectionHandler.Send(host, buf, len); } @@ -208,7 +208,7 @@ void CTCPClientConnectionHandler::Open(const CHost& host) { _connectionHandler.Connect(_serverHost); } -void CTCPClientConnectionHandler::SendToServer(const unsigned char* buf, unsigned len) { +void CTCPClientConnectionHandler::SendToServer(const unsigned char* buf, unsigned int len) { _connectionHandler.Send(buf, len); } @@ -221,7 +221,7 @@ void CUDPClientConnectionHandler::Open(const CHost& host) { _connectionHandler.Open(CHost("localhost", 0)); } -void CUDPClientConnectionHandler::SendToServer(const unsigned char* buf, unsigned len) { +void CUDPClientConnectionHandler::SendToServer(const unsigned char* buf, unsigned int len) { _connectionHandler.Send(_serverHost, buf, len); } From bb943745e47a3b1e1e045f4b54a2a78d09711616 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Sun, 24 Jun 2018 23:32:37 -0700 Subject: [PATCH 21/32] Update CMakeLists.txt --- CMakeLists.txt | 2 ++ src/stratagus/util.cpp | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97eee7bc2c..59ec399bc5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -224,6 +224,7 @@ set(network_SRCS src/network/net_lowlevel.cpp src/network/net_message.cpp src/network/master.cpp + src/network/net_connection_handler.cpp src/network/netconnect.cpp src/network/network.cpp src/network/netsockets.cpp @@ -539,6 +540,7 @@ set(stratagus_generic_HDRS src/include/net_message.h src/include/netconnect.h src/include/network.h + src/include/net_connection_handler.h src/include/network/netsockets.h src/include/parameters.h src/include/particle.h diff --git a/src/stratagus/util.cpp b/src/stratagus/util.cpp index 72da69069f..cb7869f1f2 100644 --- a/src/stratagus/util.cpp +++ b/src/stratagus/util.cpp @@ -398,7 +398,7 @@ int GetClipboard(std::string &str) #endif #ifdef USE_WIN32 - if (!IsClipboardFormatAvailable(CF_TEXT) || !OpenClipboard(NULL)) { + /*if (!IsClipboardFormatAvailable(CF_TEXT) || !OpenClipboard(NULL)) { return -1; } handle = GetClipboardData(CF_TEXT); @@ -410,7 +410,7 @@ int GetClipboard(std::string &str) if (!clipboard) { CloseClipboard(); return -1; - } + }*/ #elif defined(USE_X11) if (!(display = XOpenDisplay(NULL))) { return -1; @@ -450,15 +450,15 @@ int GetClipboard(std::string &str) } #endif // Only allow ascii characters - for (i = 0; clipboard[i] != '\0'; ++i) { + /*for (i = 0; clipboard[i] != '\0'; ++i) { if (clipboard[i] < 32 || clipboard[i] > 126) { return -1; } - } - str = (char *)clipboard; + }*/ + str = '\0'; #ifdef USE_WIN32 - GlobalUnlock(handle); - CloseClipboard(); + //GlobalUnlock(handle); + //CloseClipboard(); #elif defined(USE_X11) if (clipboard != NULL) { XFree(clipboard); From 58405d6e935299666dbea6be6a705ee2a0f1a2ca Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Sun, 24 Jun 2018 23:34:02 -0700 Subject: [PATCH 22/32] Revert util.cpp --- src/stratagus/util.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/stratagus/util.cpp b/src/stratagus/util.cpp index cb7869f1f2..72da69069f 100644 --- a/src/stratagus/util.cpp +++ b/src/stratagus/util.cpp @@ -398,7 +398,7 @@ int GetClipboard(std::string &str) #endif #ifdef USE_WIN32 - /*if (!IsClipboardFormatAvailable(CF_TEXT) || !OpenClipboard(NULL)) { + if (!IsClipboardFormatAvailable(CF_TEXT) || !OpenClipboard(NULL)) { return -1; } handle = GetClipboardData(CF_TEXT); @@ -410,7 +410,7 @@ int GetClipboard(std::string &str) if (!clipboard) { CloseClipboard(); return -1; - }*/ + } #elif defined(USE_X11) if (!(display = XOpenDisplay(NULL))) { return -1; @@ -450,15 +450,15 @@ int GetClipboard(std::string &str) } #endif // Only allow ascii characters - /*for (i = 0; clipboard[i] != '\0'; ++i) { + for (i = 0; clipboard[i] != '\0'; ++i) { if (clipboard[i] < 32 || clipboard[i] > 126) { return -1; } - }*/ - str = '\0'; + } + str = (char *)clipboard; #ifdef USE_WIN32 - //GlobalUnlock(handle); - //CloseClipboard(); + GlobalUnlock(handle); + CloseClipboard(); #elif defined(USE_X11) if (clipboard != NULL) { XFree(clipboard); From 576db54200014538af955005bca0b1cf98d9c182 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Mon, 25 Jun 2018 13:10:33 -0700 Subject: [PATCH 23/32] Handle client disconnect gracefully --- src/include/network.h | 1 + src/network/network.cpp | 2 ++ src/video/sdl.cpp | 3 +-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/include/network.h b/src/include/network.h index e73a64cfe0..bf2265e135 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -69,6 +69,7 @@ class CNetworkParameter //extern CUDPSocket NetworkFildes; /// Network file descriptor extern bool NetworkInSync; /// Network is in sync extern bool NetworkGame; +extern bool ClientDisconnected; /*---------------------------------------------------------------------------- -- Functions diff --git a/src/network/network.cpp b/src/network/network.cpp index 3b531e2ef3..593c02a777 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -292,6 +292,7 @@ void CNetworkParameter::FixValues() bool NetworkInSync = true; /// Network is in sync bool NetworkGame = false; +bool ClientDisconnected = false; //CUDPSocket NetworkFildes; /// Network file descriptor @@ -851,6 +852,7 @@ void NetworkEvent() len = Server.Recv(buf, sizeof(buf), &host); } else { // client len = Client.Recv(buf, sizeof(buf), &host); + ClientDisconnected = len < 0; } if (len == 0) diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp index bd755e1026..95a731506a 100644 --- a/src/video/sdl.cpp +++ b/src/video/sdl.cpp @@ -579,10 +579,8 @@ void InitVideoSdl() } if (hicon) { -#ifndef NO_ICON SendMessage(hwnd, (UINT)WM_SETICON, ICON_SMALL, (LPARAM)hicon); SendMessage(hwnd, (UINT)WM_SETICON, ICON_BIG, (LPARAM)hicon); -#endif } #endif } @@ -989,6 +987,7 @@ void WaitEventsOneFrame() networkHasDataToRead = NetworkHasDataToRead(); if (networkHasDataToRead) { GetCallbacks()->NetworkEvent(); + if (ClientDisconnected) break; } } // No more input and time for frame over: return From a36a7f77e0578ede5a7e035d2334a03f29eca793 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Mon, 25 Jun 2018 13:18:59 -0700 Subject: [PATCH 24/32] Add headers --- src/include/net_connection_handler.h | 29 ++++++++++++++++++++++++++ src/network/net_connection_handler.cpp | 29 ++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/include/net_connection_handler.h b/src/include/net_connection_handler.h index 96c5ca7da5..72accad453 100644 --- a/src/include/net_connection_handler.h +++ b/src/include/net_connection_handler.h @@ -1,3 +1,32 @@ +// _________ __ __ +// / _____// |_____________ _/ |______ ____ __ __ ______ +// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/ +// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ | +// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ > +// \/ \/ \//_____/ \/ +// ______________________ ______________________ +// T H E W A R B E G I N S +// Stratagus - A free fantasy real time strategy game engine +// +/**@name master.cpp - The master server. */ +// +// (c) Copyright 2003-2007 by Tom Zickel and Jimmy Salmon +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; only version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// + #ifndef __NET_CONNECTION_HANDLER_H__ #define __NET_CONNECTION_HANDLER_H__ diff --git a/src/network/net_connection_handler.cpp b/src/network/net_connection_handler.cpp index 91130a77f2..847e5ba320 100644 --- a/src/network/net_connection_handler.cpp +++ b/src/network/net_connection_handler.cpp @@ -1,3 +1,32 @@ +// _________ __ __ +// / _____// |_____________ _/ |______ ____ __ __ ______ +// \_____ \\ __\_ __ \__ \\ __\__ \ / ___\| | \/ ___/ +// / \| | | | \// __ \| | / __ \_/ /_/ > | /\___ | +// /_______ /|__| |__| (____ /__| (____ /\___ /|____//____ > +// \/ \/ \//_____/ \/ +// ______________________ ______________________ +// T H E W A R B E G I N S +// Stratagus - A free fantasy real time strategy game engine +// +/**@name master.cpp - The master server. */ +// +// (c) Copyright 2003-2007 by Tom Zickel and Jimmy Salmon +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; only version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +// 02111-1307, USA. +// + #include "net_connection_handler.h" using namespace std; From 695ef28a652a559bb3e4a99d92808694d605927e Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Tue, 26 Jun 2018 03:18:38 -0700 Subject: [PATCH 25/32] Code cleanup --- src/include/netconnect.h | 6 - src/network/netconnect.cpp | 359 +------------------------------------ src/network/network.cpp | 1 - 3 files changed, 1 insertion(+), 365 deletions(-) diff --git a/src/include/netconnect.h b/src/include/netconnect.h index 53c59d7b70..9d0911cea1 100644 --- a/src/include/netconnect.h +++ b/src/include/netconnect.h @@ -272,12 +272,6 @@ class CClient IClientConnectionHandler* _clientConnectionHandler = nullptr; -//#if UDP -// CUDPSocket *socket = nullptr; -//#else -// CTCPSocket *socket = nullptr; -//#endif - CServerSetup *serverSetup; CServerSetup *localSetup; }; diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 4ecc4f4a6d..6e10c4985a 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -81,127 +81,10 @@ CClient Client; CServerSetup ServerSetupState; // Server selection state for Multiplayer clients CServerSetup LocalSetupState; // Local selection state for Multiplayer clients -/*class CServer -{ -public: - void Init(const std::string &name, CUDPSocket *socket, CServerSetup *serverSetup); - - void Update(unsigned long frameCounter); - void Parse(unsigned long frameCounter, const unsigned char *buf, const CHost &host); - - void MarkClientsAsResync(); - void KickClient(int c); -private: - int Parse_Hello(int h, const CInitMessage_Hello &msg, const CHost &host); - void Parse_Resync(const int h); - void Parse_Waiting(const int h); - void Parse_Map(const int h); - void Parse_State(const int h, const CInitMessage_State &msg); - void Parse_GoodBye(const int h); - void Parse_SeeYou(const int h); - - void Send_AreYouThere(const CNetworkHost &host); - void Send_GameFull(const CHost &host); - void Send_Welcome(const CNetworkHost &host, int hostIndex); - void Send_Resync(const CNetworkHost &host, int hostIndex); - void Send_Map(const CNetworkHost &host); - void Send_State(const CNetworkHost &host); - void Send_GoodBye(const CNetworkHost &host); -private: - std::string name; - NetworkState networkStates[PlayerMax]; /// Client Host states - CUDPSocket *socket; - CServerSetup *serverSetup; -}; - -class CClient -{ -public: - void Init(const std::string &name, CUDPSocket *socket, CServerSetup *serverSetup, CServerSetup *localSetup, unsigned long tick); - void SetServerHost(const CHost &host) { serverHost = host; } - - bool Parse(const unsigned char *buf, const CHost &host); - bool Update(unsigned long tick); - - void DetachFromServer(); - - int GetNetworkState() const { return networkState.State; } - -private: - bool Update_disconnected(); - bool Update_detaching(unsigned long tick); - bool Update_connecting(unsigned long tick); - bool Update_connected(unsigned long tick); - bool Update_synced(unsigned long tick); - bool Update_changed(unsigned long tick); - bool Update_async(unsigned long tick); - bool Update_mapinfo(unsigned long tick); - bool Update_badmap(unsigned long tick); - bool Update_goahead(unsigned long tick); - bool Update_started(unsigned long tick); - - void Send_Go(unsigned long tick); - void Send_Config(unsigned long tick); - void Send_MapUidMismatch(unsigned long tick); - void Send_Map(unsigned long tick); - void Send_Resync(unsigned long tick); - void Send_State(unsigned long tick); - void Send_Waiting(unsigned long tick, unsigned long msec); - void Send_Hello(unsigned long tick); - void Send_GoodBye(unsigned long tick); - - template - void SendRateLimited(const T &msg, unsigned long tick, unsigned long msecs); - - void SetConfig(const CInitMessage_Config &msg); - - void Parse_GameFull(); - void Parse_LuaMismatch(const unsigned char *buf); - void Parse_EngineMismatch(const unsigned char *buf); - void Parse_Resync(const unsigned char *buf); - void Parse_Config(const unsigned char *buf); - void Parse_State(const unsigned char *buf); - void Parse_Welcome(const unsigned char *buf); - void Parse_Map(const unsigned char *buf); - void Parse_AreYouThere(); - -private: - std::string name; - CHost serverHost; /// IP:port of server to join - NetworkState networkState; - unsigned char lastMsgTypeSent; /// Subtype of last InitConfig message sent - CUDPSocket *socket; - CServerSetup *serverSetup; - CServerSetup *localSetup; -};*/ - // // CClient // -/** -** Send an InitConfig message across the Network -** -** @param host Host to send to (network byte order). -** @param port Port of host to send to (network byte order). -** @param msg The message to send -*/ -//template -//static void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const T &msg) -//{ -// const unsigned char *buf = msg.Serialize(); -// socket.Send(host, buf, msg.Size()); -// delete[] buf; -//} -// -//void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const CInitMessage_Header &msg) -//{ -// unsigned char *buf = new unsigned char [msg.Size()]; -// msg.Serialize(buf); -// socket.Send(host, buf, msg.Size()); -// delete[] buf; -//} - static const char *ncconstatenames[] = { "ccs_unused", "ccs_connecting", // new client @@ -249,29 +132,6 @@ static const char *icmsgsubtypenames[] = { "IAmHere", // Client answers I am here }; -//template -//static void NetworkSendICMessage_Log(CUDPSocket &socket, const CHost &host, const T &msg) -//{ -// NetworkSendICMessage(socket, host, msg); -// -//#ifdef DEBUG -// const std::string hostStr = host.toString(); -// DebugPrint("Sending to %s -> %s\n" _C_ hostStr.c_str() -// _C_ icmsgsubtypenames[msg.GetHeader().GetSubType()]); -//#endif -//} -// -//static void NetworkSendICMessage_Log(CUDPSocket &socket, const CHost &host, const CInitMessage_Header &msg) -//{ -// NetworkSendICMessage(socket, host, msg); -// -//#ifdef DEBUG -// const std::string hostStr = host.toString(); -// DebugPrint("Sending to %s -> %s\n" _C_ hostStr.c_str() -// _C_ icmsgsubtypenames[msg.GetSubType()]); -//#endif -//} - /** ** Send a message to the server, but only if the last packet was a while ago ** @@ -295,7 +155,6 @@ void CClient::SendRateLimited(const T &msg, unsigned long tick, unsigned long ms lastMsgTypeSent = subtype; } SendToServer(msg); - //NetworkSendICMessage(*socket, serverHost, msg); DebugPrint("[%s] Sending (%s:#%d)\n" _C_ ncconstatenames[networkState.State] _C_ icmsgsubtypenames[subtype] _C_ networkState.MsgCnt); @@ -317,7 +176,6 @@ void CClient::SendRateLimited(const CInitMessage_Header &ms lastMsgTypeSent = subtype; } SendToServer(msg); - //NetworkSendICMessage(*socket, serverHost, msg); DebugPrint("[%s] Sending (%s:#%d)\n" _C_ ncconstatenames[networkState.State] _C_ icmsgsubtypenames[subtype] _C_ networkState.MsgCnt); @@ -343,14 +201,6 @@ void CClient::Open(bool udp) { } _clientConnectionHandler->Open(CHost("localhost", 0)); - -//xxxxx -// socket->Open(CHost("localhost", 0)); -//#else -// socket->Open(CHost("localhost", 0)); -// socket->SetBlocking(); -// socket->Connect(this->serverHost); -//#endif } bool CClient::IsValid() const { @@ -359,56 +209,24 @@ bool CClient::IsValid() const { } return _clientConnectionHandler->IsValid(); - -//xxxxx -// return socket->IsValid(); -//#else -// return socket->IsValid(); -//#endif } int CClient::HasDataToRead(int timeout) { return _clientConnectionHandler->HasDataToRead(timeout); - -//xxxxx -// return socket->HasDataToRead(timeout); -//#else -// return socket->HasDataToRead(timeout); -//#endif } void CClient::SendToServer(const unsigned char *buf, unsigned int len) { _clientConnectionHandler->SendToServer(buf, len); -//xxxxx -// socket->Send(serverHost, buf, len); -//#else -// socket->Send(buf, len); -//#endif } int CClient::Recv(unsigned char *buf, int len, CHost *hostFrom) { return _clientConnectionHandler->Recv(buf, len, hostFrom); - -//xxxxx -// return socket->Recv(buf, len, hostFrom); -//#else -// *hostFrom = serverHost; -// return socket->Recv(buf, len); -//#endif } void CClient::Close() { _clientConnectionHandler->Close(); delete _clientConnectionHandler; _clientConnectionHandler = nullptr; - -//xxxxx -// socket->Close(); -// socket = nullptr; -//#else -// socket->Close(); -// socket = nullptr; -//#endif } void CClient::DetachFromServer() @@ -425,7 +243,6 @@ bool CClient::Update_disconnected() // Spew out 5 and trust in God that they arrive for (int i = 0; i < 5; ++i) { SendToServer(message); - //NetworkSendICMessage(*socket, serverHost, message); } networkState.State = ccs_usercanceled; return false; @@ -963,7 +780,6 @@ void CClient::Parse_AreYouThere() { const CInitMessage_Header message(MessageInit_FromClient, ICMIAH); // IAmHere SendToServer(message); - //NetworkSendICMessage(*socket, serverHost, message); } template @@ -1009,12 +825,6 @@ void CServer::Init(const std::string &name, CServerSetup *serverSetup) } this->serverSetup = serverSetup; this->name = name; - -//xxxxx -// this->socket = new CUDPSocket(); -//#else -// this->socket = new CTCPSocket(); -//#endif } void CServer::Open(const CHost &host, bool udp) { @@ -1026,14 +836,6 @@ void CServer::Open(const CHost &host, bool udp) { } _serverConnectionHandler->Open(host); - -//xxxxx -// socket->Open(host); -//#else -// socket->Open(host); -// socket->SetNonBlocking(); -// socket->Listen(); -//#endif } bool CServer::IsValid() const { @@ -1042,12 +844,6 @@ bool CServer::IsValid() const { } return _serverConnectionHandler->IsValid(); - -//xxxxx -// return socket->IsValid(); -//#else -// return socket->IsValid(); -//#endif } #ifndef UDP @@ -1056,28 +852,6 @@ bool CServer::IsValid() const { int CServer::HasDataToRead(int timeout) const { return _serverConnectionHandler->HasDataToRead(timeout); - -//xxxxx -// return socket->HasDataToRead(timeout); -//#else -// const auto newClientSocket = socket->Accept(); -// if (newClientSocket) -// { -// newClientSocket->SetBlocking(); -// clientSockets[newClientSocket->GetHost()] = newClientSocket; -// } -// -// for (auto& it : clientSockets) -// { -// const int read = it.second->HasDataToRead(timeout); -// if (read > 0) -// { -// return read; -// } -// } -// -// return 0; -//#endif } void CServer::SendToAllClients(CNetworkHost hosts[], int hostCount, const unsigned char *buf, unsigned int len) { @@ -1088,41 +862,12 @@ void CServer::SendToAllClients(CNetworkHost hosts[], int hostCount, const unsign hostVector.emplace_back(host); } _serverConnectionHandler->SendToAllClients(hostVector, buf, len); - -//xxxxx -// for (int i = 0; i < HostsCount; ++i) { -// const CHost host(Hosts[i].Host, Hosts[i].Port); -// socket->Send(host, buf, len); -// } -//#else -// for (int i = 0; i < HostsCount; ++i) { -// const CHost host(Hosts[i].Host, Hosts[i].Port); -// //TODO CHECK IF FAILED -// clientSockets[host]->Send(buf, len); -// } -//#endif -} - - -//template -//static void NetworkSendICMessage(CUDPSocket &socket, const CHost &host, const T &msg) -//{ -// const unsigned char *buf = msg.Serialize(); -// socket.Send(host, buf, msg.Size()); -// delete[] buf; -//} +} template void CServer::SendMessageToSpecificClient(const CHost &host, const T &msg) { const unsigned char *buf = msg.Serialize(); _serverConnectionHandler->SendToClient(host, buf, msg.Size()); - -//xxxxx -// socket->Send(host, buf, msg.Size()); -//#else -// clientSockets[host]->Send(buf, msg.Size()); -//#endif - delete[] buf; } @@ -1132,89 +877,28 @@ void CServer::SendMessageToSpecificClient(const CHost &host, const CInitMessage_ msg.Serialize(buf); _serverConnectionHandler->SendToClient(host, buf, msg.Size()); - -//xxxxx -// socket->Send(host, buf, msg.Size()); -//#else -// auto clientSocket = clientSockets[host]; -// clientSocket->Send(buf, msg.Size()); -//#endif - delete[] buf; } -//#ifndef UDP -//int skipClient = 0; -//#endif - int CServer::Recv(unsigned char *buf, int len, CHost *hostFrom) const { return _serverConnectionHandler->Recv(buf, len, hostFrom); - -//xxxxx -// return socket->Recv(buf, len, hostFrom); -//#else -// int skip = skipClient; -// int take = clientSockets.size(); -// -// skipClient = (skipClient + 1) % clientSockets.size(); -// -// for (auto& it : clientSockets) { -// if (skip-- > 0) continue; -// take--; -// -// const int read = it.second->HasDataToRead(0); -// if (read > 0) { -// *hostFrom = it.first; -// return it.second->Recv(buf, len); -// } -// } -// -// for (auto& it : clientSockets) { -// if (take-- == 0) break; -// -// const int read = it.second->HasDataToRead(0); -// if (read > 0) { -// *hostFrom = it.first; -// return it.second->Recv(buf, len); -// } -// } -// -// return 0; -//#endif } void CServer::Close() { _serverConnectionHandler->Close(); _serverConnectionHandler = nullptr; - - -//xxxxx -// socket->Close(); -//#else -// for (auto& it : clientSockets) -// { -// it.second->Close(); -// } -// -// clientSockets.clear(); -// socket->Close(); -//#endif -// -// socket = nullptr; } void CServer::Send_AreYouThere(const CNetworkHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMAYT); // AreYouThere SendMessageToSpecificClient(CHost(host.Host, host.Port), message); - //NetworkSendICMessage(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_GameFull(const CHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMGameFull); SendMessageToSpecificClient(host, message); - //NetworkSendICMessage_Log(*socket, host, message); } void CServer::Send_Welcome(const CNetworkHost &host, int index) @@ -1229,7 +913,6 @@ void CServer::Send_Welcome(const CNetworkHost &host, int index) } } SendMessageToSpecificClient(CHost(host.Host, host.Port), message); - //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_Resync(const CNetworkHost &host, int hostIndex) @@ -1242,28 +925,24 @@ void CServer::Send_Resync(const CNetworkHost &host, int hostIndex) } } SendMessageToSpecificClient(CHost(host.Host, host.Port), message); - //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_Map(const CNetworkHost &host) { const CInitMessage_Map message(NetworkMapName.c_str(), Map.Info.MapUID); SendMessageToSpecificClient(CHost(host.Host, host.Port), message); - //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_State(const CNetworkHost &host) { const CInitMessage_State message(MessageInit_FromServer, *serverSetup); SendMessageToSpecificClient(CHost(host.Host, host.Port), message); - //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Send_GoodBye(const CNetworkHost &host) { const CInitMessage_Header message(MessageInit_FromServer, ICMGoodBye); SendMessageToSpecificClient(CHost(host.Host, host.Port), message); - //NetworkSendICMessage_Log(*socket, CHost(host.Host, host.Port), message); } void CServer::Update(unsigned long frameCounter) @@ -1569,9 +1248,6 @@ static int CheckVersions(const CInitMessage_Hello &msg, const CHost &host) fprintf(stderr, "Incompatible Stratagus version %d <-> %d from %s\n", StratagusVersion, msg.Stratagus, hostStr.c_str()); - //const CInitMessage_EngineMismatch message; - //Server.SendToSpecificHost(host, message); - //NetworkSendICMessage_Log(socket, host, message); return -1; } @@ -1582,9 +1258,6 @@ static int CheckVersions(const CInitMessage_Hello &msg, const CHost &host) msg.Version, hostStr.c_str()); - //const CInitMessage_LuaFilesMismatch message; - //Server.SendToSpecificHost(host, message); - //NetworkSendICMessage_Log(socket, host, message); return -2; } return 0; @@ -1599,33 +1272,6 @@ void CServer::Parse(unsigned long frameCounter, const unsigned char *buf, const if (msgsubtype == ICMHello) { CInitMessage_Hello msg; - - //if (msg.Stratagus != StratagusVersion) { - // const std::string hostStr = host.toString(); - // fprintf(stderr, "Incompatible Stratagus version %d <-> %d from %s\n", - // StratagusVersion, msg.Stratagus, hostStr.c_str()); - - // //const CInitMessage_EngineMismatch message; - // //Server.SendToSpecificHost(host, message); - // //NetworkSendICMessage_Log(socket, host, message); - // return -1; - //} - - //if (msg.Version != FileChecksums) { - // const std::string hostStr = host.toString(); - // fprintf(stderr, "Incompatible lua files %d <-> %d\nfrom %s\n", - // FileChecksums, - // msg.Version, - // hostStr.c_str()); - - // //const CInitMessage_LuaFilesMismatch message; - // //Server.SendToSpecificHost(host, message); - // //NetworkSendICMessage_Log(socket, host, message); - // return -2; - //} - //return 0; - - msg.Deserialize(buf); int versionCheck = CheckVersions(msg, host); if (versionCheck == -1) { @@ -1962,10 +1608,8 @@ void NetworkServerStartGame() if (num[Hosts[i].PlyNr] == 1) { // not acknowledged yet message.clientIndex = i; Server.SendMessageToSpecificClient(host, message); - //NetworkSendICMessage_Log(NetworkFildes, host, message); } else if (num[Hosts[i].PlyNr] == 2) { Server.SendMessageToSpecificClient(host, statemsg); - //NetworkSendICMessage_Log(NetworkFildes, host, statemsg); } } @@ -2033,7 +1677,6 @@ void NetworkServerStartGame() for (int i = 0; i < HostsCount; ++i) { const CHost host(Hosts[i].Host, Hosts[i].Port); Server.SendMessageToSpecificClient(host, message_go); - //NetworkSendICMessage_Log(NetworkFildes, host, message_go); } } diff --git a/src/network/network.cpp b/src/network/network.cpp index 3b531e2ef3..02fc1c5bdc 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -858,7 +858,6 @@ void NetworkEvent() return; } - //int len = NetworkFildes.Recv(&buf, sizeof(buf), &host); if (len < 0) { DebugPrint("Server/Client gone?\n"); // just hope for an automatic recover right now.. From 2edc38bc28ab4e7b4707e1884c096281a9a93154 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Tue, 26 Jun 2018 03:36:26 -0700 Subject: [PATCH 26/32] Re-enable master.cpp More cleanup Use -t as TCP enabled switch --- src/include/network.h | 1 - src/network/master.cpp | 142 ++++++++++++++++++------------------ src/network/network.cpp | 24 +----- src/stratagus/stratagus.cpp | 5 +- 4 files changed, 75 insertions(+), 97 deletions(-) diff --git a/src/include/network.h b/src/include/network.h index bf2265e135..a698a10da2 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -66,7 +66,6 @@ class CNetworkParameter -- Variables ----------------------------------------------------------------------------*/ -//extern CUDPSocket NetworkFildes; /// Network file descriptor extern bool NetworkInSync; /// Network is in sync extern bool NetworkGame; extern bool ClientDisconnected; diff --git a/src/network/master.cpp b/src/network/master.cpp index 4ebca366eb..771e81697d 100644 --- a/src/network/master.cpp +++ b/src/network/master.cpp @@ -69,18 +69,18 @@ CMetaClient MetaClient; */ void CMetaClient::SetMetaServer(const std::string host, const int port) { - /*metaHost = host; - metaPort = port;*/ + metaHost = host; + metaPort = port; } CMetaClient::~CMetaClient() { - /*for (std::list::iterator it = events.begin(); it != events.end(); ++it) { + for (std::list::iterator it = events.begin(); it != events.end(); ++it) { CClientLog *log = *it; delete log; } events.clear(); - this->Close();*/ + this->Close(); } /** @@ -90,50 +90,48 @@ CMetaClient::~CMetaClient() */ int CMetaClient::Init() { - return -1; - - //if (metaPort == -1) { - // return -1; - //} + if (metaPort == -1) { + return -1; + } - //// Server socket - //CHost metaServerHost(metaHost.c_str(), metaPort); - //// Client socket + // Server socket + CHost metaServerHost(metaHost.c_str(), metaPort); + // Client socket - //// open on all interfaces, not the loopback, unless we have an override from the commandline - //std::string localHost = CNetworkParameter::Instance.localHost; - //if (!localHost.compare("127.0.0.1")) { - // localHost = "0.0.0.0"; - //} - //CHost metaClientHost(localHost.c_str(), CNetworkParameter::Instance.localPort); - //metaSocket.Open(metaClientHost); - //if (metaSocket.IsValid() == false) { - // fprintf(stderr, "METACLIENT: No free port %d available, aborting\n", metaServerHost.getPort()); - // return -1; - //} - //if (metaSocket.Connect(metaServerHost) == false) { - // fprintf(stderr, "METACLIENT: Unable to connect to host %s\n", metaServerHost.toString().c_str()); - // MetaClient.Close(); - // return -1; - //} + // open on all interfaces, not the loopback, unless we have an override from the commandline + std::string localHost = CNetworkParameter::Instance.localHost; + if (!localHost.compare("127.0.0.1")) { + localHost = "0.0.0.0"; + } + CHost metaClientHost(localHost.c_str(), CNetworkParameter::Instance.localPort); + metaSocket.Open(metaClientHost); + if (metaSocket.IsValid() == false) { + fprintf(stderr, "METACLIENT: No free port %d available, aborting\n", metaServerHost.getPort()); + return -1; + } + if (metaSocket.Connect(metaServerHost) == false) { + fprintf(stderr, "METACLIENT: Unable to connect to host %s\n", metaServerHost.toString().c_str()); + MetaClient.Close(); + return -1; + } - //if (this->Send("PING") == -1) { // not sent - // MetaClient.Close(); - // return -1; - //} - //if (this->Recv() == -1) { // not received - // MetaClient.Close(); - // return -1; - //} - //CClientLog &log = *GetLastMessage(); - //if (log.entry.find("PING_OK") != std::string::npos) { - // // Everything is OK - // return 0; - //} else { - // fprintf(stderr, "METACLIENT: inappropriate message received from %s\n", metaServerHost.toString().c_str()); - // MetaClient.Close(); - // return -1; - //} + if (this->Send("PING") == -1) { // not sent + MetaClient.Close(); + return -1; + } + if (this->Recv() == -1) { // not received + MetaClient.Close(); + return -1; + } + CClientLog &log = *GetLastMessage(); + if (log.entry.find("PING_OK") != std::string::npos) { + // Everything is OK + return 0; + } else { + fprintf(stderr, "METACLIENT: inappropriate message received from %s\n", metaServerHost.toString().c_str()); + MetaClient.Close(); + return -1; + } } /** @@ -143,9 +141,9 @@ int CMetaClient::Init() */ void CMetaClient::Close() { - /*if (metaSocket.IsValid()) { + if (metaSocket.IsValid()) { metaSocket.Close(); - }*/ + } } @@ -158,15 +156,13 @@ void CMetaClient::Close() */ int CMetaClient::Send(const std::string cmd) { - return -1; - - /*int ret = -1; + int ret = -1; if (metaSocket.IsValid()) { std::string mes(cmd); mes.append("\n"); - ret = metaSocket.Send(mes.c_str(), mes.size()); + ret = metaSocket.Send((unsigned char*)mes.c_str(), mes.size()); } - return ret;*/ + return ret; } /** @@ -176,33 +172,33 @@ int CMetaClient::Send(const std::string cmd) */ int CMetaClient::Recv() { - return -1; - - //if (metaSocket.HasDataToRead(5000) == -1) { - // return -1; - //} + if (metaSocket.HasDataToRead(5000) == -1) { + return -1; + } - //char buf[1024]; - //memset(&buf, 0, sizeof(buf)); - //int n = metaSocket.Recv(&buf, sizeof(buf)); - //if (n == -1) { - // return n; - //} - //// We know we now have the whole command. - //// Convert to standard notation - //std::string cmd(buf, strlen(buf)); - //cmd += '\n'; - //cmd += '\0'; - //CClientLog *log = new CClientLog; - //log->entry = cmd; - //events.push_back(log); - //lastRecvState = n; - //return n; + char buf[1024]; + memset(&buf, 0, sizeof(buf)); + int n = metaSocket.Recv((unsigned char*)buf, sizeof(buf)); + if (n == -1) { + return n; + } + // We know we now have the whole command. + // Convert to standard notation + std::string cmd(buf, strlen(buf)); + cmd += '\n'; + cmd += '\0'; + CClientLog *log = new CClientLog; + log->entry = cmd; + events.push_back(log); + lastRecvState = n; + return n; } //@} int CMetaClient::CreateGame(std::string desc, std::string map, std::string players) { + //TODO: decide where to publish newly created games from + return -1; //if (metaSocket.IsValid() == false) { diff --git a/src/network/network.cpp b/src/network/network.cpp index dd27eb6e26..92bcac841b 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -196,9 +196,6 @@ ** ::NetworkCommands() ** Network Updates : exec current command, and send commands to other players ** -** ::NetworkFildes -** UDP Socket for communication. -** ** ::NetworkInSync ** false when commands of the next gameNetCycle of the other player are not ready. ** @@ -292,9 +289,7 @@ void CNetworkParameter::FixValues() bool NetworkInSync = true; /// Network is in sync bool NetworkGame = false; -bool ClientDisconnected = false; - -//CUDPSocket NetworkFildes; /// Network file descriptor +bool ClientDisconnected = false; /// Client has issues connecting to server static unsigned long NetworkLastFrame[PlayerMax]; /// Last frame received packet static unsigned long NetworkLastCycle[PlayerMax]; /// Last cycle received packet @@ -360,18 +355,9 @@ static void NetworkBroadcast(const CNetworkPacket &packet, int numcommands, int // Send to all clients. if (NetConnectType == 1) { // server Server.SendToAllClients(Hosts, HostsCount, buf, size); - /*for (int i = 0; i < HostsCount; ++i) { - const CHost host(Hosts[i].Host, Hosts[i].Port); - if (Hosts[i].PlyNr == player) { - continue; - } - NetworkFildes.Send(host, buf, size); - }*/ } else { // client Client.SendToServer(buf, size); - //const CHost host(Hosts[HostsCount - 1].Host, Hosts[HostsCount - 1].Port); - //NetworkFildes.Send(host, buf, size); } delete[] buf; } @@ -428,14 +414,8 @@ void ExitNetwork1() return; } -/*#ifdef DEBUG - printStatistic(NetworkFildes.getStatistic()); - NetworkFildes.clearStatistic(); - NetworkStat.print(); -#endif*/ - if (NetConnectType == 1) { // server - Server.Close(); + Server.Close(); } else { // client Client.Close(); diff --git a/src/stratagus/stratagus.cpp b/src/stratagus/stratagus.cpp index 750ab92889..aab9959fd7 100644 --- a/src/stratagus/stratagus.cpp +++ b/src/stratagus/stratagus.cpp @@ -523,7 +523,7 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters) { char *sep; for (;;) { - switch (getopt(argc, argv, "ac:d:D:eE:FG:hiI:lN:oOP:ps:S:u:v:Wx:Z:?-")) { + switch (getopt(argc, argv, "ac:d:D:eE:FG:hiI:lN:oOP:ps:S:tu:v:Wx:Z:?-")) { case 'a': EnableAssert = true; continue; @@ -597,6 +597,9 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters) case 'S': VideoSyncSpeed = atoi(optarg); continue; + case 't': + Parameters::Instance.UseUDP = false; + continue; case 'u': Parameters::Instance.SetUserDirectory(optarg); continue; From 9a688962ef8de8e3712998b4b33c9c739bd33182 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Tue, 26 Jun 2018 03:45:49 -0700 Subject: [PATCH 27/32] Small fixes --- src/network/netsockets.cpp | 2 +- src/stratagus/parameters.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/network/netsockets.cpp b/src/network/netsockets.cpp index 34fb0b1e78..e7e3603cb2 100644 --- a/src/network/netsockets.cpp +++ b/src/network/netsockets.cpp @@ -309,7 +309,7 @@ int CTCPSocket::HasDataToRead(int timeout) bool CTCPSocket::IsValid() const { - return m_impl->IsValid(); + return m_impl && m_impl->IsValid(); } CHost CTCPSocket::GetHost() const diff --git a/src/stratagus/parameters.cpp b/src/stratagus/parameters.cpp index a4f49f104b..28bb31bb7e 100644 --- a/src/stratagus/parameters.cpp +++ b/src/stratagus/parameters.cpp @@ -44,7 +44,7 @@ void Parameters::SetDefaultValues() luaStartFilename = "scripts/stratagus.lua"; luaEditorStartFilename = "scripts/editor.lua"; SetDefaultUserDirectory(); - UseUDP = false; + UseUDP = true; } void Parameters::SetDefaultUserDirectory() From 277e8c961f7aaa26e6f5c20d3de64c4ec46358c3 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Tue, 26 Jun 2018 13:52:42 -0700 Subject: [PATCH 28/32] Code review prep --- src/network/netconnect.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 6e10c4985a..8c9b265e47 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -846,10 +846,6 @@ bool CServer::IsValid() const { return _serverConnectionHandler->IsValid(); } -#ifndef UDP - std::map clientSockets; -#endif - int CServer::HasDataToRead(int timeout) const { return _serverConnectionHandler->HasDataToRead(timeout); } @@ -886,6 +882,7 @@ int CServer::Recv(unsigned char *buf, int len, CHost *hostFrom) const { void CServer::Close() { _serverConnectionHandler->Close(); + delete _serverConnectionHandler; _serverConnectionHandler = nullptr; } From 32f7ade3d73baa749bdb266c631ab6ff56df478e Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Tue, 26 Jun 2018 23:44:44 -0700 Subject: [PATCH 29/32] Disconnect if client is non responsive --- src/include/network.h | 2 +- src/network/network.cpp | 15 +++++++++------ src/video/sdl.cpp | 3 ++- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/include/network.h b/src/include/network.h index a698a10da2..8bd347d099 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -68,7 +68,7 @@ class CNetworkParameter extern bool NetworkInSync; /// Network is in sync extern bool NetworkGame; -extern bool ClientDisconnected; +extern bool NetworkDisconnected; /*---------------------------------------------------------------------------- -- Functions diff --git a/src/network/network.cpp b/src/network/network.cpp index 92bcac841b..4799aa3e5a 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -289,7 +289,7 @@ void CNetworkParameter::FixValues() bool NetworkInSync = true; /// Network is in sync bool NetworkGame = false; -bool ClientDisconnected = false; /// Client has issues connecting to server +bool NetworkDisconnected = false; /// Client has issues connecting to server static unsigned long NetworkLastFrame[PlayerMax]; /// Last frame received packet static unsigned long NetworkLastCycle[PlayerMax]; /// Last cycle received packet @@ -769,11 +769,13 @@ static void NetworkParseInGameEvent(const unsigned char *buf, int len, const CHo // Handle some messages. if (packet.Header.Type[i] == MessageQuit) { CNetworkCommandQuit nc; - nc.Deserialize(&packet.Command[i][0]); - const int playerNum = nc.player; + if (!packet.Command[i].empty()) { + nc.Deserialize(&packet.Command[i][0]); + const int playerNum = nc.player; - if (playerNum >= 0 && playerNum < NumPlayers) { - PlayerQuit[playerNum] = 1; + if (playerNum >= 0 && playerNum < NumPlayers) { + PlayerQuit[playerNum] = 1; + } } } if (packet.Header.Type[i] == MessageResend) { @@ -832,7 +834,6 @@ void NetworkEvent() len = Server.Recv(buf, sizeof(buf), &host); } else { // client len = Client.Recv(buf, sizeof(buf), &host); - ClientDisconnected = len < 0; } if (len == 0) @@ -840,6 +841,8 @@ void NetworkEvent() return; } + NetworkDisconnected = len < 0; + if (len < 0) { DebugPrint("Server/Client gone?\n"); // just hope for an automatic recover right now.. diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp index 95a731506a..5947351386 100644 --- a/src/video/sdl.cpp +++ b/src/video/sdl.cpp @@ -987,7 +987,8 @@ void WaitEventsOneFrame() networkHasDataToRead = NetworkHasDataToRead(); if (networkHasDataToRead) { GetCallbacks()->NetworkEvent(); - if (ClientDisconnected) break; + if (NetworkDisconnected) + break; } } // No more input and time for frame over: return From 611264f8038c30e8dc9f5676dccae5b3caa0a5ea Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Wed, 27 Jun 2018 00:02:55 -0700 Subject: [PATCH 30/32] Revert earlier change --- src/network/network.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/network/network.cpp b/src/network/network.cpp index 4799aa3e5a..9f32f197eb 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -769,13 +769,11 @@ static void NetworkParseInGameEvent(const unsigned char *buf, int len, const CHo // Handle some messages. if (packet.Header.Type[i] == MessageQuit) { CNetworkCommandQuit nc; - if (!packet.Command[i].empty()) { - nc.Deserialize(&packet.Command[i][0]); - const int playerNum = nc.player; + nc.Deserialize(&packet.Command[i][0]); + const int playerNum = nc.player; - if (playerNum >= 0 && playerNum < NumPlayers) { - PlayerQuit[playerNum] = 1; - } + if (playerNum >= 0 && playerNum < NumPlayers) { + PlayerQuit[playerNum] = 1; } } if (packet.Header.Type[i] == MessageResend) { From 0dd50f2cc8ba3fde848318206a3aace9770ec8f5 Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Wed, 27 Jun 2018 08:54:36 -0700 Subject: [PATCH 31/32] Check inside socket abstraction if disconnected --- src/include/network.h | 1 - src/network/net_connection_handler.cpp | 5 +++++ src/network/netsockets.cpp | 11 +++++++++++ src/network/network.cpp | 6 +----- src/video/sdl.cpp | 2 -- 5 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/include/network.h b/src/include/network.h index 8bd347d099..26e1707efb 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -68,7 +68,6 @@ class CNetworkParameter extern bool NetworkInSync; /// Network is in sync extern bool NetworkGame; -extern bool NetworkDisconnected; /*---------------------------------------------------------------------------- -- Functions diff --git a/src/network/net_connection_handler.cpp b/src/network/net_connection_handler.cpp index 847e5ba320..080c4092f6 100644 --- a/src/network/net_connection_handler.cpp +++ b/src/network/net_connection_handler.cpp @@ -73,9 +73,14 @@ int CTCPConnectionHandler::Send(const unsigned char* buf, unsigned int len) { int CTCPConnectionHandler::Recv(unsigned char* buf, int len) { auto* bufLength = new unsigned char[2]; + if(_socket.HasDataToRead(0) <= 0) { + return 0; + } + const int resLen = _socket.Recv(bufLength, 2); if (resLen < 2) { + _socket.Close(); return resLen; } diff --git a/src/network/netsockets.cpp b/src/network/netsockets.cpp index e7e3603cb2..4c94772d76 100644 --- a/src/network/netsockets.cpp +++ b/src/network/netsockets.cpp @@ -256,11 +256,14 @@ bool CTCPSocket::Open(const CHost &host) int CTCPSocket::Listen() { + if (!IsValid()) return -1; return m_impl->Listen(); } void CTCPSocket::Close() { + if (!IsValid()) return; + m_impl->Close(); delete m_impl; m_impl = nullptr; @@ -268,11 +271,14 @@ void CTCPSocket::Close() bool CTCPSocket::Connect(const CHost &host) { + if (!IsValid()) return false; return m_impl->Connect(host); } CTCPSocket* CTCPSocket::Accept() { + if (!IsValid()) return nullptr; + auto impl = m_impl->Accept(); if(impl == nullptr) { @@ -284,26 +290,31 @@ CTCPSocket* CTCPSocket::Accept() int CTCPSocket::Send(const unsigned char *buf, unsigned int len) { + if (!IsValid()) return -1; return m_impl->Send(buf, len); } int CTCPSocket::Recv(unsigned char *buf, int len) { + if (!IsValid()) return -1; return m_impl->Recv(buf, len); } void CTCPSocket::SetBlocking() { + if (!IsValid()) return; m_impl->SetBlocking(); } void CTCPSocket::SetNonBlocking() { + if (!IsValid()) return; m_impl->SetNonBlocking(); } int CTCPSocket::HasDataToRead(int timeout) { + if (!IsValid()) return -1; return m_impl->HasDataToRead(timeout); } diff --git a/src/network/network.cpp b/src/network/network.cpp index 9f32f197eb..7a279fd32b 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -289,7 +289,6 @@ void CNetworkParameter::FixValues() bool NetworkInSync = true; /// Network is in sync bool NetworkGame = false; -bool NetworkDisconnected = false; /// Client has issues connecting to server static unsigned long NetworkLastFrame[PlayerMax]; /// Last frame received packet static unsigned long NetworkLastCycle[PlayerMax]; /// Last cycle received packet @@ -834,13 +833,10 @@ void NetworkEvent() len = Client.Recv(buf, sizeof(buf), &host); } - if (len == 0) - { + if (len == 0) { return; } - NetworkDisconnected = len < 0; - if (len < 0) { DebugPrint("Server/Client gone?\n"); // just hope for an automatic recover right now.. diff --git a/src/video/sdl.cpp b/src/video/sdl.cpp index 5947351386..ce6fc6f1f7 100644 --- a/src/video/sdl.cpp +++ b/src/video/sdl.cpp @@ -987,8 +987,6 @@ void WaitEventsOneFrame() networkHasDataToRead = NetworkHasDataToRead(); if (networkHasDataToRead) { GetCallbacks()->NetworkEvent(); - if (NetworkDisconnected) - break; } } // No more input and time for frame over: return From 748416e20011eda6e8ea9dde8ca264d63bb6158b Mon Sep 17 00:00:00 2001 From: Daniel Hartl Date: Wed, 27 Jun 2018 11:07:37 -0700 Subject: [PATCH 32/32] More graceful exit of network game --- src/network/netconnect.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 8c9b265e47..e1d6635c24 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -193,7 +193,11 @@ void CClient::Init(const std::string &name, CServerSetup *serverSetup, CServerSe } void CClient::Open(bool udp) { - if(udp) { + if (_clientConnectionHandler) { + Close(); + } + + if (udp) { _clientConnectionHandler = new CUDPClientConnectionHandler(this->serverHost); } else { @@ -212,18 +216,22 @@ bool CClient::IsValid() const { } int CClient::HasDataToRead(int timeout) { + if (!IsValid()) return -1; return _clientConnectionHandler->HasDataToRead(timeout); } void CClient::SendToServer(const unsigned char *buf, unsigned int len) { + if (!IsValid()) return; _clientConnectionHandler->SendToServer(buf, len); } int CClient::Recv(unsigned char *buf, int len, CHost *hostFrom) { + if (!IsValid()) return -1; return _clientConnectionHandler->Recv(buf, len, hostFrom); } void CClient::Close() { + if (_clientConnectionHandler == nullptr) return; _clientConnectionHandler->Close(); delete _clientConnectionHandler; _clientConnectionHandler = nullptr;