X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fnetserv.c;h=963a862b229b345067ca0e64b2ec3a5e3f4d475c;hb=5ef9148d1f605af02e872264519eda261a3e88ca;hp=5ecbf1b72082c7586a3f3604ffbbd5299c5d67cc;hpb=abe44529b439ad39b4d8dbf19cbd67c9b9844279;p=rocksndiamonds.git diff --git a/src/netserv.c b/src/netserv.c index 5ecbf1b7..963a862b 100644 --- a/src/netserv.c +++ b/src/netserv.c @@ -9,41 +9,23 @@ // netserv.c // ============================================================================ -#include "libgame/platform.h" - -#if defined(NETWORK_AVALIABLE) - #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 "main.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; @@ -60,16 +42,10 @@ 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 TCPsocket lfd; /* listening TCP socket */ +static UDPsocket udp; /* listening UDP socket */ static SDLNet_SocketSet fds; /* socket set */ -#else -static struct sockaddr_in saddr; -static int lfd; /* listening socket */ -static fd_set fds; /* socket set */ -static int tcp = -1; -#endif static unsigned char realbuffer[512], *buffer = realbuffer + 4; @@ -92,12 +68,8 @@ static void flushuser(struct NetworkServerPlayerInfo *player) { if (player->nwrite) { -#if defined(TARGET_SDL) SDLNet_TCP_Send(player->fd, player->writbuffer, player->nwrite); -#else - if (write(player->fd, player->writbuffer, player->nwrite) == -1) - Error(ERR_WARN, "write() failed; %s", strerror(errno)); -#endif + player->nwrite = 0; } } @@ -144,12 +116,8 @@ 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) { @@ -161,6 +129,7 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player) free(player); clients--; +#if 0 /* do not terminate network server if last player disconnected */ if (onceonly && clients == 0) { if (options.verbose) @@ -170,13 +139,10 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player) } exit(0); } +#endif } -#if defined(TARGET_SDL) static void AddPlayer(TCPsocket fd) -#else -static void AddPlayer(int fd) -#endif { struct NetworkServerPlayerInfo *player, *v; unsigned char nxn; @@ -194,9 +160,7 @@ 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; @@ -221,11 +185,6 @@ static void AddPlayer(int fd) } 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; @@ -470,15 +429,16 @@ static void Handle_OP_MOVE_PLAYER(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) +void ExitNetworkServer(int exit_value) +{ + Error(ERR_NETWORK_SERVER, "exiting network server"); + + exit(exit_value); +} + /* the following is not used for a standalone server; the pointer points to an integer containing the port-number */ int NetworkServerThread(void *ptr) @@ -488,23 +448,13 @@ int NetworkServerThread(void *ptr) /* should never be reached */ return 0; } -#endif void NetworkServer(int port, int serveronly) { - int sl; struct NetworkServerPlayerInfo *player; 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 mfd; -#endif #if defined(PLATFORM_UNIX) && !defined(PLATFORM_NEXT) struct sigaction sact; @@ -513,14 +463,13 @@ void NetworkServer(int port, int serveronly) if (port == 0) port = DEFAULT_SERVER_PORT; + // if only running the network server, exit on Ctrl-C + if (serveronly) + signal(SIGINT, ExitNetworkServer); + if (!serveronly) onceonly = 1; -#if !defined(TARGET_SDL) - if ((tcpproto = getprotobyname("tcp")) != NULL) - tcp = tcpproto->p_proto; -#endif - #if defined(PLATFORM_UNIX) #if defined(PLATFORM_NEXT) signal(SIGPIPE, SIG_IGN); @@ -532,68 +481,29 @@ void NetworkServer(int port, int serveronly) #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"); + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_ResolveHost() failed: %s", + SDLNet_GetError()); - fds = SDLNet_AllocSocketSet(MAX_PLAYERS+1); - SDLNet_TCP_AddSocket(fds, lfd); + if ((fds = SDLNet_AllocSocketSet(MAX_PLAYERS + 1 + 1)) == NULL) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_AllocSocketSet() failed: %s"), + SDLNet_GetError(); -#else - - if ((lfd = socket(PF_INET, SOCK_STREAM, 0)) < 0) - Error(ERR_EXIT_NETWORK_SERVER, "socket() failed"); - - saddr.sin_family = AF_INET; - saddr.sin_addr.s_addr = htonl(INADDR_ANY); - saddr.sin_port = htons(port); - - on = 1; - - setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(int)); - if (bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0) - Error(ERR_EXIT_NETWORK_SERVER, "bind() failed"); + if ((lfd = SDLNet_TCP_Open(&ip)) == NULL) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_Open() failed: %s"), + SDLNet_GetError(); - listen(lfd, 5); -#endif + if (SDLNet_TCP_AddSocket(fds, lfd) == -1) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_AddSocket() failed: %s"), + SDLNet_GetError(); -#if !defined(TARGET_SDL) - if (is_daemon) - { - /* become a daemon, breaking all ties with the controlling terminal */ - options.verbose = FALSE; - for (i = 0; i < 255; i++) - { - if (i != lfd) - close(i); - } + if ((udp = SDLNet_UDP_Open(port)) == NULL) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_UDP_Open() failed: %s", + SDLNet_GetError()); - if (fork()) - exit(0); - setsid(); - if (fork()) - exit(0); - if (chdir("/") == -1) - Error(ERR_WARN, "chdir() failed; %s", strerror(errno)); - - /* open a fake stdin, stdout, stderr, just in case */ - open("/dev/null", O_RDONLY); - open("/dev/null", O_WRONLY); - open("/dev/null", O_WRONLY); - } -#endif + if (SDLNet_UDP_AddSocket(fds, udp) == -1) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_AddSocket() failed: %s"), + SDLNet_GetError(); if (options.verbose) { @@ -609,48 +519,15 @@ void NetworkServer(int port, int serveronly) 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_CheckSockets failed: %s", - SDLNet_GetError()); - perror("SDLNet_CheckSockets"); - } - -#else - - FD_ZERO(&fds); - mfd = lfd; - player = first_player; - while (player) - { - FD_SET(player->fd, &fds); - if (player->fd > mfd) - mfd = player->fd; - player = player->next; - } - FD_SET(lfd, &fds); - tv.tv_sec = 0; - tv.tv_usec = 500000; - if ((sl = select(mfd + 1, &fds, NULL, NULL, &tv)) < 0) - { - if (errno != EINTR) - Error(ERR_EXIT_NETWORK_SERVER, "select() failed"); - else - continue; - } -#endif - - if (sl < 0) - continue; - - if (sl == 0) + // wait for 100 ms for activity on open network sockets + if (SDLNet_CheckSockets(fds, 100) < 1) continue; - /* accept incoming connections */ -#if defined(TARGET_SDL) + /* accept incoming TCP connections */ if (SDLNet_SocketReady(lfd)) { + Error(ERR_DEBUG, "got TCP packet"); + TCPsocket newsock; newsock = SDLNet_TCP_Accept(lfd); @@ -659,51 +536,31 @@ void NetworkServer(int port, int serveronly) AddPlayer(newsock); } -#else - - if (FD_ISSET(lfd, &fds)) + /* accept incoming UDP packets */ + if (SDLNet_SocketReady(udp)) { - int newfd; - socklen_t slen; + Error(ERR_DEBUG, "got UDP packet"); - slen = sizeof(saddr); - newfd = accept(lfd, (struct sockaddr *)&saddr, &slen); - if (newfd < 0) - { - if (errno != EINTR) - Error(ERR_EXIT_NETWORK_SERVER, "accept() failed"); - } - else + static UDPpacket packet; + + int num_packets = SDLNet_UDP_Recv(udp, &packet); + + if (num_packets == 1) { - if (tcp != -1) - { - on = 1; - setsockopt(newfd, tcp, TCP_NODELAY, (char *)&on, sizeof(int)); - } - AddPlayer(newfd); + // bounce packet + SDLNet_UDP_Send(udp, -1, &packet); } - continue; } -#endif player = first_player; - do + while (player && !interrupt) { -#if defined(TARGET_SDL) if (SDLNet_SocketReady(player->fd)) -#else - if (FD_ISSET(player->fd, &fds)) -#endif { -#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) { @@ -796,8 +653,5 @@ void NetworkServer(int port, int serveronly) if (player && !interrupt) player = player->next; } - while (player && !interrupt); } } - -#endif /* NETWORK_AVALIABLE */