network_udp.c
changeset 638 cb9f5f50d3c7
parent 629 4bb1f0fb0109
child 668 1fe298df8526
equal deleted inserted replaced
637:d3c50c368bb3 638:cb9f5f50d3c7
     4 #ifdef ENABLE_NETWORK
     4 #ifdef ENABLE_NETWORK
     5 
     5 
     6 #include "network_gamelist.h"
     6 #include "network_gamelist.h"
     7 
     7 
     8 extern void UpdateNetworkGameWindow(bool unselect);
     8 extern void UpdateNetworkGameWindow(bool unselect);
       
     9 extern void NetworkPopulateCompanyInfo(void);
     9 
    10 
    10 //
    11 //
    11 // This file handles all the LAN-stuff
    12 // This file handles all the LAN-stuff
    12 // Stuff like:
    13 // Stuff like:
    13 //   - UDP search over the network
    14 //   - UDP search over the network
    14 //
    15 //
    15 
    16 
    16 typedef enum {
    17 typedef enum {
    17 	PACKET_UDP_FIND_SERVER,
    18 	PACKET_UDP_CLIENT_FIND_SERVER,
    18 	PACKET_UDP_SERVER_RESPONSE,
    19 	PACKET_UDP_SERVER_RESPONSE,
       
    20 	PACKET_UDP_CLIENT_DETAIL_INFO,
       
    21 	PACKET_UDP_SERVER_DETAIL_INFO, // Is not used in OpenTTD itself, only for external querying
    19 	PACKET_UDP_END
    22 	PACKET_UDP_END
    20 } PacketUDPType;
    23 } PacketUDPType;
    21 
    24 
    22 static SOCKET _udp_server_socket; // udp server socket
    25 static SOCKET _udp_server_socket; // udp server socket
    23 
    26 
    24 #define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
    27 #define DEF_UDP_RECEIVE_COMMAND(type) void NetworkPacketReceive_ ## type ## _command(Packet *p, struct sockaddr_in *client_addr)
    25 void NetworkSendUDP_Packet(Packet *p, struct sockaddr_in *recv);
    28 void NetworkSendUDP_Packet(Packet *p, struct sockaddr_in *recv);
    26 
    29 
    27 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_FIND_SERVER)
    30 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER)
    28 {
    31 {
    29 	Packet *packet;
    32 	Packet *packet;
    30 	// Just a fail-safe.. should never happen
    33 	// Just a fail-safe.. should never happen
    31 	if (!_network_udp_server)
    34 	if (!_network_udp_server)
    32 		return;
    35 		return;
    98 	item->online = true;
   101 	item->online = true;
    99 
   102 
   100 	UpdateNetworkGameWindow(false);
   103 	UpdateNetworkGameWindow(false);
   101 }
   104 }
   102 
   105 
       
   106 DEF_UDP_RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO)
       
   107 {
       
   108 	ClientState *cs;
       
   109 	NetworkClientInfo *ci;
       
   110 	Packet *packet;
       
   111 	Player *player;
       
   112 	byte active = 0;
       
   113 	byte current = 0;
       
   114 	int i;
       
   115 
       
   116 	// Just a fail-safe.. should never happen
       
   117 	if (!_network_udp_server)
       
   118 		return;
       
   119 
       
   120 	packet = NetworkSend_Init(PACKET_UDP_SERVER_DETAIL_INFO);
       
   121 
       
   122 	FOR_ALL_PLAYERS(player) {
       
   123 		if (player->is_active)
       
   124 			active++;
       
   125 	}
       
   126 
       
   127 	/* Send the amount of active companies */
       
   128 	NetworkSend_uint8 (packet, NETWORK_COMPANY_INFO_VERSION);
       
   129 	NetworkSend_uint8 (packet, active);
       
   130 
       
   131 	/* Fetch the latest version of everything */
       
   132 	NetworkPopulateCompanyInfo();
       
   133 
       
   134 	/* Go through all the players */
       
   135 	FOR_ALL_PLAYERS(player) {
       
   136 		/* Skip non-active players */
       
   137 		if (!player->is_active)
       
   138 			continue;
       
   139 
       
   140 		current++;
       
   141 
       
   142 		/* Send the information */
       
   143 		NetworkSend_uint8 (packet, current);
       
   144 
       
   145 		NetworkSend_string(packet, _network_player_info[player->index].company_name);
       
   146 		NetworkSend_uint8 (packet, _network_player_info[player->index].inaugurated_year);
       
   147 		NetworkSend_uint64(packet, _network_player_info[player->index].company_value);
       
   148 		NetworkSend_uint64(packet, _network_player_info[player->index].money);
       
   149 		NetworkSend_uint64(packet, _network_player_info[player->index].income);
       
   150 		NetworkSend_uint16(packet, _network_player_info[player->index].performance);
       
   151 
       
   152 		for (i = 0; i < NETWORK_VEHICLE_TYPES; i++)
       
   153 			NetworkSend_uint16(packet, _network_player_info[player->index].num_vehicle[i]);
       
   154 
       
   155 		for (i = 0; i < NETWORK_STATION_TYPES; i++)
       
   156 			NetworkSend_uint16(packet, _network_player_info[player->index].num_station[i]);
       
   157 
       
   158 		/* Find the clients that are connected to this player */
       
   159 		FOR_ALL_CLIENTS(cs) {
       
   160 			ci = DEREF_CLIENT_INFO(cs);
       
   161 			if ((ci->client_playas - 1) == player->index) {
       
   162 				/* The uint8 == 1 indicates that a client is following */
       
   163 				NetworkSend_uint8(packet, 1);
       
   164 				NetworkSend_string(packet, ci->client_name);
       
   165 				NetworkSend_string(packet, ci->unique_id);
       
   166 				NetworkSend_uint16(packet, ci->join_date);
       
   167 			}
       
   168 		}
       
   169 		/* Also check for the server itself */
       
   170 		ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
       
   171 		if ((ci->client_playas - 1) == player->index) {
       
   172 			/* The uint8 == 1 indicates that a client is following */
       
   173 			NetworkSend_uint8(packet, 1);
       
   174 			NetworkSend_string(packet, ci->client_name);
       
   175 			NetworkSend_string(packet, ci->unique_id);
       
   176 			NetworkSend_uint16(packet, ci->join_date);
       
   177 		}
       
   178 
       
   179 		/* Indicates end of client list */
       
   180 		NetworkSend_uint8(packet, 0);
       
   181 	}
       
   182 
       
   183 	/* And check if we have any spectators */
       
   184 	FOR_ALL_CLIENTS(cs) {
       
   185 		ci = DEREF_CLIENT_INFO(cs);
       
   186 		if ((ci->client_playas - 1) > MAX_PLAYERS) {
       
   187 			/* The uint8 == 1 indicates that a client is following */
       
   188 			NetworkSend_uint8(packet, 1);
       
   189 			NetworkSend_string(packet, ci->client_name);
       
   190 			NetworkSend_string(packet, ci->unique_id);
       
   191 			NetworkSend_uint16(packet, ci->join_date);
       
   192 		}
       
   193 	}
       
   194 	/* Also check for the server itself */
       
   195 	ci = NetworkFindClientInfoFromIndex(NETWORK_SERVER_INDEX);
       
   196 	if ((ci->client_playas - 1) > MAX_PLAYERS) {
       
   197 		/* The uint8 == 1 indicates that a client is following */
       
   198 		NetworkSend_uint8(packet, 1);
       
   199 		NetworkSend_string(packet, ci->client_name);
       
   200 		NetworkSend_string(packet, ci->unique_id);
       
   201 		NetworkSend_uint16(packet, ci->join_date);
       
   202 	}
       
   203 
       
   204 	/* Indicates end of client list */
       
   205 	NetworkSend_uint8(packet, 0);
       
   206 
       
   207 	NetworkSendUDP_Packet(packet, client_addr);
       
   208 
       
   209 	free(packet);
       
   210 }
       
   211 
   103 
   212 
   104 // The layout for the receive-functions by UDP
   213 // The layout for the receive-functions by UDP
   105 typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
   214 typedef void NetworkUDPPacket(Packet *p, struct sockaddr_in *client_addr);
   106 
   215 
   107 static NetworkUDPPacket* const _network_udp_packet[] = {
   216 static NetworkUDPPacket* const _network_udp_packet[] = {
   108 	RECEIVE_COMMAND(PACKET_UDP_FIND_SERVER),
   217 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_FIND_SERVER),
   109 	RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
   218 	RECEIVE_COMMAND(PACKET_UDP_SERVER_RESPONSE),
       
   219 	RECEIVE_COMMAND(PACKET_UDP_CLIENT_DETAIL_INFO),
       
   220 	NULL,
   110 };
   221 };
   111 
   222 
   112 // If this fails, check the array above with network_data.h
   223 // If this fails, check the array above with network_data.h
   113 assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
   224 assert_compile(lengthof(_network_udp_packet) == PACKET_UDP_END);
   114 
   225 
   277 	byte *bcptr;
   388 	byte *bcptr;
   278 	uint32 bcaddr;
   389 	uint32 bcaddr;
   279 	Packet *p;
   390 	Packet *p;
   280 
   391 
   281 	// Init the packet
   392 	// Init the packet
   282 	p = NetworkSend_Init(PACKET_UDP_FIND_SERVER);
   393 	p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
   283 
   394 
   284 	// Go through all the ips on this pc
   395 	// Go through all the ips on this pc
   285 	i = 0;
   396 	i = 0;
   286 	while (_network_ip_list[i] != 0) {
   397 	while (_network_ip_list[i] != 0) {
   287 		bcaddr = _network_ip_list[i];
   398 		bcaddr = _network_ip_list[i];
   345 	snprintf(item->info.server_name, sizeof(item->info.server_name), "%s", hostname);
   456 	snprintf(item->info.server_name, sizeof(item->info.server_name), "%s", hostname);
   346 	snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", hostname);
   457 	snprintf(item->info.hostname, sizeof(item->info.hostname), "%s", hostname);
   347 	item->online = false;
   458 	item->online = false;
   348 
   459 
   349 	// Init the packet
   460 	// Init the packet
   350 	p = NetworkSend_Init(PACKET_UDP_FIND_SERVER);
   461 	p = NetworkSend_Init(PACKET_UDP_CLIENT_FIND_SERVER);
   351 
   462 
   352 	NetworkSendUDP_Packet(p, &out_addr);
   463 	NetworkSendUDP_Packet(p, &out_addr);
   353 
   464 
   354 	free(p);
   465 	free(p);
   355 
   466