From cdb606fae6c58d58314a15b9515290545582944b Mon Sep 17 00:00:00 2001 From: joris <joris.dauphin@gmail.com> Date: Sun, 7 Apr 2013 16:40:32 +0200 Subject: [PATCH] Move some network globals into a singleton. Remove configuration from the command line of NetworkLag, NetworkUpdates. --- src/include/network.h | 26 ++++++----- src/network/master.cpp | 2 +- src/network/net_message.cpp | 4 +- src/network/netconnect.cpp | 6 +-- src/network/network.cpp | 89 +++++++++++++++++++++++-------------- src/stratagus/stratagus.cpp | 19 ++------ 6 files changed, 81 insertions(+), 65 deletions(-) diff --git a/src/include/network.h b/src/include/network.h index 58437231d..ca13c3d3c 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -37,12 +37,6 @@ #include "network/udpsocket.h" -/*---------------------------------------------------------------------------- --- Defines -----------------------------------------------------------------------------*/ - -#define NetworkDefaultPort 6660 /// Default communication port - /*---------------------------------------------------------------------------- -- Declarations ----------------------------------------------------------------------------*/ @@ -50,16 +44,28 @@ class CUnit; class CUnitType; +class CNetworkParameter +{ +public: + CNetworkParameter(); + void FixValues(); +public: + std::string localHost; /// Local network address to use + int localPort; /// Local network port to use + int NetworkUpdates; /// Network update each # game cycles + int NetworkLag; /// Network lag (# game cycles) (multiple of NetworkUpdates) +public: + static const int defaultPort = 6660; /// Default communication port +public: + static CNetworkParameter Instance; +}; + /*---------------------------------------------------------------------------- -- Variables ----------------------------------------------------------------------------*/ -extern char *NetworkAddr; /// Local network address to use -extern int NetworkPort; /// Local network port to use extern CUDPSocket NetworkFildes; /// Network file descriptor extern int NetworkInSync; /// Network is in sync -extern int NetworkUpdates; /// Network update each # game cycles -extern int NetworkLag; /// Network lag (# game cycles) /*---------------------------------------------------------------------------- -- Functions diff --git a/src/network/master.cpp b/src/network/master.cpp index e02177359..a6618a7fd 100644 --- a/src/network/master.cpp +++ b/src/network/master.cpp @@ -89,7 +89,7 @@ int MetaInit() const int port_range_max = 1244; for (int i = port_range_min; i < port_range_max; ++i) { - MetaServerFildes = NetOpenTCP(NetworkAddr, i); //FIXME: need to make a dynamic port allocation there...if (!MetaServerFildes) {...} + MetaServerFildes = NetOpenTCP(CNetworkParameter::Instance.localHost.c_str(), i); if (MetaServerFildes != static_cast<Socket>(-1)) { if (NetConnectTCP(MetaServerFildes, NetResolveHost(MasterHost), MasterPort) != -1) { break; diff --git a/src/network/net_message.cpp b/src/network/net_message.cpp index a5e448e07..3ab37b219 100644 --- a/src/network/net_message.cpp +++ b/src/network/net_message.cpp @@ -395,8 +395,8 @@ void CInitMessage_ProtocolMismatch::Deserialize(const unsigned char *p) CInitMessage_Welcome::CInitMessage_Welcome() : header(MessageInit_FromServer, ICMWelcome) { - this->Lag = NetworkLag; - this->Updates = NetworkUpdates; + this->Lag = CNetworkParameter::Instance.NetworkLag; + this->Updates = CNetworkParameter::Instance.NetworkUpdates; } const unsigned char *CInitMessage_Welcome::Serialize() const diff --git a/src/network/netconnect.cpp b/src/network/netconnect.cpp index 53a4189f4..5c61a9121 100644 --- a/src/network/netconnect.cpp +++ b/src/network/netconnect.cpp @@ -779,8 +779,8 @@ void CClient::Parse_Welcome(const unsigned char *buf) networkState.MsgCnt = 0; NetLocalHostsSlot = msg.hosts[0].PlyNr; Hosts[0].SetName(msg.hosts[0].PlyName); // Name of server player - NetworkLag = msg.Lag; - NetworkUpdates = msg.Updates; + CNetworkParameter::Instance.NetworkLag = msg.Lag; + CNetworkParameter::Instance.NetworkUpdates = msg.Updates; Hosts[0].Host = serverHost.getIp(); Hosts[0].Port = serverHost.getPort(); @@ -1723,7 +1723,7 @@ breakout: int NetworkSetupServerAddress(const std::string &serveraddr, int port) { if (port == 0) { - port = NetworkDefaultPort; + port = CNetworkParameter::Instance.defaultPort; } CHost host(serveraddr.c_str(), port); if (host.isValid() == false) { diff --git a/src/network/network.cpp b/src/network/network.cpp index 5bada2a58..b75eeb01b 100644 --- a/src/network/network.cpp +++ b/src/network/network.cpp @@ -262,7 +262,6 @@ public: CNetworkCommand Data; /// command content }; - /** ** Network Selection Info */ @@ -277,12 +276,28 @@ struct NetworkSelectionHeader { // Variables //---------------------------------------------------------------------------- -char *NetworkAddr = NULL; /// Local network address to use -int NetworkPort = NetworkDefaultPort; /// Local network port to use -CUDPSocket NetworkFildes; /// Network file descriptor +/* static */ CNetworkParameter CNetworkParameter::Instance; + +CNetworkParameter::CNetworkParameter() +{ + localHost = "127.0.0.1"; + localPort = defaultPort; + NetworkUpdates = 5; + NetworkLag = 10; +} + +void CNetworkParameter::FixValues() +{ + NetworkUpdates = std::max(NetworkUpdates, 1); + NetworkLag = std::max(NetworkLag, 2 * NetworkUpdates); + // Lag must be multiple of updates + NetworkLag = (NetworkLag / NetworkUpdates) * NetworkUpdates; +} + int NetworkInSync = 1; /// Network is in sync -int NetworkUpdates = 5; /// Network update each # game cycles -int NetworkLag = 10; /// Network lag in # game cycles + +CUDPSocket NetworkFildes; /// Network file descriptor + static unsigned long NetworkLastFrame[PlayerMax]; /// Last frame received packet static const int NetworkTimeout = 45; /// Number of seconds until player times out @@ -373,6 +388,8 @@ static void NetworkSendPacket(const CNetworkCommandQueue (&ncq)[MaxNetworkComman */ void InitNetwork1() { + CNetworkParameter::Instance.FixValues(); + CommandsIn.clear(); MsgCommandsIn.clear(); NumNCQs = 0; @@ -385,14 +402,11 @@ void InitNetwork1() for (int i = 0; i < PlayerMax; ++i) { NetMsgBufLen[i] = 0; } - NetworkUpdates = std::max(NetworkUpdates, 1); - // Lag must be multiple of updates - NetworkLag = (NetworkLag / NetworkUpdates) * NetworkUpdates; // Our communication port - int port = NetworkPort; + int port = CNetworkParameter::Instance.localPort; for (int i = 0; i < 10; ++i) { - NetworkFildes.Open(CHost(NetworkAddr, port + i)); + NetworkFildes.Open(CHost(CNetworkParameter::Instance.localHost.c_str(), port + i)); if (NetworkFildes.IsValid()) { port = port + i; break; @@ -463,15 +477,19 @@ void InitNetwork2() for (int i = 0; i < HostsCount; ++i) { Players[Hosts[i].PlyNr].SetName(Hosts[i].PlyName); } - DebugPrint("Lag %d, Updates %d, Hosts %d\n" _C_ NetworkLag _C_ NetworkUpdates _C_ HostsCount); + DebugPrint("Updates %d, Lag %d, Hosts %d\n" _C_ + CNetworkParameter::Instance.NetworkUpdates _C_ + CNetworkParameter::Instance.NetworkLag _C_ HostsCount); // Prepare first time without syncs. memset(NetworkIn, 0, sizeof(NetworkIn)); - for (int i = 0; i <= NetworkLag; i += NetworkUpdates) { + for (int i = 0; i <= CNetworkParameter::Instance.NetworkLag; i += CNetworkParameter::Instance.NetworkUpdates) { for (int n = 0; n < HostsCount; ++n) { - for (int c = 0; c < MaxNetworkCommands; ++c) { - NetworkIn[i][Hosts[n].PlyNr][c].Time = i; - NetworkIn[i][Hosts[n].PlyNr][c].Type = MessageSync; - } + CNetworkCommandQueue (&ncqs)[MaxNetworkCommands] = NetworkIn[i][Hosts[n].PlyNr]; + + ncqs[0].Time = i; + ncqs[0].Type = MessageSync; + ncqs[1].Time = i; + ncqs[1].Type = MessageNone; } } memset(NetworkSyncSeeds, 0, sizeof(NetworkSyncSeeds)); @@ -841,7 +859,8 @@ static void NetworkParseInGameEvent(unsigned char *buf, int len, const CHost &ho } // Waiting for this time slot if (!NetworkInSync) { - unsigned long n = (GameCycle / NetworkUpdates) * NetworkUpdates + NetworkUpdates; + const int networkUpdates = CNetworkParameter::Instance.NetworkUpdates; + unsigned long n = ((GameCycle / networkUpdates) + 1) * networkUpdates; if (IsNetworkCommandReady(n) == true) { NetworkInSync = 1; } @@ -892,6 +911,8 @@ void NetworkQuit() if (!ThisPlayer) { return; } + const int NetworkUpdates = CNetworkParameter::Instance.NetworkUpdates; + const int NetworkLag = CNetworkParameter::Instance.NetworkLag; const int n = (GameCycle + NetworkUpdates) / NetworkUpdates * NetworkUpdates + NetworkLag; CNetworkCommandQueue (&ncqs)[MaxNetworkCommands] = NetworkIn[n & 0xFF][ThisPlayer->Index]; ncqs[0].Type = MessageQuit; @@ -1091,15 +1112,15 @@ void NetworkCommands() if (!IsNetworkGame()) { return; } - if ((GameCycle % NetworkUpdates) != 0) { + if ((GameCycle % CNetworkParameter::Instance.NetworkUpdates) != 0) { return; } // Send messages to all clients (other players) - NetworkSendCommands(GameCycle + NetworkLag); + NetworkSendCommands(GameCycle + CNetworkParameter::Instance.NetworkLag); NetworkExecCommands(GameCycle); - if (IsNetworkCommandReady(GameCycle + NetworkUpdates) == false) { + if (IsNetworkCommandReady(GameCycle + CNetworkParameter::Instance.NetworkUpdates) == false) { NetworkInSync = 0; - NetworkDelay = FrameCounter + NetworkUpdates; + NetworkDelay = FrameCounter + CNetworkParameter::Instance.NetworkUpdates; // FIXME: should send a resend request. } } @@ -1117,12 +1138,13 @@ static void NetworkResendCommands() ++NetworkSendResend; #endif + const int NetworkUpdates = CNetworkParameter::Instance.NetworkUpdates; + const int gameCycle = ((GameCycle / NetworkUpdates) + 1) * NetworkUpdates; // Build packet CNetworkPacket packet; packet.Header.Type[0] = MessageResend; packet.Header.Type[1] = MessageNone; - packet.Header.Cycle = - (uint8_t)((GameCycle / NetworkUpdates) * NetworkUpdates + NetworkUpdates); + packet.Header.Cycle = uint8_t(gameCycle & 0xFF); NetworkBroadcast(packet, 1); } @@ -1139,18 +1161,19 @@ void NetworkRecover() if (FrameCounter <= NetworkDelay) { return; } - NetworkDelay += NetworkUpdates; + NetworkDelay += CNetworkParameter::Instance.NetworkUpdates; // Check for players that timed out for (int i = 0; i < HostsCount; ++i) { - if (!NetworkLastFrame[Hosts[i].PlyNr]) { + const unsigned long lastFrame = NetworkLastFrame[Hosts[i].PlyNr]; + if (!lastFrame) { continue; } - int secs = (FrameCounter - NetworkLastFrame[Hosts[i].PlyNr]) / - (FRAMES_PER_SECOND * VideoSyncSpeed / 100); + const int secs = (FrameCounter - lastFrame) / + (FRAMES_PER_SECOND * VideoSyncSpeed / 100); // FIXME: display a menu while we wait - if (secs >= 3 && secs < NetworkTimeout) { - if (FrameCounter % FRAMES_PER_SECOND < (unsigned long)NetworkUpdates) { + if (3 <= secs && secs < NetworkTimeout) { + if (FrameCounter % FRAMES_PER_SECOND < (unsigned long)CNetworkParameter::Instance.NetworkUpdates) { SetMessage(_("Waiting for player \"%s\": %d:%02d"), Hosts[i].PlyName, (NetworkTimeout - secs) / 60, (NetworkTimeout - secs) % 60); } @@ -1159,7 +1182,7 @@ void NetworkRecover() CNetworkCommand nc; CNetworkPacket np; - unsigned long n = GameCycle + NetworkUpdates; + const unsigned long n = GameCycle + CNetworkParameter::Instance.NetworkUpdates; nc.X = Hosts[i].PlyNr; NetworkIn[n & 0xFF][Hosts[i].PlyNr][0].Time = n; NetworkIn[n & 0xFF][Hosts[i].PlyNr][0].Type = MessageQuit; @@ -1174,9 +1197,9 @@ void NetworkRecover() NetworkBroadcast(np, 1); - if (IsNetworkCommandReady(GameCycle + NetworkUpdates) == false) { + if (IsNetworkCommandReady(GameCycle + CNetworkParameter::Instance.NetworkUpdates) == false) { NetworkInSync = 0; - NetworkDelay = FrameCounter + NetworkUpdates; + NetworkDelay = FrameCounter + CNetworkParameter::Instance.NetworkUpdates; // FIXME: should send a resend request. } } diff --git a/src/stratagus/stratagus.cpp b/src/stratagus/stratagus.cpp index 792821506..050e8976b 100644 --- a/src/stratagus/stratagus.cpp +++ b/src/stratagus/stratagus.cpp @@ -438,7 +438,6 @@ static void Usage() "\t-h\t\tHelp shows this page\n" "\t-I addr\t\tNetwork address to use\n" "\t-l\t\tDisable command log\n" - "\t-L lag\t\tNetwork lag in # frames (default 10 = 333ms)\n" "\t-N name\t\tName of the player\n" #if defined(USE_OPENGL) || defined(USE_GLES) "\t-o\t\tDo not use OpenGL or OpenGL ES 1.1\n" @@ -447,7 +446,6 @@ static void Usage() "\t-P port\t\tNetwork port to use\n" "\t-s sleep\tNumber of frames for the AI to sleep before it starts\n" "\t-S speed\tSync speed (100 = 30 frames/s)\n" - "\t-U update\tNetwork update rate in # frames (default 5=6x per s)\n" "\t-v mode\t\tVideo mode resolution in format <xres>x<yres>\n" "\t-W\t\tWindowed video mode\n" "map is relative to StratagusLibPath=datapath, use ./map for relative to cwd\n", @@ -500,7 +498,7 @@ static void RedirectOutput() void ParseCommandLine(int argc, char **argv, Parameters ¶meters) { for (;;) { - switch (getopt(argc, argv, "c:d:D:eE:FhI:lL:N:oOP:s:S:U:v:W?")) { + switch (getopt(argc, argv, "c:d:D:eE:FhI:lN:oOP:s:S:v:W?")) { case 'c': parameters.luaStartFilename = optarg; continue; @@ -526,19 +524,11 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters) Video.FullScreen = 1; continue; case 'I': - NetworkAddr = optarg; + CNetworkParameter::Instance.localHost = optarg; continue; case 'l': CommandLogDisabled = true; continue; - case 'L': - NetworkLag = atoi(optarg); - if (!NetworkLag) { - fprintf(stderr, "%s: zero lag not supported\n", argv[0]); - Usage(); - ExitFatal(-1); - } - continue; case 'N': parameters.LocalPlayerName = optarg; continue; @@ -553,7 +543,7 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters) continue; #endif case 'P': - NetworkPort = atoi(optarg); + CNetworkParameter::Instance.localPort = atoi(optarg); continue; case 's': AiSleepCycles = atoi(optarg); @@ -561,9 +551,6 @@ void ParseCommandLine(int argc, char **argv, Parameters ¶meters) case 'S': VideoSyncSpeed = atoi(optarg); continue; - case 'U': - NetworkUpdates = atoi(optarg); - continue; case 'v': { char *sep = strchr(optarg, 'x'); if (!sep || !*(sep + 1)) {