about summary refs log tree commit diff
path: root/src/engine
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-08-31 19:29:09 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-08-31 19:29:09 +0000
commit62d9ff05d6cc0ae1cd952d51a168f6ffcf6abf60 (patch)
treea8c6e49093df4fabdc5380149d73b8e7b9fcfc43 /src/engine
parent0a48454a554f8aa221a54b694b32b3004b9f6fd7 (diff)
downloadzcatch-62d9ff05d6cc0ae1cd952d51a168f6ffcf6abf60.tar.gz
zcatch-62d9ff05d6cc0ae1cd952d51a168f6ffcf6abf60.zip
fixed connection less packets. they behave like the old version so version server and master servers still work
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/client/ec_client.c22
-rw-r--r--src/engine/e_network.c177
-rw-r--r--src/engine/e_network.h4
-rw-r--r--src/engine/server/es_server.c8
4 files changed, 133 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++)