diff options
58 files changed, 569 insertions, 197 deletions
diff --git a/script-checker b/script-checker new file mode 100755 index 000000000..521cf9025 --- /dev/null +++ b/script-checker @@ -0,0 +1,25 @@ +#!/bin/bash + +# Copyright (c) Hercules Dev Team, licensed under GNU GPL. +# See the LICENSE file +# Base Author: Haru @ http://hercules.ws + +ORIG_CWD="$(pwd)" +BASEDIR="$(dirname "$0")" +EXECUTABLE="./map-server" + +cd "${BASEDIR}" +if [ -z "$1" ]; then + echo "No file specified." + echo "Usage: $0 <path to the script>" + echo " (you may use a relative or absolute path)" + exit -1 +elif [[ "$1" =~ ^\/ ]]; then + FILE="$1" +else + FILE="${ORIG_CWD}/$1" +fi +if [ ! -x "$EXECUTABLE" ]; then + exit -1 +fi +"$EXECUTABLE" --script-check "${FILE}" 2>&1 diff --git a/script-checker.bat b/script-checker.bat new file mode 100644 index 000000000..e05eda64e --- /dev/null +++ b/script-checker.bat @@ -0,0 +1,29 @@ +@ECHO OFF + +REM Copyright (c) Hercules Dev Team, licensed under GNU GPL. +REM See the LICENSE file +REM Base Author: Mumbles @ http://hercules.ws + +COLOR 0F + +ECHO. +ECHO Hercules Development Team presents +ECHO _ _ _ +ECHO ^| ^| ^| ^| ^| ^| +ECHO ^| ^|_^| ^| ___ _ __ ___ _ _^| ^| ___ ___ +ECHO ^| _ ^|/ _ \ '__/ __^| ^| ^| ^| ^|/ _ \/ __^| +ECHO ^| ^| ^| ^| __/ ^| ^| (__^| ^|_^| ^| ^| __/\__ \ +ECHO \_^| ^|_/\___^|_^| \___^|\__,_^|_^|\___^|^|___/ +ECHO. +ECHO Script Syntax Checker +ECHO http://hercules.ws/board/ +ECHO. +ECHO Drag and drop or input manually +ECHO. +ECHO. + +:LOOP + SET /P SCRIPT="Enter path/to/your/script.txt: " %=% + map-server.exe --script-check %SCRIPT% + ECHO. +GOTO LOOP diff --git a/src/common/core.c b/src/common/core.c index 6a73d2d39..f57cc4c79 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -302,10 +302,20 @@ int main (int argc, char **argv) { arg_v = argv; } core_defaults(); + + { + int i; + for(i = 0; i < argc; i++) { + if( strcmp(argv[i], "--script-check") == 0 ) { + msg_silent = 0x7; // silence information and status messages + } + } + } iMalloc->init();// needed for Show* in display_title() [FlavioJS] - - console->display_title(); + + if (!(msg_silent&0x1)) + console->display_title(); #ifdef MINICORE // minimalist Core usercheck(); diff --git a/src/common/mapindex.c b/src/common/mapindex.c index 83de21b2b..a95e143c3 100644 --- a/src/common/mapindex.c +++ b/src/common/mapindex.c @@ -21,7 +21,12 @@ int max_index = 0; char mapindex_cfgfile[80] = "db/map_index.txt"; -#define mapindex_exists(id) (indexes[id].name[0] != '\0') +#define mapindex_exists_sub(id) (indexes[id].name[0] != '\0') + +bool mapindex_exists(int id) { + return mapindex_exists_sub(id); +} + /// Retrieves the map name from 'string' (removing .gat extension if present). /// Result gets placed either into 'buf' or in a static local buffer. const char* mapindex_getmapname(const char* string, char* output) { @@ -102,7 +107,7 @@ int mapindex_addmap(int index, const char* name) { return 0; } - if (mapindex_exists(index)) { + if (mapindex_exists_sub(index)) { ShowWarning("(mapindex_add) Overriding index %d: map \"%s\" -> \"%s\"\n", index, indexes[index].name, map_name); strdb_remove(mapindex_db, indexes[index].name); } @@ -129,18 +134,18 @@ unsigned short mapindex_name2id(const char* name) { } const char* mapindex_id2name_sub(unsigned short id,const char *file, int line, const char *func) { - if (id > MAX_MAPINDEX || !mapindex_exists(id)) { + if (id > MAX_MAPINDEX || !mapindex_exists_sub(id)) { ShowDebug("mapindex_id2name: Requested name for non-existant map index [%d] in cache. %s:%s:%d\n", id,file,func,line); return indexes[0].name; // dummy empty string so that the callee doesn't crash } return indexes[id].name; } -void mapindex_init(void) { +int mapindex_init(void) { FILE *fp; char line[1024]; int last_index = -1; - int index; + int index, total = 0; char map_name[12]; if( ( fp = fopen(mapindex_cfgfile,"r") ) == NULL ){ @@ -158,6 +163,7 @@ void mapindex_init(void) { index = last_index+1; case 2: //Map with ID given mapindex_addmap(index,map_name); + total++; break; default: continue; @@ -169,6 +175,7 @@ void mapindex_init(void) { if( !strdb_iget(mapindex_db, MAP_DEFAULT) ) { ShowError("mapindex_init: MAP_DEFAULT '%s' not found in cache! update mapindex.h MAP_DEFAULT var!!!\n",MAP_DEFAULT); } + return total; } int mapindex_removemap(int index){ diff --git a/src/common/mapindex.h b/src/common/mapindex.h index 43953a8e0..646f73f18 100644 --- a/src/common/mapindex.h +++ b/src/common/mapindex.h @@ -56,12 +56,13 @@ extern char mapindex_cfgfile[80]; #define MAP_MALAYA "malaya" #define MAP_ECLAGE "eclage" +bool mapindex_exists(int id); const char* mapindex_getmapname(const char* string, char* output); const char* mapindex_getmapname_ext(const char* string, char* output); unsigned short mapindex_name2id(const char*); #define mapindex_id2name(n) mapindex_id2name_sub(n,__FILE__, __LINE__, __func__) const char* mapindex_id2name_sub(unsigned short,const char *file, int line, const char *func); -void mapindex_init(void); +int mapindex_init(void); void mapindex_final(void); int mapindex_addmap(int index, const char* name); diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 7e5d42e69..20fcdd79c 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -10151,7 +10151,10 @@ void atcommand_doload(void) { atcommand->config_read(map->ATCOMMAND_CONF_FILENAME); } -void do_init_atcommand(void) { +void do_init_atcommand(bool minimal) { + if (minimal) + return; + atcommand->at_symbol = '@'; atcommand->char_symbol = '#'; atcommand->binding_count = 0; diff --git a/src/map/atcommand.h b/src/map/atcommand.h index e4c66df40..6b5a52fcb 100644 --- a/src/map/atcommand.h +++ b/src/map/atcommand.h @@ -77,7 +77,7 @@ struct atcommand_interface { /* */ char* msg_table[MAX_MSG]; // Server messages (0-499 reserved for GM commands, 500-999 reserved for others) /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ bool (*parse) (const int fd, struct map_session_data* sd, const char* message, int type); diff --git a/src/map/battle.c b/src/map/battle.c index 499b7e3a0..9a70acaca 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -6759,7 +6759,10 @@ int battle_config_read(const char* cfgName) return 0; } -void do_init_battle(void) { +void do_init_battle(bool minimal) { + if (minimal) + return; + battle->delay_damage_ers = ers_new(sizeof(struct delay_damage),"battle.c::delay_damage_ers",ERS_OPT_CLEAR); timer->add_func_list(battle->delay_damage_sub, "battle_delay_damage_sub"); diff --git a/src/map/battle.h b/src/map/battle.h index bf08ab8d6..0f3a22c4b 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -506,7 +506,7 @@ struct battle_interface { int attr_fix_table[4][ELE_MAX][ELE_MAX]; struct eri *delay_damage_ers; //For battle delay damage structures. /* init */ - void (*init) (void); + void (*init) (bool minimal); /* final */ void (*final) (void); /* damage calculation */ diff --git a/src/map/battleground.c b/src/map/battleground.c index 62688659e..76cf22471 100644 --- a/src/map/battleground.c +++ b/src/map/battleground.c @@ -757,7 +757,10 @@ enum BATTLEGROUNDS_QUEUE_ACK bg_canqueue(struct map_session_data *sd, struct bg_ return BGQA_SUCCESS; } -void do_init_battleground(void) { +void do_init_battleground(bool minimal) { + if (minimal) + return; + bg->team_db = idb_alloc(DB_OPT_RELEASE_DATA); timer->add_func_list(bg->send_xy_timer, "bg_send_xy_timer"); timer->add_interval(timer->gettick() + battle_config.bg_update_interval, bg->send_xy_timer, 0, 0, battle_config.bg_update_interval); diff --git a/src/map/battleground.h b/src/map/battleground.h index a5e540924..fab614d08 100644 --- a/src/map/battleground.h +++ b/src/map/battleground.h @@ -75,7 +75,7 @@ struct battleground_interface { DBMap *team_db; // int bg_id -> struct battleground_data* unsigned int team_counter; // Next bg_id /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ struct bg_arena *(*name2arena) (char *name); diff --git a/src/map/chrif.c b/src/map/chrif.c index a13217060..87ec71ec5 100644 --- a/src/map/chrif.c +++ b/src/map/chrif.c @@ -1611,8 +1611,10 @@ int do_final_chrif(void) { /*========================================== * *------------------------------------------*/ -int do_init_chrif(void) { - +int do_init_chrif(bool minimal) { + if (minimal) + return 0; + chrif->auth_db = idb_alloc(DB_OPT_BASE); chrif->auth_db_ers = ers_new(sizeof(struct auth_node),"chrif.c::auth_db_ers",ERS_OPT_NONE); diff --git a/src/map/chrif.h b/src/map/chrif.h index 9df4b9931..56aa569a3 100644 --- a/src/map/chrif.h +++ b/src/map/chrif.h @@ -63,7 +63,7 @@ struct chrif_interface { int state; /* */ int (*final) (void); - int (*init) (void); + int (*init) (bool minimal); /* funcs */ void (*setuserid) (char* id); void (*setpasswd) (char* pwd); diff --git a/src/map/clif.c b/src/map/clif.c index 913a94058..15d0ce077 100644 --- a/src/map/clif.c +++ b/src/map/clif.c @@ -18046,10 +18046,13 @@ void clif_bc_ready(void) { /*========================================== * *------------------------------------------*/ -int do_init_clif(void) { +int do_init_clif(bool minimal) { const char* colors[COLOR_MAX] = { "0xFF0000", "0x00ff00", "0xffffff" }; int i; + if (minimal) + return 0; + /** * Setup Color Table (saves unnecessary load of strtoul on every call) **/ diff --git a/src/map/clif.h b/src/map/clif.h index cbe3fa857..1710cfc88 100644 --- a/src/map/clif.h +++ b/src/map/clif.h @@ -526,7 +526,7 @@ struct clif_interface { /* */ bool ally_only; /* core */ - int (*init) (void); + int (*init) (bool minimal); void (*final) (void); int (*setip) (const char* ip); void (*setbindip) (const char* ip); diff --git a/src/map/duel.c b/src/map/duel.c index 4e41865d4..5e305244a 100644 --- a/src/map/duel.c +++ b/src/map/duel.c @@ -166,7 +166,10 @@ void duel_reject(const unsigned int did, struct map_session_data* sd) { void do_final_duel(void) { } -void do_init_duel(void) { +void do_init_duel(bool minimal) { + if (minimal) + return; + memset(&duel->list[0], 0, sizeof(duel->list)); } diff --git a/src/map/duel.h b/src/map/duel.h index d1ec58415..d60c9531a 100644 --- a/src/map/duel.h +++ b/src/map/duel.h @@ -34,7 +34,7 @@ struct duel_interface { void (*showinfo) (const unsigned int did, struct map_session_data* sd); int (*checktime) (struct map_session_data* sd); - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); } duel_s; diff --git a/src/map/elemental.c b/src/map/elemental.c index d280f5b81..f335600d6 100644 --- a/src/map/elemental.c +++ b/src/map/elemental.c @@ -931,7 +931,10 @@ void reload_elemental_skilldb(void) { elemental->read_skilldb(); } -int do_init_elemental(void) { +int do_init_elemental(bool minimal) { + if (minimal) + return 0; + elemental->read_db(); elemental->read_skilldb(); diff --git a/src/map/elemental.h b/src/map/elemental.h index 3cd819d53..8ffffa5e3 100644 --- a/src/map/elemental.h +++ b/src/map/elemental.h @@ -73,7 +73,7 @@ struct elemental_interface { struct s_elemental_db db[MAX_ELEMENTAL_CLASS]; // Elemental Database /* */ - int (*init) (void); + int (*init) (bool minimal); void (*final) (void); /* funcs */ bool (*class) (int class_); diff --git a/src/map/guild.c b/src/map/guild.c index 4dcdb6c46..fcdcddab2 100644 --- a/src/map/guild.c +++ b/src/map/guild.c @@ -2172,12 +2172,15 @@ void guild_flags_clear(void) { guild->flags_count = 0; } -void do_init_guild(void) { - guild->db = idb_alloc(DB_OPT_RELEASE_DATA); - guild->castle_db = idb_alloc(DB_OPT_BASE); - guild->expcache_db = idb_alloc(DB_OPT_BASE); - guild->infoevent_db = idb_alloc(DB_OPT_BASE); - guild->expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE); +void do_init_guild(bool minimal) { + if (minimal) + return; + + guild->db = idb_alloc(DB_OPT_RELEASE_DATA); + guild->castle_db = idb_alloc(DB_OPT_BASE); + guild->expcache_db = idb_alloc(DB_OPT_BASE); + guild->infoevent_db = idb_alloc(DB_OPT_BASE); + guild->expcache_ers = ers_new(sizeof(struct guild_expcache),"guild.c::expcache_ers",ERS_OPT_NONE); sv->readdb(map->db_path, "castle_db.txt", ',', 4, 5, -1, guild->read_castledb); diff --git a/src/map/guild.h b/src/map/guild.h index 348a6c7e4..8da9036e6 100644 --- a/src/map/guild.h +++ b/src/map/guild.h @@ -56,7 +56,7 @@ struct s_guild_skill_tree { struct guild_interface { - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ DBMap* db; // int guild_id -> struct guild* diff --git a/src/map/homunculus.c b/src/map/homunculus.c index a7a409011..0a162958a 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -1229,8 +1229,12 @@ void homunculus_skill_reload(void) { homun->skill_db_read(); } -void do_init_homunculus(void) { +void do_init_homunculus(bool minimal) { int class_; + + if (minimal) + return; + homun->read_db(); homun->exp_db_read(); homun->skill_db_read(); diff --git a/src/map/homunculus.h b/src/map/homunculus.h index e3ec38f7b..bf1de6171 100644 --- a/src/map/homunculus.h +++ b/src/map/homunculus.h @@ -91,7 +91,7 @@ struct homunculus_interface { struct s_homunculus_db db[MAX_HOMUNCULUS_CLASS]; struct homun_skill_tree_entry skill_tree[MAX_HOMUNCULUS_CLASS][MAX_SKILL_TREE]; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); void (*reload) (void); void (*reload_skill) (void); diff --git a/src/map/instance.c b/src/map/instance.c index 6b96c3112..ab68c9e22 100644 --- a/src/map/instance.c +++ b/src/map/instance.c @@ -691,7 +691,10 @@ void do_final_instance(void) { instance->instances = 0; } -void do_init_instance(void) { +void do_init_instance(bool minimal) { + if (minimal) + return; + timer->add_func_list(instance->destroy_timer, "instance_destroy_timer"); } diff --git a/src/map/instance.h b/src/map/instance.h index 27a9401b4..4f65d7db0 100644 --- a/src/map/instance.h +++ b/src/map/instance.h @@ -47,7 +47,7 @@ struct instance_data { }; struct instance_interface { - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); void (*reload) (void); /* start point */ diff --git a/src/map/irc-bot.c b/src/map/irc-bot.c index f67446629..0f487d8f7 100644 --- a/src/map/irc-bot.c +++ b/src/map/irc-bot.c @@ -386,7 +386,7 @@ void irc_relay(char *name, const char *msg) { /** * IRC bot initializer */ -void irc_bot_init(void) { +void irc_bot_init(bool minimal) { /// Command handlers const struct irc_func irc_func_base[] = { { "PING" , ircbot->pong }, @@ -399,6 +399,9 @@ void irc_bot_init(void) { struct irc_func* function; int i; + if (minimal) + return; + if( !hChSys.irc ) return; diff --git a/src/map/irc-bot.h b/src/map/irc-bot.h index 52ff0c9be..305cdfd91 100644 --- a/src/map/irc-bot.h +++ b/src/map/irc-bot.h @@ -34,7 +34,7 @@ struct irc_bot_interface { unsigned int size; } funcs; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ int (*parse) (int fd); diff --git a/src/map/itemdb.c b/src/map/itemdb.c index 8dd6e9d9d..d7d117574 100644 --- a/src/map/itemdb.c +++ b/src/map/itemdb.c @@ -1927,7 +1927,7 @@ int itemdb_uid_load() { /*==================================== * read all item-related databases *------------------------------------*/ -void itemdb_read(void) { +void itemdb_read(bool minimal) { int i; DBData prev; @@ -1945,6 +1945,9 @@ void itemdb_read(void) { } } + if (minimal) + return; + itemdb->read_combos(); itemdb->read_groups(); itemdb->read_chains(); @@ -2065,7 +2068,7 @@ void itemdb_reload(void) { db_clear(itemdb->names); // read new data - itemdb->read(); + itemdb->read(false); //Epoque's awesome @reloaditemdb fix - thanks! [Ind] //- Fixes the need of a @reloadmobdb after a @reloaditemdb to re-link monster drop data @@ -2174,12 +2177,16 @@ void do_final_itemdb(void) { db_destroy(itemdb->names); } -void do_init_itemdb(void) { +void do_init_itemdb(bool minimal) { memset(itemdb->array, 0, sizeof(itemdb->array)); itemdb->other = idb_alloc(DB_OPT_BASE); itemdb->names = strdb_alloc(DB_OPT_BASE,ITEM_NAME_LENGTH); itemdb->create_dummy_data(); //Dummy data item. - itemdb->read(); + itemdb->read(minimal); + + if (minimal) + return; + clif->cashshop_load(); } void itemdb_defaults(void) { diff --git a/src/map/itemdb.h b/src/map/itemdb.h index 2579d84ca..80d2fd0ce 100644 --- a/src/map/itemdb.h +++ b/src/map/itemdb.h @@ -266,7 +266,7 @@ struct item_package { #define itemdb_canauction(item, gmlv) itemdb->isrestricted(item , gmlv, 0, itemdb->canauction_sub) struct itemdb_interface { - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); void (*reload) (void); void (*name_constants) (void); @@ -343,7 +343,7 @@ struct itemdb_interface { int (*read_sqldb) (void); uint64 (*unique_id) (int8 flag, int64 value); int (*uid_load) (); - void (*read) (void); + void (*read) (bool minimal); void (*destroy_item_data) (struct item_data *self, int free_self); int (*final_sub) (DBKey key, DBData *data, va_list ap); }; diff --git a/src/map/map.c b/src/map/map.c index 781cc0ff9..cd192b7d4 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -2905,7 +2905,7 @@ int map_readfromcache(struct map_data *m, char *buffer) { } -int map_addmap(char* mapname) { +int map_addmap(const char* mapname) { map->list[map->count].instance_id = -1; mapindex_getmapname(mapname, map->list[map->count++].name); return 0; @@ -5419,6 +5419,8 @@ void map_load_defaults(void) { } int do_init(int argc, char *argv[]) { + bool minimal = false; + char *scriptcheck = NULL; int i; #ifdef GCOLLECT @@ -5468,6 +5470,11 @@ int do_init(int argc, char *argv[]) map->LOG_CONF_NAME = argv[++i]; } else if( strcmp(arg, "run-once") == 0 ) { // close the map-server as soon as its done.. for testing [Celest] runflag = CORE_ST_STOP; + } else if( strcmp(arg, "script-check") == 0 ) { + minimal = true; + runflag = CORE_ST_STOP; + if( map->arg_next_value(arg, i, argc) ) + scriptcheck = argv[++i]; } else { ShowError("Unknown option '%s'.\n", argv[i]); exit(EXIT_FAILURE); @@ -5489,39 +5496,42 @@ int do_init(int argc, char *argv[]) } map_load_defaults(); - 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); - // loads npcs - map->reloadnpc(false); + 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); - chrif->checkdefaultlogin(); + // loads npcs + map->reloadnpc(false); - if (!map->ip_set || !map->char_ip_set) { - char ip_str[16]; - ip2str(addr_[0], ip_str); + chrif->checkdefaultlogin(); - ShowWarning("Not all IP addresses in /conf/map-server.conf configured, autodetecting...\n"); + if (!map->ip_set || !map->char_ip_set) { + char ip_str[16]; + ip2str(addr_[0], ip_str); - if (naddr_ == 0) - ShowError("Unable to determine your IP address...\n"); - else if (naddr_ > 1) - ShowNotice("Multiple interfaces detected...\n"); + ShowWarning("Not all IP addresses in /conf/map-server.conf configured, autodetecting...\n"); - ShowInfo("Defaulting to %s as our IP address\n", ip_str); + if (naddr_ == 0) + ShowError("Unable to determine your IP address...\n"); + else if (naddr_ > 1) + ShowNotice("Multiple interfaces detected...\n"); - if (!map->ip_set) - clif->setip(ip_str); - if (!map->char_ip_set) - chrif->setip(ip_str); - } + ShowInfo("Defaulting to %s as our IP address\n", ip_str); - battle->config_read(map->BATTLE_CONF_FILENAME); - atcommand->msg_read(map->MSG_CONF_NAME); + if (!map->ip_set) + clif->setip(ip_str); + if (!map->char_ip_set) + chrif->setip(ip_str); + } + + battle->config_read(map->BATTLE_CONF_FILENAME); + atcommand->msg_read(map->MSG_CONF_NAME); + map->inter_config_read(map->INTER_CONF_NAME); + logs->config_read(map->LOG_CONF_NAME); + } script->config_read(map->SCRIPT_CONF_NAME); - map->inter_config_read(map->INTER_CONF_NAME); - logs->config_read(map->LOG_CONF_NAME); map->id_db = idb_alloc(DB_OPT_BASE); map->pc_db = idb_alloc(DB_OPT_BASE); //Added for reliable map->id2sd() use. [Skotlex] @@ -5538,53 +5548,77 @@ int do_init(int argc, char *argv[]) map->flooritem_ers = ers_new(sizeof(struct flooritem_data),"map.c::map_flooritem_ers",ERS_OPT_NONE); ers_chunk_size(map->flooritem_ers, 100); - - map->sql_init(); - if (logs->config.sql_logs) - logs->sql_init(); - mapindex_init(); + if (!minimal) { + map->sql_init(); + if (logs->config.sql_logs) + logs->sql_init(); + } + + i = mapindex_init(); + + if (minimal) { + // Pretend all maps from the mapindex are on this mapserver + CREATE(map->list,struct map_data,i); + + for( i = 0; i < MAX_MAPINDEX; i++ ) { + if (mapindex_exists(i)) { + map->addmap(mapindex_id2name(i)); + } + } + } + if(map->enable_grf) grfio_init(map->GRF_PATH_FILENAME); map->readallmaps(); - timer->add_func_list(map->freeblock_timer, "map_freeblock_timer"); - timer->add_func_list(map->clearflooritem_timer, "map_clearflooritem_timer"); - timer->add_func_list(map->removemobs_timer, "map_removemobs_timer"); - timer->add_interval(timer->gettick()+1000, map->freeblock_timer, 0, 0, 60*1000); - - HPM->load_sub = HPM_map_plugin_load_sub; - HPM->symbol_defaults_sub = map_hp_symbols; - HPM->config_read(); - HPM->event(HPET_INIT); - - atcommand->init(); - battle->init(); - instance->init(); - chrif->init(); - clif->init(); - ircbot->init(); - script->init(); - itemdb->init(); - skill->init(); - map->read_zone_db();/* read after item and skill initalization */ - mob->init(); - pc->init(); - status->init(); - party->init(); - guild->init(); - gstorage->init(); - pet->init(); - homun->init(); - mercenary->init(); - elemental->init(); - quest->init(); - npc->init(); - unit->init(); - bg->init(); - duel->init(); - vending->init(); + + if (!minimal) { + timer->add_func_list(map->freeblock_timer, "map_freeblock_timer"); + timer->add_func_list(map->clearflooritem_timer, "map_clearflooritem_timer"); + timer->add_func_list(map->removemobs_timer, "map_removemobs_timer"); + timer->add_interval(timer->gettick()+1000, map->freeblock_timer, 0, 0, 60*1000); + + HPM->load_sub = HPM_map_plugin_load_sub; + HPM->symbol_defaults_sub = map_hp_symbols; + HPM->config_read(); + HPM->event(HPET_INIT); + } + + atcommand->init(minimal); + battle->init(minimal); + instance->init(minimal); + chrif->init(minimal); + clif->init(minimal); + ircbot->init(minimal); + script->init(minimal); + itemdb->init(minimal); + skill->init(minimal); + if (!minimal) + map->read_zone_db();/* read after item and skill initalization */ + mob->init(minimal); + pc->init(minimal); + status->init(minimal); + party->init(minimal); + guild->init(minimal); + gstorage->init(minimal); + pet->init(minimal); + homun->init(minimal); + mercenary->init(minimal); + elemental->init(minimal); + quest->init(minimal); + npc->init(minimal); + unit->init(minimal); + bg->init(minimal); + duel->init(minimal); + vending->init(minimal); + + if (minimal) { + if (npc->parsesrcfile(scriptcheck, false) == 0) + exit(EXIT_SUCCESS); + exit(EXIT_FAILURE); + } npc->event_do_oninit(); // Init npcs (OnInit) diff --git a/src/map/map.h b/src/map/map.h index 6b7d2a630..31ee0ef60 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -1020,7 +1020,7 @@ struct map_interface { int (*eraseallipport_sub) (DBKey key, DBData *data, va_list va); char* (*init_mapcache) (FILE *fp); int (*readfromcache) (struct map_data *m, char *buffer); - int (*addmap) (char *mapname); + int (*addmap) (const char *mapname); void (*delmapid) (int id); void (*zone_db_clear) (void); void (*list_final) (void); diff --git a/src/map/mercenary.c b/src/map/mercenary.c index 5ea10dc66..87e7d2f3c 100644 --- a/src/map/mercenary.c +++ b/src/map/mercenary.c @@ -490,7 +490,10 @@ int read_mercenary_skilldb(void) { return 0; } -void do_init_mercenary(void) { +void do_init_mercenary(bool minimal) { + if (minimal) + return; + mercenary->read_db(); mercenary->read_skilldb(); diff --git a/src/map/mercenary.h b/src/map/mercenary.h index 3245606cf..3f2214b65 100644 --- a/src/map/mercenary.h +++ b/src/map/mercenary.h @@ -59,7 +59,7 @@ struct mercenary_interface { /* funcs */ - void (*init) (void); + void (*init) (bool minimal); bool (*class) (int class_); struct view_data * (*get_viewdata) (int class_); diff --git a/src/map/mob.c b/src/map/mob.c index 3f2ae2a55..e3e079131 100644 --- a/src/map/mob.c +++ b/src/map/mob.c @@ -4534,7 +4534,12 @@ bool mob_readdb_itemratio(char* str[], int columns, int current) /** * read all mob-related databases */ -void mob_load(void) { +void mob_load(bool minimal) { + if (minimal) { + // Only read the mob db in minimal mode + mob->readdb(); + return; + } sv->readdb(map->db_path, "mob_item_ratio.txt", ',', 2, 2+MAX_ITEMRATIO_MOBS, -1, mob->readdb_itemratio); // must be read before mobdb mob->readchatdb(); if (map->db_use_sql_mob_db) { @@ -4569,7 +4574,7 @@ void mob_reload(void) { } } - mob->load(); + mob->load(false); } void mob_clear_spawninfo() @@ -4583,15 +4588,18 @@ void mob_clear_spawninfo() /*========================================== * Circumference initialization of mob *------------------------------------------*/ -int do_init_mob(void) -{ //Initialize the mob database +int do_init_mob(bool minimal) { + // Initialize the mob database memset(mob->db_data,0,sizeof(mob->db_data)); //Clear the array - mob->db_data[0] = (struct mob_db*)aCalloc(1, sizeof (struct mob_db)); //This mob is used for random spawns + mob->db_data[0] = (struct mob_db*)aCalloc(1, sizeof (struct mob_db)); //This mob is used for random spawns mob->makedummymobdb(0); //The first time this is invoked, it creates the dummy mob item_drop_ers = ers_new(sizeof(struct item_drop),"mob.c::item_drop_ers",ERS_OPT_NONE); item_drop_list_ers = ers_new(sizeof(struct item_drop_list),"mob.c::item_drop_list_ers",ERS_OPT_NONE); - mob->load(); + mob->load(minimal); + + if (minimal) + return 0; timer->add_func_list(mob->delayspawn,"mob_delayspawn"); timer->add_func_list(mob->delay_item_drop,"mob_delay_item_drop"); diff --git a/src/map/mob.h b/src/map/mob.h index 2f425e285..31a8666a2 100644 --- a/src/map/mob.h +++ b/src/map/mob.h @@ -259,7 +259,7 @@ struct mob_interface { int manuk[8]; int splendide[5]; /* */ - int (*init) (void); + int (*init) (bool mimimal); int (*final) (void); void (*reload) (void); /* */ @@ -354,7 +354,7 @@ struct mob_interface { int (*read_sqlskilldb) (void); bool (*readdb_race2) (char *fields[], int columns, int current); bool (*readdb_itemratio) (char *str[], int columns, int current); - void (*load) (void); + void (*load) (bool minimal); void (*clear_spawninfo) (); }; diff --git a/src/map/npc.c b/src/map/npc.c index d78b3f8d4..9330d59d3 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1253,6 +1253,7 @@ int npc_buysellsel(struct map_session_data* sd, int id, int type) { } return 0; } + /*========================================== * Cash Shop Buy List *------------------------------------------*/ @@ -3498,8 +3499,7 @@ const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, const char //Read file and create npc/func/mapflag/monster... accordingly. //@runOnInit should we exec OnInit when it's done ? -void npc_parsesrcfile(const char* filepath, bool runOnInit) -{ +int npc_parsesrcfile(const char* filepath, bool runOnInit) { int16 m, x, y; int lines = 0; FILE* fp; @@ -3512,7 +3512,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) if( fp == NULL ) { ShowError("npc_parsesrcfile: File not found '%s'.\n", filepath); - return; + return -1; } fseek(fp, 0, SEEK_END); len = ftell(fp); @@ -3525,7 +3525,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) ShowError("npc_parsesrcfile: Failed to read file '%s' - %s\n", filepath, strerror(errno)); aFree(buffer); fclose(fp); - return; + return -1; } fclose(fp); @@ -3660,7 +3660,7 @@ void npc_parsesrcfile(const char* filepath, bool runOnInit) } aFree(buffer); - return; + return 0; } int npc_script_event(struct map_session_data* sd, enum npce_event type) @@ -3937,8 +3937,7 @@ static void npc_debug_warps(void) { /*========================================== * npc initialization *------------------------------------------*/ -int do_init_npc(void) -{ +int do_init_npc(bool minimal) { struct npc_src_list *file; int i; @@ -3965,43 +3964,47 @@ int do_init_npc(void) npc->name_db = strdb_alloc(DB_OPT_BASE, NAME_LENGTH); npc->path_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, 0); - npc->timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE); - npc_last_npd = NULL; npc_last_path = NULL; npc_last_ref = NULL; - // process all npc files - ShowStatus("Loading NPCs...\r"); - for( file = npc->src_files; file != NULL; file = file->next ) { - ShowStatus("Loading NPC file: %s"CL_CLL"\r", file->name); - npc->parsesrcfile(file->name,false); + if (!minimal) { + npc->timer_event_ers = ers_new(sizeof(struct timer_event_data),"clif.c::timer_event_ers",ERS_OPT_NONE); + + // process all npc files + ShowStatus("Loading NPCs...\r"); + for( file = npc->src_files; file != NULL; file = file->next ) { + ShowStatus("Loading NPC file: %s"CL_CLL"\r", file->name); + npc->parsesrcfile(file->name,false); + } + ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\n" + "\t-'"CL_WHITE"%d"CL_RESET"' Warps\n" + "\t-'"CL_WHITE"%d"CL_RESET"' Shops\n" + "\t-'"CL_WHITE"%d"CL_RESET"' Scripts\n" + "\t-'"CL_WHITE"%d"CL_RESET"' Spawn sets\n" + "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n" + "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n", + npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob); } - ShowInfo ("Done loading '"CL_WHITE"%d"CL_RESET"' NPCs:"CL_CLL"\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Warps\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Shops\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Scripts\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Spawn sets\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Cached\n" - "\t-'"CL_WHITE"%d"CL_RESET"' Mobs Not Cached\n", - npc_id - START_NPC_NUM, npc_warp, npc_shop, npc_script, npc_mob, npc_cache_mob, npc_delay_mob); itemdb->name_constants(); + + if (!minimal) { + map->zone_init(); - map->zone_init(); - - npc->motd = npc->name2id("HerculesMOTD"); /* [Ind/Hercules] */ + npc->motd = npc->name2id("HerculesMOTD"); /* [Ind/Hercules] */ - // set up the events cache - memset(script_event, 0, sizeof(script_event)); - npc->read_event_script(); + // set up the events cache + memset(script_event, 0, sizeof(script_event)); + npc->read_event_script(); - //Debug function to locate all endless loop warps. - if (battle_config.warp_point_debug) - npc->debug_warps(); + //Debug function to locate all endless loop warps. + if (battle_config.warp_point_debug) + npc->debug_warps(); - timer->add_func_list(npc->event_do_clock,"npc_event_do_clock"); - timer->add_func_list(npc->timerevent,"npc_timerevent"); + timer->add_func_list(npc->event_do_clock,"npc_event_do_clock"); + timer->add_func_list(npc->timerevent,"npc_timerevent"); + } // Init dummy NPC npc->fake_nd = (struct npc_data *)aCalloc(1,sizeof(struct npc_data)); diff --git a/src/map/npc.h b/src/map/npc.h index 5ec201e55..10f3406b4 100644 --- a/src/map/npc.h +++ b/src/map/npc.h @@ -140,7 +140,7 @@ struct npc_interface { struct npc_src_list *src_files; struct unit_data base_ud; /* */ - int (*init) (void); + int (*init) (bool minimal); int (*final) (void); /* */ int (*get_new_npc_id) (void); @@ -218,7 +218,7 @@ struct npc_interface { void (*parse_mob2) (struct spawn_data *mobspawn); const char* (*parse_mob) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath); const char* (*parse_mapflag) (char *w1, char *w2, char *w3, char *w4, const char *start, const char *buffer, const char *filepath); - void (*parsesrcfile) (const char *filepath, bool runOnInit); + int (*parsesrcfile) (const char *filepath, bool runOnInit); int (*script_event) (struct map_session_data *sd, enum npce_event type); void (*read_event_script) (void); int (*path_db_clear_sub) (DBKey key, DBData *data, va_list args); diff --git a/src/map/party.c b/src/map/party.c index ab05c23f7..2801d0466 100644 --- a/src/map/party.c +++ b/src/map/party.c @@ -1306,7 +1306,10 @@ void do_final_party(void) { db_destroy(party->booking_db); // Party Booking [Spiria] } // Constructor, init vars -void do_init_party(void) { +void do_init_party(bool minimal) { + if (minimal) + return; + party->db = idb_alloc(DB_OPT_RELEASE_DATA); party->booking_db = idb_alloc(DB_OPT_RELEASE_DATA); // Party Booking [Spiria] timer->add_func_list(party->send_xy_timer, "party_send_xy_timer"); diff --git a/src/map/party.h b/src/map/party.h index ab14d1a31..91f4c1b7d 100644 --- a/src/map/party.h +++ b/src/map/party.h @@ -73,7 +73,7 @@ struct party_interface { DBMap* booking_db; // int char_id -> struct party_booking_ad_info* (releases data) // Party Booking [Spiria] unsigned long booking_nextid; /* funcs */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ struct party_data* (*search) (int party_id); diff --git a/src/map/pc.c b/src/map/pc.c index f5e20b32b..4747cf498 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -10215,7 +10215,9 @@ void do_final_pc(void) { return; } -void do_init_pc(void) { +void do_init_pc(bool minimal) { + if (minimal) + return; pc->itemcd_db = idb_alloc(DB_OPT_RELEASE_DATA); diff --git a/src/map/pc.h b/src/map/pc.h index 7ae92c9a5..af03aa2f3 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -742,7 +742,7 @@ struct pc_interface { /* */ struct eri *sc_display_ers; /* funcs */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); struct map_session_data* (*get_dummy_sd) (void); diff --git a/src/map/pet.c b/src/map/pet.c index b75cc5a44..a2695d3b0 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -1328,8 +1328,10 @@ int read_petdb() /*========================================== * Initialization process relationship skills *------------------------------------------*/ -int do_init_pet(void) -{ +int do_init_pet(bool minimal) { + if (minimal) + return 0; + pet->read_db(); pet->item_drop_ers = ers_new(sizeof(struct item_drop),"pet.c::item_drop_ers",ERS_OPT_NONE); diff --git a/src/map/pet.h b/src/map/pet.h index f95e860a2..f9a756de2 100644 --- a/src/map/pet.h +++ b/src/map/pet.h @@ -106,7 +106,7 @@ struct pet_interface { struct eri *item_drop_ers; //For loot drops delay structures. struct eri *item_drop_list_ers; /* */ - int (*init) (void); + int (*init) (bool minimal); int (*final) (void); /* */ int (*hungry_val) (struct pet_data *pd); diff --git a/src/map/quest.c b/src/map/quest.c index f40b60c3d..0719b8dbb 100644 --- a/src/map/quest.c +++ b/src/map/quest.c @@ -351,7 +351,10 @@ int quest_read_db(void) { return 0; } -void do_init_quest(void) { +void do_init_quest(bool minimal) { + if (minimal) + return; + quest->read_db(); } diff --git a/src/map/quest.h b/src/map/quest.h index 340bc8608..0725a8c46 100644 --- a/src/map/quest.h +++ b/src/map/quest.h @@ -19,7 +19,7 @@ typedef enum quest_check_type { HAVEQUEST, PLAYTIME, HUNTING } quest_check_type; struct quest_interface { struct s_quest_db db[MAX_QUEST_DB]; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*reload) (void); /* */ int (*search_db) (int quest_id); diff --git a/src/map/script.c b/src/map/script.c index 8fd7f425c..78f5eceeb 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -1863,66 +1863,98 @@ void read_constdb(void) { fclose(fp); } +// Standard UNIX tab size is 8 +#define TAB_SIZE 8 +#define update_tabstop(tabstop,chars) \ + do { \ + (tabstop) -= (chars); \ + while ((tabstop) <= 0) (tabstop) += TAB_SIZE; \ + } while (false) + /*========================================== * Display emplacement line of script *------------------------------------------*/ const char* script_print_line(StringBuf* buf, const char* p, const char* mark, int line) { - int i; + int i, mark_pos = 0, tabstop = TAB_SIZE; if( p == NULL || !p[0] ) return NULL; if( line < 0 ) - StrBuf->Printf(buf, "*% 5d : ", -line); + StrBuf->Printf(buf, "*%5d: ", -line); // len = 8 else - StrBuf->Printf(buf, " % 5d : ", line); - for(i=0;p[i] && p[i] != '\n';i++){ - if(p + i != mark) - StrBuf->Printf(buf, "%c", p[i]); + StrBuf->Printf(buf, " %5d: ", line); // len = 8 + update_tabstop(tabstop,8); // len = 8 + for( i=0; p[i] && p[i] != '\n'; i++ ) { + char c = p[i]; + int w = 1; + // Like Clang does, let's print the code with tabs expanded to spaces to ensure that the marker will be under the right character + if( c == '\t' ) { + c = ' '; + w = tabstop; + } + update_tabstop(tabstop, w); + if( p + i < mark) + mark_pos += w; + if( p + i != mark) + StrBuf->Printf(buf, "%*c", w, c); else - StrBuf->Printf(buf, "\'%c\'", p[i]); + StrBuf->Printf(buf, CL_BT_RED"%*c"CL_RESET, w, c); } StrBuf->AppendStr(buf, "\n"); + if( mark ) { + StrBuf->AppendStr(buf, " "CL_BT_CYAN); // len = 8 + for( ; mark_pos > 0; mark_pos-- ) { + StrBuf->AppendStr(buf, "~"); + } + StrBuf->AppendStr(buf, CL_RESET CL_BT_GREEN"^"CL_RESET"\n"); + } return p+i+(p[i] == '\n' ? 1 : 0); } +#undef TAB_SIZE +#undef update_tabstop +#define CONTEXTLINES 3 void script_errorwarning_sub(StringBuf *buf, const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos) { // Find the line where the error occurred int j; int line = start_line; - const char *p; - const char *linestart[5] = { NULL, NULL, NULL, NULL, NULL }; + const char *p, *error_linepos; + const char *linestart[CONTEXTLINES]; + memset(linestart, '\0', sizeof(linestart)); for(p=src;p && *p;line++){ const char *lineend=strchr(p,'\n'); if(lineend==NULL || error_pos<lineend){ break; } - for( j = 0; j < 4; j++ ) { + for( j = 0; j < CONTEXTLINES-1; j++ ) { linestart[j] = linestart[j+1]; } - linestart[4] = p; - p=lineend+1; + linestart[CONTEXTLINES-1] = p; + p = lineend+1; } + error_linepos = p; if( line >= 0 ) - StrBuf->Printf(buf, "script error in file '%s' line %d\n", file, line); + StrBuf->Printf(buf, "script error in file '%s' line %d column %d\n", file, line, error_pos-error_linepos+1); else StrBuf->Printf(buf, "script error in file '%s' item ID %d\n", file, -line); StrBuf->Printf(buf, " %s\n", error_msg); - for(j = 0; j < 5; j++ ) { - script->print_line(buf, linestart[j], NULL, line + j - 5); + for(j = 0; j < CONTEXTLINES; j++ ) { + script->print_line(buf, linestart[j], NULL, line + j - CONTEXTLINES); } p = script->print_line(buf, p, error_pos, -line); - for(j = 0; j < 5; j++) { + for(j = 0; j < CONTEXTLINES; j++) { p = script->print_line(buf, p, NULL, line + j + 1 ); } } +#undef CONTEXTLINES void script_error(const char* src, const char* file, int start_line, const char* error_msg, const char* error_pos) { StringBuf buf; StrBuf->Init(&buf); - StrBuf->AppendStr(&buf, "\a\n"); + StrBuf->AppendStr(&buf, "\a"); script->errorwarning_sub(&buf, src, file, start_line, error_msg, error_pos); @@ -3694,7 +3726,7 @@ void do_final_script(void) { /*========================================== * Initialization *------------------------------------------*/ -void do_init_script(void) { +void do_init_script(bool minimal) { script->st_db = idb_alloc(DB_OPT_BASE); script->userfunc_db = strdb_alloc(DB_OPT_DUP_KEY,0); script->autobonus_db = strdb_alloc(DB_OPT_DUP_KEY,0); @@ -3707,6 +3739,10 @@ void do_init_script(void) { script->parse_builtin(); script->read_constdb(); + + if (minimal) + return; + mapreg->init(); } diff --git a/src/map/script.h b/src/map/script.h index a4d14c777..6aebc8a30 100644 --- a/src/map/script.h +++ b/src/map/script.h @@ -507,7 +507,7 @@ struct script_interface { int potion_hp, potion_per_hp, potion_sp, potion_per_sp; int potion_target; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); int (*reload) (void); /* parse */ diff --git a/src/map/skill.c b/src/map/skill.c index b70e58c46..c16ab832c 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -18027,7 +18027,7 @@ bool skill_parse_row_changematerialdb(char* split[], int columns, int current) { * create_arrow_db.txt * abra_db.txt *------------------------------*/ -void skill_readdb(void) { +void skill_readdb(bool minimal) { // init skill db structures db_clear(skill->name2id_db); @@ -18050,6 +18050,10 @@ void skill_readdb(void) { safestrncpy(skill->db[0].desc, "Unknown Skill", sizeof(skill->db[0].desc)); sv->readdb(map->db_path, DBPATH"skill_db.txt", ',', 17, 17, MAX_SKILL_DB, skill->parse_row_skilldb); + + if (minimal) + return; + sv->readdb(map->db_path, DBPATH"skill_require_db.txt", ',', 32, 32, MAX_SKILL_DB, skill->parse_row_requiredb); #ifdef RENEWAL_CAST sv->readdb(map->db_path, "re/skill_cast_db.txt", ',', 8, 8, MAX_SKILL_DB, skill->parse_row_castdb); @@ -18077,7 +18081,7 @@ void skill_reload (void) { struct map_session_data *sd; int i,c,k; - skill->read_db(); + skill->read_db(false); //[Ind/Hercules] refresh index cache for(c = 0; c < CLASS_COUNT; c++) { @@ -18103,9 +18107,12 @@ void skill_reload (void) { /*========================================== * *------------------------------------------*/ -int do_init_skill (void) { +int do_init_skill(bool minimal) { skill->name2id_db = strdb_alloc(DB_OPT_DUP_KEY|DB_OPT_RELEASE_DATA, MAX_SKILL_NAME_LENGTH); - skill->read_db(); + skill->read_db(minimal); + + if (minimal) + return 0; skill->group_db = idb_alloc(DB_OPT_BASE); skill->unit_db = idb_alloc(DB_OPT_BASE); diff --git a/src/map/skill.h b/src/map/skill.h index fca4952ef..918216e8a 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1797,10 +1797,10 @@ typedef int (*SkillFunc)(struct block_list *src, struct block_list *target, uint * Skill.c Interface **/ struct skill_interface { - int (*init) (void); + int (*init) (bool minimal); int (*final) (void); void (*reload) (void); - void (*read_db) (void); + void (*read_db) (bool minimal); /* */ DBMap* cd_db; // char_id -> struct skill_cd DBMap* name2id_db; diff --git a/src/map/status.c b/src/map/status.c index 1df98a957..14def3e18 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -11539,7 +11539,10 @@ int status_readdb(void) /*========================================== * Status db init and destroy. *------------------------------------------*/ -int do_init_status(void) { +int do_init_status(bool minimal) { + if (minimal) + return 0; + timer->add_func_list(status->change_timer,"status_change_timer"); timer->add_func_list(status->kaahi_heal_timer,"status_kaahi_heal_timer"); timer->add_func_list(status->natural_heal_timer,"status_natural_heal_timer"); diff --git a/src/map/status.h b/src/map/status.h index e588fbb3f..9a8b231e5 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1870,7 +1870,7 @@ struct status_interface { int64 natural_heal_prev_tick; unsigned int natural_heal_diff_tick; /* */ - int (*init) (void); + int (*init) (bool minimal); void (*final) (void); /* funcs */ int (*get_refine_chance) (enum refine_type wlv, int refine); diff --git a/src/map/storage.c b/src/map/storage.c index cc1100d28..45a80867d 100644 --- a/src/map/storage.c +++ b/src/map/storage.c @@ -717,7 +717,9 @@ int storage_guild_storage_quit(struct map_session_data* sd, int flag) { return 0; } -void do_init_gstorage(void) { +void do_init_gstorage(bool minimal) { + if (minimal) + return; gstorage->db = idb_alloc(DB_OPT_RELEASE_DATA); } void do_final_gstorage(void) { diff --git a/src/map/storage.h b/src/map/storage.h index 9258e0265..8a10c9f3b 100644 --- a/src/map/storage.h +++ b/src/map/storage.h @@ -36,7 +36,7 @@ struct guild_storage_interface { struct guild_storage *(*id2storage) (int guild_id); struct guild_storage *(*id2storage2) (int guild_id); /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ int (*delete) (int guild_id); diff --git a/src/map/unit.c b/src/map/unit.c index c7ba2f6f9..b1240def2 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -2573,7 +2573,10 @@ int unit_free(struct block_list *bl, clr_type clrtype) { return 0; } -int do_init_unit(void) { +int do_init_unit(bool minimal) { + if (minimal) + return 0; + timer->add_func_list(unit->attack_timer, "unit_attack_timer"); timer->add_func_list(unit->walktoxy_timer,"unit_walktoxy_timer"); timer->add_func_list(unit->walktobl_sub, "unit_walktobl_sub"); diff --git a/src/map/unit.h b/src/map/unit.h index 0567688a1..8220b7e8f 100644 --- a/src/map/unit.h +++ b/src/map/unit.h @@ -72,7 +72,7 @@ extern const short dirx[8]; extern const short diry[8]; struct unit_interface { - int (*init) (void); + int (*init) (bool minimal); int (*final) (void); /* */ struct unit_data* (*bl2ud) (struct block_list *bl); diff --git a/src/map/vending.c b/src/map/vending.c index 7d6d02cfb..c7a2dfa68 100644 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -360,7 +360,7 @@ void final(void) { db_destroy(vending->db); } -void init(void) { +void init(bool minimal) { vending->db = idb_alloc(DB_OPT_BASE); vending->next_id = 0; } diff --git a/src/map/vending.h b/src/map/vending.h index 968811ecd..b760bf064 100644 --- a/src/map/vending.h +++ b/src/map/vending.h @@ -20,7 +20,7 @@ struct vending_interface { unsigned int next_id;/* next vender id */ DBMap *db; /* */ - void (*init) (void); + void (*init) (bool minimal); void (*final) (void); /* */ void (*close) (struct map_session_data* sd); diff --git a/tools/Script-Checker.applescript b/tools/Script-Checker.applescript new file mode 100644 index 000000000..db1983f4b --- /dev/null +++ b/tools/Script-Checker.applescript @@ -0,0 +1,151 @@ +(* + Copyright (c) Hercules Dev Team, licensed under GNU GPL. + See the LICENSE file + Base Author: Haru @ http://hercules.ws +*) + +(* + ************************************************************* + ************************************************************* + ******** ************** + ******** NOTE: This script must be saved as app!!! ************** + ******** ************** + ************************************************************* + ************************************************************* +*) + +property allowed_extensions : {"txt", "c", "ath", "herc"} +property allowed_types : {"TEXT"} + +on run + try + set the resource_path to path to resource "Scripts" + tell application "Finder" to set the resource_path to the container of the resource_path + on error + display alert "Error" message "You need to save this script as an app bundle." buttons {"Cancel"} cancel button 1 as warning + end try + set the dialog_result to display dialog "You can drag files to this app to have them checked." with title "Hercules Script Checker" buttons {"Cancel", "(Re)build Hercules", "Check Script"} default button 3 cancel button 1 + if the button returned of the dialog_result is "(Re)build Hercules" then + rebuild() + else + set these_items to choose file of type allowed_extensions with prompt "Choose the script(s) you want to check:" with multiple selections allowed + process_items(these_items) + end if +end run + +on open these_items + process_items(these_items) +end open + +on build_hercules(hercules_repo) + try + set the resource_path to path to resource "Scripts" + tell application "Finder" to set the resource_path to the container of the resource_path + on error + display alert "Error" message "You need to save this script as an app bundle." buttons {"Cancel"} cancel button 1 as warning + end try + set the configuration_flags to display dialog "Do you want to use any configuration flags? (i.e. --disable-renewal)" with title "Configuration" default answer "" buttons {"Cancel", "Ok"} default button 2 cancel button 1 + try + set the command_output to do shell script "cd " & (the quoted form of the POSIX path of the hercules_repo) & " && echo './configure " & the text returned of the configuration_flags & " 2>&1' | bash -i" + on error + display dialog "Configuration failed" with title "Configuration result" buttons {"Abort"} cancel button 1 + end try + tell application "TextEdit" + activate + set the new_document to make new document + set the text of new_document to the command_output + end tell + display dialog "Configuration successfully completed. Please check the log file for details." with title "Configuration result" buttons {"Abort", "Continue"} default button 2 cancel button 1 + try + set the command_output to do shell script "cd " & (the quoted form of the POSIX path of the hercules_repo) & " && echo 'make clean 2>&1 && make sql -j8 2>&1' | bash -i" + on error + display dialog "Build failed." with title "Build result" buttons {"Abort"} cancel button 1 + end try + tell application "TextEdit" + activate + set the new_document to make new document + set the text of new_document to the command_output + end tell + display dialog "Build successfully completed. Please check the log file for details." with title "Build result" buttons {"Abort", "Continue"} default button 2 cancel button 1 + set the files_to_copy to {"map-server", "script-checker"} + set the conf_files_to_copy to {"inter-server.conf", "import", "packet.conf", "script.conf"} + set the db_files_to_copy to {"map_index.txt", "item_db2.txt", "const.txt", "mob_db2.txt"} + set the db2_files_to_copy to {"map_cache.dat", "item_db.txt", "skill_db.txt", "mob_db.txt"} + try + set the hercules_path to path to resource "Hercules" + do shell script "rm -r " & the quoted form of ((the POSIX path of hercules_path) & "/") + end try + set the hercules_path to the resource_path + tell application "Finder" to make new folder at hercules_path with properties {name:"Hercules"} + delay 3 + set the hercules_path to path to resource "Hercules" + repeat with each_file in files_to_copy + copy_file(each_file, hercules_repo, hercules_path, ".") + end repeat + do shell script "mkdir " & the quoted form of ((POSIX path of the hercules_path) & "/conf") + repeat with each_file in conf_files_to_copy + copy_file(each_file, hercules_repo, hercules_path, "conf") + end repeat + do shell script "mkdir " & the quoted form of ((POSIX path of the hercules_path) & "/db") + repeat with each_file in db_files_to_copy + copy_file(each_file, hercules_repo, hercules_path, "db") + end repeat + do shell script "mkdir " & the quoted form of ((POSIX path of the hercules_path) & "/db/pre-re") + repeat with each_file in db2_files_to_copy + copy_file(each_file, hercules_repo, hercules_path, "db/pre-re") + end repeat + do shell script "mkdir " & the quoted form of ((POSIX path of the hercules_path) & "/db/re") + repeat with each_file in db2_files_to_copy + copy_file(each_file, hercules_repo, hercules_path, "db/re") + end repeat + display dialog "Build complete" with title "Done" buttons {"Ok"} default button "Ok" +end build_hercules + +on rebuild() + set the repo_path to choose folder with prompt "Choose the folder where your Hercules repository is located:" + build_hercules(repo_path) +end rebuild + +on copy_file(filename, source, destination, subpath) + do shell script "cp -rp " & the quoted form of ((the POSIX path of source) & "/" & subpath & "/" & filename) & " " & the quoted form of ((the POSIX path of destination) & "/" & subpath & "/") +end copy_file + +on process_items(these_items) + repeat + try + set the scriptchecker to the path to resource "script-checker" in directory "Hercules" + set the mapserver to the path to resource "map-server" in directory "Hercules" + on error + display alert "Missing Hercules binaries" message "You need to build Hercules and place it within this app bundle before running the script checker." & linefeed & linefeed & "I can try to build it for you, but only if you have the Xcode command line tools installed." & linefeed & "Do you want to continue?" buttons {"Cancel", "Build"} default button "Build" cancel button "Cancel" as warning + rebuild() + return false + end try + exit repeat + end repeat + repeat with i from 1 to the count of these_items + set this_item to item i of these_items + set the item_info to info for this_item + set this_name to the name of the item_info + try + set this_extension to the name extension of item_info + on error + set this_extension to "" + end try + try + set this_filetype to the file type of item_info + on error + set this_filetype to "" + end try + if (folder of the item_info is false) and (alias of the item_info is false) and ((this_filetype is in the allowed_types) or (this_extension is in the allowed_extensions)) then + process_item(scriptchecker, this_item) + end if + end repeat +end process_items + +on process_item(checkerpath, this_item) + set the_result to do shell script (the quoted form of the POSIX path of checkerpath & " " & the quoted form of the POSIX path of this_item) & " 2>&1" + if the_result is "" then + set the_result to "Check passed." + end if + display dialog ("File: " & POSIX path of this_item) & linefeed & "Result: " & linefeed & the_result with title "Output" buttons {"Abort", "Next"} default button "Next" cancel button "Abort" +end process_item |