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