X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fnetserv.c;h=636fbf236c484edfee5c5a86f8eb83216d7e4679;hp=0a3661e139a7b8d0692b7a144050751df48ae3c3;hb=HEAD;hpb=457283149872e45280a6a7f0ee1dcb604ed43da2 diff --git a/src/netserv.c b/src/netserv.c index 0a3661e1..636fbf23 100644 --- a/src/netserv.c +++ b/src/netserv.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // netserv.c // ============================================================================ @@ -40,10 +40,10 @@ static struct NetworkServerPlayerInfo *first_player = NULL; #define NEXT(player) ((player)->next ? (player)->next : first_player) -/* TODO: peer address */ -static TCPsocket lfd; /* listening TCP socket */ -static UDPsocket udp; /* listening UDP socket */ -static SDLNet_SocketSet fds; /* socket set */ +// TODO: peer address +static TCPsocket lfd; // listening TCP socket +static UDPsocket udp; // listening UDP socket +static SDLNet_SocketSet fds; // socket set static struct NetworkBuffer *read_buffer = NULL; static struct NetworkBuffer *write_buffer = NULL; @@ -107,7 +107,7 @@ int putNetworkString(byte *ptr, char *s) return strlen(s) + 1; } -struct NetworkBuffer *newNetworkBuffer() +struct NetworkBuffer *newNetworkBuffer(void) { struct NetworkBuffer *new = checked_calloc(sizeof(struct NetworkBuffer)); @@ -140,7 +140,7 @@ void initNetworkBufferForReading(struct NetworkBuffer *nb) { resetNetworkBufferForReading(nb); - /* skip message length header */ + // skip message length header getNetworkBuffer32BitInteger(nb); } @@ -149,7 +149,7 @@ void initNetworkBufferForWriting(struct NetworkBuffer *nb, int message_type, { resetNetworkBufferForWriting(nb); - /* will be replaced with message length before sending */ + // will be replaced with message length before sending putNetworkBuffer32BitInteger(nb, 0); putNetworkBuffer8BitInteger(nb, message_type); @@ -164,7 +164,7 @@ static void copyNetworkBufferForWriting(struct NetworkBuffer *nb_from, int message_type = getNetworkBuffer8BitInteger(nb_from); - /* skip player number */ + // skip player number getNetworkBuffer8BitInteger(nb_from); initNetworkBufferForWriting(nb_to, message_type, player_nr); @@ -179,7 +179,7 @@ static void copyNetworkBufferForWriting(struct NetworkBuffer *nb_from, static void increaseNetworkBuffer(struct NetworkBuffer *nb, int additional_size) { - /* add some more buffer size than is really required this time */ + // add some more buffer size than is really required this time nb->max_size += additional_size + MAX_BUFFER_SIZE; nb->buffer = checked_realloc(nb->buffer, nb->max_size); } @@ -187,6 +187,14 @@ static void increaseNetworkBuffer(struct NetworkBuffer *nb, int additional_size) int receiveNetworkBufferBytes(struct NetworkBuffer *nb, TCPsocket socket, int num_bytes) { + if (num_bytes > MAX_PACKET_SIZE) + { + Debug("network:server", "protocol error: invalid packet size %d", + num_bytes); + + return -1; + } + if (nb->pos + num_bytes > nb->max_size) increaseNetworkBuffer(nb, num_bytes); @@ -320,7 +328,7 @@ int getNetworkBufferFile(struct NetworkBuffer *nb, char *filename) if (!(file = fopen(filename, MODE_WRITE))) { - Error(ERR_WARN, "cannot write file '%s' from network buffer", filename); + Warn("cannot write file '%s' from network buffer", filename); return 0; } @@ -343,12 +351,12 @@ int putNetworkBufferFile(struct NetworkBuffer *nb, char *filename) int filesize_pos = nb->pos; int num_bytes = 0; - /* will be replaced with file size */ + // will be replaced with file size putNetworkBuffer32BitInteger(nb, 0); if (!(file = openFile(filename, MODE_READ))) { - Error(ERR_WARN, "cannot read file '%s' to network buffer", filename); + Warn("cannot read file '%s' to network buffer", filename); return 0; } @@ -367,7 +375,7 @@ int putNetworkBufferFile(struct NetworkBuffer *nb, char *filename) closeFile(file); - /* set file size */ + // set file size putNetwork32BitInteger(&nb->buffer[filesize_pos], num_bytes); return num_bytes; @@ -377,19 +385,19 @@ void dumpNetworkBuffer(struct NetworkBuffer *nb) { int i; - printf("::: network buffer maximum size: %d\n", nb->max_size); - printf("::: network buffer size: %d\n", nb->size); - printf("::: network buffer position : %d\n", nb->pos); + Debug("network:buffer", "network buffer maximum size: %d\n", nb->max_size); + Debug("network:buffer", "network buffer size: %d\n", nb->size); + Debug("network:buffer", "network buffer position : %d\n", nb->pos); for (i = 0; i < nb->size; i++) { if ((i % 16) == 0) - printf("\n::: "); + DebugContinued("network:buffer", "\n"); - printf("%02x ", nb->buffer[i]); + DebugContinued("", "%02x ", nb->buffer[i]); } - printf("\n"); + DebugContinued("network:buffer", "\n"); } static void SendNetworkBufferToAllButOne(struct NetworkBuffer *nb, @@ -397,14 +405,14 @@ static void SendNetworkBufferToAllButOne(struct NetworkBuffer *nb, { struct NetworkServerPlayerInfo *player; - /* set message length header */ + // set message length header putNetwork32BitInteger(nb->buffer, nb->size - 4); for (player = first_player; player != NULL; player = player->next) { if (player != except && player->introduced) { - /* directly send the buffer to the network client */ + // directly send the buffer to the network client SDLNet_TCP_Send(player->fd, nb->buffer, nb->size); } } @@ -418,18 +426,17 @@ static void SendNetworkBufferToAll(struct NetworkBuffer *nb) static void SendNetworkBufferToClient(struct NetworkBuffer *nb, struct NetworkServerPlayerInfo *player) { - /* set message length header */ + // set message length header putNetwork32BitInteger(nb->buffer, nb->size - 4); - /* directly send the buffer to the network client */ + // directly send the buffer to the network client SDLNet_TCP_Send(player->fd, nb->buffer, nb->size); } static void RemovePlayer(struct NetworkServerPlayerInfo *player) { - if (options.verbose) - Error(ERR_NETWORK_SERVER, "dropping client %d (%s)", - player->number, player->player_name); + Debug("network:server", "dropping client %d (%s)", + player->number, player->player_name); SDLNet_TCP_DelSocket(fds, player->fd); SDLNet_TCP_Close(player->fd); @@ -464,14 +471,11 @@ static void RemovePlayer(struct NetworkServerPlayerInfo *player) free(player); num_clients--; -#if 0 /* do not terminate network server if last player disconnected */ +#if 0 // do not terminate network server if last player disconnected if (run_server_only_once && num_clients == 0) { - if (options.verbose) - { - Error(ERR_NETWORK_SERVER, "no clients left"); - Error(ERR_NETWORK_SERVER, "aborting"); - } + Debug("network:server", "no clients left"); + Debug("network:server", "aborting"); exit(0); } @@ -537,13 +541,12 @@ static void Handle_OP_PROTOCOL_VERSION(struct NetworkServerPlayerInfo *player) if (protocol_version_major != PROTOCOL_VERSION_MAJOR || protocol_version_minor != PROTOCOL_VERSION_MINOR) { - if (options.verbose) - Error(ERR_NETWORK_SERVER, - "client %d (%s) has wrong protocol version %d.%d.%d", - player->number, player->player_name, - protocol_version_major, - protocol_version_minor, - protocol_version_patch); + Debug("network:server", + "client %d (%s) has wrong protocol version %d.%d.%d", + player->number, player->player_name, + protocol_version_major, + protocol_version_minor, + protocol_version_patch); initNetworkBufferForWriting(write_buffer, OP_BAD_PROTOCOL_VERSION, 0); @@ -557,13 +560,12 @@ static void Handle_OP_PROTOCOL_VERSION(struct NetworkServerPlayerInfo *player) } else { - if (options.verbose) - Error(ERR_NETWORK_SERVER, - "client %d (%s) uses protocol version %d.%d.%d", - player->number, player->player_name, - protocol_version_major, - protocol_version_minor, - protocol_version_patch); + Debug("network:server", + "client %d (%s) uses protocol version %d.%d.%d", + player->number, player->player_name, + protocol_version_major, + protocol_version_minor, + protocol_version_patch); } } @@ -574,9 +576,8 @@ static void Handle_OP_NUMBER_WANTED(struct NetworkServerPlayerInfo *player) boolean nr_is_free = TRUE; struct NetworkServerPlayerInfo *p; - if (options.verbose) - Error(ERR_NETWORK_SERVER, "client %d (%s) wants to switch to # %d", - player->number, player->player_name, nr_wanted); + Debug("network:server", "client %d (%s) wants to switch to # %d", + player->number, player->player_name, nr_wanted); for (p = first_player; p != NULL; p = p->next) { @@ -588,19 +589,16 @@ static void Handle_OP_NUMBER_WANTED(struct NetworkServerPlayerInfo *player) } } - if (options.verbose) - { - if (nr_is_free) - 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) already has # %d", - player->number, player->player_name, nr_wanted); - else - Error(ERR_NETWORK_SERVER, - "client %d (%s) cannot switch (client %d already exists)", - player->number, player->player_name, nr_wanted); - } + if (nr_is_free) + Debug("network:server", "client %d (%s) switches to # %d", + player->number, player->player_name, nr_wanted); + else if (player->number == nr_wanted) + Debug("network:server", "client %d (%s) already has # %d", + player->number, player->player_name, nr_wanted); + else + Debug("network:server", + "client %d (%s) cannot switch (client %d already exists)", + player->number, player->player_name, nr_wanted); if (nr_is_free) player->number = nr_wanted; @@ -641,9 +639,8 @@ static void Handle_OP_PLAYER_NAME(struct NetworkServerPlayerInfo *player) SendNetworkBufferToAllButOne(write_buffer, player); } - if (options.verbose) - Error(ERR_NETWORK_SERVER, "client %d calls itself \"%s\"", - player->number, player->player_name); + Debug("network:server", "client %d calls itself \"%s\"", + player->number, player->player_name); copyNetworkBufferForWriting(read_buffer, write_buffer, player->number); @@ -679,20 +676,19 @@ static void Handle_OP_START_PLAYING(struct NetworkServerPlayerInfo *player) char *new_leveldir_identifier = getNetworkBufferString(read_buffer); int level_nr = getNetworkBuffer16BitInteger(read_buffer); - if (options.verbose) - Error(ERR_NETWORK_SERVER, - "client %d (%s) starts game [level %d from level set '%s']", - player->number, player->player_name, level_nr, - new_leveldir_identifier); + Debug("network:server", + "client %d (%s) starts game [level %d from level set '%s']", + player->number, player->player_name, level_nr, + new_leveldir_identifier); struct NetworkServerPlayerInfo *p; - /* reset frame counter */ + // reset frame counter ServerFrameCounter = 0; - Error(ERR_NETWORK_SERVER, "resetting ServerFrameCounter to 0"); + Debug("network:server", "resetting ServerFrameCounter to 0"); - /* reset player actions */ + // reset player actions for (p = first_player; p != NULL; p = p->next) { p->action = 0; @@ -709,9 +705,8 @@ static void Handle_OP_START_PLAYING(struct NetworkServerPlayerInfo *player) static void Handle_OP_PAUSE_PLAYING(struct NetworkServerPlayerInfo *player) { - if (options.verbose) - Error(ERR_NETWORK_SERVER, "client %d (%s) pauses game", - player->number, player->player_name); + Debug("network:server", "client %d (%s) pauses game", + player->number, player->player_name); copyNetworkBufferForWriting(read_buffer, write_buffer, player->number); @@ -720,9 +715,8 @@ static void Handle_OP_PAUSE_PLAYING(struct NetworkServerPlayerInfo *player) static void Handle_OP_CONTINUE_PLAYING(struct NetworkServerPlayerInfo *player) { - if (options.verbose) - Error(ERR_NETWORK_SERVER, "client %d (%s) continues game", - player->number, player->player_name); + Debug("network:server", "client %d (%s) continues game", + player->number, player->player_name); copyNetworkBufferForWriting(read_buffer, write_buffer, player->number); @@ -733,9 +727,8 @@ static void Handle_OP_STOP_PLAYING(struct NetworkServerPlayerInfo *player) { int cause_for_stopping = getNetworkBuffer8BitInteger(read_buffer); - if (options.verbose) - Error(ERR_NETWORK_SERVER, "client %d (%s) stops game [%d]", - player->number, player->player_name, cause_for_stopping); + Debug("network:server", "client %d (%s) stops game [%d]", + player->number, player->player_name, cause_for_stopping); copyNetworkBufferForWriting(read_buffer, write_buffer, player->number); @@ -749,7 +742,7 @@ static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player) struct NetworkServerPlayerInfo *p; int i; - /* store player action */ + // store player action for (p = first_player; p != NULL; p = p->next) { if (p->number == player->number) @@ -759,7 +752,7 @@ static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player) } } - /* check if server received action from each player */ + // check if server received action from each player for (p = first_player; p != NULL; p = p->next) { if (!p->action_received) @@ -771,11 +764,11 @@ static void Handle_OP_MOVE_PLAYER(struct NetworkServerPlayerInfo *player) int player_action_all[last_client_nr]; - /* initialize all player actions to zero */ + // initialize all player actions to zero for (i = 0; i < last_client_nr; i++) player_action_all[i] = 0; - /* broadcast actions of all players to all players */ + // broadcast actions of all players to all players for (p = first_player; p != NULL; p = p->next) { player_action_all[p->number - 1] = p->action; @@ -800,29 +793,37 @@ static void Handle_OP_BROADCAST_MESSAGE(struct NetworkServerPlayerInfo *player) { char *message = getNetworkBufferString(read_buffer); - if (options.verbose) - Error(ERR_NETWORK_SERVER, "client %d (%s) sends message: %s", - player->number, player->player_name, message); + Debug("network:server", "client %d (%s) sends message: %s", + player->number, player->player_name, message); copyNetworkBufferForWriting(read_buffer, write_buffer, player->number); SendNetworkBufferToAllButOne(write_buffer, player); } -void ExitNetworkServer(int exit_value) +static void Handle_OP_LEVEL_FILE(struct NetworkServerPlayerInfo *player) { - Error(ERR_NETWORK_SERVER, "exiting network server"); + copyNetworkBufferForWriting(read_buffer, write_buffer, player->number); + + SendNetworkBufferToAllButOne(write_buffer, player); +} + +static void ExitNetworkServer(int exit_value) +{ + Debug("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 */ +// the following is not used for a standalone server; +// the pointer points to an integer containing the port-number int NetworkServerThread(void *ptr) { + network.is_server_thread = TRUE; + NetworkServer(*((int *) ptr), 0); - /* should never be reached */ + // should never be reached return 0; } @@ -863,37 +864,28 @@ void NetworkServer(int port, int serveronly) #endif if (SDLNet_ResolveHost(&ip, NULL, port) == -1) - Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_ResolveHost() failed: %s", - SDLNet_GetError()); + Fail("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(); + Fail("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(); + Fail("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(); + Fail("SDLNet_TCP_AddSocket() failed: %s"), SDLNet_GetError(); if ((udp = SDLNet_UDP_Open(port)) == NULL) - Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_UDP_Open() failed: %s", - SDLNet_GetError()); + Fail("SDLNet_UDP_Open() failed: %s", SDLNet_GetError()); if (SDLNet_UDP_AddSocket(fds, udp) == -1) - Error(ERR_EXIT_NETWORK_SERVER, "SDLNet_TCP_AddSocket() failed: %s"), - SDLNet_GetError(); + Fail("SDLNet_TCP_AddSocket() failed: %s"), SDLNet_GetError(); - if (options.verbose) - { - Error(ERR_NETWORK_SERVER, "started up, listening on port %d", port); - Error(ERR_NETWORK_SERVER, "using protocol version %d.%d.%d", - PROTOCOL_VERSION_MAJOR, - PROTOCOL_VERSION_MINOR, - PROTOCOL_VERSION_PATCH); - } + Debug("network:server", "started up, listening on port %d", port); + Debug("network:server", "using protocol version %d.%d.%d", + PROTOCOL_VERSION_MAJOR, + PROTOCOL_VERSION_MINOR, + PROTOCOL_VERSION_PATCH); while (1) { @@ -901,10 +893,10 @@ void NetworkServer(int port, int serveronly) if (SDLNet_CheckSockets(fds, 100) < 1) continue; - /* accept incoming TCP connections */ + // accept incoming TCP connections if (SDLNet_SocketReady(lfd)) { - Error(ERR_DEBUG, "got TCP packet"); + Debug("network:server", "got TCP packet"); TCPsocket newsock; @@ -914,10 +906,10 @@ void NetworkServer(int port, int serveronly) AddPlayer(newsock); } - /* accept incoming UDP packets */ + // accept incoming UDP packets if (SDLNet_SocketReady(udp)) { - Error(ERR_DEBUG, "got UDP packet"); + Debug("network:server", "got UDP packet"); static UDPpacket packet; @@ -941,9 +933,8 @@ void NetworkServer(int port, int serveronly) if (num_bytes <= 0) { - if (options.verbose) - Error(ERR_NETWORK_SERVER, "EOF from client %d (%s)", - player->number, player->player_name); + Debug("network:server", "EOF from client %d (%s)", + player->number, player->player_name); RemovePlayer(player); @@ -954,15 +945,14 @@ void NetworkServer(int port, int serveronly) int message_type = getNetworkBuffer8BitInteger(read_buffer); - /* skip player number */ + // skip player number getNetworkBuffer8BitInteger(read_buffer); if (!player->introduced && message_type != OP_PLAYER_NAME && message_type != OP_PROTOCOL_VERSION) { - if (options.verbose) - Error(ERR_NETWORK_SERVER, "got opcode %d for client %d which is not introduced yet (expected OP_PLAYER_NAME or OP_PROTOCOL_VERSION)", message_type, player->number); + Debug("network:server", "got opcode %d for client %d which is not introduced yet (expected OP_PLAYER_NAME or OP_PROTOCOL_VERSION)", message_type, player->number); RemovePlayer(player); @@ -1007,11 +997,13 @@ void NetworkServer(int port, int serveronly) Handle_OP_BROADCAST_MESSAGE(player); break; + case OP_LEVEL_FILE: + Handle_OP_LEVEL_FILE(player); + break; + default: - if (options.verbose) - Error(ERR_NETWORK_SERVER, - "unknown opcode %d from client %d (%s)", - message_type, player->number, player->player_name); + Debug("network:server", "unknown opcode %d from client %d (%s)", + message_type, player->number, player->player_name); } } }