summaryrefslogtreecommitdiff
path: root/src/map/map.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/map.c')
-rw-r--r--src/map/map.c1150
1 files changed, 794 insertions, 356 deletions
diff --git a/src/map/map.c b/src/map/map.c
index 3dad25fce..16d5e645d 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -2,7 +2,7 @@
* This file is part of Hercules.
* http://herc.ws - http://github.com/HerculesWS/Hercules
*
- * Copyright (C) 2012-2015 Hercules Dev Team
+ * Copyright (C) 2012-2016 Hercules Dev Team
* Copyright (C) Athena Dev Teams
*
* Hercules is free software: you can redistribute it and/or modify
@@ -69,6 +69,7 @@
#include "common/random.h"
#include "common/showmsg.h"
#include "common/socket.h" // WFIFO*()
+#include "common/sql.h"
#include "common/strlib.h"
#include "common/timer.h"
#include "common/utils.h"
@@ -78,6 +79,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
#ifndef _WIN32
#include <unistd.h>
#endif
@@ -192,6 +194,7 @@ void map_update_cell_bl( struct block_list *bl, bool increase ) {
#ifdef CELL_NOSTACK
int pos;
+ nullpo_retv(bl);
if( bl->m < 0 || bl->x < 0 || bl->x >= map->list[bl->m].xs
|| bl->y < 0 || bl->y >= map->list[bl->m].ys
|| !(bl->type&BL_CHAR) )
@@ -308,9 +311,14 @@ int map_delblock(struct block_list* bl)
* (which are executed by default on BL_CHAR types)
*------------------------------------------*/
int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) {
- int x0 = bl->x, y0 = bl->y;
struct status_change *sc = NULL;
- int moveblock = ( x0/BLOCK_SIZE != x1/BLOCK_SIZE || y0/BLOCK_SIZE != y1/BLOCK_SIZE);
+ int x0, y0;
+ int moveblock;
+
+ nullpo_ret(bl);
+ x0 = bl->x;
+ y0 = bl->y;
+ moveblock = ( x0/BLOCK_SIZE != x1/BLOCK_SIZE || y0/BLOCK_SIZE != y1/BLOCK_SIZE);
if (!bl->prev) {
//Block not in map, just update coordinates, but do naught else.
@@ -329,6 +337,7 @@ int map_moveblock(struct block_list *bl, int x1, int y1, int64 tick) {
//status_change_end(bl, SC_BLADESTOP, INVALID_TIMER); //Won't stop when you are knocked away, go figure...
status_change_end(bl, SC_NJ_TATAMIGAESHI, INVALID_TIMER);
status_change_end(bl, SC_MAGICROD, INVALID_TIMER);
+ status_change_end(bl, SC_SU_STOOP, INVALID_TIMER);
if (sc && sc->data[SC_PROPERTYWALK] &&
sc->data[SC_PROPERTYWALK]->val3 >= skill->get_maxcount(sc->data[SC_PROPERTYWALK]->val1,sc->data[SC_PROPERTYWALK]->val2) )
status_change_end(bl,SC_PROPERTYWALK,INVALID_TIMER);
@@ -476,6 +485,8 @@ struct skill_unit* map_find_skill_unit_oncell(struct block_list* target,int16 x,
int16 m,bx,by;
struct block_list *bl;
struct skill_unit *su;
+
+ nullpo_retr(NULL, target);
m = target->m;
if (x < 0 || y < 0 || (x >= map->list[m].xs) || (y >= map->list[m].ys))
@@ -674,49 +685,95 @@ static int bl_getall_area(int type, int m, int x0, int y0, int x1, int y1, int (
x1 = min(x1, map->list[m].xs - 1);
y1 = min(y1, map->list[m].ys - 1);
- for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
- for (bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
- if (type&~BL_MOB) {
- for (bl = map->list[m].block[bx + by * map->list[m].bxs]; bl != NULL; bl = bl->next) {
- if (bl->type&type && bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1) {
- if( map->bl_list_count >= map->bl_list_size )
- map_bl_list_expand();
- if (func) {
- va_start(args, func);
- if (func(bl, args)) {
+ {
+ const int x0b = x0 / BLOCK_SIZE;
+ const int x1b = x1 / BLOCK_SIZE;
+ const int y0b = y0 / BLOCK_SIZE;
+ const int y1b = y1 / BLOCK_SIZE;
+ const struct map_data *const listm = &map->list[m];
+ const int bxs0 = listm->bxs;
+
+ // duplication for better performance
+ if (func != NULL) {
+ if (type & ~BL_MOB) {
+ for (by = y0b; by <= y1b; by++) {
+ const int bxs = by * bxs0;
+ for (bx = x0b; bx <= x1b; bx++) {
+ for (bl = listm->block[bx + bxs]; bl != NULL; bl = bl->next) {
+ const int x = bl->x;
+ const int y = bl->y;
+ if (bl->type & type && x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ va_start(args, func);
+ if (func(bl, args)) {
+ if (map->bl_list_count >= map->bl_list_size)
+ map_bl_list_expand();
+ map->bl_list[map->bl_list_count++] = bl;
+ found++;
+ }
+ va_end(args);
+ }
+ }
+ }
+ }
+ }
+ if (type & BL_MOB) {
+ for (by = y0b; by <= y1b; by++) {
+ const int bxs = by * bxs0;
+ for (bx = x0b; bx <= x1b; bx++) {
+ for (bl = listm->block_mob[bx + bxs]; bl != NULL; bl = bl->next) {
+ const int x = bl->x;
+ const int y = bl->y;
+ if (x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ va_start(args, func);
+ if (func(bl, args)) {
+ if (map->bl_list_count >= map->bl_list_size)
+ map_bl_list_expand();
+ map->bl_list[map->bl_list_count++] = bl;
+ found++;
+ }
+ va_end(args);
+ }
+ }
+ }
+ }
+ }
+ } else { // func != NULL
+ if (type & ~BL_MOB) {
+ for (by = y0b; by <= y1b; by++) {
+ const int bxs = by * bxs0;
+ for (bx = x0b; bx <= x1b; bx++) {
+ for (bl = listm->block[bx + bxs]; bl != NULL; bl = bl->next) {
+ const int x = bl->x;
+ const int y = bl->y;
+ if (bl->type & type && x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ if (map->bl_list_count >= map->bl_list_size)
+ map_bl_list_expand();
map->bl_list[map->bl_list_count++] = bl;
found++;
}
- va_end(args);
- } else {
- map->bl_list[map->bl_list_count++] = bl;
- found++;
}
}
}
}
- if (type&BL_MOB) { // TODO: fix this code duplication
- for (bl = map->list[m].block_mob[bx + by * map->list[m].bxs]; bl != NULL; bl = bl->next) {
- if (bl->x >= x0 && bl->x <= x1 && bl->y >= y0 && bl->y <= y1) {
- if( map->bl_list_count >= map->bl_list_size )
- map_bl_list_expand();
- if (func) {
- va_start(args, func);
- if (func(bl, args)) {
+ if (type & BL_MOB) {
+ for (by = y0b; by <= y1b; by++) {
+ const int bxs = by * bxs0;
+ for (bx = x0b; bx <= x1b; bx++) {
+ for (bl = listm->block_mob[bx + bxs]; bl != NULL; bl = bl->next) {
+ const int x = bl->x;
+ const int y = bl->y;
+ if (x >= x0 && x <= x1 && y >= y0 && y <= y1) {
+ if (map->bl_list_count >= map->bl_list_size)
+ map_bl_list_expand();
map->bl_list[map->bl_list_count++] = bl;
found++;
}
- va_end(args);
- } else {
- map->bl_list[map->bl_list_count++] = bl;
- found++;
}
}
}
}
}
}
-
return found;
}
@@ -853,6 +910,9 @@ static int bl_vgetall_inshootrange(struct block_list *bl, va_list args)
struct block_list *center = va_arg(args, struct block_list*);
#ifdef CIRCULAR_AREA
int range = va_arg(args, int);
+ nullpo_ret(center);
+ nullpo_ret(bl);
+
if (!check_distance_bl(center, bl, range))
return 0;
#endif
@@ -1040,6 +1100,9 @@ static int bl_vgetall_inmovearea(struct block_list *bl, va_list args)
struct block_list *center = va_arg(args, struct block_list*);
int range = va_arg(args, int);
+ nullpo_ret(bl);
+ nullpo_ret(center);
+
if ((dx > 0 && bl->x < center->x - range + dx) ||
(dx < 0 && bl->x > center->x + range + dx) ||
(dy > 0 && bl->y < center->y - range + dy) ||
@@ -1202,11 +1265,15 @@ static int bl_vgetall_inpath(struct block_list *bl, va_list args)
int len_limit = va_arg(args, int);
int magnitude2 = va_arg(args, int);
- int xi = bl->x;
- int yi = bl->y;
+ int xi;
+ int yi;
int xu, yu;
+ int k;
- int k = ( xi - x0 ) * ( x1 - x0 ) + ( yi - y0 ) * ( y1 - y0 );
+ nullpo_ret(bl);
+ xi = bl->x;
+ yi = bl->y;
+ k = ( xi - x0 ) * ( x1 - x0 ) + ( yi - y0 ) * ( y1 - y0 );
if ( k < 0 || k > len_limit ) //Since more skills use this, check for ending point as well.
return 0;
@@ -1421,6 +1488,9 @@ int map_searchrandfreecell(int16 m, const struct block_list *bl, int16 *x, int16
int free_cell,i,j;
int free_cells[9][2];
+ nullpo_ret(x);
+ nullpo_ret(y);
+
for(free_cell=0,i=-1;i<=1;i++){
if(i+*y<0 || i+*y>=map->list[m].ys)
continue;
@@ -1467,6 +1537,9 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1
int rx2 = 2*rx+1;
int ry2 = 2*ry+1;
+ nullpo_ret(x);
+ nullpo_ret(y);
+
if( !src && (!(flag&1) || flag&2) )
{
ShowDebug("map_search_freecell: Incorrect usage! When src is NULL, flag has to be &1 and can't have &2\n");
@@ -1477,6 +1550,7 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1
bx = *x;
by = *y;
} else {
+ nullpo_ret(src);
bx = src->x;
by = src->y;
m = src->m;
@@ -1533,10 +1607,15 @@ int map_search_freecell(struct block_list *src, int16 m, int16 *x,int16 *y, int1
bool map_closest_freecell(int16 m, const struct block_list *bl, int16 *x, int16 *y, int type, int flag)
{
uint8 dir = 6;
- int16 tx = *x;
- int16 ty = *y;
+ int16 tx;
+ int16 ty;
int costrange = 10;
+ nullpo_ret(x);
+ nullpo_ret(y);
+ tx = *x;
+ ty = *y;
+
if(!map->count_oncell(m, tx, ty, type, flag))
return true; //Current cell is free
@@ -1657,7 +1736,7 @@ int map_addflooritem(const struct block_list *bl, struct item *item_data, int am
/**
* @see DBCreateData
*/
-DBData create_charid2nick(DBKey key, va_list args)
+struct DBData create_charid2nick(union DBKey key, va_list args)
{
struct charid2nick *p;
CREATE(p, struct charid2nick, 1);
@@ -1694,7 +1773,7 @@ void map_delnickdb(int charid, const char* name)
{
struct charid2nick* p;
struct charid_request* req;
- DBData data;
+ struct DBData data;
if (!map->nick_db->remove(map->nick_db, DB->i2key(charid), &data) || (p = DB->data2ptr(&data)) == NULL)
return;
@@ -1793,6 +1872,8 @@ void map_deliddb(struct block_list *bl)
int map_quit(struct map_session_data *sd) {
int i;
+ nullpo_ret(sd);
+
if(!sd->state.active) { //Removing a player that is not active.
struct auth_node *node = chrif->search(sd->status.account_id);
if (node && node->char_id == sd->status.char_id &&
@@ -1849,6 +1930,7 @@ int map_quit(struct map_session_data *sd) {
case SC_GDSKILL_REGENERATION:
if( !sd->sc.data[i]->val4 )
break;
+ FALLTHROUGH
default:
status_change_end(&sd->bl, (sc_type)i, INVALID_TIMER);
}
@@ -2166,9 +2248,9 @@ struct map_session_data * map_nick2sd(const char *nick)
/*==========================================
* Convext Mirror
*------------------------------------------*/
-struct mob_data * map_getmob_boss(int16 m)
+struct mob_data *map_getmob_boss(int16 m)
{
- DBIterator* iter;
+ struct DBIterator *iter;
struct mob_data *md = NULL;
bool found = false;
@@ -2230,11 +2312,11 @@ uint32 map_race_id2mask(int race)
/// Applies func to all the players in the db.
/// Stops iterating if func returns -1.
-void map_vforeachpc(int (*func)(struct map_session_data* sd, va_list args), va_list args) {
- DBIterator* iter;
- struct map_session_data* sd;
+void map_vforeachpc(int (*func)(struct map_session_data* sd, va_list args), va_list args)
+{
+ struct DBIterator *iter = db_iterator(map->pc_db);
+ struct map_session_data *sd = NULL;
- iter = db_iterator(map->pc_db);
for( sd = dbi_first(iter); dbi_exists(iter); sd = dbi_next(iter) )
{
va_list argscopy;
@@ -2262,11 +2344,11 @@ void map_foreachpc(int (*func)(struct map_session_data* sd, va_list args), ...)
/// Applies func to all the mobs in the db.
/// Stops iterating if func returns -1.
-void map_vforeachmob(int (*func)(struct mob_data* md, va_list args), va_list args) {
- DBIterator* iter;
- struct mob_data* md;
+void map_vforeachmob(int (*func)(struct mob_data* md, va_list args), va_list args)
+{
+ struct DBIterator *iter = db_iterator(map->mobid_db);
+ struct mob_data *md = NULL;
- iter = db_iterator(map->mobid_db);
for (md = dbi_first(iter); dbi_exists(iter); md = dbi_next(iter)) {
va_list argscopy;
int ret;
@@ -2293,11 +2375,11 @@ void map_foreachmob(int (*func)(struct mob_data* md, va_list args), ...) {
/// Applies func to all the npcs in the db.
/// Stops iterating if func returns -1.
-void map_vforeachnpc(int (*func)(struct npc_data* nd, va_list args), va_list args) {
- DBIterator* iter;
- struct block_list* bl;
+void map_vforeachnpc(int (*func)(struct npc_data* nd, va_list args), va_list args)
+{
+ struct DBIterator *iter = db_iterator(map->id_db);
+ struct block_list *bl = NULL;
- iter = db_iterator(map->id_db);
for (bl = dbi_first(iter); dbi_exists(iter); bl = dbi_next(iter)) {
if (bl->type == BL_NPC) {
struct npc_data *nd = BL_UCAST(BL_NPC, bl);
@@ -2327,11 +2409,11 @@ void map_foreachnpc(int (*func)(struct npc_data* nd, va_list args), ...) {
/// Applies func to everything in the db.
/// Stops iterating gif func returns -1.
-void map_vforeachregen(int (*func)(struct block_list* bl, va_list args), va_list args) {
- DBIterator* iter;
- struct block_list* bl;
+void map_vforeachregen(int (*func)(struct block_list* bl, va_list args), va_list args)
+{
+ struct DBIterator *iter = db_iterator(map->regen_db);
+ struct block_list *bl = NULL;
- iter = db_iterator(map->regen_db);
for (bl = dbi_first(iter); dbi_exists(iter); bl = dbi_next(iter)) {
va_list argscopy;
int ret;
@@ -2358,11 +2440,11 @@ void map_foreachregen(int (*func)(struct block_list* bl, va_list args), ...) {
/// Applies func to everything in the db.
/// Stops iterating if func returns -1.
-void map_vforeachiddb(int (*func)(struct block_list* bl, va_list args), va_list args) {
- DBIterator* iter;
- struct block_list* bl;
+void map_vforeachiddb(int (*func)(struct block_list* bl, va_list args), va_list args)
+{
+ struct DBIterator *iter = db_iterator(map->id_db);
+ struct block_list *bl = NULL;
- iter = db_iterator(map->id_db);
for (bl = dbi_first(iter); dbi_exists(iter); bl = dbi_next(iter)) {
va_list argscopy;
int ret;
@@ -2389,11 +2471,10 @@ void map_foreachiddb(int (*func)(struct block_list* bl, va_list args), ...) {
/// Iterator.
/// Can filter by bl type.
-struct s_mapiterator
-{
- enum e_mapitflags flags;// flags for special behaviour
- enum bl_type types;// what bl types to return
- DBIterator* dbi;// database iterator
+struct s_mapiterator {
+ enum e_mapitflags flags; ///< flags for special behaviour
+ enum bl_type types; ///< what bl types to return
+ struct DBIterator *dbi; ///< database iterator
};
/// Returns true if the block_list matches the description in the iterator.
@@ -2547,6 +2628,7 @@ bool map_addnpc(int16 m,struct npc_data *nd) {
// Returns the index of successful, or -1 if the list was full.
int map_addmobtolist(unsigned short m, struct spawn_data *spawn) {
int i;
+ nullpo_retr(-1, spawn);
ARR_FIND( 0, MAX_MOB_LIST_PER_MAP, i, map->list[m].moblist[i] == NULL );
if( i < MAX_MOB_LIST_PER_MAP ) {
map->list[m].moblist[i] = spawn;
@@ -2628,6 +2710,7 @@ int map_removemobs_timer(int tid, int64 tick, int id, intptr_t data) {
}
void map_removemobs(int16 m) {
+ Assert_retv(m >= 0 && m < map->count);
if (map->list[m].mob_delete_timer != INVALID_TIMER) // should never happen
return; //Mobs are already scheduled for removal
@@ -2662,6 +2745,8 @@ int16 map_mapindex2mapid(unsigned short map_index) {
int map_mapname2ipport(unsigned short name, uint32* ip, uint16* port) {
struct map_data_other_server *mdos;
+ nullpo_retr(-1, ip);
+ nullpo_retr(-1, port);
mdos = (struct map_data_other_server*)uidb_get(map->map_db,(unsigned int)name);
if(mdos==NULL || mdos->cell) //If gat isn't null, this is a local map.
return -1;
@@ -2737,11 +2822,19 @@ uint8 map_calc_dir(struct block_list* src, int16 x, int16 y)
*------------------------------------------*/
int map_random_dir(struct block_list *bl, int16 *x, int16 *y)
{
- short xi = *x-bl->x;
- short yi = *y-bl->y;
+ short xi;
+ short yi;
short i=0;
- int dist2 = xi*xi + yi*yi;
- short dist = (short)sqrt((float)dist2);
+ int dist2;
+ short dist;
+
+ nullpo_ret(bl);
+ nullpo_ret(x);
+ nullpo_ret(y);
+ xi = *x-bl->x;
+ yi = *y-bl->y;
+ dist2 = xi*xi + yi*yi;
+ dist = (short)sqrt((float)dist2);
if (dist < 1) dist =1;
@@ -2794,7 +2887,10 @@ int map_cell2gat(struct mapcell cell) {
return 1; // default to 'wall'
}
void map_cellfromcache(struct map_data *m) {
- struct map_cache_map_info *info = (struct map_cache_map_info *)m->cellPos;
+ struct map_cache_map_info *info;
+
+ nullpo_retv(m);
+ info = (struct map_cache_map_info *)m->cellPos;
if (info) {
char decode_buffer[MAX_MAP_SIZE];
@@ -2804,7 +2900,7 @@ void map_cellfromcache(struct map_data *m) {
size = (unsigned long)info->xs*(unsigned long)info->ys;
// TO-DO: Maybe handle the scenario, if the decoded buffer isn't the same size as expected? [Shinryo]
- decode_zip(decode_buffer, &size, m->cellPos+sizeof(struct map_cache_map_info), info->len);
+ grfio->decode_zip(decode_buffer, &size, m->cellPos+sizeof(struct map_cache_map_info), info->len);
CREATE(m->cell, struct mapcell, size);
// Set cell properties
@@ -2897,6 +2993,7 @@ int map_getcellp(struct map_data* m, const struct block_list *bl, int16 x, int16
/* [Ind/Hercules] */
int map_sub_getcellp(struct map_data* m, const struct block_list *bl, int16 x, int16 y, cell_chk cellchk) {
+ nullpo_ret(m);
map->cellfromcache(m);
m->getcellp = map->getcellp;
m->setcell = map->setcell;
@@ -2963,6 +3060,9 @@ void map_setgatcell(int16 m, int16 x, int16 y, int gat) {
*------------------------------------------*/
void map_iwall_nextxy(int16 x, int16 y, int8 dir, int pos, int16 *x1, int16 *y1)
{
+ nullpo_retv(x1);
+ nullpo_retv(y1);
+
if( dir == 0 || dir == 4 )
*x1 = x; // Keep X
else if( dir > 0 && dir < 4 )
@@ -3022,12 +3122,15 @@ bool map_iwall_set(int16 m, int16 x, int16 y, int size, int8 dir, bool shootable
return true;
}
-void map_iwall_get(struct map_session_data *sd) {
+void map_iwall_get(struct map_session_data *sd)
+{
struct iwall_data *iwall;
- DBIterator* iter;
+ struct DBIterator *iter;
int16 x1, y1;
int i;
+ nullpo_retv(sd);
+
if( map->list[sd->bl.m].iwall_num < 1 )
return;
@@ -3068,7 +3171,7 @@ void map_iwall_remove(const char *wall_name)
/**
* @see DBCreateData
*/
-DBData create_map_data_other_server(DBKey key, va_list args)
+struct DBData create_map_data_other_server(union DBKey key, va_list args)
{
struct map_data_other_server *mdos;
unsigned short map_index = (unsigned short)key.ui;
@@ -3103,9 +3206,10 @@ int map_setipport(unsigned short map_index, uint32 ip, uint16 port)
* Delete all the other maps server management
* @see DBApply
*/
-int map_eraseallipport_sub(DBKey key, DBData *data, va_list va)
+int map_eraseallipport_sub(union DBKey key, struct DBData *data, va_list va)
{
struct map_data_other_server *mdos = DB->data2ptr(data);
+ nullpo_ret(mdos);
if(mdos->cell == NULL) {
db_remove(map->map_db,key);
aFree(mdos);
@@ -3192,6 +3296,9 @@ int map_readfromcache(struct map_data *m, char *buffer) {
struct map_cache_map_info *info = NULL;
char *p = buffer + sizeof(struct map_cache_main_header);
+ nullpo_ret(m);
+ nullpo_ret(buffer);
+
for(i = 0; i < header->map_count; i++) {
info = (struct map_cache_map_info *)p;
@@ -3226,22 +3333,46 @@ int map_readfromcache(struct map_data *m, char *buffer) {
return 0; // Not found
}
-int map_addmap(const char* mapname) {
+/**
+ * Adds a new empty map to the map list.
+ *
+ * Assumes that there's enough space in the map list.
+ *
+ * @param mapname The new map's name.
+ * @return success state.
+ */
+int map_addmap(const char *mapname)
+{
map->list[map->count].instance_id = -1;
mapindex->getmapname(mapname, map->list[map->count++].name);
return 0;
}
-void map_delmapid(int id) {
+/**
+ * Removes a map from the map list.
+ *
+ * @param id The map ID.
+ */
+void map_delmapid(int id)
+{
+ Assert_retv(id >= 0 && id < map->count);
ShowNotice("Removing map [ %s ] from maplist"CL_CLL"\n",map->list[id].name);
memmove(map->list+id, map->list+id+1, sizeof(map->list[0])*(map->count-id-1));
map->count--;
}
-int map_delmap(char* mapname) {
+/**
+ * Removes a map fromt he map list.
+ *
+ * @param mapname The name of the map to remove.
+ * @return the number of removed maps.
+ */
+int map_delmap(const char *mapname)
+{
int i;
char map_name[MAP_NAME_LENGTH];
+ nullpo_ret(mapname);
if (strcmpi(mapname, "all") == 0) {
map->count = 0;
return 0;
@@ -3263,6 +3394,8 @@ int map_delmap(char* mapname) {
void map_zone_clear_single(struct map_zone_data *zone) {
int i;
+ nullpo_retv(zone);
+
for(i = 0; i < zone->disabled_skills_count; i++) {
aFree(zone->disabled_skills[i]);
}
@@ -3300,9 +3433,10 @@ void map_zone_clear_single(struct map_zone_data *zone) {
/**
*
**/
-void map_zone_db_clear(void) {
- struct map_zone_data *zone;
- DBIterator *iter = db_iterator(map->zone_db);
+void map_zone_db_clear(void)
+{
+ struct DBIterator *iter = db_iterator(map->zone_db);
+ struct map_zone_data *zone = NULL;
for(zone = dbi_first(iter); dbi_exists(iter); zone = dbi_next(iter)) {
map->zone_clear_single(zone);
@@ -3319,6 +3453,7 @@ void map_zone_db_clear(void) {
}
void map_clean(int i) {
int v;
+ Assert_retv(i >= 0 && i < map->count);
if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf) aFree(map->list[i].cell);
if(map->list[i].block) aFree(map->list[i].block);
if(map->list[i].block_mob) aFree(map->list[i].block_mob);
@@ -3515,16 +3650,18 @@ void map_flags_init(void) {
int map_waterheight(char* mapname)
{
char fn[256];
- char *rsw, *found;
+ char *rsw = NULL;
+ const char *found;
+ nullpo_retr(NO_WATER, mapname);
//Look up for the rsw
snprintf(fn, sizeof(fn), "data\\%s.rsw", mapname);
- if ( (found = grfio_find_file(fn)) )
+ if ((found = grfio->find_file(fn)))
safestrncpy(fn, found, sizeof(fn)); // replace with real name
// read & convert fn
- rsw = (char *) grfio_read (fn);
+ rsw = grfio_read(fn);
if (rsw) {
//Load water height from file
int wh = (int) *(float*)(rsw+166);
@@ -3545,9 +3682,10 @@ int map_readgat (struct map_data* m)
int water_height;
size_t xy, off, num_cells;
+ nullpo_ret(m);
sprintf(filename, "data\\%s.gat", m->name);
- gat = (uint8 *) grfio_read(filename);
+ gat = grfio_read(filename);
if (gat == NULL)
return 0;
@@ -3582,10 +3720,12 @@ int map_readgat (struct map_data* m)
* Add/Remove map to the map_db
*--------------------------------------*/
void map_addmap2db(struct map_data *m) {
+ nullpo_retv(m);
map->index2mapid[m->index] = m->m;
}
void map_removemapdb(struct map_data *m) {
+ nullpo_retv(m);
map->index2mapid[m->index] = -1;
}
@@ -3600,8 +3740,8 @@ int map_readallmaps (void) {
if( map->enable_grf )
ShowStatus("Loading maps (using GRF files)...\n");
else {
- char mapcachefilepath[254];
- sprintf(mapcachefilepath,"%s/%s%s",map->db_path,DBPATH,"map_cache.dat");
+ char mapcachefilepath[256];
+ snprintf(mapcachefilepath, 256, "%s/%s%s", map->db_path, DBPATH, "map_cache.dat");
ShowStatus("Loading maps (using %s as map cache)...\n", mapcachefilepath);
if( (fp = fopen(mapcachefilepath, "rb")) == NULL ) {
ShowFatalError("Unable to open map cache file "CL_WHITE"%s"CL_RESET"\n", mapcachefilepath);
@@ -3683,177 +3823,387 @@ int map_readallmaps (void) {
return 0;
}
-/*==========================================
- * Read map server configuration files (conf/map_server.conf...)
- *------------------------------------------*/
-int map_config_read(char *cfgName) {
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
+/**
+ * Reads 'map_configuration/console' and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool map_config_read_console(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
- fp = fopen(cfgName,"r");
- if( fp == NULL ) {
- ShowError("Map configuration file not found at: %s\n", cfgName);
- return 1;
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "map_configuration/console")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration/console was not found in %s!\n", filename);
+ return false;
}
- while (fgets(line, sizeof(line), fp)) {
- char* ptr;
+ libconfig->setting_lookup_bool_real(setting, "stdout_with_ansisequence", &showmsg->stdout_with_ansisequence);
+ if (libconfig->setting_lookup_int(setting, "console_silent", &showmsg->silent) == CONFIG_TRUE) {
+ if (showmsg->silent) // only bother if its actually enabled
+ ShowInfo("Console Silent Setting: %d\n", showmsg->silent);
+ }
+ libconfig->setting_lookup_mutable_string(setting, "timestamp_format", showmsg->timestamp_format, sizeof(showmsg->timestamp_format));
+ libconfig->setting_lookup_int(setting, "console_msg_log", &showmsg->console_log);
- if (line[0] == '/' && line[1] == '/')
- continue;
- if ((ptr = strstr(line, "//")) != NULL)
- *ptr = '\n'; //Strip comments
- if (sscanf(line, "%1023[^:]: %1023[^\t\r\n]", w1, w2) < 2)
- continue;
+ return true;
+}
- //Strip trailing spaces
- ptr = w2 + strlen(w2);
- while (--ptr >= w2 && *ptr == ' ');
- ptr++;
- *ptr = '\0';
-
- if(strcmpi(w1,"timestamp_format")==0)
- safestrncpy(showmsg->timestamp_format, w2, 20);
- else if(strcmpi(w1,"stdout_with_ansisequence")==0)
- showmsg->stdout_with_ansisequence = config_switch(w2) ? true : false;
- else if(strcmpi(w1,"console_silent")==0) {
- showmsg->silent = atoi(w2);
- if (showmsg->silent) // only bother if its actually enabled
- ShowInfo("Console Silent Setting: %d\n", atoi(w2));
- } else if (strcmpi(w1, "userid")==0)
- chrif->setuserid(w2);
- else if (strcmpi(w1, "passwd") == 0)
- chrif->setpasswd(w2);
- else if (strcmpi(w1, "char_ip") == 0)
- map->char_ip_set = chrif->setip(w2);
- else if (strcmpi(w1, "char_port") == 0)
- chrif->setport(atoi(w2));
- else if (strcmpi(w1, "map_ip") == 0)
- map->ip_set = clif->setip(w2);
- else if (strcmpi(w1, "bind_ip") == 0)
- clif->setbindip(w2);
- else if (strcmpi(w1, "map_port") == 0) {
- clif->setport(atoi(w2));
- map->port = (atoi(w2));
- } else if (strcmpi(w1, "map") == 0)
- map->count++;
- else if (strcmpi(w1, "delmap") == 0)
- map->count--;
- else if (strcmpi(w1, "npc") == 0)
- npc->addsrcfile(w2);
- else if (strcmpi(w1, "delnpc") == 0)
- npc->delsrcfile(w2);
- else if (strcmpi(w1, "autosave_time") == 0) {
- map->autosave_interval = atoi(w2);
- if (map->autosave_interval < 1) //Revert to default saving.
- map->autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
- else
- map->autosave_interval *= 1000; //Pass from sec to ms
- } else if (strcmpi(w1, "minsave_time") == 0) {
- map->minsave_interval= atoi(w2);
- if (map->minsave_interval < 1)
- map->minsave_interval = 1;
- } else if (strcmpi(w1, "save_settings") == 0)
- map->save_settings = atoi(w2);
- else if (strcmpi(w1, "help_txt") == 0)
- strcpy(map->help_txt, w2);
- else if (strcmpi(w1, "help2_txt") == 0)
- strcpy(map->help2_txt, w2);
- else if (strcmpi(w1, "charhelp_txt") == 0)
- strcpy(map->charhelp_txt, w2);
- else if(strcmpi(w1,"db_path") == 0)
- safestrncpy(map->db_path,w2,255);
- else if (strcmpi(w1, "enable_spy") == 0)
- map->enable_spy = config_switch(w2);
- else if (strcmpi(w1, "use_grf") == 0)
- map->enable_grf = config_switch(w2);
- else if (strcmpi(w1, "console_msg_log") == 0)
- showmsg->console_log = atoi(w2);//[Ind]
- else if (strcmpi(w1, "default_language") == 0)
- safestrncpy(map->default_lang_str, w2, sizeof(map->default_lang_str));
- else if (strcmpi(w1, "import") == 0)
- map->config_read(w2);
+/**
+ * Reads 'map_configuration/sql_connection' and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool map_config_read_connection(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "map_configuration/sql_connection")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration/sql_connection was not found in %s!\n", filename);
+ ShowWarning("map_config_read_connection: Defaulting sql_connection...\n");
+ return false;
+ }
+
+ libconfig->setting_lookup_int(setting, "db_port", &map->server_port);
+ libconfig->setting_lookup_mutable_string(setting, "db_hostname", map->server_ip, sizeof(map->server_ip));
+ libconfig->setting_lookup_mutable_string(setting, "db_username", map->server_id, sizeof(map->server_id));
+ libconfig->setting_lookup_mutable_string(setting, "db_password", map->server_pw, sizeof(map->server_pw));
+ libconfig->setting_lookup_mutable_string(setting, "db_database", map->server_db, sizeof(map->server_db));
+ libconfig->setting_lookup_mutable_string(setting, "default_codepage", map->default_codepage, sizeof(map->default_codepage));
+ return true;
+}
+
+/**
+ * Reads 'map_configuration/inter' and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool map_config_read_inter(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
+ const char *str = NULL;
+ char temp[24];
+ uint16 port;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "map_configuration/inter")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration/inter was not found in %s!\n", filename);
+ return false;
+ }
+
+ // Login information
+ if (libconfig->setting_lookup_mutable_string(setting, "userid", temp, sizeof(temp)) == CONFIG_TRUE)
+ chrif->setuserid(temp);
+ if (libconfig->setting_lookup_mutable_string(setting, "passwd", temp, sizeof(temp)) == CONFIG_TRUE)
+ chrif->setpasswd(temp);
+
+ // Char and map-server information
+ if (libconfig->setting_lookup_string(setting, "char_ip", &str) == CONFIG_TRUE)
+ map->char_ip_set = chrif->setip(str);
+ if (libconfig->setting_lookup_uint16(setting, "char_port", &port) == CONFIG_TRUE)
+ chrif->setport(port);
+
+ if (libconfig->setting_lookup_string(setting, "map_ip", &str) == CONFIG_TRUE)
+ map->ip_set = clif->setip(str);
+ if (libconfig->setting_lookup_uint16(setting, "map_port", &port) == CONFIG_TRUE) {
+ clif->setport(port);
+ map->port = port;
+ }
+ if (libconfig->setting_lookup_string(setting, "bind_ip", &str) == CONFIG_TRUE)
+ clif->setbindip(str);
+
+ return true;
+}
+
+/**
+ * Reads 'map_configuration/database' and initializes required variables
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool map_config_read_database(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "map_configuration/database")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration/database was not found in %s!\n", filename);
+ return false;
+ }
+ libconfig->setting_lookup_mutable_string(setting, "db_path", map->db_path, sizeof(map->db_path));
+ libconfig->setting_lookup_int(setting, "save_settings", &map->save_settings);
+
+ if (libconfig->setting_lookup_int(setting, "autosave_time", &map->autosave_interval) == CONFIG_TRUE) {
+ if (map->autosave_interval < 1) // Revert to default saving
+ map->autosave_interval = DEFAULT_AUTOSAVE_INTERVAL;
else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ map->autosave_interval *= 1000; // Pass from s to ms
+ }
+ if (libconfig->setting_lookup_int(setting, "minsave_time", &map->minsave_interval) == CONFIG_TRUE) {
+ if (map->minsave_interval < 1)
+ map->minsave_interval = 1;
}
- fclose(fp);
- return 0;
+ return true;
}
-int map_config_read_sub(char *cfgName) {
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
- fp = fopen(cfgName,"r");
- if (fp == NULL) {
- ShowError("Map configuration file not found at: %s\n", cfgName);
- return 1;
+/**
+ * Reads 'map_configuration/map_list'/'map_configuration/map_removed' and adds
+ * or removes maps from map-server.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool map_config_read_map_list(const char *filename, struct config_t *config, bool imported)
+{
+ struct config_setting_t *setting = NULL;
+ int i, count = 0;
+ struct DBMap *deleted_maps;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ deleted_maps = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_ALLOW_NULL_DATA, MAP_NAME_LENGTH);
+
+ // Remove maps
+ if ((setting = libconfig->lookup(config, "map_configuration/map_removed")) != NULL) {
+ count = libconfig->setting_length(setting);
+ for (i = 0; i < count; i++) {
+ const char *mapname;
+
+ if ((mapname = libconfig->setting_get_string_elem(setting, i)) == NULL || mapname[0] == '\0')
+ continue;
+
+ strdb_put(deleted_maps, mapname, NULL);
+
+ if (imported) // Map list is empty on the first run, only do this for imported files.
+ map->delmap(mapname);
+ }
+ }
+
+ if ((setting = libconfig->lookup(config, "map_configuration/map_list")) == NULL) {
+ db_destroy(deleted_maps);
+ if (imported)
+ return true;
+ ShowError("map_config_read_map_list: map_configuration/map_list was not found in %s!\n", filename);
+ return false;
+ }
+
+ // Add maps to map->list
+ count = libconfig->setting_length(setting);
+
+ if (count <= 0) {
+ db_destroy(deleted_maps);
+ if (imported)
+ return true;
+ ShowWarning("map_config_read_map_list: no maps found in %s!\n", filename);
+ return false;
}
- while (fgets(line, sizeof(line), fp)) {
- char* ptr;
+ RECREATE(map->list, struct map_data, map->count + count); // TODO: VECTOR candidate
+
+ for (i = 0; i < count; i++) {
+ const char *mapname;
- if (line[0] == '/' && line[1] == '/')
+ if ((mapname = libconfig->setting_get_string_elem(setting, i)) == NULL || mapname[0] == '\0')
continue;
- if ((ptr = strstr(line, "//")) != NULL)
- *ptr = '\n'; //Strip comments
- if (sscanf(line, "%1023[^:]: %1023[^\t\r\n]", w1, w2) < 2)
+
+ if (strdb_exists(deleted_maps, mapname))
continue;
- //Strip trailing spaces
- ptr = w2 + strlen(w2);
- while (--ptr >= w2 && *ptr == ' ');
- ptr++;
- *ptr = '\0';
+ map->addmap(mapname);
+ }
+
+ RECREATE(map->list, struct map_data, map->count);
+
+ db_destroy(deleted_maps);
+ return true;
+}
+
+/**
+ * Reads map-server configuration files (map-server.conf) and initialises
+ * required variables.
+ *
+ * @param filename Path to configuration file.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool map_config_read(const char *filename, bool imported)
+{
+ struct config_t config;
+ struct config_setting_t *setting = NULL;
+ const char *import = NULL;
+ bool retval = true;
+
+ nullpo_retr(false, filename);
+
+ if (!libconfig->load_file(&config, filename))
+ return false;
+
+ if ((setting = libconfig->lookup(&config, "map_configuration")) == NULL) {
+ libconfig->destroy(&config);
+ if (imported)
+ return true;
+ ShowError("map_config_read: map_configuration was not found in %s!\n", filename);
+ return false;
+ }
- if (strcmpi(w1, "map") == 0)
- map->addmap(w2);
- else if (strcmpi(w1, "delmap") == 0)
- map->delmap(w2);
- else if (strcmpi(w1, "import") == 0)
- map->config_read_sub(w2);
+ libconfig->setting_lookup_mutable_string(setting, "help_txt", map->help_txt, sizeof(map->help_txt));
+ libconfig->setting_lookup_mutable_string(setting, "charhelp_txt", map->charhelp_txt, sizeof(map->charhelp_txt));
+ libconfig->setting_lookup_bool(setting, "enable_spy", &map->enable_spy);
+ libconfig->setting_lookup_bool(setting, "use_grf", &map->enable_grf);
+ libconfig->setting_lookup_mutable_string(setting, "default_language", map->default_lang_str, sizeof(map->default_lang_str));
+
+ if (!map_config_read_console(filename, &config, imported))
+ retval = false;
+ if (!map_config_read_connection(filename, &config, imported))
+ retval = false;
+ if (!map_config_read_inter(filename, &config, imported))
+ retval = false;
+ if (!map_config_read_database(filename, &config, imported))
+ retval = false;
+ if (!map_config_read_map_list(filename, &config, imported))
+ retval = false;
+
+ // import should overwrite any previous configuration, so it should be called last
+ if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
+ if (strcmp(import, filename) == 0 || strcmp(import, map->MAP_CONF_NAME) == 0) {
+ ShowWarning("map_config_read: Loop detected! Skipping 'import'...\n");
+ } else {
+ if (!map->config_read(import, true))
+ retval = false;
+ }
}
- fclose(fp);
- return 0;
+ libconfig->destroy(&config);
+ return retval;
}
-void map_reloadnpc_sub(char *cfgName) {
- char line[1024], w1[1024], w2[1024];
- FILE *fp;
- fp = fopen(cfgName,"r");
- if (fp == NULL) {
- ShowError("Map configuration file not found at: %s\n", cfgName);
- return;
+/**
+ * Reads 'npc_global_list'/'npc_removed_list' and adds or removes NPC sources
+ * from map-server.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool map_read_npclist(const char *filename, bool imported)
+{
+ struct config_t config;
+ struct config_setting_t *setting = NULL;
+ const char *import = NULL;
+ bool retval = true;
+ bool remove_all = false;
+
+ struct DBMap *deleted_npcs;
+
+ nullpo_retr(false, filename);
+
+ if (!libconfig->load_file(&config, filename))
+ return false;
+
+ deleted_npcs = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_ALLOW_NULL_DATA, 0);
+
+ // Remove NPCs
+ if ((setting = libconfig->lookup(&config, "npc_removed_list")) != NULL) {
+ int i, del_count = libconfig->setting_length(setting);
+ for (i = 0; i < del_count; i++) {
+ const char *scriptname;
+
+ if ((scriptname = libconfig->setting_get_string_elem(setting, i)) == NULL || scriptname[0] == '\0')
+ continue;
+
+ if (strcmp(scriptname, "all") == 0) {
+ remove_all = true;
+ npc->clearsrcfile();
+ } else {
+ strdb_put(deleted_npcs, scriptname, NULL);
+ npc->delsrcfile(scriptname);
+ }
+ }
}
- while (fgets(line, sizeof(line), fp)) {
- char* ptr;
+ if ((setting = libconfig->lookup(&config, "npc_global_list")) != NULL) {
+ int i, count = libconfig->setting_length(setting);
+ if (count <= 0) {
+ if (!imported) {
+ ShowWarning("map_read_npclist: no NPCs found in %s!\n", filename);
+ retval = false;
+ }
+ }
+ for (i = 0; i < count; i++) {
+ const char *scriptname;
+
+ if ((scriptname = libconfig->setting_get_string_elem(setting, i)) == NULL || scriptname[0] == '\0')
+ continue;
- if (line[0] == '/' && line[1] == '/')
- continue;
- if ((ptr = strstr(line, "//")) != NULL)
- *ptr = '\n'; //Strip comments
- if (sscanf(line, "%1023[^:]: %1023[^\t\r\n]", w1, w2) < 2)
- continue;
+ if (remove_all || strdb_exists(deleted_npcs, scriptname))
+ continue;
- //Strip trailing spaces
- ptr = w2 + strlen(w2);
- while (--ptr >= w2 && *ptr == ' ');
- ptr++;
- *ptr = '\0';
-
- if (strcmpi(w1, "npc") == 0)
- npc->addsrcfile(w2);
- else if (strcmpi(w1, "import") == 0)
- map->reloadnpc_sub(w2);
- else if (strcmpi(w1, "delnpc") == 0)
- npc->delsrcfile(w2);
- else
- ShowWarning("Unknown setting '%s' in file %s\n", w1, cfgName);
+ npc->addsrcfile(scriptname);
+ }
+ } else {
+ ShowError("map_read_npclist: npc_global_list was not found in %s!\n", filename);
+ retval = false;
+ }
+
+ db_destroy(deleted_npcs);
+
+ // import should overwrite any previous configuration, so it should be called last
+ if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
+ const char *base_npclist = NULL;
+#ifdef RENEWAL
+ base_npclist = "npc/re/scripts_main.conf";
+#else
+ base_npclist = "npc/pre-re/scripts_main.conf";
+#endif
+ if (strcmp(import, filename) == 0 || strcmp(import, base_npclist) == 0) {
+ ShowWarning("map_read_npclist: Loop detected! Skipping 'import'...\n");
+ } else {
+ if (!map->read_npclist(import, true))
+ retval = false;
+ }
}
- fclose(fp);
+ libconfig->destroy(&config);
+ return retval;
}
/**
@@ -3864,12 +4214,12 @@ void map_reloadnpc_sub(char *cfgName) {
void map_reloadnpc(bool clear) {
int i;
if (clear)
- npc->addsrcfile("clear"); // this will clear the current script list
+ npc->clearsrcfile();
#ifdef RENEWAL
- map->reloadnpc_sub("npc/re/scripts_main.conf");
+ map->read_npclist("npc/re/scripts_main.conf", false);
#else
- map->reloadnpc_sub("npc/pre-re/scripts_main.conf");
+ map->read_npclist("npc/pre-re/scripts_main.conf", false);
#endif
// Append extra scripts
@@ -3878,62 +4228,126 @@ void map_reloadnpc(bool clear) {
}
}
-int inter_config_read(char *cfgName) {
- char line[1024],w1[1024],w2[1024];
- FILE *fp;
+/**
+ * Reads inter-server.conf and initializes required variables.
+ *
+ * @param filename Path to configuration file
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool inter_config_read(const char *filename, bool imported)
+{
+ struct config_t config;
+ const struct config_setting_t *setting = NULL;
+ const char *import = NULL;
+ bool retval = true;
- if (!(fp = fopen(cfgName,"r"))) {
- ShowError("File not found: %s\n",cfgName);
- return 1;
+ nullpo_retr(false, filename);
+
+ if (!libconfig->load_file(&config, filename))
+ return false;
+
+ if ((setting = libconfig->lookup(&config, "inter_configuration")) == NULL) {
+ libconfig->destroy(&config);
+ if (imported)
+ return true;
+ ShowError("inter_config_read: inter_configuration was not found in %s!\n", filename);
+ return false;
}
- while (fgets(line, sizeof(line), fp)) {
- if (line[0] == '/' && line[1] == '/')
- continue;
- if (sscanf(line,"%1023[^:]: %1023[^\r\n]", w1, w2) < 2)
- continue;
- /* map sql stuff */
- if(strcmpi(w1,"map_server_ip")==0)
- safestrncpy(map->server_ip, w2, sizeof(map->server_ip));
- else if(strcmpi(w1,"map_server_port")==0)
- map->server_port=atoi(w2);
- else if(strcmpi(w1,"map_server_id")==0)
- safestrncpy(map->server_id, w2, sizeof(map->server_id));
- else if(strcmpi(w1,"map_server_pw")==0)
- safestrncpy(map->server_pw, w2, sizeof(map->server_pw));
- else if(strcmpi(w1,"map_server_db")==0)
- safestrncpy(map->server_db, w2, sizeof(map->server_db));
- else if(strcmpi(w1,"default_codepage")==0)
- safestrncpy(map->default_codepage, w2, sizeof(map->default_codepage));
- else if(strcmpi(w1,"autotrade_merchants_db")==0)
- safestrncpy(map->autotrade_merchants_db, w2, sizeof(map->autotrade_merchants_db));
- else if(strcmpi(w1,"autotrade_data_db")==0)
- safestrncpy(map->autotrade_data_db, w2, sizeof(map->autotrade_data_db));
- else if(strcmpi(w1,"npc_market_data_db")==0)
- safestrncpy(map->npc_market_data_db, w2, sizeof(map->npc_market_data_db));
- /* sql log db */
- else if(strcmpi(w1,"log_db_ip")==0)
- safestrncpy(logs->db_ip, w2, sizeof(logs->db_ip));
- else if(strcmpi(w1,"log_db_id")==0)
- safestrncpy(logs->db_id, w2, sizeof(logs->db_id));
- else if(strcmpi(w1,"log_db_pw")==0)
- safestrncpy(logs->db_pw, w2, sizeof(logs->db_pw));
- else if(strcmpi(w1,"log_db_port")==0)
- logs->db_port = atoi(w2);
- else if(strcmpi(w1,"log_db_db")==0)
- safestrncpy(logs->db_name, w2, sizeof(logs->db_name));
- /* mapreg */
- else if( mapreg->config_read(w1,w2) )
- continue;
- /* import */
- else if(strcmpi(w1,"import")==0)
- map->inter_config_read(w2);
- else
- HPM->parseConf(w1, w2, HPCT_MAP_INTER);
+ if (!map->inter_config_read_database_names(filename, &config, imported))
+ retval = false;
+ if (!map->inter_config_read_connection(filename, &config, imported))
+ retval = false;
+
+ if (!HPM->parse_conf(&config, filename, HPCT_MAP_INTER, imported))
+ retval = false;
+
+ // import should overwrite any previous configuration, so it should be called last
+ if (libconfig->lookup_string(&config, "import", &import) == CONFIG_TRUE) {
+ if (strcmp(import, filename) == 0 || strcmp(import, map->INTER_CONF_NAME) == 0) {
+ ShowWarning("inter_config_read: Loop detected in %s! Skipping 'import'...\n", filename);
+ } else {
+ if (!map->inter_config_read(import, true))
+ retval = false;
+ }
}
- fclose(fp);
- return 0;
+ libconfig->destroy(&config);
+ return retval;
+}
+
+/**
+ * Reads the 'inter_configuration/log/sql_connection' config entry and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool inter_config_read_connection(const char *filename, const struct config_t *config, bool imported)
+{
+ const struct config_setting_t *setting = NULL;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "inter_configuration/log/sql_connection")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("inter_config_read: inter_configuration/log/sql_connection was not found in %s!\n", filename);
+ return false;
+ }
+
+ libconfig->setting_lookup_int(setting, "db_port", &logs->db_port);
+ libconfig->setting_lookup_mutable_string(setting, "db_hostname", logs->db_ip, sizeof(logs->db_ip));
+ libconfig->setting_lookup_mutable_string(setting, "db_username", logs->db_id, sizeof(logs->db_id));
+ libconfig->setting_lookup_mutable_string(setting, "db_password", logs->db_pw, sizeof(logs->db_pw));
+ libconfig->setting_lookup_mutable_string(setting, "db_database", logs->db_name, sizeof(logs->db_name));
+
+ return true;
+}
+
+/**
+ * Reads the 'inter_configuration/database_names' config entry and initializes required variables.
+ *
+ * @param filename Path to configuration file (used in error and warning messages).
+ * @param config The current config being parsed.
+ * @param imported Whether the current config is imported from another file.
+ *
+ * @retval false in case of error.
+ */
+bool inter_config_read_database_names(const char *filename, const struct config_t *config, bool imported)
+{
+ const struct config_setting_t *setting = NULL;
+ bool retval = true;
+
+ nullpo_retr(false, filename);
+ nullpo_retr(false, config);
+
+ if ((setting = libconfig->lookup(config, "inter_configuration/database_names")) == NULL) {
+ if (imported)
+ return true;
+ ShowError("inter_config_read: inter_configuration/database_names was not found in %s!\n", filename);
+ return false;
+ }
+
+ libconfig->setting_lookup_mutable_string(setting, "autotrade_merchants_db", map->autotrade_merchants_db, sizeof(map->autotrade_merchants_db));
+ libconfig->setting_lookup_mutable_string(setting, "autotrade_data_db", map->autotrade_data_db, sizeof(map->autotrade_data_db));
+ libconfig->setting_lookup_mutable_string(setting, "npc_market_data_db", map->npc_market_data_db, sizeof(map->npc_market_data_db));
+
+ if (!mapreg->config_read(filename, setting, imported))
+ retval = false;
+
+ if ((setting = libconfig->lookup(config, "inter_configuration/database_names/registry")) == NULL) {
+ if (imported)
+ return retval;
+ ShowError("inter_config_read: inter_configuration/database_names/registry was not found in %s!\n", filename);
+ return false;
+ }
+ return retval;
}
/*=======================================
@@ -3979,7 +4393,10 @@ struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone
struct map_zone_data *zone = NULL;
int cursor, i, j;
- sprintf(newzone, "%s+%s",main->name,other->name);
+ nullpo_retr(NULL, main);
+ nullpo_retr(NULL, other);
+
+ snprintf(newzone, MAP_ZONE_NAME_LENGTH, "%s+%s", main->name, other->name);
if( (zone = strdb_get(map->zone_db, newzone)) )
return zone;/* this zone has already been merged */
@@ -4072,6 +4489,7 @@ void map_zone_change2(int m, struct map_zone_data *zone)
{
const char *empty = "";
+ Assert_retv(m >= 0 && m < map->count);
if( map->list[m].zone == zone )
return;
@@ -4089,6 +4507,7 @@ void map_zone_change2(int m, struct map_zone_data *zone)
}
/* when changing from a mapflag to another during runtime */
void map_zone_change(int m, struct map_zone_data *zone, const char* start, const char* buffer, const char* filepath) {
+ Assert_retv(m >= 0 && m < map->count);
map->list[m].prev_zone = map->list[m].zone;
if( map->list[m].zone_mf_count )
@@ -4101,6 +4520,7 @@ void map_zone_remove(int m)
char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
unsigned short k;
const char *empty = "";
+ Assert_retv(m >= 0 && m < map->count);
for(k = 0; k < map->list[m].zone_mf_count; k++) {
size_t len = strlen(map->list[m].zone_mf[k]),j;
params[0] = '\0';
@@ -4123,6 +4543,7 @@ void map_zone_remove(int m)
map->list[m].zone_mf_count = 0;
}
static inline void map_zone_mf_cache_add(int m, char *rflag) {
+ Assert_retv(m >= 0 && m < map->count);
RECREATE(map->list[m].zone_mf, char *, ++map->list[m].zone_mf_count);
CREATE(map->list[m].zone_mf[map->list[m].zone_mf_count - 1], char, MAP_ZONE_MAPFLAG_LENGTH);
safestrncpy(map->list[m].zone_mf[map->list[m].zone_mf_count - 1], rflag, MAP_ZONE_MAPFLAG_LENGTH);
@@ -4133,6 +4554,10 @@ bool map_zone_mf_cache(int m, char *flag, char *params) {
char rflag[MAP_ZONE_MAPFLAG_LENGTH];
int state = 1;
+ nullpo_retr(false, flag);
+ nullpo_retr(false, params);
+ Assert_retr(false, m >= 0 && m < map->count);
+
if (params[0] != '\0' && !strcmpi(params, "off"))
state = 0;
@@ -4829,6 +5254,8 @@ void map_zone_apply(int m, struct map_zone_data *zone, const char* start, const
int i;
const char *empty = "";
char flag[MAP_ZONE_MAPFLAG_LENGTH], params[MAP_ZONE_MAPFLAG_LENGTH];
+ Assert_retv(m >= 0 && m < map->count);
+ nullpo_retv(zone);
map->list[m].zone = zone;
for(i = 0; i < zone->mapflags_count; i++) {
size_t len = strlen(zone->mapflags[i]);
@@ -4939,8 +5366,9 @@ unsigned short map_zone_str2skillid(const char *name) {
enum bl_type map_zone_bl_type(const char *entry, enum map_zone_skill_subtype *subtype) {
char temp[200], *parse;
enum bl_type bl = BL_NUL;
- *subtype = MZS_NONE;
+ nullpo_retr(BL_NUL, subtype);
+ *subtype = MZS_NONE;
if( !entry )
return BL_NUL;
@@ -4982,27 +5410,27 @@ enum bl_type map_zone_bl_type(const char *entry, enum map_zone_skill_subtype *su
}
/* [Ind/Hercules] */
void read_map_zone_db(void) {
- config_t map_zone_db;
- config_setting_t *zones = NULL;
+ struct config_t map_zone_db;
+ struct config_setting_t *zones = NULL;
/* TODO: #ifndef required for re/pre-re */
#ifdef RENEWAL
const char *config_filename = "db/re/map_zone_db.conf"; // FIXME hardcoded name
#else
const char *config_filename = "db/pre-re/map_zone_db.conf"; // FIXME hardcoded name
#endif
- if (libconfig->read_file(&map_zone_db, config_filename))
+ if (!libconfig->load_file(&map_zone_db, config_filename))
return;
zones = libconfig->lookup(&map_zone_db, "zones");
if (zones != NULL) {
struct map_zone_data *zone;
- config_setting_t *zone_e;
- config_setting_t *skills;
- config_setting_t *items;
- config_setting_t *mapflags;
- config_setting_t *commands;
- config_setting_t *caps;
+ struct config_setting_t *zone_e;
+ struct config_setting_t *skills;
+ struct config_setting_t *items;
+ struct config_setting_t *mapflags;
+ struct config_setting_t *commands;
+ struct config_setting_t *caps;
const char *name;
const char *zonename;
int i,h,v,j;
@@ -5017,7 +5445,7 @@ void read_map_zone_db(void) {
zone_e = libconfig->setting_get_elem(zones, i);
if (!libconfig->setting_lookup_string(zone_e, "name", &zonename)) {
- ShowError("map_zone_db: missing zone name, skipping... (%s:%d)\n",
+ ShowError("map_zone_db: missing zone name, skipping... (%s:%u)\n",
config_setting_source_file(zone_e), config_setting_source_line(zone_e));
libconfig->setting_remove_elem(zones,i);/* remove from the tree */
--zone_count;
@@ -5054,7 +5482,7 @@ void read_map_zone_db(void) {
disabled_skills_count = libconfig->setting_length(skills);
/* validate */
for(h = 0; h < libconfig->setting_length(skills); h++) {
- config_setting_t *skillinfo = libconfig->setting_get_elem(skills, h);
+ struct config_setting_t *skillinfo = libconfig->setting_get_elem(skills, h);
name = config_setting_name(skillinfo);
if( !map->zone_str2skillid(name) ) {
ShowError("map_zone_db: unknown skill (%s) in disabled_skills for zone '%s', skipping skill...\n",name,zone->name);
@@ -5069,7 +5497,7 @@ void read_map_zone_db(void) {
/* all ok, process */
CREATE( zone->disabled_skills, struct map_zone_disabled_skill_entry *, disabled_skills_count );
for(h = 0, v = 0; h < libconfig->setting_length(skills); h++) {
- config_setting_t *skillinfo = libconfig->setting_get_elem(skills, h);
+ struct config_setting_t *skillinfo = libconfig->setting_get_elem(skills, h);
struct map_zone_disabled_skill_entry * entry;
enum bl_type type;
name = config_setting_name(skillinfo);
@@ -5092,7 +5520,7 @@ void read_map_zone_db(void) {
disabled_items_count = libconfig->setting_length(items);
/* validate */
for(h = 0; h < libconfig->setting_length(items); h++) {
- config_setting_t *item = libconfig->setting_get_elem(items, h);
+ struct config_setting_t *item = libconfig->setting_get_elem(items, h);
name = config_setting_name(item);
if( !map->zone_str2itemid(name) ) {
ShowError("map_zone_db: unknown item (%s) in disabled_items for zone '%s', skipping item...\n",name,zone->name);
@@ -5111,7 +5539,7 @@ void read_map_zone_db(void) {
CREATE(zone->cant_disable_items, int, zone->cant_disable_items_count);
}
for(h = 0, v = 0, j = 0; h < libconfig->setting_length(items); h++) {
- config_setting_t *item = libconfig->setting_get_elem(items, h);
+ struct config_setting_t *item = libconfig->setting_get_elem(items, h);
name = config_setting_name(item);
if( libconfig->setting_get_bool(item) ) { /* only add if enabled */
@@ -5143,7 +5571,7 @@ void read_map_zone_db(void) {
disabled_commands_count = libconfig->setting_length(commands);
/* validate */
for(h = 0; h < libconfig->setting_length(commands); h++) {
- config_setting_t *command = libconfig->setting_get_elem(commands, h);
+ struct config_setting_t *command = libconfig->setting_get_elem(commands, h);
name = config_setting_name(command);
if( !atcommand->exists(name) ) {
ShowError("map_zone_db: unknown command '%s' in disabled_commands for zone '%s', skipping entry...\n",name,zone->name);
@@ -5158,7 +5586,7 @@ void read_map_zone_db(void) {
/* all ok, process */
CREATE( zone->disabled_commands, struct map_zone_disabled_command_entry *, disabled_commands_count );
for(h = 0, v = 0; h < libconfig->setting_length(commands); h++) {
- config_setting_t *command = libconfig->setting_get_elem(commands, h);
+ struct config_setting_t *command = libconfig->setting_get_elem(commands, h);
struct map_zone_disabled_command_entry * entry;
int group_lv;
name = config_setting_name(command);
@@ -5179,7 +5607,7 @@ void read_map_zone_db(void) {
capped_skills_count = libconfig->setting_length(caps);
/* validate */
for(h = 0; h < libconfig->setting_length(caps); h++) {
- config_setting_t *cap = libconfig->setting_get_elem(caps, h);
+ struct config_setting_t *cap = libconfig->setting_get_elem(caps, h);
name = config_setting_name(cap);
if( !map->zone_str2skillid(name) ) {
ShowError("map_zone_db: unknown skill (%s) in skill_damage_cap for zone '%s', skipping skill...\n",name,zone->name);
@@ -5194,7 +5622,7 @@ void read_map_zone_db(void) {
/* all ok, process */
CREATE( zone->capped_skills, struct map_zone_skill_damage_cap_entry *, capped_skills_count );
for(h = 0, v = 0; h < libconfig->setting_length(caps); h++) {
- config_setting_t *cap = libconfig->setting_get_elem(caps, h);
+ struct config_setting_t *cap = libconfig->setting_get_elem(caps, h);
struct map_zone_skill_damage_cap_entry * entry;
enum bl_type type;
name = config_setting_name(cap);
@@ -5219,8 +5647,8 @@ void read_map_zone_db(void) {
/* process inheritance, aka loop through the whole thing again :P */
for (i = 0; i < zone_count; ++i) {
- config_setting_t *inherit_tree = NULL;
- config_setting_t *new_entry = NULL;
+ struct config_setting_t *inherit_tree = NULL;
+ struct config_setting_t *new_entry = NULL;
int inherit_count;
zone_e = libconfig->setting_get_elem(zones, i);
@@ -5278,7 +5706,7 @@ void read_map_zone_db(void) {
for(j = 0; j < disabled_skills_count_i; j++) {
int k;
for(k = 0; k < disabled_skills_count; k++) {
- config_setting_t *skillinfo = libconfig->setting_get_elem(skills, k);
+ struct config_setting_t *skillinfo = libconfig->setting_get_elem(skills, k);
if( map->zone_str2skillid(config_setting_name(skillinfo)) == izone->disabled_skills[j]->nameid ) {
break;
}
@@ -5302,7 +5730,7 @@ void read_map_zone_db(void) {
for(j = 0; j < disabled_items_count_i; j++) {
int k;
for(k = 0; k < disabled_items_count; k++) {
- config_setting_t *item = libconfig->setting_get_elem(items, k);
+ struct config_setting_t *item = libconfig->setting_get_elem(items, k);
name = config_setting_name(item);
@@ -5348,7 +5776,7 @@ void read_map_zone_db(void) {
for(j = 0; j < disabled_commands_count_i; j++) {
int k;
for(k = 0; k < disabled_commands_count; k++) {
- config_setting_t *command = libconfig->setting_get_elem(commands, k);
+ struct config_setting_t *command = libconfig->setting_get_elem(commands, k);
if( atcommand->exists(config_setting_name(command))->func == izone->disabled_commands[j]->cmd ) {
break;
}
@@ -5372,7 +5800,7 @@ void read_map_zone_db(void) {
for(j = 0; j < capped_skills_count_i; j++) {
int k;
for(k = 0; k < capped_skills_count; k++) {
- config_setting_t *cap = libconfig->setting_get_elem(caps, k);
+ struct config_setting_t *cap = libconfig->setting_get_elem(caps, k);
if( map->zone_str2skillid(config_setting_name(cap)) == izone->capped_skills[j]->nameid ) {
break;
}
@@ -5414,6 +5842,8 @@ int map_get_new_bonus_id (void) {
void map_add_questinfo(int m, struct questinfo *qi) {
unsigned short i;
+ nullpo_retv(qi);
+ Assert_retv(m >= 0 && m < map->count);
/* duplicate, override */
for(i = 0; i < map->list[m].qi_count; i++) {
if( map->list[m].qi_data[i].nd == qi->nd )
@@ -5429,6 +5859,7 @@ void map_add_questinfo(int m, struct questinfo *qi) {
bool map_remove_questinfo(int m, struct npc_data *nd) {
unsigned short i;
+ Assert_retr(false, m >= 0 && m < map->count);
for(i = 0; i < map->list[m].qi_count; i++) {
struct questinfo *qi = &map->list[m].qi_data[i];
if( qi->nd == nd ) {
@@ -5445,7 +5876,8 @@ bool map_remove_questinfo(int m, struct npc_data *nd) {
/**
* @see DBApply
*/
-int map_db_final(DBKey key, DBData *data, va_list ap) {
+int map_db_final(union DBKey key, struct DBData *data, va_list ap)
+{
struct map_data_other_server *mdos = DB->data2ptr(data);
if(mdos && iMalloc->verify_ptr(mdos) && mdos->cell == NULL)
@@ -5457,7 +5889,7 @@ int map_db_final(DBKey key, DBData *data, va_list ap) {
/**
* @see DBApply
*/
-int nick_db_final(DBKey key, DBData *data, va_list args)
+int nick_db_final(union DBKey key, struct DBData *data, va_list args)
{
struct charid2nick* p = DB->data2ptr(data);
struct charid_request* req;
@@ -5504,7 +5936,8 @@ int cleanup_sub(struct block_list *bl, va_list ap) {
/**
* @see DBApply
*/
-int cleanup_db_sub(DBKey key, DBData *data, va_list va) {
+int cleanup_db_sub(union DBKey key, struct DBData *data, va_list va)
+{
return map->cleanup_sub(DB->data2ptr(data), va);
}
@@ -5585,8 +6018,8 @@ int do_final(void) {
map->map_db->destroy(map->map_db, map->db_final);
mapindex->final();
- if(map->enable_grf)
- grfio_final();
+ if (map->enable_grf)
+ grfio->final();
db_destroy(map->id_db);
db_destroy(map->pc_db);
@@ -5910,22 +6343,6 @@ static CMDLINEARG(loadscript)
}
/**
- * --generate-translations
- *
- * Creates "./generated_translations.pot"
- * @see cmdline->exec
- **/
-static CMDLINEARG(generatetranslations) {
- script->lang_export_file = aStrdup("./generated_translations.pot");
-
- if( !(script->lang_export_fp = fopen(script->lang_export_file,"wb")) ) {
- ShowError("export-dialog: failed to open '%s' for writing\n",script->lang_export_file);
- }
- core->runflag = CORE_ST_STOP;
- return true;
-}
-
-/**
* Defines the local command line arguments
*/
void cmdline_args_init_local(void)
@@ -5941,7 +6358,6 @@ void cmdline_args_init_local(void)
CMDLINEARG_DEF2(log-config, logconfig, "Alternative logging configuration.", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM);
CMDLINEARG_DEF2(script-check, scriptcheck, "Doesn't run the server, only tests the scripts passed through --load-script.", CMDLINE_OPT_SILENT);
CMDLINEARG_DEF2(load-script, loadscript, "Loads an additional script (can be repeated).", CMDLINE_OPT_NORMAL|CMDLINE_OPT_PARAM);
- CMDLINEARG_DEF2(generate-translations, generatetranslations, "Creates './generated_translations.pot' file with all translateable strings from scripts, server terminates afterwards.", CMDLINE_OPT_NORMAL);
}
int do_init(int argc, char *argv[])
@@ -5955,12 +6371,12 @@ int do_init(int argc, char *argv[])
map_load_defaults();
- map->INTER_CONF_NAME = aStrdup("conf/inter-server.conf");
- map->LOG_CONF_NAME = aStrdup("conf/logs.conf");
- map->MAP_CONF_NAME = aStrdup("conf/map-server.conf");
- map->BATTLE_CONF_FILENAME = aStrdup("conf/battle.conf");
+ map->INTER_CONF_NAME = aStrdup("conf/common/inter-server.conf");
+ map->LOG_CONF_NAME = aStrdup("conf/map/logs.conf");
+ map->MAP_CONF_NAME = aStrdup("conf/map/map-server.conf");
+ map->BATTLE_CONF_FILENAME = aStrdup("conf/map/battle.conf");
map->ATCOMMAND_CONF_FILENAME = aStrdup("conf/atcommand.conf");
- map->SCRIPT_CONF_NAME = aStrdup("conf/script.conf");
+ map->SCRIPT_CONF_NAME = aStrdup("conf/map/script.conf");
map->MSG_CONF_NAME = aStrdup("conf/messages.conf");
map->GRF_PATH_FILENAME = aStrdup("conf/grf-files.txt");
@@ -5973,10 +6389,30 @@ int do_init(int argc, char *argv[])
cmdline->exec(argc, argv, CMDLINE_OPT_NORMAL);
minimal = map->minimal;/* temp (perhaps make minimal a mask with options of what to load? e.g. plugin 1 does minimal |= mob_db; */
if (!minimal) {
- map->config_read(map->MAP_CONF_NAME);
- CREATE(map->list,struct map_data,map->count);
- map->count = 0;
- map->config_read_sub(map->MAP_CONF_NAME);
+ map->config_read(map->MAP_CONF_NAME, false);
+
+ {
+ // TODO: Remove this when no longer needed.
+#define CHECK_OLD_LOCAL_CONF(oldname, newname) do { \
+ if (stat((oldname), &fileinfo) == 0 && fileinfo.st_size > 0) { \
+ ShowWarning("An old configuration file \"%s\" was found.\n", (oldname)); \
+ ShowWarning("If it contains settings you wish to keep, please merge them into \"%s\".\n", (newname)); \
+ ShowWarning("Otherwise, just delete it.\n"); \
+ ShowInfo("Resuming in 10 seconds...\n"); \
+ HSleep(10); \
+ } \
+} while (0)
+ struct stat fileinfo;
+
+ CHECK_OLD_LOCAL_CONF("conf/import/map_conf.txt", "conf/import/map-server.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/inter_conf.txt", "conf/import/inter-server.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/log_conf.txt", "conf/import/logs.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/script_conf.txt", "conf/import/script.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/packet_conf.txt", "conf/import/socket.conf");
+ CHECK_OLD_LOCAL_CONF("conf/import/battle_conf.txt", "conf/import/battle.conf");
+
+#undef CHECK_OLD_LOCAL_CONF
+ }
// loads npcs
map->reloadnpc(false);
@@ -5987,7 +6423,9 @@ int do_init(int argc, char *argv[])
char ip_str[16];
sockt->ip2str(sockt->addr_[0], ip_str);
- ShowWarning("Not all IP addresses in /conf/map-server.conf configured, auto-detecting...\n");
+#ifndef BUILDBOT
+ ShowWarning("Not all IP addresses in /conf/map/map-server.conf configured, auto-detecting...\n");
+#endif
if (sockt->naddr_ == 0)
ShowError("Unable to determine your IP address...\n");
@@ -6002,12 +6440,12 @@ int do_init(int argc, char *argv[])
chrif->setip(ip_str);
}
- battle->config_read(map->BATTLE_CONF_FILENAME);
+ battle->config_read(map->BATTLE_CONF_FILENAME, false);
atcommand->msg_read(map->MSG_CONF_NAME, false);
- map->inter_config_read(map->INTER_CONF_NAME);
- logs->config_read(map->LOG_CONF_NAME);
+ map->inter_config_read(map->INTER_CONF_NAME, false);
+ logs->config_read(map->LOG_CONF_NAME, false);
}
- script->config_read(map->SCRIPT_CONF_NAME);
+ script->config_read(map->SCRIPT_CONF_NAME, false);
map->id_db = idb_alloc(DB_OPT_BASE);
map->pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map->id2sd() use. [Skotlex]
@@ -6045,8 +6483,8 @@ int do_init(int argc, char *argv[])
}
}
- if(map->enable_grf)
- grfio_init(map->GRF_PATH_FILENAME);
+ if (map->enable_grf)
+ grfio->init(map->GRF_PATH_FILENAME);
map->readallmaps();
@@ -6151,7 +6589,6 @@ void map_defaults(void) {
sprintf(map->db_path ,"db");
sprintf(map->help_txt ,"conf/help.txt");
- sprintf(map->help2_txt ,"conf/help2.txt");
sprintf(map->charhelp_txt ,"conf/charhelp.txt");
sprintf(map->wisp_server_name ,"Server"); // can be modified in char-server configuration file
@@ -6164,12 +6601,12 @@ void map_defaults(void) {
map->night_flag = 0; // 0=day, 1=night [Yor]
map->enable_spy = 0; //To enable/disable @spy commands, which consume too much cpu time when sending packets. [Skotlex]
- map->INTER_CONF_NAME="conf/inter-server.conf";
- map->LOG_CONF_NAME="conf/logs.conf";
- map->MAP_CONF_NAME = "conf/map-server.conf";
- map->BATTLE_CONF_FILENAME = "conf/battle.conf";
+ map->INTER_CONF_NAME="conf/common/inter-server.conf";
+ map->LOG_CONF_NAME="conf/map/logs.conf";
+ map->MAP_CONF_NAME = "conf/map/map-server.conf";
+ map->BATTLE_CONF_FILENAME = "conf/map/battle.conf";
map->ATCOMMAND_CONF_FILENAME = "conf/atcommand.conf";
- map->SCRIPT_CONF_NAME = "conf/script.conf";
+ map->SCRIPT_CONF_NAME = "conf/map/script.conf";
map->MSG_CONF_NAME = "conf/messages.conf";
map->GRF_PATH_FILENAME = "conf/grf-files.txt";
@@ -6375,9 +6812,10 @@ void map_defaults(void) {
map->readgat = map_readgat;
map->readallmaps = map_readallmaps;
map->config_read = map_config_read;
- map->config_read_sub = map_config_read_sub;
- map->reloadnpc_sub = map_reloadnpc_sub;
+ map->read_npclist = map_read_npclist;
map->inter_config_read = inter_config_read;
+ map->inter_config_read_database_names = inter_config_read_database_names;
+ map->inter_config_read_connection = inter_config_read_connection;
map->sql_init = map_sql_init;
map->sql_close = map_sql_close;
map->zone_mf_cache = map_zone_mf_cache;