about summary refs log tree commit diff
path: root/src/engine/e_engine.c
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-10 21:54:52 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-02-10 21:54:52 +0000
commit548a919ea379a3b9d1d9e41cf4dad6b4779fd3e6 (patch)
tree85666198fed3d4803f3ec3373c134d12bde9329b /src/engine/e_engine.c
parent2f969d9d6fece689e05857580ffb1843439e5fbb (diff)
downloadzcatch-548a919ea379a3b9d1d9e41cf4dad6b4779fd3e6.tar.gz
zcatch-548a919ea379a3b9d1d9e41cf4dad6b4779fd3e6.zip
merged 0.3.4 changes to trunk
Diffstat (limited to 'src/engine/e_engine.c')
-rw-r--r--src/engine/e_engine.c215
1 files changed, 212 insertions, 3 deletions
diff --git a/src/engine/e_engine.c b/src/engine/e_engine.c
index f4f1ed3b..b85f1eb3 100644
--- a/src/engine/e_engine.c
+++ b/src/engine/e_engine.c
@@ -7,7 +7,8 @@
 /*#include <engine/e_client_interface.h>*/
 #include <engine/e_config.h>
 #include <engine/e_console.h>
-
+#include <engine/e_engine.h>
+#include "e_linereader.h"
 
 static void con_dbg_dumpmem(void *result, void *user_data)
 {
@@ -24,7 +25,7 @@ const char *engine_savepath(const char *filename, char *buffer, int max)
 }
 
 
-void engine_init(const char *appname, int argc, char **argv)
+void engine_init(const char *appname)
 {
 	dbg_msg("engine", "running on %s-%s-%s", CONF_FAMILY_STRING, CONF_PLATFORM_STRING, CONF_ARCH_STRING);
 #ifdef CONF_ARCH_ENDIAN_LITTLE
@@ -37,7 +38,7 @@ void engine_init(const char *appname, int argc, char **argv)
 
 	/* init the network */
 	net_init();
-
+	
 	/* create storage location */
 	{
 		char path[1024] = {0};
@@ -92,6 +93,10 @@ void engine_parse_arguments(int argc, char **argv)
 		for(i = 1; i < argc; i++)
 			config_set(argv[i]);
 	}
+	
+	/* set default servers and load from disk*/
+	mastersrv_default();
+	mastersrv_load();
 }
 
 void engine_writeconfig()
@@ -175,3 +180,207 @@ void perf_dump(PERFORMACE_INFO *top)
 {
 	perf_dump_imp(top, 0);
 }
