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 |