X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fnetserv.c;h=4a83492304dc2e2ee5183e44276309fe90a2cb01;hp=10b0ab504d5615a66dc17e9221e7630f7bd60238;hb=61c3da024802ecc0268bab42d7499fc0346e4fd3;hpb=74b5b6c19587f93c45b72b1153154030dc99b50d diff --git a/src/netserv.c b/src/netserv.c index 10b0ab50..4a834923 100644 --- a/src/netserv.c +++ b/src/netserv.c @@ -1,38 +1,51 @@ /*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * +* Rocks'n'Diamonds -- McDuffin Strikes Back! * *----------------------------------------------------------* -* (c) 1995-98 Artsoft Entertainment * -* Holger Schemel * -* Oststrasse 11a * -* 33604 Bielefeld * -* phone: ++49 +521 290471 * -* email: aeglos@valinor.owl.de * +* (c) 1995-2006 Artsoft Entertainment * +* Holger Schemel * +* Detmolder Strasse 189 * +* 33604 Bielefeld * +* Germany * +* e-mail: info@artsoft.org * *----------------------------------------------------------* -* network.c * +* netserv.c * ***********************************************************/ -#if !defined(MSDOS) && !defined(WIN32) +#include "libgame/platform.h" + +#if defined(NETWORK_AVALIABLE) #include #include #include -#include #include -#include + +#if defined(TARGET_SDL) +#include "main.h" +#else +#include #include #include #include #include +#include /* apparently needed for OS/2 port */ +#endif + +#include "libgame/libgame.h" #include "netserv.h" -#include "misc.h" static int clients = 0; static int onceonly = 0; struct NetworkServerPlayerInfo { +#if defined(TARGET_SDL) + TCPsocket fd; +#else int fd; +#endif + char player_name[16]; unsigned char number; struct NetworkServerPlayerInfo *next; @@ -49,16 +62,22 @@ static struct NetworkServerPlayerInfo *first_player = NULL; #define NEXT(player) ((player)->next ? (player)->next : first_player) +#if defined(TARGET_SDL) +/* TODO: peer address */ +static TCPsocket lfd; /* listening socket */ +static SDLNet_SocketSet fds; /* socket set */ +#else static struct sockaddr_in saddr; -static int lfd; +static int lfd; /* listening socket */ +static fd_set fds; /* socket set */ +static int tcp = -1; +#endif + static unsigned char realbuffer[512], *buffer = realbuffer + 4; static int interrupt; -static int tcp = -1; -static unsigned long ServerFrameCounter = 0; - -static fd_set fds; +static unsigned int ServerFrameCounter = 0; static void addtobuffer(struct NetworkServerPlayerInfo *player, unsigned char *b, int len) @@ -75,7 +94,11 @@ static void flushuser(struct NetworkServerPlayerInfo *player) { if (player->nwrite) { +#if defined(TARGET_SDL) + SDLNet_TCP_Send(player->fd, player->writbuffer, player->nwrite); +#else write(player->fd, player->writbuffer, player->nwrite); +#endif player->nwrite = 0; } } @@ -87,8 +110,9 @@ static void broadcast(struct NetworkServerPlayerInfo *except, realbuffer[0] = realbuffer[1] = realbuffer[2] = 0; realbuffer[3] = (unsigned char)len; - for (player=first_player; player; player=player->next) - if (player != except && (player->active || !activeonly) && player->introduced) + for (player = first_player; player; player = player->next) + if (player != except && player->introduced && + (player->active || !activeonly)) addtobuffer(player, realbuffer, 4 + len); } @@ -111,7 +135,7 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player) first_player = player->next; else { - for (v=first_player; v; v=v->next) + for (v = first_player; v; v = v->next) { if (v->next && v->next == player) { @@ -120,7 +144,13 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player) } } } + +#if defined(TARGET_SDL) + SDLNet_TCP_DelSocket(fds, player->fd); + SDLNet_TCP_Close(player->fd); +#else close(player->fd); +#endif if (player->introduced) { @@ -143,10 +173,15 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player) } } +#if defined(TARGET_SDL) +static void AddPlayer(TCPsocket fd) +#else static void AddPlayer(int fd) +#endif { struct NetworkServerPlayerInfo *player, *v; unsigned char nxn; + boolean again = TRUE; player = checked_malloc(sizeof (struct NetworkServerPlayerInfo)); @@ -160,26 +195,38 @@ static void AddPlayer(int fd) player->action = 0; player->action_received = FALSE; +#if defined(TARGET_SDL) + SDLNet_TCP_AddSocket(fds, fd); +#endif + first_player = player; nxn = 1; - again: - v = player->next; - while(v) + while (again) { - if (v->number == nxn) + again = FALSE; + v = player->next; + + while (v) { - nxn++; - goto again; + if (v->number == nxn) + { + nxn++; + + again = TRUE; + break; + } + v = v->next; } - v = v->next; } player->number = nxn; +#if !defined(TARGET_SDL) if (options.verbose) Error(ERR_NETWORK_SERVER, "client %d connecting from %s", nxn, inet_ntoa(saddr.sin_addr)); +#endif clients++; buffer[0] = 0; @@ -231,7 +278,7 @@ static void Handle_OP_NUMBER_WANTED(struct NetworkServerPlayerInfo *player) Error(ERR_NETWORK_SERVER, "client %d (%s) wants to switch to # %d", player->number, player->player_name, nr_wanted); - for (v=first_player; v; v=v->next) + for (v = first_player; v; v = v->next) { if (v->number == nr_wanted) { @@ -246,11 +293,11 @@ static void Handle_OP_NUMBER_WANTED(struct NetworkServerPlayerInfo *player) Error(ERR_NETWORK_SERVER, "client %d (%s) switches to # %d", player->number, player->player_name, nr_wanted); else if (player->number == nr_wanted) - Error(ERR_NETWORK_SERVER, "client %d (%s) still has # %d", + Error(ERR_NETWORK_SERVER, "client %d (%s) already has # %d", player->number, player->player_name, nr_wanted); else Error(ERR_NETWORK_SERVER, - "client %d (%s) cannot switch (client %d still exists)", + "client %d (%s) cannot switch (client %d already exists)", player->number, player->player_name, nr_wanted); } @@ -279,7 +326,7 @@ static void Handle_OP_PLAYER_NAME(struct NetworkServerPlayerInfo *player, len=16; memcpy(player->player_name, &buffer[2], len-2); player->player_name[len-2] = 0; - for (i=0; iplayer_name[i] < ' ' || ((unsigned char)(player->player_name[i]) > 0x7e && @@ -305,7 +352,7 @@ static void Handle_OP_PLAYER_NAME(struct NetworkServerPlayerInfo *player, if (!player->introduced) { - for (v=first_player; v; v=v->next) + for (v = first_player; v; v = v->next) { if (v != player && v->introduced) { @@ -328,21 +375,23 @@ static void Handle_OP_START_PLAYING(struct NetworkServerPlayerInfo *player) if (options.verbose) Error(ERR_NETWORK_SERVER, - "client %d (%s) starts game [level %d from levedir %d (%s)]", + "client %d (%s) starts game [level %d from leveldir %d (%s)]", player->number, player->player_name, (buffer[2] << 8) + buffer[3], (buffer[4] << 8) + buffer[5], - &buffer[6]); + &buffer[10]); - for (w=first_player; w; w=w->next) + for (w = first_player; w; w = w->next) if (w->introduced) w->active = 1; /* reset frame counter */ ServerFrameCounter = 0; + Error(ERR_NETWORK_SERVER, "resetting ServerFrameCounter to 0"); + /* reset player actions */ - for (v=first_player; v; v=v->next) + for (v = first_player; v; v = v->next) { v->action = 0; v->action_received = FALSE; @@ -369,20 +418,22 @@ static void Handle_OP_CONTINUE_PLAYING(struct NetworkServerPlayerInfo *player) static void Handle_OP_STOP_PLAYING(struct NetworkServerPlayerInfo *player) { + int cause_for_stopping = buffer[2]; + if (options.verbose) - Error(ERR_NETWORK_SERVER, "client %d (%s) stops game", - player->number, player->player_name); - broadcast(NULL, 2, 0); + Error(ERR_NETWORK_SERVER, "client %d (%s) stops game [%d]", + player->number, player->player_name, cause_for_stopping); + broadcast(NULL, 3, 0); } -static void Handle_OP_MOVE_FIGURE(struct NetworkServerPlayerInfo *player) +static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player) { struct NetworkServerPlayerInfo *v; int last_client_nr = 0; int i; /* store player action */ - for (v=first_player; v; v=v->next) + for (v = first_player; v; v = v->next) { if (v->number == player->number) { @@ -392,7 +443,7 @@ static void Handle_OP_MOVE_FIGURE(struct NetworkServerPlayerInfo *player) } /* check if server received action from each player */ - for (v=first_player; v; v=v->next) + for (v = first_player; v; v = v->next) { if (!v->action_received) return; @@ -402,11 +453,11 @@ static void Handle_OP_MOVE_FIGURE(struct NetworkServerPlayerInfo *player) } /* initialize all player actions to zero */ - for (i=0; inext) + for (v = first_player; v; v = v->next) { buffer[6 + v->number-1] = v->action; v->action = 0; @@ -420,21 +471,43 @@ static void Handle_OP_MOVE_FIGURE(struct NetworkServerPlayerInfo *player) broadcast(NULL, 6 + last_client_nr, 0); +#if 0 + Error(ERR_NETWORK_SERVER, "sending ServerFrameCounter value %d", + ServerFrameCounter); +#endif + ServerFrameCounter++; } +#if defined(TARGET_SDL) +/* the following is not used for a standalone server; + the pointer points to an integer containing the port-number */ +int NetworkServerThread(void *ptr) +{ + NetworkServer(*((int *) ptr), 0); + + /* should never be reached */ + return 0; +} +#endif + void NetworkServer(int port, int serveronly) { - int i, sl, on; + int sl; struct NetworkServerPlayerInfo *player; - int mfd; int r; unsigned int len; +#if defined(TARGET_SDL) + IPaddress ip; +#else + int i, on; + int is_daemon = 0; struct protoent *tcpproto; struct timeval tv; - int is_daemon = 0; + int mfd; +#endif -#ifndef NeXT +#if defined(PLATFORM_UNIX) && !defined(PLATFORM_NEXT) struct sigaction sact; #endif @@ -444,10 +517,13 @@ void NetworkServer(int port, int serveronly) if (!serveronly) onceonly = 1; +#if !defined(TARGET_SDL) if ((tcpproto = getprotobyname("tcp")) != NULL) tcp = tcpproto->p_proto; +#endif -#ifdef NeXT +#if defined(PLATFORM_UNIX) +#if defined(PLATFORM_NEXT) signal(SIGPIPE, SIG_IGN); #else sact.sa_handler = SIG_IGN; @@ -455,7 +531,28 @@ void NetworkServer(int port, int serveronly) sact.sa_flags = 0; sigaction(SIGPIPE, &sact, NULL); #endif +#endif + +#if defined(TARGET_SDL) + + /* assume that SDL is already initialized */ +#if 0 + if (SDLNet_Init() == -1) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_Init() failed"); + atexit(SDLNet_Quit); +#endif + + if (SDLNet_ResolveHost(&ip, NULL, port) == -1) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_ResolveHost() failed"); + lfd = SDLNet_TCP_Open(&ip); + if (!lfd) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_Open() failed"); + + fds = SDLNet_AllocSocketSet(MAX_PLAYERS+1); + SDLNet_TCP_AddSocket(fds, lfd); + +#else if ((lfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) Error(ERR_EXIT_NETWORK_SERVER, "socket() failed"); @@ -471,12 +568,14 @@ void NetworkServer(int port, int serveronly) Error(ERR_EXIT_NETWORK_SERVER, "bind() failed"); listen(lfd, 5); +#endif +#if !defined(TARGET_SDL) if (is_daemon) { /* become a daemon, breaking all ties with the controlling terminal */ - options.verbose = 0; - for (i=0; i<255; i++) + options.verbose = FALSE; + for (i = 0; i < 255; i++) { if (i != lfd) close(i); @@ -494,6 +593,7 @@ void NetworkServer(int port, int serveronly) open("/dev/null", O_WRONLY); open("/dev/null", O_WRONLY); } +#endif if (options.verbose) { @@ -502,13 +602,22 @@ void NetworkServer(int port, int serveronly) PROTOCOL_VERSION_1, PROTOCOL_VERSION_2, PROTOCOL_VERSION_3); } - while(1) + while (1) { interrupt = 0; - for (player=first_player; player; player=player->next) + for (player = first_player; player; player = player->next) flushuser(player); +#if defined(TARGET_SDL) + if ((sl = SDLNet_CheckSockets(fds, 500000)) < 1) + { + Error(ERR_NETWORK_SERVER, SDLNet_GetError()); + perror("SDLNet_CheckSockets"); + } + +#else + FD_ZERO(&fds); mfd = lfd; player = first_player; @@ -529,6 +638,7 @@ void NetworkServer(int port, int serveronly) else continue; } +#endif if (sl < 0) continue; @@ -536,9 +646,24 @@ void NetworkServer(int port, int serveronly) if (sl == 0) continue; + /* accept incoming connections */ +#if defined(TARGET_SDL) + if (SDLNet_SocketReady(lfd)) + { + TCPsocket newsock; + + newsock = SDLNet_TCP_Accept(lfd); + + if (newsock) + AddPlayer(newsock); + } + +#else + if (FD_ISSET(lfd, &fds)) { - int newfd, slen; + int newfd; + socklen_t slen; slen = sizeof(saddr); newfd = accept(lfd, (struct sockaddr *)&saddr, &slen); @@ -558,14 +683,27 @@ void NetworkServer(int port, int serveronly) } continue; } +#endif player = first_player; do { +#if defined(TARGET_SDL) + if (SDLNet_SocketReady(player->fd)) +#else if (FD_ISSET(player->fd, &fds)) +#endif { - r = read(player->fd, player->readbuffer + player->nread, MAX_BUFFER_SIZE - player->nread); +#if defined(TARGET_SDL) + /* read only 1 byte, because SDLNet blocks when we want more than is + in the buffer */ + r = SDLNet_TCP_Recv(player->fd, player->readbuffer + player->nread, 1); +#else + r = read(player->fd, player->readbuffer + player->nread, + MAX_BUFFER_SIZE - player->nread); +#endif + if (r <= 0) { if (options.verbose) @@ -603,7 +741,7 @@ void NetworkServer(int port, int serveronly) break; } - switch(buffer[1]) + switch (buffer[1]) { case OP_PLAYER_NAME: Handle_OP_PLAYER_NAME(player, len); @@ -633,8 +771,8 @@ void NetworkServer(int port, int serveronly) Handle_OP_STOP_PLAYING(player); break; - case OP_MOVE_FIGURE: - Handle_OP_MOVE_FIGURE(player); + case OP_MOVE_PLAYER: + Handle_OP_MOVE_PLAYER(player); break; case OP_BROADCAST_MESSAGE: @@ -661,4 +799,4 @@ void NetworkServer(int port, int serveronly) } } -#endif /* !MSDOS && !WIN32 */ +#endif /* NETWORK_AVALIABLE */