forked from oerkki/voxelands
multiworld support pt2
This commit is contained in:
parent
157f9511ab
commit
c0b93d8ca1
13
src/common.h
13
src/common.h
|
@ -73,6 +73,18 @@ typedef struct command_context_s {
|
||||||
} command_context_t;
|
} command_context_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef _HAVE_WORDLIST_TYPE
|
||||||
|
#define _HAVE_WORDLIST_TYPE
|
||||||
|
typedef struct worldlist_s {
|
||||||
|
struct worldlist_s *prev;
|
||||||
|
struct worldlist_s *next;
|
||||||
|
char* name;
|
||||||
|
char* path;
|
||||||
|
char* version;
|
||||||
|
int8_t compat;
|
||||||
|
} worldlist_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
#define CN_ERROR 0x01
|
#define CN_ERROR 0x01
|
||||||
#define CN_WARN 0x02
|
#define CN_WARN 0x02
|
||||||
#define CN_ACTION 0x03
|
#define CN_ACTION 0x03
|
||||||
|
@ -187,6 +199,7 @@ int command_setpassword(command_context_t *ctx, array_t *args);
|
||||||
/* defined in world.c */
|
/* defined in world.c */
|
||||||
int world_create(char* name);
|
int world_create(char* name);
|
||||||
int world_load(char* name);
|
int world_load(char* name);
|
||||||
|
int world_import(char* path);
|
||||||
void world_unload(void);
|
void world_unload(void);
|
||||||
int world_init(char* name);
|
int world_init(char* name);
|
||||||
void world_exit(void);
|
void world_exit(void);
|
||||||
|
|
13
src/path.c
13
src/path.c
|
@ -752,3 +752,16 @@ dirlist_t *path_dirlist(char* type, char* file)
|
||||||
#endif
|
#endif
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void path_dirlist_free(dirlist_t *l)
|
||||||
|
{
|
||||||
|
dirlist_t *w;
|
||||||
|
if (!l)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while ((w = list_pull(&l))) {
|
||||||
|
if (w->name)
|
||||||
|
free(w->name);
|
||||||
|
free(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ int path_exists(char* path);
|
||||||
int path_create(char* type, char* file);
|
int path_create(char* type, char* file);
|
||||||
int path_remove(char* type, char* path);
|
int path_remove(char* type, char* path);
|
||||||
dirlist_t *path_dirlist(char* type, char* path);
|
dirlist_t *path_dirlist(char* type, char* path);
|
||||||
|
void path_dirlist_free(dirlist_t *l);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
168
src/world.c
168
src/world.c
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "path.h"
|
#include "path.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static int world_exists(char* name)
|
static int world_exists(char* name)
|
||||||
{
|
{
|
||||||
|
@ -62,6 +65,7 @@ int world_create(char* name)
|
||||||
|
|
||||||
config_set("world.path",buff);
|
config_set("world.path",buff);
|
||||||
config_set("world.name",name);
|
config_set("world.name",name);
|
||||||
|
config_set("world.version",VERSION_STRING);
|
||||||
|
|
||||||
return path_create("world","players");
|
return path_create("world","players");
|
||||||
}
|
}
|
||||||
|
@ -75,6 +79,7 @@ int world_create(char* name)
|
||||||
config_set("world.path",nbuff1);
|
config_set("world.path",nbuff1);
|
||||||
snprintf(nbuff,256,"%s %d",name,i);
|
snprintf(nbuff,256,"%s %d",name,i);
|
||||||
config_set("world.name",nbuff);
|
config_set("world.name",nbuff);
|
||||||
|
config_set("world.version",VERSION_STRING);
|
||||||
|
|
||||||
return path_create("world","players");
|
return path_create("world","players");
|
||||||
}
|
}
|
||||||
|
@ -86,7 +91,9 @@ int world_create(char* name)
|
||||||
int world_load(char* name)
|
int world_load(char* name)
|
||||||
{
|
{
|
||||||
char buff[2048];
|
char buff[2048];
|
||||||
|
char buff1[2048];
|
||||||
char nbuff[256];
|
char nbuff[256];
|
||||||
|
char* v;
|
||||||
|
|
||||||
config_clear("world");
|
config_clear("world");
|
||||||
|
|
||||||
|
@ -101,7 +108,8 @@ int world_load(char* name)
|
||||||
}
|
}
|
||||||
|
|
||||||
name = trim(name);
|
name = trim(name);
|
||||||
snprintf(nbuff,256,"%s",name);
|
if (snprintf(nbuff,256,"%s",name) >= 256)
|
||||||
|
return 1;
|
||||||
|
|
||||||
if (str_sanitise(buff,2048,nbuff) < 1)
|
if (str_sanitise(buff,2048,nbuff) < 1)
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -109,23 +117,77 @@ int world_load(char* name)
|
||||||
config_set("world.path",buff);
|
config_set("world.path",buff);
|
||||||
config_set("world.name",nbuff);
|
config_set("world.name",nbuff);
|
||||||
|
|
||||||
if (path_get("world","world.cfg",1,buff,2048)) {
|
if (path_get("world","world.cfg",1,buff1,2048)) {
|
||||||
config_load("world","world.cfg");
|
config_load("world","world.cfg");
|
||||||
}else{
|
}else{
|
||||||
vlprintf(CN_WARN,"Unknown world config: using defaults");
|
vlprintf(CN_WARN,"Unknown world config: using defaults");
|
||||||
|
config_save("world","world","world.cfg");
|
||||||
}
|
}
|
||||||
|
|
||||||
config_set("world.version",VERSION_STRING);
|
v = config_get("world.path");
|
||||||
|
/* world.path may have changed, if so then load world config from the new path */
|
||||||
#ifdef SERVER
|
if (v && strcmp(v,buff))
|
||||||
config_set("server.world",nbuff);
|
config_load("world","world.cfg");
|
||||||
#else
|
|
||||||
config_set("client.world",nbuff);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* imports a world from an absolute path, path = /path/to/world.cfg */
|
||||||
|
int world_import(char* path)
|
||||||
|
{
|
||||||
|
char buff[2048];
|
||||||
|
char pbuff[2048];
|
||||||
|
char newp[256];
|
||||||
|
char id[256];
|
||||||
|
char* v;
|
||||||
|
|
||||||
|
if (!path_exists(path))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (snprintf(buff,2048,"%s",path) >= 2048)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
v = strrchr(buff,'/');
|
||||||
|
if (!v)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
*v = 0;
|
||||||
|
|
||||||
|
config_set("world.path",buff);
|
||||||
|
config_load("world","world.cfg");
|
||||||
|
|
||||||
|
v = config_get("world.path");
|
||||||
|
if (!v || !strcmp(v,buff) || !config_get("world.name")) {
|
||||||
|
config_clear("world");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snprintf(id,256,"%s",v) >= 256) {
|
||||||
|
config_clear("world");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snprintf(newp,256,"%s/world.cfg",id) >= 256) {
|
||||||
|
config_clear("world");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (path_get("worlds",newp,1,pbuff,2048)) {
|
||||||
|
config_clear("world");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!path_get("worlds",newp,0,pbuff,2048)) {
|
||||||
|
config_clear("world");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
config_save("world",NULL,pbuff);
|
||||||
|
config_clear("world");
|
||||||
|
|
||||||
|
return world_load(id);
|
||||||
|
}
|
||||||
|
|
||||||
/* save the world data, then clear all world.* config */
|
/* save the world data, then clear all world.* config */
|
||||||
void world_unload()
|
void world_unload()
|
||||||
{
|
{
|
||||||
|
@ -136,6 +198,7 @@ void world_unload()
|
||||||
/* initialise and/or create a world */
|
/* initialise and/or create a world */
|
||||||
int world_init(char* name)
|
int world_init(char* name)
|
||||||
{
|
{
|
||||||
|
char *v;
|
||||||
if (!world_exists(name)) {
|
if (!world_exists(name)) {
|
||||||
if (world_create(name))
|
if (world_create(name))
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -144,6 +207,16 @@ int world_init(char* name)
|
||||||
if (world_load(name))
|
if (world_load(name))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
v = config_get("world.name");
|
||||||
|
|
||||||
|
config_set("world.version",VERSION_STRING);
|
||||||
|
|
||||||
|
#ifdef SERVER
|
||||||
|
config_set("server.world",v);
|
||||||
|
#else
|
||||||
|
config_set("client.world",v);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* TODO: init server/environment/etc */
|
/* TODO: init server/environment/etc */
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,3 +230,80 @@ void world_exit()
|
||||||
|
|
||||||
world_unload();
|
world_unload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int8_t world_compatibility(char* version)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef _HAVE_WORDLIST_TYPE
|
||||||
|
#define _HAVE_WORDLIST_TYPE
|
||||||
|
typedef struct worldlist_s {
|
||||||
|
struct worldlist_s *prev;
|
||||||
|
struct worldlist_s *next;
|
||||||
|
char* name;
|
||||||
|
char* path;
|
||||||
|
char* version;
|
||||||
|
int8_t compat;
|
||||||
|
} worldlist_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
worldlist_t *world_list_get()
|
||||||
|
{
|
||||||
|
dirlist_t *d;
|
||||||
|
dirlist_t *e;
|
||||||
|
worldlist_t *l = NULL;
|
||||||
|
worldlist_t *w;
|
||||||
|
char* n;
|
||||||
|
char* v;
|
||||||
|
|
||||||
|
d = path_dirlist("worlds",NULL);
|
||||||
|
|
||||||
|
if (!d)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
e = d;
|
||||||
|
while (e) {
|
||||||
|
world_load(e->name);
|
||||||
|
n = config_get("world.name");
|
||||||
|
v = config_get("world.version");
|
||||||
|
if (n) {
|
||||||
|
w = malloc(sizeof(worldlist_t));
|
||||||
|
if (w) {
|
||||||
|
w->name = strdup(n);
|
||||||
|
w->path = strdup(e->name);
|
||||||
|
if (v) {
|
||||||
|
w->version = strdup(v);
|
||||||
|
w->compat = world_compatibility(w->version);
|
||||||
|
}else{
|
||||||
|
w->version = strdup(VERSION_STRING);
|
||||||
|
w->compat = -1;
|
||||||
|
}
|
||||||
|
l = list_push(&l,w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_clear("world");
|
||||||
|
e = e->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
path_dirlist_free(d);
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
void world_list_free(worldlist_t *l)
|
||||||
|
{
|
||||||
|
worldlist_t *w;
|
||||||
|
if (!l)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while ((w = list_pull(&l))) {
|
||||||
|
if (w->name)
|
||||||
|
free(w->name);
|
||||||
|
if (w->path)
|
||||||
|
free(w->path);
|
||||||
|
if (w->version)
|
||||||
|
free(w->version);
|
||||||
|
free(w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue