1 /* $id:$ */
2 /* network commands and data */
3 
4 #include "basic.h"
5 #include "bomberclone.h"
6 #include "network.h"
7 #include "packets.h"
8 #include "chat.h"
9 #include "sound.h"
10 #include "menu.h"
11 
12 extern _point debug_field;
13 extern int debug_lastping;
14 
15 static short int pkg_lastid;    /* the packet id, this will only counted
16                                  * up nothing more.. if we are at 0x10000
17                                  * we will start at 0 */
18 
19 struct _resend_cache resend_cache;
20 struct _inpkg_index inpkg_index[PKG_IN_INDEX_NUM];
21 int inpkg_index_pos = 0;
22 
23 
24 /*
25  * help function to get the playernumber from the address.
26  * this function  does not indicate which player it is, this function only checks
27  * if the packet comed from a known player
28  */
get_player_nr(char * host,char * port)29 int get_player_nr (char *host, char *port) {
30     int i,
31       res;
32 
33     for (i = 0, res = -1; (i < MAX_PLAYERS && res == -1); i++) {
34         if (players[i].net.addr.host[0] != 0)
35             if ((strcmp (players[i].net.addr.host, host) == 0)
36                 && (strcmp (players[i].net.addr.port, port) == 0))
37                 res = i;
38     }
39     return res;
40 }
41 
42 
43 /*
44  * Packettype: error
45  */
send_error(_net_addr * addr,char * text)46 void send_error (_net_addr * addr, char *text) {
47     struct pkg_error p_err;
48 
49     d_printf ("Send Network Error : %s\n", text);
50     strncpy (p_err.text, text, 127);
51     p_err.h.typ = PKG_error;
52     p_err.h.flags = 0;
53     p_err.h.len = HTON16 (sizeof (struct pkg_error));
54     p_err.nr = 0;
55 
56     send_pkg ((struct pkg *) &p_err, addr);
57 };
58 
59 
do_error(struct pkg_error * data,_net_addr * addr)60 void do_error (struct pkg_error *data, _net_addr * addr) {
61     d_printf ("Network Error from %s:%s : '%s'\n", addr->host, addr->port, data->text);
62 
63 	/* check if the packet comes from the server, the server
64 	 * never gets errormessages from a client, if a client has
65 	 * some trouble the client will just disconnect */
66 	if (GT_MP_PTPS && addr->pl_nr == bman.p_servnr) {
67 		menu_displaymessage ("Network Error", "Got Error from: %s:%s\nMessage:%s", addr->host,
68                 addr->port, data->text);
69 		network_shutdown ();
70 	}
71 };
72 
73 
74 
75 /*
76  * Packettype: joingame
77  * client sends this to the server if he want's to join
78  *
79  * 1) check if this package comes from a already joined and known player
80  *    if so: just send the current playerlist back.
81  * else:
82  * 2) find free playerslot and add the player there
83  * 3) send to all players the new playerid
84  */
do_joingame(struct pkg_joingame * p_jg,_net_addr * addr)85 void do_joingame (struct pkg_joingame *p_jg, _net_addr * addr) {
86     _player *pl;
87     int i,
88       vma,
89       vmi,
90       vsu;
91     char text[255];
92 
93     d_printf ("do_joingame (From:%s:%s Player(name:%s) addr:%p\n", addr->host, addr->port, p_jg->name, addr);
94 
95     sscanf (VERSION, "%d.%d.%d", &vma, &vmi, &vsu);
96 
97     /* Do some basic checks befor we accept this data packet
98      * 1) check if we are a server */
99     if (GT_MP_PTPS) {
100         sprintf (text, "Sorry this is a client and not a server.");
101         send_error (addr, text);
102         return;
103     }
104     /* 2) check the version */
105     if (p_jg->ver_sub != vsu || p_jg->ver_major != vma || p_jg->ver_minor != vmi) {
106         sprintf (text, "Version Error - Host/Server Version: %s", VERSION);
107         send_error (addr, text);
108         return;
109     }
110 
111     /* 3) check if we have a password */
112     d_printf ("Password Check Server:\"%s\" Client:\"%s\"   %d, %d\n", bman.password,
113               p_jg->password, strlen (bman.password), strlen (p_jg->password));
114     if (bman.passwordenabled && (strncmp (bman.password, p_jg->password, LEN_PASSWORD)
115                                  || strlen (bman.password) != strlen (p_jg->password))) {
116         send_error (addr, "This game is Password protected. Your Password is wrong.");
117         return;
118     }
119 
120     /* find a free place for the player and add the player to the game */
121     if (GS_WAITRUNNING && GT_MP_PTPM) {
122         int j,
123           freeslot;
124         /* find a free playerslot and check if this player isn't already in the list */
125         for (i = -1, freeslot = -1, j = 0; j < MAX_PLAYERS; j++) {
126             if (!PS_IS_used (players[j].state) && freeslot == -1)
127                 freeslot = j;
128             if (strncmp (players[j].net.addr.host, addr->host, LEN_SERVERNAME) == 0
129                 && strncmp (players[j].net.addr.port, addr->port, LEN_PORT) == 0
130                 && ((p_jg->secondplayer && (players[j].net.flags & NETF_local2) != 0)
131                     || (!p_jg->secondplayer && (players[j].net.flags & NETF_local2) == 0)))
132                 i = j;
133         }
134 
135         if (i == -1)
136             i = freeslot;
137 
138         if ((i >= 0) && (i < MAX_PLAYERS) && (i < bman.maxplayer)) {
139             /* free player slot found ... fill in data */
140             pl = &players[i];
141 
142             pl->state = PSF_used + PSF_net;
143             if (strncmp (pl->name, p_jg->name, LEN_PLAYERNAME) == 0)
144                 d_printf ("     Player ReJoined : Nr:[%d]   Name:%10s\n", i, p_jg->name);
145             else {
146                 d_printf ("     Player Added : Nr:[%d]   Name:%10s\n", i, p_jg->name);
147                 pl->points = 0;
148                 pl->wins = 0;
149                 pl->nbrKilled = 0;
150                 pl->team_nr = -1;
151 
152                 team_choose (pl);
153             }
154 
155             strncpy (pl->name, p_jg->name, LEN_PLAYERNAME);
156 
157             pl->gfx_nr = -1;
158             pl->gfx = NULL;
159 
160             pl->state &= (0xFF - (PSF_alife + PSF_playing));
161 
162             /* Reset the network data */
163             pl->net.timestamp = timestamp;
164             pl->net.pkgopt.to_timestamp = timestamp;
165             pl->net.pkgopt.to_2sec = 0;
166             pl->net.pkgopt.send_to = 0;
167             pl->net.pkgopt.send_set = PKG_SENDSETOPT;
168 
169             strncpy (pl->net.addr.host, addr->host, LEN_SERVERNAME);
170             strncpy (pl->net.addr.port, addr->port, LEN_PORT);
171             dns_filladdr (pl->net.addr.host, LEN_SERVERNAME, pl->net.addr.port,
172                           LEN_PORT, bman.net_ai_family, &pl->net.addr.sAddr);
173             if (p_jg->secondplayer)
174                 pl->net.flags = NETF_local2 + NETF_firewall;
175             else
176                 pl->net.flags = NETF_firewall;
177             pl->net.addr.pl_nr = i;
178             bman.players_nr_s++;
179             addr->pl_nr = i;
180 
181             /* send to the new client the servermode and the complete playerlist */
182             if ((!p_jg->secondplayer) && !(players[j].net.flags & NETF_local2))
183                 send_mapinfo (addr);
184             send_servermode (addr, i); // with this packet the client know it'S pl_nr
185 
186         }
187 
188         else if (GS_WAITRUNNING) {
189             send_error (addr, "No Free Playerslot found\n");
190             return;
191         }
192 
193         else if (!GS_WAITRUNNING) {
194             send_error (addr, "Update mode, please try again.\n");
195             return;
196         }
197     }
198 
199     d_playerdetail ("*** PLAYER List ***");
200     bman.updatestatusbar = 1;
201 };
202 
203 
send_joingame(_net_addr * addr,char * name,int secondplayer)204 void send_joingame (_net_addr * addr, char *name, int secondplayer) {
205     struct pkg_joingame p_jg;
206     int vmi,
207       vma,
208       vsu;
209 
210     d_printf ("send_joingame SendTo: %s:%s (Name:%16s)\n", addr->host, addr->port, name);
211 
212     sscanf (VERSION, "%d.%d.%d", &vma, &vmi, &vsu);
213 
214     p_jg.h.typ = PKG_joingame;
215     p_jg.h.flags = PKGF_ackreq;
216     p_jg.h.len = HTON16 (sizeof (struct pkg_joingame));
217     p_jg.ver_sub = vsu;
218     p_jg.ver_major = vma;
219     p_jg.ver_minor = vmi;
220     p_jg.secondplayer = secondplayer;
221     strncpy (p_jg.name, name, LEN_PLAYERNAME);
222     strncpy (p_jg.password, bman.password, LEN_PASSWORD);
223 
224     bman.firewall = 1;
225     send_pkg ((struct pkg *) &p_jg, addr);
226 };
227 
228 
229 
230 /***
231  *** Packettype: contest
232  *** Test the connection from a new player for the firewall flag.
233  *** This packet will be send from one player to the other the
234  *** current server will only get this packet if a connection test was positive
235  ***/
236 void
do_contest(struct pkg_contest * ct_pkg,_net_addr * addr)237 do_contest (struct pkg_contest *ct_pkg, _net_addr * addr)
238 {
239     d_printf ("do_contest (pl_nr = %d) from=%d to=%d\n", addr->pl_nr, ct_pkg->from, ct_pkg->to);
240 
241     if (addr->pl_nr >= MAX_PLAYERS
242         || (addr->pl_nr == -1 && PS_IS_netplayer (players[ct_pkg->from].state))) {
243         d_printf ("     addr->pl_nr out of range (0-MAX_PLAYERS)\n");
244         return;
245     }
246 
247     /* master will have to change the firewall flag on a player */
248     if (GT_MP_PTPM) {
249 		if ((ct_pkg->from < 0 || ct_pkg->from >= MAX_PLAYERS
250 			 || ct_pkg->to < -1 || ct_pkg->to >= MAX_PLAYERS
251 			 || addr->pl_nr != ct_pkg->from)) {
252 				 d_printf ("     from or to value out of range (0-MAX_PLAYERS)\n");
253 				 return;
254 		}
255 		/* ignore packet it's just a workaround for
256 		 * some hardware router */
257 		if (ct_pkg->to == -1) return;
258 
259         players[ct_pkg->to].net.flags &= (0xFF - NETF_firewall);
260         net_game_send_player (ct_pkg->to);
261     }
262 
263     /* if a client get this packet we send a packet
264      * to the server that we have got this packet. */
265     else {
266         send_contest (&players[bman.p_servnr].net.addr, ct_pkg->from, bman.p_nr, 1);
267         bman.firewall = 0;
268     }
269 }
270 
271 
272 void
send_contest(_net_addr * addr,int from,int to,int ackreq)273 send_contest (_net_addr * addr, int from, int to, int ackreq)
274 {
275     struct pkg_contest ct_pkg;
276 
277     d_printf ("send_contest addr->id:%d, from:%d, to:%d\n", addr->pl_nr, from, to);
278 
279     ct_pkg.h.typ = PKG_contest;
280     if (ackreq)
281         ct_pkg.h.flags = PKGF_ackreq;
282     else
283         ct_pkg.h.flags = 0;
284     ct_pkg.h.len = HTON16 (sizeof (struct pkg_contest));
285 
286     ct_pkg.from = from;
287     ct_pkg.to = to;
288 
289     send_pkg ((struct pkg *) &ct_pkg, addr);
290 }
291 
292 
293 /***
294  *** Packettype: playerid
295  *** Update Playerinformation, Teampoints of a Player, Points
296  ***
297  ***
298  *** if  : the pl_nr == -1 send the whole list to the sender
299  *** else: set the new values for this player
300  ***/
301 void
do_playerid(struct pkg_playerid * p_id,_net_addr * addr)302 do_playerid (struct pkg_playerid *p_id, _net_addr * addr)
303 {
304     _player *pl;
305     int i;
306 
307     d_printf
308         ("do_playerid (From:%s:%s pl_nr=%d) Player(name:%s [%s:%s], pl_nr:%d state:%d,%d)\n",
309          addr->host, addr->port, addr->pl_nr, p_id->name, p_id->host, p_id->port, p_id->pl_nr, p_id->state, PS_IS_alife (p_id->state));
310 
311     /*
312      * check if we have to send the whole playerlist to a client
313      */
314     if (GT_MP_PTPM && p_id->pl_nr == -1 && addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) {
315         /* Send all connected players the new PlayerID, except to the new player */
316         pl = &players[addr->pl_nr];
317         for (i = 0; i < MAX_PLAYERS; i++)
318             if (NET_CANSEND (i) && addr->pl_nr != i)
319                 send_playerid (&players[i].net.addr, pl->name, pl->net.addr.host,
320                                pl->net.addr.port, pl->net.addr.pl_nr, pl->gfx_nr,
321                                pl->team_nr, pl->net.flags);
322 
323         for (i = 0; i < MAX_PLAYERS; i++)
324             send_playerid (addr, players[i].name, players[i].net.addr.host,
325                            players[i].net.addr.port, i, players[i].gfx_nr, players[i].team_nr,
326                            players[i].net.flags);
327     }
328 
329     /*
330      * check if we have to update someones data
331      */
332     else if ((GT_MP_PTPM && p_id->pl_nr >= 0 && p_id->pl_nr < MAX_PLAYERS &&
333               p_id->pl_nr != bman.p_nr && p_id->pl_nr != bman.p2_nr && bman.state == GS_wait)
334              || (GT_MP_PTPS && p_id->pl_nr >= 0 && p_id->pl_nr < MAX_PLAYERS)) {
335 
336         pl = &players[p_id->pl_nr];
337 
338         pl->net.timestamp = timestamp;
339         pl->net.pingreq = pl->net.pingack + 5;
340         if (GT_MP_PTPS)
341             pl->net.flags = p_id->netflags;
342         if (p_id->host[0] != 0 && p_id->pl_nr != bman.p_servnr) { // copy addr only if p_id != server
343             pl->net.addr.pl_nr = addr->pl_nr;
344             strncpy (pl->net.addr.host, p_id->host, LEN_SERVERNAME);
345             strncpy (pl->net.addr.port, p_id->port, LEN_PORT);
346             dns_filladdr (pl->net.addr.host, LEN_SERVERNAME,
347                           pl->net.addr.port, LEN_PORT, bman.net_ai_family, &pl->net.addr.sAddr);
348         }
349         /* player is used, we need to check if it's the second player from the server
350          * to set it's host and port name */
351         else if (PS_IS_used (p_id->state) && p_id->pl_nr != bman.p_servnr) { // copy addr only if p_id != server
352             strncpy (pl->net.addr.host, players[bman.p_servnr].net.addr.host, LEN_SERVERNAME);
353             strncpy (pl->net.addr.port, players[bman.p_servnr].net.addr.port, LEN_PORT);
354             memcpy (&pl->net.addr.sAddr, &players[bman.p_servnr].net.addr.sAddr,
355                     sizeof (struct _sockaddr));
356         }
357 
358         /* Check if we have to make a network test.. only client to client
359          * we won't check 2 players too because it won't be possible to send
360          * something to them.
361          *
362          * Check only as long as pl->state is still not a network player */
363         if (GT_MP_PTPS && !(PS_IS_netplayer (pl->state)) && (PS_IS_netplayer (p_id->state))
364             && p_id->pl_nr != bman.p_servnr && p_id->pl_nr != bman.p_nr
365             && !(pl->net.flags & NETF_local2) && p_id->pl_nr != bman.p2_nr) {
366 
367             send_contest (&pl->net.addr, bman.p_nr, -1, 0); // send contest without ackreq.
368             /* make sure we still get messages from the server, this is a
369              * work around for some hardware routers */
370             send_contest (&players[bman.p_servnr].net.addr, bman.p_nr, -1, 1);
371         }
372 
373 		/* to make sure that in games the client won't reborn without a reason */
374 		if (bman.state != GS_running || PS_IS_alife (pl->state) == 1)
375 			pl->state = p_id->state;
376 		else
377 			pl->state = p_id->state & (0xFF - PSF_alife);
378 
379 		/* set the NETWORK flag for the network player.
380 		 * this had to be done after the contest part. */
381         if (p_id->pl_nr != bman.p_nr && PS_IS_used (pl->state))
382             pl->state |= PSF_net;
383         else
384             pl->state &= (0xff - PSF_net);
385 
386 		/* make sure we won't end up in an infinite loop, because of a slow network.
387 		 * only accept the gfx data from other players. Our own we will not overwrite.*/
388 		if ((bman.state != GS_wait
389 			|| (p_id->pl_nr != bman.p_nr && p_id->pl_nr != bman.p2_nr))
390 			&& pl->gfx_nr != p_id->gfx_nr)
391 	            player_set_gfx (pl, p_id->gfx_nr);
392         strncpy (pl->name, p_id->name, LEN_PLAYERNAME);
393 
394         if (GT_MP_PTPS) {
395             pl->points = NTOH16 (p_id->points);
396             pl->nbrKilled = NTOH16 (p_id->nbrKilled);
397             pl->wins = NTOH16 (p_id->wins);
398             pl->team_nr = p_id->team_nr;
399             if (pl->team_nr >= 0 && pl->team_nr < MAX_TEAMS) {
400                 teams[pl->team_nr].points = NTOH16 (p_id->team_points);
401                 teams[pl->team_nr].wins = NTOH16 (p_id->team_wins);
402             }
403         }
404 
405         /* Send all connected players the new PlayerID */
406         if (GT_MP_PTPM && GS_WAITRUNNING && addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS)
407             net_send_playerid (addr->pl_nr);
408     }
409 
410     /*
411      * if we are already in a game don't let the player change the gfx */
412     else if (GT_MP_PTPM && p_id->pl_nr >= 0 && p_id->pl_nr < MAX_PLAYERS &&
413              p_id->pl_nr != bman.p_nr && p_id->pl_nr != bman.p2_nr && bman.state != GS_wait) {
414         /* Send all connected players the new PlayerID */
415         if (GT_MP_PTPM && GS_WAITRUNNING && addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS)
416             net_send_playerid (addr->pl_nr);
417     }
418 
419     //  d_playerdetail ("*** PLAYER List ***");
420     team_update ();
421     bman.updatestatusbar = 1;
422 };
423 
424 
425 void
send_playerid(_net_addr * addr,char * name,char * pladdr,char * plport,int pl_nr,int gfx_nr,int team_nr,signed char netflags)426 send_playerid (_net_addr * addr, char *name, char *pladdr, char *plport,
427                int pl_nr, int gfx_nr, int team_nr, signed char netflags)
428 {
429     struct pkg_playerid p_id;
430 
431     d_printf ("send_playerid SendTo: %s:%s (Name:%16s p_nr:%d)\n", addr->host,
432               addr->port, name, pl_nr);
433 
434     p_id.h.typ = PKG_playerid;
435     p_id.h.flags = PKGF_ackreq;
436     p_id.h.len = HTON16 (sizeof (struct pkg_playerid));
437 
438     if (name != NULL)
439         strncpy (p_id.name, name, LEN_PLAYERNAME);
440     else
441         p_id.name[0] = 0;
442 
443     if (pladdr == NULL)
444         p_id.host[0] = 0;
445     else
446         strncpy (p_id.host, pladdr, LEN_SERVERNAME);
447 
448     if (plport == NULL)
449         p_id.port[0] = 0;
450     else
451         strncpy (p_id.port, plport, LEN_PORT);
452 
453     p_id.pl_nr = pl_nr;
454     p_id.netflags = netflags;
455     p_id.gfx_nr = gfx_nr;
456     if (pl_nr != -1) {
457         p_id.points = HTON16 (players[pl_nr].points);
458         p_id.wins = HTON16 (players[pl_nr].wins);
459         p_id.nbrKilled = HTON16 (players[pl_nr].nbrKilled);
460         p_id.state = players[pl_nr].state;
461         p_id.team_nr = team_nr;
462         if (team_nr >= 0 && team_nr < MAX_TEAMS) {
463             p_id.team_points = teams[team_nr].points;
464             p_id.team_wins = teams[team_nr].wins;
465         }
466     }
467     else {
468         p_id.points = 0;
469         p_id.wins = 0;
470         p_id.nbrKilled = 0;
471         p_id.state = 0;
472         p_id.team_nr = -1;
473         p_id.team_points = 0;
474         p_id.team_wins = 0;
475     }
476 
477     send_pkg ((struct pkg *) &p_id, addr);
478 };
479 
480 
481 
482 /***
483  *** Packettype: teamdata
484  *** Server Side:
485  ***    Send all teamdata to the client.
486  *** Client Side:
487  ***    Get all Teamdata
488  ***/
489 void
do_teamdata(struct pkg_teamdata * td,_net_addr * addr)490 do_teamdata (struct pkg_teamdata *td, _net_addr * addr)
491 {
492     int i;
493 
494     if (addr->pl_nr == -1)
495         return;
496 
497     d_printf ("do_teamdata (addr->pl_nr: %d): team:%d col:%d wins:%d\n", addr->pl_nr, td->team_nr, td->col, td->wins);
498 
499     if (addr->pl_nr == bman.p_servnr) { /* packet comes from the server */
500         if (td->team_nr >= 0 && td->team_nr < MAX_TEAMS) {
501             strncpy (teams[td->team_nr].name, td->name, LEN_PLAYERNAME);
502             teams[td->team_nr].col = td->col;
503             teams[td->team_nr].wins = td->wins;
504             bman.updatestatusbar = 1;
505         }
506     }
507     else {
508         if (td->team_nr < 0 || td->team_nr >= MAX_TEAMS) {
509             for (i = 0; i < MAX_TEAMS; i++)
510                 send_teamdata (addr, i);
511         }
512         else {
513             send_teamdata (addr, td->team_nr);
514         }
515     }
516 }
517 
518 
519 void
send_teamdata(_net_addr * addr,int team_nr)520 send_teamdata (_net_addr * addr, int team_nr)
521 {
522     struct pkg_teamdata td;
523 
524     d_printf ("send_teamdata (%s:%s) team:%d\n", addr->host, addr->port, team_nr);
525 
526     td.h.typ = PKG_teamdata;
527     td.h.flags = PKGF_ackreq;
528     td.h.len = HTON16 (sizeof (struct pkg_teamdata));
529 
530     td.team_nr = team_nr;
531     if (team_nr >= 0 && team_nr < MAX_PLAYERS) {
532         strncpy (td.name, teams[team_nr].name, LEN_PLAYERNAME);
533         td.wins = teams[team_nr].wins;
534         td.col = teams[team_nr].col;
535     }
536     else {
537         td.name[0] = 0;
538         td.wins = 0;
539         td.col = 0;
540     }
541     send_pkg ((struct pkg *) &td, addr);
542 }
543 
544 
545 /***
546  *** Packettype: servermode
547  ***/
548 void
do_servermode(struct pkg_servermode * s_mod,_net_addr * addr)549 do_servermode (struct pkg_servermode *s_mod, _net_addr * addr)
550 {
551     if (addr->pl_nr == -1)
552         return;
553 
554     d_printf ("do_servermode (%s:%s) state = %d\n", addr->host, addr->port, s_mod->state);
555 
556     /* if we just have connected the bman.p_nr is still -1, so we handle the
557        servermode packet still alittle diffrent */
558     if ((!s_mod->lplayer2 && bman.p_nr == -1) || (s_mod->lplayer2 && bman.p2_nr == -1)) {
559         d_printf ("     Server gave us: p_nr/p2_nr: %d(old:%d), p_servnr: %d(old:%d), lplayer2:%d\n", s_mod->p_nr,
560                   bman.p_nr, s_mod->p_servnr, bman.p_servnr, s_mod->lplayer2);
561 
562         /* set the p_servnr to the playerslot which is the server */
563         if (bman.p_servnr != s_mod->p_servnr) {
564             memcpy (&players[s_mod->p_servnr].net, &players[bman.p_servnr].net,
565                     sizeof (_net_player));
566             memset (&players[bman.p_servnr], '\0', sizeof (_net_player));
567             bman.p_servnr = s_mod->p_servnr;
568         }
569 
570         /* set now the new p_nr number */
571         if (s_mod->p_nr >= 0 && s_mod->p_nr < MAX_PLAYERS && bman.p_nr == -1
572             && s_mod->lplayer2 == 0) {
573             bman.p_nr = s_mod->p_nr;
574             bman.firewall = 1;
575             players[bman.p_nr].net.flags = NETF_firewall;
576             players[bman.p_nr].state &= (0xFF - PSF_net);
577             strncpy (players[s_mod->p_nr].name, bman.playername, LEN_PLAYERNAME);
578 
579             /* send playerid with p_nr -1 so we get the whole playerlist
580              * do the same with the teamdata */
581             send_playerid (addr, NULL, NULL, NULL, -1, -1, -1, 0);
582             send_teamdata (addr, -1);
583         }
584         else if (s_mod->p_nr >= 0 && s_mod->p_nr < MAX_PLAYERS && bman.p2_nr == -1
585                  && s_mod->lplayer2 == 1) {
586             bman.p2_nr = s_mod->p_nr;
587             players[bman.p2_nr].net.flags = NETF_firewall + NETF_local2;
588             players[bman.p2_nr].state &= (0xFF - PSF_net);
589             strncpy (players[s_mod->p_nr].name, bman.player2name, LEN_PLAYERNAME);
590             send_playerid (addr, NULL, NULL, NULL, -1, -1, -1, 0);
591             send_teamdata (addr, -1);
592         }
593     }
594 
595     /* do the normal update */
596     if (GT_MP_PTPS && addr->pl_nr == bman.p_servnr) {
597         bman.state = s_mod->state;
598         bman.gametype = s_mod->gametype;
599         bman.dropitemsondeath = s_mod->dropitemsondeath;
600         map.state = s_mod->mapstate;
601 
602         bman.players_nr_s = s_mod->players;
603         bman.lastwinner = s_mod->last_winner;
604 
605         map.size.x = s_mod->fieldsize_x;
606         map.size.y = s_mod->fieldsize_y;
607 
608         strncpy (map.tileset, s_mod->tileset, LEN_TILESETNAME);
609     }
610 
611     bman.updatestatusbar = 1;
612 };
613 
614 
615 void
send_servermode(_net_addr * addr,int pl_nr)616 send_servermode (_net_addr * addr, int pl_nr)
617 {
618     struct pkg_servermode s_mod;
619 
620     switch (bman.state) {
621     case (GS_startup):
622         d_printf ("Send ServerMode : startup");
623         break;
624     case (GS_ready):
625         d_printf ("Send ServerMode : ready");
626         break;
627     case (GS_running):
628         d_printf ("Send ServerMode : running");
629         break;
630     case (GS_quit):
631         d_printf ("Send ServerMode : quit");
632         break;
633     case (GS_wait):
634         d_printf ("Send ServerMode : wait");
635         break;
636     case (GS_update):
637         d_printf ("Send ServerMode : update");
638         break;
639     default:
640         d_printf ("Send ServerMode : mode %d", bman.state);
641     }
642 
643 	d_printf ("Addr: %p\n", addr);
644 
645     s_mod.h.typ = PKG_servermode;
646     s_mod.h.len = HTON16 (sizeof (struct pkg_servermode));
647     s_mod.h.flags = PKGF_ackreq;
648     s_mod.type = bman.gametype;
649     s_mod.dropitemsondeath = bman.dropitemsondeath;
650     s_mod.mapstate = map.state;
651     if (bman.state == GS_quit)  /* do not send GS_quit */
652         s_mod.state = GS_startup;
653     else
654         s_mod.state = bman.state;
655     s_mod.gametype = bman.gametype;
656     s_mod.players = bman.players_nr_s;
657     s_mod.maxplayer = bman.maxplayer;
658     s_mod.p_nr = pl_nr;
659     if (pl_nr >= 0 && pl_nr < MAX_PLAYERS
660         && (players[pl_nr].net.flags & NETF_local2) == NETF_local2)
661         s_mod.lplayer2 = 1;
662     else
663         s_mod.lplayer2 = 0;
664     s_mod.p_servnr = bman.p_servnr;
665     s_mod.last_winner = bman.lastwinner;
666     s_mod.fieldsize_x = map.size.x;
667     s_mod.fieldsize_y = map.size.y;
668     strncpy (s_mod.tileset, map.tileset, LEN_TILESETNAME);
669     send_pkg ((struct pkg *) &s_mod, addr);
670 };
671 
672 
673 
674 /***
675  *** Packettype: field
676  ***/
677 void
send_field(_net_addr * addr,int x,int y,_field * field)678 send_field (_net_addr * addr, int x, int y, _field * field)
679 {
680     struct pkg_field f_dat;
681     int i;
682 
683     d_printf ("send_field [%d,%d]\n", x, y);
684 
685     f_dat.h.typ = PKG_field;
686     f_dat.h.len = HTON16 (sizeof (struct pkg_field));
687     f_dat.h.flags = PKGF_ackreq;
688 
689     f_dat.x = x;
690     f_dat.y = y;
691 
692     if (x < 0 || x >= map.size.x || y < 0 || y >= map.size.y)
693         return;
694 
695     for (i = 0; i < 4; i++) {
696         f_dat.ex[i].count = map.field[x][y].ex[i].count;
697         f_dat.ex[i].frame = (int) map.field[x][y].ex[i].frame;
698         f_dat.ex[i].bomb_p = map.field[x][y].ex[i].bomb_p;
699         f_dat.ex[i].bomb_b = map.field[x][y].ex[i].bomb_b;
700     }
701     f_dat.type = map.field[x][y].type;
702     f_dat.mixframe = map.field[x][y].mixframe;
703     f_dat.special = map.field[x][y].special;
704     f_dat.frame = HTON16 (FTOI16 (map.field[x][y].frame));
705     f_dat.ex_nr = HTON32 (map.field[x][y].ex_nr);
706 
707     send_pkg ((struct pkg *) &f_dat, addr);
708 };
709 
710 
711 void
do_field(struct pkg_field * f_dat,_net_addr * addr)712 do_field (struct pkg_field *f_dat, _net_addr * addr)
713 {
714     int i;
715 
716     if (addr->pl_nr == -1)
717         return;
718 
719     if (f_dat->x < map.size.x && f_dat->y < map.size.y) {
720         /* convert the fielddata */
721         map.field[f_dat->x][f_dat->y].type = f_dat->type; // CHECK_BFIELD::: FOR BOMBS:::::
722         map.field[f_dat->x][f_dat->y].mixframe = f_dat->mixframe;
723         map.field[f_dat->x][f_dat->y].special = f_dat->special;
724         for (i = 0; i < 4; i++) { /* set the explosion field data */
725             map.field[f_dat->x][f_dat->y].ex[i].count = f_dat->ex[i].count;
726             map.field[f_dat->x][f_dat->y].ex[i].frame = f_dat->ex[i].frame;
727             map.field[f_dat->x][f_dat->y].ex[i].bomb_p = f_dat->ex[i].bomb_p;
728             map.field[f_dat->x][f_dat->y].ex[i].bomb_b = f_dat->ex[i].bomb_b;
729         }
730         map.field[f_dat->x][f_dat->y].frame = I16TOF (NTOH16 (f_dat->frame));
731         map.field[f_dat->x][f_dat->y].ex_nr = NTOH32 (f_dat->ex_nr);
732     }
733     if (bman.state == GS_running)
734         stonelist_add (f_dat->x, f_dat->y);
735 
736     if (NTOH32 (f_dat->ex_nr) > bman.last_ex_nr)
737         bman.last_ex_nr = NTOH32 (f_dat->ex_nr);
738 
739     d_printf ("do_field (%d,%d) ex_nr = %d, special = %d, type = %d\n",
740               f_dat->x, f_dat->y, NTOH32 (f_dat->ex_nr), f_dat->special, f_dat->type);
741 };
742 
743 
744 /***
745  *** Packettype: pingack/pingreq
746  ***/
747 void
do_ping(struct pkg_ping * p_dat,_net_addr * addr)748 do_ping (struct pkg_ping *p_dat, _net_addr * addr)
749 {
750     if (addr->pl_nr == -1)
751         return;
752 
753     if (p_dat->h.typ == PKG_pingack)
754         /* ping was an answer */
755         players[addr->pl_nr].net.pingack = NTOH32 (p_dat->data);
756 
757     else
758         /* send the answer */
759         send_ping (addr, NTOH32 (p_dat->data), PKG_pingack);
760 
761     d_printf ("do_ping pl_nr[%d] (%s:%s)   req=%d, ack=%d\n", addr->pl_nr,
762               addr->host, addr->port, players[addr->pl_nr].net.pingreq,
763               players[addr->pl_nr].net.pingack);
764 };
765 
766 void
send_ping(_net_addr * addr,int data,unsigned char typ)767 send_ping (_net_addr * addr, int data, unsigned char typ)
768 {
769     struct pkg_ping p_dat;
770 
771     if (addr->pl_nr == -1)
772         return;
773 
774     p_dat.h.len = HTON16 (sizeof (struct pkg_ping));
775     p_dat.h.flags = 0;
776 
777     if (typ == PKG_pingack) {
778         p_dat.h.typ = typ;
779         p_dat.data = HTON32 (data);
780         send_pkg ((struct pkg *) &p_dat, addr);
781     }
782 
783     else if (typ == PKG_pingreq) {
784         p_dat.h.typ = typ;
785         p_dat.data = HTON32 (data);
786         send_pkg ((struct pkg *) &p_dat, addr);
787     }
788 
789     d_printf ("send_ping Player[%d] (%s:%s)   req=%d, ack=%d\n", addr->pl_nr,
790               addr->host, addr->port, players[addr->pl_nr].net.pingreq,
791               players[addr->pl_nr].net.pingack);
792 
793     players[addr->pl_nr].net.timestamp = timestamp; /* we need to set it here, so we can check
794                                                        for the timeout again */
795 };
796 
797 
798 /***
799  *** Packettype: playerdata
800  ***/
801 void
send_playerdata(_net_addr * addr,int p_nr,_player * pl)802 send_playerdata (_net_addr * addr, int p_nr, _player * pl)
803 {
804     struct pkg_playerdata p_dat;
805 
806     p_dat.h.typ = PKG_playerdata;
807     p_dat.h.len = HTON16 (sizeof (struct pkg_playerdata));
808 
809     if (bman.state == GS_update)
810         p_dat.h.flags = 0;
811     else
812         p_dat.h.flags = PKGF_ackreq;
813 
814     p_dat.pos.x = HTON16 (FTOI16 (pl->pos.x));
815     p_dat.pos.y = HTON16 (FTOI16 (pl->pos.y));
816     p_dat.bombs_n = pl->bombs_n;
817     p_dat.d = pl->d;
818     p_dat.range = pl->range;
819     p_dat.gfx_nr = pl->gfx_nr;
820     p_dat.state = pl->state;
821     p_dat.wins = HTON16 (pl->wins);
822     p_dat.points = HTON16 (pl->points);
823     p_dat.nbrKilled = HTON16 (pl->nbrKilled);
824     p_dat.dead_by = pl->dead_by;
825     p_dat.frame = HTON16 (FTOI16 (pl->frame));
826     p_dat.p_nr = p_nr;
827     p_dat.ready = pl->ready;
828     p_dat.team_nr = pl->team_nr;
829 
830     send_pkg ((struct pkg *) &p_dat, addr);
831 };
832 
833 
834 void
do_playerdata(struct pkg_playerdata * p_dat,_net_addr * addr)835 do_playerdata (struct pkg_playerdata *p_dat, _net_addr * addr)
836 {
837     _player *pl;
838 
839     if (addr->pl_nr == -1)
840         return;
841 
842     if (p_dat->p_nr < 0 || p_dat->p_nr >= MAX_PLAYERS)
843         return;
844 
845     d_printf ("do_playerdata (From: %d) p_nr: %d --> state alife? %d new %d\n", addr->pl_nr, p_dat->p_nr, PS_IS_alife(players[p_dat->p_nr].state) , PS_IS_alife(p_dat->state));
846     bman.updatestatusbar = 1;   // force an update
847 
848     pl = &players[p_dat->p_nr];
849 
850     if (bman.state == GS_running && bman.p_nr != p_dat->p_nr) {
851         pl->points = NTOH16 (p_dat->points);
852         pl->nbrKilled = NTOH16 (p_dat->nbrKilled);
853         pl->dead_by = NTOH16 (p_dat->dead_by);
854         pl->team_nr = p_dat->team_nr;
855     }
856     else if (bman.state != GS_running || bman.p_nr != p_dat->p_nr) {
857         pl->pos.x = I16TOF (NTOH16 (p_dat->pos.x));
858         pl->pos.y = I16TOF (NTOH16 (p_dat->pos.y));
859         pl->dead_by = p_dat->dead_by;
860         pl->nbrKilled = NTOH16 (p_dat->nbrKilled);
861         pl->points = NTOH16 (p_dat->points);
862         pl->d = p_dat->d;
863         pl->bombs_n = p_dat->bombs_n;
864         pl->range = p_dat->range;
865         pl->frame = I16TOF (NTOH16 (p_dat->frame));
866         pl->state = p_dat->state;
867         pl->team_nr = p_dat->team_nr;
868         pl->ready = p_dat->ready;
869         team_update ();
870     }
871 
872     if (p_dat->dead_by < 0 || p_dat->dead_by >= MAX_PLAYERS) /* set player state no matter what */
873         pl->state = p_dat->state;
874     else {                      /* player died in the game */
875         /* check if the player just died */
876         if (PS_IS_alife (pl->state) && PS_IS_dead (p_dat->state)) {
877             /* player just died */
878                 player_died (pl, p_dat->dead_by, 1);
879             }
880         pl->state = p_dat->state;
881     }
882 
883     /* set the state of the player */
884     if (p_dat->p_nr != bman.p_nr && PS_IS_used (pl->state))
885         pl->state |= PSF_net;
886     else
887         pl->state &= (0xff - PSF_net);
888 
889     if (p_dat->gfx_nr == -1)
890         pl->state &= (0xff - PSF_alife);
891 
892     if (bman.state == GS_update && PS_IS_used (p_dat->state))
893         bman.players_nr_s++;
894 
895     if (players[bman.p_nr].net.net_istep == 1)
896         players[bman.p_nr].net.net_status = p_dat->p_nr;
897 
898     player_set_gfx (pl, p_dat->gfx_nr);
899 }
900 
901 
902 /***
903  *** Packettype: ill
904  ***/
905 void
do_ill(struct pkg_ill * ill,_net_addr * addr)906 do_ill (struct pkg_ill *ill, _net_addr * addr)
907 {
908     int i,
909       old_to;
910 
911     if (addr->pl_nr == -1)
912         return;
913 
914     d_printf ("do_ill (From: %d) For Player %d\n", addr->pl_nr, ill->pl_nr);
915     if (ill->pl_nr < 0 || ill->pl_nr >= MAX_PLAYERS || ill->pl_nr == bman.p_nr)
916         return;
917 
918     for (i = 0; i < PI_max; i++) {
919         old_to = players[ill->pl_nr].ill[i].to;
920         players[ill->pl_nr].ill[i].to = I32TOF (NTOH32 (ill->to[i]));
921         if (players[ill->pl_nr].ill[i].to <= 0.0f && old_to > 0.0f)
922             player_clear_ilness (&players[ill->pl_nr], i);
923         else if (players[ill->pl_nr].ill[i].to > 0.0f && old_to <= 0.0f)
924             player_set_ilness (&players[ill->pl_nr], i, players[ill->pl_nr].ill[i].to);
925         d_printf ("    to[%d]:%f dataf:%f datai:%d\n", i, players[ill->pl_nr].ill[i].to,
926                   players[ill->pl_nr].ill[i].dataf, players[ill->pl_nr].ill[i].datai);
927     }
928 };
929 
930 void
send_ill(_net_addr * addr,int p_nr,_player * pl)931 send_ill (_net_addr * addr, int p_nr, _player * pl)
932 {
933     struct pkg_ill ill;
934     int i;
935 
936     ill.h.typ = PKG_ill;
937     ill.h.len = HTON16 (sizeof (struct pkg_ill));
938     ill.h.flags = PKGF_ackreq;
939 
940     ill.pl_nr = p_nr;
941     for (i = 0; i < PI_max; i++)
942         ill.to[i] = HTON32 (FTOI32 (pl->ill[i].to));
943 
944     send_pkg ((struct pkg *) &ill, addr);
945 };
946 
947 
948 /***
949  *** Packettype: playermove
950  ***/
951 void
send_playermove(_net_addr * addr,int p_nr,_player * pl)952 send_playermove (_net_addr * addr, int p_nr, _player * pl)
953 {
954     struct pkg_playermove p_dat;
955 
956     p_dat.h.typ = PKG_playermove;
957     p_dat.h.len = HTON16 (sizeof (struct pkg_playermove));
958     p_dat.h.flags = 0;
959 
960     p_dat.pos.x = HTON16 (FTOI16 (pl->pos.x));
961     p_dat.pos.y = HTON16 (FTOI16 (pl->pos.y));
962     p_dat.m = pl->m;
963     p_dat.d = pl->d;
964     p_dat.p_nr = p_nr;
965     p_dat.speed = HTON16 (FTOI16 (pl->speed));
966     p_dat.tunnelto = HTON16 (FTOI16 (pl->tunnelto));
967 
968     send_pkg ((struct pkg *) &p_dat, addr);
969 };
970 
971 void
do_playermove(struct pkg_playermove * p_dat,_net_addr * addr)972 do_playermove (struct pkg_playermove *p_dat, _net_addr * addr)
973 {
974     _player *pl;
975 
976     if (addr->pl_nr == -1)
977         return;
978 
979     if (p_dat->p_nr == -1)
980         return;
981 
982     if (addr->pl_nr == -1)      // unknown player
983         return;
984 
985     /* check if the right player is sending the information */
986     pl = &players[p_dat->p_nr];
987 
988     pl->m = p_dat->m;
989     pl->d = p_dat->d;
990     pl->speed = I16TOF (NTOH16 (p_dat->speed));
991     pl->pos.x = I16TOF (NTOH16 (p_dat->pos.x));
992     pl->pos.y = I16TOF (NTOH16 (p_dat->pos.y));
993     pl->tunnelto = I16TOF (NTOH16 (p_dat->tunnelto));
994 }
995 
996 
997 /***
998  *** Packettype: bombdata
999  ***/
do_bombdata(struct pkg_bombdata * b_dat,_net_addr * addr)1000 void do_bombdata (struct pkg_bombdata *b_dat, _net_addr * addr) {
1001     _bomb *bomb;
1002 
1003     if (addr->pl_nr == -1)
1004         return;
1005 
1006     if (b_dat->p_nr >= MAX_PLAYERS || b_dat->b_nr >= MAX_BOMBS) {
1007         d_printf ("Bomb Error\n");
1008         return;
1009     }
1010 
1011     if (b_dat->state == BS_off)
1012         return;                 // if there was a bomb let it explose don't delete the bomb
1013 
1014 	d_printf ("do_bombdata [%f,%f] Player: %d PlayerIgnition: %d Bomb: %d, ex_nr:%d\n",
1015               I16TOF (NTOH16 (b_dat->x)), I16TOF (NTOH16 (b_dat->y)), b_dat->p_nr, b_dat->pi_nr, b_dat->b_nr, NTOH32 (b_dat->ex_nr));
1016 
1017     bomb = &players[b_dat->p_nr].bombs[b_dat->b_nr];
1018     if (bomb->state == BS_exploding) {
1019         d_printf ("do_bombdata ---> bomb is already exploding\n");
1020         return;
1021     }
1022     // Update player ignition
1023     bomb->id.pIgnition = b_dat->pi_nr;
1024     if ((bomb->pos.x != NTOH16 (b_dat->x) || bomb->pos.y != NTOH16 (b_dat->y))
1025         && bomb->state == BS_exploding && b_dat->state != BS_exploding)
1026         d_printf ("do_bombdata  WARNING : bomb explosion haven't finished\n");
1027 
1028     if (bomb->state != BS_off) { // handle push & kick special
1029         map.bfield[(int) bomb->pos.x][(int) bomb->pos.y] = 0; //remove bomb at old location
1030         stonelist_add (bomb->pos.x, bomb->pos.y);
1031         stonelist_add (bomb->pos.x + 1, bomb->pos.y);
1032         stonelist_add (bomb->pos.x, bomb->pos.y + 1);
1033         stonelist_add (bomb->pos.x + 1, bomb->pos.y + 1);
1034     }
1035 
1036     if (bomb->state == BS_off && (b_dat->state == BS_ticking || b_dat->state == BS_trigger))
1037         snd_play (SND_bombdrop);
1038 
1039     /* convert position back to float */
1040     bomb->pos.x = I16TOF (NTOH16 (b_dat->x));
1041     bomb->pos.y = I16TOF (NTOH16 (b_dat->y));
1042 
1043     if (bomb->state != b_dat->state && bomb->state != BS_ticking)
1044         bomb->to = I32TOF (NTOH32 (b_dat->to)); /* only set if the bomb isn't already ticking
1045                                                    to make sure the timeout won't be resetted
1046                                                    by an old network packet */
1047 
1048     map.bfield[(int) bomb->pos.x][(int) bomb->pos.y] = 1; // keep the bfield up to date
1049 
1050     bomb->r = b_dat->r;
1051     bomb->ex_nr = NTOH32 (b_dat->ex_nr);
1052     bomb->state = b_dat->state & 0x0F;
1053 
1054 	if (bomb->mode != b_dat->state >> 4) {		// bombmode changed set source to current position
1055 		bomb->source.x = bomb->pos.x;
1056 		bomb->source.y = bomb->pos.y;
1057 	}
1058     bomb->mode = b_dat->state >> 4;
1059     bomb->fdata = I16TOF (NTOH16 (b_dat->fdata));
1060     bomb->dest.x = I16TOF (NTOH16 (b_dat->destx));
1061     bomb->dest.y = I16TOF (NTOH16 (b_dat->desty));
1062 
1063     if (bomb->state == BS_exploding)
1064         bomb_explode (bomb, 0);
1065 
1066     if (bomb->ex_nr > bman.last_ex_nr)
1067         bman.last_ex_nr = bomb->ex_nr;
1068 };
1069 
1070 void
send_bombdata(_net_addr * addr,int p,int b,_bomb * bomb)1071 send_bombdata (_net_addr * addr, int p, int b, _bomb * bomb)
1072 {
1073     struct pkg_bombdata b_dat;
1074 
1075     b_dat.h.typ = PKG_bombdata;
1076     b_dat.h.len = HTON16 (sizeof (struct pkg_bombdata));
1077     b_dat.x = HTON16 (FTOI16 (bomb->pos.x));
1078     b_dat.y = HTON16 (FTOI16 (bomb->pos.y));
1079     b_dat.to = HTON32 (FTOI32 (bomb->to));
1080     b_dat.r = bomb->r;
1081     b_dat.ex_nr = HTON32 (bomb->ex_nr);
1082     b_dat.state = (bomb->mode << 4) | (bomb->state);
1083     b_dat.b_nr = b;
1084     b_dat.p_nr = p;
1085     b_dat.pi_nr = bomb->id.pIgnition;
1086     b_dat.h.flags = PKGF_ackreq;
1087     b_dat.fdata = HTON16 (FTOI16 (bomb->fdata));
1088     b_dat.destx = HTON16 (FTOI16 (bomb->dest.x));
1089     b_dat.desty = HTON16 (FTOI16 (bomb->dest.y));
1090 
1091     send_pkg ((struct pkg *) &b_dat, addr);
1092 };
1093 
1094 
1095 /***
1096  *** Packettype: bombdata
1097  *** recive a request for some tunneldata or receive tunneldata
1098  ***/
1099 void
do_tunneldata(struct pkg_tunneldata * tun_pkg,_net_addr * addr)1100 do_tunneldata (struct pkg_tunneldata *tun_pkg, _net_addr * addr)
1101 {
1102     d_printf ("do_tunneldata: From %d [%s:%s] (Tunnel %d Target [%d,%d])\n",
1103               addr->pl_nr, addr->host, addr->port, tun_pkg->tunnel_nr,
1104               NTOH16 (tun_pkg->target.x), NTOH16 (tun_pkg->target.y));
1105 
1106     if (addr->pl_nr != bman.p_servnr && GT_MP_PTPM && NTOH16 (tun_pkg->target.y) == -1
1107         && NTOH16 (tun_pkg->target.x) == -1) {
1108         send_tunneldata (addr, tun_pkg->tunnel_nr,
1109                          map.tunnel[tun_pkg->tunnel_nr].x, map.tunnel[tun_pkg->tunnel_nr].y);
1110         players[addr->pl_nr].net.net_status = tun_pkg->tunnel_nr;
1111         players[addr->pl_nr].net.net_istep = 3;
1112     }
1113     else if (addr->pl_nr == bman.p_servnr && tun_pkg->tunnel_nr < GAME_MAX_TUNNELS) {
1114         map.tunnel[tun_pkg->tunnel_nr].x = NTOH16 (tun_pkg->target.x);
1115         map.tunnel[tun_pkg->tunnel_nr].y = NTOH16 (tun_pkg->target.y);
1116         players[bman.p_nr].net.net_status = tun_pkg->tunnel_nr;
1117     }
1118 };
1119 
1120 /* send a tunneldata request (x && y == -1) or send tunneldata */
1121 void
send_tunneldata(_net_addr * addr,int tunnelnr,int x,int y)1122 send_tunneldata (_net_addr * addr, int tunnelnr, int x, int y)
1123 {
1124     struct pkg_tunneldata tun_pkg;
1125 
1126     d_printf ("send_tunneldata (Tunnel %d Target [%d,%d])\n", tunnelnr, x, y);
1127 
1128     tun_pkg.h.typ = PKG_tunneldata;
1129     tun_pkg.h.flags = PKGF_ackreq;
1130     tun_pkg.h.len = HTON16 (sizeof (struct pkg_tunneldata));
1131 
1132     if (GT_MP_PTPM || (GT_MP_PTPS && x == -1 && y == -1)) {
1133         tun_pkg.tunnel_nr = tunnelnr;
1134         tun_pkg.target.x = HTON16 (x);
1135         tun_pkg.target.y = HTON16 (y);
1136 
1137         send_pkg ((struct pkg *) &tun_pkg, addr);
1138     }
1139 };
1140 
1141 
1142 /***
1143  *** Packettype: quit
1144  ***/
1145 void
send_quit(_net_addr * addr,int pl_nr,int new_server)1146 send_quit (_net_addr * addr, int pl_nr, int new_server)
1147 {
1148     struct pkg_quit q_dat;
1149 
1150     d_printf ("send_quit (%s:%s) pl_nr: %d\n", addr->host, addr->port, pl_nr);
1151 
1152     q_dat.h.typ = PKG_quit;
1153     q_dat.h.flags = 0;
1154     q_dat.h.len = HTON16 (sizeof (struct pkg_quit));
1155     if (pl_nr == -1)
1156         q_dat.pl_nr = bman.p_nr;
1157     else
1158         q_dat.pl_nr = pl_nr;
1159     q_dat.new_server = new_server;
1160     send_pkg ((struct pkg *) &q_dat, addr);
1161 };
1162 
1163 
1164 void
do_quit(struct pkg_quit * q_dat,_net_addr * addr)1165 do_quit (struct pkg_quit *q_dat, _net_addr * addr)
1166 {
1167     d_printf ("do_quit (%s:%s) pl_nr=%d new_server=%d\n", addr->host, addr->port, q_dat->pl_nr,
1168               q_dat->new_server);
1169 
1170     if (addr->pl_nr == -1)
1171         return;
1172 
1173 	if (q_dat->pl_nr == -1)
1174 		q_dat->pl_nr = addr->pl_nr;
1175 
1176     bman.updatestatusbar = 1;
1177     player_delete (q_dat->pl_nr);
1178 
1179     /* the player who send this quit */
1180     if (q_dat->pl_nr == bman.p_servnr && q_dat->new_server != bman.p_servnr) {
1181         d_printf ("do_quit: new server is set to: %d\n", q_dat->new_server);
1182         bman.p_servnr = q_dat->new_server;
1183 
1184         if (GT_MP_PTPM && bman.notifygamemaster) {
1185             /* if there are any AI players delete the network flag from them */
1186             int i;
1187 
1188             for (i = 0; i < MAX_PLAYERS; i++)
1189                 if (PS_IS_aiplayer (players[i].state))
1190                     players[i].state &= (0xFF - PSF_net);
1191 
1192             send_ogc_update ();
1193         }
1194     }
1195     else if (q_dat->pl_nr == bman.p_servnr && q_dat->new_server == bman.p_servnr)
1196         menu_displaymessage ("Server Quit",
1197                              "The game closed because you are the only one who is left."
1198                              " Or the server could not find any other possible new server.");
1199 };
1200 
1201 
1202 /***
1203  *** Packettype: getfield
1204  ***/
1205 void
send_getfield(_net_addr * addr,int line)1206 send_getfield (_net_addr * addr, int line)
1207 {
1208     struct pkg_getfield gf_dat;
1209 
1210     gf_dat.h.typ = PKG_getfield;
1211     gf_dat.h.len = HTON16 (sizeof (struct pkg_getfield));
1212     gf_dat.h.flags = 0;
1213     gf_dat.line = line;
1214     send_pkg ((struct pkg *) &gf_dat, addr);
1215 };
1216 
1217 
1218 void
do_getfield(struct pkg_getfield * gf_dat,_net_addr * addr)1219 do_getfield (struct pkg_getfield *gf_dat, _net_addr * addr)
1220 {
1221     if (addr->pl_nr == -1)
1222         return;
1223 
1224     if (gf_dat->line < 0 || gf_dat->line >= MAX_FIELDSIZE_Y)
1225         return;
1226 
1227     if (addr->pl_nr != -1 && bman.state == GS_update && GT_MP_PTPM) {
1228         if (addr->pl_nr != bman.p_servnr && addr->pl_nr < MAX_PLAYERS) {
1229             players[addr->pl_nr].net.net_status = gf_dat->line;
1230             players[addr->pl_nr].net.net_istep = 2;
1231         }
1232     }
1233     send_fieldline (addr, gf_dat->line);
1234 };
1235 
1236 
1237 /***
1238  *** Packettype: fieldline
1239  ***/
1240 void
send_fieldline(_net_addr * addr,int line)1241 send_fieldline (_net_addr * addr, int line)
1242 {
1243     int i,
1244       j;
1245     struct pkg_fieldline f_dat;
1246 
1247     f_dat.h.typ = PKG_fieldline;
1248     f_dat.h.len = HTON16 (sizeof (struct pkg_fieldline));
1249     f_dat.h.flags = 0;
1250     f_dat.line = line;
1251 
1252     if (line < 0 || line >= MAX_FIELDSIZE_Y)
1253         return;
1254 
1255     for (i = 0; i < MAX_FIELDSIZE_X; i++) {
1256         f_dat.type[i] = map.field[i][line].type;
1257         f_dat.special[i] = map.field[i][line].special;
1258         map.field[i][line].frame = 0.0f;
1259         map.field[i][line].ex_nr = 0;
1260         for (j = 0; j < 4; j++) {
1261             map.field[i][line].ex[j].frame = 0.0f;
1262             map.field[i][line].ex[j].count = 0;
1263         }
1264     }
1265     send_pkg ((struct pkg *) &f_dat, addr);
1266 };
1267 
1268 
1269 void
do_fieldline(struct pkg_fieldline * f_dat,_net_addr * addr)1270 do_fieldline (struct pkg_fieldline *f_dat, _net_addr * addr)
1271 {
1272     int i,
1273       d;
1274 
1275     if (addr->pl_nr == -1)
1276         return;
1277 
1278     if (addr->pl_nr != bman.p_servnr) {
1279         /* the data we have got are not from the server */
1280         d_printf ("do_fieldline: the data we have got are not from the server\n");
1281         return;
1282     }
1283     if (f_dat->line < 0 || f_dat->line >= MAX_FIELDSIZE_Y) {
1284         /* the line number is wrong */
1285         d_printf ("do_fieldline: the line number is not correct\n");
1286         return;
1287     }
1288 
1289     if (players[bman.p_nr].net.net_istep == 2)
1290         players[bman.p_nr].net.net_status = f_dat->line;
1291 
1292     for (i = 0; i < MAX_FIELDSIZE_X; i++) {
1293         map.field[i][f_dat->line].type = f_dat->type[i];
1294         map.field[i][f_dat->line].special = f_dat->special[i];
1295         map.field[i][f_dat->line].frame = 0.0f;
1296         for (d = 0; d < 4; d++) {
1297             map.field[i][f_dat->line].ex[d].frame = 0.0f;
1298             map.field[i][f_dat->line].ex[d].count = 0;
1299         }
1300     }
1301 };
1302 
1303 
1304 /***
1305  *** Packettype: getplayerdata
1306  ***/
1307 void
send_getplayerdata(_net_addr * addr,int pl)1308 send_getplayerdata (_net_addr * addr, int pl)
1309 {
1310     struct pkg_getplayerdata gp_dat;
1311 
1312     gp_dat.h.typ = PKG_getplayerdata;
1313     gp_dat.h.len = HTON16 (sizeof (struct pkg_getplayerdata));
1314     gp_dat.pl_nr = pl;
1315     gp_dat.h.flags = 0;
1316     send_pkg ((struct pkg *) &gp_dat, addr);
1317 };
1318 
1319 
1320 void
do_getplayerdata(struct pkg_getplayerdata * gp_dat,_net_addr * addr)1321 do_getplayerdata (struct pkg_getplayerdata *gp_dat, _net_addr * addr)
1322 {
1323     if (addr->pl_nr == -1)
1324         return;
1325 
1326     if (gp_dat->pl_nr < 0 || gp_dat->pl_nr >= MAX_PLAYERS)
1327         return;
1328 
1329     if (addr->pl_nr != -1 && bman.state == GS_update && GT_MP_PTPM) {
1330         if (addr->pl_nr != bman.p_servnr && addr->pl_nr < MAX_PLAYERS) {
1331             players[addr->pl_nr].net.net_status = gp_dat->pl_nr;
1332             players[addr->pl_nr].net.net_istep = 1;
1333         }
1334     }
1335     send_playerdata (addr, gp_dat->pl_nr, &players[gp_dat->pl_nr]);
1336 };
1337 
1338 
1339 /***
1340  *** Packettype: playerstatus
1341  ***/
1342 void
do_playerstatus(struct pkg_playerstatus * stat,_net_addr * addr)1343 do_playerstatus (struct pkg_playerstatus *stat, _net_addr * addr)
1344 {
1345     d_printf ("do_playerstatus (%s,%s)\n", addr->host, addr->port);
1346 
1347     if (addr->pl_nr != bman.p_servnr && !(GT_MP_PTPM)) {
1348         /* the data we have got are not from the server */
1349         d_printf ("do_playerstatus: the data we have got are not from the server\n");
1350         return;
1351     }
1352     if (stat->pl_nr < 0 || stat->pl_nr >= MAX_PLAYERS) {
1353         /* the player number is wrong */
1354         d_printf ("do_playerstatus: playernumber not correct\n");
1355         return;
1356     }
1357 
1358     players[addr->pl_nr].net.net_status = stat->status;
1359     players[addr->pl_nr].net.net_istep = stat->net_istep;
1360     /*
1361        if (GT_MP_PTPM)
1362        for (i = 0; i < MAX_PLAYERS; i++)
1363        if (players[i].net.addr.host[0] != 0)
1364        send_playerstatus (addr, stat->pl_nr,
1365        stat->net_istep, stat->status);
1366      */
1367 };
1368 
1369 void
send_playerstatus(_net_addr * addr,int pl_nr,int net_istep,int status)1370 send_playerstatus (_net_addr * addr, int pl_nr, int net_istep, int status)
1371 {
1372     struct pkg_playerstatus stat;
1373 
1374     d_printf ("send_playerstatus (%s,%s) %d, %d, %d\n", addr->host,
1375               addr->port, pl_nr, net_istep, status);
1376 
1377     stat.h.typ = PKG_playerstatus;
1378     stat.h.flags = 0;
1379     stat.h.len = HTON16 (sizeof (struct pkg_playerstatus));
1380     stat.pl_nr = pl_nr;
1381     stat.net_istep = net_istep;
1382     stat.status = status;
1383 
1384     send_pkg ((struct pkg *) &stat, addr);
1385 };
1386 
1387 /***
1388  *** Packettype: updateinfo
1389  ***/
1390 void
do_updateinfo(struct pkg_updateinfo * stat,_net_addr * addr)1391 do_updateinfo (struct pkg_updateinfo *stat, _net_addr * addr)
1392 {
1393     int i;
1394 
1395     d_printf ("do_updateinfo (%s,%s)\n", addr->host, addr->port);
1396 
1397     if (addr->pl_nr != bman.p_servnr && !(GT_MP_PTPM)) {
1398         /* the data we have got are not from the server */
1399         d_printf ("do_updateinfo: the data we have got are not from the server\n");
1400         return;
1401     }
1402     for (i = 0; i < MAX_PLAYERS; i++)
1403         if ((i != bman.p_servnr) && (i != bman.p_nr)) {
1404             players[i].net.net_status = stat->status[i];
1405             players[i].net.net_istep = stat->step[i];
1406         }
1407 };
1408 
1409 void
send_updateinfo(_net_addr * addr)1410 send_updateinfo (_net_addr * addr)
1411 {
1412     struct pkg_updateinfo stat;
1413     int i;
1414     stat.h.typ = PKG_updateinfo;
1415     stat.h.flags = 0;
1416     stat.h.len = HTON16 (sizeof (struct pkg_updateinfo));
1417     for (i = 0; i < MAX_PLAYERS; i++) {
1418         stat.step[i] = players[i].net.net_istep;
1419         stat.status[i] = players[i].net.net_status;
1420     }
1421     send_pkg ((struct pkg *) &stat, addr);
1422 };
1423 
1424 
1425 /***
1426  *** Packettype: chat
1427  ***/
1428 void
do_chat(struct pkg_chat * chat_pkg,_net_addr * addr)1429 do_chat (struct pkg_chat *chat_pkg, _net_addr * addr)
1430 {
1431     d_printf ("do_chat (%s:%s) %d Text:%s\n", addr->host, addr->port, addr->pl_nr, chat_pkg->text);
1432 
1433     chat_addline (chat_pkg->text, -1);
1434 };
1435 
1436 
1437 void
send_chat(_net_addr * addr,char * text)1438 send_chat (_net_addr * addr, char *text)
1439 {
1440     struct pkg_chat chat_pkg;
1441     int i;
1442 
1443     chat_pkg.h.typ = PKG_chat;
1444     chat_pkg.h.flags = 0;
1445     chat_pkg.h.len = HTON16 (sizeof (struct pkg_chat));
1446 
1447     for (i = 0; i < sizeof (chat_pkg.text); i++)
1448         chat_pkg.text[i] = 0;
1449     strncpy (chat_pkg.text, text, sizeof (struct pkg_chat) - sizeof (struct pkg));
1450 
1451     send_pkg ((struct pkg *) &chat_pkg, addr);
1452 };
1453 
1454 
1455 /***
1456  *** Packettype: pkgack
1457  ***/
1458 void
send_pkgack(_net_addr * addr,unsigned char typ,short int id)1459 send_pkgack (_net_addr * addr, unsigned char typ, short int id)
1460 {
1461     struct pkg_pkgack p_ack;
1462 
1463     p_ack.h.typ = PKG_pkgack;
1464     p_ack.h.flags = 0;
1465     p_ack.h.len = HTON16 (sizeof (struct pkg_pkgack));
1466     p_ack.id = HTON16 (id);
1467     p_ack.typ = typ;
1468 
1469     send_pkg ((struct pkg *) &p_ack, addr);
1470 };
1471 
1472 
1473 void
do_pkgack(struct pkg_pkgack * p_ack,_net_addr * addr)1474 do_pkgack (struct pkg_pkgack *p_ack, _net_addr * addr)
1475 {
1476     d_printf ("do_pkgack pl_nr:%d type:%u id:%u\n", addr->pl_nr, p_ack->typ, p_ack->id);
1477     if ( ! rscache_del (addr, p_ack->typ, NTOH16 (p_ack->id)))
1478 		d_printf ("do_pkgack ERROR rscache_del data not found : pl_nr:%d type:%u id:%u\n", addr->pl_nr, p_ack->typ, p_ack->id);
1479 };
1480 
1481 
1482 /***
1483  *** Packettype: dropitems
1484  *** send a generated list of drop items
1485  ***/
1486 void
send_dropitems(_net_addr * addr,int pl_nr,_flyingitem ** fitems,int cnt)1487 send_dropitems (_net_addr * addr, int pl_nr, _flyingitem ** fitems, int cnt)
1488 {
1489     char outdata[BUF_SIZE];     // this should be enough memory for the outgoin data
1490     struct pkg_dropitem *dipkg = (struct pkg_dropitem *) outdata; // set the pointer to outdata
1491     int i;
1492 
1493     dipkg->h.typ = PKG_dropitem;
1494     dipkg->h.len = HTON16 (sizeof (struct pkg_dropitem) + cnt * sizeof (struct pkgdropitemelemt));
1495     dipkg->h.flags = PKGF_ackreq;
1496     dipkg->pl_nr = pl_nr;
1497     dipkg->from.x = HTON16 (FTOI16 (players[pl_nr].pos.x));
1498     dipkg->from.y = HTON16 (FTOI16 (players[pl_nr].pos.y));
1499     dipkg->count = cnt;
1500 
1501     for (i = 0; (i < cnt && fitems[i] != NULL); i++) {
1502         dipkg->items[i].x = (int) fitems[i]->to.x;
1503         dipkg->items[i].y = (int) fitems[i]->to.y;
1504         dipkg->items[i].typ = (int) fitems[i]->type;
1505     }
1506 
1507     send_pkg ((struct pkg *) dipkg, addr);
1508 };
1509 
1510 
1511 void
do_dropitems(struct pkg_dropitem * di_pkg,_net_addr * addr)1512 do_dropitems (struct pkg_dropitem *di_pkg, _net_addr * addr)
1513 {
1514     int i;
1515     _pointf from;
1516     _point to;
1517 
1518     d_printf ("do_dropitems from:%d (pl_nr %d, cnt %d)\n", addr->pl_nr, di_pkg->pl_nr,
1519               di_pkg->count);
1520     if (addr->pl_nr == -1)
1521         return;
1522     from.x = I16TOF (NTOH16 (di_pkg->from.x));
1523     from.y = I16TOF (NTOH16 (di_pkg->from.y));
1524 
1525     for (i = 0; i < di_pkg->count; i++) {
1526         to.x = di_pkg->items[i].x;
1527         to.y = di_pkg->items[i].y;
1528         flitems_additem (from, to, di_pkg->items[i].typ);
1529     }
1530 };
1531 
1532 
1533 
1534 /***
1535  *** Packettype: special
1536  *** moves/bombs... whatever will be send as we use it
1537  ***/
do_special(struct pkg_special * sp_pkg,_net_addr * addr)1538 void do_special (struct pkg_special *sp_pkg, _net_addr * addr) {
1539     d_printf ("do_special (addr %d, pl_nr %d, typ %d)\n", addr->pl_nr, sp_pkg->pl_nr, sp_pkg->typ);
1540     if (addr->pl_nr == -1 || sp_pkg->pl_nr == -1 || sp_pkg->pl_nr == bman.p_nr
1541         || sp_pkg->pl_nr == bman.p2_nr)
1542         return;
1543 
1544     /* set or use special */
1545     if (sp_pkg->typ < SP_max) {
1546         players[sp_pkg->pl_nr].special.type = sp_pkg->typ;
1547         bman.last_ex_nr = NTOH32 (sp_pkg->ex_nr);
1548         special_use (sp_pkg->pl_nr);
1549     }
1550 
1551     /* clear special */
1552     else if (sp_pkg->typ == SP_clear)
1553         players[sp_pkg->pl_nr].special.clear = 1;
1554 };
1555 
1556 
1557 void
send_special(_net_addr * addr,int p_nr,int typ,int ex_nr)1558 send_special (_net_addr * addr, int p_nr, int typ, int ex_nr)
1559 {
1560     struct pkg_special sp_dat;
1561 
1562     sp_dat.h.typ = PKG_special;
1563     sp_dat.h.len = HTON16 (sizeof (struct pkg_special));
1564     sp_dat.h.flags = PKGF_ackreq;
1565     sp_dat.pl_nr = p_nr;
1566     sp_dat.typ = typ;
1567     sp_dat.ex_nr = HTON32 (ex_nr);
1568     send_pkg ((struct pkg *) &sp_dat, addr);
1569 };
1570 
1571 
1572 /***
1573  *** Packettype: mapinfo
1574  ***/
1575 void
send_mapinfo(_net_addr * addr)1576 send_mapinfo (_net_addr * addr)
1577 {
1578     struct pkg_mapinfo map_pkg;
1579 #ifndef BUG_MAPINFO
1580 	_net_addr *test;			// VERY DIRTY WORKAROUND WHY IS HERE A BUG
1581 #endif
1582     map_pkg.h.typ = PKG_mapinfo;
1583     map_pkg.h.len = HTON16 (sizeof (struct pkg_mapinfo));
1584     map_pkg.h.flags = PKGF_ackreq;
1585     map_pkg.size_x = map.size.x;
1586     map_pkg.size_y = map.size.y;
1587     map_pkg.bombs = map.bombs;
1588     map_pkg.fire = map.fire;
1589     map_pkg.shoes = map.shoes;
1590     map_pkg.mixed = map.mixed;
1591     map_pkg.death = map.death;
1592     map_pkg.sp_trigger = map.sp_trigger;
1593     map_pkg.sp_row = map.sp_row;
1594     map_pkg.sp_push = map.sp_push;
1595     map_pkg.start_bombs = bman.start_bombs;
1596     map_pkg.start_range = bman.start_range;
1597     sprintf (map_pkg.start_speed, "%4f", bman.start_speed);
1598     sprintf (map_pkg.bomb_tickingtime, "%4f", bman.bomb_tickingtime);
1599 
1600     if (map.random_tileset)
1601         map_pkg.tileset[0] = 0;
1602     else
1603         strncpy (map_pkg.tileset, map.tileset, LEN_TILESETNAME);
1604     map_pkg.map_selection = map.map_selection;
1605     strncpy (map_pkg.mapname, map.map, LEN_FILENAME);
1606     d_printf ("send_mapinfo: Tileset: %s\n", map.tileset);
1607 #ifndef BUG_MAPINFO
1608 	test = addr;				// VERY DIRTY WORKAROUND WHY IS HERE A BUG
1609     send_pkg ((struct pkg *) &map_pkg, addr);
1610 	addr = test;				// VERY DIRTY WORKAROUND WHY IS HERE A BUG
1611 #else
1612 	printf ("Addr before send: %p\n", addr);
1613     send_pkg ((struct pkg *) &map_pkg, addr);
1614 	printf ("Addr after send: %p\n", addr);
1615 #endif
1616 };
1617 
1618 
1619 void
do_mapinfo(struct pkg_mapinfo * map_pkg,_net_addr * addr)1620 do_mapinfo (struct pkg_mapinfo *map_pkg, _net_addr * addr)
1621 {
1622     d_printf ("do_mapinfo (addr %d) size[%d,%d]\n", addr->pl_nr, map_pkg->size_x, map_pkg->size_y);
1623 
1624     /* check if the server send this information */
1625     if (addr->pl_nr != bman.p_servnr)
1626         return;
1627 
1628     if (map_pkg->tileset[0] == 0) {
1629         map.random_tileset = 1;
1630         map.tileset[0] = 0;
1631     }
1632     else {
1633         map.random_tileset = 0;
1634         strncpy (map.tileset, map_pkg->tileset, LEN_TILESETNAME);
1635     }
1636     strncpy (map.map, map_pkg->mapname, LEN_FILENAME);
1637     map.map_selection = map_pkg->map_selection;
1638     map.size.x = map_pkg->size_x;
1639     map.size.y = map_pkg->size_y;
1640     map.bombs = map_pkg->bombs;
1641     map.fire = map_pkg->fire;
1642     map.shoes = map_pkg->shoes;
1643     map.mixed = map_pkg->mixed;
1644     map.death = map_pkg->death;
1645     map.sp_trigger = map_pkg->sp_trigger;
1646     map.sp_push = map_pkg->sp_push;
1647     map.sp_row = map_pkg->sp_row;
1648 
1649     bman.start_bombs = map_pkg->start_bombs;
1650     bman.start_range = map_pkg->start_range;
1651     sscanf (map_pkg->start_speed, "%f", &bman.start_speed);
1652     sscanf (map_pkg->bomb_tickingtime, "%f", &bman.bomb_tickingtime);
1653 };
1654 
1655 
1656 /***
1657  *** Respawn Date Handling
1658  ***/
1659 void
send_respawn(_net_addr * addr,int plnr)1660 send_respawn (_net_addr * addr, int plnr)
1661 {
1662     struct pkg_respawn r_dat;
1663 
1664     r_dat.h.typ = PKG_respawn;
1665     r_dat.h.len = HTON16 (sizeof (struct pkg_respawn));
1666     r_dat.h.flags = PKGF_ackreq;
1667     r_dat.pl_nr = plnr;
1668     r_dat.state = players[plnr].state;
1669     r_dat.x = players[plnr].pos.x;
1670     r_dat.y = players[plnr].pos.y;
1671     send_pkg ((struct pkg *) &r_dat, addr);
1672 };
1673 
1674 
1675 void
do_respawn(struct pkg_respawn * r_pkg,_net_addr * addr)1676 do_respawn (struct pkg_respawn *r_pkg, _net_addr * addr)
1677 {
1678     d_printf ("do_respawn (addr %d, pl_nr %d, pos %d,%d)\n", addr->pl_nr, r_pkg->pl_nr, r_pkg->x,
1679               r_pkg->y);
1680     if (addr->pl_nr == -1 || r_pkg->pl_nr == -1)
1681         return;
1682 
1683     if ((r_pkg->state & PSF_respawn) == PSF_respawn) {
1684         players[r_pkg->pl_nr].pos.x = r_pkg->x;
1685         players[r_pkg->pl_nr].pos.y = r_pkg->y;
1686         players[r_pkg->pl_nr].state &= (0xFF - PSF_alife);
1687         players[r_pkg->pl_nr].state |= PSF_respawn;
1688         players[r_pkg->pl_nr].frame = 0.0f;
1689 
1690     }
1691     else if (r_pkg->state & (PSF_respawn + PSF_alife)) {
1692         players[r_pkg->pl_nr].pos.x = r_pkg->x;
1693         players[r_pkg->pl_nr].pos.y = r_pkg->y;
1694         players[r_pkg->pl_nr].state |= PSF_alife;
1695         players[r_pkg->pl_nr].state &= (0xFF - PSF_respawn);
1696     }
1697 };
1698 
1699 
1700 
1701 /***
1702  *** gameinfo packet is used to get some data from a running game
1703  *** just fill in the informations we need and send this packet back.
1704  ***/
1705 void
do_gameinfo(struct pkg_gameinfo * pgi,_net_addr * addr)1706 do_gameinfo (struct pkg_gameinfo *pgi, _net_addr * addr)
1707 {
1708     if (GT_MP_PTPM && pgi->password == -1) {
1709         d_printf ("do_gameinfo (from: %s:%s) Broadcast Req: %d\n", addr->host, addr->port,
1710                   pgi->broadcast);
1711 
1712         strncpy (pgi->version, VERSION, LEN_VERSION);
1713         pgi->maxplayers = bman.maxplayer;
1714         pgi->curplayers = bman.players_nr_s;
1715 		pgi->h.len = HTON16 (sizeof (struct pkg_gameinfo));
1716         strncpy (pgi->gamename, bman.gamename, LEN_GAMENAME);
1717         send_pkg ((struct pkg *) pgi, addr);
1718     }
1719     else if (pgi->password != -1)
1720         d_printf ("do_gameinfo (from: %s:%s) ** NO REQUEST **\n", addr->host, addr->port);
1721     else
1722         d_printf ("do_gameinfo (from: %s:%s) ** WE ARE NOT THE MASTER OF THIS GAME **\n",
1723                   addr->host, addr->port);
1724 }
1725 
1726 
1727 void
send_gameinfo(_net_addr * addr,int sock,int broadcast)1728 send_gameinfo (_net_addr * addr, int sock, int broadcast)
1729 {
1730     struct pkg_gameinfo pgi;
1731 
1732     pgi.h.typ = PKG_gameinfo;
1733     pgi.h.len = HTON16 (sizeof (struct pkg_gameinfo));
1734     pgi.h.flags = 0;
1735     pgi.timestamp = timestamp;
1736     pgi.gamename[0] = 0;
1737     pgi.version[0] = 0;
1738     pgi.password = -1;
1739     pgi.broadcast = broadcast;
1740 
1741     if (bman.net_ai_family != PF_INET)
1742         pgi.h.flags = pgi.h.flags | PKGF_ipv6;
1743     if (broadcast)
1744         udp_sendbroadcast (sock, (char *) &pgi, NTOH16 (pgi.h.len), &addr->sAddr,
1745                            bman.net_ai_family);
1746     else
1747         udp_send (sock, (char *) &pgi, NTOH16 (pgi.h.len), &addr->sAddr, bman.net_ai_family);
1748 };
1749 
1750 
1751 /***
1752  *** general packet handling, like check for double recived packets
1753  *** network type. Autoreply on PKGF_ackreq and such things.
1754  ***/
1755 
1756 /* check incoming packet, if we have got the same already if so return != -1
1757    if we haven't got it yet, Add to the incache and return -1 */
1758 int
inpkg_check(unsigned char typ,short int id,_net_addr * addr)1759 inpkg_check (unsigned char typ, short int id, _net_addr * addr)
1760 {
1761     int i,
1762       pos;
1763 
1764     /* check if the player is still connected */
1765     if (!PS_IS_used (players[addr->pl_nr].state))
1766         return -1;
1767 
1768     /* find packet */
1769     for (i = 0, pos = -1; (i < PKG_IN_INDEX_NUM && pos == -1); i++)
1770         if (inpkg_index[i].pl_nr == addr->pl_nr
1771             && inpkg_index[i].typ == typ && inpkg_index[i].id == id)
1772             pos = i;
1773 
1774     if (pos == -1) {
1775         /* add to index */
1776         if (++inpkg_index_pos >= PKG_IN_INDEX_NUM)
1777             inpkg_index_pos = 0;
1778 
1779         inpkg_index[inpkg_index_pos].pl_nr = addr->pl_nr;
1780         inpkg_index[inpkg_index_pos].typ = typ;
1781         inpkg_index[inpkg_index_pos].id = id;
1782     }
1783     return pos;
1784 };
1785 
1786 
1787 /* delete all old pkg indexes about a player */
1788 void
inpkg_delplayer(int pl_nr)1789 inpkg_delplayer (int pl_nr)
1790 {
1791     int i;
1792 
1793     for (i = 0; i < PKG_IN_INDEX_NUM; i++)
1794         if (inpkg_index[i].pl_nr == pl_nr)
1795             inpkg_index[i].pl_nr = -1;
1796 }
1797 
1798 
1799 /* sends the packet and if PKGF_ackreq is set add packet to the resendcache */
1800 void
send_pkg(struct pkg * packet,_net_addr * addr)1801 send_pkg (struct pkg *packet, _net_addr * addr)
1802 {
1803 	d_printf ("send_pkg: plnr:%d, typ:%u id:%u\n", addr->pl_nr, packet->h.typ, packet->h.id);
1804 
1805     /* check if the packet would be send to
1806      * an AI_Player, so ignore it. */
1807     if ((addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS)
1808         && PS_IS_aiplayer (players[addr->pl_nr].state))
1809         return;
1810 
1811     /* set the id for the packet and the network flags
1812      * the id is needed for the inpkg index to check for
1813      * double reached packets
1814      * The id is limited to 32700 if */
1815     packet->h.id = HTON16 (pkg_lastid++ % 32767);
1816     if (bman.net_ai_family != PF_INET)
1817         packet->h.flags = packet->h.flags | PKGF_ipv6;
1818     udp_send (bman.sock, (char *) packet, NTOH16 (packet->h.len), &addr->sAddr, bman.net_ai_family);
1819 
1820     /* if PKGF_ackreq is set add the packet to the resendcache
1821      * so we can resend it if no PKF_ackreq returned for the packet. */
1822     if (packet->h.flags & PKGF_ackreq)
1823 		rscache_add (addr, packet);
1824 };
1825 
1826 
1827 /* forward the packet to all who are behind a firewall */
1828 void
fwd_pkg(struct pkg * packet,_net_addr * addr)1829 fwd_pkg (struct pkg *packet, _net_addr * addr)
1830 {
1831     int pl;
1832 
1833     if (GT_MP_PTPS)             /* clients don't forward anything */
1834         return;
1835 
1836     if (packet->h.typ >= PKG_field && packet->h.typ < PKG_quit) {
1837         for (pl = 0; pl < MAX_PLAYERS; pl++)
1838             if ((!PS_IS_aiplayer (players[pl].state)) && PS_IS_netplayer (players[pl].state)
1839                 && ((players[addr->pl_nr].net.flags & NETF_firewall) == NETF_firewall
1840                     || (players[pl].net.flags & NETF_firewall) == NETF_firewall)
1841                 && pl != addr->pl_nr && (players[pl].net.flags & NETF_local2) == 0)
1842                 send_pkg (packet, &players[pl].net.addr);
1843     }
1844     else if (packet->h.typ > PKG_quit)
1845         d_fatal ("fwd_pkg: not forwarding unknown packet From Player:%d (%s) Typ:%d Len:%d\n",
1846                  addr->pl_nr, players[addr->pl_nr].name, packet->h.typ, NTOH16 (packet->h.len));
1847 };
1848 
1849 
1850 /* entry point for all incoming network data. determinate packet type and
1851    forward it to all needed functions, like inpkg_check()--> send answer if needed,
1852    if we are the server then forward the packet if needed
1853    and go into the do_PACKETTYP function */
1854 void
do_pkg(struct pkg * packet,_net_addr * addr,int len)1855 do_pkg (struct pkg *packet, _net_addr * addr, int len)
1856 {
1857     d_printf ("do_pkg: plnr:%d, typ:%u id:%u\n", addr->pl_nr, packet->h.typ, packet->h.id);
1858     if (((packet->h.flags & PKGF_ipv6) == 0 && bman.net_ai_family != PF_INET)
1859         || ((packet->h.flags & PKGF_ipv6) != 0 && bman.net_ai_family == PF_INET)) {
1860         d_printf ("do_pkg: packet comes from the wrong network type\n");
1861         return;
1862     }
1863 
1864 	/* Check the size of the incoming packet */
1865 	if (len != NTOH16(packet->h.len)) {
1866         d_printf ("do_pkg: len(%d) of the incoming packet is not the same as in pkg->h.len(%d)\n", len, NTOH16(packet->h.len));
1867         return;
1868 	}
1869 
1870     /* get the addr and set the ping timeout value
1871      * check if the packet is from a player in the game and not from someone else
1872      * this exception is only for PKG_joingame, PKG_error */
1873     addr->pl_nr = get_player_nr (addr->host, addr->port);
1874     if ((addr->pl_nr < 0 || addr->pl_nr >= MAX_PLAYERS) && packet->h.typ > PKG_joingame
1875         && PS_IS_netplayer (players[addr->pl_nr].state)) {
1876         d_printf ("do_pkg: error addr->pl_nr out of range\n");
1877         return;
1878     }
1879 
1880     if (addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) {
1881         players[addr->pl_nr].net.timestamp = timestamp;
1882         players[addr->pl_nr].net.pingreq = players[addr->pl_nr].net.pingack + 5;
1883 
1884         /* test if we have any important packet */
1885         if (packet->h.flags & PKGF_ackreq) {
1886 
1887             /* we need to send an acknolege so the client
1888              * knows we have got this packet and delete
1889              * it from the resend cache. */
1890             send_pkgack (addr, packet->h.typ, NTOH16 (packet->h.id));
1891 
1892             /* check the packet with the index so we can
1893              * ignore packets we already have got
1894              * this is important to keep away from
1895              * the bomb is dropped twice bug. */
1896             if (inpkg_check (packet->h.typ, NTOH16 (packet->h.id), addr) != -1) {
1897                 /* we have got this packet already */
1898                 d_printf ("do_pkg: double packet ignoring addr->pl_nr=%d type:%d\n", addr->pl_nr, packet->h.typ);
1899                 if (addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS)
1900                     players[addr->pl_nr].net.pkgopt.to_2sec++;
1901                 return;
1902             }
1903         }
1904 
1905         /* forward packet */
1906         if (GT_MP_PTPM)
1907             fwd_pkg (packet, addr);
1908     }
1909 
1910     switch (packet->h.typ) {
1911     case (PKG_error):
1912         do_error ((struct pkg_error *) packet, addr);
1913         break;
1914     case (PKG_gameinfo):
1915         do_gameinfo ((struct pkg_gameinfo *) packet, addr);
1916         break;
1917     case (PKG_playerid):
1918         do_playerid ((struct pkg_playerid *) packet, addr);
1919         break;
1920     case (PKG_servermode):
1921         do_servermode ((struct pkg_servermode *) packet, addr);
1922         break;
1923     case (PKG_field):
1924         do_field ((struct pkg_field *) packet, addr);
1925         break;
1926     case (PKG_contest):
1927         do_contest ((struct pkg_contest *) packet, addr);
1928         break;
1929     case (PKG_pingreq):
1930         do_ping ((struct pkg_ping *) packet, addr);
1931         break;
1932     case (PKG_pingack):
1933         do_ping ((struct pkg_ping *) packet, addr);
1934         break;
1935     case (PKG_bombdata):
1936         do_bombdata ((struct pkg_bombdata *) packet, addr);
1937         break;
1938     case (PKG_playerdata):
1939         do_playerdata ((struct pkg_playerdata *) packet, addr);
1940         break;
1941     case (PKG_quit):
1942         do_quit ((struct pkg_quit *) packet, addr);
1943         break;
1944     case (PKG_getfield):
1945         do_getfield ((struct pkg_getfield *) packet, addr);
1946         break;
1947     case (PKG_getplayerdata):
1948         do_getplayerdata ((struct pkg_getplayerdata *) packet, addr);
1949         break;
1950     case (PKG_fieldline):
1951         do_fieldline ((struct pkg_fieldline *) packet, addr);
1952         break;
1953     case (PKG_playerstatus):
1954         do_playerstatus ((struct pkg_playerstatus *) packet, addr);
1955         break;
1956     case (PKG_pkgack):
1957         do_pkgack ((struct pkg_pkgack *) packet, addr);
1958         break;
1959     case (PKG_chat):
1960         do_chat ((struct pkg_chat *) packet, addr);
1961         break;
1962     case (PKG_playermove):
1963         do_playermove ((struct pkg_playermove *) packet, addr);
1964         break;
1965     case (PKG_ill):
1966         do_ill ((struct pkg_ill *) packet, addr);
1967         break;
1968     case (PKG_special):
1969         do_special ((struct pkg_special *) packet, addr);
1970         break;
1971     case (PKG_mapinfo):
1972         do_mapinfo ((struct pkg_mapinfo *) packet, addr);
1973         break;
1974     case (PKG_tunneldata):
1975         do_tunneldata ((struct pkg_tunneldata *) packet, addr);
1976         break;
1977     case (PKG_joingame):
1978         do_joingame ((struct pkg_joingame *) packet, addr);
1979         break;
1980     case (PKG_dropitem):
1981         do_dropitems ((struct pkg_dropitem *) packet, addr);
1982         break;
1983     case (PKG_respawn):
1984         do_respawn ((struct pkg_respawn *) packet, addr);
1985         break;
1986     case (PKG_updateinfo):
1987         do_updateinfo ((struct pkg_updateinfo *) packet, addr);
1988         break;
1989     case (PKG_teamdata):
1990         do_teamdata ((struct pkg_teamdata *) packet, addr);
1991         break;
1992     default:
1993         send_error (addr, "BomberClone: unknown data packet");
1994         break;
1995     }
1996 };
1997