1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6
7 #include "servership.h"
8 #include "thread.h"
9 #include "serverdata.h"
10 #include "servergame.h"
11 #include "netdata.h"
12 #include "netconfig.h"
13 #include "mainplayerthread.h"
14
15
16 extern ServerShip *ServerShips[MAX_PLAYERS];
17
18
19 // Function to loop and continuously read all network data
ReadNetworkData()20 void ReadNetworkData()
21 {
22 int i, n, playernum, rc;
23 char readval[64];
24 int threadnum;
25 int keypress;
26 int WaitTime;
27 struct sockaddr_in PlayerIp;
28 #ifdef CYGWIN
29 int addrlen=16;
30 #else
31 socklen_t addrlen=16;
32 #endif
33 struct timezone tz;
34 struct timeval now;
35 KeyValuesStruct KeyValues;
36 GameParametersStruct GameParameters;
37
38 // Setup game parameters
39 GameParameters.MaxPlayers=htons(MaxPlayers);
40 GameParameters.WorldWidth=ServerWorldWidth;
41 GameParameters.MaxShield=htonl(ServerMaxShield);
42 GameParameters.MaxArmor=htonl(ServerMaxArmor);
43 if (MaxPlayers==1) {
44 GameParameters.GameType=htons(SINGLE_PLAYER);
45 } else {
46 GameParameters.GameType=htons(ServerGameType);
47 }
48
49 while (!StopServer) {
50 if ((n=recvfrom(listenfd, readval, 64, 0,
51 (struct sockaddr *)&PlayerIp, &addrlen)) <= 0) {
52 continue;
53 }
54 pthread_mutex_lock(&ServerLock);
55 #ifdef DEBUG
56 printf("Read Network Data Thread Awake\n");
57 #endif
58
59 // Check for status update packet
60 if (n==sizeof(KeyValuesStruct)) {
61 for (i=0; i<MAX_PLAYERS; i++) {
62 if (Connections[i].Connected) {
63 if (Connections[i].PlayerIp.sin_addr.s_addr==PlayerIp.sin_addr.s_addr &&
64 Connections[i].PlayerIp.sin_port==PlayerIp.sin_port) {
65 gettimeofday(&Connections[i].LastPacketTime, &tz);
66 memcpy(&KeyValues, readval, sizeof(KeyValuesStruct));
67 /*
68 if (KeyValues.xForwardKey && !KeyValues.xBackwardKey) {
69 ServerShips[i]->xAcceleration=1.0;
70 } else if (KeyValues.xBackwardKey && !KeyValues.xForwardKey) {
71 ServerShips[i]->xAcceleration=-1.0;
72 } else {
73 ServerShips[i]->xAcceleration=0.0;
74 }
75 if (KeyValues.yForwardKey && !KeyValues.yBackwardKey) {
76 ServerShips[i]->yAcceleration=1.0;
77 } else if (KeyValues.yBackwardKey && !KeyValues.yForwardKey) {
78 ServerShips[i]->yAcceleration=-1.0;
79 } else {
80 ServerShips[i]->yAcceleration=0.0;
81 }
82 */
83 if (KeyValues.zForwardKey && !KeyValues.zBackwardKey) {
84 ServerShips[i]->zAcceleration=3.0;
85 } else if (KeyValues.zBackwardKey && !KeyValues.zForwardKey) {
86 ServerShips[i]->zAcceleration=-1.0;
87 } else {
88 ServerShips[i]->zAcceleration=0.0;
89 }
90
91 if (KeyValues.xFRotateKey && !KeyValues.xBRotateKey) {
92 ServerShips[i]->Rotation.x=1.0;
93 } else if (KeyValues.xBRotateKey && !KeyValues.xFRotateKey) {
94 ServerShips[i]->Rotation.x=-1.0;
95 } else {
96 ServerShips[i]->Rotation.x=0.0;
97 }
98 if (KeyValues.yFRotateKey && !KeyValues.yBRotateKey) {
99 ServerShips[i]->Rotation.y=1.0;
100 } else if (KeyValues.yBRotateKey && !KeyValues.yFRotateKey) {
101 ServerShips[i]->Rotation.y=-1.0;
102 } else {
103 ServerShips[i]->Rotation.y=0.0;
104 }
105 if (KeyValues.zFRotateKey && !KeyValues.zBRotateKey) {
106 ServerShips[i]->Rotation.z=1.0;
107 } else if (KeyValues.zBRotateKey && !KeyValues.zFRotateKey) {
108 ServerShips[i]->Rotation.z=-1.0;
109 } else {
110 ServerShips[i]->Rotation.z=0.0;
111 }
112
113 ServerShips[i]->Action.shield=KeyValues.ShieldKey;
114 }
115 }
116 }
117 } else if (n==MAX_PLAYERNAME_LENGTH) {
118 // Check if player is already connected, if so delete them and reconnect
119 for (i=0; i<MAX_PLAYERS; i++) {
120 if (Connections[i].Connected) {
121 if (Connections[i].PlayerIp.sin_addr.s_addr==PlayerIp.sin_addr.s_addr &&
122 Connections[i].PlayerIp.sin_port==PlayerIp.sin_port) {
123 DeletePlayer(i);
124 }
125 }
126 }
127
128 if (NumConnectedPlayers==MaxPlayers) {
129 pthread_mutex_unlock(&ServerLock);
130 continue;
131 }
132
133 for (i=0; i<MAX_PLAYERS; i++) {
134 if (!Connections[i].Connected && !ServerShips[i]) {
135 // Send Game Parameters to player and connect them to the game
136 GameParameters.PlayerNum=htons(i);
137 if (sendto(listenfd, &GameParameters, sizeof(GameParametersStruct),
138 0, (struct sockaddr *)&PlayerIp, addrlen) < 0) {
139 printf("Write Error\n");
140 break;
141 }
142
143 memcpy(&Connections[i].PlayerIp, &PlayerIp,
144 sizeof(struct sockaddr_in));
145 gettimeofday(&Connections[i].LastPacketTime, &tz);
146 readval[MAX_PLAYERNAME_LENGTH-1]='\0';
147
148 // Spawn off a thread for the connected player
149 if (rc = pthread_create(&ServerThreads[i], NULL,
150 MainPlayerThread, (void *)i)) {
151 printf("ERROR, return code from pthread_create() is %d\n", rc);
152 exit(8);
153 }
154
155 struct Point Position, Rotation, Velocity;
156 CreateRandomPosition(&Position);
157 Rotation.x=0.0;
158 Rotation.y=0.0;
159 Rotation.z=0.0;
160 Velocity.x=0.0;
161 Velocity.y=0.0;
162 Velocity.z=0.0;
163 ServerShips[i]=new ServerShip(Position, Velocity, Rotation, SHIP_TYPE,
164 ShipSize, 1.0, i, readval);
165 break;
166 }
167 }
168 } else if (n==1) {
169 for (i=0; i<MAX_PLAYERS; i++) {
170 if (Connections[i].Connected) {
171 if (Connections[i].PlayerIp.sin_addr.s_addr==PlayerIp.sin_addr.s_addr &&
172 Connections[i].PlayerIp.sin_port==PlayerIp.sin_port) {
173 keypress=*readval/0x10;
174 if (*readval > 0x10) {
175 *readval-=0x10;
176 }
177
178 if (keypress) {
179 switch (*readval) {
180 case FIRE_KEY:
181 ServerShips[i]->Action.shooting=1;
182 break;
183 case WARP_KEY:
184 ServerShips[i]->WarpShip();
185 break;
186 case NUKE_KEY:
187 ServerShips[i]->FireNuke();
188 break;
189 case X_FORWARD_KEY:
190 ServerShips[i]->Accelerate(1, 1.0);
191 break;
192 case Y_FORWARD_KEY:
193 ServerShips[i]->Accelerate(2, 1.0);
194 break;
195 case Z_FORWARD_KEY:
196 ServerShips[i]->Accelerate(3, 3.0);
197 break;
198 case X_BACKWARD_KEY:
199 ServerShips[i]->Accelerate(1, -1.0);
200 break;
201 case Y_BACKWARD_KEY:
202 ServerShips[i]->Accelerate(2, -1.0);
203 break;
204 case Z_BACKWARD_KEY:
205 ServerShips[i]->Accelerate(3, -1.0);
206 break;
207 case X_FROTATE_KEY:
208 ServerShips[i]->Rotation.x+=1.0;
209 if (ServerShips[i]->Rotation.x > 1.0) {
210 ServerShips[i]->Rotation.x=1.0;
211 }
212 break;
213 case Y_FROTATE_KEY:
214 ServerShips[i]->Rotation.y+=1.0;
215 if (ServerShips[i]->Rotation.y > 1.0) {
216 ServerShips[i]->Rotation.y=1.0;
217 }
218 break;
219 case Z_FROTATE_KEY:
220 ServerShips[i]->Rotation.z+=1.0;
221 if (ServerShips[i]->Rotation.z > 1.0) {
222 ServerShips[i]->Rotation.z=1.0;
223 }
224 break;
225 case X_BROTATE_KEY:
226 ServerShips[i]->Rotation.x-=1.0;
227 if (ServerShips[i]->Rotation.x < -1.0) {
228 ServerShips[i]->Rotation.x=-1.0;
229 }
230 break;
231 case Y_BROTATE_KEY:
232 ServerShips[i]->Rotation.y-=1.0;
233 if (ServerShips[i]->Rotation.y < -1.0) {
234 ServerShips[i]->Rotation.y=-1.0;
235 }
236 break;
237 case Z_BROTATE_KEY:
238 ServerShips[i]->Rotation.z-=1.0;
239 if (ServerShips[i]->Rotation.z < -1.0) {
240 ServerShips[i]->Rotation.z=-1.0;
241 }
242 break;
243 case SHIELD_KEY:
244 ServerShips[i]->Action.shield=1;
245 break;
246 case ABORT_KEY:
247 if (MaxPlayers==1) {
248 StopServer=1;
249 }
250 if ((rc=sendto(listenfd, "\0", 1, 0,
251 (struct sockaddr *)&Connections[i].PlayerIp,
252 sizeof(struct sockaddr))) < 0) {
253 printf("write error\n");
254 }
255 DeletePlayer(i);
256 break;
257 }
258 } else {
259 switch (*readval) {
260 case X_FORWARD_KEY:
261 ServerShips[i]->Accelerate(1, 0.0);
262 break;
263 case Y_FORWARD_KEY:
264 ServerShips[i]->Accelerate(2, 0.0);
265 break;
266 case Z_FORWARD_KEY:
267 ServerShips[i]->Accelerate(3, 0.0);
268 break;
269 case X_BACKWARD_KEY:
270 ServerShips[i]->Accelerate(1, 0.0);
271 break;
272 case Y_BACKWARD_KEY:
273 ServerShips[i]->Accelerate(2, 0.0);
274 break;
275 case Z_BACKWARD_KEY:
276 ServerShips[i]->Accelerate(3, 0.0);
277 break;
278 case X_FROTATE_KEY:
279 ServerShips[i]->Rotation.x-=1.0;
280 if (ServerShips[i]->Rotation.x < -1.0) {
281 ServerShips[i]->Rotation.x=-1.0;
282 }
283 break;
284 case Y_FROTATE_KEY:
285 ServerShips[i]->Rotation.y-=1.0;
286 if (ServerShips[i]->Rotation.y < -1.0) {
287 ServerShips[i]->Rotation.y=-1.0;
288 }
289 break;
290 case Z_FROTATE_KEY:
291 ServerShips[i]->Rotation.z-=1.0;
292 if (ServerShips[i]->Rotation.z < -1.0) {
293 ServerShips[i]->Rotation.z=-1.0;
294 }
295 break;
296 case X_BROTATE_KEY:
297 ServerShips[i]->Rotation.x+=1.0;
298 if (ServerShips[i]->Rotation.x > 1.0) {
299 ServerShips[i]->Rotation.x=1.0;
300 }
301 break;
302 case Y_BROTATE_KEY:
303 ServerShips[i]->Rotation.y+=1.0;
304 if (ServerShips[i]->Rotation.y > 1.0) {
305 ServerShips[i]->Rotation.y=1.0;
306 }
307 break;
308 case Z_BROTATE_KEY:
309 ServerShips[i]->Rotation.z+=1.0;
310 if (ServerShips[i]->Rotation.z > 1.0) {
311 ServerShips[i]->Rotation.z=1.0;
312 }
313 break;
314 case SHIELD_KEY:
315 ServerShips[i]->Action.shield=0;
316 break;
317 }
318 }
319 break;
320 }
321 }
322 }
323 }
324
325 // Check if any players are timed out
326 gettimeofday(&now, &tz);
327 for (i=0; i<MAX_PLAYERS; i++) {
328 if (Connections[i].Connected) {
329 WaitTime=(now.tv_sec-Connections[i].LastPacketTime.tv_sec)*1000000+
330 (now.tv_usec-Connections[i].LastPacketTime.tv_usec);
331 // Check if a player hasn't responded for 10 seconds
332 if (WaitTime > 10000000) {
333 if (MaxPlayers==1) {
334 StopServer=1;
335 }
336 DeletePlayer(i);
337 }
338 }
339 }
340
341 #ifdef DEBUG
342 printf("Read Network Data Thread Sleeping\n");
343 #endif
344 pthread_mutex_unlock(&ServerLock);
345 }
346
347 close(listenfd);
348
349 ServerStarted=0;
350
351 pthread_exit(NULL);
352 }
353