--- deliantra/server/common/region.C 2007/01/29 14:46:01 1.19 +++ deliantra/server/common/region.C 2007/01/29 15:04:21 1.20 @@ -217,6 +217,95 @@ } /* + * Reads/parses the region file, and copies into a linked list + * of region structs. + */ +static bool +parse_regions (object_thawer &fp) +{ + region *newreg; + region *reg; + + newreg = NULL; + for (;;) + { + keyword kw = fp.get_kv (); + + switch (kw) + { + case KW_EOF: + if (newreg) + { + LOG (llevError, "%s: end of file while reading regions.\n", fp.name); + return false; + } + else + return true; + + case KW_end: + /* Place this new region last on the list, if the list is empty put it first */ + for (reg = first_region; reg && reg->next; reg = reg->next) + ; + + if (!reg) + first_region = newreg; + else + reg->next = newreg; + + newreg = 0; + break; + + default: + case KW_ERROR: + LOG (llevError, "%s: skipping errornous line (%s) while reading regions.\n", fp.name, fp.last_keyword); + break; + + case KW_region: + newreg = new region; + fp.get (newreg->name); + break; + + case KW_parent: + /* + * Note that this is in the initialisation code, so we don't actually + * assign the pointer to the parent yet, because it might not have been + * parsed. + */ + fp.get (newreg->parent_name); + break; + + case KW_longname: + newreg->longname = strdup (fp.get_str ()); + break; + + case KW_jail_map: + fp.get (newreg->jailmap); + break; + + case KW_jail_x: + fp.get (newreg->jailx); + break; + + case KW_jail_y: + fp.get (newreg->jaily); + break; + + case KW_msg: + fp.get_ml (KW_endmsg, newreg->msg); + break; + + case KW_fallback: + fp.get (newreg->fallback); + break; + + case KW_nomore: + /* we have reached the end of the region specs.... */ + return true; + } + } +} + +/* * First initialises the archtype hash-table (init_archetable()). * Reads and parses the archetype file (with the first and second-pass * functions). @@ -225,7 +314,6 @@ void init_regions (void) { - FILE *fp; char filename[MAX_BUF]; int comp; @@ -239,156 +327,17 @@ sprintf (filename, "%s/%s/%s", settings.datadir, settings.mapdir, settings.regions); LOG (llevDebug, "Reading regions from %s...\n", filename); - if ((fp = open_and_uncompress (filename, 0, &comp)) == NULL) + + object_thawer fp (filename); + + if (!fp) { LOG (llevError, " Can't open regions file %s in init_regions.\n", filename); return; } parse_regions (fp); + assign_region_parents (); LOG (llevDebug, " done\n"); - - close_and_delete (fp, comp); } - -/* - * Reads/parses the region file, and copies into a linked list - * of region structs. - */ -void -parse_regions (FILE * fp) -{ - region *newreg; - region *reg; - - char buf[HUGE_BUF], msgbuf[HUGE_BUF], *key = NULL, *value, *end; - int msgpos = 0; - - newreg = NULL; - while (fgets (buf, HUGE_BUF - 1, fp) != NULL) - { - buf[HUGE_BUF - 1] = 0; - key = buf; - while (isspace (*key)) - key++; - if (*key == 0) - continue; /* empty line */ - value = strchr (key, ' '); - if (!value) - { - end = strchr (key, '\n'); - *end = 0; - } - else - { - *value = 0; - value++; - while (isspace (*value)) - value++; - end = strchr (value, '\n'); - } - - /* - * This is a bizzare mutated form of the map and archetype parser - * rolled into one. Key is the field name, value is what it should - * be set to. - * We've already done the work to null terminate key, - * and strip off any leading spaces for both of these. - * We have not touched the newline at the end of the line - - * these might be needed for some values. the end pointer - * points to the first of the newlines. - * value could be NULL! It would be easy enough to just point - * this to "" to prevent cores, but that would let more errors slide - * through. - */ - if (!strcmp (key, "region")) - { - *end = 0; - newreg = new region; - newreg->name = value; - } - else if (!strcmp (key, "parent")) - { - /* - * Note that this is in the initialisation code, so we don't actually - * assign the pointer to the parent yet, because it might not have been - * parsed. - */ - *end = 0; - newreg->parent_name = value; - } - else if (!strcmp (key, "longname")) - { - *end = 0; - newreg->longname = strdup (value); - } - else if (!strcmp (key, "jail")) - { - /* jail entries are of the form: /path/to/map x y */ - char path[MAX_BUF]; - int x, y; - - if (sscanf (value, "%[^ ] %d %d\n", path, &x, &y) != 3) - { - LOG (llevError, "region.c: malformated regions entry: jail %s\n", value); - continue; - } - newreg->jailmap = strdup (path); - newreg->jailx = x; - newreg->jaily = y; - } - else if (!strcmp (key, "msg")) - { - while (fgets (buf, HUGE_BUF - 1, fp) != NULL) - { - if (!strcmp (buf, "endmsg\n")) - break; - else - { - strcpy (msgbuf + msgpos, buf); - msgpos += strlen (buf); - } - } - /* - * There may be regions with empty messages (eg, msg/endmsg - * with nothing between). When maps are loaded, this is done - * so better do it here too... - */ - if (msgpos != 0) - newreg->msg = strdup (msgbuf); - - /* we have to reset msgpos, or the next region will store both msg blocks. */ - msgpos = 0; - } - else if (!strcmp (key, "fallback")) - { - *end = 0; - newreg->fallback = atoi (value); - } - else if (!strcmp (key, "end")) - { - /* Place this new region last on the list, if the list is empty put it first */ - for (reg = first_region; reg != NULL && reg->next != NULL; reg = reg->next); - - if (reg == NULL) - first_region = newreg; - else - reg->next = newreg; - newreg = NULL; - } - else if (!strcmp (key, "nomore")) - { - /* we have reached the end of the region specs.... */ - break; - } - else - { - /* we should never get here, if we have, then something is wrong */ - LOG (llevError, "Got unknown value in region file: %s %s\n", key, value); - } - } - if (!key || strcmp (key, "nomore")) - LOG (llevError, "Got premature eof on regions file!\n"); -} -