diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-02-10 21:54:52 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-02-10 21:54:52 +0000 |
| commit | 548a919ea379a3b9d1d9e41cf4dad6b4779fd3e6 (patch) | |
| tree | 85666198fed3d4803f3ec3373c134d12bde9329b /src/engine/e_engine.c | |
| parent | 2f969d9d6fece689e05857580ffb1843439e5fbb (diff) | |
| download | zcatch-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.c | 215 |
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; +} |