+
+/* master server functions */
+enum
+{
+	NUM_LOOKUP_THREADS=4,
+	
+	STATE_PROCESSED=0,
+	STATE_RESULT,
+	STATE_QUERYING
+};
+
+typedef struct
+{
+	char hostname[128];
+	NETADDR4 addr;
+	
+	/* these are used for lookups */
+	struct {
+		NETADDR4 addr;
+		int result;
+		void *thread;
+		volatile int state;
+	} lookup;
+} MASTER_INFO;
+
+typedef struct
+{
+	int start;
+	int num;
+} THREAD_INFO;
+
+static MASTER_INFO master_servers[MAX_MASTERSERVERS] = {{{0}}};
+static THREAD_INFO thread_info[NUM_LOOKUP_THREADS];
+static int needs_update = 0;
+
+void lookup_thread(void *user)
+{
+	THREAD_INFO *info = (THREAD_INFO *)user;
+	int i;
+	
+	for(i = 0; i < info->num; i++)
+	{
+		int index = info->start+i;
+		master_servers[index].lookup.result = net_host_lookup(master_servers[index].hostname, 8300, &master_servers[index].lookup.addr);
+		master_servers[index].lookup.state = STATE_RESULT;
+	}
+}
+
+int mastersrv_refresh_addresses()
+{
+	int i;
+	dbg_msg("engine/mastersrv", "refreshing master server addresses");
+	
+	/* spawn threads that does the lookups */
+	for(i = 0; i < NUM_LOOKUP_THREADS; i++)	
+	{
+		thread_info[i].start = MAX_MASTERSERVERS/NUM_LOOKUP_THREADS * i;
+		thread_info[i].num = MAX_MASTERSERVERS/NUM_LOOKUP_THREADS;
+		master_servers[i].lookup.state = STATE_QUERYING;
+		master_servers[i].lookup.thread = thread_create(lookup_thread, &thread_info[i]);
+	}
+	
+	needs_update = 1;
+	return 0;
+}
+
+void mastersrv_update()
+{
+	int i;
+	
+	/* check if we need to update */
+	if(!needs_update)
+		return;
+	needs_update = 0;
+	
+	for(i = 0; i < MAX_MASTERSERVERS; i++)
+	{
+		if(master_servers[i].lookup.state == STATE_RESULT)
+		{
+			/* we got a result from the lookup ready */
+			if(master_servers[i].lookup.result == 0)
+				master_servers[i].addr = master_servers[i].lookup.addr;
+			master_servers[i].lookup.state = STATE_PROCESSED;
+		}
+
+		/* set the needs_update flag if we isn't done */		
+		if(master_servers[i].lookup.state != STATE_PROCESSED)
+			needs_update = 1;
+	}
+	
+	if(!needs_update)
+	{
+		dbg_msg("engine/mastersrv", "saving addresses");
+		mastersrv_save();
+	}
+}
+
+int mastersrv_refreshing()
+{
+	return needs_update;
+}
+
+NETADDR4 mastersrv_get(int index) 
+{
+	return master_servers[index].addr;
+}
+
+const char *mastersrv_name(int index) 
+{
+	return master_servers[index].hostname;
+}
+
+void mastersrv_dump_servers()
+{
+	int i;
+	for(i = 0; i < MAX_MASTERSERVERS; i++)
+	{
+		dbg_msg("mastersrv", "#%d = %d.%d.%d.%d", i,
+			master_servers[i].addr.ip[0], master_servers[i].addr.ip[1],
+			master_servers[i].addr.ip[2], master_servers[i].addr.ip[3]);
+	}
+}
+
+void mastersrv_default()
+{
+	int i;
+	mem_zero(master_servers, sizeof(master_servers));
+	for(i = 0; i < MAX_MASTERSERVERS; i++)
+		sprintf(master_servers[i].hostname, "master%d.teewars.com", i+1);
+}
+
+int mastersrv_load()
+{
+	LINEREADER lr;
+	IOHANDLE file;
+	int count = 0;
+	char filename[1024];
+	
+	engine_savepath("masters.cfg", filename, sizeof(filename));
+	
+	/* try to open file */
+	file = io_open(filename, IOFLAG_READ);
+	if(!file)
+		return -1;
+	
+	linereader_init(&lr, file);
+	while(1)
+	{
+		MASTER_INFO info = {{0}};
+		int ip[4];
+		const char *line = linereader_get(&lr);
+		if(!line)
+			break;
+
+		/* parse line */		
+		if(sscanf(line, "%s %d.%d.%d.%d", info.hostname, &ip[0], &ip[1], &ip[2], &ip[3]) == 5)
+		{
+			info.addr.ip[0] = (unsigned char)ip[0];
+			info.addr.ip[1] = (unsigned char)ip[1];
+			info.addr.ip[2] = (unsigned char)ip[2];
+			info.addr.ip[3] = (unsigned char)ip[3];
+			info.addr.port = 8300;
+			if(count != MAX_MASTERSERVERS)
+			{
+				master_servers[count] = info;
+				count++;
+			}
+			else
+				dbg_msg("engine/mastersrv", "warning: skipped master server '%s' due to limit of %d", line, MAX_MASTERSERVERS);
+		}
+		else
+			dbg_msg("engine/mastersrv", "warning: couldn't parse master server '%s'", line);
+	}
+	
+	io_close(file);
+	return 0;
+}
+
+int mastersrv_save()
+{
+	IOHANDLE file;
+	int i;
+	char filename[1024];
+
+	engine_savepath("masters.cfg", filename, sizeof(filename));
+	
+	/* try to open file */
+	file = io_open(filename, IOFLAG_WRITE);
+	if(!file)
+		return -1;
+
+	for(i = 0; i < MAX_MASTERSERVERS; i++)
+	{
+		char buf[1024];
+		sprintf(buf, "%s %d.%d.%d.%d\n", master_servers[i].hostname,
+			master_servers[i].addr.ip[0], master_servers[i].addr.ip[1],
+			master_servers[i].addr.ip[2], master_servers[i].addr.ip[3]);
+			
+		io_write(file, buf, strlen(buf));
+	}
+	
+	io_close(file);
+	return 0;
+}