diff --git a/src/alchemy.c b/src/alchemy.c index 3d37af6a7..86f6e6bb6 100644 --- a/src/alchemy.c +++ b/src/alchemy.c @@ -33,6 +33,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include +#include #include #include #include @@ -301,8 +302,9 @@ a_writeeffect(const attrib * a, const void *owner, struct storage *store) WRITE_INT(store, edata->value); } -static int a_readeffect(attrib * a, void *owner, struct storage *store) +static int a_readeffect(attrib * a, void *owner, struct gamedata *data) { + struct storage *store = data->store; int power; const resource_type *rtype; effect_data *edata = (effect_data *)a->data.v; diff --git a/src/attributes/attributes.c b/src/attributes/attributes.c index 47e5e4cc0..770ba7524 100644 --- a/src/attributes/attributes.c +++ b/src/attributes/attributes.c @@ -57,6 +57,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include @@ -64,12 +65,12 @@ attrib_type at_unitdissolve = { "unitdissolve", NULL, NULL, NULL, a_writechars, a_readchars }; -static int read_ext(attrib * a, void *owner, struct storage *store) +static int read_ext(attrib * a, void *owner, gamedata *data) { int len; - READ_INT(store, &len); - store->api->r_bin(store->handle, NULL, (size_t)len); + READ_INT(data->store, &len); + data->store->api->r_bin(data->store->handle, NULL, (size_t)len); return AT_READ_OK; } diff --git a/src/attributes/dict.c b/src/attributes/dict.c index 7ce81d6a3..fa65d1f3d 100644 --- a/src/attributes/dict.c +++ b/src/attributes/dict.c @@ -31,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include +#include #include #include @@ -95,63 +96,64 @@ dict_write(const attrib * a, const void *owner, struct storage *store) } } -static int dict_read(attrib * a, void *owner, struct storage *store) +static int dict_read(attrib * a, void *owner, gamedata *data) { + storage *store = data->store; char name[NAMESIZE]; - dict_data *data = (dict_data *)a->data.v; + dict_data *dd = (dict_data *)a->data.v; int result, n; float flt; READ_STR(store, name, sizeof(name)); - data->name = _strdup(name); + dd->name = _strdup(name); READ_INT(store, &n); - data->type = (dict_type)n; - switch (data->type) { + dd->type = (dict_type)n; + switch (dd->type) { case TINTEGER: - READ_INT(store, &data->data.i); + READ_INT(store, &dd->data.i); break; case TREAL: READ_FLT(store, &flt); if ((int)flt == flt) { - data->type = TINTEGER; - data->data.i = (int)flt; + dd->type = TINTEGER; + dd->data.i = (int)flt; } else { - data->data.real = flt; + dd->data.real = flt; } break; case TSTRING: READ_STR(store, name, sizeof(name)); - data->data.str = _strdup(name); + dd->data.str = _strdup(name); break; case TBUILDING: result = - read_reference(&data->data.b, store, read_building_reference, - resolve_building); - if (result == 0 && !data->data.b) { + read_reference(&dd->data.b, data, read_building_reference, + resolve_building); + if (result == 0 && !dd->data.b) { return AT_READ_FAIL; } break; case TUNIT: result = - read_reference(&data->data.u, store, read_unit_reference, resolve_unit); - if (result == 0 && !data->data.u) { + read_reference(&dd->data.u, data, read_unit_reference, resolve_unit); + if (result == 0 && !dd->data.u) { return AT_READ_FAIL; } break; case TFACTION: result = - read_reference(&data->data.f, store, read_faction_reference, + read_reference(&dd->data.f, data, read_faction_reference, resolve_faction); - if (result == 0 && !data->data.f) { + if (result == 0 && !dd->data.f) { return AT_READ_FAIL; } break; case TREGION: result = - read_reference(&data->data.r, store, read_region_reference, - RESOLVE_REGION(global.data_version)); - if (result == 0 && !data->data.r) { + read_reference(&dd->data.r, data, read_region_reference, + RESOLVE_REGION(data->version)); + if (result == 0 && !dd->data.r) { return AT_READ_FAIL; } break; diff --git a/src/attributes/follow.c b/src/attributes/follow.c index 1c3f7908e..d68fcaebd 100644 --- a/src/attributes/follow.c +++ b/src/attributes/follow.c @@ -23,13 +23,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include #include -static int read_follow(attrib * a, void *owner, struct storage *store) +static int read_follow(attrib * a, void *owner, gamedata *data) { - read_unit_reference(store); /* skip it */ + read_unit_reference(data); /* skip it */ return AT_READ_FAIL; } diff --git a/src/attributes/hate.c b/src/attributes/hate.c index 84768944a..3d9a2fb0a 100644 --- a/src/attributes/hate.c +++ b/src/attributes/hate.c @@ -24,6 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include #include @@ -43,10 +44,10 @@ write_hate(const attrib * a, const void *owner, struct storage *store) write_unit_reference((unit *)a->data.v, store); } -static int read_hate(attrib * a, void *owner, struct storage *store) +static int read_hate(attrib * a, void *owner, gamedata *data) { - int result = - read_reference(&a->data.v, store, read_unit_reference, resolve_unit); + int result = read_reference(&a->data.v, data, read_unit_reference, + resolve_unit); if (result == 0 && !a->data.v) { return AT_READ_FAIL; } diff --git a/src/attributes/key.c b/src/attributes/key.c index 4f51f81d5..2d43df504 100644 --- a/src/attributes/key.c +++ b/src/attributes/key.c @@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include #include @@ -35,20 +36,20 @@ static void a_writekeys(const attrib *a, const void *o, storage *store) { } } -static int a_readkeys(attrib * a, void *owner, struct storage *store) { +static int a_readkeys(attrib * a, void *owner, gamedata *data) { int i, *p = 0; - READ_INT(store, &i); + READ_INT(data->store, &i); assert(i < 4096 && i>0); a->data.v = p = malloc(sizeof(int)*(i + 1)); *p++ = i; while (i--) { - READ_INT(store, p++); + READ_INT(data->store, p++); } return AT_READ_OK; } -static int a_readkey(attrib *a, void *owner, struct storage *store) { - int res = a_readint(a, owner, store); +static int a_readkey(attrib *a, void *owner, struct gamedata *data) { + int res = a_readint(a, owner, data); return (res != AT_READ_FAIL) ? AT_READ_DEPR : res; } diff --git a/src/attributes/moved.c b/src/attributes/moved.c index b671646c1..3da2a4c3b 100644 --- a/src/attributes/moved.c +++ b/src/attributes/moved.c @@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "moved.h" #include +#include #include @@ -37,9 +38,9 @@ write_moved(const attrib * a, const void *owner, struct storage *store) WRITE_INT(store, a->data.i); } -static int read_moved(attrib * a, void *owner, struct storage *store) +static int read_moved(attrib * a, void *owner, gamedata *data) { - READ_INT(store, &a->data.i); + READ_INT(data->store, &a->data.i); if (a->data.i != 0) return AT_READ_OK; else diff --git a/src/attributes/movement.c b/src/attributes/movement.c index aa6d6504f..0ad08030e 100644 --- a/src/attributes/movement.c +++ b/src/attributes/movement.c @@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include @@ -34,9 +35,9 @@ write_movement(const attrib * a, const void *owner, struct storage *store) WRITE_INT(store, a->data.i); } -static int read_movement(attrib * a, void *owner, struct storage *store) +static int read_movement(attrib * a, void *owner, gamedata *data) { - READ_INT(store, &a->data.i); + READ_INT(data->store, &a->data.i); if (a->data.i != 0) return AT_READ_OK; else diff --git a/src/attributes/otherfaction.c b/src/attributes/otherfaction.c index fa00c3205..7e5739392 100644 --- a/src/attributes/otherfaction.c +++ b/src/attributes/otherfaction.c @@ -24,6 +24,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include @@ -38,11 +39,11 @@ void write_of(const struct attrib *a, const void *owner, struct storage *store) WRITE_INT(store, f->no); } -int read_of(struct attrib *a, void *owner, struct storage *store) +int read_of(struct attrib *a, void *owner, gamedata *data) { /* return 1 on success, 0 if attrib needs removal */ int of; - READ_INT(store, &of); + READ_INT(data->store, &of); if (rule_stealth_other()) { a->data.v = findfaction(of); if (a->data.v) { diff --git a/src/attributes/targetregion.c b/src/attributes/targetregion.c index 42f78465d..b293b458c 100644 --- a/src/attributes/targetregion.c +++ b/src/attributes/targetregion.c @@ -25,6 +25,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include #include @@ -35,11 +36,10 @@ write_targetregion(const attrib * a, const void *owner, struct storage *store) write_region_reference((region *)a->data.v, store); } -static int read_targetregion(attrib * a, void *owner, struct storage *store) +static int read_targetregion(attrib * a, void *owner, gamedata *data) { - int result = - read_reference(&a->data.v, store, read_region_reference, - RESOLVE_REGION(global.data_version)); + int result = read_reference(&a->data.v, data, read_region_reference, + RESOLVE_REGION(data->version)); if (result == 0 && !a->data.v) return AT_READ_FAIL; return AT_READ_OK; diff --git a/src/bind_storage.c b/src/bind_storage.c index ca83f199a..0255b2982 100644 --- a/src/bind_storage.c +++ b/src/bind_storage.c @@ -17,6 +17,8 @@ without prior permission by the authors of Eressea. #include #include +#include + #include #include #include @@ -26,6 +28,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include @@ -35,11 +38,12 @@ static int tolua_storage_create(lua_State * L) const char *type = tolua_tostring(L, 2, "rb"); gamedata *data; - data = gamedata_open(filename, type); + data = gamedata_open(filename, type, RELEASE_VERSION); if (data) { tolua_pushusertype(L, (void *)data, TOLUA_CAST "storage"); return 1; } + log_error("could not open %s, mode %s (%s).", filename, type, strerror(errno)); return 0; } @@ -97,8 +101,7 @@ static int tolua_storage_tostring(lua_State * L) { gamedata *data = (gamedata *)tolua_tousertype(L, 1, 0); char name[64]; - _snprintf(name, sizeof(name), "", data->encoding, - data->version); + _snprintf(name, sizeof(name), "", (void *)data, data->version); lua_pushstring(L, name); return 1; } diff --git a/src/building_action.c b/src/building_action.c index 29c20a99d..b6ce0f72c 100644 --- a/src/building_action.c +++ b/src/building_action.c @@ -15,6 +15,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include @@ -98,14 +99,15 @@ lc_write(const struct attrib *a, const void *owner, struct storage *store) WRITE_TOK(store, fparam ? fparam : NULLSTRING); } -static int lc_read(struct attrib *a, void *owner, struct storage *store) +static int lc_read(struct attrib *a, void *owner, gamedata *data) { + struct storage *store = data->store; char name[NAMESIZE]; - building_action *data = (building_action *)a->data.v; + building_action *bd = (building_action *)a->data.v; building *b = (building *)owner; int result = 0; - if (global.data_version < ATTRIBOWNER_VERSION) { - result = read_reference(&b, store, read_building_reference, resolve_building); + if (data->version < ATTRIBOWNER_VERSION) { + result = read_reference(&b, data, read_building_reference, resolve_building); assert(b == owner); } READ_TOK(store, name, sizeof(name)); @@ -115,7 +117,7 @@ static int lc_read(struct attrib *a, void *owner, struct storage *store) b = 0; } else { - data->fname = _strdup(name); + bd->fname = _strdup(name); } READ_TOK(store, name, sizeof(name)); if (strcmp(name, "tnnL") == 0) { @@ -124,9 +126,9 @@ static int lc_read(struct attrib *a, void *owner, struct storage *store) b = 0; } if (strcmp(name, NULLSTRING) == 0) - data->param = 0; + bd->param = 0; else { - data->param = _strdup(name); + bd->param = _strdup(name); } if (result == 0 && !b) { return AT_READ_FAIL; diff --git a/src/kernel/building.c b/src/kernel/building.c index 609b000c8..f0e46cc7e 100644 --- a/src/kernel/building.c +++ b/src/kernel/building.c @@ -386,10 +386,10 @@ int resolve_building(variant id, void *address) return result; } -variant read_building_reference(struct storage * store) +variant read_building_reference(gamedata * data) { variant result; - READ_INT(store, &result.i); + READ_INT(data->store, &result.i); return result; } diff --git a/src/kernel/building.h b/src/kernel/building.h index 4d08ae647..766242c4a 100644 --- a/src/kernel/building.h +++ b/src/kernel/building.h @@ -26,6 +26,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. extern "C" { #endif + struct gamedata; + /* maintenance::flags */ #define MTF_NONE 0x00 #define MTF_VARIABLE 0x01 /* resource usage scales with size */ @@ -158,7 +160,7 @@ extern "C" { extern int resolve_building(variant data, void *address); extern void write_building_reference(const struct building *b, struct storage *store); - extern variant read_building_reference(struct storage *store); + extern variant read_building_reference(struct gamedata *data); extern struct building *findbuilding(int n); diff --git a/src/kernel/connection.c b/src/kernel/connection.c index 257a78af3..41c67299a 100644 --- a/src/kernel/connection.c +++ b/src/kernel/connection.c @@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include #include #include @@ -217,8 +218,9 @@ border_type *find_bordertype(const char *name) return bt; } -void b_read(connection * b, storage * store) +void b_read(connection * b, gamedata * data) { + storage * store = data->store; int n, result = 0; switch (b->type->datatype) { case VAR_NONE: @@ -529,8 +531,9 @@ static const char *b_nameroad(const connection * b, const region * r, return buffer; } -static void b_readroad(connection * b, storage * store) +static void b_readroad(connection * b, gamedata * data) { + storage * store = data->store; int n; READ_INT(store, &n); b->data.sa[0] = (short)n; @@ -601,8 +604,9 @@ void write_borders(struct storage *store) WRITE_TOK(store, "end"); } -int read_borders(struct storage *store) +int read_borders(gamedata *data) { + struct storage *store = data->store; for (;;) { int bid = 0; char zText[32]; @@ -613,7 +617,7 @@ int read_borders(struct storage *store) if (!strcmp(zText, "end")) break; READ_INT(store, &bid); - if (global.data_version < UIDHASH_VERSION) { + if (data->version < UIDHASH_VERSION) { int fx, fy, tx, ty; READ_INT(store, &fx); READ_INT(store, &fy); @@ -655,11 +659,12 @@ int read_borders(struct storage *store) nextborder--; /* new_border erhöht den Wert */ b->id = bid; assert(bid <= nextborder); - if (type->read) - type->read(b, store); - if (global.data_version < NOBORDERATTRIBS_VERSION) { + if (type->read) { + type->read(b, data); + } + if (data->version < NOBORDERATTRIBS_VERSION) { attrib *a = NULL; - int result = read_attribs(store, &a, b); + int result = read_attribs(data, &a, b); if (border_convert_cb) { border_convert_cb(b, a); } diff --git a/src/kernel/connection.h b/src/kernel/connection.h index ed4e2a50e..2c0800849 100644 --- a/src/kernel/connection.h +++ b/src/kernel/connection.h @@ -30,6 +30,7 @@ extern "C" { struct faction; struct region; struct storage; + struct gamedata; struct unit; extern int nextborder; @@ -52,7 +53,7 @@ extern "C" { /* constructor: initialize the connection. allocate extra memory if needed */ void(*destroy) (connection *); /* destructor: remove all extra memory for destruction */ - void(*read) (connection *, struct storage *); + void(*read) (connection *, struct gamedata *); void(*write) (const connection *, struct storage *); bool(*block) (const connection *, const struct unit *, const struct region * r); @@ -113,12 +114,12 @@ extern "C" { void register_bordertype(border_type * type); /* register a new bordertype */ - int read_borders(struct storage *store); + int read_borders(struct gamedata *store); void write_borders(struct storage *store); void age_borders(void); /* provide default implementations for some member functions: */ - void b_read(connection * b, struct storage *store); + void b_read(connection * b, struct gamedata *store); void b_write(const connection * b, struct storage *store); bool b_blockall(const connection *, const struct unit *, const struct region *); diff --git a/src/kernel/curse.c b/src/kernel/curse.c index 8b7a4b51a..66890475e 100644 --- a/src/kernel/curse.c +++ b/src/kernel/curse.c @@ -35,6 +35,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include #include @@ -184,8 +185,9 @@ static int read_ccompat(const char *cursename, struct storage *store) return -1; } -int curse_read(attrib * a, void *owner, struct storage *store) +int curse_read(attrib * a, void *owner, gamedata *data) { + storage *store = data->store; curse *c = (curse *)a->data.v; int ur; char cursename[64]; @@ -200,13 +202,13 @@ int curse_read(attrib * a, void *owner, struct storage *store) READ_INT(store, &c->duration); READ_FLT(store, &flt); c->vigour = flt; - if (global.data_version < INTPAK_VERSION) { - ur = read_reference(&c->magician, store, read_int, resolve_unit); + if (data->version < INTPAK_VERSION) { + ur = resolve_unit(read_int(data->store), &c->magician); } else { - ur = read_reference(&c->magician, store, read_unit_reference, resolve_unit); + ur = read_reference(&c->magician, data, read_unit_reference, resolve_unit); } - if (global.data_version < CURSEFLOAT_VERSION) { + if (data->version < CURSEFLOAT_VERSION) { READ_INT(store, &n); c->effect = (float)n; } @@ -224,19 +226,20 @@ int curse_read(attrib * a, void *owner, struct storage *store) return AT_READ_FAIL; } c->flags = flags; - if (global.data_version < EXPLICIT_CURSE_ISNEW_VERSION) { + if (data->version < EXPLICIT_CURSE_ISNEW_VERSION) { c_clearflag(c, CURSE_ISNEW); } - if (c->type->read) - c->type->read(store, c, owner); + if (c->type->read) { + c->type->read(data, c, owner); + } else if (c->type->typ == CURSETYP_UNIT) { READ_INT(store, &c->data.i); } if (c->type->typ == CURSETYP_REGION) { int rr = - read_reference(&c->data.v, store, read_region_reference, - RESOLVE_REGION(global.data_version)); + read_reference(&c->data.v, data, read_region_reference, + RESOLVE_REGION(data->version)); if (ur == 0 && rr == 0 && !c->data.v) { return AT_READ_FAIL; } @@ -253,12 +256,11 @@ void curse_write(const attrib * a, const void *owner, struct storage *store) unit *mage = (c->magician && c->magician->number) ? c->magician : NULL; /* copied from c_clearflag */ - if (global.data_version < EXPLICIT_CURSE_ISNEW_VERSION) { - flags = (c->flags & ~CURSE_ISNEW) | (c->type->flags & CURSE_ISNEW); - } - else { - flags = c->flags | c->type->flags; - } +#if RELEASE_VERSION < EXPLICIT_CURSE_ISNEW_VERSION + flags = (c->flags & ~CURSE_ISNEW) | (c->type->flags & CURSE_ISNEW); +#else + flags = c->flags | c->type->flags; +#endif WRITE_INT(store, c->no); WRITE_TOK(store, ct->cname); diff --git a/src/kernel/curse.h b/src/kernel/curse.h index 263b66125..77da43451 100644 --- a/src/kernel/curse.h +++ b/src/kernel/curse.h @@ -28,6 +28,8 @@ extern "C" { struct curse; struct curse_type; + struct gamedata; + struct storage; /* Sprueche in der struct region und auf Einheiten, Schiffen oder Burgen * (struct attribute) @@ -93,7 +95,7 @@ extern "C" { * * */ -#include + extern struct attrib_type at_curse; /* ------------------------------------------------------------- */ /* Zauberwirkungen */ @@ -194,8 +196,8 @@ extern "C" { struct message *(*curseinfo) (const void *, objtype_t, const struct curse *, int); void(*change_vigour) (struct curse *, double); - int(*read) (struct storage * store, struct curse *, void *target); - int(*write) (struct storage * store, const struct curse *, + int(*read) (struct gamedata *data, struct curse *, void *target); + int(*write) (struct storage *store, const struct curse *, const void *target); int(*cansee) (const struct faction *, const void *, objtype_t, const struct curse *, int); @@ -216,10 +218,9 @@ extern "C" { void free_curses(void); /* de-register all curse-types */ - extern struct attrib_type at_curse; void curse_write(const struct attrib *a, const void *owner, - struct storage *store); - int curse_read(struct attrib *a, void *owner, struct storage *store); + struct storage *store); + int curse_read(struct attrib *a, void *owner, struct gamedata *store); /* ------------------------------------------------------------- */ /* Kommentare: diff --git a/src/kernel/curse.test.c b/src/kernel/curse.test.c index 002ef18ec..b8d765f72 100644 --- a/src/kernel/curse.test.c +++ b/src/kernel/curse.test.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -122,29 +123,21 @@ static void test_memstream(CuTest *tc) { static void test_write_flag(CuTest *tc) { curse_fixture fix; + gamedata data; storage store; - char buf[1024]; - stream out = { 0 }; - size_t len; - mstream_init(&out); - binstore_init(&store, &out); - store.handle.data = &out; + mstream_init(&data.strm); + gamedata_init(&data, &store, RELEASE_VERSION); setup_curse(&fix, "gbdream"); fix.c->flags = 42 | CURSE_ISNEW; curse_write(fix.r->attribs, fix.r, &store); - out.api->rewind(out.handle); - len = out.api->read(out.handle, buf, sizeof(buf)); - buf[len] = '\0'; - out.api->rewind(out.handle); - curse_read(fix.r->attribs, fix.r, &store); + data.strm.api->rewind(data.strm.handle); + curse_read(fix.r->attribs, fix.r, &data); CuAssertIntEquals(tc, 42 | CURSE_ISNEW, ((curse *) fix.r->attribs->data.v)->flags); - global.data_version = RELEASE_VERSION; - CuAssertIntEquals(tc, RELEASE_VERSION, global.data_version); - mstream_done(&out); - binstore_done(&store); + mstream_done(&data.strm); + gamedata_done(&data); test_cleanup(); } diff --git a/src/kernel/faction.c b/src/kernel/faction.c index f8d240503..a330e6878 100755 --- a/src/kernel/faction.c +++ b/src/kernel/faction.c @@ -325,10 +325,10 @@ bool checkpasswd(const faction * f, const char *passwd) return true; } -variant read_faction_reference(struct storage * store) +variant read_faction_reference(gamedata * data) { variant id; - READ_INT(store, &id.i); + READ_INT(data->store, &id.i); return id; } diff --git a/src/kernel/faction.h b/src/kernel/faction.h index 6369444f5..c7578cc47 100644 --- a/src/kernel/faction.h +++ b/src/kernel/faction.h @@ -30,7 +30,8 @@ extern "C" { struct item; struct seen_region; struct attrib_type; - + struct gamedata; + extern struct attrib_type at_maxmagicians; /* SMART_INTERVALS: define to speed up finding the interval of regions that a faction is in. defining this speeds up the turn by 30-40% */ @@ -133,7 +134,7 @@ extern "C" { void write_faction_reference(const struct faction *f, struct storage *store); - variant read_faction_reference(struct storage *store); + variant read_faction_reference(struct gamedata *store); int resolve_faction(variant data, void *addr); void renumber_faction(faction * f, int no); diff --git a/src/kernel/group.c b/src/kernel/group.c index 564b3df5e..9a4de33de 100755 --- a/src/kernel/group.c +++ b/src/kernel/group.c @@ -33,6 +33,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include @@ -95,8 +96,9 @@ static group *find_group(int gid) return g; } -static int read_group(attrib * a, void *owner, struct storage *store) +static int read_group(attrib * a, void *owner, gamedata *data) { + struct storage *store = data->store; group *g; int gid; @@ -215,8 +217,9 @@ void write_groups(struct storage *store, const faction * f) WRITE_INT(store, 0); } -void read_groups(struct storage *store, faction * f) +void read_groups(gamedata *data, faction * f) { + struct storage *store = data->store; for (;;) { ally **pa; group *g; @@ -233,7 +236,7 @@ void read_groups(struct storage *store, faction * f) ally *a; variant fid; - fid = read_faction_reference(store); + fid = read_faction_reference(data); if (fid.i <= 0) break; a = ally_add(pa, findfaction(fid.i)); @@ -241,6 +244,6 @@ void read_groups(struct storage *store, faction * f) if (!a->faction) ur_add(fid, &a->faction, resolve_faction); } - read_attribs(store, &g->attribs, g); + read_attribs(data, &g->attribs, g); } } diff --git a/src/kernel/group.h b/src/kernel/group.h index 145881c00..b257f515a 100755 --- a/src/kernel/group.h +++ b/src/kernel/group.h @@ -43,7 +43,7 @@ extern "C" { struct group *new_group(struct faction * f, const char *name, int gid); extern void write_groups(struct storage *data, const struct faction *f); - extern void read_groups(struct storage *data, struct faction *f); + extern void read_groups(struct gamedata *data, struct faction *f); #ifdef __cplusplus } diff --git a/src/kernel/group.test.c b/src/kernel/group.test.c index ae4ae96d0..c30e16f98 100644 --- a/src/kernel/group.test.c +++ b/src/kernel/group.test.c @@ -5,8 +5,13 @@ #include "faction.h" #include "unit.h" #include "region.h" +#include "save.h" +#include "version.h" + +#include #include #include + #include #include #include @@ -21,35 +26,29 @@ static void test_group_readwrite(CuTest * tc) faction * f; group *g; ally *al; - storage store; - FILE *F; - stream strm; int i; + gamedata *data; - F = fopen("test.dat", "wb"); - fstream_init(&strm, F); - binstore_init(&store, &strm); test_cleanup(); - test_create_world(); + data = gamedata_open("test.dat", "wb", RELEASE_VERSION); + CuAssertPtrNotNull(tc, data); f = test_create_faction(0); g = new_group(f, "NW", 42); g = new_group(f, "Egoisten", 43); key_set(&g->attribs, 44); al = ally_add(&g->allies, f); al->status = HELP_GIVE; - write_groups(&store, f); - WRITE_INT(&store, 47); - binstore_done(&store); - fstream_done(&strm); + write_groups(data->store, f); + WRITE_INT(data->store, 47); + binstore_done(data->store); + gamedata_close(data); - F = fopen("test.dat", "rb"); - fstream_init(&strm, F); - binstore_init(&store, &strm); f->groups = 0; - read_groups(&store, f); - READ_INT(&store, &i); - binstore_done(&store); - fstream_done(&strm); + free_group(g); + data = gamedata_open("test.dat", "rb", RELEASE_VERSION); + read_groups(data, f); + READ_INT(data->store, &i); + gamedata_close(data); CuAssertIntEquals(tc, 47, i); CuAssertPtrNotNull(tc, f->groups); diff --git a/src/kernel/region.c b/src/kernel/region.c index 04e0c46b3..c3d0559bf 100644 --- a/src/kernel/region.c +++ b/src/kernel/region.c @@ -42,6 +42,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include #include @@ -176,12 +177,12 @@ void a_initmoveblock(attrib * a) a->data.v = calloc(1, sizeof(moveblock)); } -int a_readmoveblock(attrib * a, void *owner, struct storage *store) +int a_readmoveblock(attrib * a, void *owner, gamedata *data) { moveblock *m = (moveblock *)(a->data.v); int i; - READ_INT(store, &i); + READ_INT(data->store, &i); m->dir = (direction_t)i; return AT_READ_OK; } @@ -1225,10 +1226,11 @@ int resolve_region_id(variant id, void *address) return 0; } -variant read_region_reference(struct storage * store) +variant read_region_reference(gamedata *data) { + struct storage * store = data->store; variant result; - if (global.data_version < UIDHASH_VERSION) { + if (data->version < UIDHASH_VERSION) { int n; READ_INT(store, &n); result.sa[0] = (short)n; diff --git a/src/kernel/region.h b/src/kernel/region.h index 72496193b..411fa5580 100644 --- a/src/kernel/region.h +++ b/src/kernel/region.h @@ -18,9 +18,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #ifndef H_KRNL_REGION #define H_KRNL_REGION -#ifdef __cplusplus -extern "C" { -#endif #include #include "types.h" @@ -67,6 +64,7 @@ extern "C" { struct rawmaterial; struct item; struct faction; + struct gamedata; #define MORALE_TAX_FACTOR 0.005 /* 0.5% tax per point of morale */ #define MORALE_MAX 10 /* Maximum morale allowed */ @@ -76,6 +74,11 @@ extern "C" { #define MORALE_AVERAGE 6 /* default average time for morale to change */ #define MORALE_TRANSFER 2 /* points of morale lost when GIVE COMMAND */ +#ifdef __cplusplus +extern "C" { +#endif + + typedef struct region_owner { struct faction *owner; struct faction *last_owner; @@ -255,7 +258,7 @@ extern "C" { void region_set_morale(region * r, int morale, int turn); void write_region_reference(const struct region *r, struct storage *store); - variant read_region_reference(struct storage *store); + variant read_region_reference(struct gamedata *data); int resolve_region_coor(variant id, void *address); int resolve_region_id(variant id, void *address); #define RESOLVE_REGION(version) ((version #include #include +#include #include +#include #include #include #include @@ -417,11 +419,12 @@ void read_items(struct storage *store, item ** ilist) } } -static void read_alliances(struct storage *store) +static void read_alliances(struct gamedata *data) { + storage *store = data->store; char pbuf[8]; int id, terminator = 0; - if (global.data_version < ALLIANCELEADER_VERSION) { + if (data->version < ALLIANCELEADER_VERSION) { terminator = atoi36("end"); READ_STR(store, pbuf, sizeof(pbuf)); id = atoi36(pbuf); @@ -434,11 +437,11 @@ static void read_alliances(struct storage *store) alliance *al; READ_STR(store, aname, sizeof(aname)); al = makealliance(id, aname); - if (global.data_version >= OWNER_2_VERSION) { + if (data->version >= OWNER_2_VERSION) { READ_INT(store, &al->flags); } - if (global.data_version >= ALLIANCELEADER_VERSION) { - read_reference(&al->_leader, store, read_faction_reference, + if (data->version >= ALLIANCELEADER_VERSION) { + read_reference(&al->_leader, data, read_faction_reference, resolve_faction); READ_INT(store, &id); } @@ -525,7 +528,7 @@ static void read_owner(struct gamedata *data, region_owner ** powner) else { owner->last_owner = NULL; } - read_reference(owner, data->store, &read_faction_reference, &resolve_owner); + read_reference(owner, data, &read_faction_reference, &resolve_owner); *powner = owner; } else { @@ -581,12 +584,12 @@ writeorder(struct gamedata *data, const struct order *ord, WRITE_STR(data->store, obuf); } -int read_attribs(storage *store, attrib **alist, void *owner) { - if (global.data_version < ATHASH_VERSION) { - return a_read_orig(store, alist, owner); +int read_attribs(gamedata *data, attrib **alist, void *owner) { + if (data->version < ATHASH_VERSION) { + return a_read_orig(data, alist, owner); } else { - return a_read(store, alist, owner); + return a_read(data, alist, owner); } } @@ -770,7 +773,7 @@ unit *read_unit(struct gamedata *data) log_error("Einheit %s hat %u Personen, und %u Trefferpunkte\n", itoa36(u->no), u->number, u->hp); u->hp = u->number; } - read_attribs(data->store, &u->attribs, u); + read_attribs(data, &u->attribs, u); return u; } @@ -1004,7 +1007,7 @@ static region *readregion(struct gamedata *data, int x, int y) read_owner(data, &r->land->ownership); } } - read_attribs(data->store, &r->attribs, r); + read_attribs(data, &r->attribs, r); return r; } @@ -1126,14 +1129,14 @@ int get_spell_level_faction(const spell * sp, void * cbdata) return 0; } -void read_spellbook(spellbook **bookp, struct storage *store, int(*get_level)(const spell * sp, void *), void * cbdata) +void read_spellbook(spellbook **bookp, gamedata *data, int(*get_level)(const spell * sp, void *), void * cbdata) { for (;;) { spell *sp = 0; char spname[64]; int level = 0; - READ_TOK(store, spname, sizeof(spname)); + READ_TOK(data->store, spname, sizeof(spname)); if (strcmp(spname, "end") == 0) break; if (bookp) { @@ -1142,8 +1145,8 @@ void read_spellbook(spellbook **bookp, struct storage *store, int(*get_level)(co log_error("read_spells: could not find spell '%s'\n", spname); } } - if (global.data_version >= SPELLBOOK_VERSION) { - READ_INT(store, &level); + if (data->version >= SPELLBOOK_VERSION) { + READ_INT(data->store, &level); } if (sp) { spellbook * sb = *bookp; @@ -1154,7 +1157,7 @@ void read_spellbook(spellbook **bookp, struct storage *store, int(*get_level)(co *bookp = create_spellbook(0); sb = *bookp; } - if (level > 0 && (global.data_version >= SPELLBOOK_VERSION || !spellbook_get(sb, sp))) { + if (level > 0 && (data->version >= SPELLBOOK_VERSION || !spellbook_get(sb, sp))) { spellbook_add(sb, sp, level); } } @@ -1326,7 +1329,7 @@ faction *readfaction(struct gamedata * data) } } - read_attribs(data->store, &f->attribs, f); + read_attribs(data, &f->attribs, f); read_items(data->store, &f->items); for (;;) { READ_TOK(data->store, name, sizeof(name)); @@ -1369,10 +1372,10 @@ faction *readfaction(struct gamedata * data) break; } } - read_groups(data->store, f); + read_groups(data, f); f->spellbook = 0; if (data->version >= REGIONOWNER_VERSION) { - read_spellbook(FactionSpells() ? &f->spellbook : 0, data->store, get_spell_level_faction, (void *)f); + read_spellbook(FactionSpells() ? &f->spellbook : 0, data, get_spell_level_faction, (void *)f); } return f; } @@ -1496,11 +1499,9 @@ int readgame(const char *filename, bool backup) assert(gdata.version >= MIN_VERSION || !"unsupported data format"); assert(gdata.version <= MAX_VERSION || !"unsupported data format"); - gdata.encoding = enc_gamedata; fstream_init(&strm, F); binstore_init(&store, &strm); gdata.store = &store; - global.data_version = gdata.version; /* HACK: attribute::read does not have access to gamedata, only storage */ if (gdata.version >= BUILDNO_VERSION) { int build; @@ -1525,7 +1526,7 @@ int readgame(const char *filename, bool backup) else { READ_STR(&store, NULL, 0); } - read_attribs(&store, &global.attribs, NULL); + read_attribs(&gdata, &global.attribs, NULL); READ_INT(&store, &turn); global.data_turn = turn; log_debug(" - reading turn %d\n", turn); @@ -1577,20 +1578,20 @@ int readgame(const char *filename, bool backup) else { /* WATCHERS - eliminated in February 2016, ca. turn 966 */ if (gdata.version < NOWATCH_VERSION) { - fno = read_faction_reference(&store); + fno = read_faction_reference(&gdata); while (fno.i) { - fno = read_faction_reference(&store); + fno = read_faction_reference(&gdata); } } } - read_attribs(&store, &pl->attribs, pl); + read_attribs(&gdata, &pl->attribs, pl); if (pl->id != 1094969858) { // Regatta addlist(&planes, pl); } } /* Read factions */ - read_alliances(&store); + read_alliances(&gdata); READ_INT(&store, &nread); log_debug(" - Einzulesende Parteien: %d\n", nread); fp = &factions; @@ -1651,7 +1652,7 @@ int readgame(const char *filename, bool backup) READ_STR(&store, name, sizeof(name)); b->type = bt_find(name); b->region = r; - read_attribs(&store, &b->attribs, b); + read_attribs(&gdata, &b->attribs, b); if (b->type == bt_lighthouse) { r->flags |= RF_LIGHTHOUSE; } @@ -1698,7 +1699,7 @@ int readgame(const char *filename, bool backup) if (sh->type->flags & SFL_NOCOAST) { sh->coast = NODIRECTION; } - read_attribs(&store, &sh->attribs, sh); + read_attribs(&gdata, &sh->attribs, sh); } *shp = 0; @@ -1726,7 +1727,7 @@ int readgame(const char *filename, bool backup) update_interval(u->faction, u->region); } } - read_borders(&store); + read_borders(&gdata); binstore_done(&store); fstream_done(&strm); @@ -1757,7 +1758,7 @@ int readgame(const char *filename, bool backup) } else { for (u = f->units; u; u = u->nextF) { - if (global.data_version < SPELL_LEVEL_VERSION) { + if (gdata.version < SPELL_LEVEL_VERSION) { sc_mage *mage = get_mage(u); if (mage) { faction *f = u->faction; @@ -1776,12 +1777,12 @@ int readgame(const char *filename, bool backup) } if (u->number > 0) { f->_alive = true; - if (global.data_version >= SPELL_LEVEL_VERSION) { + if (gdata.version >= SPELL_LEVEL_VERSION) { break; } } } - if (global.data_version < SPELL_LEVEL_VERSION && f->spellbook) { + if (gdata.version < SPELL_LEVEL_VERSION && f->spellbook) { spellbook_foreach(f->spellbook, cb_sb_maxlevel, f); } } @@ -1832,9 +1833,7 @@ int writegame(const char *filename) } gdata.store = &store; - gdata.encoding = enc_gamedata; gdata.version = RELEASE_VERSION; - global.data_version = RELEASE_VERSION; n = STREAM_VERSION; fwrite(&gdata.version, sizeof(int), 1, F); fwrite(&n, sizeof(int), 1, F); @@ -1954,55 +1953,10 @@ int writegame(const char *filename) return 0; } -void gamedata_close(gamedata *data) { - binstore_done(data->store); - fstream_done(&data->strm); -} - -gamedata *gamedata_open(const char *filename, const char *mode) { - FILE *F = fopen(filename, mode); - - if (F) { - gamedata *data = (gamedata *)calloc(1, sizeof(gamedata)); - storage *store = (storage *)calloc(1, sizeof(storage)); - int err = 0; - size_t sz; - - data->store = store; - if (strchr(mode, 'r')) { - sz = fread(&data->version, 1, sizeof(int), F); - if (sz != sizeof(int)) { - err = ferror(F); - } - else { - err = fseek(F, sizeof(int), SEEK_CUR); - } - } - else if (strchr(mode, 'w')) { - int n = STREAM_VERSION; - data->version = RELEASE_VERSION; - fwrite(&data->version, sizeof(int), 1, F); - fwrite(&n, sizeof(int), 1, F); - } - if (err) { - fclose(F); - free(data); - free(store); - } - else { - fstream_init(&data->strm, F); - binstore_init(store, &data->strm); - return data; - } - } - log_error("could not open %s: %s", filename, strerror(errno)); - return 0; -} - -int a_readint(attrib * a, void *owner, struct storage *store) +int a_readint(attrib * a, void *owner, struct gamedata *data) { /* assert(sizeof(int)==sizeof(a->data)); */ - READ_INT(store, &a->data.i); + READ_INT(data->store, &a->data.i); return AT_READ_OK; } @@ -2011,12 +1965,12 @@ void a_writeint(const attrib * a, const void *owner, struct storage *store) WRITE_INT(store, a->data.i); } -int a_readshorts(attrib * a, void *owner, struct storage *store) +int a_readshorts(attrib * a, void *owner, struct gamedata *data) { int n; - READ_INT(store, &n); + READ_INT(data->store, &n); a->data.sa[0] = (short)n; - READ_INT(store, &n); + READ_INT(data->store, &n); a->data.sa[1] = (short)n; return AT_READ_OK; } @@ -2027,12 +1981,12 @@ void a_writeshorts(const attrib * a, const void *owner, struct storage *store) WRITE_INT(store, a->data.sa[1]); } -int a_readchars(attrib * a, void *owner, struct storage *store) +int a_readchars(attrib * a, void *owner, struct gamedata *data) { int i; for (i = 0; i != 4; ++i) { int n; - READ_INT(store, &n); + READ_INT(data->store, &n); a->data.ca[i] = (char)n; } return AT_READ_OK; @@ -2047,7 +2001,7 @@ void a_writechars(const attrib * a, const void *owner, struct storage *store) } } -int a_readvoid(attrib * a, void *owner, struct storage *store) +int a_readvoid(attrib * a, void *owner, struct gamedata *data) { return AT_READ_OK; } @@ -2056,14 +2010,14 @@ void a_writevoid(const attrib * a, const void *owner, struct storage *store) { } -int a_readstring(attrib * a, void *owner, struct storage *store) +int a_readstring(attrib * a, void *owner, struct gamedata *data) { char buf[DISPLAYSIZE]; char * result = 0; int e; size_t len = 0; do { - e = READ_STR(store, buf, sizeof(buf)); + e = READ_STR(data->store, buf, sizeof(buf)); if (result) { result = realloc(result, len + DISPLAYSIZE - 1); strcpy(result + len, buf); diff --git a/src/kernel/save.h b/src/kernel/save.h index 01773f5f7..a606b8ad4 100644 --- a/src/kernel/save.h +++ b/src/kernel/save.h @@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #define H_KRNL_SAVE #include +#include // FIXME: eliminate include dependency from this file #ifdef __cplusplus extern "C" { #endif @@ -30,13 +31,7 @@ extern "C" { struct spell; struct spellbook; struct unit; - - typedef struct gamedata { - struct storage *store; - stream strm; - int version; - int encoding; - } gamedata; + struct gamedata; #define MAX_INPUT_SIZE DISPLAYSIZE*2 /* Nach MAX_INPUT_SIZE brechen wir das Einlesen der Zeile ab und nehmen an, @@ -55,37 +50,34 @@ extern "C" { void read_items(struct storage *store, struct item **it); void write_items(struct storage *store, struct item *it); - void read_spellbook(struct spellbook **bookp, struct storage *store, int(*get_level)(const struct spell * sp, void *), void * cbdata); + void read_spellbook(struct spellbook **bookp, struct gamedata *data, int(*get_level)(const struct spell * sp, void *), void * cbdata); void write_spellbook(const struct spellbook *book, struct storage *store); void write_attribs(struct storage *store, struct attrib *alist, const void *owner); - int read_attribs(struct storage *store, struct attrib **alist, void *owner); + int read_attribs(struct gamedata *store, struct attrib **alist, void *owner); void write_unit(struct gamedata *data, const struct unit *u); struct unit *read_unit(struct gamedata *data); - int a_readint(struct attrib *a, void *owner, struct storage *store); + int a_readint(struct attrib *a, void *owner, struct gamedata *); void a_writeint(const struct attrib *a, const void *owner, struct storage *store); - int a_readshorts(struct attrib *a, void *owner, struct storage *store); + int a_readshorts(struct attrib *a, void *owner, struct gamedata *); void a_writeshorts(const struct attrib *a, const void *owner, struct storage *store); - int a_readchars(struct attrib *a, void *owner, struct storage *store); + int a_readchars(struct attrib *a, void *owner, struct gamedata *); void a_writechars(const struct attrib *a, const void *owner, struct storage *store); - int a_readvoid(struct attrib *a, void *owner, struct storage *store); + int a_readvoid(struct attrib *a, void *owner, struct gamedata *); void a_writevoid(const struct attrib *a, const void *owner, - struct storage *store); - int a_readstring(struct attrib *a, void *owner, struct storage *store); + struct storage *); + int a_readstring(struct attrib *a, void *owner, struct gamedata *); void a_writestring(const struct attrib *a, const void *owner, - struct storage *store); + struct storage *); void a_finalizestring(struct attrib *a); void create_backup(char *file); - struct gamedata *gamedata_open(const char *filename, const char *mode); - void gamedata_close(struct gamedata *data); - /* test-only functions that give access to internal implementation details (BAD) */ void _test_write_password(struct gamedata *data, const struct faction *f); void _test_read_password(struct gamedata *data, struct faction *f); diff --git a/src/kernel/save.test.c b/src/kernel/save.test.c index b7af173ef..4d8176756 100644 --- a/src/kernel/save.test.c +++ b/src/kernel/save.test.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "save.h" @@ -11,6 +12,7 @@ #include "plane.h" #include "region.h" #include "version.h" + #include #include #include @@ -19,6 +21,8 @@ #include #include +#include +#include #include #include @@ -33,7 +37,6 @@ static void test_readwrite_data(CuTest * tc) test_cleanup(); CuAssertIntEquals(tc, 0, writegame(filename)); CuAssertIntEquals(tc, 0, readgame(filename, false)); - CuAssertIntEquals(tc, RELEASE_VERSION, global.data_version); join_path(datapath(), filename, path, sizeof(path)); CuAssertIntEquals(tc, 0, remove(path)); test_cleanup(); @@ -41,69 +44,60 @@ static void test_readwrite_data(CuTest * tc) static void test_readwrite_unit(CuTest * tc) { - const char *filename = "test.dat"; - char path[MAX_PATH]; - gamedata *data; + gamedata data; + storage store; struct unit *u; struct region *r; struct faction *f; int fno; - /* FIXME: at some point during this test, errno is set to 17 (File exists), why? */ - create_directories(); test_cleanup(); r = test_create_region(0, 0, 0); f = test_create_faction(0); fno = f->no; u = test_create_unit(f, r); - join_path(datapath(), filename, path, sizeof(path)); - - data = gamedata_open(path, "wb"); - CuAssertPtrNotNull(tc, data); // TODO: intermittent test (even after the 'b' fix!) - - write_unit(data, u); - gamedata_close(data); + mstream_init(&data.strm); + gamedata_init(&data, &store, RELEASE_VERSION); + write_unit(&data, u); + + data.strm.api->rewind(data.strm.handle); free_gamedata(); f = test_create_faction(0); renumber_faction(f, fno); - data = gamedata_open(path, "rb"); - CuAssertPtrNotNull(tc, data); - - u = read_unit(data); - gamedata_close(data); + gamedata_init(&data, &store, RELEASE_VERSION); + u = read_unit(&data); + mstream_done(&data.strm); + gamedata_done(&data); CuAssertPtrNotNull(tc, u); CuAssertPtrEquals(tc, f, u->faction); CuAssertPtrEquals(tc, 0, u->region); - CuAssertIntEquals(tc, 0, remove(path)); test_cleanup(); } static void test_readwrite_attrib(CuTest *tc) { - gamedata *data; + gamedata data; + storage store; attrib *a = NULL; - const char *path = "attrib.dat"; + test_cleanup(); - global.data_version = RELEASE_VERSION; // FIXME: hack! - data = gamedata_open(path, "wb"); - CuAssertPtrNotNull(tc, data); key_set(&a, 41); key_set(&a, 42); - write_attribs(data->store, a, NULL); - gamedata_close(data); + mstream_init(&data.strm); + gamedata_init(&data, &store, RELEASE_VERSION); + write_attribs(data.store, a, NULL); a_removeall(&a, NULL); CuAssertPtrEquals(tc, 0, a); - data = gamedata_open(path, "rb"); - CuAssertPtrNotNull(tc, data); - read_attribs(data->store, &a, NULL); - gamedata_close(data); + data.strm.api->rewind(data.strm.handle); + read_attribs(&data, &a, NULL); + mstream_done(&data.strm); + gamedata_done(&data); CuAssertTrue(tc, key_get(a, 41)); CuAssertTrue(tc, key_get(a, 42)); a_removeall(&a, NULL); - CuAssertIntEquals(tc, 0, remove(path)); test_cleanup(); } @@ -237,11 +231,11 @@ static void test_read_password(CuTest *tc) { faction *f; f = test_create_faction(0); faction_setpassword(f, password_encode("secret", PASSWORD_DEFAULT)); - data = gamedata_open(path, "wb"); + data = gamedata_open(path, "wb", RELEASE_VERSION); CuAssertPtrNotNull(tc, data); _test_write_password(data, f); gamedata_close(data); - data = gamedata_open(path, "rb"); + data = gamedata_open(path, "rb", RELEASE_VERSION); CuAssertPtrNotNull(tc, data); _test_read_password(data, f); gamedata_close(data); @@ -259,12 +253,12 @@ static void test_read_password_external(CuTest *tc) { f = test_create_faction(0); faction_setpassword(f, password_encode("secret", PASSWORD_DEFAULT)); CuAssertPtrNotNull(tc, f->_password); - data = gamedata_open(path, "wb"); + data = gamedata_open(path, "wb", RELEASE_VERSION); CuAssertPtrNotNull(tc, data); WRITE_TOK(data->store, (const char *)f->_password); WRITE_TOK(data->store, (const char *)f->_password); gamedata_close(data); - data = gamedata_open(path, "rb"); + data = gamedata_open(path, "rb", RELEASE_VERSION); CuAssertPtrNotNull(tc, data); data->version = BADCRYPT_VERSION; _test_read_password(data, f); diff --git a/src/kernel/unit.c b/src/kernel/unit.c index 04d113033..5fc797e25 100644 --- a/src/kernel/unit.c +++ b/src/kernel/unit.c @@ -52,6 +52,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -116,9 +117,9 @@ unit *findunitr(const region * r, int n) { unit *u; /* findunit regional! */ - assert(n>0); + assert(n > 0); u = ufindhash(n); - return (u && u->region==r)?u:0; + return (u && u->region == r) ? u : 0; } // TODO: deprecated, replace with findunit(n) @@ -443,8 +444,9 @@ int ualias(const unit * u) return a->data.i; } -int a_readprivate(attrib * a, void *owner, struct storage *store) +int a_readprivate(attrib * a, void *owner, gamedata *data) { + struct storage *store = data->store; char lbuf[DISPLAYSIZE]; READ_STR(store, lbuf, sizeof(lbuf)); a->data.v = _strdup(lbuf); @@ -579,9 +581,9 @@ void a_writesiege(const attrib * a, const void *owner, struct storage *store) write_building_reference(b, store); } -int a_readsiege(attrib * a, void *owner, struct storage *store) +int a_readsiege(attrib * a, void *owner, gamedata *data) { - int result = read_reference(&a->data.v, store, read_building_reference, + int result = read_reference(&a->data.v, data, read_building_reference, resolve_building); if (result == 0 && !a->data.v) { return AT_READ_FAIL; @@ -656,7 +658,7 @@ bool ucontact(const unit * u, const unit * u2) /* Explizites KONTAKTIERE */ for (ru = a_find(u->attribs, &at_contact); ru && ru->type == &at_contact; - ru = ru->next) { + ru = ru->next) { if (((unit *)ru->data.v) == u2) { return true; } @@ -698,10 +700,10 @@ int resolve_unit(variant id, void *address) return 0; } -variant read_unit_reference(struct storage * store) +variant read_unit_reference(gamedata *data) { variant var; - READ_INT(store, &var.i); + READ_INT(data->store, &var.i); return var; } @@ -830,7 +832,7 @@ bool can_leave(unit * u) rule_leave = config_get_int("rules.move.owner_leave", 0); - if (rule_leave!=0 && u->building && u == building_owner(u->building)) { + if (rule_leave != 0 && u->building && u == building_owner(u->building)) { return false; } return true; @@ -1001,7 +1003,7 @@ void transfermen(unit * u, unit * dst, int n) set_leftship(dst, sh); dst->flags |= u->flags & (UFL_LONGACTION | UFL_NOTMOVING | UFL_HUNGER | UFL_MOVED | - UFL_ENTER); + UFL_ENTER); if (u->attribs) { transfer_curse(u, dst, n); } @@ -1132,8 +1134,8 @@ bool learn_skill(unit * u, skill_t sk, double learn_chance) { skill *sv = u->skills; if (learn_chance < 1.0 && rng_int() % 10000 >= learn_chance * 10000) - if (!chance(learn_chance)) - return false; + if (!chance(learn_chance)) + return false; while (sv != u->skills + u->skill_size) { assert(sv->weeks > 0); if (sv->id == sk) { @@ -1280,7 +1282,8 @@ static int att_modification(const unit * u, skill_t sk) bool allied = alliedunit(c->magician, u->faction, HELP_GUARD); if (allied) { if (effect > bonus) bonus = effect; - } else { + } + else { if (effect < malus) malus = effect; } } @@ -1329,7 +1332,7 @@ int eff_skill(const unit * u, const skill *sv, const region *r) { assert(u); if (!r) r = u->region; - if (sv && sv->level>0) { + if (sv && sv->level > 0) { int mlevel = sv->level + get_modifier(u, sv->id, sv->level, r, false); if (mlevel > 0) { @@ -1418,10 +1421,10 @@ void default_name(const unit *u, char name[], int len) { static const char * prefix[MAXLOCALES]; int i = locale_index(lang); /*if (!prefix[i]) {*/ - prefix[i] = LOC(lang, "unitdefault"); - if (!prefix[i]) { - prefix[i] = parameters[P_UNIT]; - } + prefix[i] = LOC(lang, "unitdefault"); + if (!prefix[i]) { + prefix[i] = parameters[P_UNIT]; + } /*}*/ result = prefix[i]; } @@ -1733,7 +1736,7 @@ void scale_number(unit * u, int n) } if (u->number > 0) { for (a = a_find(u->attribs, &at_effect); a && a->type == &at_effect; - a = a->next) { + a = a->next) { effect_data *data = (effect_data *)a->data.v; int snew = data->value / u->number * n; if (n) { @@ -1893,7 +1896,7 @@ static double produceexp_chance(void) { return config_get_flt("study.from_use", 1.0 / 3); } -void produceexp_ex(struct unit *u, skill_t sk, int n, bool (*learn)(unit *, skill_t, double)) +void produceexp_ex(struct unit *u, skill_t sk, int n, bool(*learn)(unit *, skill_t, double)) { if (n != 0 && (is_monsters(u->faction) || playerrace(u_race(u)))) { double chance = produceexp_chance(); diff --git a/src/kernel/unit.h b/src/kernel/unit.h index e2dac5abe..36abb1cf3 100644 --- a/src/kernel/unit.h +++ b/src/kernel/unit.h @@ -30,7 +30,7 @@ extern "C" { struct skill; struct item; struct sc_mage; - + struct gamedata; #define UFL_DEAD (1<<0) #define UFL_ISNEW (1<<1) /* 2 */ #define UFL_LONGACTION (1<<2) /* 4 */ @@ -186,7 +186,7 @@ extern "C" { /* see resolve.h */ int resolve_unit(variant data, void *address); void write_unit_reference(const struct unit *u, struct storage *store); - variant read_unit_reference(struct storage *store); + variant read_unit_reference(struct gamedata *data); bool leave(struct unit *u, bool force); bool can_leave(struct unit *u); diff --git a/src/kernel/version.h b/src/kernel/version.h index 235be6086..94e8e547c 100644 --- a/src/kernel/version.h +++ b/src/kernel/version.h @@ -35,10 +35,8 @@ #define ATTRIBOWNER_VERSION 350 /* all attrib_type functions know who owns the attribute */ #define BADCRYPT_VERSION 351 /* passwords are encrypted, poorly */ #define ATHASH_VERSION 352 /* attribute-type hash, not name */ -#define CRYPT_VERSION 353 /* passwords are encrypted */ -#define NOWATCH_VERSION 354 /* plane->watchers is gone */ -#define RELEASE_VERSION ATHASH_VERSION /* current datafile */ +#define NOWATCH_VERSION 353 /* plane->watchers is gone */ +#define CRYPT_VERSION 354 /* passwords are encrypted */ +#define RELEASE_VERSION NOWATCH_VERSION /* current datafile */ #define MIN_VERSION INTPAK_VERSION /* minimal datafile we support */ #define MAX_VERSION RELEASE_VERSION /* change this if we can need to read the future datafile, and we can do so */ - -#define STREAM_VERSION 2 /* internal encoding of binary files */ diff --git a/src/magic.c b/src/magic.c index b8b5005da..e7d94ac25 100644 --- a/src/magic.c +++ b/src/magic.c @@ -54,7 +54,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include -#include +#include #include #include #include @@ -67,6 +67,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include +#include #include /* libc includes */ @@ -128,16 +129,17 @@ typedef struct icastle_data { int time; } icastle_data; -static int a_readicastle(attrib * a, void *owner, struct storage *store) +static int a_readicastle(attrib * a, void *owner, struct gamedata *data) { - icastle_data *data = (icastle_data *)a->data.v; + storage *store = data->store; + icastle_data *idata = (icastle_data *)a->data.v; char token[32]; READ_TOK(store, token, sizeof(token)); - if (global.data_version < ATTRIBOWNER_VERSION) { + if (data->version < ATTRIBOWNER_VERSION) { READ_INT(store, NULL); } - READ_INT(store, &data->time); - data->type = bt_find(token); + READ_INT(store, &idata->time); + idata->type = bt_find(token); return AT_READ_OK; } @@ -254,8 +256,9 @@ int get_spell_level_mage(const spell * sp, void * cbdata) return sbe ? sbe->level : 0; } -static int read_mage(attrib * a, void *owner, struct storage *store) +static int read_mage(attrib * a, void *owner, struct gamedata *data) { + storage *store = data->store; int i, mtype; sc_mage *mage = (sc_mage *)a->data.v; char spname[64]; @@ -291,10 +294,10 @@ static int read_mage(attrib * a, void *owner, struct storage *store) } } if (mage->magietyp == M_GRAY) { - read_spellbook(&mage->spellbook, store, get_spell_level_mage, mage); + read_spellbook(&mage->spellbook, data, get_spell_level_mage, mage); } else { - read_spellbook(0, store, 0, mage); + read_spellbook(0, data, 0, mage); } return AT_READ_OK; } @@ -362,8 +365,9 @@ sc_mage *get_mage(const unit * u) * Spruch zu seiner List-of-known-spells hinzugefügt werden. */ -static int read_seenspell(attrib * a, void *owner, struct storage *store) +static int read_seenspell(attrib * a, void *owner, struct gamedata *data) { + storage *store = data->store; int i; spell *sp = 0; char token[32]; @@ -374,7 +378,7 @@ static int read_seenspell(attrib * a, void *owner, struct storage *store) sp = find_spellbyid((unsigned int)i); } else { - if (global.data_version < UNIQUE_SPELLS_VERSION) { + if (data->version < UNIQUE_SPELLS_VERSION) { READ_INT(store, 0); /* ignore mtype */ } sp = find_spell(token); @@ -2281,10 +2285,10 @@ static int resolve_familiar(variant data, void *addr) return result; } -static int read_familiar(attrib * a, void *owner, struct storage *store) +static int read_familiar(attrib * a, void *owner, struct gamedata *data) { int result = - read_reference(&a->data.v, store, read_unit_reference, resolve_familiar); + read_reference(&a->data.v, data, read_unit_reference, resolve_familiar); if (result == 0 && a->data.v == NULL) { return AT_READ_FAIL; } @@ -2365,10 +2369,10 @@ static int resolve_clone(variant data, void *addr) return result; } -static int read_clone(attrib * a, void *owner, struct storage *store) +static int read_clone(attrib * a, void *owner, struct gamedata *data) { int result = - read_reference(&a->data.v, store, read_unit_reference, resolve_clone); + read_reference(&a->data.v, data, read_unit_reference, resolve_clone); if (result == 0 && a->data.v == NULL) { return AT_READ_FAIL; } @@ -2392,10 +2396,10 @@ static int resolve_mage(variant data, void *addr) return result; } -static int read_magician(attrib * a, void *owner, struct storage *store) +static int read_magician(attrib * a, void *owner, struct gamedata *data) { int result = - read_reference(&a->data.v, store, read_unit_reference, resolve_mage); + read_reference(&a->data.v, data, read_unit_reference, resolve_mage); if (result == 0 && a->data.v == NULL) { return AT_READ_FAIL; } diff --git a/src/modules/arena.c b/src/modules/arena.c index 6b76a3434..97488218a 100644 --- a/src/modules/arena.c +++ b/src/modules/arena.c @@ -48,6 +48,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -248,10 +249,10 @@ write_hurting(const attrib * a, const void *owner, struct storage *store) WRITE_INT(store, b->no); } -static int read_hurting(attrib * a, void *owner, struct storage *store) +static int read_hurting(attrib * a, void *owner, struct gamedata *data) { int i; - READ_INT(store, &i); + READ_INT(data->store, &i); a->data.v = (void *)findbuilding(i); if (a->data.v == NULL) { log_error("temple of pain is broken\n"); @@ -448,10 +449,10 @@ static void caldera_write(const trigger * t, struct storage *store) write_building_reference(b, store); } -static int caldera_read(trigger * t, struct storage *store) +static int caldera_read(trigger * t, struct gamedata *data) { int rb = - read_reference(&t->data.v, store, read_building_reference, + read_reference(&t->data.v, data, read_building_reference, resolve_building); if (rb == 0 && !t->data.v) { return AT_READ_FAIL; diff --git a/src/modules/gmcmd.c b/src/modules/gmcmd.c index 02bd2b889..f450cd67f 100644 --- a/src/modules/gmcmd.c +++ b/src/modules/gmcmd.c @@ -35,6 +35,8 @@ /* util includes */ #include +#include + #include /* libc includes */ @@ -43,18 +45,18 @@ #include #include -static int read_permissions(attrib * a, void *owner, struct storage *store) +static int read_permissions(attrib * a, void *owner, struct gamedata *data) { assert(!a); - a_read(store, &a, owner); + a_read(data, &a, owner); a_remove(&a, a); return AT_READ_OK; } -static int read_gmcreate(attrib * a, void *owner, struct storage *store) +static int read_gmcreate(attrib * a, void *owner, struct gamedata *data) { char zText[32]; - READ_TOK(store, zText, sizeof(zText)); + READ_TOK(data->store, zText, sizeof(zText)); return AT_READ_OK; } diff --git a/src/modules/museum.c b/src/modules/museum.c index 516bf775f..5ad9092a4 100644 --- a/src/modules/museum.c +++ b/src/modules/museum.c @@ -43,6 +43,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include @@ -79,11 +80,11 @@ struct storage *store) } static int -a_readmuseumgivebackcookie(attrib * a, void *owner, struct storage *store) +a_readmuseumgivebackcookie(attrib * a, void *owner, gamedata *data) { museumgivebackcookie *gbc = (museumgivebackcookie *)a->data.v; - READ_INT(store, &gbc->warden_no); - READ_INT(store, &gbc->cookie); + READ_INT(data->store, &gbc->warden_no); + READ_INT(data->store, &gbc->cookie); return AT_READ_OK; } @@ -121,11 +122,11 @@ struct storage *store) write_items(store, gb->items); } -static int a_readmuseumgiveback(attrib * a, void *owner, struct storage *store) +static int a_readmuseumgiveback(attrib * a, void *owner, struct gamedata *data) { museumgiveback *gb = (museumgiveback *)a->data.v; - READ_INT(store, &gb->cookie); - read_items(store, &gb->items); + READ_INT(data->store, &gb->cookie); + read_items(data->store, &gb->items); return AT_READ_OK; } diff --git a/src/modules/xmas.c b/src/modules/xmas.c index 1aa8aaba7..4b90af68e 100644 --- a/src/modules/xmas.c +++ b/src/modules/xmas.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -47,10 +48,10 @@ static void xmasgate_write(const trigger * t, struct storage *store) WRITE_TOK(store, itoa36(b->no)); } -static int xmasgate_read(trigger * t, struct storage *store) +static int xmasgate_read(trigger * t, struct gamedata *data) { int bc = - read_reference(&t->data.v, store, read_building_reference, + read_reference(&t->data.v, data, read_building_reference, resolve_building); if (bc == 0 && !t->data.v) { return AT_READ_FAIL; diff --git a/src/move.c b/src/move.c index cd6361605..456610866 100644 --- a/src/move.c +++ b/src/move.c @@ -59,6 +59,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -154,8 +155,9 @@ static int shiptrail_age(attrib * a, void *owner) return (t->age > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE; } -static int shiptrail_read(attrib * a, void *owner, struct storage *store) +static int shiptrail_read(attrib * a, void *owner, struct gamedata *data) { + storage *store = data->store; int n; traveldir *t = (traveldir *)(a->data.v); diff --git a/src/move.test.c b/src/move.test.c index c4e9944c9..81398ec62 100644 --- a/src/move.test.c +++ b/src/move.test.c @@ -35,8 +35,6 @@ static void test_ship_not_allowed_in_coast(CuTest * tc) ship_type *stype; test_cleanup(); - test_create_world(); - ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO | SAIL_INTO); otype = test_create_terrain("ocean", SEA_REGION | SAIL_INTO); stype = test_create_shiptype("derp"); @@ -50,6 +48,7 @@ static void test_ship_not_allowed_in_coast(CuTest * tc) CuAssertIntEquals(tc, SA_NO_COAST, check_ship_allowed(sh, r1)); stype->coasts[0] = ttype; CuAssertIntEquals(tc, SA_COAST, check_ship_allowed(sh, r1)); + test_cleanup(); } typedef struct move_fixture { @@ -68,7 +67,6 @@ static void setup_harbor(move_fixture *mf) { unit *u; test_cleanup(); - test_create_world(); ttype = test_create_terrain("glacier", LAND_REGION | ARCTIC_REGION | WALK_INTO | SAIL_INTO); btype = test_create_buildingtype("harbour"); diff --git a/src/spells.c b/src/spells.c index e7240b8dc..ceb66d69f 100644 --- a/src/spells.c +++ b/src/spells.c @@ -62,6 +62,7 @@ #include #include #include +#include #include #include #include @@ -2866,9 +2867,10 @@ static curse *mk_deathcloud(unit * mage, region * r, double force, int duration) #define COMPAT_DEATHCLOUD #ifdef COMPAT_DEATHCLOUD -static int dc_read_compat(struct attrib *a, void *target, struct storage * store) +static int dc_read_compat(struct attrib *a, void *target, gamedata *data) /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */ { + struct storage *store = data->store; region *r = NULL; unit *u; variant var; diff --git a/src/spells/alp.c b/src/spells/alp.c index e44b52ffa..61c60df03 100644 --- a/src/spells/alp.c +++ b/src/spells/alp.c @@ -25,6 +25,7 @@ /* util includes */ #include #include +#include #include #include @@ -76,12 +77,12 @@ alp_write(const attrib * a, const void *owner, struct storage *store) write_unit_reference(ad->target, store); } -static int alp_read(attrib * a, void *owner, struct storage *store) +static int alp_read(attrib * a, void *owner, struct gamedata *data) { alp_data *ad = (alp_data *)a->data.v; - int rm = read_reference(&ad->mage, store, read_unit_reference, resolve_unit); + int rm = read_reference(&ad->mage, data, read_unit_reference, resolve_unit); int rt = - read_reference(&ad->target, store, read_unit_reference, resolve_unit); + read_reference(&ad->target, data, read_unit_reference, resolve_unit); if (rt == 0 && rm == 0 && (!ad->target || !ad->mage)) { /* the target or mage disappeared. */ return AT_READ_FAIL; diff --git a/src/spells/borders.c b/src/spells/borders.c index 3f107a389..2c222a9dd 100644 --- a/src/spells/borders.c +++ b/src/spells/borders.c @@ -14,6 +14,7 @@ #include #include +#include #include #include #include @@ -51,8 +52,9 @@ typedef struct bresolve { static int resolve_buddy(variant data, void *addr); -static int cw_read(attrib * a, void *target, storage * store) +static int cw_read(attrib * a, void *target, gamedata *data) { + storage *store = data->store; bresolve *br = calloc(sizeof(bresolve), 1); curse *c = (curse *)a->data.v; wallcurse *wc = (wallcurse *)c->data.v; @@ -172,15 +174,15 @@ static void wall_destroy(connection * b) free(b->data.v); } -static void wall_read(connection * b, storage * store) +static void wall_read(connection * b, gamedata * data) { static wall_data dummy; wall_data *fd = b->data.v ? (wall_data *)b->data.v : &dummy; - read_reference(&fd->mage, store, read_unit_reference, resolve_unit); - READ_INT(store, &fd->force); - if (global.data_version >= NOBORDERATTRIBS_VERSION) { - READ_INT(store, &fd->countdown); + read_reference(&fd->mage, data, read_unit_reference, resolve_unit); + READ_INT(data->store, &fd->force); + if (data->version >= NOBORDERATTRIBS_VERSION) { + READ_INT(data->store, &fd->countdown); } fd->active = true; } diff --git a/src/spells/flyingship.c b/src/spells/flyingship.c index e8574db2b..c58ec270c 100644 --- a/src/spells/flyingship.c +++ b/src/spells/flyingship.c @@ -11,6 +11,8 @@ #include #include +#include + #include #include @@ -95,11 +97,11 @@ int sp_flying_ship(castorder * co) return cast_level; } -static int flyingship_read(storage * store, curse * c, void *target) +static int flyingship_read(gamedata * data, curse * c, void *target) { ship *sh = (ship *)target; c->data.v = sh; - if (global.data_version < FOSS_VERSION) { + if (data->version < FOSS_VERSION) { sh->flags |= SF_FLYING; return 0; } diff --git a/src/spells/unitcurse.c b/src/spells/unitcurse.c index 73925a55a..c29935479 100644 --- a/src/spells/unitcurse.c +++ b/src/spells/unitcurse.c @@ -25,6 +25,7 @@ #include /* util includes */ +#include #include #include #include @@ -307,10 +308,10 @@ static struct curse_type ct_oldrace = { * C_SKILL */ -static int read_skill(struct storage *store, curse * c, void *target) +static int read_skill(gamedata *data, curse * c, void *target) { int skill; - READ_INT(store, &skill); + READ_INT(data->store, &skill); c->data.i = skill; return 0; } diff --git a/src/test_eressea.c b/src/test_eressea.c index 34a8ba141..658f20b9b 100644 --- a/src/test_eressea.c +++ b/src/test_eressea.c @@ -75,6 +75,7 @@ int RunAllTests(int argc, char *argv[]) ADD_SUITE(base36); ADD_SUITE(bsdstring); ADD_SUITE(functions); + ADD_SUITE(gamedata); ADD_SUITE(parser); ADD_SUITE(password); ADD_SUITE(umlaut); diff --git a/src/tests.c b/src/tests.c index b52759489..69d4d4f2b 100644 --- a/src/tests.c +++ b/src/tests.c @@ -156,7 +156,7 @@ ship_type * test_create_shiptype(const char * name) stype->coasts = (terrain_type **)malloc(sizeof(terrain_type *)*2); - stype->coasts[0] = get_or_create_terrain("plain"); + stype->coasts[0] = test_create_terrain("plain", LAND_REGION | FOREST_REGION | WALK_INTO | CAVALRY_REGION | SAIL_INTO | FLY_INTO); stype->coasts[1] = NULL; if (default_locale) { diff --git a/src/triggers/changefaction.c b/src/triggers/changefaction.c index 47eee5874..13785dfb9 100644 --- a/src/triggers/changefaction.c +++ b/src/triggers/changefaction.c @@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include #include @@ -82,12 +83,13 @@ static void changefaction_write(const trigger * t, struct storage *store) write_faction_reference(td->faction->_alive ? td->faction : NULL, store); } -static int changefaction_read(trigger * t, struct storage *store) +static int changefaction_read(trigger * t, gamedata *data) { variant var; changefaction_data *td = (changefaction_data *)t->data.v; - read_reference(&td->unit, store, read_unit_reference, resolve_unit); - var = read_faction_reference(store); + + read_reference(&td->unit, data, read_unit_reference, resolve_unit); + var = read_faction_reference(data); if (var.i == 0) { return AT_READ_FAIL; } diff --git a/src/triggers/changerace.c b/src/triggers/changerace.c index d4937cc9f..0e7fc997e 100644 --- a/src/triggers/changerace.c +++ b/src/triggers/changerace.c @@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include #include @@ -86,12 +87,12 @@ static void changerace_write(const trigger * t, struct storage *store) write_race_reference(td->irace, store); } -static int changerace_read(trigger * t, struct storage *store) +static int changerace_read(trigger * t, gamedata *data) { changerace_data *td = (changerace_data *)t->data.v; - read_reference(&td->u, store, read_unit_reference, resolve_unit); - td->race = (const struct race *)read_race_reference(store).v; - td->irace = (const struct race *)read_race_reference(store).v; + read_reference(&td->u, data, read_unit_reference, resolve_unit); + td->race = (const struct race *)read_race_reference(data->store).v; + td->irace = (const struct race *)read_race_reference(data->store).v; return AT_READ_OK; } diff --git a/src/triggers/clonedied.c b/src/triggers/clonedied.c index 7a91ea514..37693fdbf 100644 --- a/src/triggers/clonedied.c +++ b/src/triggers/clonedied.c @@ -29,6 +29,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include #include @@ -68,10 +69,10 @@ static void clonedied_write(const trigger * t, struct storage *store) write_unit_reference(u, store); } -static int clonedied_read(trigger * t, struct storage *store) +static int clonedied_read(trigger * t, gamedata *data) { int result = - read_reference(&t->data.v, store, read_unit_reference, resolve_unit); + read_reference(&t->data.v, data, read_unit_reference, resolve_unit); if (result == 0 && t->data.v == NULL) { return AT_READ_FAIL; } diff --git a/src/triggers/createcurse.c b/src/triggers/createcurse.c index 07e8a370e..d0d65571b 100644 --- a/src/triggers/createcurse.c +++ b/src/triggers/createcurse.c @@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include #include @@ -93,30 +94,30 @@ static void createcurse_write(const trigger * t, struct storage *store) WRITE_INT(store, td->men); } -static int createcurse_read(trigger * t, struct storage *store) +static int createcurse_read(trigger * t, gamedata *data) { createcurse_data *td = (createcurse_data *)t->data.v; char zText[128]; float flt; - read_reference(&td->mage, store, read_unit_reference, resolve_unit); - read_reference(&td->target, store, read_unit_reference, resolve_unit); + read_reference(&td->mage, data, read_unit_reference, resolve_unit); + read_reference(&td->target, data, read_unit_reference, resolve_unit); - READ_TOK(store, zText, sizeof(zText)); + READ_TOK(data->store, zText, sizeof(zText)); td->type = ct_find(zText); - READ_FLT(store, &flt); + READ_FLT(data->store, &flt); td->vigour = flt; - READ_INT(store, &td->duration); - if (global.data_version < CURSEFLOAT_VERSION) { + READ_INT(data->store, &td->duration); + if (data->version < CURSEFLOAT_VERSION) { int n; - READ_INT(store, &n); + READ_INT(data->store, &n); td->effect = (float)n; } else { - READ_FLT(store, &flt); + READ_FLT(data->store, &flt); td->effect = flt; } - READ_INT(store, &td->men); + READ_INT(data->store, &td->men); return AT_READ_OK; } diff --git a/src/triggers/createunit.c b/src/triggers/createunit.c index bd8595378..6e98901ca 100644 --- a/src/triggers/createunit.c +++ b/src/triggers/createunit.c @@ -31,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include @@ -88,12 +89,12 @@ static void createunit_write(const trigger * t, struct storage *store) WRITE_INT(store, td->number); } -static int createunit_read(trigger * t, struct storage *store) +static int createunit_read(trigger * t, gamedata *data) { createunit_data *td = (createunit_data *)t->data.v; variant var; int result = AT_READ_OK; - var = read_faction_reference(store); + var = read_faction_reference(data); if (var.i > 0) { td->f = findfaction(var.i); if (!td->f) { @@ -105,13 +106,13 @@ static int createunit_read(trigger * t, struct storage *store) } // read_reference(&td->f, store, read_faction_reference, resolve_faction); - read_reference(&td->r, store, read_region_reference, - RESOLVE_REGION(global.data_version)); - td->race = (const struct race *)read_race_reference(store).v; + read_reference(&td->r, data, read_region_reference, + RESOLVE_REGION(data->version)); + td->race = (const struct race *)read_race_reference(data->store).v; if (!td->race) { result = AT_READ_FAIL; } - READ_INT(store, &td->number); + READ_INT(data->store, &td->number); return result; } diff --git a/src/triggers/gate.c b/src/triggers/gate.c index 44d26e0ef..2a9c5693d 100644 --- a/src/triggers/gate.c +++ b/src/triggers/gate.c @@ -13,7 +13,7 @@ #include #include "gate.h" -/* kernel includes */ + /* kernel includes */ #include #include #include @@ -22,6 +22,7 @@ /* util includes */ #include #include +#include #include #include @@ -72,15 +73,15 @@ static void gate_write(const trigger * t, struct storage *store) write_region_reference(r, store); } -static int gate_read(trigger * t, struct storage *store) +static int gate_read(trigger * t, gamedata *data) { gate_data *gd = (gate_data *)t->data.v; int bc = - read_reference(&gd->gate, store, read_building_reference, resolve_building); + read_reference(&gd->gate, data, read_building_reference, resolve_building); int rc = - read_reference(&gd->target, store, read_region_reference, - RESOLVE_REGION(global.data_version)); + read_reference(&gd->target, data, read_region_reference, + RESOLVE_REGION(data->version)); if (bc == 0 && rc == 0) { if (!gd->gate || !gd->target) diff --git a/src/triggers/giveitem.c b/src/triggers/giveitem.c index 02161775b..d4a56162b 100644 --- a/src/triggers/giveitem.c +++ b/src/triggers/giveitem.c @@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include @@ -82,15 +83,15 @@ static void giveitem_write(const trigger * t, struct storage *store) WRITE_TOK(store, td->itype->rtype->_name); } -static int giveitem_read(trigger * t, struct storage *store) +static int giveitem_read(trigger * t, gamedata *data) { giveitem_data *td = (giveitem_data *)t->data.v; char zText[128]; - int result = read_reference(&td->u, store, read_unit_reference, resolve_unit); + int result = read_reference(&td->u, data, read_unit_reference, resolve_unit); - READ_INT(store, &td->number); - READ_TOK(store, zText, sizeof(zText)); + READ_INT(data->store, &td->number); + READ_TOK(data->store, zText, sizeof(zText)); td->itype = it_find(zText); assert(td->itype); diff --git a/src/triggers/killunit.c b/src/triggers/killunit.c index 866914835..23275a6af 100644 --- a/src/triggers/killunit.c +++ b/src/triggers/killunit.c @@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include @@ -58,10 +59,10 @@ static void killunit_write(const trigger * t, struct storage *store) write_unit_reference(u, store); } -static int killunit_read(trigger * t, struct storage *store) +static int killunit_read(trigger * t, gamedata *data) { - int result = - read_reference(&t->data.v, store, read_unit_reference, resolve_unit); + int result = read_reference(&t->data.v, data, read_unit_reference, + resolve_unit); if (result == 0 && t->data.v == NULL) { return AT_READ_FAIL; } diff --git a/src/triggers/removecurse.c b/src/triggers/removecurse.c index 94819843a..d44f9dc22 100644 --- a/src/triggers/removecurse.c +++ b/src/triggers/removecurse.c @@ -28,6 +28,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include @@ -77,12 +78,16 @@ static void removecurse_write(const trigger * t, struct storage *store) WRITE_INT(store, td->curse ? td->curse->no : 0); } -static int removecurse_read(trigger * t, struct storage *store) +static variant read_curse_reference(struct gamedata *data) { + return read_int(data->store); +} + +static int removecurse_read(trigger * t, gamedata *data) { removecurse_data *td = (removecurse_data *)t->data.v; - read_reference(&td->target, store, read_unit_reference, resolve_unit); - read_reference(&td->curse, store, read_int, resolve_curse); + read_reference(&td->target, data, read_unit_reference, resolve_unit); + read_reference(&td->curse, data, read_curse_reference, resolve_curse); return AT_READ_OK; } diff --git a/src/triggers/shock.c b/src/triggers/shock.c index 95e7b61b6..75904e346 100644 --- a/src/triggers/shock.c +++ b/src/triggers/shock.c @@ -33,6 +33,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include #include +#include #include #include #include @@ -125,10 +126,10 @@ static void shock_write(const trigger * t, struct storage *store) } } -static int shock_read(trigger * t, struct storage *store) +static int shock_read(trigger * t, gamedata *data) { int result = - read_reference(&t->data.v, store, read_unit_reference, resolve_unit); + read_reference(&t->data.v, data, read_unit_reference, resolve_unit); if (result == 0 && t->data.v == NULL) { return AT_READ_FAIL; } diff --git a/src/triggers/timeout.c b/src/triggers/timeout.c index 8f1778f21..06fa18363 100644 --- a/src/triggers/timeout.c +++ b/src/triggers/timeout.c @@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include #include +#include #include #include @@ -72,11 +73,11 @@ static void timeout_write(const trigger * t, struct storage *store) write_triggers(store, td->triggers); } -static int timeout_read(trigger * t, struct storage *store) +static int timeout_read(trigger * t, gamedata *data) { timeout_data *td = (timeout_data *)t->data.v; - READ_INT(store, &td->timer); - read_triggers(store, &td->triggers); + READ_INT(data->store, &td->timer); + read_triggers(data, &td->triggers); if (td->timer > 20) { trigger *tr = td->triggers; log_warning("there is a timeout lasting for another %d turns\n", td->timer); diff --git a/src/triggers/unguard.c b/src/triggers/unguard.c index 49cb6fe25..e6471f977 100644 --- a/src/triggers/unguard.c +++ b/src/triggers/unguard.c @@ -22,6 +22,7 @@ /* util includes */ #include #include +#include #include #include @@ -48,10 +49,9 @@ static void unguard_write(const trigger * t, struct storage *store) write_building_reference((building *)t->data.v, store); } -static int unguard_read(trigger * t, struct storage *store) +static int unguard_read(trigger * t, gamedata *data) { - int rb = - read_reference(&t->data.v, store, read_building_reference, + int rb = read_reference(&t->data.v, data, read_building_reference, resolve_building); if (rb == 0 && !t->data.v) { return AT_READ_FAIL; diff --git a/src/triggers/unitmessage.c b/src/triggers/unitmessage.c index df227ed24..2d869fc49 100644 --- a/src/triggers/unitmessage.c +++ b/src/triggers/unitmessage.c @@ -20,6 +20,7 @@ without prior permission by the authors of Eressea. #include #include #include +#include #include #include #include @@ -84,17 +85,17 @@ static void unitmessage_write(const trigger * t, struct storage *store) WRITE_INT(store, td->level); } -static int unitmessage_read(trigger * t, struct storage *store) +static int unitmessage_read(trigger * t, gamedata *data) { unitmessage_data *td = (unitmessage_data *)t->data.v; char zText[256]; - int result = - read_reference(&td->target, store, read_unit_reference, resolve_unit); - READ_TOK(store, zText, sizeof(zText)); + int result = read_reference(&td->target, data, read_unit_reference, + resolve_unit); + READ_TOK(data->store, zText, sizeof(zText)); td->string = _strdup(zText); - READ_INT(store, &td->type); - READ_INT(store, &td->level); + READ_INT(data->store, &td->type); + READ_INT(data->store, &td->level); if (result == 0 && td->target == NULL) { return AT_READ_FAIL; diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index a441bcfe7..6fc0b5dea 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -2,6 +2,7 @@ project(util C) SET(_TEST_FILES base36.test.c +gamedata.test.c parser.test.c password.test.c attrib.test.c @@ -22,7 +23,9 @@ dice.c event.c filereader.c functions.c +gamedata.c goodies.c +gamedata.c language.c lists.c log.c diff --git a/src/util/attrib.c b/src/util/attrib.c index b5ea3ad3c..841bf9559 100644 --- a/src/util/attrib.c +++ b/src/util/attrib.c @@ -22,6 +22,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "log.h" #include "storage.h" +#include #include #include @@ -279,10 +280,10 @@ static critbit_tree cb_deprecated = { 0 }; typedef struct deprecated_s { unsigned int hash; - int(*reader)(attrib *, void *, struct storage *); + int(*reader)(attrib *, void *, struct gamedata *); } deprecated_t; -void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct storage *)) +void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamedata *)) { deprecated_t value; @@ -291,9 +292,9 @@ void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct stora cb_insert(&cb_deprecated, &value, sizeof(value)); } -static int a_read_i(struct storage *store, attrib ** attribs, void *owner, unsigned int key) { +static int a_read_i(gamedata *data, attrib ** attribs, void *owner, unsigned int key) { int retval = AT_READ_OK; - int(*reader)(attrib *, void *, struct storage *) = 0; + int(*reader)(attrib *, void *, struct gamedata *) = 0; attrib_type *at = at_find(key); attrib * na = 0; @@ -313,7 +314,7 @@ static int a_read_i(struct storage *store, attrib ** attribs, void *owner, unsig } } if (reader) { - int ret = reader(na, owner, store); + int ret = reader(na, owner, data); if (na) { switch (ret) { case AT_READ_DEPR: @@ -336,13 +337,14 @@ static int a_read_i(struct storage *store, attrib ** attribs, void *owner, unsig return retval; } -int a_read(struct storage *store, attrib ** attribs, void *owner) { +int a_read(gamedata *data, attrib ** attribs, void *owner) { + struct storage *store = data->store; int key, retval = AT_READ_OK; key = -1; READ_INT(store, &key); while (key > 0) { - int ret = a_read_i(store, attribs, owner, key); + int ret = a_read_i(data, attribs, owner, key); if (ret == AT_READ_DEPR) { retval = AT_READ_DEPR; } @@ -361,14 +363,14 @@ int a_read(struct storage *store, attrib ** attribs, void *owner) { return AT_READ_OK; } -int a_read_orig(struct storage *store, attrib ** attribs, void *owner) +int a_read_orig(gamedata *data, attrib ** attribs, void *owner) { int key, retval = AT_READ_OK; char zText[128]; zText[0] = 0; key = -1; - READ_TOK(store, zText, sizeof(zText)); + READ_TOK(data->store, zText, sizeof(zText)); if (strcmp(zText, "end") == 0) { return retval; } @@ -376,8 +378,8 @@ int a_read_orig(struct storage *store, attrib ** attribs, void *owner) key = __at_hashkey(zText); } while (key > 0) { - retval = a_read_i(store, attribs, owner, key); - READ_TOK(store, zText, sizeof(zText)); + retval = a_read_i(data, attribs, owner, key); + READ_TOK(data->store, zText, sizeof(zText)); if (!strcmp(zText, "end")) break; key = __at_hashkey(zText); diff --git a/src/util/attrib.h b/src/util/attrib.h index 9f421bfef..b41ac2bcf 100644 --- a/src/util/attrib.h +++ b/src/util/attrib.h @@ -55,7 +55,7 @@ extern "C" { int(*age) (struct attrib *, void *owner); /* age returns 0 if the attribute needs to be removed, !=0 otherwise */ void(*write) (const struct attrib *, const void *owner, struct storage *); - int(*read) (struct attrib *, void *owner, struct storage *); /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */ + int(*read) (struct attrib *, void *owner, struct gamedata *); /* return AT_READ_OK on success, AT_READ_FAIL if attrib needs removal */ void(*upgrade) (struct attrib **alist, struct attrib *a); unsigned int flags; /* ---- internal data, do not modify: ---- */ @@ -64,7 +64,7 @@ extern "C" { } attrib_type; extern void at_register(attrib_type * at); - extern void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct storage *)); + extern void at_deprecate(const char * name, int(*reader)(attrib *, void *, struct gamedata *)); extern attrib *a_select(attrib * a, const void *data, bool(*compare) (const attrib *, const void *)); @@ -75,10 +75,10 @@ extern "C" { extern attrib *a_new(const attrib_type * at); int a_age(attrib ** attribs, void *owner); - int a_read_orig(struct storage *store, attrib ** attribs, void *owner); + int a_read_orig(struct gamedata *data, attrib ** attribs, void *owner); void a_write_orig(struct storage *store, const attrib * attribs, const void *owner); - int a_read(struct storage *store, attrib ** attribs, void *owner); + int a_read(struct gamedata *data, attrib ** attribs, void *owner); void a_write(struct storage *store, const attrib * attribs, const void *owner); void free_attribs(void); diff --git a/src/util/event.c b/src/util/event.c index 5784a116a..b367081b3 100644 --- a/src/util/event.c +++ b/src/util/event.c @@ -21,6 +21,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. /* util includes */ #include "attrib.h" +#include "gamedata.h" #include "log.h" #include "storage.h" @@ -42,20 +43,20 @@ void write_triggers(struct storage *store, const trigger * t) WRITE_TOK(store, "end"); } -int read_triggers(struct storage *store, trigger ** tp) +int read_triggers(struct gamedata *data, trigger ** tp) { for (;;) { trigger_type *ttype; char zText[128]; - READ_TOK(store, zText, sizeof(zText)); + READ_TOK(data->store, zText, sizeof(zText)); if (!strcmp(zText, "end")) break; ttype = tt_find(zText); assert(ttype || !"unknown trigger-type"); *tp = t_new(ttype); if (ttype->read) { - int i = ttype->read(*tp, store); + int i = ttype->read(*tp, data); switch (i) { case AT_READ_OK: tp = &(*tp)->next; @@ -143,14 +144,15 @@ write_handler(const attrib * a, const void *owner, struct storage *store) write_triggers(store, hi->triggers); } -static int read_handler(attrib * a, void *owner, struct storage *store) +static int read_handler(attrib * a, void *owner, gamedata *data) { + struct storage *store = data->store; char zText[128]; handler_info *hi = (handler_info *)a->data.v; READ_TOK(store, zText, sizeof(zText)); hi->event = _strdup(zText); - read_triggers(store, &hi->triggers); + read_triggers(data, &hi->triggers); if (hi->triggers != NULL) { return AT_READ_OK; } diff --git a/src/util/event.h b/src/util/event.h index 2fb5f4806..ad4ca373d 100644 --- a/src/util/event.h +++ b/src/util/event.h @@ -27,6 +27,7 @@ extern "C" { struct attrib; struct trigger; struct storage; + struct gamedata; typedef struct trigger_type { const char *name; @@ -34,7 +35,7 @@ extern "C" { void(*finalize) (struct trigger *); int(*handle) (struct trigger *, void *); void(*write) (const struct trigger *, struct storage * store); - int(*read) (struct trigger *, struct storage * store); + int(*read) (struct trigger *, struct gamedata * store); struct trigger_type *next; } trigger_type; @@ -73,7 +74,7 @@ extern "C" { /* functions for making complex triggers: */ void free_triggers(trigger * triggers); /* release all these triggers */ void write_triggers(struct storage *store, const trigger * t); - int read_triggers(struct storage *store, trigger ** tp); + int read_triggers(struct gamedata *data, trigger ** tp); int handle_triggers(trigger ** triggers, void *data); extern struct attrib_type at_eventhandler; diff --git a/src/util/gamedata.c b/src/util/gamedata.c new file mode 100644 index 000000000..4dc334cc8 --- /dev/null +++ b/src/util/gamedata.c @@ -0,0 +1,72 @@ +#include + +#include "gamedata.h" +#include "log.h" + +#include +#include +#include +#include + +#include +#include +#include +#include + +void gamedata_done(gamedata *data) { + binstore_done(data->store); +} + +void gamedata_init(gamedata *data, storage *store, int version) { + data->version = version; + data->store = store; + binstore_init(data->store, &data->strm); +} + +void gamedata_close(gamedata *data) { + gamedata_done(data); + fstream_done(&data->strm); +} + +int gamedata_openfile(gamedata *data, const char *filename, const char *mode, int version) { + FILE *F = fopen(filename, mode); + if (F) { + int err = 0; + + if (strchr(mode, 'r')) { + size_t sz; + sz = fread(&version, 1, sizeof(int), F); + if (sz != sizeof(int)) { + err = ferror(F); + } + else { + err = fseek(F, sizeof(int), SEEK_CUR); + } + } + else if (strchr(mode, 'w')) { + int n = STREAM_VERSION; + fwrite(&version, sizeof(int), 1, F); + fwrite(&n, sizeof(int), 1, F); + } + if (err) { + log_error("could not open %s: %s", filename, strerror(errno)); + fclose(F); + } + else { + storage *store = malloc(sizeof(storage)); + fstream_init(&data->strm, F); + gamedata_init(data, store, version); + } + return err; + } + return errno; +} + +gamedata *gamedata_open(const char *filename, const char *mode, int version) { + gamedata *data = (gamedata *)calloc(1, sizeof(gamedata)); + if (gamedata_openfile(data, filename, mode, version) != 0) { + free(data); + return NULL; + } + return data; +} diff --git a/src/util/gamedata.h b/src/util/gamedata.h new file mode 100644 index 000000000..e75f7d681 --- /dev/null +++ b/src/util/gamedata.h @@ -0,0 +1,25 @@ +#pragma once + +#ifndef _GAMEDATA_H +#define _GAMEDATA_H + +#include + +struct storage; + +typedef struct gamedata { + struct storage *store; + stream strm; + int version; +} gamedata; + +void gamedata_init(gamedata *data, struct storage *store, int version); +void gamedata_done(gamedata *data); + +void gamedata_close(gamedata *data); +gamedata *gamedata_open(const char *filename, const char *mode, int version); +int gamedata_openfile(gamedata *data, const char *filename, const char *mode, int version); + +#define STREAM_VERSION 2 /* internal encoding of binary files */ + +#endif diff --git a/src/util/password.c b/src/util/password.c index 3434fb407..7b1bb9901 100644 --- a/src/util/password.c +++ b/src/util/password.c @@ -82,7 +82,7 @@ static const char * password_hash_i(const char * passwd, const char *input, int memcpy(salt, input, salt_len); salt[salt_len] = 0; } else { - input = password_gensalt(salt, sizeof(salt)); + input = password_gensalt(salt, SALTLEN); } if (algo == PASSWORD_MD5) { return md5_crypt_r(passwd, input, result, len); diff --git a/src/util/resolve.c b/src/util/resolve.c index e8dd0c17a..63ef5d933 100644 --- a/src/util/resolve.c +++ b/src/util/resolve.c @@ -45,10 +45,10 @@ variant read_int(struct storage *store) } int -read_reference(void *address, storage * store, read_fun reader, -resolve_fun resolver) +read_reference(void *address, struct gamedata * data, read_fun reader, + resolve_fun resolver) { - variant var = reader(store); + variant var = reader(data); int result = resolver(var, address); if (result != 0) { ur_add(var, address, resolver); diff --git a/src/util/resolve.h b/src/util/resolve.h index 8d24cc359..076b20508 100644 --- a/src/util/resolve.h +++ b/src/util/resolve.h @@ -21,14 +21,15 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "variant.h" struct storage; +struct gamedata; #ifdef __cplusplus extern "C" { #endif typedef int(*resolve_fun) (variant data, void *address); - typedef variant(*read_fun) (struct storage * store); - extern int read_reference(void *address, struct storage *store, + typedef variant(*read_fun) (struct gamedata * data); + extern int read_reference(void *address, struct gamedata *data, read_fun reader, resolve_fun resolver); extern void ur_add(variant data, void *address, resolve_fun fun); diff --git a/src/vortex.c b/src/vortex.c index 57dac78f8..8aac12aec 100644 --- a/src/vortex.c +++ b/src/vortex.c @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -74,8 +75,9 @@ static int a_agedirection(attrib * a, void *owner) return (d->duration > 0) ? AT_AGE_KEEP : AT_AGE_REMOVE; } -static int a_readdirection(attrib * a, void *owner, struct storage *store) +static int a_readdirection(attrib * a, void *owner, struct gamedata *data) { + struct storage *store = data->store; spec_direction *d = (spec_direction *)(a->data.v); char lbuf[32]; diff --git a/src/wormhole.c b/src/wormhole.c index 794dbc836..36e04e9e0 100644 --- a/src/wormhole.c +++ b/src/wormhole.c @@ -27,6 +27,7 @@ /* util includes */ #include +#include #include #include #include @@ -109,17 +110,18 @@ static int resolve_exit(variant id, void *address) return -1; } -static int wormhole_read(struct attrib *a, void *owner, struct storage *store) +static int wormhole_read(struct attrib *a, void *owner, struct gamedata *data) { - resolve_fun resolver = (global.data_version < UIDHASH_VERSION) + storage *store = data->store; + resolve_fun resolver = (data->version < UIDHASH_VERSION) ? resolve_exit : resolve_region_id; - read_fun reader = (global.data_version < UIDHASH_VERSION) + read_fun reader = (data->version < UIDHASH_VERSION) ? read_building_reference : read_region_reference; - if (global.data_version < ATTRIBOWNER_VERSION) { + if (data->version < ATTRIBOWNER_VERSION) { READ_INT(store, NULL); } - if (read_reference(&a->data.v, store, reader, resolver) == 0) { + if (read_reference(&a->data.v, data, reader, resolver) == 0) { if (!a->data.v) { return AT_READ_FAIL; }