You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
807 lines
23 KiB
807 lines
23 KiB
/* $Id: network.c,v 1.27 2003/05/29 21:35:03 stpohle Exp $ */
|
|
/*
|
|
network routines.
|
|
*/
|
|
|
|
#include "bomberclone.h"
|
|
#include "network.h"
|
|
#include "gamesrv.h"
|
|
#include "packets.h"
|
|
#include "gfx.h"
|
|
|
|
int
|
|
network_server_port (char *server, char *host, int hostlen, char *port, int portlen)
|
|
{
|
|
char *pos,
|
|
*pos2;
|
|
|
|
if (host == NULL)
|
|
return -1;
|
|
|
|
pos2 = pos = strchr (server, ':');
|
|
|
|
if (pos != NULL)
|
|
while (pos2 != NULL) {
|
|
pos = pos2;
|
|
pos2 = strchr (pos + 1, ':');
|
|
}
|
|
|
|
if (pos != NULL) {
|
|
// : für Portangabe gefunden
|
|
if (pos - server < hostlen) {
|
|
strncpy (host, server, pos - server);
|
|
host[pos - server] = 0;
|
|
if (pos[1] == 0)
|
|
sprintf (port, "11000");
|
|
else
|
|
strcpy (port, pos + 1);
|
|
}
|
|
else {
|
|
return -1;
|
|
}
|
|
}
|
|
else {
|
|
// Portangabe wurde nicht gefunden und wird auf 0 gesetzt
|
|
strncpy (host, server, hostlen);
|
|
sprintf (port, "11000");
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
|
|
|
|
/*
|
|
try to work better with the network packet option
|
|
*/
|
|
void
|
|
net_dyn_pkgoption ()
|
|
{
|
|
int p;
|
|
_net_pkgopt *npkg;
|
|
|
|
for (p = 0; p < MAX_PLAYERS; p++)
|
|
if (PS_IS_netplayer (bman.players[p].state)) {
|
|
npkg = &bman.players[p].net.pkgopt;
|
|
|
|
if (npkg->to_2sec > DYN_PKG_MAX_MISSING) {
|
|
if (npkg->send_set < 10)
|
|
npkg->send_set++;
|
|
npkg->to_2sec = 0;
|
|
npkg->to_timestamp = timestamp;
|
|
}
|
|
|
|
if ((timestamp - npkg->to_timestamp > 2000) && npkg->to_2sec <= DYN_PKG_MIN_MISSING) {
|
|
if (npkg->send_set > PKG_SENDSETOPT)
|
|
npkg->send_set--;
|
|
npkg->to_2sec = 0;
|
|
npkg->to_timestamp = timestamp;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
/*
|
|
setup everything for the network loop
|
|
*/
|
|
int
|
|
network_init ()
|
|
{
|
|
int i;
|
|
/*
|
|
we need it for the windows winsock
|
|
*/
|
|
#ifdef _WIN32
|
|
WSADATA wsaData;
|
|
|
|
if (WSAStartup (MAKEWORD (1, 1), &wsaData) != 0) {
|
|
d_printf ("WSAStartup failed.\n");
|
|
exit (1);
|
|
}
|
|
#endif
|
|
|
|
bman.sock = -1;
|
|
bman.p_nr = -1;
|
|
|
|
timestamp = SDL_GetTicks ();
|
|
|
|
// reset playernumber and number of connected players
|
|
for (i = 0; i < MAX_PLAYERS; i++) {
|
|
bman.players[i].net.addr.host[0] = 0;
|
|
bman.players[i].net.addr.port[0] = 0;
|
|
bman.players[i].name[0] = 0;
|
|
bman.players[i].gfx_nr = -1;
|
|
bman.players[i].net.timestamp = timestamp;
|
|
bman.players[i].points = 0;
|
|
bman.players[i].wins = 0;
|
|
bman.players[i].net.pingreq = 20;
|
|
bman.players[i].net.pingack = 22;
|
|
bman.players[i].state = 0;
|
|
}
|
|
|
|
bman.lastwinner = -1;
|
|
bman.players_nr_s = 1;
|
|
|
|
// start the udp server
|
|
bman.sock = udp_server (bman.port, bman.net_ai_family);
|
|
|
|
if (bman.sock < 0) {
|
|
#ifdef _WIN32
|
|
WSACleanup ();
|
|
#endif
|
|
return -1;
|
|
}
|
|
|
|
// we have got out socket.. so now allocate the memory for the resend_cache
|
|
resend_cache.data = (char *) malloc (PKG_RESENDCACHE_SIZE);
|
|
resend_cache.fill = 0;
|
|
|
|
// if we are the server set up my data
|
|
if (GT_MP_PTPM) {
|
|
strncpy (bman.players[0].name, bman.playername, LEN_PLAYERNAME);
|
|
bman.p_nr = 0;
|
|
bman.players[0].state = PSF_used;
|
|
if (bman.notifygamemaster)
|
|
gamesrv_sendmode (bman.maxplayer, 1);
|
|
}
|
|
|
|
// if client send Data to the server
|
|
if (GT_MP_PTPS) {
|
|
network_server_port (bman.servername, bman.players[0].net.addr.host,
|
|
LEN_SERVERNAME, bman.players[0].net.addr.port, LEN_PORT);
|
|
|
|
d_printf ("Connect To: %s[:%s]\n", bman.players[0].net.addr.host,
|
|
bman.players[0].net.addr.port);
|
|
|
|
dns_filladdr (bman.players[0].net.addr.host, LEN_SERVERNAME, bman.players[0].net.addr.port,
|
|
LEN_PORT, bman.net_ai_family, &bman.players[0].net.addr.sAddr);
|
|
bman.players[0].net.addr.port[0] = bman.players[0].net.addr.host[0] = 0;
|
|
dns_filladdr (bman.players[0].net.addr.host, LEN_SERVERNAME, bman.players[0].net.addr.port,
|
|
LEN_PORT, bman.net_ai_family, &bman.players[0].net.addr.sAddr);
|
|
if (bman.firewall)
|
|
i = NETF_firewall;
|
|
else
|
|
i = 0;
|
|
send_playerid (&bman.players[0].net.addr, bman.playername, NULL, NULL, -1, -1, i);
|
|
}
|
|
|
|
return 0;
|
|
};
|
|
|
|
|
|
/*
|
|
shutdown the network part
|
|
*/
|
|
void
|
|
network_shutdown ()
|
|
{
|
|
int i;
|
|
|
|
if (GT_MP_PTPM) {
|
|
for (i = 1; i < MAX_PLAYERS; i++)
|
|
if (bman.players[i].net.addr.host[0] != 0)
|
|
send_quit (&bman.players[i].net.addr, NULL, NULL);
|
|
if (bman.notifygamemaster)
|
|
gamesrv_quit ();
|
|
}
|
|
else if (bman.players[0].net.addr.host[0] != 0)
|
|
send_quit (&bman.players[0].net.addr, NULL, NULL);
|
|
|
|
udp_close (bman.sock);
|
|
|
|
if (resend_cache.data != NULL)
|
|
free (resend_cache.data);
|
|
|
|
resend_cache.data = NULL;
|
|
resend_cache.fill = -1;
|
|
|
|
bman.p_nr = -1;
|
|
bman.sock = -1;
|
|
#ifdef _WIN32
|
|
WSACleanup ();
|
|
#endif
|
|
};
|
|
|
|
|
|
int
|
|
net_check_timeout (int pl_nr)
|
|
{
|
|
int timeout = UDP_TIMEOUT;
|
|
|
|
if ((bman.players[pl_nr].state & (PSF_net + PSF_used)) == (PSF_used + PSF_net)
|
|
&& timestamp - bman.players[pl_nr].net.timestamp > timeout
|
|
&& bman.players[pl_nr].net.pingreq != bman.players[pl_nr].net.pingack) {
|
|
d_printf ("net_check_timeout pl_nr=%d, ack=%d, req=%d, timediff=%d\n", pl_nr,
|
|
bman.players[pl_nr].net.pingack, bman.players[pl_nr].net.pingreq,
|
|
timestamp - bman.players[pl_nr].net.timestamp);
|
|
bman.players[pl_nr].net.timestamp = timestamp;
|
|
bman.players[pl_nr].net.pingack = bman.players[pl_nr].net.pingreq;
|
|
send_ping (&bman.players[pl_nr].net.addr, bman.players[pl_nr].net.pingack + 100,
|
|
PKG_pingreq);
|
|
}
|
|
if ((bman.players[pl_nr].state & (PSF_net + PSF_used)) == (PSF_used + PSF_net)
|
|
&& timestamp - bman.players[pl_nr].net.timestamp > timeout
|
|
&& bman.players[pl_nr].net.pingreq == bman.players[pl_nr].net.pingack) {
|
|
d_printf ("net_check_timeout pl_nr=%d, ack=%d, req=%d, timediff=%d\n", pl_nr,
|
|
bman.players[pl_nr].net.pingack, bman.players[pl_nr].net.pingreq,
|
|
timestamp - bman.players[pl_nr].net.timestamp);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
Read data from the network and work with it
|
|
*/
|
|
int
|
|
network_loop ()
|
|
{
|
|
char data[MAX_UDPDATA];
|
|
struct pkg *packet = (struct pkg *) data;
|
|
int inlen,
|
|
i;
|
|
|
|
_net_addr addr;
|
|
|
|
if (bman.state != GS_running && bman.state != GS_ready)
|
|
timestamp = SDL_GetTicks ();
|
|
|
|
/*
|
|
as long as we get any new data, work with them
|
|
*/
|
|
inlen = udp_get (bman.sock, data, MAX_UDPDATA, &addr.sAddr, bman.net_ai_family);
|
|
addr.port[0] = addr.host[0] = 0;
|
|
if (inlen > 0)
|
|
dns_filladdr (addr.host, LEN_SERVERNAME, addr.port, LEN_PORT, bman.net_ai_family,
|
|
&addr.sAddr);
|
|
|
|
while (inlen > 0) {
|
|
|
|
do_pkg (packet, &addr);
|
|
|
|
// printf ("Network : inlen (%d) typ (%d) Size (%d)\n", inlen, packet->typ, pkglen);
|
|
inlen = udp_get (bman.sock, data, MAX_UDPDATA, &addr.sAddr, bman.net_ai_family);
|
|
addr.port[0] = addr.host[0] = 0;
|
|
if (inlen > 0)
|
|
dns_filladdr (addr.host, LEN_SERVERNAME, addr.port, LEN_PORT, bman.net_ai_family,
|
|
&addr.sAddr);
|
|
}
|
|
|
|
/*
|
|
check here for old connections who aren't answering
|
|
*/
|
|
if (bman.state == GS_wait || bman.state == GS_ready || bman.state == GS_running) {
|
|
if (GT_MP_PTPS) {
|
|
if (net_check_timeout (0)) {
|
|
d_printf ("Server Timed Out\n");
|
|
bman.state = GS_startup;
|
|
}
|
|
}
|
|
else if (GT_MP_PTPM) {
|
|
for (i = 1; i < MAX_PLAYERS; i++)
|
|
if (net_check_timeout (i)) {
|
|
d_printf ("Player %d Timed Out\n", i);
|
|
net_delplayer (i);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
resend_cache....
|
|
*/
|
|
rscache_loop ();
|
|
|
|
/*
|
|
dynamic calibration of the network traffic option
|
|
*/
|
|
net_dyn_pkgoption ();
|
|
|
|
return 0;
|
|
};
|
|
|
|
|
|
/*
|
|
this is needed to draw the whole uppdate of everything
|
|
*/
|
|
void
|
|
draw_netupdatestate ()
|
|
{
|
|
char text[255];
|
|
int y = 0,
|
|
i;
|
|
SDL_Rect src,
|
|
dest;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
if (PS_IS_used (bman.players[i].state)) {
|
|
y += 48;
|
|
redraw_logo (0, y, gfx.res.x, y + 48);
|
|
|
|
if (bman.players[i].gfx_nr != -1) {
|
|
dest.w = src.w = bman.players[i].gfx->smal_size.x;
|
|
dest.h = src.h = bman.players[i].gfx->smal_size.y;
|
|
src.x = bman.players[i].gfx->smal_size.x * down;
|
|
src.y = 0;
|
|
|
|
dest.x = 50;
|
|
dest.y = y;
|
|
|
|
SDL_BlitSurface (bman.players[i].gfx->smal_image, &src, gfx.screen, &dest);
|
|
gfx_AddUpdateRect (dest.x, dest.y, gfx.res.x - dest.x, dest.h);
|
|
}
|
|
|
|
if (bman.players[i].net.net_istep == 0)
|
|
sprintf (text, "%s - State : READY", bman.players[i].name);
|
|
else
|
|
sprintf (text, "%s - State : DOWNLOAD", bman.players[i].name);
|
|
draw_text (70, y, text, 1);
|
|
|
|
text[0] = 0;
|
|
if (bman.players[i].net.net_istep == 2)
|
|
sprintf (text, "Getting Field Data %d of %d.", bman.players[i].net.net_status,
|
|
bman.fieldsize.x);
|
|
|
|
if (bman.players[i].net.net_istep == 1)
|
|
sprintf (text, "Getting Player Data %d of %d.", bman.players[i].net.net_status,
|
|
MAX_PLAYERS);
|
|
|
|
draw_text (70, y + 16, text, 1);
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*
|
|
used to update settings at startup
|
|
*/
|
|
void
|
|
net_change_playerid (int pl_nr, unsigned char senddata)
|
|
{
|
|
int i;
|
|
|
|
if (GT_MP_PTPM) {
|
|
/*
|
|
Send to all connected clients the update
|
|
*/
|
|
for (i = 1; i < MAX_PLAYERS; i++)
|
|
if (bman.players[i].net.addr.host[0] != 0)
|
|
send_playerid (&bman.players[i].net.addr, bman.players[pl_nr].name,
|
|
bman.players[pl_nr].net.addr.host, bman.players[pl_nr].net.addr.port,
|
|
pl_nr, bman.players[pl_nr].gfx_nr, bman.players[pl_nr].net.flags);
|
|
}
|
|
else {
|
|
/*
|
|
Send only to the Server the update and only if in_nr == bman.in_nr
|
|
*/
|
|
if (pl_nr == bman.p_nr && senddata)
|
|
send_playerid (&bman.players[0].net.addr, bman.players[pl_nr].name,
|
|
bman.players[pl_nr].net.addr.host, bman.players[pl_nr].net.addr.port,
|
|
pl_nr, bman.players[pl_nr].gfx_nr, bman.players[pl_nr].net.flags);
|
|
}
|
|
|
|
player_set_gfx (&bman.players[pl_nr], bman.players[pl_nr].gfx_nr);
|
|
};
|
|
|
|
|
|
/*
|
|
sets up everything for the network game..
|
|
on servers the game field will be created and the clients will wait for the game data
|
|
within the network loop
|
|
*/
|
|
void
|
|
net_new_gamedata ()
|
|
{
|
|
int done = 0,
|
|
keypressed = 0,
|
|
x,
|
|
y,
|
|
p,
|
|
i,
|
|
net_istep; // network init step
|
|
SDL_Event event;
|
|
Uint8 *keys;
|
|
Uint32 downtimestamp = 0;
|
|
|
|
draw_logo ();
|
|
|
|
if (GT_MP_PTPM)
|
|
draw_text (100, 0, "Waiting for the Clients", 1);
|
|
else
|
|
draw_text (100, 0, "Downloading Data", 1);
|
|
|
|
SDL_Flip (gfx.screen);
|
|
|
|
/*
|
|
prepare everything for the loop
|
|
*/
|
|
for (x = 0; x < MAX_PLAYERS; x++) {
|
|
bman.players[x].net.timestamp = 0;
|
|
bman.players[x].net.net_status = -1;
|
|
bman.players[x].net.net_istep = 2;
|
|
}
|
|
|
|
y = -1;
|
|
if (GT_MP_PTPM)
|
|
net_istep = 0;
|
|
else
|
|
net_istep = 2;
|
|
|
|
while (!done && bman.state == GS_update) {
|
|
/* the network thing */
|
|
|
|
network_loop ();
|
|
|
|
/* if PTPM check if all players are ready */
|
|
if (GT_MP_PTPM) {
|
|
for (p = 1, i = 1; p < MAX_PLAYERS; p++)
|
|
if (PS_IS_playing (bman.players[p].state) && bman.players[p].net.net_istep != 0)
|
|
i = 0;
|
|
if (i == 1) { /* all players are ready */
|
|
done = 1;
|
|
bman.state = GS_ready;
|
|
}
|
|
}
|
|
|
|
/* if PTPS get all data */
|
|
if (GT_MP_PTPS) {
|
|
if (net_istep == 2) {
|
|
if ((y < bman.fieldsize.y - 1 && y == bman.players[bman.p_nr].net.net_status)
|
|
|| y == -1) {
|
|
/* send field data req */
|
|
y++;
|
|
downtimestamp = timestamp;
|
|
send_getfield (&bman.players[0].net.addr, y);
|
|
}
|
|
else if (y < bman.fieldsize.y && y != bman.players[bman.p_nr].net.net_status
|
|
&& y >= 0 && timestamp - downtimestamp > DOWNLOAD_TIMEOUT) {
|
|
/* we have got no field data */
|
|
y--;
|
|
}
|
|
else if (y == bman.fieldsize.y - 1 && bman.players[bman.p_nr].net.net_status == y) {
|
|
/* we have got all field data */
|
|
y = -1;
|
|
bman.players[bman.p_nr].net.net_istep = --net_istep;
|
|
bman.players[bman.p_nr].net.net_status = -1;
|
|
}
|
|
}
|
|
|
|
if (net_istep == 1) {
|
|
if ((y < MAX_PLAYERS - 1 && y == bman.players[bman.p_nr].net.net_status) || y == -1) {
|
|
/* send player date req */
|
|
y++;
|
|
downtimestamp = timestamp;
|
|
send_getplayerdata (&bman.players[0].net.addr, y);
|
|
}
|
|
if (y < MAX_PLAYERS && y != bman.players[bman.p_nr].net.net_status && y >= 0
|
|
&& timestamp - downtimestamp > DOWNLOAD_TIMEOUT) {
|
|
/* we have got no player data */
|
|
y--;
|
|
}
|
|
if (y == MAX_PLAYERS - 1 && bman.players[bman.p_nr].net.net_status == y) {
|
|
/* we have got all playerdata */
|
|
y = -1;
|
|
bman.players[bman.p_nr].net.net_istep = --net_istep;
|
|
bman.players[bman.p_nr].net.net_status = -1;
|
|
downtimestamp = timestamp;
|
|
send_playerstatus (&bman.players[0].net.addr, bman.p_nr, 0, 0);
|
|
}
|
|
}
|
|
if (net_istep == 0 && bman.players[bman.p_nr].net.net_status == -1
|
|
&& timestamp - downtimestamp > DOWNLOAD_TIMEOUT) {
|
|
/* server did not send informations back */
|
|
downtimestamp = timestamp;
|
|
send_playerstatus (&bman.players[0].net.addr, bman.p_nr, 0, 0);
|
|
}
|
|
}
|
|
|
|
/* do the grafik work */
|
|
draw_netupdatestate ();
|
|
SDL_Flip (gfx.screen);
|
|
|
|
if (SDL_PollEvent (&event) != 0)
|
|
switch (event.type) {
|
|
case (SDL_QUIT):
|
|
bman.state = GS_quit;
|
|
bman.p_nr = -1;
|
|
done = 1;
|
|
}
|
|
|
|
keys = SDL_GetKeyState (NULL);
|
|
|
|
if (keys[SDLK_ESCAPE] && event.type == SDL_KEYDOWN) {
|
|
done = 1;
|
|
bman.p_nr = -1;
|
|
keypressed = 1;
|
|
bman.state = GS_startup;
|
|
}
|
|
|
|
if (event.type == SDL_KEYUP)
|
|
keypressed = 0;
|
|
|
|
timestamp = SDL_GetTicks (); // needed for time sync.
|
|
SDL_Delay (1); // we don't need here anything better
|
|
|
|
/* player is only watching so just go after we have got everything
|
|
go to show the field */
|
|
if (GT_MP_PTPS && bman.state == GS_update && net_istep == 0
|
|
&& bman.players[bman.p_nr].gfx_nr == -1) {
|
|
done = 1;
|
|
bman.state = GS_running;
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
void
|
|
net_game_send_player (int p_nr)
|
|
{
|
|
int p;
|
|
|
|
if (GT_MP_PTPM) {
|
|
for (p = 0; p < MAX_PLAYERS; p++)
|
|
if (PS_IS_netplayer (bman.players[p].state) && p != bman.p_nr)
|
|
send_playerdata (&bman.players[p].net.addr, p_nr, &bman.players[p_nr]);
|
|
}
|
|
else if (p_nr == bman.p_nr) {
|
|
for (p = 0; p < MAX_PLAYERS; p++)
|
|
if (PS_IS_netplayer (bman.players[p].state) && p != bman.p_nr && NET_CANSEND(p))
|
|
send_playerdata (&bman.players[p].net.addr, p_nr, &bman.players[p_nr]);
|
|
}
|
|
};
|
|
|
|
|
|
void
|
|
net_game_send_playermove (int p_nr, int mustsend)
|
|
{
|
|
int p;
|
|
_player *pl;
|
|
|
|
for (p = 0; p < MAX_PLAYERS; p++)
|
|
if (PS_IS_netplayer (bman.players[p].state) && p != bman.p_nr) {
|
|
pl = &bman.players[p_nr];
|
|
|
|
pl->net.pkgopt.send_to--;
|
|
if ((pl->net.pkgopt.send_to <= 0 || mustsend) && NET_CANSEND(p))
|
|
send_playermove (&bman.players[p].net.addr, p_nr, pl);
|
|
|
|
/* network packet send control */
|
|
if (pl->net.pkgopt.send_to <= 0 || pl->net.pkgopt.send_to > pl->net.pkgopt.send_set)
|
|
pl->net.pkgopt.send_to = pl->net.pkgopt.send_set;
|
|
}
|
|
};
|
|
|
|
void
|
|
net_game_send_bomb (int p, int b)
|
|
{
|
|
int pl;
|
|
|
|
/* check if we are slave and send something else as dropping a bomb */
|
|
if (GT_MP_PTPS && bman.players[p].bombs[b].state != BS_ticking && bman.players[p].bombs[b].state != BS_trigger)
|
|
return;
|
|
|
|
d_printf ("Send BombData %d, %d\n", p, b);
|
|
|
|
if (p < 0 || p >= MAX_PLAYERS || b < 0 || b >= MAX_BOMBS)
|
|
return;
|
|
|
|
for (pl = 0; pl < MAX_PLAYERS; pl++)
|
|
if (PS_IS_netplayer (bman.players[pl].state) && pl != bman.p_nr && NET_CANSEND(pl))
|
|
send_bombdata (&bman.players[pl].net.addr, p, b, &bman.players[p].bombs[b]);
|
|
};
|
|
|
|
|
|
void
|
|
net_game_send_field (int x, int y)
|
|
{
|
|
int pl;
|
|
|
|
d_printf ("Send FieldData %d, %d\n", x, y);
|
|
|
|
if (x < 0 || x >= MAX_FIELDSIZE_X || y < 0 || y >= MAX_FIELDSIZE_Y)
|
|
return;
|
|
|
|
for (pl = 0; pl < MAX_PLAYERS; pl++)
|
|
if (PS_IS_netplayer (bman.players[pl].state) && pl != bman.p_nr && NET_CANSEND(pl))
|
|
send_field (&bman.players[pl].net.addr, x, y, &bman.field[x][y]);
|
|
};
|
|
|
|
|
|
|
|
void
|
|
net_delplayer (int pl_nr)
|
|
{
|
|
char host[LEN_SERVERNAME];
|
|
char port[LEN_PORT];
|
|
int i,
|
|
j = 1;
|
|
|
|
d_printf ("net_delplayer (%d)\n", pl_nr);
|
|
bman.updatestatusbar = 1; // force an update
|
|
|
|
if (pl_nr == bman.p_nr) {
|
|
/* we're not wanted */
|
|
network_shutdown ();
|
|
bman.state = GS_startup;
|
|
}
|
|
else {
|
|
strncpy (host, bman.players[pl_nr].net.addr.host, LEN_SERVERNAME);
|
|
strncpy (port, bman.players[pl_nr].net.addr.port, LEN_PORT);
|
|
|
|
bman.players[pl_nr].state &= (0xFF - (PSF_used + PSF_alife)); // Delete the used flag
|
|
bman.players[pl_nr].net.net_istep = 0; // needed for disconnect during the update
|
|
bman.players_nr_s--;
|
|
bman.players[pl_nr].gfx_nr = -1;
|
|
|
|
if (GT_MP_PTPM && (GS_WAITRUNNING || bman.state == GS_update)) {
|
|
for (i = 1; i < MAX_PLAYERS; i++)
|
|
if (PS_IS_netplayer (bman.players[i].state)) {
|
|
send_quit (&bman.players[i].net.addr, host, port);
|
|
j++;
|
|
}
|
|
if (bman.notifygamemaster)
|
|
gamesrv_sendmode (bman.maxplayer, j);
|
|
bman.updatestatusbar=1;
|
|
}
|
|
}
|
|
|
|
if (GT_MP_PTPS && pl_nr == 0) /* masterserver quit */
|
|
bman.state = GS_startup;
|
|
|
|
if (GT_MP_PTPM && bman.notifygamemaster)
|
|
gamesrv_sendmode (bman.maxplayer, bman.players_nr_s);
|
|
};
|
|
|
|
|
|
void
|
|
net_game_fillsockaddr ()
|
|
{
|
|
/* Update all sockaddr before the game starts */
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
if (bman.players[i].net.addr.host[0] != 0 && bman.players[i].net.addr.host[0] != 0)
|
|
dns_filladdr (bman.players[i].net.addr.host, LEN_SERVERNAME,
|
|
bman.players[i].net.addr.port, LEN_PORT, bman.net_ai_family,
|
|
&bman.players[i].net.addr.sAddr);
|
|
};
|
|
|
|
|
|
void
|
|
net_send_servermode ()
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
if (PS_IS_netplayer (bman.players[i].state) && i != bman.p_nr && NET_CANSEND(i))
|
|
send_servermode (&bman.players[i].net.addr, i);
|
|
|
|
if (GT_MP_PTPM && bman.notifygamemaster) /* send notification the the gamemaster */
|
|
gamesrv_sendmode (bman.maxplayer, bman.players_nr_s);
|
|
|
|
};
|
|
|
|
|
|
/* sends to everyone an up to date playerlist*/
|
|
void
|
|
net_send_players ()
|
|
{
|
|
int i,
|
|
j;
|
|
|
|
for (j = 0; j < MAX_PLAYERS; j++)
|
|
if (PS_IS_netplayer (bman.players[j].state) && j != bman.p_nr)
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
send_playerid (&bman.players[j].net.addr, bman.players[i].name,
|
|
bman.players[i].net.addr.host, bman.players[i].net.addr.port, i,
|
|
bman.players[i].gfx_nr, bman.players[i].net.flags);
|
|
|
|
};
|
|
|
|
|
|
|
|
void
|
|
net_send_chat (char *text, signed char notigamesrv)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
if (PS_IS_netplayer (bman.players[i].state) && i != bman.p_nr && NET_CANSEND(i))
|
|
send_chat (&bman.players[i].net.addr, text);
|
|
|
|
if (GT_MP_PTPM && bman.notifygamemaster && notigamesrv == 1) /* send notification the the gamemaster */
|
|
gamesrv_sendchat (text);
|
|
};
|
|
|
|
|
|
void
|
|
net_game_send_ill (int p_nr)
|
|
{
|
|
int i;
|
|
|
|
d_printf ("net_game_send_ill (%d)\n", p_nr);
|
|
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
if (PS_IS_netplayer (bman.players[i].state) && i != bman.p_nr && NET_CANSEND(i))
|
|
send_ill (&bman.players[i].net.addr, p_nr, &bman.players[p_nr]);
|
|
};
|
|
|
|
|
|
/*
|
|
this routine will set up some things for the network game
|
|
after this the data should be transfered to the other clients.
|
|
*/
|
|
void
|
|
net_new_game ()
|
|
{
|
|
int p,
|
|
i;
|
|
|
|
// reset playerposition
|
|
for (i = 0; i < MAX_PLAYERS; i++)
|
|
bman.players[i].pos.y = bman.players[i].pos.x = -1;
|
|
|
|
bman.players_nr = 0;
|
|
bman.players_nr_s = 0;
|
|
for (p = 0; p < MAX_PLAYERS; p++) {
|
|
bman.players[p].frame = 0;
|
|
bman.players[p].frameto = 0;
|
|
|
|
if (PS_IS_used (bman.players[p].state)) {
|
|
bman.players_nr_s++;
|
|
if (bman.players[p].gfx_nr == -1) {
|
|
bman.players[p].gfx = NULL;
|
|
bman.players[p].state &= (0xff - (PSF_alife + PSF_playing));
|
|
}
|
|
else {
|
|
bman.players[p].state |= PSF_alife + PSF_playing;
|
|
bman.players[p].gfx = &gfx.players[bman.players[p].gfx_nr];
|
|
}
|
|
}
|
|
else
|
|
bman.players[p].state = 0;
|
|
|
|
bman.players[p].bombs_n = START_BOMBS;
|
|
bman.players[p].range = START_RANGE;
|
|
bman.players[p].speed = START_SPEED;
|
|
bman.players[p].special = SP_nothing;
|
|
bman.updatestatusbar=1;
|
|
|
|
for (i = 0; i < PI_max; i++) /* all types of illnes turn them off */
|
|
bman.players[p].ill[i].to = 0;
|
|
bman.players[p].frame = 0;
|
|
bman.players[p].frameto = 0;
|
|
bman.players[p].d = 0;
|
|
|
|
// reset bombs
|
|
for (i = 0; i < MAX_BOMBS; i++) {
|
|
bman.players[p].bombs[i].state = BS_off;
|
|
bman.players[p].bombs[i].ex_nr = -1;
|
|
}
|
|
}
|
|
|
|
bman.players[bman.p_nr].state &= (0xFF - PSF_net); // we are the local player
|
|
bman.last_ex_nr = 1;
|
|
};
|
|
|
|
|
|
|
|
/* send special use elements into the network,
|
|
to make sure nothing bad happens with explosions
|
|
we send the ex_nr number too */
|
|
void
|
|
net_game_send_special (int pl_nr, int ex_nr)
|
|
{
|
|
int pl;
|
|
|
|
d_printf ("Send Special Data %d\n", pl_nr);
|
|
|
|
if (pl_nr < 0 || pl_nr >= MAX_PLAYERS)
|
|
return;
|
|
|
|
for (pl = 0; pl < MAX_PLAYERS; pl++)
|
|
if (PS_IS_netplayer (bman.players[pl].state) && pl != pl_nr && NET_CANSEND(pl))
|
|
send_special (&bman.players[pl].net.addr, pl_nr, bman.players[pl_nr].special, ex_nr);
|
|
};
|