network_udp.c
changeset 4077 d4d440dd8925
parent 4035 e3280e6deef7
child 4261 28670f743746
equal deleted inserted replaced
4076:a6650b616430 4077:d4d440dd8925
   139 
   139 
   140 			if (item->info.hostname[0] == '\0')
   140 			if (item->info.hostname[0] == '\0')
   141 				snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", inet_ntoa(client_addr->sin_addr));
   141 				snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", inet_ntoa(client_addr->sin_addr));
   142 
   142 
   143 			/* Check if we are allowed on this server based on the revision-match */
   143 			/* Check if we are allowed on this server based on the revision-match */
   144 			item->info.compatible = (
   144 			item->info.compatible =
   145 			strcmp(item->info.server_revision, _openttd_revision) == 0 ||
   145 				strcmp(item->info.server_revision, _openttd_revision) == 0 ||
   146 			strcmp(item->info.server_revision, NOREV_STRING) == 0) ? true : false;
   146 				strcmp(item->info.server_revision, NOREV_STRING) == 0;
   147 
       
   148 			break;
   147 			break;
   149 	}
   148 	}
   150 
   149 
   151 	item->online = true;
   150 	item->online = true;
   152 
   151 
   161 	Player *player;
   160 	Player *player;
   162 	byte current = 0;
   161 	byte current = 0;
   163 	int i;
   162 	int i;
   164 
   163 
   165 	// Just a fail-safe.. should never happen
   164 	// Just a fail-safe.. should never happen
   166 	if (!_network_udp_server)
   165 	if (!_network_udp_server) return;
   167 		return;
       
   168 
   166 
   169 	packet = NetworkSend_Init(PACKET_UDP_SERVER_DETAIL_INFO);
   167 	packet = NetworkSend_Init(PACKET_UDP_SERVER_DETAIL_INFO);
   170 
   168 
   171 	/* Send the amount of active companies */
   169 	/* Send the amount of active companies */
   172 	NetworkSend_uint8 (packet, NETWORK_COMPANY_INFO_VERSION);
   170 	NetworkSend_uint8 (packet, NETWORK_COMPANY_INFO_VERSION);
   176 	NetworkPopulateCompanyInfo();
   174 	NetworkPopulateCompanyInfo();
   177 
   175 
   178 	/* Go through all the players */
   176 	/* Go through all the players */
   179 	FOR_ALL_PLAYERS(player) {
   177 	FOR_ALL_PLAYERS(player) {
   180 		/* Skip non-active players */
   178 		/* Skip non-active players */
   181 		if (!player->is_active)
   179 		if (!player->is_active) continue;
   182 			continue;
       
   183 
   180 
   184 		current++;
   181 		current++;
   185 
   182 
   186 		/* Send the information */
   183 		/* Send the information */
   187 		NetworkSend_uint8 (packet, current);
   184 		NetworkSend_uint8(packet, current);
   188 
   185 
   189 		NetworkSend_string(packet, _network_player_info[player->index].company_name);
   186 		NetworkSend_string(packet, _network_player_info[player->index].company_name);
   190 		NetworkSend_uint8 (packet, _network_player_info[player->index].inaugurated_year);
   187 		NetworkSend_uint8 (packet, _network_player_info[player->index].inaugurated_year);
   191 		NetworkSend_uint64(packet, _network_player_info[player->index].company_value);
   188 		NetworkSend_uint64(packet, _network_player_info[player->index].company_value);
   192 		NetworkSend_uint64(packet, _network_player_info[player->index].money);
   189 		NetworkSend_uint64(packet, _network_player_info[player->index].money);
   193 		NetworkSend_uint64(packet, _network_player_info[player->index].income);
   190 		NetworkSend_uint64(packet, _network_player_info[player->index].income);
   194 		NetworkSend_uint16(packet, _network_player_info[player->index].performance);
   191 		NetworkSend_uint16(packet, _network_player_info[player->index].performance);
   195 
   192 
   196                 /* Send 1 if there is a passord for the company else send 0 */
   193 		/* Send 1 if there is a passord for the company else send 0 */
   197 		if (_network_player_info[player->index].password[0] != '\0') {
   194 		if (_network_player_info[player->index].password[0] != '\0') {
   198 			NetworkSend_uint8 (packet, 1);
   195 			NetworkSend_uint8(packet, 1);
   199 		} else {
   196 		} else {
   200 			NetworkSend_uint8 (packet, 0);
   197 			NetworkSend_uint8(packet, 0);
   201 		}
   198 		}
   202 
   199 
   203 		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
   200 		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
   204 			NetworkSend_uint16(packet, _network_player_info[player->index].num_vehicle[i]);
   201 			NetworkSend_uint16(packet, _network_player_info[player->index].num_vehicle[i]);
   205 
   202 
   207 			NetworkSend_uint16(packet, _network_player_info[player->index].num_station[i]);
   204 			NetworkSend_uint16(packet, _network_player_info[player->index].num_station[i]);
   208 
   205 
   209 		/* Find the clients that are connected to this player */
   206 		/* Find the clients that are connected to this player */
   210 		FOR_ALL_CLIENTS(cs) {
   207 		FOR_ALL_CLIENTS(cs) {
   211 			ci = DEREF_CLIENT_INFO(cs);
   208 			ci = DEREF_CLIENT_INFO(cs);
   212 			if ((ci->client_playas - 1) == player->index) {
   209 			if (ci->client_playas - 1 == player->index) {
   213 				/* The uint8 == 1 indicates that a client is following */
   210 				/* The uint8 == 1 indicates that a client is following */
   214 				NetworkSend_uint8(packet, 1);
   211 				NetworkSend_uint8(packet, 1);
   215 				NetworkSend_string(packet, ci->client_name);
   212 				NetworkSend_string(packet, ci->client_name);
   216 				NetworkSend_string(packet, ci->unique_id);
   213 				NetworkSend_string(packet, ci->unique_id);
   217 				NetworkSend_uint16(packet, ci->join_date);
   214 				NetworkSend_uint16(packet, ci->join_date);
   218 			}
   215 			}
   219 		}
   216 		}
   220 		/* Also check for the server itself */
   217 		/* Also check for the server itself */
   221 		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
   218 		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
   222 		if ((ci->client_playas - 1) == player->index) {
   219 		if (ci->client_playas - 1 == player->index) {
   223 			/* The uint8 == 1 indicates that a client is following */
   220 			/* The uint8 == 1 indicates that a client is following */
   224 			NetworkSend_uint8(packet, 1);
   221 			NetworkSend_uint8(packet, 1);
   225 			NetworkSend_string(packet, ci->client_name);
   222 			NetworkSend_string(packet, ci->client_name);
   226 			NetworkSend_string(packet, ci->unique_id);
   223 			NetworkSend_string(packet, ci->unique_id);
   227 			NetworkSend_uint16(packet, ci->join_date);
   224 			NetworkSend_uint16(packet, ci->join_date);
   232 	}
   229 	}
   233 
   230 
   234 	/* And check if we have any spectators */
   231 	/* And check if we have any spectators */
   235 	FOR_ALL_CLIENTS(cs) {
   232 	FOR_ALL_CLIENTS(cs) {
   236 		ci = DEREF_CLIENT_INFO(cs);
   233 		ci = DEREF_CLIENT_INFO(cs);
   237 		if ((ci->client_playas - 1) > MAX_PLAYERS) {
   234 		if (ci->client_playas - 1 > MAX_PLAYERS) {
   238 			/* The uint8 == 1 indicates that a client is following */
   235 			/* The uint8 == 1 indicates that a client is following */
   239 			NetworkSend_uint8(packet, 1);
   236 			NetworkSend_uint8(packet, 1);
   240 			NetworkSend_string(packet, ci->client_name);
   237 			NetworkSend_string(packet, ci->client_name);
   241 			NetworkSend_string(packet, ci->unique_id);
   238 			NetworkSend_string(packet, ci->unique_id);
   242 			NetworkSend_uint16(packet, ci->join_date);
   239 			NetworkSend_uint16(packet, ci->join_date);
   243 		}
   240 		}
   244 	}
   241 	}
   245 	/* Also check for the server itself */
   242 	/* Also check for the server itself */
   246 	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
   243 	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
   247 	if ((ci->client_playas - 1) > MAX_PLAYERS) {
   244 	if (ci->client_playas - 1 > MAX_PLAYERS) {
   248 		/* The uint8 == 1 indicates that a client is following */
   245 		/* The uint8 == 1 indicates that a client is following */
   249 		NetworkSend_uint8(packet, 1);
   246 		NetworkSend_uint8(packet, 1);
   250 		NetworkSend_string(packet, ci->client_name);
   247 		NetworkSend_string(packet, ci->client_name);
   251 		NetworkSend_string(packet, ci->unique_id);
   248 		NetworkSend_string(packet, ci->unique_id);
   252 		NetworkSend_uint16(packet, ci->join_date);
   249 		NetworkSend_uint16(packet, ci->join_date);
   258 	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
   255 	NetworkSendUDP_Packet(_udp_server_socket, packet, client_addr);
   259 
   256 
   260 	free(packet);
   257 	free(packet);
   261 }
   258 }
   262 
   259 
   263 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST) {
   260 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_RESPONSE_LIST)
       
   261 {
   264 	int i;
   262 	int i;
   265 	struct in_addr ip;
   263 	struct in_addr ip;
   266 	uint16 port;
   264 	uint16 port;
   267 	uint8 ver;
   265 	uint8 ver;
   268 
   266 
   284 			NetworkUDPQueryServer(inet_ntoa(ip), port);
   282 			NetworkUDPQueryServer(inet_ntoa(ip), port);
   285 		}
   283 		}
   286 	}
   284 	}
   287 }
   285 }
   288 
   286 
   289 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER) {
   287 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_MASTER_ACK_REGISTER)
       
   288 {
   290 	_network_advertise_retries = 0;
   289 	_network_advertise_retries = 0;
   291 	DEBUG(net, 2)("[NET][UDP] We are advertised on the master-server!");
   290 	DEBUG(net, 2)("[NET][UDP] We are advertised on the master-server!");
   292 
   291 
   293 	if (!_network_advertise)
   292 	if (!_network_advertise) {
   294 		/* We are advertised, but we don't want to! */
   293 		/* We are advertised, but we don't want to! */
   295 		NetworkUDPRemoveAdvertise();
   294 		NetworkUDPRemoveAdvertise();
       
   295 	}
   296 }
   296 }
   297 
   297 
   298 
   298 
   299 // The layout for the receive-functions by UDP
   299 // The layout for the receive-functions by UDP
   300 typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
   300 typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
   438 	int nbytes;
   438 	int nbytes;
   439 	static Packet *p = NULL;
   439 	static Packet *p = NULL;
   440 	int packet_len;
   440 	int packet_len;
   441 
   441 
   442 	// If p is NULL, malloc him.. this prevents unneeded mallocs
   442 	// If p is NULL, malloc him.. this prevents unneeded mallocs
   443 	if (p == NULL)
   443 	if (p == NULL) p = malloc(sizeof(*p));
   444 		p = malloc(sizeof(Packet));
       
   445 
   444 
   446 	packet_len = sizeof(p->buffer);
   445 	packet_len = sizeof(p->buffer);
   447 	client_len = sizeof(client_addr);
   446 	client_len = sizeof(client_addr);
   448 
   447 
   449 	// Try to receive anything
   448 	// Try to receive anything
   468 }
   467 }
   469 
   468 
   470 // Broadcast to all ips
   469 // Broadcast to all ips
   471 static void NetworkUDPBroadCast(SOCKET udp)
   470 static void NetworkUDPBroadCast(SOCKET udp)
   472 {
   471 {
   473 	int i;
   472 	Packet* p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
   474 	struct sockaddr_in out_addr;
   473 	uint i;
   475 	Packet *p;
   474 
   476 
   475 	for (i = 0; _broadcast_list[i] != 0; i++) {
   477 	// Init the packet
   476 		struct sockaddr_in out_addr;
   478 	p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
   477 
   479 
       
   480 	i = 0;
       
   481 	while (_broadcast_list[i] != 0) {
       
   482 		out_addr.sin_family = AF_INET;
   478 		out_addr.sin_family = AF_INET;
   483 		out_addr.sin_port = htons(_network_server_port);
   479 		out_addr.sin_port = htons(_network_server_port);
   484 		out_addr.sin_addr.s_addr = _broadcast_list[i];
   480 		out_addr.sin_addr.s_addr = _broadcast_list[i];
   485 
   481 
   486 		DEBUG(net, 6)("[NET][UDP] Broadcasting to %s", inet_ntoa(out_addr.sin_addr));
   482 		DEBUG(net, 6)("[NET][UDP] Broadcasting to %s", inet_ntoa(out_addr.sin_addr));
   487 
   483 
   488 		NetworkSendUDP_Packet(udp, p, &out_addr);
   484 		NetworkSendUDP_Packet(udp, p, &out_addr);
   489 
       
   490 		i++;
       
   491 	}
   485 	}
   492 
   486 
   493 	free(p);
   487 	free(p);
   494 }
   488 }
   495 
   489