diff options
-rw-r--r-- | functions.h | 1 | ||||
-rw-r--r-- | lang/english.txt | 1 | ||||
-rw-r--r-- | network.c | 195 | ||||
-rw-r--r-- | ttd.c | 5 | ||||
-rw-r--r-- | variables.h | 1 |
5 files changed, 140 insertions, 63 deletions
diff --git a/functions.h b/functions.h index c898e2b7a..90f99b530 100644 --- a/functions.h +++ b/functions.h @@ -130,6 +130,7 @@ void NetworkShutdown(); void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback); void NetworkStartSync(bool fcreset); void NetworkClose(bool client); +void NetworkSendReadyPacket(); void NetworkIPListInit(); diff --git a/lang/english.txt b/lang/english.txt index 0dd4a4289..0d39fd950 100644 --- a/lang/english.txt +++ b/lang/english.txt @@ -1242,6 +1242,7 @@ STR_NETWORK_ERR_NOCONNECTION :{WHITE} The server didn't answer the request STR_NETWORK_ERR_DESYNC :{WHITE} Network-Game synchronization failed. STR_NETWORK_ERR_LOSTCONNECTION :{WHITE} Network-Game connection lost. STR_NETWORK_ERR_SAVEGAMEERROR :{WHITE} Could not load server-savegame. +STR_NETWORK_ERR_TIMEOUT :{WHITE} Connection #{NUMU16} timed out. ############ end network gui strings @@ -116,6 +116,11 @@ typedef struct AckPacket { byte packet_type; } AckPacket; +typedef struct ReadyPacket { + byte packet_length; + byte packet_type; +} ReadyPacket; + typedef struct FilePacketHdr { byte packet_length; byte packet_type; @@ -142,6 +147,8 @@ typedef struct ClientState { int socket; bool inactive; // disable sending of commands/syncs to client bool writable; + bool ready; + uint timeout; uint xmitpos; uint eaten; @@ -183,6 +190,8 @@ static int _num_clients; // keep a history of the 16 most recent seeds to be able to capture out of sync errors. static uint32 _my_seed_list[16][2]; +static bool _network_ready_sent; +static uint32 _network_client_timeout; typedef struct FutureSeeds { int32 frame; @@ -246,6 +255,7 @@ typedef struct NetworkGameList { static NetworkGameInfo _network_game; static NetworkGameList * _network_game_list = NULL; + /* multi os compatible sleep function */ void CSleep(int milliseconds) { #if defined(WIN32) @@ -287,30 +297,33 @@ usleep(milliseconds*1000); // * Network Error Handlers * // // ****************************** // -static void NetworkHandleSaveGameError() { +static void NetworkHandleSaveGameError() +{ _networking_sync = false; _networking_queuing = true; _switch_mode = SM_MENU; _switch_mode_errorstr = STR_NETWORK_ERR_SAVEGAMEERROR; } -static void NetworkHandleConnectionLost() { +static void NetworkHandleConnectionLost() +{ _networking_sync = false; _networking_queuing = true; _switch_mode = SM_MENU; _switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION; } -static void NetworkHandleDeSync() { - printf("fatal error: network sync error at frame %i\n",_frame_counter); - { - int i; - for (i=15; i>=0; i--) printf("frame %i: [0]=%i, [1]=%i\n",_frame_counter-(i+1),_my_seed_list[i][0],_my_seed_list[i][1]); - for (i=0; i<8; i++) printf("frame %i: [0]=%i, [1]=%i\n",_frame_counter+i,_future_seed[i].seed[0],_future_seed[i].seed[1]); - } - _networking_sync = false; - _networking_queuing = true; - _switch_mode = SM_MENU; - _switch_mode_errorstr = STR_NETWORK_ERR_DESYNC; +static void NetworkHandleDeSync() +{ + DEBUG(net, 0) ("[NET] Fatal ERROR: network sync error at frame %i", _frame_counter); + { + int i; + for (i=15; i>=0; i--) DEBUG(net,0) ("[NET] frame %i: [0]=%i, [1]=%i",_frame_counter-(i+1),_my_seed_list[i][0],_my_seed_list[i][1]); + for (i=0; i<8; i++) DEBUG(net,0) ("[NET] frame %i: [0]=%i, [1]=%i",_frame_counter+i,_future_seed[i].seed[0],_future_seed[i].seed[1]); + } + _networking_sync = false; + _networking_queuing = true; + _switch_mode = SM_MENU; + _switch_mode_errorstr = STR_NETWORK_ERR_DESYNC; } // ****************************** // @@ -343,12 +356,13 @@ void NetworkProcessCommands() if (!(nq->head = qp->next)) nq->last = &nq->head; if (qp->frame < _frame_counter && _networking_sync) { - error("!qp->cp.frame < _frame_counter, %d < %d\n", qp->frame, _frame_counter); + DEBUG(net,0) ("error: !qp->cp.frame < _frame_counter, %d < %d\n", qp->frame, _frame_counter); } // run the command _current_player = qp->cp.player; memcpy(_decode_parameters, qp->cp.dp, (qp->cp.packet_length - COMMAND_PACKET_BASE_SIZE)); + DoCommandP(qp->cp.tile, qp->cp.p1, qp->cp.p2, qp->callback, qp->cmd | CMD_DONT_NETWORK); free(qp); } @@ -466,7 +480,7 @@ static void HandleCommandPacket(ClientState *cs, CommandPacket *np) ClientState *c; AckPacket ap; - printf("net: cmd size %d\n", np->packet_length); + DEBUG(net, 2) ("[NET] cmd size %d", np->packet_length); assert(np->packet_length >= COMMAND_PACKET_BASE_SIZE); @@ -515,7 +529,8 @@ static void HandleSyncPacket(SyncPacket *sp) _frame_counter_srv = _frame_counter_max - sp->server; _frame_counter_max += sp->frames; - printf("net: sync max=%d cur=%d server=%d\n", _frame_counter_max, _frame_counter, _frame_counter_srv); + // reset network ready packet state + _network_ready_sent = false; // queueing only? if (_networking_queuing || _frame_counter == 0) @@ -524,6 +539,8 @@ static void HandleSyncPacket(SyncPacket *sp) s1 = TO_LE32(sp->random_seed_1); s2 = TO_LE32(sp->random_seed_2); + DEBUG(net, 2) ("[NET] sync seeds: [1]=%i rnd[2]=%i", sp->random_seed_1, sp->random_seed_2); + if (_frame_counter_srv <= _frame_counter) { // we are ahead of the server check if the seed is in our list. if (_frame_counter_srv + 16 > _frame_counter) { @@ -556,7 +573,7 @@ static void HandleAckPacket() *_command_queue.last = q; _command_queue.last = &q->next; - printf("net: ack\n"); + DEBUG(net, 2) ("[NET] ack"); } static void HandleFilePacket(FilePacketHdr *fp) @@ -605,7 +622,7 @@ static void CloseClient(ClientState *cs) { Packet *p, *next; - DEBUG(misc,1) ("[NET][TCP] closed client connection"); + DEBUG(net, 1) ("[NET][TCP] closed client connection"); assert(cs->socket != INVALID_SOCKET); @@ -645,7 +662,7 @@ static bool ReadPackets(ClientState *cs) if ( recv_bytes == (unsigned long)-1) { int err = GET_LAST_ERROR(); if (err == EWOULDBLOCK) break; - printf("net: recv() failed with error %d\n", err); + DEBUG(net, 0) ("[NET] recv() failed with error %d", err); CloseClient(cs); return false; } @@ -661,7 +678,6 @@ static bool ReadPackets(ClientState *cs) if (size < packet[0]) break; size -= packet[0]; pos += packet[0]; - switch(packet[1]) { case 0: HandleCommandPacket(cs, (CommandPacket*)packet); @@ -678,8 +694,12 @@ static bool ReadPackets(ClientState *cs) case 3: HandleFilePacket((FilePacketHdr*)packet); break; + case 5: + cs->ready=true; + cs->timeout=_network_client_timeout; + break; default: - error("unknown packet type"); + DEBUG (net,0) ("net: unknown packet type"); } } @@ -709,7 +729,7 @@ static bool SendPackets(ClientState *cs) if (n == -1) { int err = GET_LAST_ERROR(); if (err == EWOULDBLOCK) break; - printf("net: send() failed with error %d\n", err); + DEBUG(net, 0) ("[NET] send() failed with error %d", err); CloseClient(cs); return false; } @@ -776,7 +796,7 @@ static void SendXmit(ClientState *cs) cs->xmitpos = pos + 1; - printf("net: client xmit at %d\n", pos + 1); + DEBUG(net, 2) ("[NET] client xmit at %d", pos + 1); } static ClientState *AllocClient(SOCKET s) @@ -792,9 +812,22 @@ static ClientState *AllocClient(SOCKET s) memset(cs, 0, sizeof(*cs)); cs->last = &cs->head; cs->socket = s; + cs->timeout = _network_client_timeout; return cs; } +void NetworkSendReadyPacket() +{ + if (!_network_ready_sent) { + ReadyPacket *rp = malloc(sizeof(rp)); + ClientState *c = _clients; + + rp->packet_type = 5; + rp->packet_length = sizeof(rp); + SendBytes(c, rp, sizeof(rp)); + _network_ready_sent = true; + } +} static void NetworkAcceptClients() { @@ -817,7 +850,7 @@ static void NetworkAcceptClients() // set nonblocking mode for client socket { unsigned long blocking = 1; ioctlsocket(s, FIONBIO, &blocking); } - printf("net: got client from %s\n", inet_ntoa(sin.sin_addr)); + DEBUG(net, 1) ("[NET] got client from %s", inet_ntoa(sin.sin_addr)); // set nodelay {int b = 1; setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b));} @@ -856,7 +889,7 @@ static void SendQueuedCommandsToNewClient(ClientState *cs) SyncPacket sp; int32 frame; - printf("net: sending queued commands to client\n"); + DEBUG(net, 2) ("[NET] sending queued commands to client"); sp.packet_length = sizeof(sp); sp.packet_type = 1; @@ -866,7 +899,7 @@ static void SendQueuedCommandsToNewClient(ClientState *cs) frame = _frame_counter; for(qp=_command_queue.head; qp; qp = qp->next) { - printf("net: sending cmd to be executed at %d (old %d)\n", qp->frame, frame); + DEBUG(net, 4) ("[NET] sending cmd to be executed at %d (old %d)", qp->frame, frame); if (qp->frame > frame) { assert(qp->frame <= _frame_counter_max); sp.frames = qp->frame - frame; @@ -877,7 +910,7 @@ static void SendQueuedCommandsToNewClient(ClientState *cs) } if (frame < _frame_counter_max) { - printf("net: sending queued sync %d (%d)\n", _frame_counter_max, frame); + DEBUG(net, 4) ("[NET] sending queued sync %d (%d)", _frame_counter_max, frame); sp.frames = _frame_counter_max - frame; SendBytes(cs, &sp, sizeof(sp)); } @@ -895,10 +928,10 @@ unsigned long NetworkResolveHost(const char *hostname) { // seems to be an hostname [first character is no number] remotehost = gethostbyname(hostname); if (remotehost == NULL) { - DEBUG(misc, 2) ("[NET][IP] cannot resolve %s", hostname); + DEBUG(net, 1) ("[NET][IP] cannot resolve %s", hostname); return 0; } else { - DEBUG(misc,2) ("[NET][IP] resolved %s to %s",hostname, inet_ntoa(*(struct in_addr *) remotehost->h_addr_list[0])); + DEBUG(net, 1) ("[NET][IP] resolved %s to %s",hostname, inet_ntoa(*(struct in_addr *) remotehost->h_addr_list[0])); return inet_addr(inet_ntoa(*(struct in_addr *) remotehost->h_addr_list[0])); } } else { @@ -914,7 +947,7 @@ bool NetworkConnect(const char *hostname, int port) struct sockaddr_in sin; int b; - DEBUG(misc, 1) ("[NET][TCP] Connecting to %s %d", hostname, port); + DEBUG(net, 1) ("[NET][TCP] Connecting to %s %d", hostname, port); s = socket(AF_INET, SOCK_STREAM, 0); if (s == INVALID_SOCKET) error("socket() failed"); @@ -953,7 +986,7 @@ void NetworkListen() port = _network_server_port; - DEBUG(misc, 1) ("[NET][TCP] listening on port %d", port); + DEBUG(net, 1) ("[NET][TCP] listening on port %d", port); ls = socket(AF_INET, SOCK_STREAM, 0); if (ls == INVALID_SOCKET) @@ -1007,7 +1040,7 @@ void NetworkReceive() #else n = WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL); #endif - if (n == -1) NetworkHandleConnectionLost(); + if ((n == -1) && (!_networking_server)) NetworkHandleConnectionLost(); // accept clients.. if (_networking_server && FD_ISSET(_listensocket, &read_fd)) @@ -1052,13 +1085,39 @@ void NetworkSend() { ClientState *cs; void *free_xmit; + uint16 count; + bool ready_all; // send sync packets? if (_networking_server && _networking_sync && !_pause) { + if (++_not_packet >= _network_sync_freq) { SyncPacket sp; uint new_max; + + ready_all=false; + + while (!ready_all) { + // check wether all clients are ready + ready_all=true; + count=0; + for(cs=_clients;cs->socket != INVALID_SOCKET; cs++) { + count++; + ready_all = ready_all && (cs->ready || cs->inactive || (cs->xmitpos>0)); + cs->timeout-=5; + if (cs->timeout == 0) { + SET_DPARAM16(0,count); + ShowErrorMessage(-1,STR_NETWORK_ERR_TIMEOUT,0,0); + CloseClient(cs); + } + } + if (!ready_all) { + NetworkReceive(); + CSleep(5); + } + } + _not_packet = 0; new_max = max(_frame_counter + (int)_network_ahead_frames, _frame_counter_max); @@ -1071,8 +1130,11 @@ void NetworkSend() sp.random_seed_2 = TO_LE32(_sync_seed_2); _frame_counter_max = new_max; - // send it to all the clients - for(cs=_clients;cs->socket != INVALID_SOCKET; cs++) SendBytes(cs, &sp, sizeof(sp)); + // send it to all the clients and mark them unready + for(cs=_clients;cs->socket != INVALID_SOCKET; cs++) { + cs->ready=false; + SendBytes(cs, &sp, sizeof(sp)); + } } } @@ -1124,7 +1186,7 @@ void NetworkClose(bool client) { // if in servermode --> close listener closesocket(_listensocket); _listensocket= INVALID_SOCKET; - DEBUG(misc,1) ("[NET][TCP] closed listener on port %i", _network_server_port); + DEBUG(net, 1) ("[NET][TCP] closed listener on port %i", _network_server_port); } } @@ -1141,7 +1203,7 @@ void NetworkShutdown() // switch to synced mode. void NetworkStartSync(bool fcreset) { - DEBUG(misc,3) ("[NET][SYNC] switching to synced game mode"); + DEBUG(net, 3) ("[NET][SYNC] switching to synced game mode"); _networking_sync = true; _frame_counter = 0; if (fcreset) { @@ -1182,7 +1244,7 @@ void NetworkUDPListen(bool client) if (client) { port = _network_client_port; } else { port = _network_server_port; }; - DEBUG(misc,1) ("[NET][UDP] listening on port %i", port); + DEBUG(net, 1) ("[NET][UDP] listening on port %i", port); udp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); @@ -1197,7 +1259,7 @@ void NetworkUDPListen(bool client) sin.sin_port = htons(port); if (bind(udp, (struct sockaddr*)&sin, sizeof(sin)) != 0) - DEBUG(misc,1) ("[NET][UDP] error: bind failed on port %i", port); + DEBUG(net, 1) ("[NET][UDP] error: bind failed on port %i", port); // enable broadcasting @@ -1211,11 +1273,11 @@ void NetworkUDPListen(bool client) void NetworkUDPClose(bool client) { if (client) { - DEBUG(misc,1) ("[NET][UDP] closed listener on port %i", _network_client_port); + DEBUG(net, 1) ("[NET][UDP] closed listener on port %i", _network_client_port); closesocket(_udp_client_socket); _udp_client_socket = INVALID_SOCKET; } else { - DEBUG(misc,1) ("[NET][UDP] closed listener on port %i", _network_server_port); + DEBUG(net, 1) ("[NET][UDP] closed listener on port %i", _network_server_port); closesocket(_udp_server_socket); _udp_server_socket = INVALID_SOCKET; }; @@ -1292,7 +1354,7 @@ void NetworkUDPBroadCast(bool client, struct UDPPacket packet) { bcptr[3]=255; out_addr.sin_addr.s_addr = bcaddr; res=sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &out_addr,sizeof(out_addr)); - if (res==-1) DEBUG(misc,1)("udp: broadcast error: %i",GET_LAST_ERROR()); + if (res==-1) DEBUG(net, 1)("udp: broadcast error: %i",GET_LAST_ERROR()); i++; } @@ -1313,7 +1375,7 @@ bool NetworkUDPSearchGame(const byte ** _network_detected_serverip, unsigned sho NetworkGameListClear(); - DEBUG(misc,0) ("[NET][UDP] searching server"); + DEBUG(net, 0) ("[NET][UDP] searching server"); *_network_detected_serverip = "255.255.255.255"; *_network_detected_serverport = 0; @@ -1331,7 +1393,7 @@ bool NetworkUDPSearchGame(const byte ** _network_detected_serverip, unsigned sho *_network_detected_serverip=inet_ntoa(*(struct in_addr *) &item->ip); *_network_detected_serverport=item->port; timeout=-1; - DEBUG(misc,0) ("[NET][UDP] server found on %s", *_network_detected_serverip); + DEBUG(net, 0) ("[NET][UDP] server found on %s", *_network_detected_serverip); } } @@ -1352,7 +1414,7 @@ void NetworkIPListInit() { int i=0; gethostname(hostname,250); - DEBUG(misc,2) ("[NET][IP] init for host %s", hostname); + DEBUG(net, 2) ("[NET][IP] init for host %s", hostname); he=gethostbyname((char *) hostname); if (he == NULL) { @@ -1365,12 +1427,12 @@ void NetworkIPListInit() { } if (he == NULL) { - DEBUG(misc, 2) ("[NET][IP] cannot resolve %s", hostname); + DEBUG(net, 2) ("[NET][IP] cannot resolve %s", hostname); } else { while(he->h_addr_list[i]) { bcaddr = inet_addr(inet_ntoa(*(struct in_addr *) he->h_addr_list[i])); _network_ip_list[i]=bcaddr; - DEBUG(misc,2) ("[NET][IP] add %s",inet_ntoa(*(struct in_addr *) he->h_addr_list[i])); + DEBUG(net, 2) ("[NET][IP] add %s",inet_ntoa(*(struct in_addr *) he->h_addr_list[i])); i++; } @@ -1383,17 +1445,18 @@ void NetworkIPListInit() { void NetworkCoreInit() { -DEBUG(misc,3) ("[NET][Core] init()"); +DEBUG(net, 3) ("[NET][Core] init()"); _network_available=true; +_network_client_timeout=3000; // [win32] winsock startup #if defined(WIN32) { WSADATA wsa; - DEBUG(misc,3) ("[NET][Core] using windows socket library"); + DEBUG(net, 3) ("[NET][Core] using windows socket library"); if (WSAStartup(MAKEWORD(2,0), &wsa) != 0) { - DEBUG(misc,3) ("[NET][Core] error: WSAStartup failed"); + DEBUG(net, 3) ("[NET][Core] error: WSAStartup failed"); _network_available=false; } } @@ -1405,7 +1468,7 @@ _network_available=true; { DEBUG(misc,3) ("[NET][Core] using bsd socket library"); if (!(SocketBase = OpenLibrary("bsdsocket.library", 4))) { - DEBUG(misc,3) ("[NET][Core] Couldn't open bsdsocket.library version 4."); + DEBUG(net, 3) ("[NET][Core] Couldn't open bsdsocket.library version 4."); _network_available=false; } @@ -1416,7 +1479,7 @@ _network_available=true; if ( OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *) TimerRequest, 0) == 0 ) { if ( !(TimerBase = TimerRequest->tr_node.io_Device) ) { // free ressources... - DEBUG(misc,3) ("[NET][Core] Couldn't initialize timer."); + DEBUG(net, 3) ("[NET][Core] Couldn't initialize timer."); _network_available=false; } } @@ -1429,7 +1492,7 @@ _network_available=true; // [linux/macos] unix-socket startup - DEBUG(misc,3) ("[NET][Core] using unix socket library"); + DEBUG(net, 3) ("[NET][Core] using unix socket library"); #endif @@ -1437,12 +1500,13 @@ _network_available=true; if (_network_available) { - DEBUG(misc,3) ("[NET][Core] OK: multiplayer available"); + DEBUG(net, 3) ("[NET][Core] OK: multiplayer available"); // initiate network ip list NetworkIPListInit(); IConsoleCmdRegister("connect",NetworkConsoleCmdConnect); + IConsoleVarRegister("cfg_client_timeout",&_network_client_timeout,ICONSOLE_VAR_UINT16); } else { - DEBUG(misc,3) ("[NET][Core] FAILED: multiplayer not available"); + DEBUG(net, 3) ("[NET][Core] FAILED: multiplayer not available"); } } @@ -1450,7 +1514,7 @@ if (_network_available) { void NetworkCoreShutdown() { -DEBUG(misc,3) ("[NET][Core] shutdown()"); +DEBUG(net, 3) ("[NET][Core] shutdown()"); #if defined(__MORPHOS__) || defined(__AMIGA__) { @@ -1564,6 +1628,13 @@ if (incomming) { // outgoing + if ((_networking) && (!_networking_server) && (_frame_counter+1 >= _frame_counter_max)) { + // send the "i" am ready message to the server + // one frame before "i" reach the frame-limit + NetworkSendReadyPacket(); + } + + if (_networking) { NetworkSend(); } @@ -1573,12 +1644,12 @@ if (incomming) { } void NetworkLobbyInit() { - DEBUG(misc,3) ("[NET][Lobby] init()"); + DEBUG(net, 3) ("[NET][Lobby] init()"); NetworkUDPListen(true); } void NetworkLobbyShutdown() { - DEBUG(misc,3) ("[NET][Lobby] shutdown()"); + DEBUG(net, 3) ("[NET][Lobby] shutdown()"); NetworkUDPClose(true); } @@ -1591,7 +1662,7 @@ void NetworkGameListClear() { NetworkGameList * item; NetworkGameList * next; -DEBUG(misc,4) ("[NET][G-List] cleared server list"); +DEBUG(net, 4) ("[NET][G-List] cleared server list"); item = _network_game_list; while (item != NULL) { @@ -1607,7 +1678,7 @@ char * NetworkGameListAdd() { NetworkGameList * item; NetworkGameList * before; -DEBUG(misc,4) ("[NET][G-List] added server to list"); +DEBUG(net, 4) ("[NET][G-List] added server to list"); item = _network_game_list; before = item; @@ -1628,7 +1699,7 @@ return (char *) item; void NetworkGameListFromLAN() { struct UDPPacket packet; - DEBUG(misc,2) ("[NET][G-List] searching server over lan"); + DEBUG(net, 2) ("[NET][G-List] searching server over lan"); NetworkGameListClear(); packet.command_check=packet.command_code=NET_UDPCMD_SERVERSEARCH; packet.data_len=0; @@ -1636,7 +1707,7 @@ void NetworkGameListFromLAN() { } void NetworkGameListFromInternet() { - DEBUG(misc,2) ("[NET][G-List] searching servers over internet"); + DEBUG(net, 2) ("[NET][G-List] searching servers over internet"); NetworkGameListClear(); // **TODO** masterserver communication [internet protocol list] @@ -1669,7 +1740,7 @@ void NetworkGameFillDefaults() { extern char _openttd_revision[]; #endif - DEBUG(misc,4) ("[NET][G-Info] setting defaults"); + DEBUG(net, 4) ("[NET][G-Info] setting defaults"); ttd_strlcpy(game->server_name,"OpenTTD Game",13); game->game_password[0]='\0'; @@ -432,6 +432,7 @@ void SetDebugString(const char *s) _debug_misc_level = v; _debug_grf_level = v; _debug_ai_level = v; + _debug_net_level = v; } // individual levels @@ -449,6 +450,7 @@ void SetDebugString(const char *s) else if IS_LVL("spritecache") p = &_debug_spritecache_level; else if IS_LVL("grf") p = &_debug_grf_level; else if IS_LVL("ai") p = &_debug_ai_level; + else if IS_LVL("net") p = &_debug_net_level; else { ShowInfoF("Unknown debug level '%.*s'", s-t, t); return; @@ -881,6 +883,7 @@ void StateGameLoop() // store the random seed to be able to detect out of sync errors _sync_seed_1 = _random_seed_1; _sync_seed_2 = _random_seed_2; + if (_networking) disable_computer=true; if (_savedump_path[0] && (uint)_frame_counter >= _savedump_first && (uint)(_frame_counter -_savedump_first) % _savedump_freq == 0 ) { char buf[100]; @@ -993,7 +996,7 @@ void GameLoop() if (_frame_counter < _frame_counter_max) { StateGameLoop(); NetworkProcessCommands(); - } + } } else { if (!_pause) StateGameLoop(); diff --git a/variables.h b/variables.h index d4f3c91b3..f34571460 100644 --- a/variables.h +++ b/variables.h @@ -442,6 +442,7 @@ VARDEF int _debug_spritecache_level; VARDEF int _debug_misc_level; VARDEF int _debug_grf_level; VARDEF int _debug_ai_level; +VARDEF int _debug_net_level; void CDECL debug(const char *s, ...); #ifdef NO_DEBUG_MESSAGES |