X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fnetserv.c;h=4b846f9da413425db5e86999fd149111f34ea77c;hb=d2bb945e958e551ee43005160e671db37899e8cb;hp=6555e0497922502843b7ef909c34cfc69be28bf1;hpb=3ff2e8a0b5c27b99a9920bdf5ed82bc41bf40181;p=rocksndiamonds.git diff --git a/src/netserv.c b/src/netserv.c index 6555e049..4b846f9d 100644 --- a/src/netserv.c +++ b/src/netserv.c @@ -9,20 +9,16 @@ // netserv.c // ============================================================================ -#include "libgame/platform.h" - -#if defined(NETWORK_AVALIABLE) - #include #include #include #include -#include "main.h" - #include "libgame/libgame.h" #include "netserv.h" +#include "main.h" + static int clients = 0; static int onceonly = 0; @@ -47,7 +43,8 @@ static struct NetworkServerPlayerInfo *first_player = NULL; #define NEXT(player) ((player)->next ? (player)->next : first_player) /* 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 */ static unsigned char realbuffer[512], *buffer = realbuffer + 4; @@ -132,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) @@ -141,6 +139,7 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player) } exit(0); } +#endif } static void AddPlayer(TCPsocket fd) @@ -433,6 +432,13 @@ static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player) ServerFrameCounter++; } +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) @@ -445,7 +451,6 @@ int NetworkServerThread(void *ptr) void NetworkServer(int port, int serveronly) { - int sl; struct NetworkServerPlayerInfo *player; int r; unsigned int len; @@ -458,6 +463,10 @@ 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; @@ -473,14 +482,28 @@ void NetworkServer(int port, int serveronly) #endif if (SDLNet_ResolveHost(&ip, NULL, port) == -1) - Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_ResolveHost() failed"); + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_ResolveHost() failed: %s", + SDLNet_GetError()); + + if ((fds = SDLNet_AllocSocketSet(MAX_PLAYERS + 1 + 1)) == NULL) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_AllocSocketSet() failed: %s"), + SDLNet_GetError(); + + if ((lfd = SDLNet_TCP_Open(&ip)) == NULL) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_Open() failed: %s"), + SDLNet_GetError(); + + if (SDLNet_TCP_AddSocket(fds, lfd) == -1) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_AddSocket() failed: %s"), + SDLNet_GetError(); - lfd = SDLNet_TCP_Open(&ip); - if (!lfd) - Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_Open() failed"); + if ((udp = SDLNet_UDP_Open(port)) == NULL) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_UDP_Open() failed: %s", + SDLNet_GetError()); - fds = SDLNet_AllocSocketSet(MAX_PLAYERS+1); - SDLNet_TCP_AddSocket(fds, lfd); + if (SDLNet_UDP_AddSocket(fds, udp) == -1) + Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_AddSocket() failed: %s"), + SDLNet_GetError(); if (options.verbose) { @@ -496,22 +519,15 @@ void NetworkServer(int port, int serveronly) for (player = first_player; player; player = player->next) flushuser(player); - if ((sl = SDLNet_CheckSockets(fds, 500000)) < 1) - { - Error(ERR_NETWORK_SERVER, "SDLNet_CheckSockets failed: %s", - SDLNet_GetError()); - perror("SDLNet_CheckSockets"); - } - - 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 */ + /* accept incoming TCP connections */ if (SDLNet_SocketReady(lfd)) { + Error(ERR_DEBUG, "got TCP packet"); + TCPsocket newsock; newsock = SDLNet_TCP_Accept(lfd); @@ -520,9 +536,25 @@ void NetworkServer(int port, int serveronly) AddPlayer(newsock); } + /* accept incoming UDP packets */ + if (SDLNet_SocketReady(udp)) + { + Error(ERR_DEBUG, "got UDP packet"); + + static UDPpacket packet; + + int num_packets = SDLNet_UDP_Recv(udp, &packet); + + if (num_packets == 1) + { + // bounce packet + SDLNet_UDP_Send(udp, -1, &packet); + } + } + player = first_player; - do + while (player && !interrupt) { if (SDLNet_SocketReady(player->fd)) { @@ -557,10 +589,12 @@ void NetworkServer(int port, int serveronly) memmove(player->readbuffer, player->readbuffer + 4 + len, player->nread); buffer[0] = player->number; - if (!player->introduced && buffer[1] != OP_PLAYER_NAME) + if (!player->introduced && + buffer[1] != OP_PLAYER_NAME && + buffer[1] != OP_PROTOCOL_VERSION) { if (options.verbose) - Error(ERR_NETWORK_SERVER, "!(client %d)->introduced && buffer[1]==%d (expected OP_PLAYER_NAME)", buffer[0], buffer[1]); + Error(ERR_NETWORK_SERVER, "!(client %d)->introduced && buffer[1]==%d (expected OP_PLAYER_NAME or OP_PROTOCOL_VERSION)", buffer[0], buffer[1]); RemovePlayer(player); interrupt = 1; @@ -621,8 +655,5 @@ void NetworkServer(int port, int serveronly) if (player && !interrupt) player = player->next; } - while (player && !interrupt); } } - -#endif /* NETWORK_AVALIABLE */