X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fnetserv.c;h=25055e019e06a73745d5c2353ea4482e62156ec7;hp=551772a00c883b5053ddfe00b2925f6bf8ee2b5d;hb=10406b9d6cad2b0ec7c30c71520abe2c702bccbc;hpb=45c910a978cabc8e8dd40fac47b17b7d402c91aa diff --git a/src/netserv.c b/src/netserv.c index 551772a0..25055e01 100644 --- a/src/netserv.c +++ b/src/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) + { + Error(ERR_NETWORK_SERVER, "protocol error: invalid packet size %d", + num_bytes); + + return -1; + } + if (nb->pos + num_bytes > nb->max_size) increaseNetworkBuffer(nb, num_bytes); @@ -312,19 +320,99 @@ void putNetworkBufferString(struct NetworkBuffer *nb, char *s) nb->size = nb->pos; } +int getNetworkBufferFile(struct NetworkBuffer *nb, char *filename) +{ + FILE *file; + int num_bytes = getNetworkBuffer32BitInteger(nb); + int i; + + if (!(file = fopen(filename, MODE_WRITE))) + { + Error(ERR_WARN, "cannot write file '%s' from network buffer", filename); + + return 0; + } + + for (i = 0; i < num_bytes; i++) + { + int b = getNetworkBuffer8BitInteger(nb); + + putFile8Bit(file, b); + } + + fclose(file); + + return num_bytes; +} + +int putNetworkBufferFile(struct NetworkBuffer *nb, char *filename) +{ + File *file; + int filesize_pos = nb->pos; + int num_bytes = 0; + + // 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); + + return 0; + } + + while (1) + { + int b = getFile8Bit(file); + + if (checkEndOfFile(file)) + break; + + putNetworkBuffer8BitInteger(nb, b); + + num_bytes++; + } + + closeFile(file); + + // set file size + putNetwork32BitInteger(&nb->buffer[filesize_pos], num_bytes); + + return num_bytes; +} + +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); + + for (i = 0; i < nb->size; i++) + { + if ((i % 16) == 0) + printf("\n::: "); + + printf("%02x ", nb->buffer[i]); + } + + printf("\n"); +} + static void SendNetworkBufferToAllButOne(struct NetworkBuffer *nb, struct NetworkServerPlayerInfo *except) { 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); } } @@ -338,10 +426,10 @@ 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); } @@ -384,7 +472,7 @@ 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) @@ -607,12 +695,12 @@ static void Handle_OP_START_PLAYING(struct NetworkServerPlayerInfo *player) struct NetworkServerPlayerInfo *p; - /* reset frame counter */ + // reset frame counter ServerFrameCounter = 0; Error(ERR_NETWORK_SERVER, "resetting ServerFrameCounter to 0"); - /* reset player actions */ + // reset player actions for (p = first_player; p != NULL; p = p->next) { p->action = 0; @@ -669,7 +757,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) @@ -679,7 +767,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) @@ -691,11 +779,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; @@ -729,20 +817,27 @@ static void Handle_OP_BROADCAST_MESSAGE(struct NetworkServerPlayerInfo *player) SendNetworkBufferToAllButOne(write_buffer, player); } -void ExitNetworkServer(int exit_value) +static void Handle_OP_LEVEL_FILE(struct NetworkServerPlayerInfo *player) +{ + copyNetworkBufferForWriting(read_buffer, write_buffer, player->number); + + SendNetworkBufferToAllButOne(write_buffer, player); +} + +static 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 */ +// 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 */ + // should never be reached return 0; } @@ -821,7 +916,7 @@ 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"); @@ -834,7 +929,7 @@ 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"); @@ -874,7 +969,7 @@ void NetworkServer(int port, int serveronly) int message_type = getNetworkBuffer8BitInteger(read_buffer); - /* skip player number */ + // skip player number getNetworkBuffer8BitInteger(read_buffer); if (!player->introduced && @@ -927,6 +1022,10 @@ 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,