diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-08-31 19:29:09 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-08-31 19:29:09 +0000 |
| commit | 62d9ff05d6cc0ae1cd952d51a168f6ffcf6abf60 (patch) | |
| tree | a8c6e49093df4fabdc5380149d73b8e7b9fcfc43 | |
| parent | 0a48454a554f8aa221a54b694b32b3004b9f6fd7 (diff) | |
| download | zcatch-62d9ff05d6cc0ae1cd952d51a168f6ffcf6abf60.tar.gz zcatch-62d9ff05d6cc0ae1cd952d51a168f6ffcf6abf60.zip | |
fixed connection less packets. they behave like the old version so version server and master servers still work
| -rw-r--r-- | src/engine/client/ec_client.c | 22 | ||||
| -rw-r--r-- | src/engine/e_network.c | 177 | ||||
| -rw-r--r-- | src/engine/e_network.h | 4 | ||||
| -rw-r--r-- | src/engine/server/es_server.c | 8 | ||||
| -rw-r--r-- | src/mastersrv/mastersrv.h | 6 |
5 files changed, 139 insertions, 78 deletions
diff --git a/src/engine/client/ec_client.c b/src/engine/client/ec_client.c index 409534d1..7445974f 100644 --- a/src/engine/client/ec_client.c +++ b/src/engine/client/ec_client.c @@ -711,19 +711,23 @@ static void client_process_packet(NETCHUNK *packet) memcmp(packet->data, SERVERBROWSE_LIST, sizeof(SERVERBROWSE_LIST)) == 0) { int size = packet->data_size-sizeof(SERVERBROWSE_LIST); - int num = size/sizeof(NETADDR); - NETADDR *addrs = (NETADDR *)((char*)packet->data+sizeof(SERVERBROWSE_LIST)); + int num = size/sizeof(MASTERSRV_ADDR); + MASTERSRV_ADDR *addrs = (MASTERSRV_ADDR *)((char*)packet->data+sizeof(SERVERBROWSE_LIST)); int i; - + for(i = 0; i < num; i++) { - NETADDR addr = addrs[i]; + NETADDR addr; SERVER_INFO info = {0}; - -#if defined(CONF_ARCH_ENDIAN_BIG) - const char *tmp = (const char *)&addr.port; - addr.port = (tmp[1]<<8) | tmp[0]; -#endif + + /* convert address */ + mem_zero(&addr, sizeof(addr)); + addr.type = NETTYPE_IPV4; + addr.ip[0] = addrs[i].ip[0]; + addr.ip[1] = addrs[i].ip[1]; + addr.ip[2] = addrs[i].ip[2]; + addr.ip[3] = addrs[i].ip[3]; + addr.port = (addrs[i].port[1]<<8) | addrs[i].port[0]; info.latency = 999; str_format(info.address, sizeof(info.address), "%d.%d.%d.%d:%d", diff --git a/src/engine/e_network.c b/src/engine/e_network.c index d3560d84..8f9a24e1 100644 --- a/src/engine/e_network.c +++ b/src/engine/e_network.c @@ -11,9 +11,13 @@ CURRENT: packet header: 3 bytes - unsigned char flags_ack; // 6bit flags, 2bit ack + unsigned char flags_ack; // 4bit flags, 4bit ack unsigned char ack; // 8 bit ack unsigned char num_chunks; // 8 bit chunks + + (unsigned char padding[3]) // 24 bit extra incase it's a connection less packet + // this is to make sure that it's compatible with the + // old protocol chunk header: 2-3 bytes unsigned char flags_size; // 2bit flags, 6 bit size @@ -41,8 +45,8 @@ enum NET_CONNSTATE_ERROR=4, NET_PACKETFLAG_CONTROL=1, - NET_PACKETFLAG_RESEND=2, - NET_PACKETFLAG_CONNLESS=4, + NET_PACKETFLAG_CONNLESS=2, + NET_PACKETFLAG_RESEND=4, NET_CHUNKFLAG_VITAL=1, NET_CHUNKFLAG_RESEND=2, @@ -82,10 +86,10 @@ typedef struct int64 first_send_time; } NETCHUNKDATA; -typedef struct RINGBUFFER_ITEM_t +typedef struct RINGBUFFER_ITEM { - struct RINGBUFFER_ITEM_t *next; - struct RINGBUFFER_ITEM_t *prev; + struct RINGBUFFER_ITEM *next; + struct RINGBUFFER_ITEM *prev; int size; } RINGBUFFER_ITEM; @@ -187,7 +191,7 @@ typedef struct unsigned char buffer[NET_MAX_PACKETSIZE]; } NETRECVINFO; -struct NETSERVER_t +struct NETSERVER { NETSOCKET socket; NETSLOT slots[NET_MAX_CLIENTS]; @@ -197,9 +201,9 @@ struct NETSERVER_t void *user_ptr; NETRECVINFO recv; -} ; +}; -struct NETCLIENT_t +struct NETCLIENT { NETADDR server_addr; NETSOCKET socket; @@ -214,6 +218,19 @@ static HUFFMAN_STATE huffmanstate; #define COMPRESSION 1 /* packs the data tight and sends it */ +static void send_packet_connless(NETSOCKET socket, NETADDR *addr, const void *data, int data_size) +{ + unsigned char buffer[NET_MAX_PACKETSIZE]; + buffer[0] = 0xff; + buffer[1] = 0xff; + buffer[2] = 0xff; + buffer[3] = 0xff; + buffer[4] = 0xff; + buffer[5] = 0xff; + mem_copy(&buffer[6], data, data_size); + net_udp_send(socket, addr, buffer, 6+data_size); +} + static void send_packet(NETSOCKET socket, NETADDR *addr, NETPACKETCONSTRUCT *packet) { unsigned char buffer[NET_MAX_PACKETSIZE]; @@ -254,10 +271,21 @@ static int unpack_packet(unsigned char *buffer, int size, NETPACKETCONSTRUCT *pa packet->num_chunks = buffer[2]; packet->data_size = size - NET_PACKETHEADERSIZE; - if(COMPRESSION) - huffman_decompress(&huffmanstate, &buffer[3], packet->data_size, packet->chunk_data, sizeof(packet->chunk_data)); + if(packet->flags&NET_PACKETFLAG_CONNLESS) + { + packet->flags = NET_PACKETFLAG_CONNLESS; + packet->ack = 0; + packet->num_chunks = 0; + packet->data_size = size - 6; + mem_copy(packet->chunk_data, &buffer[6], packet->data_size); + } else - mem_copy(packet->chunk_data, &buffer[3], packet->data_size); + { + if(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); + } /* return success */ return 0; @@ -810,57 +838,68 @@ int netserver_recv(NETSERVER *s, NETCHUNK *chunk) if(unpack_packet(s->recv.buffer, bytes, &s->recv.data) == 0) { - /* TODO: handle connection less packets here */ - /* TODO: check size here */ - if(s->recv.data.flags&NET_PACKETFLAG_CONTROL && s->recv.data.chunk_data[0] == NET_CTRLMSG_CONNECT) + if(s->recv.data.flags&NET_PACKETFLAG_CONNLESS) { - found = 0; - - /* check if we already got this client */ - for(i = 0; i < s->max_clients; i++) - { - if(s->slots[i].conn.state != NET_CONNSTATE_OFFLINE && - net_addr_comp(&s->slots[i].conn.peeraddr, &addr) == 0) - { - found = 1; /* silent ignore.. we got this client already */ - break; - } - } - - /* client that wants to connect */ - if(!found) + chunk->flags = NETSENDFLAG_CONNLESS; + chunk->client_id = -1; + chunk->address = addr; + chunk->data_size = s->recv.data.data_size; + chunk->data = s->recv.data.chunk_data; + return 1; + } + else + { + /* TODO: check size here */ + if(s->recv.data.flags&NET_PACKETFLAG_CONTROL && s->recv.data.chunk_data[0] == NET_CTRLMSG_CONNECT) { found = 0; + /* check if we already got this client */ for(i = 0; i < s->max_clients; i++) { - if(s->slots[i].conn.state == NET_CONNSTATE_OFFLINE) + if(s->slots[i].conn.state != NET_CONNSTATE_OFFLINE && + net_addr_comp(&s->slots[i].conn.peeraddr, &addr) == 0) { - found = 1; - conn_feed(&s->slots[i].conn, &s->recv.data, &addr); - if(s->new_client) - s->new_client(i, s->user_ptr); + found = 1; /* silent ignore.. we got this client already */ break; } } + /* client that wants to connect */ if(!found) { - /* TODO: send server full emssage */ + found = 0; + + for(i = 0; i < s->max_clients; i++) + { + if(s->slots[i].conn.state == NET_CONNSTATE_OFFLINE) + { + found = 1; + conn_feed(&s->slots[i].conn, &s->recv.data, &addr); + if(s->new_client) + s->new_client(i, s->user_ptr); + break; + } + } + + if(!found) + { + /* TODO: send server full emssage */ + } } } - } - else - { - /* normal packet, find matching slot */ - for(i = 0; i < s->max_clients; i++) + else { - if(net_addr_comp(&s->slots[i].conn.peeraddr, &addr) == 0) + /* normal packet, find matching slot */ + for(i = 0; i < s->max_clients; i++) { - if(conn_feed(&s->slots[i].conn, &s->recv.data, &addr)) + if(net_addr_comp(&s->slots[i].conn.peeraddr, &addr) == 0) { - if(s->recv.data.data_size) - recvinfo_start(&s->recv, &addr, &s->slots[i].conn, i); + if(conn_feed(&s->slots[i].conn, &s->recv.data, &addr)) + { + if(s->recv.data.data_size) + recvinfo_start(&s->recv, &addr, &s->slots[i].conn, i); + } } } } @@ -880,7 +919,8 @@ int netserver_send(NETSERVER *s, NETCHUNK *chunk) if(chunk->flags&NETSENDFLAG_CONNLESS) { - /* TODO: handle connectionless */ + /* send connectionless packet */ + send_packet_connless(s->socket, &chunk->address, chunk->data, chunk->data_size); } else { @@ -985,9 +1025,20 @@ int netclient_recv(NETCLIENT *c, NETCHUNK *chunk) if(unpack_packet(c->recv.buffer, bytes, &c->recv.data) == 0) { - /* TODO: handle connection less packets here */ - if(conn_feed(&c->conn, &c->recv.data, &addr)) - recvinfo_start(&c->recv, &addr, &c->conn, 0); + if(c->recv.data.flags&NET_PACKETFLAG_CONNLESS) + { + chunk->flags = NETSENDFLAG_CONNLESS; + chunk->client_id = -1; + chunk->address = addr; + chunk->data_size = c->recv.data.data_size; + chunk->data = c->recv.data.chunk_data; + return 1; + } + else + { + if(conn_feed(&c->conn, &c->recv.data, &addr)) + recvinfo_start(&c->recv, &addr, &c->conn, 0); + } } } return 0; @@ -1004,7 +1055,7 @@ int netclient_send(NETCLIENT *c, NETCHUNK *chunk) if(chunk->flags&NETSENDFLAG_CONNLESS) { /* send connectionless packet */ - /* TODO: fix connectionless packets */ + send_packet_connless(c->socket, &chunk->address, chunk->data, chunk->data_size); } else { @@ -1060,19 +1111,19 @@ void netcommon_openlog(const char *filename) static const unsigned freq_table[256+1] = { -1<<30,4545,2657,431,1950,919,444,482,2244,617,838,542,715,1814,304,240,754,212,647,186, -283,131,146,166,543,164,167,136,179,859,363,113,157,154,204,108,137,180,202,176, -872,404,168,134,151,111,113,109,120,126,129,100,41,20,16,22,18,18,17,19, -16,37,13,21,362,166,99,78,95,88,81,70,83,284,91,187,77,68,52,68, -59,66,61,638,71,157,50,46,69,43,11,24,13,19,10,12,12,20,14,9, -20,20,10,10,15,15,12,12,7,19,15,14,13,18,35,19,17,14,8,5, -15,17,9,15,14,18,8,10,2173,134,157,68,188,60,170,60,194,62,175,71, -148,67,167,78,211,67,156,69,1674,90,174,53,147,89,181,51,174,63,163,80, -167,94,128,122,223,153,218,77,200,110,190,73,174,69,145,66,277,143,141,60, -136,53,180,57,142,57,158,61,166,112,152,92,26,22,21,28,20,26,30,21, -32,27,20,17,23,21,30,22,22,21,27,25,17,27,23,18,39,26,15,21, -12,18,18,27,20,18,15,19,11,17,33,12,18,15,19,18,16,26,17,18, -9,10,25,22,22,17,20,16,6,16,15,20,14,18,24,335,1517 }; + 1<<30,4545,2657,431,1950,919,444,482,2244,617,838,542,715,1814,304,240,754,212,647,186, + 283,131,146,166,543,164,167,136,179,859,363,113,157,154,204,108,137,180,202,176, + 872,404,168,134,151,111,113,109,120,126,129,100,41,20,16,22,18,18,17,19, + 16,37,13,21,362,166,99,78,95,88,81,70,83,284,91,187,77,68,52,68, + 59,66,61,638,71,157,50,46,69,43,11,24,13,19,10,12,12,20,14,9, + 20,20,10,10,15,15,12,12,7,19,15,14,13,18,35,19,17,14,8,5, + 15,17,9,15,14,18,8,10,2173,134,157,68,188,60,170,60,194,62,175,71, + 148,67,167,78,211,67,156,69,1674,90,174,53,147,89,181,51,174,63,163,80, + 167,94,128,122,223,153,218,77,200,110,190,73,174,69,145,66,277,143,141,60, + 136,53,180,57,142,57,158,61,166,112,152,92,26,22,21,28,20,26,30,21, + 32,27,20,17,23,21,30,22,22,21,27,25,17,27,23,18,39,26,15,21, + 12,18,18,27,20,18,15,19,11,17,33,12,18,15,19,18,16,26,17,18, + 9,10,25,22,22,17,20,16,6,16,15,20,14,18,24,335,1517}; void netcommon_init() { diff --git a/src/engine/e_network.h b/src/engine/e_network.h index eaa9df39..efacc9fa 100644 --- a/src/engine/e_network.h +++ b/src/engine/e_network.h @@ -22,8 +22,8 @@ typedef struct int resend_bytes; } NETSTATS;*/ -typedef struct NETSERVER_t NETSERVER; -typedef struct NETCLIENT_t NETCLIENT; +typedef struct NETSERVER NETSERVER; +typedef struct NETCLIENT NETCLIENT; enum { diff --git a/src/engine/server/es_server.c b/src/engine/server/es_server.c index 8db9865c..62a8921d 100644 --- a/src/engine/server/es_server.c +++ b/src/engine/server/es_server.c @@ -787,12 +787,12 @@ static void server_send_serverinfo(NETADDR *addr, int lan) char buf[128]; /* count the players */ - int c = 0; + int player_count = 0; int i; for(i = 0; i < MAX_CLIENTS; i++) { if(clients[i].state != SRVCLIENT_STATE_EMPTY) - c++; + player_count++; } packer_reset(&p); @@ -806,7 +806,7 @@ static void server_send_serverinfo(NETADDR *addr, int lan) /* gametype */ str_format(buf, sizeof(buf), "%d", browseinfo_gametype); - packer_add_string(&p, buf, 2); + packer_add_string(&p, browseinfo_gametype, 16); /* flags */ i = 0; @@ -819,7 +819,7 @@ static void server_send_serverinfo(NETADDR *addr, int lan) str_format(buf, sizeof(buf), "%d", browseinfo_progression); packer_add_string(&p, buf, 4); - str_format(buf, sizeof(buf), "%d", c); packer_add_string(&p, buf, 3); /* num players */ + str_format(buf, sizeof(buf), "%d", player_count); packer_add_string(&p, buf, 3); /* num players */ str_format(buf, sizeof(buf), "%d", netserver_max_clients(net)); packer_add_string(&p, buf, 3); /* max players */ for(i = 0; i < MAX_CLIENTS; i++) diff --git a/src/mastersrv/mastersrv.h b/src/mastersrv/mastersrv.h index b5347914..86cd28fe 100644 --- a/src/mastersrv/mastersrv.h +++ b/src/mastersrv/mastersrv.h @@ -5,6 +5,12 @@ enum { MAX_SERVERS = 200 }; +typedef struct MASTERSRV_ADDR +{ + unsigned char ip[4]; + unsigned char port[2]; +} MASTERSRV_ADDR; + static const unsigned char SERVERBROWSE_HEARTBEAT[] = {255, 255, 255, 255, 'b', 'e', 'a', 't'}; static const unsigned char SERVERBROWSE_GETLIST[] = {255, 255, 255, 255, 'r', 'e', 'q', 't'}; |