multiworld support pt2

This commit is contained in:
darkrose 2017-08-15 22:40:45 +10:00
parent 157f9511ab
commit c0b93d8ca1
4 changed files with 186 additions and 9 deletions

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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
} }

View File

@ -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);
}
}