diff options
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/e_network.c | 34 | ||||
| -rw-r--r-- | src/engine/server/es_server.c | 45 |
2 files changed, 48 insertions, 31 deletions
diff --git a/src/engine/e_network.c b/src/engine/e_network.c index ed9f3405..85a9117c 100644 --- a/src/engine/e_network.c +++ b/src/engine/e_network.c @@ -47,6 +47,7 @@ enum NET_PACKETFLAG_CONTROL=1, NET_PACKETFLAG_CONNLESS=2, NET_PACKETFLAG_RESEND=4, + NET_PACKETFLAG_COMPRESSION=8, NET_CHUNKFLAG_VITAL=1, NET_CHUNKFLAG_RESEND=2, @@ -234,24 +235,41 @@ static void send_packet_connless(NETSOCKET socket, NETADDR *addr, const void *da static void send_packet(NETSOCKET socket, NETADDR *addr, NETPACKETCONSTRUCT *packet) { unsigned char buffer[NET_MAX_PACKETSIZE]; - buffer[0] = ((packet->flags<<4)&0xf0)|((packet->ack>>8)&0xf); - buffer[1] = packet->ack&0xff; - buffer[2] = packet->num_chunks; + int compressed_size = -1; + int final_size = -1; + + /* log the data */ if(datalog) { io_write(datalog, &packet->data_size, sizeof(packet->data_size)); io_write(datalog, &packet->chunk_data, packet->data_size); } + /* compress if its enabled */ if(COMPRESSION) + compressed_size = huffman_compress(&huffmanstate, packet->chunk_data, packet->data_size, &buffer[3], NET_MAX_PACKETSIZE-4); + + /* check if the compression was enabled, successful and good enough */ + if(compressed_size > 0 && compressed_size < packet->data_size) { - int compressed_size = huffman_compress(&huffmanstate, packet->chunk_data, packet->data_size, &buffer[3], NET_MAX_PACKETSIZE-4); - net_udp_send(socket, addr, buffer, NET_PACKETHEADERSIZE+compressed_size); + final_size = compressed_size; + packet->flags |= NET_PACKETFLAG_COMPRESSION; } else { + /* use uncompressed data */ + final_size = packet->data_size; mem_copy(&buffer[3], packet->chunk_data, packet->data_size); - net_udp_send(socket, addr, buffer, NET_PACKETHEADERSIZE+packet->data_size); + packet->flags &= ~NET_PACKETFLAG_COMPRESSION; + } + + /* set header and send the packet if all things are good */ + if(final_size >= 0) + { + buffer[0] = ((packet->flags<<4)&0xf0)|((packet->ack>>8)&0xf); + buffer[1] = packet->ack&0xff; + buffer[2] = packet->num_chunks; + net_udp_send(socket, addr, buffer, NET_PACKETHEADERSIZE+final_size); } } @@ -261,7 +279,7 @@ static int unpack_packet(unsigned char *buffer, int size, NETPACKETCONSTRUCT *pa /* check the size */ if(size < NET_PACKETHEADERSIZE || size > NET_MAX_PACKETSIZE) { - dbg_msg("", "packet too small"); + dbg_msg("", "packet too small, %d", size); return -1; } @@ -281,7 +299,7 @@ static int unpack_packet(unsigned char *buffer, int size, NETPACKETCONSTRUCT *pa } else { - if(COMPRESSION) + if(packet->flags&NET_PACKETFLAG_COMPRESSION) huffman_decompress(&huffmanstate, &buffer[3], packet->data_size, packet->chunk_data, sizeof(packet->chunk_data)); else mem_copy(packet->chunk_data, &buffer[3], packet->data_size); diff --git a/src/engine/server/es_server.c b/src/engine/server/es_server.c index a3c8327f..6cdf835f 100644 --- a/src/engine/server/es_server.c +++ b/src/engine/server/es_server.c @@ -38,8 +38,6 @@ static int browseinfo_progression = -1; static int64 lastheartbeat; /*static NETADDR4 master_server;*/ - - static char current_map[64]; static int current_map_crc; static unsigned char *current_map_data = 0; @@ -521,40 +519,40 @@ static void server_do_snap() } -static int new_client_callback(int cid, void *user) +static void reset_client(int cid) { - int i; - clients[cid].state = SRVCLIENT_STATE_CONNECTING; - clients[cid].name[0] = 0; - clients[cid].clan[0] = 0; - /* reset input */ + int i; for(i = 0; i < 200; i++) { clients[cid].inputs[i].game_tick = -1; clients[cid].inputs[i].pred_tick = -1; } clients[cid].current_input = 0; - mem_zero(&clients[cid].latestinput, sizeof(clients[cid].latestinput)); - + snapstorage_purge_all(&clients[cid].snapshots); clients[cid].last_acked_snapshot = -1; clients[cid].snap_rate = SRVCLIENT_SNAPRATE_INIT; clients[cid].score = 0; clients[cid].authed = 0; +} + +static int new_client_callback(int cid, void *user) +{ + clients[cid].state = SRVCLIENT_STATE_CONNECTING; + clients[cid].name[0] = 0; + clients[cid].clan[0] = 0; + reset_client(cid); return 0; } static int del_client_callback(int cid, void *user) { /* notify the mod about the drop */ - if(clients[cid].state == SRVCLIENT_STATE_READY || - clients[cid].state == SRVCLIENT_STATE_INGAME) - { + if(clients[cid].state >= SRVCLIENT_STATE_READY) mods_client_drop(cid); - } - + clients[cid].state = SRVCLIENT_STATE_EMPTY; clients[cid].name[0] = 0; clients[cid].clan[0] = 0; @@ -682,7 +680,7 @@ static void server_process_client_packet(NETCHUNK *packet) int tick, size, i; CLIENT_INPUT *input; int64 tagtime; - + clients[cid].last_acked_snapshot = msg_unpack_int(); tick = msg_unpack_int(); size = msg_unpack_int(); @@ -690,7 +688,7 @@ static void server_process_client_packet(NETCHUNK *packet) /* check for errors */ if(msg_unpack_error() || size/4 > MAX_INPUT_SIZE) return; - + if(clients[cid].last_acked_snapshot > 0) clients[cid].snap_rate = SRVCLIENT_SNAPRATE_FULL; @@ -715,7 +713,8 @@ static void server_process_client_packet(NETCHUNK *packet) clients[cid].current_input %= 200; /* call the mod with the fresh input data */ - mods_client_direct_input(cid, clients[cid].latestinput.data); + if(clients[cid].state == SRVCLIENT_STATE_INGAME) + mods_client_direct_input(cid, clients[cid].latestinput.data); } else if(msg == NETMSG_RCON_CMD) { @@ -784,7 +783,8 @@ static void server_process_client_packet(NETCHUNK *packet) else { /* game message */ - mods_message(msg, cid); + if(clients[cid].state >= SRVCLIENT_STATE_READY) + mods_message(msg, cid); } } @@ -992,10 +992,8 @@ static int server_run() continue; server_send_map(c); + reset_client(c); clients[c].state = SRVCLIENT_STATE_CONNECTING; - clients[c].last_acked_snapshot = -1; - clients[c].snap_rate = SRVCLIENT_SNAPRATE_RECOVER; - snapstorage_purge_all(&clients[c].snapshots); } game_start_time = time_get(); @@ -1029,7 +1027,8 @@ static int server_run() { if(clients[c].inputs[i].game_tick == server_tick()) { - mods_client_predicted_input(c, clients[c].inputs[i].data); + if(clients[c].state == SRVCLIENT_STATE_INGAME) + mods_client_predicted_input(c, clients[c].inputs[i].data); break; } } |