Date: Sunday February 15, 2004 @ 19:45 Author: cameron Update of /home/netrek/cvsroot/Vanilla/ntserv In directory swashbuckler.real-time.com:/var/tmp/cvs-serv6142/ntserv Modified Files: Makefile.in data.c db.c getname.c getpath.c Log Message: add player file index support **************************************** Index: Vanilla/ntserv/Makefile.in diff -u Vanilla/ntserv/Makefile.in:1.5 Vanilla/ntserv/Makefile.in:1.6 --- Vanilla/ntserv/Makefile.in:1.5 Wed Sep 24 04:20:19 2003 +++ Vanilla/ntserv/Makefile.in Sun Feb 15 19:45:47 2004 @@ -73,6 +73,9 @@ commands.o: $(PMAKE) ${srcdir}/commands.c $(CC) $(CFLAGS) $(DEP) -c ${srcdir}/commands.c +db.o: ($PMAKE) db.c + $(CC) $(CFLAGS) $(DEP) `glib-config --cflags` -c $db.c + cflags: echo "static char cflags[]=\"$(CFLAGS) $(LIBS)\";" >../cflags.h Index: Vanilla/ntserv/data.c diff -u Vanilla/ntserv/data.c:1.19 Vanilla/ntserv/data.c:1.20 --- Vanilla/ntserv/data.c:1.19 Mon Jul 7 17:19:55 2003 +++ Vanilla/ntserv/data.c Sun Feb 15 19:45:47 2004 @@ -1,4 +1,4 @@ -/* $Id: data.c,v 1.19 2003/07/07 22:19:55 ahn Exp $ +/* $Id: data.c,v 1.20 2004/02/16 01:45:47 cameron Exp $ */ #include "copyright.h" @@ -237,6 +237,7 @@ char Robot[FNAMESIZE]; char LogFileName[FNAMESIZE]; char PlayerFile[FNAMESIZE]; +char PlayerIndexFile[FNAMESIZE]; char ConqFile[FNAMESIZE]; char SysDef_File[FNAMESIZE]; char Time_File[FNAMESIZE]; Index: Vanilla/ntserv/db.c diff -u Vanilla/ntserv/db.c:1.1 Vanilla/ntserv/db.c:1.2 --- Vanilla/ntserv/db.c:1.1 Wed Sep 24 04:14:02 2003 +++ Vanilla/ntserv/db.c Sun Feb 15 19:45:47 2004 @@ -11,7 +11,11 @@ #include <errno.h> #include <sys/types.h> #include <sys/time.h> +#include <time.h> #include <fcntl.h> +#ifdef PLAYER_INDEX +#include <gdbm.h> +#endif #include "defs.h" #include INC_STRINGS #include INC_UNISTD @@ -19,35 +23,169 @@ #include "data.h" #include "salt.h" +/* support for timing requires glib, not expected to remain */ +#define DB_TIMING 1 +#ifdef DB_TIMING +#include <glib.h> +#endif + +#ifdef PLAYER_INDEX + +/* fetch the offset to a player from the index database */ +static off_t db_index_fetch(char *namePick, struct statentry *player) { + GDBM_FILE dbf; + datum key, content; + off_t position; + + /* open the player index database */ + dbf = gdbm_open(PlayerIndexFile, 0, GDBM_WRCREAT, 0644, NULL); + if (dbf == NULL) { + ERROR(1,("db.c: db_index_fetch: gdbm_open('%s'): '%s', '%s'\n", + PlayerIndexFile, gdbm_strerror(gdbm_errno), strerror(errno))); + return -1; + } + ERROR(8,("db.c: db_index_fetch: gdbm_open('%s'): ok\n", + PlayerIndexFile)); + + /* fetch the database entry for this player name */ + key.dptr = namePick; + key.dsize = strlen(namePick); + content = gdbm_fetch(dbf, key); + + /* player index may not contain this player, that's fine */ + if (content.dptr == NULL) { + ERROR(8,("db.c: db_index_fetch: gdbm_fetch('%s'): not found in index\n", + namePick)); + gdbm_close(dbf); + return -1; + } + + if (content.dsize != sizeof(off_t)) { + ERROR(8,("db.c: db_index_fetch: gdbm_fetch('%s'): dsize [%d] not sizeof(off_t) [%d]\n", + namePick, content.dsize, sizeof(off_t))); + gdbm_close(dbf); + return -1; + } + + /* return the position from the database entry */ + position = *((off_t *) content.dptr); + free(content.dptr); + gdbm_close(dbf); + ERROR(8,("db.c: db_index_fetch: gdbm_fetch('%s'): index says position '%d'\n", + namePick, position)); + return position; +} + +/* store the offset to a player into the index database */ +static void db_index_store(struct statentry *player, off_t position) { + GDBM_FILE dbf; + datum key, content; + + /* open the player index database */ + dbf = gdbm_open(PlayerIndexFile, 0, GDBM_WRCREAT, 0644, NULL); + if (dbf == NULL) { return; } + + /* prepare the key and content pair from name and position */ + key.dptr = player->name; + key.dsize = strlen(player->name); + content.dptr = (char *) &position; + content.dsize = sizeof(position); + + /* store this key and position */ + if (gdbm_store(dbf, key, content, GDBM_REPLACE) < 0) { + ERROR(8,("db.c: db_index_store: gdbm_store('%s' -> '%d'): %s, %s\n", + player->name, position, gdbm_strerror(gdbm_errno), + strerror(errno))); + gdbm_close(dbf); + return; + } + + ERROR(8,("db.c: db_index_store: gdbm_store('%s' -> '%d'): ok\n", + player->name, position)); + gdbm_close(dbf); +} +#endif /* given a name, find the player in the file, return position */ int findplayer(char *namePick, struct statentry *player) { - int position, plfd; + off_t position; + int fd; +#ifdef DB_TIMING + GTimer *timer = g_timer_new(); +#endif - /* open the player file to find the player */ - plfd = open(PlayerFile, O_RDONLY, 0644); - if (plfd < 0) { - ERROR(1,("I cannot open the player file!\n")); - ERROR(1,("Error number: %d\n", errno)); + /* open the player file */ + fd = open(PlayerFile, O_RDONLY, 0644); + if (fd < 0) { + ERROR(1,("db.c: findplayer: open('%s'): '%s'\n", PlayerFile, + strerror(errno))); strcpy(player->name, namePick); +#ifdef DB_TIMING + g_timer_destroy(timer); +#endif return -1; } +#ifdef PLAYER_INDEX + /* use the index as a hint as to position in the player file */ + position = db_index_fetch(namePick, player); + + /* if an index entry was present, read the entry to check it's right */ + if (position != -1) { + lseek(fd, position * sizeof(struct statentry), SEEK_SET); + if (read(fd, (char *) player, sizeof(struct statentry)) < 0) { + /* read failed for some reason */ + ERROR(1,("db.c: findplayer: read: '%s'\n", strerror(errno))); + strcpy(player->name, ""); + } + /* check the entry in the main file matches what the index said */ + if (strcmp(namePick, player->name)==0) { + close(fd); + ERROR(8,("db.c: findplayer: ok, '%s' is indeed at position '%d'\n", + namePick, position)); +#ifdef DB_TIMING + ERROR(8,("db.c: timing, cached resolution, %f\n", g_timer_elapsed(timer, NULL))); + g_timer_destroy(timer); +#endif + return position; + } + /* otherwise there's an inconsistency that we can recover from */ + ERROR(2,("db.c: findplayer: player index inconsistent with player file, entered name '%s', index says position '%d', but file entry name '%s'\n", namePick, position, player->name)); + /* return file to start for sequential search */ + lseek(fd, 0, SEEK_SET); + } +#endif + /* sequential search of player file */ position = 0; - while (read(plfd, (char *) player, sizeof(struct statentry)) == + while (read(fd, (char *) player, sizeof(struct statentry)) == sizeof(struct statentry)) { if (strcmp(namePick, player->name)==0) { - close(plfd); + close(fd); +#ifdef PLAYER_INDEX + db_index_store(player, position); +#endif + ERROR(8,("db.c: findplayer: '%s' found in sequential scan at position '%d'\n", + namePick, position)); +#ifdef DB_TIMING + ERROR(8,("db.c: timing, sequential resolution, %f\n", g_timer_elapsed(timer, NULL))); + g_timer_destroy(timer); +#endif return position; } position++; } /* not found, return failure */ - close(plfd); + close(fd); strcpy(player->name, namePick); + ERROR(8,("db.c: findplayer: '%s' not found in sequential scan\n", + namePick)); +#ifdef DB_TIMING + ERROR(8,("db.c: timing, sequential failure, %f\n", g_timer_elapsed(timer, NULL))); + g_timer_destroy(timer); +#endif return -1; } @@ -55,6 +193,7 @@ { int fd; if (me->p_pos < 0) return; + ERROR(8,("db.c: savepass: saving to position '%d'\n", me->p_pos)); fd = open(PlayerFile, O_WRONLY, 0644); if (fd >= 0) { lseek(fd, me->p_pos * sizeof(struct statentry) + @@ -95,12 +234,24 @@ int newplayer(struct statentry *player) { - int plfd, file_pos; + int fd, offset, position; + + ERROR(8,("db.c: newplayer: adding '%s'\n", player->name)); + + fd = open(PlayerFile, O_RDWR|O_CREAT, 0644); + if (fd < 0) return -1; + if ((offset = lseek(fd, 0, SEEK_END)) < 0) return -1; + write(fd, (char *) player, sizeof(struct statentry)); + close(fd); + position = offset / sizeof(struct statentry); + + ERROR(8,("db.c: newplayer: sizeof '%d' offset '%d' position '%d'\n", + sizeof(struct statentry), offset, position)); + +#ifdef PLAYER_INDEX + /* do not create an index entry until the character name is reused, + because not all characters are re-used */ +#endif - plfd = open(PlayerFile, O_RDWR|O_CREAT, 0644); - if (plfd < 0) return -1; - if ((file_pos = lseek(plfd, 0, SEEK_END)) < 0) return -1; - write(plfd, (char *) &player, sizeof(struct statentry)); - close(plfd); - return file_pos / sizeof(struct statentry); + return position; } Index: Vanilla/ntserv/getname.c diff -u Vanilla/ntserv/getname.c:1.13 Vanilla/ntserv/getname.c:1.14 --- Vanilla/ntserv/getname.c:1.13 Sat Aug 23 01:14:19 2003 +++ Vanilla/ntserv/getname.c Sun Feb 15 19:45:47 2004 @@ -68,12 +68,10 @@ readFromClient(); } - /* ERROR(8,("handleLogin: %s %s %s\n", passPick[15] == 0 ? "attempt" : "query", namePick, passPick)); - */ - if ((strcmp(namePick, "Guest")==0 || strcmp(namePick, "guest")==0) && + if (streq(namePick, "Guest") || streq(namePick, "guest") && !lockout()) { handlelogin_guest: @@ -83,7 +81,7 @@ flushSockBuf(); return; } - /* todo: we don't check for existing players on INL robot entry */ + /* todo: we don't check for existing guests on INL robot entry */ hourratio=5; MZERO(&player.stats, sizeof(struct stats)); @@ -132,13 +130,13 @@ hourratio=1; /* We look for the guy in the stat file */ - if (strcmp(player.name, namePick) != 0) { + if (!streq(player.name, namePick)) { position = findplayer(namePick, &player); } /* Was this just a query? */ if (passPick[15]!=0) { - if (position== -1) { + if (position == -1) { sendClientLogin(NULL); } else { sendClientLogin(&player.stats); @@ -164,7 +162,7 @@ #endif /* A new guy? */ - if ((position== -1) && !lockout()) { + if ((position == -1) && !lockout()) { strcpy(player.name, namePick); /* Linux: compiler warnings with -Wall here, as crypt is in unistd.h but needs _XOPEN_SOURCE defined, which then breaks lots of other @@ -202,10 +200,10 @@ !streq(player.password, (char *) crypt(passPick, player.password)))) { sendClientLogin(NULL); flushSockBuf(); - /* ERROR(8,("handleLogin: password-failure namePick=%s passPick=%s file=%s newstyle=%s oldstyle=%s\n", namePick, passPick, player.password, newpass, (char *) crypt(passPick, player.password))); */ + ERROR(8,("handleLogin: password-failure namePick=%s passPick=%s file=%s newstyle=%s oldstyle=%s\n", namePick, passPick, player.password, newpass, (char *) crypt(passPick, player.password))); return; } - /* ERROR(8,("handleLogin: password-success namePick=%s passPick=%s file=%s newstyle=%s oldstyle=%s\n", namePick, passPick, player.password, newpass, (char *) crypt(passPick, player.password))); */ + ERROR(8,("handleLogin: password-success namePick=%s passPick=%s file=%s newstyle=%s oldstyle=%s\n", namePick, passPick, player.password, newpass, (char *) crypt(passPick, player.password))); sendClientLogin(&player.stats); strcpy(me->p_name, namePick); me->p_pos=position; Index: Vanilla/ntserv/getpath.c diff -u Vanilla/ntserv/getpath.c:1.6 Vanilla/ntserv/getpath.c:1.7 --- Vanilla/ntserv/getpath.c:1.6 Mon Jul 7 17:19:55 2003 +++ Vanilla/ntserv/getpath.c Sun Feb 15 19:45:47 2004 @@ -41,6 +41,8 @@ sprintf(PlayerFile,"%s/%s",path,N_PLAYERFILE); + sprintf(PlayerIndexFile,"%s/%s",path,N_PLAYERINDEXFILE); + sprintf(ConqFile,"%s/%s",path,N_CONQFILE); sprintf(SysDef_File,"%s/%s",path,N_SYSDEF_FILE); _______________________________________________ vanilla-devel mailing list vanilla-devel at us.netrek.org https://mailman.real-time.com/mailman/listinfo/vanilla-devel