summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorshennetsind <shennetsind@users.noreply.github.com>2013-11-06 15:10:38 -0800
committershennetsind <shennetsind@users.noreply.github.com>2013-11-06 15:10:38 -0800
commit87d7348396af97428638723ae49ca2ff166e4acd (patch)
treef9cebecab0aaf281a8ebb5405648fe8d0b731ecb
parent7d1bbde0046ee7520c907e090f1b4087eb713172 (diff)
parent4fbe8e2a270997b02e2e002074259e4648ac0031 (diff)
downloadhercules-87d7348396af97428638723ae49ca2ff166e4acd.tar.gz
hercules-87d7348396af97428638723ae49ca2ff166e4acd.tar.bz2
hercules-87d7348396af97428638723ae49ca2ff166e4acd.tar.xz
hercules-87d7348396af97428638723ae49ca2ff166e4acd.zip
Merge pull request #217 from HerculesWS/script-checker
Introducing the Hercules Standalone Script Syntax Checker
-rwxr-xr-xscript-checker25
-rw-r--r--script-checker.bat29
-rw-r--r--src/common/core.c14
-rw-r--r--src/common/mapindex.c17
-rw-r--r--src/common/mapindex.h3
-rw-r--r--src/map/atcommand.c5
-rw-r--r--src/map/atcommand.h2
-rw-r--r--src/map/battle.c5
-rw-r--r--src/map/battle.h2
-rw-r--r--src/map/battleground.c5
-rw-r--r--src/map/battleground.h2
-rw-r--r--src/map/chrif.c6
-rw-r--r--src/map/chrif.h2
-rw-r--r--src/map/clif.c5
-rw-r--r--src/map/clif.h2
-rw-r--r--src/map/duel.c5
-rw-r--r--src/map/duel.h2
-rw-r--r--src/map/elemental.c5
-rw-r--r--src/map/elemental.h2
-rw-r--r--src/map/guild.c15
-rw-r--r--src/map/guild.h2
-rw-r--r--src/map/homunculus.c6
-rw-r--r--src/map/homunculus.h2
-rw-r--r--src/map/instance.c5
-rw-r--r--src/map/instance.h2
-rw-r--r--src/map/irc-bot.c5
-rw-r--r--src/map/irc-bot.h2
-rw-r--r--src/map/itemdb.c15
-rw-r--r--src/map/itemdb.h4
-rw-r--r--src/map/map.c168
-rw-r--r--src/map/map.h2
-rw-r--r--src/map/mercenary.c5
-rw-r--r--src/map/mercenary.h2
-rw-r--r--src/map/mob.c20
-rw-r--r--src/map/mob.h4
-rw-r--r--src/map/npc.c69
-rw-r--r--src/map/npc.h4
-rw-r--r--src/map/party.c5
-rw-r--r--src/map/party.h2
-rw-r--r--src/map/pc.c4
-rw-r--r--src/map/pc.h2
-rw-r--r--src/map/pet.c6
-rw-r--r--src/map/pet.h2
-rw-r--r--src/map/quest.c5
-rw-r--r--src/map/quest.h2
-rw-r--r--src/map/script.c72
-rw-r--r--src/map/script.h2
-rw-r--r--src/map/skill.c15
-rw-r--r--src/map/skill.h4
-rw-r--r--src/map/status.c5
-rw-r--r--src/map/status.h2
-rw-r--r--src/map/storage.c4
-rw-r--r--src/map/storage.h2
-rw-r--r--src/map/unit.c5
-rw-r--r--src/map/unit.h2
-rw-r--r--src/map/vending.c2
-rw-r--r--src/map/vending.h2
-rw-r--r--tools/Script-Checker.applescript151
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