multiworld support pt2

master
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;
#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_WARN 0x02
#define CN_ACTION 0x03
@ -187,6 +199,7 @@ int command_setpassword(command_context_t *ctx, array_t *args);
/* defined in world.c */
int world_create(char* name);
int world_load(char* name);
int world_import(char* path);
void world_unload(void);
int world_init(char* name);
void world_exit(void);

View File

@ -752,3 +752,16 @@ dirlist_t *path_dirlist(char* type, char* file)
#endif
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_remove(char* type, char* path);
dirlist_t *path_dirlist(char* type, char* path);
void path_dirlist_free(dirlist_t *l);
#ifdef __cplusplus
}

View File

@ -19,6 +19,9 @@
#include "common.h"
#include "path.h"
#include "list.h"
#include <string.h>
static int world_exists(char* name)
{
@ -62,6 +65,7 @@ int world_create(char* name)
config_set("world.path",buff);
config_set("world.name",name);
config_set("world.version",VERSION_STRING);
return path_create("world","players");
}
@ -75,6 +79,7 @@ int world_create(char* name)
config_set("world.path",nbuff1);
snprintf(nbuff,256,"%s %d",name,i);
config_set("world.name",nbuff);
config_set("world.version",VERSION_STRING);
return path_create("world","players");
}
@ -86,7 +91,9 @@ int world_create(char* name)
int world_load(char* name)
{
char buff[2048];
char buff1[2048];
char nbuff[256];
char* v;
config_clear("world");
@ -101,7 +108,8 @@ int world_load(char* 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)
return 1;
@ -109,23 +117,77 @@ int world_load(char* name)
config_set("world.path",buff);
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");
}else{
vlprintf(CN_WARN,"Unknown world config: using defaults");
config_save("world","world","world.cfg");
}
config_set("world.version",VERSION_STRING);
#ifdef SERVER
config_set("server.world",nbuff);
#else
config_set("client.world",nbuff);
#endif
v = config_get("world.path");
/* world.path may have changed, if so then load world config from the new path */
if (v && strcmp(v,buff))
config_load("world","world.cfg");
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 */
void world_unload()
{
@ -136,6 +198,7 @@ void world_unload()
/* initialise and/or create a world */
int world_init(char* name)
{
char *v;
if (!world_exists(name)) {
if (world_create(name))
return 1;
@ -144,6 +207,16 @@ int world_init(char* name)
if (world_load(name))
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 */
@ -157,3 +230,80 @@ void world_exit()
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);
}
}