forked from github/server
extract gamedata into a separate file.
This commit is contained in:
parent
0197ad16cc
commit
6ca81646eb
|
@ -35,7 +35,7 @@ static int tolua_storage_create(lua_State * L)
|
||||||
const char *type = tolua_tostring(L, 2, "rb");
|
const char *type = tolua_tostring(L, 2, "rb");
|
||||||
gamedata *data;
|
gamedata *data;
|
||||||
|
|
||||||
data = gamedata_open(filename, type);
|
data = gamedata_open(filename, type, RELEASE_VERSION);
|
||||||
if (data) {
|
if (data) {
|
||||||
tolua_pushusertype(L, (void *)data, TOLUA_CAST "storage");
|
tolua_pushusertype(L, (void *)data, TOLUA_CAST "storage");
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -60,6 +60,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#include <util/event.h>
|
#include <util/event.h>
|
||||||
#include <util/filereader.h>
|
#include <util/filereader.h>
|
||||||
#include <util/goodies.h>
|
#include <util/goodies.h>
|
||||||
|
#include <util/gamedata.h>
|
||||||
#include <util/language.h>
|
#include <util/language.h>
|
||||||
#include <util/lists.h>
|
#include <util/lists.h>
|
||||||
#include <util/log.h>
|
#include <util/log.h>
|
||||||
|
@ -1954,51 +1955,6 @@ int writegame(const char *filename)
|
||||||
return 0;
|
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 storage *store)
|
||||||
{
|
{
|
||||||
/* assert(sizeof(int)==sizeof(a->data)); */
|
/* assert(sizeof(int)==sizeof(a->data)); */
|
||||||
|
|
|
@ -20,6 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
#define H_KRNL_SAVE
|
#define H_KRNL_SAVE
|
||||||
|
|
||||||
#include <stream.h>
|
#include <stream.h>
|
||||||
|
#include <util/gamedata.h> // FIXME: eliminate include dependency from this file
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
@ -31,13 +32,6 @@ extern "C" {
|
||||||
struct spellbook;
|
struct spellbook;
|
||||||
struct unit;
|
struct unit;
|
||||||
|
|
||||||
typedef struct gamedata {
|
|
||||||
struct storage *store;
|
|
||||||
stream strm;
|
|
||||||
int version;
|
|
||||||
int encoding;
|
|
||||||
} gamedata;
|
|
||||||
|
|
||||||
#define MAX_INPUT_SIZE DISPLAYSIZE*2
|
#define MAX_INPUT_SIZE DISPLAYSIZE*2
|
||||||
/* Nach MAX_INPUT_SIZE brechen wir das Einlesen der Zeile ab und nehmen an,
|
/* Nach MAX_INPUT_SIZE brechen wir das Einlesen der Zeile ab und nehmen an,
|
||||||
* dass hier ein Fehler (fehlende ") vorliegt */
|
* dass hier ein Fehler (fehlende ") vorliegt */
|
||||||
|
@ -83,9 +77,6 @@ extern "C" {
|
||||||
|
|
||||||
void create_backup(char *file);
|
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) */
|
/* test-only functions that give access to internal implementation details (BAD) */
|
||||||
void _test_write_password(struct gamedata *data, const struct faction *f);
|
void _test_write_password(struct gamedata *data, const struct faction *f);
|
||||||
void _test_read_password(struct gamedata *data, struct faction *f);
|
void _test_read_password(struct gamedata *data, struct faction *f);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include <platform.h>
|
#include <platform.h>
|
||||||
#include <kernel/config.h>
|
#include <kernel/config.h>
|
||||||
#include <util/attrib.h>
|
#include <util/attrib.h>
|
||||||
|
#include <util/gamedata.h>
|
||||||
#include <attributes/key.h>
|
#include <attributes/key.h>
|
||||||
|
|
||||||
#include "save.h"
|
#include "save.h"
|
||||||
|
@ -43,7 +44,7 @@ static void test_readwrite_unit(CuTest * tc)
|
||||||
{
|
{
|
||||||
const char *filename = "test.dat";
|
const char *filename = "test.dat";
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
gamedata *data;
|
gamedata data;
|
||||||
struct unit *u;
|
struct unit *u;
|
||||||
struct region *r;
|
struct region *r;
|
||||||
struct faction *f;
|
struct faction *f;
|
||||||
|
@ -58,20 +59,16 @@ static void test_readwrite_unit(CuTest * tc)
|
||||||
u = test_create_unit(f, r);
|
u = test_create_unit(f, r);
|
||||||
join_path(datapath(), filename, path, sizeof(path));
|
join_path(datapath(), filename, path, sizeof(path));
|
||||||
|
|
||||||
data = gamedata_open(path, "wb");
|
CuAssertIntEquals(tc, 0, gamedata_openfile(&data, path, "wb", RELEASE_VERSION)); // TODO: intermittent test (even after the 'b' fix!)
|
||||||
CuAssertPtrNotNull(tc, data); // TODO: intermittent test (even after the 'b' fix!)
|
write_unit(&data, u);
|
||||||
|
gamedata_close(&data);
|
||||||
write_unit(data, u);
|
|
||||||
gamedata_close(data);
|
|
||||||
|
|
||||||
free_gamedata();
|
free_gamedata();
|
||||||
f = test_create_faction(0);
|
f = test_create_faction(0);
|
||||||
renumber_faction(f, fno);
|
renumber_faction(f, fno);
|
||||||
data = gamedata_open(path, "rb");
|
CuAssertIntEquals(tc, 0, gamedata_openfile(&data, path, "rb", RELEASE_VERSION)); // TODO: intermittent test (even after the 'b' fix!)
|
||||||
CuAssertPtrNotNull(tc, data);
|
u = read_unit(&data);
|
||||||
|
gamedata_close(&data);
|
||||||
u = read_unit(data);
|
|
||||||
gamedata_close(data);
|
|
||||||
|
|
||||||
CuAssertPtrNotNull(tc, u);
|
CuAssertPtrNotNull(tc, u);
|
||||||
CuAssertPtrEquals(tc, f, u->faction);
|
CuAssertPtrEquals(tc, f, u->faction);
|
||||||
|
@ -86,7 +83,7 @@ static void test_readwrite_attrib(CuTest *tc) {
|
||||||
const char *path = "attrib.dat";
|
const char *path = "attrib.dat";
|
||||||
test_cleanup();
|
test_cleanup();
|
||||||
global.data_version = RELEASE_VERSION; // FIXME: hack!
|
global.data_version = RELEASE_VERSION; // FIXME: hack!
|
||||||
data = gamedata_open(path, "wb");
|
data = gamedata_open(path, "wb", RELEASE_VERSION);
|
||||||
CuAssertPtrNotNull(tc, data);
|
CuAssertPtrNotNull(tc, data);
|
||||||
key_set(&a, 41);
|
key_set(&a, 41);
|
||||||
key_set(&a, 42);
|
key_set(&a, 42);
|
||||||
|
@ -95,7 +92,7 @@ static void test_readwrite_attrib(CuTest *tc) {
|
||||||
a_removeall(&a, NULL);
|
a_removeall(&a, NULL);
|
||||||
CuAssertPtrEquals(tc, 0, a);
|
CuAssertPtrEquals(tc, 0, a);
|
||||||
|
|
||||||
data = gamedata_open(path, "rb");
|
data = gamedata_open(path, "rb", RELEASE_VERSION);
|
||||||
CuAssertPtrNotNull(tc, data);
|
CuAssertPtrNotNull(tc, data);
|
||||||
read_attribs(data->store, &a, NULL);
|
read_attribs(data->store, &a, NULL);
|
||||||
gamedata_close(data);
|
gamedata_close(data);
|
||||||
|
@ -237,11 +234,11 @@ static void test_read_password(CuTest *tc) {
|
||||||
faction *f;
|
faction *f;
|
||||||
f = test_create_faction(0);
|
f = test_create_faction(0);
|
||||||
faction_setpassword(f, password_encode("secret", PASSWORD_DEFAULT));
|
faction_setpassword(f, password_encode("secret", PASSWORD_DEFAULT));
|
||||||
data = gamedata_open(path, "wb");
|
data = gamedata_open(path, "wb", RELEASE_VERSION);
|
||||||
CuAssertPtrNotNull(tc, data);
|
CuAssertPtrNotNull(tc, data);
|
||||||
_test_write_password(data, f);
|
_test_write_password(data, f);
|
||||||
gamedata_close(data);
|
gamedata_close(data);
|
||||||
data = gamedata_open(path, "rb");
|
data = gamedata_open(path, "rb", RELEASE_VERSION);
|
||||||
CuAssertPtrNotNull(tc, data);
|
CuAssertPtrNotNull(tc, data);
|
||||||
_test_read_password(data, f);
|
_test_read_password(data, f);
|
||||||
gamedata_close(data);
|
gamedata_close(data);
|
||||||
|
@ -259,12 +256,12 @@ static void test_read_password_external(CuTest *tc) {
|
||||||
f = test_create_faction(0);
|
f = test_create_faction(0);
|
||||||
faction_setpassword(f, password_encode("secret", PASSWORD_DEFAULT));
|
faction_setpassword(f, password_encode("secret", PASSWORD_DEFAULT));
|
||||||
CuAssertPtrNotNull(tc, f->_password);
|
CuAssertPtrNotNull(tc, f->_password);
|
||||||
data = gamedata_open(path, "wb");
|
data = gamedata_open(path, "wb", RELEASE_VERSION);
|
||||||
CuAssertPtrNotNull(tc, data);
|
CuAssertPtrNotNull(tc, data);
|
||||||
WRITE_TOK(data->store, (const char *)f->_password);
|
WRITE_TOK(data->store, (const char *)f->_password);
|
||||||
WRITE_TOK(data->store, (const char *)f->_password);
|
WRITE_TOK(data->store, (const char *)f->_password);
|
||||||
gamedata_close(data);
|
gamedata_close(data);
|
||||||
data = gamedata_open(path, "rb");
|
data = gamedata_open(path, "rb", RELEASE_VERSION);
|
||||||
CuAssertPtrNotNull(tc, data);
|
CuAssertPtrNotNull(tc, data);
|
||||||
data->version = BADCRYPT_VERSION;
|
data->version = BADCRYPT_VERSION;
|
||||||
_test_read_password(data, f);
|
_test_read_password(data, f);
|
||||||
|
|
|
@ -23,6 +23,7 @@ event.c
|
||||||
filereader.c
|
filereader.c
|
||||||
functions.c
|
functions.c
|
||||||
goodies.c
|
goodies.c
|
||||||
|
gamedata.c
|
||||||
language.c
|
language.c
|
||||||
lists.c
|
lists.c
|
||||||
log.c
|
log.c
|
||||||
|
|
|
@ -0,0 +1,98 @@
|
||||||
|
#include <platform.h>
|
||||||
|
|
||||||
|
#include "gamedata.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
#include <storage.h>
|
||||||
|
#include <filestream.h>
|
||||||
|
#include <memstream.h>
|
||||||
|
#include <binarystore.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void gamedata_close(gamedata *data) {
|
||||||
|
binstore_done(data->store);
|
||||||
|
fstream_done(&data->strm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void gamedata_init(gamedata *data, storage *store, int version) {
|
||||||
|
data->version = version;
|
||||||
|
data->store = store;
|
||||||
|
binstore_init(data->store, &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) {
|
||||||
|
fclose(F);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
|
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) {
|
||||||
|
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 = 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;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef _GAMEDATA_H
|
||||||
|
#define _GAMEDATA_H
|
||||||
|
|
||||||
|
#include <stream.h>
|
||||||
|
|
||||||
|
struct storage;
|
||||||
|
|
||||||
|
typedef struct gamedata {
|
||||||
|
struct storage *store;
|
||||||
|
stream strm;
|
||||||
|
int version;
|
||||||
|
int encoding;
|
||||||
|
} gamedata;
|
||||||
|
|
||||||
|
void gamedata_close(struct gamedata *data);
|
||||||
|
struct 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
|
Loading…
Reference in New Issue