From 5fce04d2fdbb35d4c6f0e1a0bdd3a66435c5c7ba Mon Sep 17 00:00:00 2001 From: stpohle Date: Sun, 9 Nov 2003 03:56:56 +0000 Subject: [PATCH] AI player are able to run in multiplayer games.. --- include/basic.h | 6 +- include/network.h | 7 +- include/packets.h | 26 +++-- src/debug.c | 12 +- src/game.c | 5 +- src/multiwait.c | 10 +- src/netmenu.c | 2 +- src/network.c | 75 +++++++------ src/packets.c | 278 ++++++++++++++++++++++++++++++---------------- src/single.c | 11 +- 10 files changed, 278 insertions(+), 154 deletions(-) diff --git a/include/basic.h b/include/basic.h index 30b70e9..b12aa95 100644 --- a/include/basic.h +++ b/include/basic.h @@ -1,4 +1,4 @@ -/* $Id: basic.h,v 1.7 2003/11/08 19:53:06 stpohle Exp $ */ +/* $Id: basic.h,v 1.8 2003/11/09 03:56:56 stpohle Exp $ */ /* basic types which we need everywhere */ #ifndef _BC_BASIC_H_ @@ -186,9 +186,10 @@ enum _bombmode { enum _playerstateflags { // not Set | Set PSF_used = 1, // Player Unused | Player Used - PSF_net = 2, // Local Player | AI / Network Player + PSF_net = 2, // Local Player | Network Player PSF_alife = 4, // Player is Dead | Player is Alife PSF_playing = 8, // Watching Player| Playing Player -- as long as one don't delete + PSF_ai = 16 // | AI Player }; #define PSFM_used (PSF_used + PSF_playing) @@ -198,6 +199,7 @@ enum _playerstateflags { // not Set | Set #define PS_IS_netplayer(__ps) (((__ps) & (PSF_net)) != 0) #define PS_IS_playing(__ps) (((__ps) & (PSFM_used)) == (PSFM_used)) #define PS_IS_used(__ps) (((__ps) & (PSFM_used)) != 0) +#define PS_IS_aiplayer(__ps) ((((__ps) & (PSFM_used)) != 0) && (((__ps) & (PSF_ai)) == PSF_ai)) enum _direction { // to handle directions better diff --git a/include/network.h b/include/network.h index 506fb7a..1a7009d 100644 --- a/include/network.h +++ b/include/network.h @@ -53,7 +53,7 @@ network.h file... for everything what have to do with the network stuff #define _sockaddr sockaddr_in6 #endif -struct __net_addr { // this holds the network data +struct { // this holds the network data char host[LEN_SERVERNAME]; char port[LEN_PORT]; struct _sockaddr sAddr; @@ -61,7 +61,7 @@ struct __net_addr { // this holds the network data } typedef _net_addr; -struct __net_pkgopt { /* this will hold all needed data for the packet +struct { /* this will hold all needed data for the packet timeout function */ signed char send_to; // sending packet data (playermove) on 0 it will be send signed char send_set; // start value for the packet data option (dynamic set) @@ -69,7 +69,8 @@ struct __net_pkgopt { /* this will hold all needed data for the packet Uint32 to_timestamp; } typedef _net_pkgopt; -struct __net_player { + +struct { _net_addr addr; // holds the address int pingreq; // just to send a ping and to save the number in here int pingack; // just to wait for an ping reply.. it will show up here diff --git a/include/packets.h b/include/packets.h index f38c707..d37468d 100644 --- a/include/packets.h +++ b/include/packets.h @@ -6,6 +6,7 @@ enum _network_data { PKG_pingack, PKG_playerid, PKG_servermode, + PKG_joingame, PKG_quit, PKG_field, PKG_playerdata, @@ -107,9 +108,20 @@ struct pkg_servermode { signed char fieldsize_x; signed char fieldsize_y; char tileset[LEN_TILESETNAME]; - signed char pl_nr; /* if the server sends this to a client... - it will be the clients in_nr number - (-1) for not set */ + signed char p_servnr; + signed char p_nr; /* if the server sends this to a client... + it will be the clients in_nr number + (-1) for not set */ +}; + + +struct pkg_joingame { + struct pkgheader h; + signed char ver_major; // Version + signed char ver_minor; // Version + signed char ver_sub; // Version + signed char netflags; + char name[LEN_PLAYERNAME]; }; @@ -118,22 +130,18 @@ struct pkg_playerid { char name[LEN_PLAYERNAME]; char host[LEN_SERVERNAME]; char port[LEN_PORT]; - signed char ver_major; // Version - signed char ver_minor; // Version - signed char ver_sub; // Version signed char pl_nr; // Player Nummer signed char gfx_nr; // number of the graphic signed char state; Sint16 points; Sint16 wins; - signed char netflags; }; struct pkg_playerdata { struct pkgheader h; signed char p_nr; // Playernumber - Sint16 points; // points + Sint16 points; // points Sint16 wins; // how many times we win signed char gfx_nr; // the gfx number we want to use _point pos; @@ -274,6 +282,7 @@ struct _inpkg_index { extern int do_error (struct pkg_error *data, _net_addr *addr); extern void do_playerid (struct pkg_playerid *p_id, _net_addr *addr); extern void do_servermode (struct pkg_servermode *s_mod, _net_addr *addr); +extern void do_joingame (struct pkg_joingame *p_jg, _net_addr * addr); extern void do_field (struct pkg_field *f_dat, _net_addr *addr); extern void do_ping (struct pkg_ping *p_dat, _net_addr *addr); extern void do_playerdata (struct pkg_playerdata *p_dat, _net_addr *addr); @@ -296,6 +305,7 @@ extern void do_tunneldata (struct pkg_tunneldata *tun_pkg, _net_addr *addr); extern void send_pkg (struct pkg *packet, _net_addr *addr); extern void send_playerid (_net_addr *addr, char *name, char *pladdr, char *plport, int p_nr, int gfx_nr, signed char netflags); extern void send_servermode (_net_addr *addr, int pl_nr); +extern void send_joingame (_net_addr * addr, char *name); extern void send_error (_net_addr *addr, char *text); extern void send_field (_net_addr *addr, int x, int y, _field * field); extern void send_ping (_net_addr *addr, int data, unsigned char typ); diff --git a/src/debug.c b/src/debug.c index cb0f6c7..6580d5b 100644 --- a/src/debug.c +++ b/src/debug.c @@ -8,11 +8,13 @@ int debug; void d_gamedetail (char *head) { d_playerdetail (head); - d_printf ("bman.players_nr = %d\n", bman.players_nr); - d_printf ("bman.players_nr_s = %d\n", bman.players_nr_s); - d_printf ("bman.gametype = %d\n", bman.gametype); - d_printf ("bman.multitype = %d\n", bman.multitype); - d_printf ("bman.state = %d\n", bman.state); + d_printf ("p_nr = %d ", bman.p_nr); + d_printf ("p_servnr = %d \n", bman.p_servnr); + d_printf ("players_nr = %d ", bman.players_nr); + d_printf ("players_nr_s = %d \n", bman.players_nr_s); + d_printf ("gametype = %d ", bman.gametype); + d_printf ("multitype = %d \n", bman.multitype); + d_printf ("state = %d\n", bman.state); }; diff --git a/src/game.c b/src/game.c index 424c433..24b24a4 100644 --- a/src/game.c +++ b/src/game.c @@ -1,4 +1,4 @@ -/* $Id: game.c,v 1.58 2003/11/08 06:27:58 stpohle Exp $ +/* $Id: game.c,v 1.59 2003/11/09 03:56:56 stpohle Exp $ game.c - procedures for the game. */ #include @@ -211,7 +211,8 @@ game_loop () if (GT_MP) network_loop (); - single_loop (); + if (bman.state == GS_running) + single_loop (); /* this will even set the variable "bman.player_nr" to let us know how much Players are still left */ diff --git a/src/multiwait.c b/src/multiwait.c index 8ca6163..1aedc77 100644 --- a/src/multiwait.c +++ b/src/multiwait.c @@ -371,7 +371,7 @@ wait_for_players () bman.updatestatusbar = 1; } - if (keys[SDLK_F5] && (!keypressed)) { + if (keys[SDLK_F2] && (!keypressed)) { /* Map modification or setting display */ if (GT_MP_PTPM) { mapmenu (); @@ -387,6 +387,14 @@ wait_for_players () chat_drawbox (); mw_draw_chat (); } + + if ((GT_MP_PTPM) && keys[SDLK_F3] && (!keypressed)) { + single_create_ai (1); + for (i = 0; i < MAX_PLAYERS; i++) + net_change_playerid (i, GT_MP_PTPM); + bman.updatestatusbar = 1; + } + chat_loop (&event); } diff --git a/src/netmenu.c b/src/netmenu.c index c487920..659d11d 100644 --- a/src/netmenu.c +++ b/src/netmenu.c @@ -213,12 +213,12 @@ multiplayer_firstrun () void host_multiplayer_game () { - if (bman.firewall) { menu_displaymessage ("Firewall Option", "You can't start a game with Firewall enabled."); return; } + bman.servername[0] = 0; // delete servername multiplayer_firstrun (); while (bman.state != GS_startup && bman.state != GS_quit) { diff --git a/src/network.c b/src/network.c index ede354c..83a40db 100644 --- a/src/network.c +++ b/src/network.c @@ -1,4 +1,4 @@ -/* $Id: network.c,v 1.43 2003/11/08 06:27:59 stpohle Exp $ */ +/* $Id: network.c,v 1.44 2003/11/09 03:56:56 stpohle Exp $ */ /* network routines. */ @@ -60,7 +60,7 @@ net_dyn_pkgoption () _net_pkgopt *npkg; for (p = 0; p < MAX_PLAYERS; p++) - if (PS_IS_netplayer (players[p].state)) { + if (PS_IS_netplayer (players[p].state) && !PS_IS_aiplayer(players[p].state)) { npkg = &players[p].net.pkgopt; if (npkg->to_2sec > DYN_PKG_MAX_MISSING) { @@ -102,7 +102,16 @@ network_init () #endif bman.sock = -1; - bman.p_nr = -1; + + /* set playernumber and server playernumber */ + if (bman.servername[0] == 0) { // we are the server + bman.p_servnr = 0; + bman.p_nr = 0; + } + else { + bman.p_servnr = 0; // to make sure GT_MP_PTPM/S is working right + bman.p_nr = -1; + } timestamp = SDL_GetTicks (); @@ -133,7 +142,7 @@ network_init () return -1; } - // we have got out socket.. so now allocate the memory for the resend_cache + // we have got our socket.. so now allocate the memory for the resend_cache resend_cache.data = (char *) malloc (PKG_RESENDCACHE_SIZE); resend_cache.fill = 0; @@ -144,10 +153,7 @@ network_init () players[0].state = PSF_used; if (bman.notifygamemaster) gamesrv_sendmode (bman.maxplayer, 1); - } - - // if client send Data to the server - if (GT_MP_PTPS) { + } else { network_server_port (bman.servername, players[0].net.addr.host, LEN_SERVERNAME, players[0].net.addr.port, LEN_PORT); @@ -163,7 +169,7 @@ network_init () i = NETF_firewall; else i = 0; - send_playerid (&players[0].net.addr, bman.playername, NULL, NULL, -1, -1, i); + send_joingame (&players[0].net.addr, bman.playername); } return 0; @@ -185,8 +191,8 @@ network_shutdown () if (bman.notifygamemaster) gamesrv_quit (); } - else if (players[0].net.addr.host[0] != 0) - send_quit (&players[0].net.addr, NULL, NULL); + else if (players[bman.p_servnr].net.addr.host[0] != 0) + send_quit (&players[bman.p_servnr].net.addr, NULL, NULL); udp_close (bman.sock); @@ -209,7 +215,7 @@ net_check_timeout (int pl_nr) { int timeout = UDP_TIMEOUT; - if ((players[pl_nr].state & (PSF_net + PSF_used)) == (PSF_used + PSF_net) + if ((players[pl_nr].state & (PSF_net + PSF_used + PSF_ai)) == (PSF_used + PSF_net) && timestamp - players[pl_nr].net.timestamp > timeout && players[pl_nr].net.pingreq != players[pl_nr].net.pingack) { d_printf ("net_check_timeout pl_nr=%d, ack=%d, req=%d, timediff=%d\n", pl_nr, @@ -220,7 +226,7 @@ net_check_timeout (int pl_nr) send_ping (&players[pl_nr].net.addr, players[pl_nr].net.pingack + 100, PKG_pingreq); } - if ((players[pl_nr].state & (PSF_net + PSF_used)) == (PSF_used + PSF_net) + if ((players[pl_nr].state & (PSF_net + PSF_used + PSF_ai)) == (PSF_used + PSF_net) && timestamp - players[pl_nr].net.timestamp > timeout && players[pl_nr].net.pingreq == players[pl_nr].net.pingack) { d_printf ("net_check_timeout pl_nr=%d, ack=%d, req=%d, timediff=%d\n", pl_nr, @@ -369,7 +375,7 @@ net_change_playerid (int pl_nr, unsigned char senddata) Send to all connected clients the update */ for (i = 1; i < MAX_PLAYERS; i++) - if (players[i].net.addr.host[0] != 0) + if (!PS_IS_aiplayer (players[i].state) && players[i].net.addr.host[0] != 0) send_playerid (&players[i].net.addr, players[pl_nr].name, players[pl_nr].net.addr.host, players[pl_nr].net.addr.port, pl_nr, players[pl_nr].gfx_nr, players[pl_nr].net.flags); @@ -379,7 +385,7 @@ net_change_playerid (int pl_nr, unsigned char senddata) Send only to the Server the update and only if in_nr == bman.in_nr */ if (pl_nr == bman.p_nr && senddata) - send_playerid (&players[0].net.addr, players[pl_nr].name, + send_playerid (&players[bman.p_servnr].net.addr, players[pl_nr].name, players[pl_nr].net.addr.host, players[pl_nr].net.addr.port, pl_nr, players[pl_nr].gfx_nr, players[pl_nr].net.flags); } @@ -422,7 +428,10 @@ net_transmit_gamedata () for (x = 0; x < MAX_PLAYERS; x++) { players[x].net.timestamp = 0; players[x].net.net_status = -1; - players[x].net.net_istep = 3; + if (PS_IS_aiplayer (players[x].state)) + players[x].net.net_istep = 0; + else + players[x].net.net_istep = 3; } y = -1; @@ -457,7 +466,7 @@ net_transmit_gamedata () || y == -1) { y++; downtimestamp = timestamp; - send_tunneldata (&players[0].net.addr, y, -1, -1); + send_tunneldata (&players[bman.p_servnr].net.addr, y, -1, -1); } else if (y < GAME_MAX_TUNNELS && y != players[bman.p_nr].net.net_status && y >= 0 && timestamp - downtimestamp > DOWNLOAD_TIMEOUT) { @@ -481,7 +490,7 @@ net_transmit_gamedata () /* send field data req */ y++; downtimestamp = timestamp; - send_getfield (&players[0].net.addr, y); + send_getfield (&players[bman.p_servnr].net.addr, y); } else if (y < map.size.y && y != players[bman.p_nr].net.net_status && y >= 0 && timestamp - downtimestamp > DOWNLOAD_TIMEOUT) { @@ -504,7 +513,7 @@ net_transmit_gamedata () /* send player date req */ y++; downtimestamp = timestamp; - send_getplayerdata (&players[0].net.addr, y); + send_getplayerdata (&players[bman.p_servnr].net.addr, y); } if (y < MAX_PLAYERS && y != players[bman.p_nr].net.net_status && y >= 0 && timestamp - downtimestamp > DOWNLOAD_TIMEOUT) { @@ -517,14 +526,14 @@ net_transmit_gamedata () players[bman.p_nr].net.net_istep = --net_istep; players[bman.p_nr].net.net_status = -1; downtimestamp = timestamp; - send_playerstatus (&players[0].net.addr, bman.p_nr, 0, 0); + send_playerstatus (&players[bman.p_servnr].net.addr, bman.p_nr, 0, 0); } } if (net_istep == 0 && players[bman.p_nr].net.net_status == -1 && timestamp - downtimestamp > DOWNLOAD_TIMEOUT) { /* server did not send informations back */ downtimestamp = timestamp; - send_playerstatus (&players[0].net.addr, bman.p_nr, 0, 0); + send_playerstatus (&players[bman.p_servnr].net.addr, bman.p_nr, 0, 0); } } @@ -573,7 +582,7 @@ net_game_send_player (int p_nr) if (GT_MP_PTPM) { for (p = 0; p < MAX_PLAYERS; p++) - if (PS_IS_netplayer (players[p].state) && p != bman.p_nr) + if (!PS_IS_aiplayer (players[p].state) && PS_IS_netplayer (players[p].state) && p != bman.p_nr) send_playerdata (&players[p].net.addr, p_nr, &players[p_nr]); } else if (p_nr == bman.p_nr) { @@ -591,7 +600,7 @@ net_game_send_playermove (int p_nr, int mustsend) _player *pl; for (p = 0; p < MAX_PLAYERS; p++) - if (PS_IS_netplayer (players[p].state) && p != bman.p_nr) { + if (!PS_IS_aiplayer (players[p].state) && PS_IS_netplayer (players[p].state) && p != bman.p_nr) { pl = &players[p_nr]; pl->net.pkgopt.send_to--; @@ -619,7 +628,7 @@ net_game_send_bomb (int p, int b) return; for (pl = 0; pl < MAX_PLAYERS; pl++) - if (PS_IS_netplayer (players[pl].state) && pl != bman.p_nr && NET_CANSEND(pl)) + if (!PS_IS_aiplayer (players[pl].state) && PS_IS_netplayer (players[pl].state) && pl != bman.p_nr && NET_CANSEND(pl)) send_bombdata (&players[pl].net.addr, p, b, &players[p].bombs[b]); }; @@ -635,7 +644,7 @@ net_game_send_field (int x, int y) return; for (pl = 0; pl < MAX_PLAYERS; pl++) - if (PS_IS_netplayer (players[pl].state) && pl != bman.p_nr && NET_CANSEND(pl)) + if (!PS_IS_aiplayer (players[pl].state) && PS_IS_netplayer (players[pl].state) && pl != bman.p_nr && NET_CANSEND(pl)) send_field (&players[pl].net.addr, x, y, &map.field[x][y]); }; @@ -669,7 +678,7 @@ net_delplayer (int pl_nr) if (GT_MP_PTPM && (GS_WAITRUNNING || bman.state == GS_update)) { for (i = 1; i < MAX_PLAYERS; i++) - if (PS_IS_netplayer (players[i].state)) { + if (!PS_IS_aiplayer (players[i].state) && PS_IS_netplayer (players[i].state)) { send_quit (&players[i].net.addr, host, port); j++; } @@ -694,7 +703,7 @@ net_game_fillsockaddr () int i; for (i = 0; i < MAX_PLAYERS; i++) - if (players[i].net.addr.host[0] != 0 && players[i].net.addr.host[0] != 0) + if (!PS_IS_aiplayer (players[i].state) && players[i].net.addr.host[0] != 0 && players[i].net.addr.host[0] != 0) dns_filladdr (players[i].net.addr.host, LEN_SERVERNAME, players[i].net.addr.port, LEN_PORT, bman.net_ai_family, &players[i].net.addr.sAddr); @@ -707,7 +716,7 @@ net_send_servermode () int i; for (i = 0; i < MAX_PLAYERS; i++) - if (PS_IS_netplayer (players[i].state) && i != bman.p_nr && NET_CANSEND(i)) + if (!PS_IS_aiplayer (players[i].state) && PS_IS_netplayer (players[i].state) && i != bman.p_nr && NET_CANSEND(i)) send_servermode (&players[i].net.addr, i); if (GT_MP_PTPM && bman.notifygamemaster) /* send notification the the gamemaster */ @@ -723,7 +732,7 @@ net_send_players () j; for (j = 0; j < MAX_PLAYERS; j++) - if (PS_IS_netplayer (players[j].state) && j != bman.p_nr) + if (!PS_IS_aiplayer (players[j].state) && PS_IS_netplayer (players[j].state) && j != bman.p_nr) for (i = 0; i < MAX_PLAYERS; i++) send_playerid (&players[j].net.addr, players[i].name, players[i].net.addr.host, players[i].net.addr.port, i, @@ -739,7 +748,7 @@ net_send_chat (char *text, signed char notigamesrv) int i; for (i = 0; i < MAX_PLAYERS; i++) - if (PS_IS_netplayer (players[i].state) && i != bman.p_nr && NET_CANSEND(i)) + if (!PS_IS_aiplayer (players[i].state) && PS_IS_netplayer (players[i].state) && i != bman.p_nr && NET_CANSEND(i)) send_chat (&players[i].net.addr, text); if (GT_MP_PTPM && bman.notifygamemaster && notigamesrv == 1 && bman.broadcasted_chat) /* send notification the the gamemaster */ @@ -755,7 +764,7 @@ net_game_send_ill (int p_nr) d_printf ("net_game_send_ill (%d)\n", p_nr); for (i = 0; i < MAX_PLAYERS; i++) - if (PS_IS_netplayer (players[i].state) && i != bman.p_nr && NET_CANSEND(i)) + if (!PS_IS_aiplayer (players[i].state) && PS_IS_netplayer (players[i].state) && i != bman.p_nr && NET_CANSEND(i)) send_ill (&players[i].net.addr, p_nr, &players[p_nr]); }; @@ -799,7 +808,7 @@ net_game_send_special (int pl_nr, int ex_nr) return; for (pl = 0; pl < MAX_PLAYERS; pl++) - if (PS_IS_netplayer (players[pl].state) && pl != pl_nr && NET_CANSEND(pl)) + if (!PS_IS_aiplayer (players[pl].state) && PS_IS_netplayer (players[pl].state) && pl != pl_nr && NET_CANSEND(pl)) send_special (&players[pl].net.addr, pl_nr, players[pl_nr].special.type, ex_nr); }; @@ -816,6 +825,6 @@ net_send_mapinfo () d_printf ("Send Mapinfo\n"); for (i = 0; i < MAX_PLAYERS; i++) - if (PS_IS_netplayer (players[i].state) && i != bman.p_nr && NET_CANSEND(i)) + if (!PS_IS_aiplayer (players[i].state) && PS_IS_netplayer (players[i].state) && i != bman.p_nr && NET_CANSEND(i)) send_mapinfo (&players[i].net.addr); }; diff --git a/src/packets.c b/src/packets.c index da69a45..25be992 100644 --- a/src/packets.c +++ b/src/packets.c @@ -70,13 +70,13 @@ do_error (struct pkg_error *data, _net_addr * addr) }; + /*** - *** Packettype: pingack/pingreq - *** Update Playerinformation, add players into the current game + *** Packettype: joingame + *** client sends this to the server if he want's to join ***/ void -do_playerid (struct pkg_playerid *p_id, _net_addr * addr) -{ +do_joingame (struct pkg_joingame *p_jg, _net_addr * addr) { _player *pl; int i, j, @@ -87,50 +87,22 @@ do_playerid (struct pkg_playerid *p_id, _net_addr * addr) sscanf (VERSION, "%d.%d.%d", &vma, &vmi, &vsu); - if (p_id->ver_sub != vsu || p_id->ver_major != vma || p_id->ver_minor != vmi) { + if (p_jg->ver_sub != vsu || p_jg->ver_major != vma || p_jg->ver_minor != vmi) { sprintf (text, "Version Error - Host/Server Version: %s", VERSION); send_error (addr, text); return; } + if (GT_MP_PTPS) { + sprintf (text, "Sorry this is a client and not a server."); + send_error (addr, text); + return; + } + d_printf - ("do_playerid (From:%s:%s pl_nr=%d) Player(name:%s [%s:%s], pl_nr:%d)\n", - addr->host, addr->port, addr->pl_nr, p_id->name, p_id->host, p_id->port, p_id->pl_nr); - - /* As Server/Master Only change settings, or do ignore them if we are not in GS_wait */ - if (((GT_MP_PTPM && (bman.state == GS_wait && addr->pl_nr != -1)) || // PTPM change setting - (GT_MP_PTPS && addr->pl_nr == 0)) && p_id->pl_nr >= 0 && p_id->pl_nr < MAX_PLAYERS) { // PTPS and information send by PTPM - - pl = &players[p_id->pl_nr]; - - pl->state = p_id->state; - if (p_id->pl_nr != bman.p_nr && PS_IS_used (pl->state)) - pl->state |= PSF_net; - else - pl->state &= (0xff - PSF_net); - - player_set_gfx (pl, p_id->gfx_nr); - strncpy (pl->name, p_id->name, LEN_PLAYERNAME); - pl->net.timestamp = timestamp; - pl->net.pingreq = pl->net.pingack + 5; - pl->net.flags = p_id->netflags; - - if (p_id->host[0] != 0) { - pl->net.addr.pl_nr = addr->pl_nr; - strncpy (pl->net.addr.host, p_id->host, LEN_SERVERNAME); - strncpy (pl->net.addr.port, p_id->port, LEN_PORT); - dns_filladdr (pl->net.addr.host, LEN_SERVERNAME, - pl->net.addr.port, LEN_PORT, bman.net_ai_family, &pl->net.addr.sAddr); - } - - if (GT_MP_PTPS) { - pl->points = NTOH16 (p_id->points); - pl->wins = NTOH16 (p_id->wins); - } - } - - /* add player into the list if there is something free */ - else if ((addr->pl_nr == -1 || p_id->pl_nr == -1) && GS_WAITRUNNING && GT_MP_PTPM) { + ("do_joingame (From:%s:%s Player(name:%s)\n", addr->host, addr->port, p_jg->name); + /* find a free place for the player and add the player to the game*/ + if ((addr->pl_nr == -1) && GS_WAITRUNNING && GT_MP_PTPM) { /* find free player slot */ if (addr->pl_nr == -1) for (i = 0; (i < MAX_PLAYERS && PS_IS_used (players[i].state)); i++); @@ -138,19 +110,19 @@ do_playerid (struct pkg_playerid *p_id, _net_addr * addr) i = addr->pl_nr; if ((i < MAX_PLAYERS) && (i < bman.maxplayer)) { - /* free in_pl slot ... fill in data */ + /* free player slot found ... fill in data */ pl = &players[i]; pl->state = PSF_used + PSF_net; - if (strncmp (pl->name, p_id->name, LEN_PLAYERNAME) == 0) - d_printf ("***** Player ReJoined : Nr:[%d] Name:%10s\n", i, p_id->name); + if (strncmp (pl->name, p_jg->name, LEN_PLAYERNAME) == 0) + d_printf (" Player ReJoined : Nr:[%d] Name:%10s\n", i, p_jg->name); else { - d_printf ("***** Player Added : Nr:[%d] Name:%10s\n", i, p_id->name); + d_printf (" Player Added : Nr:[%d] Name:%10s\n", i, p_jg->name); pl->points = 0; pl->wins = 0; } - strncpy (pl->name, p_id->name, LEN_PLAYERNAME); - player_set_gfx (pl, p_id->gfx_nr); + strncpy (pl->name, p_jg->name, LEN_PLAYERNAME); + player_set_gfx (pl, -1); /* Reset the network data */ pl->net.timestamp = timestamp; @@ -163,26 +135,28 @@ do_playerid (struct pkg_playerid *p_id, _net_addr * addr) strncpy (pl->net.addr.port, addr->port, LEN_PORT); dns_filladdr (pl->net.addr.host, LEN_SERVERNAME, pl->net.addr.port, LEN_PORT, bman.net_ai_family, &pl->net.addr.sAddr); - pl->net.flags = p_id->netflags; + pl->net.flags = p_jg->netflags; pl->net.addr.pl_nr = i; bman.players_nr_s++; /* send to the new client the servermode and the complete playerlist */ send_servermode (addr, i); send_mapinfo (addr); - for (j = 0; j < MAX_PLAYERS; j++) - if (players[j].net.addr.host[0] != 0 || players[j].name[0] != 0) - send_playerid (addr, players[j].name, - players[j].net.addr.host, - players[j].net.addr.port, j, - players[j].gfx_nr, players[i].net.flags); - - addr->pl_nr = i; + + addr->pl_nr = i; for (j = 0, i = 0; i < bman.maxplayer; i++) if (PS_IS_used (players[i].state)) j++; - if (bman.notifygamemaster) + + if (bman.notifygamemaster) gamesrv_sendmode (bman.maxplayer, j); + + /* Send all connected players the new PlayerID */ + for (i = 0; i < MAX_PLAYERS; i++) + if (i != bman.p_servnr && i != pl->net.addr.pl_nr && PS_IS_netplayer (players[i].state)) + send_playerid (&players[i].net.addr, pl->name, pl->net.addr.host, pl->net.addr.port, pl->net.addr.pl_nr, pl->gfx_nr, pl->net.flags); + + } else if (GS_WAITRUNNING) { @@ -191,17 +165,100 @@ do_playerid (struct pkg_playerid *p_id, _net_addr * addr) } else if (!GS_WAITRUNNING) { - send_error (addr, "Game is in the wrong mode.\n"); + send_error (addr, "Update mode, please try again.\n"); return; } } - /* Send all connected players the new PlayerID */ - if (GS_WAITRUNNING && addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) - net_change_playerid (addr->pl_nr, (GT_MP_PTPM)); + d_playerdetail ("*** PLAYER List ***"); + bman.updatestatusbar = 1; +}; - d_playerdetail ("*** PLAYER List ***"); +void +send_joingame (_net_addr * addr, char *name) { + struct pkg_joingame p_jg; + int vmi, + vma, + vsu; + + d_printf ("send_joingame SendTo: %s:%s (Name:%16s)\n", addr->host, + addr->port, name); + + sscanf (VERSION, "%d.%d.%d", &vma, &vmi, &vsu); + + p_jg.h.typ = PKG_joingame; + p_jg.h.flags = PKGF_ackreq; + p_jg.h.len = HTON16 (sizeof (struct pkg_joingame)); + p_jg.ver_sub = vsu; + p_jg.ver_major = vma; + p_jg.ver_minor = vmi; + if (bman.firewall) + p_jg.netflags = NETF_firewall; + else + p_jg.netflags = 0; + strncpy (p_jg.name, bman.playername, LEN_PLAYERNAME); + + send_pkg ((struct pkg *)&p_jg, addr); +}; + + +/*** + *** Packettype: pingack/pingreq + *** Update Playerinformation, add players into the current game + ***/ +void +do_playerid (struct pkg_playerid *p_id, _net_addr * addr) +{ + _player *pl; + int i; + + d_printf + ("do_playerid (From:%s:%s pl_nr=%d) Player(name:%s [%s:%s], pl_nr:%d)\n", + addr->host, addr->port, addr->pl_nr, p_id->name, p_id->host, p_id->port, p_id->pl_nr); + + /* As Server/Master Only change settings */ + if (((GT_MP_PTPM && (bman.state == GS_wait && addr->pl_nr != -1)) || // PTPM change setting + (GT_MP_PTPS && addr->pl_nr == bman.p_servnr)) && p_id->pl_nr >= 0 && p_id->pl_nr < MAX_PLAYERS) { // PTPS and information send by PTPM + + pl = &players[p_id->pl_nr]; + + pl->state = p_id->state; + if (p_id->pl_nr != bman.p_nr && PS_IS_used (pl->state)) + pl->state |= PSF_net; + else + pl->state &= (0xff - PSF_net); + + player_set_gfx (pl, p_id->gfx_nr); + strncpy (pl->name, p_id->name, LEN_PLAYERNAME); + pl->net.timestamp = timestamp; + pl->net.pingreq = pl->net.pingack + 5; + + if (p_id->host[0] != 0) { + pl->net.addr.pl_nr = addr->pl_nr; + strncpy (pl->net.addr.host, p_id->host, LEN_SERVERNAME); + strncpy (pl->net.addr.port, p_id->port, LEN_PORT); + dns_filladdr (pl->net.addr.host, LEN_SERVERNAME, + pl->net.addr.port, LEN_PORT, bman.net_ai_family, &pl->net.addr.sAddr); + } + + if (GT_MP_PTPS) { + pl->points = NTOH16 (p_id->points); + pl->wins = NTOH16 (p_id->wins); + } + + /* Send all connected players the new PlayerID */ + if (GS_WAITRUNNING && addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) + net_change_playerid (addr->pl_nr, (GT_MP_PTPM)); + } + + /* send the whole playerlist to the client to update the playerlist */ + else if (p_id->pl_nr == -1 && addr->pl_nr >= 0 && addr->pl_nr < MAX_PLAYERS) { + for (i = 0; i < MAX_PLAYERS; i++) + send_playerid (addr, players[i].name, players[i].net.addr.host,players[i].net.addr.port, i, players[i].gfx_nr, players[i].net.flags); + } + + d_playerdetail ("*** PLAYER List ***"); bman.updatestatusbar = 1; }; @@ -222,12 +279,12 @@ send_playerid (_net_addr * addr, char *name, char *pladdr, char *plport, p_id.h.typ = PKG_playerid; p_id.h.flags = PKGF_ackreq; p_id.h.len = HTON16 (sizeof (struct pkg_playerid)); - p_id.ver_sub = vsu; - p_id.ver_major = vma; - p_id.ver_minor = vmi; - p_id.netflags = netflags; - strncpy (p_id.name, name, LEN_PLAYERNAME); + if (name != NULL) + strncpy (p_id.name, name, LEN_PLAYERNAME); + else + p_id.name[0] = 0; + if (pladdr == NULL) p_id.host[0] = 0; else @@ -235,7 +292,6 @@ send_playerid (_net_addr * addr, char *name, char *pladdr, char *plport, if (plport == NULL) p_id.port[0] = 0; - else strncpy (p_id.port, plport, LEN_PORT); @@ -267,24 +323,46 @@ do_servermode (struct pkg_servermode *s_mod, _net_addr * addr) d_printf ("do_servermode (%s:%s) state = %d\n", addr->host, addr->port, s_mod->state); - if (s_mod->pl_nr >= 0 && s_mod->pl_nr < MAX_PLAYERS) { - bman.p_nr = s_mod->pl_nr; - players[bman.p_nr].state &= (0xFF - PSF_net); - strncpy (players[s_mod->pl_nr].name, bman.playername, LEN_PLAYERNAME); - } - - bman.state = s_mod->state; - map.state = s_mod->mapstate; + /* if we just have connected the bman.p_nr is still -1, so we handle the + servermode packet still alittle diffrent */ + if (bman.p_nr == -1) { + d_printf (" Server gave us: p_nr: %d, p_servnr: %d\n", s_mod->p_nr, s_mod->p_servnr); + + /* set the p_servnr to the playerslot which is the server */ + if (bman.p_servnr != s_mod->p_servnr) { + bman.p_servnr = s_mod->p_servnr; + memcpy (&players[bman.p_servnr].net, &players[0].net, sizeof (_net_player)); + } + + /* set now the new p_nr number */ + if (s_mod->p_nr >= 0 && s_mod->p_nr < MAX_PLAYERS && bman.p_nr == -1) { + bman.p_nr = s_mod->p_nr; + players[bman.p_nr].state &= (0xFF - PSF_net); + strncpy (players[s_mod->p_nr].name, bman.playername, LEN_PLAYERNAME); + } + + /* send playerid with p_nr -1 so we get the whole playerlist */ + send_playerid (addr, NULL, NULL, NULL, -1, -1, 0); + } + + /* the server changed */ + if (bman.p_servnr != s_mod->p_servnr) { + menu_displaymessage ("Server Quit", "FIXME: Server Quit the game and code is not finished"); + } + + /* do the normal update */ + if (GT_MP_PTPS) { + bman.state = s_mod->state; + map.state = s_mod->mapstate; - bman.players_nr_s = s_mod->players; - bman.lastwinner = s_mod->last_winner; + bman.players_nr_s = s_mod->players; + bman.lastwinner = s_mod->last_winner; - if (GT_MP_PTPS) { map.size.x = s_mod->fieldsize_x; map.size.y = s_mod->fieldsize_y; - } - strncpy (map.tileset, s_mod->tileset, LEN_TILESETNAME); + strncpy (map.tileset, s_mod->tileset, LEN_TILESETNAME); + } bman.updatestatusbar = 1; }; @@ -308,7 +386,8 @@ send_servermode (_net_addr * addr, int pl_nr) s_mod.multitype = bman.multitype; s_mod.players = bman.players_nr_s; s_mod.maxplayer = bman.maxplayer; - s_mod.pl_nr = pl_nr; + s_mod.p_nr = pl_nr; + s_mod.p_servnr = bman.p_servnr; s_mod.last_winner = bman.lastwinner; s_mod.fieldsize_x = map.size.x; s_mod.fieldsize_y = map.size.y; @@ -519,8 +598,10 @@ do_playerdata (struct pkg_playerdata *p_dat, _net_addr * addr) } /* set the state of the player */ - if (p_dat->p_nr != bman.p_nr && PS_IS_used (pl->state)) - pl->state |= PSF_net; + if (p_dat->p_nr != bman.p_nr && PS_IS_used (pl->state)) { + pl->state |= PSF_net; + pl->state &= (0xff - PSF_ai); + } else pl->state &= (0xff - PSF_net); @@ -607,7 +688,7 @@ do_playermove (struct pkg_playermove *p_dat, _net_addr * addr) /* check if the right player is sending the information */ pl = &players[p_dat->p_nr]; - if (addr->pl_nr != 0 && addr->pl_nr != p_dat->p_nr) + if (addr->pl_nr != bman.p_servnr && addr->pl_nr != p_dat->p_nr) return; pl->m = p_dat->m; @@ -721,14 +802,14 @@ do_tunneldata (struct pkg_tunneldata *tun_pkg, _net_addr * addr) addr->pl_nr, addr->host, addr->port, tun_pkg->tunnel_nr, NTOH16 (tun_pkg->target.x), NTOH16 (tun_pkg->target.y)); - if (addr->pl_nr != 0 && GT_MP_PTPM && NTOH16 (tun_pkg->target.y) == -1 + if (addr->pl_nr != bman.p_servnr && GT_MP_PTPM && NTOH16 (tun_pkg->target.y) == -1 && NTOH16 (tun_pkg->target.x) == -1) { send_tunneldata (addr, tun_pkg->tunnel_nr, map.tunnel[tun_pkg->tunnel_nr].x, map.tunnel[tun_pkg->tunnel_nr].y); players[addr->pl_nr].net.net_status = tun_pkg->tunnel_nr; players[addr->pl_nr].net.net_istep = 3; } - else if (addr->pl_nr == 0 && tun_pkg->tunnel_nr < GAME_MAX_TUNNELS) { + else if (addr->pl_nr == bman.p_servnr && tun_pkg->tunnel_nr < GAME_MAX_TUNNELS) { map.tunnel[tun_pkg->tunnel_nr].x = NTOH16 (tun_pkg->target.x); map.tunnel[tun_pkg->tunnel_nr].y = NTOH16 (tun_pkg->target.y); players[bman.p_nr].net.net_status = tun_pkg->tunnel_nr; @@ -832,7 +913,7 @@ do_getfield (struct pkg_getfield *gf_dat, _net_addr * addr) return; if (addr->pl_nr != -1 && bman.state == GS_update && GT_MP_PTPM) { - if (addr->pl_nr > 0 && addr->pl_nr < MAX_PLAYERS) { + if (addr->pl_nr != bman.p_servnr && addr->pl_nr < MAX_PLAYERS) { players[addr->pl_nr].net.net_status = gf_dat->line; players[addr->pl_nr].net.net_istep = 2; } @@ -882,7 +963,7 @@ do_fieldline (struct pkg_fieldline *f_dat, _net_addr * addr) if (addr->pl_nr == -1) return; - if (addr->pl_nr != 0) { + if (addr->pl_nr != bman.p_servnr ) { /* the data we have got are not from the server */ d_printf ("do_fieldline: the data we have got are not from the server\n"); return; @@ -934,7 +1015,7 @@ do_getplayerdata (struct pkg_getplayerdata *gp_dat, _net_addr * addr) return; if (addr->pl_nr != -1 && bman.state == GS_update && GT_MP_PTPM) { - if (addr->pl_nr > 0 && addr->pl_nr < MAX_PLAYERS) { + if (addr->pl_nr != bman.p_servnr && addr->pl_nr < MAX_PLAYERS) { players[addr->pl_nr].net.net_status = gp_dat->pl_nr; players[addr->pl_nr].net.net_istep = 1; } @@ -953,7 +1034,7 @@ do_playerstatus (struct pkg_playerstatus *stat, _net_addr * addr) d_printf ("do_playerstatus (%s,%s)\n", addr->host, addr->port); - if (addr->pl_nr != 0 && !(GT_MP_PTPM)) { + if (addr->pl_nr != bman.p_servnr && !(GT_MP_PTPM)) { /* the data we have got are not from the server */ d_printf ("do_playerstatus: the data we have got are not from the server\n"); return; @@ -1067,7 +1148,7 @@ do_special (struct pkg_special *sp_pkg, _net_addr * addr) return; /* check if the right player is sending the information */ - if (addr->pl_nr != 0 && addr->pl_nr != sp_pkg->pl_nr) + if (addr->pl_nr != bman.p_servnr && addr->pl_nr != sp_pkg->pl_nr) return; players[sp_pkg->pl_nr].special.type = sp_pkg->typ; @@ -1146,7 +1227,7 @@ do_mapinfo (struct pkg_mapinfo *map_pkg, _net_addr * addr) d_printf ("do_mapinfo (addr %d) size[%d,%d]\n", addr->pl_nr, map_pkg->size_x, map_pkg->size_y); /* check if the server send this information */ - if (addr->pl_nr != 0) + if (addr->pl_nr != bman.p_servnr) return; if (map_pkg->tileset[0] == 0) { @@ -1207,6 +1288,10 @@ inpkg_check (unsigned char typ, short int id, _net_addr * addr) void send_pkg (struct pkg *packet, _net_addr * addr) { + /* if the packet would be send to the ai player so ignore it */ + if (PS_IS_aiplayer (players[addr->pl_nr].state)) + return; + packet->h.id = HTON16 (pkg_lastid++); if (bman.net_ai_family != PF_INET) packet->h.flags = packet->h.flags | PKGF_ipv6; @@ -1234,7 +1319,7 @@ fwd_pkg (struct pkg *packet, _net_addr * addr) || packet->h.typ == PKG_bombdata || packet->h.typ == PKG_chat || packet->h.typ == PKG_special) for (pl = 1; pl < MAX_PLAYERS; pl++) - if (PS_IS_netplayer (players[pl].state) + if ((!PS_IS_aiplayer (players[pl].state)) && PS_IS_netplayer (players[pl].state) && ((players[pl].net.flags & NETF_firewall) == NETF_firewall || (players[addr->pl_nr].net.flags & NETF_firewall) == NETF_firewall) && pl != addr->pl_nr) @@ -1346,6 +1431,9 @@ do_pkg (struct pkg *packet, _net_addr * addr) case (PKG_tunneldata): do_tunneldata ((struct pkg_tunneldata *) packet, addr); break; + case (PKG_joingame): + do_joingame ((struct pkg_joingame *) packet, addr); + break; default: send_error (addr, "BomberClone: unknown data packet"); break; diff --git a/src/single.c b/src/single.c index 307ce03..5a8a7cb 100644 --- a/src/single.c +++ b/src/single.c @@ -1,4 +1,4 @@ -/* $Id: single.c,v 1.46 2003/11/08 06:27:59 stpohle Exp $ */ +/* $Id: single.c,v 1.47 2003/11/09 03:56:56 stpohle Exp $ */ /* single player */ #include "basic.h" @@ -17,7 +17,7 @@ single_game_new () if (PS_IS_used (players[p].state)) { bman.players_nr_s++; bman.players_nr++; - players[p].state = PSF_used + PSF_alife + PSF_playing; + players[p].state |= PSF_used + PSF_alife + PSF_playing; } else players[p].state = 0; @@ -553,7 +553,10 @@ single_create_ai (int num_players) if (!(PS_IS_used (players[p].state))) { pl = &players[p]; sprintf (pl->name, "AI %d", count + 1); - pl->state |= PSF_used + PSF_alife + PSF_playing; + pl->state |= PSF_used + PSF_alife + PSF_playing + PSF_ai; + pl->net.flags = NETF_firewall; + sprintf (pl->net.addr.host, "localhost"); + sprintf (pl->net.addr.port, "11000"); do { gfx_sel = s_random (MAX_PLAYERS); MW_IS_GFX_SELECT (gfx_sel, i); @@ -623,7 +626,7 @@ single_loop () _airunaway rawdir; for (p = 0; p < MAX_PLAYERS; p++) - if (p != bman.p_nr && PS_IS_alife (players[p].state)) { + if (p != bman.p_nr && PS_IS_alife (players[p].state) && PS_IS_aiplayer(players[p].state)) { pl = &players[p]; i = ai_checkpos (pl, &plpos);