network.c
changeset 172 8d8b3383470d
parent 169 4081f1d1f393
child 173 df7c566d219f
equal deleted inserted replaced
171:29854f28b90b 172:8d8b3383470d
   219 static size_t _transmit_file_size;
   219 static size_t _transmit_file_size;
   220 
   220 
   221 static FILE *_recv_file;
   221 static FILE *_recv_file;
   222 
   222 
   223 typedef struct NetworkGameInfo {	
   223 typedef struct NetworkGameInfo {	
   224 	char server_name[40]; // name of the game
   224 	char server_name[40];			// name of the game
   225 	char server_revision[8]; // server game version
   225 	char server_revision[8];	// server game version
   226 	byte server_lang; // langid
   226 	byte server_lang;					// langid
   227 	byte players_max; // max players allowed on server
   227 	byte players_max;					// max players allowed on server
   228 	byte players_on; // current count of players on server
   228 	byte players_on;					// current count of players on server
   229 	uint16 game_date; // current date
   229 	uint16 game_date;					// current date
   230 	char game_password[10]; // should fit ... 14 chars
   230 	char game_password[10];		// should fit ... 10 chars
   231 	char map_name[40]; // map which is played ["random" for a randomized map]
   231 	char map_name[40];				// map which is played ["random" for a randomized map]
   232 	uint map_width; // map width / 8
   232 	uint map_width;						// map width / 8
   233 	uint map_height; // map height / 8
   233 	uint map_height;					// map height / 8
   234 	byte map_set; // graphical set
   234 	byte map_set;							// graphical set
   235 } NetworkGameInfo;
   235 } NetworkGameInfo;
   236 
   236 
   237 typedef struct NetworkGameList {
   237 typedef struct NetworkGameList {
   238 	NetworkGameInfo item;
   238 	NetworkGameInfo item;
   239 	uint32 ip;
   239 	uint32 ip;
   277 }
   277 }
   278 
   278 
   279 //////////////////////////////////////////////////////////////////////
   279 //////////////////////////////////////////////////////////////////////
   280 
   280 
   281 // ****************************** //
   281 // ****************************** //
       
   282 // * Network Error Handlers     * //
       
   283 // ****************************** //
       
   284 
       
   285 static void NetworkHandleSaveGameError() {
       
   286 		_networking_sync = false;
       
   287 		_networking_queuing = true;
       
   288 		_switch_mode = SM_MENU;
       
   289 		_switch_mode_errorstr = STR_NETWORK_ERR_SAVEGAMEERROR;
       
   290 }
       
   291 
       
   292 static void NetworkHandleConnectionLost() {
       
   293 		_networking_sync = false;
       
   294 		_networking_queuing = true;
       
   295 		_switch_mode = SM_MENU;
       
   296 		_switch_mode_errorstr = STR_NETWORK_ERR_LOSTCONNECTION;
       
   297 }
       
   298 static void NetworkHandleDeSync() {
       
   299 	printf("fatal error: network sync error at frame %i\n",_frame_counter);
       
   300 		{
       
   301 			int i;
       
   302 			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]);
       
   303 			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]);
       
   304 		}
       
   305 		_networking_sync = false;
       
   306 		_networking_queuing = true;
       
   307 		_switch_mode = SM_MENU;
       
   308 		_switch_mode_errorstr = STR_NETWORK_ERR_DESYNC;
       
   309 }
       
   310 
       
   311 // ****************************** //
   282 // * TCP Packets and Handlers   * //
   312 // * TCP Packets and Handlers   * //
   283 // ****************************** //
   313 // ****************************** //
   284 
   314 
   285 static QueuedCommand *AllocQueuedCommand(CommandQueue *nq)
   315 static QueuedCommand *AllocQueuedCommand(CommandQueue *nq)
   286 {
   316 {
   324 		_my_seed_list[_frame_counter & 15][1] = _sync_seed_2;
   354 		_my_seed_list[_frame_counter & 15][1] = _sync_seed_2;
   325 
   355 
   326 		while (_num_future_seed) {
   356 		while (_num_future_seed) {
   327 			assert(_future_seed[0].frame >= _frame_counter);
   357 			assert(_future_seed[0].frame >= _frame_counter);
   328 			if (_future_seed[0].frame != _frame_counter) break;
   358 			if (_future_seed[0].frame != _frame_counter) break;
   329 			if (_future_seed[0].seed[0] != _sync_seed_1 ||_future_seed[0].seed[1] != _sync_seed_2)
   359 			if (_future_seed[0].seed[0] != _sync_seed_1 ||_future_seed[0].seed[1] != _sync_seed_2) NetworkHandleDeSync();
   330 				error("!network sync error");
       
   331 			memcpy_overlapping(_future_seed, _future_seed + 1, --_num_future_seed * sizeof(FutureSeeds));
   360 			memcpy_overlapping(_future_seed, _future_seed + 1, --_num_future_seed * sizeof(FutureSeeds));
   332 		}
   361 		}
   333 	}
   362 	}
   334 }
   363 }
   335 
   364 
   492 
   521 
   493 	if (_frame_counter_srv <= _frame_counter) {
   522 	if (_frame_counter_srv <= _frame_counter) {
   494 		// we are ahead of the server check if the seed is in our list.
   523 		// we are ahead of the server check if the seed is in our list.
   495 		if (_frame_counter_srv + 16 > _frame_counter) {
   524 		if (_frame_counter_srv + 16 > _frame_counter) {
   496 			// the random seed exists in our array check it.
   525 			// the random seed exists in our array check it.
   497 			if (s1 != _my_seed_list[_frame_counter_srv & 0xF][0] || s2 != _my_seed_list[_frame_counter_srv & 0xF][1])
   526 			if (s1 != _my_seed_list[_frame_counter_srv & 0xF][0] || s2 != _my_seed_list[_frame_counter_srv & 0xF][1]) NetworkHandleDeSync();
   498 				error("!network is desynched\n");
       
   499 		}
   527 		}
   500 	} else {
   528 	} else {
   501 		// the server's frame has not been executed yet. store the server's seed in a list.
   529 		// the server's frame has not been executed yet. store the server's seed in a list.
   502 		if (_num_future_seed < lengthof(_future_seed)) {
   530 		if (_num_future_seed < lengthof(_future_seed)) {
   503 			_future_seed[_num_future_seed].frame = _frame_counter_srv;
   531 			_future_seed[_num_future_seed].frame = _frame_counter_srv;
   535 		// eof
   563 		// eof
   536 		if (_recv_file) { fclose(_recv_file); _recv_file = NULL; }
   564 		if (_recv_file) { fclose(_recv_file); _recv_file = NULL; }
   537 
   565 
   538 		// attempt loading the game.
   566 		// attempt loading the game.
   539 		_game_mode = GM_NORMAL;
   567 		_game_mode = GM_NORMAL;
   540 		if (SaveOrLoad("networkc.tmp", SL_LOAD) != SL_OK) error("network load failed");
   568 		if (SaveOrLoad("networkc.tmp", SL_LOAD) != SL_OK) {
   541 
   569 				NetworkCoreDisconnect();
       
   570 				NetworkHandleSaveGameError();
       
   571 				return;
       
   572 				}
   542 		// sync to server.
   573 		// sync to server.
   543 		_networking_queuing = false;
   574 		_networking_queuing = false;
   544 		NetworkStartSync(false);
   575 		NetworkStartSync(false);
   545 /*		
       
   546 		_networking_sync = true;
       
   547 		_frame_counter = 0; // start executing at frame 0.
       
   548 		_sync_seed_1 = _sync_seed_2 = 0;
       
   549 		_num_future_seed = 0;
       
   550 		memset(_my_seed_list, 0, sizeof(_my_seed_list)); */
       
   551 
   576 
   552 		if (_network_playas == 0) {
   577 		if (_network_playas == 0) {
   553 			// send a command to make a new player
   578 			// send a command to make a new player
   554 			_local_player = 0;
   579 			_local_player = 0;
   555 			NetworkSendCommand(0, 0, 0, CMD_PLAYER_CTRL, NULL);
   580 			NetworkSendCommand(0, 0, 0, CMD_PLAYER_CTRL, NULL);
   975 #if !defined(__MORPHOS__) && !defined(__AMIGA__)
  1000 #if !defined(__MORPHOS__) && !defined(__AMIGA__)
   976 	n = select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv);
  1001 	n = select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv);
   977 #else
  1002 #else
   978 	n = WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL);
  1003 	n = WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL);
   979 #endif
  1004 #endif
   980 	if (n == -1) error("select failed");
  1005 	if (n == -1) NetworkHandleConnectionLost();
   981 
  1006 
   982 	// accept clients..
  1007 	// accept clients..
   983 	if (_networking_server && FD_ISSET(_listensocket, &read_fd))
  1008 	if (_networking_server && FD_ISSET(_listensocket, &read_fd))
   984 		NetworkAcceptClients();
  1009 		NetworkAcceptClients();
   985 
  1010 
  1256 		if (client) { out_addr.sin_port = htons(_network_server_port); } else { out_addr.sin_port = htons(_network_client_port); };
  1281 		if (client) { out_addr.sin_port = htons(_network_server_port); } else { out_addr.sin_port = htons(_network_client_port); };
  1257 		bcptr = (byte *) &bcaddr;
  1282 		bcptr = (byte *) &bcaddr;
  1258 		bcptr[3]=255;
  1283 		bcptr[3]=255;
  1259 		out_addr.sin_addr.s_addr = bcaddr;
  1284 		out_addr.sin_addr.s_addr = bcaddr;
  1260 		res=sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &out_addr,sizeof(out_addr));
  1285 		res=sendto(udp,(char *) &packet,sizeof(packet),0,(struct sockaddr *) &out_addr,sizeof(out_addr));
  1261 		if (res==-1) error("udp: broadcast error: %i",GET_LAST_ERROR());
  1286 		if (res==-1) DEBUG(misc,1)("udp: broadcast error: %i",GET_LAST_ERROR());
  1262 		i++;
  1287 		i++;
  1263 	}
  1288 	}
  1264 	
  1289 	
  1265 }
  1290 }
  1266 
  1291 
  1444 	if (!_network_available) return false;
  1469 	if (!_network_available) return false;
  1445 
  1470 
  1446 	if (strcmp((char *) b,"auto")==0) {
  1471 	if (strcmp((char *) b,"auto")==0) {
  1447 		// do autodetect
  1472 		// do autodetect
  1448 		NetworkUDPSearchGame(&b, &port);
  1473 		NetworkUDPSearchGame(&b, &port);
  1449 		}
  1474 	}
  1450 
  1475 
  1451 	if (port==0) {
  1476 	if (port==0) {
  1452 		// autodetection failed
  1477 		// autodetection failed
  1453 		if (_networking_override) NetworkLobbyShutdown();
  1478 		if (_networking_override) NetworkLobbyShutdown();
  1454 		ShowErrorMessage(-1, STR_NETWORK_ERR_NOSERVER, 0, 0);
  1479 		ShowErrorMessage(-1, STR_NETWORK_ERR_NOSERVER, 0, 0);
       
  1480 		_switch_mode_errorstr = STR_NETWORK_ERR_NOSERVER;
  1455 		return false;
  1481 		return false;
  1456 		}
  1482 	}
       
  1483 
  1457 	NetworkInitialize();
  1484 	NetworkInitialize();
  1458 	_networking = NetworkConnect(b, port);
  1485 	_networking = NetworkConnect(b, port);
  1459 	if (_networking) {
  1486 	if (_networking) {
  1460 		NetworkLobbyShutdown();
  1487 		NetworkLobbyShutdown();
  1461 		} else {
  1488 	} else {
  1462 		if (_networking_override) NetworkLobbyShutdown();
  1489 		if (_networking_override) 
       
  1490 			NetworkLobbyShutdown();
       
  1491 		
  1463 		ShowErrorMessage(-1, STR_NETWORK_ERR_NOCONNECTION,0,0);
  1492 		ShowErrorMessage(-1, STR_NETWORK_ERR_NOCONNECTION,0,0);
  1464 		}
  1493 		_switch_mode_errorstr = STR_NETWORK_ERR_NOCONNECTION;
       
  1494 	}
  1465 	return _networking;
  1495 	return _networking;
  1466 }
  1496 }
  1467 
  1497 
  1468 /* *************************************************** */
  1498 /* *************************************************** */
  1469 
  1499