diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/HPM.c | 24 | ||||
-rw-r--r-- | src/common/HPM.h | 2 | ||||
-rw-r--r-- | src/common/HPMDataCheck.h | 2 | ||||
-rw-r--r-- | src/common/Makefile.in | 2 | ||||
-rw-r--r-- | src/common/cbasetypes.h | 2 | ||||
-rw-r--r-- | src/common/conf.c | 288 | ||||
-rw-r--r-- | src/common/conf.h | 154 | ||||
-rw-r--r-- | src/common/console.c | 1 | ||||
-rw-r--r-- | src/common/core.c | 5 | ||||
-rw-r--r-- | src/common/db.c | 2 | ||||
-rw-r--r-- | src/common/db.h | 4 | ||||
-rw-r--r-- | src/common/ers.c | 6 | ||||
-rw-r--r-- | src/common/ers.h | 14 | ||||
-rw-r--r-- | src/common/md5calc.c | 6 | ||||
-rw-r--r-- | src/common/memmgr.c | 99 | ||||
-rw-r--r-- | src/common/memmgr.h | 4 | ||||
-rw-r--r-- | src/common/mmo.h | 44 | ||||
-rw-r--r-- | src/common/mutex.h | 4 | ||||
-rw-r--r-- | src/common/showmsg.c | 11 | ||||
-rw-r--r-- | src/common/showmsg.h | 7 | ||||
-rw-r--r-- | src/common/socket.c | 39 | ||||
-rw-r--r-- | src/common/socket.h | 48 | ||||
-rw-r--r-- | src/common/sql.c | 7 | ||||
-rw-r--r-- | src/common/sql.h | 4 | ||||
-rw-r--r-- | src/common/sysinfo.c | 17 | ||||
-rw-r--r-- | src/common/sysinfo.h | 1 | ||||
-rw-r--r-- | src/common/thread.c | 2 | ||||
-rw-r--r-- | src/common/timer.c | 64 | ||||
-rw-r--r-- | src/common/utils.c | 43 | ||||
-rw-r--r-- | src/common/utils.h | 6 |
30 files changed, 703 insertions, 209 deletions
diff --git a/src/common/HPM.c b/src/common/HPM.c index 62ef54499..fa4025fb8 100644 --- a/src/common/HPM.c +++ b/src/common/HPM.c @@ -214,11 +214,11 @@ bool hplugin_data_store_validate(enum HPluginDataTypes type, struct hplugin_data break; default: if (HPM->data_store_validate_sub == NULL) { - ShowError("HPM:validateHPData failed, type %d needs sub-handler!\n",type); + ShowError("HPM:validateHPData failed, type %u needs sub-handler!\n", type); return false; } if (!HPM->data_store_validate_sub(type, storeptr, initialize)) { - ShowError("HPM:HPM:validateHPData failed, unknown type %d!\n",type); + ShowError("HPM:HPM:validateHPData failed, unknown type %u!\n", type); return false; } break; @@ -228,7 +228,7 @@ bool hplugin_data_store_validate(enum HPluginDataTypes type, struct hplugin_data store = *storeptr; } if (store->type != type) { - ShowError("HPM:HPM:validateHPData failed, store type mismatch %d != %d.\n",store->type, type); + ShowError("HPM:HPM:validateHPData failed, store type mismatch %u != %u.\n", store->type, type); return false; } return true; @@ -253,7 +253,7 @@ void hplugins_addToHPData(enum HPluginDataTypes type, uint32 pluginID, struct hp if (!HPM->data_store_validate(type, storeptr, true)) { /* woo it failed! */ - ShowError("HPM:addToHPData:%s: failed, type %d (%u|%u)\n", HPM->pid2name(pluginID), type, pluginID, classid); + ShowError("HPM:addToHPData:%s: failed, type %u (%u|%u)\n", HPM->pid2name(pluginID), type, pluginID, classid); return; } store = *storeptr; @@ -294,7 +294,7 @@ void *hplugins_getFromHPData(enum HPluginDataTypes type, uint32 pluginID, struct if (!HPM->data_store_validate(type, &store, false)) { /* woo it failed! */ - ShowError("HPM:getFromHPData:%s: failed, type %d (%u|%u)\n", HPM->pid2name(pluginID), type, pluginID, classid); + ShowError("HPM:getFromHPData:%s: failed, type %u (%u|%u)\n", HPM->pid2name(pluginID), type, pluginID, classid); return NULL; } if (!store) @@ -322,7 +322,7 @@ void hplugins_removeFromHPData(enum HPluginDataTypes type, uint32 pluginID, stru if (!HPM->data_store_validate(type, &store, false)) { /* woo it failed! */ - ShowError("HPM:removeFromHPData:%s: failed, type %d (%u|%u)\n", HPM->pid2name(pluginID), type, pluginID, classid); + ShowError("HPM:removeFromHPData:%s: failed, type %u (%u|%u)\n", HPM->pid2name(pluginID), type, pluginID, classid); return; } if (!store) @@ -616,8 +616,8 @@ CMDLINEARG(loadplugin) * Reads the plugin configuration and loads the plugins as necessary. */ void hplugins_config_read(void) { - config_t plugins_conf; - config_setting_t *plist = NULL; + struct config_t plugins_conf; + struct config_setting_t *plist = NULL; const char *config_filename = "conf/plugins.conf"; // FIXME hardcoded name FILE *fp; int i; @@ -628,12 +628,12 @@ void hplugins_config_read(void) { fclose(fp); } - if (libconfig->read_file(&plugins_conf, config_filename)) + if (!libconfig->load_file(&plugins_conf, config_filename)) return; plist = libconfig->lookup(&plugins_conf, "plugins_list"); for (i = 0; i < VECTOR_LENGTH(HPM->cmdline_load_plugins); i++) { - config_setting_t *entry = libconfig->setting_add(plist, NULL, CONFIG_TYPE_STRING); + struct config_setting_t *entry = libconfig->setting_add(plist, NULL, CONFIG_TYPE_STRING); config_setting_set_string(entry, VECTOR_INDEX(HPM->cmdline_load_plugins, i)); } @@ -718,13 +718,13 @@ CPCMD(plugins) * @retval 1 OK * @retval 2 incomplete packet */ -unsigned char hplugins_parse_packets(int fd, enum HPluginPacketHookingPoints point) +unsigned char hplugins_parse_packets(int fd, int packet_id, enum HPluginPacketHookingPoints point) { struct HPluginPacket *packet = NULL; int i; int16 length; - ARR_FIND(0, VECTOR_LENGTH(HPM->packets[point]), i, VECTOR_INDEX(HPM->packets[point], i).cmd == RFIFOW(fd,0)); + ARR_FIND(0, VECTOR_LENGTH(HPM->packets[point]), i, VECTOR_INDEX(HPM->packets[point], i).cmd == packet_id); if (i == VECTOR_LENGTH(HPM->packets[point])) return 0; diff --git a/src/common/HPM.h b/src/common/HPM.h index 215161a86..109549aad 100644 --- a/src/common/HPM.h +++ b/src/common/HPM.h @@ -157,7 +157,7 @@ struct HPM_interface { void (*share) (void *value, const char *name); void (*config_read) (void); char *(*pid2name) (unsigned int pid); - unsigned char (*parse_packets) (int fd, enum HPluginPacketHookingPoints point); + unsigned char (*parse_packets) (int fd, int packet_id, enum HPluginPacketHookingPoints point); void (*load_sub) (struct hplugin *plugin); bool (*addhook_sub) (enum HPluginHookType type, const char *target, void *hook, unsigned int pID); /* for custom config parsing */ diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h index 666d306db..7e88b5a34 100644 --- a/src/common/HPMDataCheck.h +++ b/src/common/HPMDataCheck.h @@ -402,6 +402,8 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = { { "item_package_rand_entry", sizeof(struct item_package_rand_entry), SERVER_TYPE_MAP }, { "item_package_rand_group", sizeof(struct item_package_rand_group), SERVER_TYPE_MAP }, { "itemdb_interface", sizeof(struct itemdb_interface), SERVER_TYPE_MAP }, + { "itemlist", sizeof(struct itemlist), SERVER_TYPE_MAP }, + { "itemlist_entry", sizeof(struct itemlist_entry), SERVER_TYPE_MAP }, #else #define MAP_ITEMDB_H #endif // MAP_ITEMDB_H diff --git a/src/common/Makefile.in b/src/common/Makefile.in index df3ecaf2d..9d4b2d044 100644 --- a/src/common/Makefile.in +++ b/src/common/Makefile.in @@ -135,7 +135,7 @@ obj_all/sysinfo.o: sysinfo.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_ obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_all @echo " CC $<" - @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @PCRE_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $< + @$(CC) @CFLAGS@ @DEFS@ $(COMMON_INCLUDE) $(THIRDPARTY_INCLUDE) @CPPFLAGS@ -c $(OUTPUT_OPTION) $< obj_all/mini%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_all @echo " CC $<" diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h index 61d0646eb..6843ce486 100644 --- a/src/common/cbasetypes.h +++ b/src/common/cbasetypes.h @@ -94,7 +94,7 @@ // debug function name #ifndef __NETBSD__ -#if __STDC_VERSION__ < 199901L +#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L # if __GNUC__ >= 2 # define __func__ __FUNCTION__ # else diff --git a/src/common/conf.c b/src/common/conf.c index 3e8c08963..25f1013f5 100644 --- a/src/common/conf.c +++ b/src/common/conf.c @@ -23,6 +23,7 @@ #include "conf.h" #include "common/showmsg.h" // ShowError +#include "common/strlib.h" // safestrncpy #include <libconfig/libconfig.h> @@ -30,26 +31,39 @@ struct libconfig_interface libconfig_s; struct libconfig_interface *libconfig; -int conf_read_file(config_t *config, const char *config_filename) { +/** + * Initializes 'config' and loads a configuration file. + * + * Shows error and destroys 'config' in case of failure. + * It is the caller's care to destroy 'config' in case of success. + * + * @param config The config file to initialize. + * @param config_filename The file to read. + * + * @retval CONFIG_TRUE in case of success. + * @retval CONFIG_FALSE in case of failure. + */ +int config_load_file(struct config_t *config, const char *config_filename) +{ libconfig->init(config); - if (!libconfig->read_file_src(config, config_filename)) { + if (libconfig->read_file_src(config, config_filename) != CONFIG_TRUE) { ShowError("%s:%d - %s\n", config_error_file(config), config_error_line(config), config_error_text(config)); libconfig->destroy(config); - return 1; + return CONFIG_FALSE; } - return 0; + return CONFIG_TRUE; } // // Functions to copy settings from libconfig/contrib // -void config_setting_copy_simple(config_setting_t *parent, const config_setting_t *src) { +void config_setting_copy_simple(struct config_setting_t *parent, const struct config_setting_t *src) +{ if (config_setting_is_aggregate(src)) { libconfig->setting_copy_aggregate(parent, src); - } - else { - config_setting_t *set; + } else { + struct config_setting_t *set; if( libconfig->setting_get_member(parent, config_setting_name(src)) != NULL ) return; @@ -73,8 +87,9 @@ void config_setting_copy_simple(config_setting_t *parent, const config_setting_t } } -void config_setting_copy_elem(config_setting_t *parent, const config_setting_t *src) { - config_setting_t *set = NULL; +void config_setting_copy_elem(struct config_setting_t *parent, const struct config_setting_t *src) +{ + struct config_setting_t *set = NULL; if (config_setting_is_aggregate(src)) libconfig->setting_copy_aggregate(parent, src); @@ -93,8 +108,9 @@ void config_setting_copy_elem(config_setting_t *parent, const config_setting_t * } } -void config_setting_copy_aggregate(config_setting_t *parent, const config_setting_t *src) { - config_setting_t *newAgg; +void config_setting_copy_aggregate(struct config_setting_t *parent, const struct config_setting_t *src) +{ + struct config_setting_t *newAgg; int i, n; if( libconfig->setting_get_member(parent, config_setting_name(src)) != NULL ) @@ -116,7 +132,8 @@ void config_setting_copy_aggregate(config_setting_t *parent, const config_settin } } -int config_setting_copy(config_setting_t *parent, const config_setting_t *src) { +int config_setting_copy(struct config_setting_t *parent, const struct config_setting_t *src) +{ if (!config_setting_is_group(parent) && !config_setting_is_list(parent)) return CONFIG_FALSE; @@ -128,14 +145,237 @@ int config_setting_copy(config_setting_t *parent, const config_setting_t *src) { return CONFIG_TRUE; } +/** + * Converts the value of a setting that is type CONFIG_TYPE_BOOL to bool. + * + * @param setting The setting to read. + * + * @return The converted value. + * @retval false in case of failure. + */ +bool config_setting_get_bool_real(const struct config_setting_t *setting) +{ + if (setting == NULL || setting->type != CONFIG_TYPE_BOOL) + return false; + + return setting->value.ival ? true : false; +} + +/** + * Same as config_setting_lookup_bool, but uses bool instead of int. + * + * @param[in] setting The setting to read. + * @param[in] name The setting name to lookup. + * @param[out] value The output value. + * + * @retval CONFIG_TRUE in case of success. + * @retval CONFIG_FALSE in case of failure. + */ +int config_setting_lookup_bool_real(const struct config_setting_t *setting, const char *name, bool *value) +{ + struct config_setting_t *member = config_setting_get_member(setting, name); + + if (!member) + return CONFIG_FALSE; + + if (config_setting_type(member) != CONFIG_TYPE_BOOL) + return CONFIG_FALSE; + + *value = config_setting_get_bool_real(member); + + return CONFIG_TRUE; +} + +/** + * Converts and returns a configuration that is CONFIG_TYPE_INT to unsigned int (uint32). + * + * @param setting The setting to read. + * + * @return The converted value. + * @retval 0 in case of failure. + */ +uint32 config_setting_get_uint32(const struct config_setting_t *setting) +{ + if (setting == NULL || setting->type != CONFIG_TYPE_INT) + return 0; + + if (setting->value.ival < 0) + return 0; + + return (uint32)setting->value.ival; +} + +/** + * Looks up a configuration entry of type CONFIG_TYPE_INT and reads it as uint32. + * + * @param[in] setting The setting to read. + * @param[in] name The setting name to lookup. + * @param[out] value The output value. + * + * @retval CONFIG_TRUE in case of success. + * @retval CONFIG_FALSE in case of failure. + */ +int config_setting_lookup_uint32(const struct config_setting_t *setting, const char *name, uint32 *value) +{ + struct config_setting_t *member = config_setting_get_member(setting, name); + + if (!member) + return CONFIG_FALSE; + + if (config_setting_type(member) != CONFIG_TYPE_INT) + return CONFIG_FALSE; + + *value = config_setting_get_uint32(member); + + return CONFIG_TRUE; +} + +/** + * Converts and returns a configuration that is CONFIG_TYPE_INT to uint16 + * + * @param setting The setting to read. + * + * @return The converted value. + * @retval 0 in case of failure. + */ +uint16 config_setting_get_uint16(const struct config_setting_t *setting) +{ + if (setting == NULL || setting->type != CONFIG_TYPE_INT) + return 0; + + if (setting->value.ival > UINT16_MAX) + return UINT16_MAX; + if (setting->value.ival < UINT16_MIN) + return UINT16_MIN; + + return (uint16)setting->value.ival; +} + +/** + * Looks up a configuration entry of type CONFIG_TYPE_INT and reads it as uint16. + * + * @param[in] setting The setting to read. + * @param[in] name The setting name to lookup. + * @param[out] value The output value. + * + * @retval CONFIG_TRUE in case of success. + * @retval CONFIG_FALSE in case of failure. + */ +int config_setting_lookup_uint16(const struct config_setting_t *setting, const char *name, uint16 *value) +{ + struct config_setting_t *member = config_setting_get_member(setting, name); + + if (!member) + return CONFIG_FALSE; + + if (config_setting_type(member) != CONFIG_TYPE_INT) + return CONFIG_FALSE; + + *value = config_setting_get_uint16(member); + + return CONFIG_TRUE; +} + +/** + * Converts and returns a configuration that is CONFIG_TYPE_INT to int16 + * + * @param setting The setting to read. + * + * @return The converted value. + * @retval 0 in case of failure. + */ +int16 config_setting_get_int16(const struct config_setting_t *setting) +{ + if (setting == NULL || setting->type != CONFIG_TYPE_INT) + return 0; + + if (setting->value.ival > INT16_MAX) + return INT16_MAX; + if (setting->value.ival < INT16_MIN) + return INT16_MIN; + + return (int16)setting->value.ival; +} + +/** + * Looks up a configuration entry of type CONFIG_TYPE_INT and reads it as int16. + * + * @param[in] setting The setting to read. + * @param[in] name The setting name to lookup. + * @param[out] value The output value. + * + * @retval CONFIG_TRUE in case of success. + * @retval CONFIG_FALSE in case of failure. + */ +int config_setting_lookup_int16(const struct config_setting_t *setting, const char *name, int16 *value) +{ + struct config_setting_t *member = config_setting_get_member(setting, name); + + if (!member) + return CONFIG_FALSE; + + if (config_setting_type(member) != CONFIG_TYPE_INT) + return CONFIG_FALSE; + + *value = config_setting_get_int16(member); + + return CONFIG_TRUE; +} + +/** + * Looks up a configuration entry of type CONFIG_TYPE_STRING inside a struct config_setting_t and copies it into a (non-const) char buffer. + * + * @param[in] setting The setting to read. + * @param[in] name The setting name to lookup. + * @param[out] out The output buffer. + * @param[in] out_size The size of the output buffer. + * + * @retval CONFIG_TRUE in case of success. + * @retval CONFIG_FALSE in case of failure. + */ +int config_setting_lookup_mutable_string(const struct config_setting_t *setting, const char *name, char *out, size_t out_size) +{ + const char *str = NULL; + + if (libconfig->setting_lookup_string(setting, name, &str) == CONFIG_TRUE) { + safestrncpy(out, str, out_size); + return CONFIG_TRUE; + } + + return CONFIG_FALSE; +} + +/** + * Looks up a configuration entry of type CONFIG_TYPE_STRING inside a struct config_t and copies it into a (non-const) char buffer. + * + * @param[in] config The configuration to read. + * @param[in] name The setting name to lookup. + * @param[out] out The output buffer. + * @param[in] out_size The size of the output buffer. + * + * @retval CONFIG_TRUE in case of success. + * @retval CONFIG_FALSE in case of failure. + */ +int config_lookup_mutable_string(const struct config_t *config, const char *name, char *out, size_t out_size) +{ + const char *str = NULL; + + if (libconfig->lookup_string(config, name, &str) == CONFIG_TRUE) { + safestrncpy(out, str, out_size); + return CONFIG_TRUE; + } + + return CONFIG_FALSE; +} + void libconfig_defaults(void) { libconfig = &libconfig_s; libconfig->read = config_read; libconfig->write = config_write; /* */ - libconfig->set_auto_convert = config_set_auto_convert; - libconfig->get_auto_convert = config_get_auto_convert; + libconfig->set_options = config_set_options; + libconfig->get_options = config_get_options; /* */ libconfig->read_string = config_read_string; libconfig->read_file_src = config_read_file; @@ -153,6 +393,7 @@ void libconfig_defaults(void) { libconfig->setting_get_bool = config_setting_get_bool; libconfig->setting_get_string = config_setting_get_string; /* */ + libconfig->setting_lookup = config_setting_lookup; libconfig->setting_lookup_int = config_setting_lookup_int; libconfig->setting_lookup_int64 = config_setting_lookup_int64; libconfig->setting_lookup_float = config_setting_lookup_float; @@ -193,7 +434,6 @@ void libconfig_defaults(void) { libconfig->setting_set_hook = config_setting_set_hook; /* */ libconfig->lookup = config_lookup; - libconfig->lookup_from = config_lookup_from; /* */ libconfig->lookup_int = config_lookup_int; libconfig->lookup_int64 = config_lookup_int64; @@ -201,9 +441,23 @@ void libconfig_defaults(void) { libconfig->lookup_bool = config_lookup_bool; libconfig->lookup_string = config_lookup_string; /* those are custom and are from src/common/conf.c */ - libconfig->read_file = conf_read_file; + libconfig->load_file = config_load_file; libconfig->setting_copy_simple = config_setting_copy_simple; libconfig->setting_copy_elem = config_setting_copy_elem; libconfig->setting_copy_aggregate = config_setting_copy_aggregate; libconfig->setting_copy = config_setting_copy; + + /* Functions to get different types */ + libconfig->setting_get_bool_real = config_setting_get_bool_real; + libconfig->setting_get_uint32 = config_setting_get_uint32; + libconfig->setting_get_uint16 = config_setting_get_uint16; + libconfig->setting_get_int16 = config_setting_get_int16; + + /* Functions to lookup different types */ + libconfig->setting_lookup_int16 = config_setting_lookup_int16; + libconfig->setting_lookup_bool_real = config_setting_lookup_bool_real; + libconfig->setting_lookup_uint32 = config_setting_lookup_uint32; + libconfig->setting_lookup_uint16 = config_setting_lookup_uint16; + libconfig->setting_lookup_mutable_string = config_setting_lookup_mutable_string; + libconfig->lookup_mutable_string = config_lookup_mutable_string; } diff --git a/src/common/conf.h b/src/common/conf.h index 19b13c51a..f2bfcac62 100644 --- a/src/common/conf.h +++ b/src/common/conf.h @@ -29,82 +29,94 @@ * The libconfig interface -- specially for plugins, but we enforce it throughout the core to be consistent **/ struct libconfig_interface { - int (*read) (config_t *config, FILE *stream); - void (*write) (const config_t *config, FILE *stream); + int (*read) (struct config_t *config, FILE *stream); + void (*write) (const struct config_t *config, FILE *stream); /* */ - void (*set_auto_convert) (config_t *config, int flag); // TODO: Replace with config_set_options - int (*get_auto_convert) (const config_t *config); // TODO: Replace with config_get_options + void (*set_options) (struct config_t *config, int options); + int (*get_options) (const struct config_t *config); /* */ - int (*read_string) (config_t *config, const char *str); - int (*read_file_src) (config_t *config, const char *filename); - int (*write_file) (config_t *config, const char *filename); - - void (*set_destructor) (config_t *config, void (*destructor)(void *)); - void (*set_include_dir) (config_t *config, const char *include_dir); - - void (*init) (config_t *config); - void (*destroy) (config_t *config); - - int (*setting_get_int) (const config_setting_t *setting); - long long (*setting_get_int64) (const config_setting_t *setting); - double (*setting_get_float) (const config_setting_t *setting); - - int (*setting_get_bool) (const config_setting_t *setting); - - const char * (*setting_get_string) (const config_setting_t *setting); - - int (*setting_lookup_int) (const config_setting_t *setting, const char *name, int *value); - int (*setting_lookup_int64) (const config_setting_t *setting, const char *name, long long *value); - int (*setting_lookup_float) (const config_setting_t *setting, const char *name, double *value); - int (*setting_lookup_bool) (const config_setting_t *setting, const char *name, int *value); - int (*setting_lookup_string) (const config_setting_t *setting, const char *name, const char **value); - int (*setting_set_int) (config_setting_t *setting ,int value); - int (*setting_set_int64) (config_setting_t *setting, long long value); - int (*setting_set_float) (config_setting_t *setting, double value); - int (*setting_set_bool) (config_setting_t *setting, int value); - int (*setting_set_string) (config_setting_t *setting, const char *value); - - int (*setting_set_format) (config_setting_t *setting, short format); - short (*setting_get_format) (const config_setting_t *setting); - - int (*setting_get_int_elem) (const config_setting_t *setting, int idx); - long long (*setting_get_int64_elem) (const config_setting_t *setting, int idx); - double (*setting_get_float_elem) (const config_setting_t *setting, int idx); - int (*setting_get_bool_elem) (const config_setting_t *setting, int idx); - const char * (*setting_get_string_elem) (const config_setting_t *setting, int idx); - config_setting_t * (*setting_set_int_elem) (config_setting_t *setting, int idx, int value); - config_setting_t * (*setting_set_int64_elem) (config_setting_t *setting, int idx, long long value); - config_setting_t * (*setting_set_float_elem) (config_setting_t *setting, int idx, double value); - config_setting_t * (*setting_set_bool_elem) (config_setting_t *setting, int idx, int value); - config_setting_t * (*setting_set_string_elem) (config_setting_t *setting, int idx, const char *value); - - int (*setting_index) (const config_setting_t *setting); - int (*setting_length) (const config_setting_t *setting); - - config_setting_t * (*setting_get_elem) (const config_setting_t *setting, unsigned int idx); - config_setting_t * (*setting_get_member) (const config_setting_t *setting, const char *name); - - config_setting_t * (*setting_add) (config_setting_t *parent, const char *name, int type); - int (*setting_remove) (config_setting_t *parent, const char *name); - - int (*setting_remove_elem) (config_setting_t *parent, unsigned int idx); - void (*setting_set_hook) (config_setting_t *setting, void *hook); - - config_setting_t * (*lookup) (const config_t *config, const char *filepath); - config_setting_t * (*lookup_from) (config_setting_t *setting, const char *filepath); - int (*lookup_int) (const config_t *config, const char *filepath, int *value); - int (*lookup_int64) (const config_t *config, const char *filepath, long long *value); - int (*lookup_float) (const config_t *config, const char *filepath, double *value); - int (*lookup_bool) (const config_t *config, const char *filepath, int *value); - int (*lookup_string) (const config_t *config, const char *filepath, const char **value); + int (*read_string) (struct config_t *config, const char *str); + int (*read_file_src) (struct config_t *config, const char *filename); + int (*write_file) (struct config_t *config, const char *filename); + + void (*set_destructor) (struct config_t *config, void (*destructor)(void *)); + void (*set_include_dir) (struct config_t *config, const char *include_dir); + + void (*init) (struct config_t *config); + void (*destroy) (struct config_t *config); + + int (*setting_get_int) (const struct config_setting_t *setting); + long long (*setting_get_int64) (const struct config_setting_t *setting); + double (*setting_get_float) (const struct config_setting_t *setting); + + int (*setting_get_bool) (const struct config_setting_t *setting); + + const char * (*setting_get_string) (const struct config_setting_t *setting); + + struct config_setting_t * (*setting_lookup) (struct config_setting_t *setting, const char *name); + int (*setting_lookup_int) (const struct config_setting_t *setting, const char *name, int *value); + int (*setting_lookup_int64) (const struct config_setting_t *setting, const char *name, long long *value); + int (*setting_lookup_float) (const struct config_setting_t *setting, const char *name, double *value); + int (*setting_lookup_bool) (const struct config_setting_t *setting, const char *name, int *value); + int (*setting_lookup_string) (const struct config_setting_t *setting, const char *name, const char **value); + int (*setting_set_int) (struct config_setting_t *setting ,int value); + int (*setting_set_int64) (struct config_setting_t *setting, long long value); + int (*setting_set_float) (struct config_setting_t *setting, double value); + int (*setting_set_bool) (struct config_setting_t *setting, int value); + int (*setting_set_string) (struct config_setting_t *setting, const char *value); + + int (*setting_set_format) (struct config_setting_t *setting, short format); + short (*setting_get_format) (const struct config_setting_t *setting); + + int (*setting_get_int_elem) (const struct config_setting_t *setting, int idx); + long long (*setting_get_int64_elem) (const struct config_setting_t *setting, int idx); + double (*setting_get_float_elem) (const struct config_setting_t *setting, int idx); + int (*setting_get_bool_elem) (const struct config_setting_t *setting, int idx); + const char * (*setting_get_string_elem) (const struct config_setting_t *setting, int idx); + struct config_setting_t * (*setting_set_int_elem) (struct config_setting_t *setting, int idx, int value); + struct config_setting_t * (*setting_set_int64_elem) (struct config_setting_t *setting, int idx, long long value); + struct config_setting_t * (*setting_set_float_elem) (struct config_setting_t *setting, int idx, double value); + struct config_setting_t * (*setting_set_bool_elem) (struct config_setting_t *setting, int idx, int value); + struct config_setting_t * (*setting_set_string_elem) (struct config_setting_t *setting, int idx, const char *value); + + int (*setting_index) (const struct config_setting_t *setting); + int (*setting_length) (const struct config_setting_t *setting); + + struct config_setting_t * (*setting_get_elem) (const struct config_setting_t *setting, unsigned int idx); + struct config_setting_t * (*setting_get_member) (const struct config_setting_t *setting, const char *name); + + struct config_setting_t * (*setting_add) (struct config_setting_t *parent, const char *name, int type); + int (*setting_remove) (struct config_setting_t *parent, const char *name); + + int (*setting_remove_elem) (struct config_setting_t *parent, unsigned int idx); + void (*setting_set_hook) (struct config_setting_t *setting, void *hook); + + struct config_setting_t * (*lookup) (const struct config_t *config, const char *filepath); + int (*lookup_int) (const struct config_t *config, const char *filepath, int *value); + int (*lookup_int64) (const struct config_t *config, const char *filepath, long long *value); + int (*lookup_float) (const struct config_t *config, const char *filepath, double *value); + int (*lookup_bool) (const struct config_t *config, const char *filepath, int *value); + int (*lookup_string) (const struct config_t *config, const char *filepath, const char **value); /* those are custom and are from src/common/conf.c */ /* Functions to copy settings from libconfig/contrib */ - int (*read_file) (config_t *config, const char *config_filename); - void (*setting_copy_simple) (config_setting_t *parent, const config_setting_t *src); - void (*setting_copy_elem) (config_setting_t *parent, const config_setting_t *src); - void (*setting_copy_aggregate) (config_setting_t *parent, const config_setting_t *src); - int (*setting_copy) (config_setting_t *parent, const config_setting_t *src); + int (*load_file) (struct config_t *config, const char *config_filename); + void (*setting_copy_simple) (struct config_setting_t *parent, const struct config_setting_t *src); + void (*setting_copy_elem) (struct config_setting_t *parent, const struct config_setting_t *src); + void (*setting_copy_aggregate) (struct config_setting_t *parent, const struct config_setting_t *src); + int (*setting_copy) (struct config_setting_t *parent, const struct config_setting_t *src); + /* Functions to get other types */ + bool (*setting_get_bool_real) (const struct config_setting_t *setting); + uint32 (*setting_get_uint32) (const struct config_setting_t *setting); + uint16 (*setting_get_uint16) (const struct config_setting_t *setting); + int16 (*setting_get_int16) (const struct config_setting_t *setting); + + int (*setting_lookup_bool_real) (const struct config_setting_t *setting, const char *name, bool *value); + int (*setting_lookup_uint32) (const struct config_setting_t *setting, const char *name, uint32 *value); + int (*setting_lookup_uint16) (const struct config_setting_t *setting, const char *name, uint16 *value); + int (*setting_lookup_int16) (const struct config_setting_t *setting, const char *name, int16 *value); + int (*setting_lookup_mutable_string) (const struct config_setting_t *setting, const char *name, char *out, size_t out_size); + int (*lookup_mutable_string) (const struct config_t *config, const char *name, char *out, size_t out_size); }; #ifdef HERCULES_CORE diff --git a/src/common/console.c b/src/common/console.c index f0702d0da..10e1bee1a 100644 --- a/src/common/console.c +++ b/src/common/console.c @@ -90,6 +90,7 @@ void display_title(void) { ShowInfo("CPU: '"CL_WHITE"%s [%d]"CL_RESET"'\n", sysinfo->cpu(), sysinfo->cpucores()); ShowInfo("Compiled with %s\n", sysinfo->compiler()); ShowInfo("Compile Flags: %s\n", sysinfo->cflags()); + ShowInfo("Timer Function Type: %s\n", sysinfo->time()); } /** diff --git a/src/common/core.c b/src/common/core.c index 201d4f5e8..ccd80c44b 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -230,7 +230,10 @@ bool cmdline_arg_add(unsigned int pluginID, const char *name, char shortname, Cm data->name = aStrdup(name); data->shortname = shortname; data->func = func; - data->help = aStrdup(help); + if (help) + data->help = aStrdup(help); + else + data->help = NULL; data->options = options; return true; diff --git a/src/common/db.c b/src/common/db.c index 361e212cb..ca9a70f7c 100644 --- a/src/common/db.c +++ b/src/common/db.c @@ -353,7 +353,7 @@ static struct db_stats { }; #define DB_COUNTSTAT(token) do { if ((stats.token) != UINT32_MAX) ++(stats.token); } while(0) #else /* !defined(DB_ENABLE_STATS) */ -#define DB_COUNTSTAT(token) +#define DB_COUNTSTAT(token) (void)0 #endif /* !defined(DB_ENABLE_STATS) */ /* [Ind/Hercules] */ diff --git a/src/common/db.h b/src/common/db.h index 205288f13..b73970947 100644 --- a/src/common/db.h +++ b/src/common/db.h @@ -1717,7 +1717,7 @@ HPShared struct db_interface *DB; * @return negative if v1 is top, positive if v2 is top, 0 if equal. */ #define BHEAP_MINTOPCMP(v1, v2) \ - ( v1 == v2 ? 0 : v1 < v2 ? -1 : 1 ) + ( (v1) == (v2) ? 0 : (v1) < (v2) ? -1 : 1 ) /** * Generic comparator for a max-heap (maximum value at top). @@ -1732,6 +1732,6 @@ HPShared struct db_interface *DB; * @return negative if v1 is top, positive if v2 is top, 0 if equal. */ #define BHEAP_MAXTOPCMP(v1, v2) \ - ( v1 == v2 ? 0 : v1 > v2 ? -1 : 1 ) + ( (v1) == (v2) ? 0 : (v1) > (v2) ? -1 : 1 ) #endif /* COMMON_DB_H */ diff --git a/src/common/ers.c b/src/common/ers.c index 85e1fb759..8970fefc2 100644 --- a/src/common/ers.c +++ b/src/common/ers.c @@ -288,7 +288,7 @@ static void ers_obj_destroy(ERS *self) if (instance->Count > 0) if (!(instance->Options & ERS_OPT_CLEAR)) - ShowWarning("Memory leak detected at ERS '%s', %d objects not freed.\n", instance->Name, instance->Count); + ShowWarning("Memory leak detected at ERS '%s', %u objects not freed.\n", instance->Name, instance->Count); if (--instance->Cache->ReferenceCount <= 0) ers_free_cache(instance->Cache, true); @@ -313,7 +313,7 @@ void ers_cache_size(ERS *self, unsigned int new_size) { nullpo_retv(instance); if( !(instance->Cache->Options&ERS_OPT_FLEX_CHUNK) ) { - ShowWarning("ers_cache_size: '%s' has adjusted its chunk size to '%d', however ERS_OPT_FLEX_CHUNK is missing!\n",instance->Name,new_size); + ShowWarning("ers_cache_size: '%s' has adjusted its chunk size to '%u', however ERS_OPT_FLEX_CHUNK is missing!\n", instance->Name, new_size); } instance->Cache->ChunkSize = new_size; @@ -382,7 +382,7 @@ void ers_report(void) { for (cache = CacheList; cache; cache = cache->Next) { cache_c++; ShowMessage(CL_BOLD"[ERS Cache of size '"CL_NORMAL""CL_WHITE"%u"CL_NORMAL""CL_BOLD"' report]\n"CL_NORMAL, cache->ObjectSize); - ShowMessage("\tinstances : %u\n", cache->ReferenceCount); + ShowMessage("\tinstances : %d\n", cache->ReferenceCount); ShowMessage("\tblocks in use : %u/%u\n", cache->UsedObjs, cache->UsedObjs+cache->Free); ShowMessage("\tblocks unused : %u\n", cache->Free); ShowMessage("\tmemory in use : %.2f MB\n", cache->UsedObjs == 0 ? 0. : (double)((cache->UsedObjs * cache->ObjectSize)/1024)/1024); diff --git a/src/common/ers.h b/src/common/ers.h index 938882edd..1689345dc 100644 --- a/src/common/ers.h +++ b/src/common/ers.h @@ -148,15 +148,15 @@ typedef struct eri { #ifdef DISABLE_ERS // Use memory manager to allocate/free and disable other interface functions -# define ers_alloc(obj,type) (type *)aMalloc(sizeof(type)) -# define ers_free(obj,entry) aFree(entry) -# define ers_entry_size(obj) (size_t)0 -# define ers_destroy(obj) -# define ers_chunk_size(obj,size) +# define ers_alloc(obj,type) ((void)(obj), (type *)aMalloc(sizeof(type))) +# define ers_free(obj,entry) ((void)(obj), aFree(entry)) +# define ers_entry_size(obj) ((void)(obj), (size_t)0) +# define ers_destroy(obj) ((void)(obj), (void)0) +# define ers_chunk_size(obj,size) ((void)(obj), (void)(size), (size_t)0) // Disable the public functions # define ers_new(size,name,options) NULL -# define ers_report() -# define ers_final() +# define ers_report() (void)0 +# define ers_final() (void)0 #else /* not DISABLE_ERS */ // These defines should be used to allow the code to keep working whenever // the system is disabled diff --git a/src/common/md5calc.c b/src/common/md5calc.c index 44f912992..bc70d9006 100644 --- a/src/common/md5calc.c +++ b/src/common/md5calc.c @@ -169,7 +169,7 @@ static void MD5_String2binary(const char * string, unsigned char * output) //var /*8bit*/ unsigned char padding_message[64]; //Extended message 512bit 64byte - unsigned char *pstring; //The position of string in the present scanning notes is held. + const unsigned char *pstring; //The position of string in the present scanning notes is held. /*32bit*/ unsigned int string_byte_len, //The byte chief of string is held. @@ -192,7 +192,7 @@ static void MD5_String2binary(const char * string, unsigned char * output) //Step 1.Append Padding Bits (extension of a mark bit) //1-1 string_byte_len = (unsigned int)strlen(string); //The byte chief of a character sequence is acquired. - pstring = (unsigned char *)string; //The position of the present character sequence is set. + pstring = (const unsigned char *)string; //The position of the present character sequence is set. //1-2 Repeat calculation until length becomes less than 64 bytes. for (i=string_byte_len; 64<=i; i-=64,pstring+=64) @@ -200,7 +200,7 @@ static void MD5_String2binary(const char * string, unsigned char * output) //1-3 copy_len = string_byte_len % 64; //The number of bytes which remained is computed. - strncpy((char *)padding_message, (char *)pstring, copy_len); //A message is copied to an extended bit sequence. + strncpy((char *)padding_message, (const char *)pstring, copy_len); //A message is copied to an extended bit sequence. memset(padding_message+copy_len, 0, 64 - copy_len); //It buries by 0 until it becomes extended bit length. padding_message[copy_len] |= 0x80; //The next of a message is 1. diff --git a/src/common/memmgr.c b/src/common/memmgr.c index 97991ceaa..15e55fbeb 100644 --- a/src/common/memmgr.c +++ b/src/common/memmgr.c @@ -45,7 +45,7 @@ struct malloc_interface *iMalloc; # define REALLOC(p,n,file,line,func) mwRealloc((p),(n),(file),(line)) # define STRDUP(p,file,line,func) mwStrdup((p),(file),(line)) # define FREE(p,file,line,func) mwFree((p),(file),(line)) -# define MEMORY_USAGE() (size_t)0 +# define MEMORY_USAGE() ((size_t)0) # define MEMORY_VERIFY(ptr) mwIsSafeAddr((ptr), 1) # define MEMORY_CHECK() CHECK() @@ -67,21 +67,21 @@ struct malloc_interface *iMalloc; # include <gc.h> # ifdef GC_ADD_CALLER -# define RETURN_ADDR 0, +# define MALLOC(n,file,line,func) GC_debug_malloc((n), 0, (file), (line)) +# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), 0, (file), (line)) +# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), 0, (file), (line)) +# define STRDUP(p,file,line,func) GC_debug_strdup((p), 0, (file), (line)) # else -# define RETURN_ADDR +# define MALLOC(n,file,line,func) GC_debug_malloc((n), (file), (line)) +# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), (file), (line)) +# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), (file), (line)) +# define STRDUP(p,file,line,func) GC_debug_strdup((p), (file), (line)) # endif -# define MALLOC(n,file,line,func) GC_debug_malloc((n), RETURN_ADDR (file),(line)) -# define CALLOC(m,n,file,line,func) GC_debug_malloc((m)*(n), RETURN_ADDR (file),(line)) -# define REALLOC(p,n,file,line,func) GC_debug_realloc((p),(n), RETURN_ADDR (file),(line)) -# define STRDUP(p,file,line,func) GC_debug_strdup((p), RETURN_ADDR (file),(line)) # define FREE(p,file,line,func) GC_debug_free(p) # define MEMORY_USAGE() GC_get_heap_size() # define MEMORY_VERIFY(ptr) (GC_base(ptr) != NULL) # define MEMORY_CHECK() GC_gcollect() -# undef RETURN_ADDR - #else # define MALLOC(n,file,line,func) malloc(n) @@ -89,18 +89,18 @@ struct malloc_interface *iMalloc; # define REALLOC(p,n,file,line,func) realloc((p),(n)) # define STRDUP(p,file,line,func) strdup(p) # define FREE(p,file,line,func) free(p) -# define MEMORY_USAGE() (size_t)0 +# define MEMORY_USAGE() ((size_t)0) # define MEMORY_VERIFY(ptr) true -# define MEMORY_CHECK() +# define MEMORY_CHECK() (void)0 #endif #ifndef USE_MEMMGR -#ifdef __APPLE__ +#if defined __APPLE__ #include <malloc/malloc.h> #define BUFFER_SIZE(ptr) malloc_size(ptr) -#elif __FreeBSD__ +#elif defined __FreeBSD__ #include <malloc_np.h> #define BUFFER_SIZE(ptr) malloc_usable_size(ptr) #elif defined __linux__ || defined __linux || defined CYGWIN @@ -149,7 +149,7 @@ void* aRealloc_(void *p, size_t size, const char *file, int line, const char *fu void* aReallocz_(void *p, size_t size, const char *file, int line, const char *func) { - void *ret; + unsigned char *ret = NULL; // ShowMessage("%s:%d: in func %s: aReallocz %p %ld\n",file,line,func,p,size); #ifdef USE_MEMMGR ret = REALLOC(p, size, file, line, func); @@ -159,11 +159,11 @@ void* aReallocz_(void *p, size_t size, const char *file, int line, const char *f size_t oldSize = BUFFER_SIZE(p); ret = REALLOC(p, size, file, line, func); newSize = BUFFER_SIZE(ret); - if (ret && newSize > oldSize) + if (ret != NULL && newSize > oldSize) memset(ret + oldSize, 0, newSize - oldSize); } else { ret = REALLOC(p, size, file, line, func); - if (ret) + if (ret != NULL) memset(ret, 0, BUFFER_SIZE(ret)); } #endif @@ -184,6 +184,36 @@ char* aStrdup_(const char *p, const char *file, int line, const char *func) } return ret; } + +/** + * Copies a string to a newly allocated buffer, setting a maximum length. + * + * The string is always NULL-terminated. If the string is longer than `size`, + * then `size` bytes are copied, not including the appended NULL terminator. + * + * @warning + * If malloc is out of memory, throws a fatal error and aborts the program. + * + * @param p the source string to copy. + * @param size The maximum string length to copy. + * @param file @see ALC_MARK. + * @param line @see ALC_MARK. + * @param func @see ALC_MARK. + * @return the copied string. + */ +char *aStrndup_(const char *p, size_t size, const char *file, int line, const char *func) +{ + size_t len = strnlen(p, size); + char *ret = MALLOC(len + 1, file, line, func); + if (ret == NULL) { + ShowFatalError("%s:%d: in func %s: aStrndup error out of memory!\n", file, line, func); + exit(EXIT_FAILURE); + } + memcpy(ret, p, len); + ret[len] = '\0'; + return ret; +} + void aFree_(void *p, const char *file, int line, const char *func) { // ShowMessage("%s:%d: in func %s: aFree %p\n",file,line,func,p); @@ -305,7 +335,7 @@ void *mmalloc_(size_t size, const char *file, int line, const char *func) { struct unit_head *head; if (((long) size) < 0) { - ShowError("mmalloc_: %"PRIdS"\n", size); + ShowError("mmalloc_: %"PRIuS"\n", size); return NULL; } @@ -478,6 +508,37 @@ char *mstrdup_(const char *p, const char *file, int line, const char *func) { } } +/** + * Copies a string to a newly allocated buffer, setting a maximum length. + * + * The string is always NULL-terminated. If the string is longer than `size`, + * then `size` bytes are copied, not including the appended NULL terminator. + * + * @warning + * If malloc is out of memory, throws a fatal error and aborts the program. + * + * @param p the source string to copy. + * @param size The maximum string length to copy. + * @param file @see ALC_MARK. + * @param line @see ALC_MARK. + * @param func @see ALC_MARK. + * @return the copied string. + * @retval NULL if the source string is NULL or in case of error. + */ +char *mstrndup_(const char *p, size_t size, const char *file, int line, const char *func) +{ + if (p == NULL) { + return NULL; + } else { + size_t len = strnlen(p, size); + char *string = iMalloc->malloc(len + 1, file, line, func); + memcpy(string, p, len); + string[len] = '\0'; + return string; + } +} + + void mfree_(void *ptr, const char *file, int line, const char *func) { struct unit_head *head; @@ -820,7 +881,7 @@ void memmgr_report (int extra) { } for( j = 0; j < 100; j++ ) { if( data[j].size != 0 ) { - ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %d instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024); + ShowMessage("[malloc] : "CL_WHITE"%s"CL_RESET":"CL_WHITE"%d"CL_RESET" %u instances => %.2f MB\n",data[j].file,data[j].line,data[j].count,(double)((data[j].size)/1024)/1024); } } ShowMessage("[malloc] : reporting %u instances | %.2f MB\n",count,(double)((size)/1024)/1024); @@ -947,6 +1008,7 @@ void malloc_defaults(void) { iMalloc->realloc = mrealloc_; iMalloc->reallocz = mreallocz_; iMalloc->astrdup = mstrdup_; + iMalloc->astrndup = mstrndup_; iMalloc->free = mfree_; #else iMalloc->malloc = aMalloc_; @@ -954,6 +1016,7 @@ void malloc_defaults(void) { iMalloc->realloc = aRealloc_; iMalloc->reallocz = aReallocz_;/* not using memory manager huhum o.o perhaps we could still do something about */ iMalloc->astrdup = aStrdup_; + iMalloc->astrndup = aStrndup_; iMalloc->free = aFree_; #endif iMalloc->post_shutdown = NULL; diff --git a/src/common/memmgr.h b/src/common/memmgr.h index 4b06ae56e..680947466 100644 --- a/src/common/memmgr.h +++ b/src/common/memmgr.h @@ -52,6 +52,7 @@ # define aRealloc(p,n) (iMalloc->realloc((p),(n),ALC_MARK)) # define aReallocz(p,n) (iMalloc->reallocz((p),(n),ALC_MARK)) # define aStrdup(p) (iMalloc->astrdup((p),ALC_MARK)) +# define aStrndup(p,n) (iMalloc->astrndup((p),(n),ALC_MARK)) # define aFree(p) (iMalloc->free((p),ALC_MARK)) /////////////// Buffer Creation ///////////////// @@ -60,7 +61,7 @@ #ifdef __GNUC__ // GCC has variable length arrays #define CREATE_BUFFER(name, type, size) type name[size] -#define DELETE_BUFFER(name) +#define DELETE_BUFFER(name) (void)0 #else // others don't, so we emulate them @@ -85,6 +86,7 @@ struct malloc_interface { void* (*realloc)(void *p, size_t size, const char *file, int line, const char *func); void* (*reallocz)(void *p, size_t size, const char *file, int line, const char *func); char* (*astrdup)(const char *p, const char *file, int line, const char *func); + char *(*astrndup)(const char *p, size_t size, const char *file, int line, const char *func); void (*free)(void *p, const char *file, int line, const char *func); /* */ void (*memory_check)(void); diff --git a/src/common/mmo.h b/src/common/mmo.h index eb1d7cc8e..0abae6092 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -98,13 +98,19 @@ #endif // 20090603 #endif // 20070227 -/* Feb 1st 2012 */ -#if PACKETVER >= 20120201 -# define NEW_CARTS -# define MAX_CARTS 9 +#if PACKETVER >= 20150805 /* Cart Decoration */ + #define CART_DECORATION + #define MAX_CARTDECORATION_CARTS 3 // Currently there are 3 Carts available in kRO. [Frost] #else -# define MAX_CARTS 5 + #define MAX_CARTDECORATION_CARTS 0 #endif +#if PACKETVER >= 20120201 /* New Geneticist Carts */ + #define NEW_CARTS + #define MAX_BASE_CARTS 9 +#else + #define MAX_BASE_CARTS 5 +#endif +#define MAX_CARTS (MAX_BASE_CARTS + MAX_CARTDECORATION_CARTS) #define MAX_INVENTORY 100 //Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well. @@ -207,8 +213,15 @@ #define JOBL_BABY 0x2000 //8192 #define JOBL_THIRD 0x4000 //16384 +//Packet DB +#define MIN_PACKET_DB 0x0064 //what's the point of minimum packet id ? [hemagx] +#define MAX_PACKET_DB 0x0F00 +#define MAX_PACKET_POS 20 + #define SCRIPT_VARNAME_LENGTH 32 ///< Maximum length of a script variable +#define INFINITE_DURATION (-1) // Infinite duration for status changes + struct hplugin_data_store; enum item_types { @@ -262,6 +275,7 @@ struct item { //Equip position constants enum equip_pos { + EQP_NONE = 0x000000, EQP_HEAD_LOW = 0x000001, EQP_HEAD_MID = 0x000200, //512 EQP_HEAD_TOP = 0x000100, //256 @@ -380,11 +394,11 @@ struct script_reg_str { char *value; }; -// For saving status changes across sessions. [Skotlex] +/// For saving status changes across sessions. [Skotlex] struct status_change_data { - unsigned short type; //SC_type - int val1, val2, val3, val4; - unsigned int tick; //Remaining duration. + unsigned short type; ///< Status change type (@see enum sc_type) + int val1, val2, val3, val4; ///< Parameters (meaning depends on type). + int tick; ///< Remaining duration. }; struct storage_data { @@ -461,7 +475,7 @@ struct s_elemental { int elemental_id; int char_id; short class_; - int mode; + uint32 mode; int hp, sp, max_hp, max_sp, matk, atk, atk2; short hit, flee, amotion, def, mdef; int life_time; @@ -742,7 +756,8 @@ enum { //Change Member Infos enum guild_permission { // Guild permissions GPERM_INVITE = 0x01, GPERM_EXPEL = 0x10, - GPERM_BOTH = GPERM_INVITE|GPERM_EXPEL, + GPERM_ALL = GPERM_INVITE|GPERM_EXPEL, + GPERM_MASK = GPERM_ALL, }; enum { @@ -956,7 +971,7 @@ enum weapon_type { W_GRENADE, //21 W_HUUMA, //22 W_2HSTAFF, //23 - MAX_WEAPON_TYPE, + MAX_SINGLE_WEAPON_TYPE, // dual-wield constants W_DOUBLE_DD, ///< 2 daggers W_DOUBLE_SS, ///< 2 swords @@ -964,6 +979,7 @@ enum weapon_type { W_DOUBLE_DS, ///< dagger + sword W_DOUBLE_DA, ///< dagger + axe W_DOUBLE_SA, ///< sword + axe + MAX_WEAPON_TYPE, }; enum ammo_type { @@ -1032,4 +1048,8 @@ enum hz_char_ask_name_answer { #error MAX_ZENY is too big #endif +#if MAX_SLOTS < 4 +#error MAX_SLOTS it too small +#endif + #endif /* COMMON_MMO_H */ diff --git a/src/common/mutex.h b/src/common/mutex.h index 5127d9f4b..e49791493 100644 --- a/src/common/mutex.h +++ b/src/common/mutex.h @@ -32,7 +32,7 @@ typedef struct racond racond; // Condition Var * * @return not NULL */ -ramutex *ramutex_create(); +ramutex *ramutex_create(void); /** * Destroys a Mutex @@ -70,7 +70,7 @@ void ramutex_unlock(ramutex *m); * * @return not NULL */ -racond *racond_create(); +racond *racond_create(void); /** * Destroy a Condition variable diff --git a/src/common/showmsg.c b/src/common/showmsg.c index e60b9f536..1c1d4ca8b 100644 --- a/src/common/showmsg.c +++ b/src/common/showmsg.c @@ -23,11 +23,10 @@ #include "showmsg.h" #include "common/cbasetypes.h" +#include "common/conf.h" #include "common/core.h" //[Ind] - For SERVER_TYPE #include "common/strlib.h" // StringBuf -#include <libconfig/libconfig.h> - #include <stdarg.h> #include <stdio.h> #include <stdlib.h> // atexit @@ -478,7 +477,7 @@ int FPRINTF(HANDLE handle, const char *fmt, ...) { return ret; } -#define FFLUSH(handle) +#define FFLUSH(handle) (void)(handle) #define STDOUT GetStdHandle(STD_OUTPUT_HANDLE) #define STDERR GetStdHandle(STD_ERROR_HANDLE) @@ -799,14 +798,14 @@ void showmsg_showWarning(const char *string, ...) vShowMessage_(MSG_WARNING, string, ap); va_end(ap); } -void showmsg_showConfigWarning(config_setting_t *config, const char *string, ...) __attribute__((format(printf, 2, 3))); -void showmsg_showConfigWarning(config_setting_t *config, const char *string, ...) +void showmsg_showConfigWarning(struct config_setting_t *config, const char *string, ...) __attribute__((format(printf, 2, 3))); +void showmsg_showConfigWarning(struct config_setting_t *config, const char *string, ...) { StringBuf buf; va_list ap; StrBuf->Init(&buf); StrBuf->AppendStr(&buf, string); - StrBuf->Printf(&buf, " (%s:%d)\n", config_setting_source_file(config), config_setting_source_line(config)); + StrBuf->Printf(&buf, " (%s:%u)\n", config_setting_source_file(config), config_setting_source_line(config)); va_start(ap, string); vShowMessage_(MSG_WARNING, StrBuf->Value(&buf), ap); va_end(ap); diff --git a/src/common/showmsg.h b/src/common/showmsg.h index ed8776fb0..7b48d0df2 100644 --- a/src/common/showmsg.h +++ b/src/common/showmsg.h @@ -23,10 +23,11 @@ #include "common/hercules.h" -#include <libconfig/libconfig.h> - #include <stdarg.h> +/* Forward Declarations */ +struct config_setting_t; + // for help with the console colors look here: // http://www.edoceo.com/liberum/?doc=printf-with-color // some code explanation (used here): @@ -118,7 +119,7 @@ struct showmsg_interface { void (*showDebug) (const char *, ...) __attribute__((format(printf, 1, 2))); void (*showError) (const char *, ...) __attribute__((format(printf, 1, 2))); void (*showFatalError) (const char *, ...) __attribute__((format(printf, 1, 2))); - void (*showConfigWarning) (config_setting_t *config, const char *string, ...) __attribute__((format(printf, 2, 3))); + void (*showConfigWarning) (struct config_setting_t *config, const char *string, ...) __attribute__((format(printf, 2, 3))); }; /* the purpose of these macros is simply to not make calling them be an annoyance */ diff --git a/src/common/socket.c b/src/common/socket.c index f67c3d074..10712c78b 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -25,6 +25,7 @@ #include "common/HPM.h" #include "common/cbasetypes.h" +#include "common/conf.h" #include "common/db.h" #include "common/memmgr.h" #include "common/mmo.h" @@ -76,11 +77,11 @@ struct socket_interface *sockt; struct socket_data **session; #ifdef SEND_SHORTLIST - // Add a fd to the shortlist so that it'll be recognized as a fd that needs - // sending done on it. - void send_shortlist_add_fd(int fd); - // Do pending network sends (and eof handling) from the shortlist. - void send_shortlist_do_sends(); +// Add a fd to the shortlist so that it'll be recognized as a fd that needs +// sending done on it. +void send_shortlist_add_fd(int fd); +// Do pending network sends (and eof handling) from the shortlist. +void send_shortlist_do_sends(void); #endif ///////////////////////////////////////////////////////////////////// @@ -624,7 +625,7 @@ int make_connection(uint32 ip, uint16 port, struct hSockOpt *opt) { remote_address.sin_port = htons(port); if( !( opt && opt->silent ) ) - ShowStatus("Connecting to %d.%d.%d.%d:%i\n", CONVIP(ip), port); + ShowStatus("Connecting to %u.%u.%u.%u:%i\n", CONVIP(ip), port); result = sConnect(fd, (struct sockaddr *)(&remote_address), sizeof(struct sockaddr_in)); if( result == SOCKET_ERROR ) { @@ -757,7 +758,7 @@ int wfifoset(int fd, size_t len) if (s->wdata_size+len > s->max_wdata) { // actually there was a buffer overflow already uint32 ip = s->client_addr; - ShowFatalError("WFIFOSET: Write Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %u bytes on a %u/%u bytes buffer.\n", fd, CONVIP(ip), (unsigned int)len, (unsigned int)s->wdata_size, (unsigned int)s->max_wdata); + ShowFatalError("WFIFOSET: Write Buffer Overflow. Connection %d (%u.%u.%u.%u) has written %u bytes on a %u/%u bytes buffer.\n", fd, CONVIP(ip), (unsigned int)len, (unsigned int)s->wdata_size, (unsigned int)s->max_wdata); ShowDebug("Likely command that caused it: 0x%x\n", (*(uint16*)(s->wdata + s->wdata_size))); // no other chance, make a better fifo model exit(EXIT_FAILURE); @@ -767,7 +768,7 @@ int wfifoset(int fd, size_t len) { // dynamic packets allow up to UINT16_MAX bytes (<packet_id>.W <packet_len>.W ...) // all known fixed-size packets are within this limit, so use the same limit - ShowFatalError("WFIFOSET: Packet 0x%x is too big. (len=%u, max=%u)\n", (*(uint16*)(s->wdata + s->wdata_size)), (unsigned int)len, 0xFFFF); + ShowFatalError("WFIFOSET: Packet 0x%x is too big. (len=%u, max=%u)\n", (*(uint16*)(s->wdata + s->wdata_size)), (unsigned int)len, 0xFFFFU); exit(EXIT_FAILURE); } else if( len == 0 ) @@ -984,7 +985,7 @@ static int connect_check(uint32 ip) { int result = connect_check_(ip); if( access_debug ) { - ShowInfo("connect_check: Connection from %d.%d.%d.%d %s\n", CONVIP(ip),result ? "allowed." : "denied!"); + ShowInfo("connect_check: Connection from %u.%u.%u.%u %s\n", CONVIP(ip),result ? "allowed." : "denied!"); } return result; } @@ -1004,7 +1005,7 @@ static int connect_check_(uint32 ip) for( i=0; i < access_allownum; ++i ){ if (SUBNET_MATCH(ip, access_allow[i].ip, access_allow[i].mask)) { if( access_debug ){ - ShowInfo("connect_check: Found match from allow list:%d.%d.%d.%d IP:%d.%d.%d.%d Mask:%d.%d.%d.%d\n", + ShowInfo("connect_check: Found match from allow list:%u.%u.%u.%u IP:%u.%u.%u.%u Mask:%u.%u.%u.%u\n", CONVIP(ip), CONVIP(access_allow[i].ip), CONVIP(access_allow[i].mask)); @@ -1017,7 +1018,7 @@ static int connect_check_(uint32 ip) for( i=0; i < access_denynum; ++i ){ if (SUBNET_MATCH(ip, access_deny[i].ip, access_deny[i].mask)) { if( access_debug ){ - ShowInfo("connect_check: Found match from deny list:%d.%d.%d.%d IP:%d.%d.%d.%d Mask:%d.%d.%d.%d\n", + ShowInfo("connect_check: Found match from deny list:%u.%u.%u.%u IP:%u.%u.%u.%u Mask:%u.%u.%u.%u\n", CONVIP(ip), CONVIP(access_deny[i].ip), CONVIP(access_deny[i].mask)); @@ -1064,7 +1065,7 @@ static int connect_check_(uint32 ip) hist->tick = timer->gettick(); if( ++hist->count >= ddos_count ) {// DDoS attack detected hist->ddos = 1; - ShowWarning("connect_check: DDoS Attack detected from %d.%d.%d.%d!\n", CONVIP(ip)); + ShowWarning("connect_check: DDoS Attack detected from %u.%u.%u.%u!\n", CONVIP(ip)); return (connect_ok == 2 ? 1 : 0); } return connect_ok; @@ -1103,7 +1104,7 @@ static int connect_check_clear(int tid, int64 tick, int id, intptr_t data) { clear++; } list++; - } + } dbi_destroy(iter); if( access_debug ){ @@ -1152,7 +1153,7 @@ int access_ipmask(const char* str, AccessControl* acc) } } if( access_debug ){ - ShowInfo("access_ipmask: Loaded IP:%d.%d.%d.%d mask:%d.%d.%d.%d\n", CONVIP(ip), CONVIP(mask)); + ShowInfo("access_ipmask: Loaded IP:%u.%u.%u.%u mask:%u.%u.%u.%u\n", CONVIP(ip), CONVIP(mask)); } acc->ip = ip; acc->mask = mask; @@ -1428,7 +1429,7 @@ void socket_init(void) timer->add_interval(timer->gettick()+1000, connect_check_clear, 0, 0, 5*60*1000); #endif - ShowInfo("Server supports up to '"CL_WHITE"%"PRId64""CL_RESET"' concurrent connections.\n", rlim_cur); + ShowInfo("Server supports up to '"CL_WHITE"%"PRIu64""CL_RESET"' concurrent connections.\n", rlim_cur); } bool session_is_valid(int fd) @@ -1570,7 +1571,7 @@ void send_shortlist_add_fd(int fd) } // Do pending network sends and eof handling from the shortlist. -void send_shortlist_do_sends() +void send_shortlist_do_sends(void) { int i; @@ -1686,7 +1687,7 @@ bool socket_trusted_ip_check(uint32 ip) * @param[in] groupname Current group name, for output/logging reasons. * @return The amount of entries read, zero in case of errors. */ -int socket_net_config_read_sub(config_setting_t *t, struct s_subnet_vector *list, const char *filename, const char *groupname) +int socket_net_config_read_sub(struct config_setting_t *t, struct s_subnet_vector *list, const char *filename, const char *groupname) { int i, len; char ipbuf[64], maskbuf[64]; @@ -1722,11 +1723,11 @@ int socket_net_config_read_sub(config_setting_t *t, struct s_subnet_vector *list */ void socket_net_config_read(const char *filename) { - config_t network_config; + struct config_t network_config; int i; nullpo_retv(filename); - if (libconfig->read_file(&network_config, filename)) { + if (!libconfig->load_file(&network_config, filename)) { ShowError("LAN Support configuration file is not found: '%s'. This server won't be able to accept connections from any servers.\n", filename); return; } diff --git a/src/common/socket.h b/src/common/socket.h index b33fd2acf..947ea8d3e 100644 --- a/src/common/socket.h +++ b/src/common/socket.h @@ -22,7 +22,6 @@ #define COMMON_SOCKET_H #include "common/hercules.h" -#include "common/conf.h" #include "common/db.h" #ifdef WIN32 @@ -34,7 +33,9 @@ # include <sys/types.h> #endif +/* Forward Declarations */ struct hplugin_data_store; +struct config_setting_t; #define FIFOSIZE_SERVERLINK 256*1024 @@ -46,16 +47,16 @@ struct hplugin_data_store; sockt->realloc_writefifo((fd), (size)); \ } while(0) -#define RFIFOP(fd,pos) (sockt->session[fd]->rdata + sockt->session[fd]->rdata_pos + (pos)) -#define WFIFOP(fd,pos) (sockt->session[fd]->wdata + sockt->session[fd]->wdata_size + (pos)) +#define RFIFOP(fd,pos) ((const void *)(sockt->session[fd]->rdata + sockt->session[fd]->rdata_pos + (pos))) +#define WFIFOP(fd,pos) ((void *)(sockt->session[fd]->wdata + sockt->session[fd]->wdata_size + (pos))) -#define RFIFOB(fd,pos) (*(uint8*)RFIFOP((fd),(pos))) +#define RFIFOB(fd,pos) (*(const uint8*)RFIFOP((fd),(pos))) #define WFIFOB(fd,pos) (*(uint8*)WFIFOP((fd),(pos))) -#define RFIFOW(fd,pos) (*(uint16*)RFIFOP((fd),(pos))) +#define RFIFOW(fd,pos) (*(const uint16*)RFIFOP((fd),(pos))) #define WFIFOW(fd,pos) (*(uint16*)WFIFOP((fd),(pos))) -#define RFIFOL(fd,pos) (*(uint32*)RFIFOP((fd),(pos))) +#define RFIFOL(fd,pos) (*(const uint32*)RFIFOP((fd),(pos))) #define WFIFOL(fd,pos) (*(uint32*)WFIFOP((fd),(pos))) -#define RFIFOQ(fd,pos) (*(uint64*)RFIFOP((fd),(pos))) +#define RFIFOQ(fd,pos) (*(const uint64*)RFIFOP((fd),(pos))) #define WFIFOQ(fd,pos) (*(uint64*)WFIFOP((fd),(pos))) #define RFIFOSPACE(fd) (sockt->session[fd]->max_rdata - sockt->session[fd]->rdata_size) #define WFIFOSPACE(fd) (sockt->session[fd]->max_wdata - sockt->session[fd]->wdata_size) @@ -76,16 +77,31 @@ struct hplugin_data_store; #define RFIFOSKIP(fd, len) (sockt->rfifoskip(fd, len)) /* [Ind/Hercules] */ -#define RFIFO2PTR(fd) (void*)(sockt->session[fd]->rdata + sockt->session[fd]->rdata_pos) +#define RFIFO2PTR(fd) ((const void *)(sockt->session[fd]->rdata + sockt->session[fd]->rdata_pos)) +#define RP2PTR(fd) RFIFO2PTR(fd) -// buffer I/O macros -#define RBUFP(p,pos) (((uint8*)(p)) + (pos)) -#define RBUFB(p,pos) (*(uint8*)RBUFP((p),(pos))) -#define RBUFW(p,pos) (*(uint16*)RBUFP((p),(pos))) -#define RBUFL(p,pos) (*(uint32*)RBUFP((p),(pos))) -#define RBUFQ(p,pos) (*(uint64*)RBUFP((p),(pos))) +/* [Hemagx/Hercules] */ +#define WFIFO2PTR(fd) ((void *)(sockt->session[fd]->wdata + sockt->session[fd]->wdata_size)) +#define WP2PTR(fd) WFIFO2PTR(fd) -#define WBUFP(p,pos) (((uint8*)(p)) + (pos)) +// buffer I/O macros +static inline const void *RBUFP_(const void *p, int pos) __attribute__((const, unused)); +static inline const void *RBUFP_(const void *p, int pos) +{ + return ((const uint8 *)p) + pos; +} +#define RBUFP(p,pos) RBUFP_(p, (int)(pos)) +#define RBUFB(p,pos) (*(const uint8 *)RBUFP((p),(pos))) +#define RBUFW(p,pos) (*(const uint16 *)RBUFP((p),(pos))) +#define RBUFL(p,pos) (*(const uint32 *)RBUFP((p),(pos))) +#define RBUFQ(p,pos) (*(const uint64 *)RBUFP((p),(pos))) + +static inline void *WBUFP_(void *p, int pos) __attribute__((const, unused)); +static inline void *WBUFP_(void *p, int pos) +{ + return ((uint8 *)p) + pos; +} +#define WBUFP(p,pos) WBUFP_(p, (int)(pos)) #define WBUFB(p,pos) (*(uint8*)WBUFP((p),(pos))) #define WBUFW(p,pos) (*(uint16*)WBUFP((p),(pos))) #define WBUFL(p,pos) (*(uint32*)WBUFP((p),(pos))) @@ -209,7 +225,7 @@ struct socket_interface { uint32 (*lan_subnet_check) (uint32 ip, struct s_subnet *info); bool (*allowed_ip_check) (uint32 ip); bool (*trusted_ip_check) (uint32 ip); - int (*net_config_read_sub) (config_setting_t *t, struct s_subnet_vector *list, const char *filename, const char *groupname); + int (*net_config_read_sub) (struct config_setting_t *t, struct s_subnet_vector *list, const char *filename, const char *groupname); void (*net_config_read) (const char *filename); }; diff --git a/src/common/sql.c b/src/common/sql.c index f6280c436..ed93169ea 100644 --- a/src/common/sql.c +++ b/src/common/sql.c @@ -32,6 +32,7 @@ # include "common/winapi.h" // Needed before mysql.h #endif #include <mysql.h> +#include <stdio.h> #include <stdlib.h> // strtoul void hercules_mysql_error_handler(unsigned int ecode); @@ -466,7 +467,7 @@ static int Sql_P_BindSqlDataType(MYSQL_BIND* bind, enum SqlDataType buffer_type, case SQLDT_BLOB: bind->buffer_type = MYSQL_TYPE_BLOB; break; default: - ShowDebug("Sql_P_BindSqlDataType: unsupported buffer type (%d)\n", buffer_type); + ShowDebug("Sql_P_BindSqlDataType: unsupported buffer type (%u)\n", buffer_type); return SQL_ERROR; } bind->buffer = buffer; @@ -869,7 +870,7 @@ void hercules_mysql_error_handler(unsigned int ecode) { case 2003:/* Can't connect to MySQL (this error only happens here when failing to reconnect) */ if( mysql_reconnect_type == 1 ) { if( ++retry > mysql_reconnect_count ) { - ShowFatalError("MySQL has been unreachable for too long, %d reconnects were attempted. Shutting Down\n", retry); + ShowFatalError("MySQL has been unreachable for too long, %u reconnects were attempted. Shutting Down\n", retry); exit(EXIT_FAILURE); } } @@ -971,7 +972,7 @@ void Sql_HerculesUpdateCheck(Sql* self) { fclose(ifp); if( performed ) { - ShowSQL("- detected %d new "CL_WHITE"SQL updates"CL_RESET"\n",performed); + ShowSQL("- detected %u new "CL_WHITE"SQL updates"CL_RESET"\n",performed); ShowMessage("%s",StrBuf->Value(&buf)); ShowSQL("To manually skip, type: 'sql update skip <file name>'\n"); } diff --git a/src/common/sql.h b/src/common/sql.h index 33643407d..e949a8280 100644 --- a/src/common/sql.h +++ b/src/common/sql.h @@ -272,13 +272,13 @@ void Sql_HerculesUpdateSkip(Sql* self,const char *filename); HPShared struct sql_interface *SQL; #if defined(SQL_REMOVE_SHOWDEBUG) -#define Sql_ShowDebug(self) (void)0 +#define Sql_ShowDebug(self) (void)(self) #else #define Sql_ShowDebug(self) (SQL->ShowDebug_((self), __FILE__, __LINE__)) #endif #if defined(SQL_REMOVE_SHOWDEBUG) -#define SqlStmt_ShowDebug(self) (void)0 +#define SqlStmt_ShowDebug(self) (void)(self) #else /// Shows debug information (with statement). #define SqlStmt_ShowDebug(self) (SQL->StmtShowDebug_((self), __FILE__, __LINE__)) diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index dbedfa2db..95f423ff7 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -38,6 +38,7 @@ #ifdef WIN32 # include <windows.h> #else +# include <sys/time.h> // time constants # include <unistd.h> #endif @@ -65,7 +66,7 @@ struct sysinfo_interface *sysinfo; #define VCSTYPE_UNKNOWN 0 #define VCSTYPE_GIT 1 #define VCSTYPE_SVN 2 -#define VCSTYPE_NONE -1 +#define VCSTYPE_NONE (-1) #ifdef WIN32 /** @@ -1052,6 +1053,19 @@ void sysinfo_final(void) { sysinfo->p->vcstype_name = NULL; } +static const char *sysinfo_time(void) +{ +#if defined(WIN32) + return "ticks count"; +#elif defined(ENABLE_RDTSC) + return "rdtsc"; +#elif defined(HAVE_MONOTONIC_CLOCK) + return "monotonic clock"; +#else + return "time of day"; +#endif +} + /** * Interface default values initialization. */ @@ -1072,6 +1086,7 @@ void sysinfo_defaults(void) { sysinfo->is64bit = sysinfo_is64bit; sysinfo->compiler = sysinfo_compiler; sysinfo->cflags = sysinfo_cflags; + sysinfo->time = sysinfo_time; sysinfo->vcstype = sysinfo_vcstype; sysinfo->vcstypeid = sysinfo_vcstypeid; sysinfo->vcsrevision_src = sysinfo_vcsrevision_src; diff --git a/src/common/sysinfo.h b/src/common/sysinfo.h index 904be832f..2a391bfa4 100644 --- a/src/common/sysinfo.h +++ b/src/common/sysinfo.h @@ -52,6 +52,7 @@ struct sysinfo_interface { bool (*is64bit) (void); const char *(*compiler) (void); const char *(*cflags) (void); + const char *(*time) (void); const char *(*vcstype) (void); int (*vcstypeid) (void); const char *(*vcsrevision_src) (void); diff --git a/src/common/thread.c b/src/common/thread.c index 6012791e2..b724344e6 100644 --- a/src/common/thread.c +++ b/src/common/thread.c @@ -263,7 +263,7 @@ int rathread_get_tid(void) { #ifdef WIN32 return (int)GetCurrentThreadId(); #else - return (intptr_t)pthread_self(); + return (int)pthread_self(); #endif #endif diff --git a/src/common/timer.c b/src/common/timer.c index 7f71157ae..e7a57481a 100644 --- a/src/common/timer.c +++ b/src/common/timer.c @@ -25,6 +25,7 @@ #include "common/cbasetypes.h" #include "common/db.h" #include "common/memmgr.h" +#include "common/nullpo.h" #include "common/showmsg.h" #include "common/utils.h" @@ -87,6 +88,8 @@ struct timer_func_list { int timer_add_func_list(TimerFunc func, char* name) { struct timer_func_list* tfl; + nullpo_ret(func); + nullpo_ret(name); if (name) { for( tfl=tfl_root; tfl != NULL; tfl=tfl->next ) {// check suspicious cases @@ -303,7 +306,19 @@ static int acquire_timer(void) { int timer_add(int64 tick, TimerFunc func, int id, intptr_t data) { int tid; + nullpo_retr(INVALID_TIMER, func); + tid = acquire_timer(); + if (timer_data[tid].type != 0 && timer_data[tid].type != TIMER_REMOVE_HEAP) + { + ShowError("timer_add error: wrong tid type: %d, [%d]%p(%s) -> %p(%s)\n", timer_data[tid].type, tid, func, search_timer_func_list(func), timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + Assert_retr(INVALID_TIMER, 0); + } + if (timer_data[tid].func != NULL) + { + ShowError("timer_add error: func non NULL: [%d]%p(%s) -> %p(%s)\n", tid, func, search_timer_func_list(func), timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + Assert_retr(INVALID_TIMER, 0); + } timer_data[tid].tick = tick; timer_data[tid].func = func; timer_data[tid].id = id; @@ -317,9 +332,11 @@ int timer_add(int64 tick, TimerFunc func, int id, intptr_t data) { /// Starts a new timer that automatically restarts itself (infinite loop until manually removed). /// Returns the timer's id, or INVALID_TIMER if it fails. -int timer_add_interval(int64 tick, TimerFunc func, int id, intptr_t data, int interval) { +int timer_add_interval(int64 tick, TimerFunc func, int id, intptr_t data, int interval) +{ int tid; + nullpo_retr(INVALID_TIMER, func); if (interval < 1) { ShowError("timer_add_interval: invalid interval (tick=%"PRId64" %p[%s] id=%d data=%"PRIdPTR" diff_tick=%"PRId64")\n", tick, func, search_timer_func_list(func), id, data, DIFF_TICK(tick, timer->gettick())); @@ -327,6 +344,18 @@ int timer_add_interval(int64 tick, TimerFunc func, int id, intptr_t data, int in } tid = acquire_timer(); + if (timer_data[tid].type != 0 && timer_data[tid].type != TIMER_REMOVE_HEAP) + { + ShowError("timer_add_interval: wrong tid type: %d, [%d]%p(%s) -> %p(%s)\n", timer_data[tid].type, tid, func, search_timer_func_list(func), timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + Assert_retr(INVALID_TIMER, 0); + return INVALID_TIMER; + } + if (timer_data[tid].func != NULL) + { + ShowError("timer_add_interval: func non NULL: [%d]%p(%s) -> %p(%s)\n", tid, func, search_timer_func_list(func), timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + Assert_retr(INVALID_TIMER, 0); + return INVALID_TIMER; + } timer_data[tid].tick = tick; timer_data[tid].func = func; timer_data[tid].id = id; @@ -346,16 +375,28 @@ const struct TimerData* timer_get(int tid) { /// Marks a timer specified by 'id' for immediate deletion once it expires. /// Param 'func' is used for debug/verification purposes. /// Returns 0 on success, < 0 on failure. -int timer_do_delete(int tid, TimerFunc func) { +int timer_do_delete(int tid, TimerFunc func) +{ + nullpo_ret(func); + if( tid < 0 || tid >= timer_data_num ) { - ShowError("timer_do_delete error : no such timer %d (%p(%s))\n", tid, func, search_timer_func_list(func)); + ShowError("timer_do_delete error : no such timer [%d](%p(%s))\n", tid, func, search_timer_func_list(func)); + Assert_retr(-1, 0); return -1; } if( timer_data[tid].func != func ) { - ShowError("timer_do_delete error : function mismatch %p(%s) != %p(%s)\n", timer_data[tid].func, search_timer_func_list(timer_data[tid].func), func, search_timer_func_list(func)); + ShowError("timer_do_delete error : function mismatch [%d]%p(%s) != %p(%s)\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func), func, search_timer_func_list(func)); + Assert_retr(-2, 0); return -2; } + if (timer_data[tid].type == 0 || timer_data[tid].type == TIMER_REMOVE_HEAP) + { + ShowError("timer_do_delete: timer already deleted: %d, [%d]%p(%s) -> %p(%s)\n", timer_data[tid].type, tid, func, search_timer_func_list(func), func, search_timer_func_list(func)); + Assert_retr(-3, 0); + return -3; + } + timer_data[tid].func = NULL; timer_data[tid].type = TIMER_ONCE_AUTODEL; @@ -383,7 +424,19 @@ int64 timer_settick(int tid, int64 tick) // search timer position ARR_FIND(0, BHEAP_LENGTH(timer_heap), i, BHEAP_DATA(timer_heap)[i] == tid); if (i == BHEAP_LENGTH(timer_heap)) { - ShowError("timer_settick: no such timer %d (%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + ShowError("timer_settick: no such timer [%d](%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + Assert_retr(-1, 0); + return -1; + } + + if (timer_data[tid].type == 0 || timer_data[tid].type == TIMER_REMOVE_HEAP) { + ShowError("timer_settick error: set tick for deleted timer %d, [%d](%p(%s))\n", timer_data[tid].type, tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + Assert_retr(-1, 0); + return -1; + } + if (timer_data[tid].func == NULL) { + ShowError("timer_settick error: set tick for timer with wrong func [%d](%p(%s))\n", tid, timer_data[tid].func, search_timer_func_list(timer_data[tid].func)); + Assert_retr(-1, 0); return -1; } @@ -438,6 +491,7 @@ int do_timer(int64 tick) default: case TIMER_ONCE_AUTODEL: timer_data[tid].type = 0; + timer_data[tid].func = NULL; if (free_timer_list_pos >= free_timer_list_max) { free_timer_list_max += 256; RECREATE(free_timer_list,int,free_timer_list_max); diff --git a/src/common/utils.c b/src/common/utils.c index dcf0a749a..73df3aae1 100644 --- a/src/common/utils.c +++ b/src/common/utils.c @@ -25,6 +25,7 @@ #include "common/cbasetypes.h" #include "common/core.h" #include "common/mmo.h" +#include "common/nullpo.h" #include "common/showmsg.h" #include "common/socket.h" #include "common/strlib.h" @@ -352,6 +353,48 @@ unsigned int get_percentage(const unsigned int A, const unsigned int B) return (unsigned int)floor(result); } +/** + * Applies a percentual rate modifier. + * + * @param value The base value. + * @param rate The rate modifier to apply. + * @param stdrate The rate modifier's divider (rate == stdrate => 100%). + * @return The modified value. + */ +int64 apply_percentrate64(int64 value, int rate, int stdrate) +{ + Assert_ret(stdrate > 0); + Assert_ret(rate >= 0); + if (rate == stdrate) + return value; + if (rate == 0) + return 0; + if (INT64_MAX / rate < value) { + // Give up some precision to prevent overflows + return value / stdrate * rate; + } + return value * rate / stdrate; +} + +/** + * Applies a percentual rate modifier. + * + * @param value The base value. + * @param rate The rate modifier to apply. Must be <= maxrate. + * @param maxrate The rate modifier's divider (maxrate = 100%). + * @return The modified value. + */ +int apply_percentrate(int value, int rate, int maxrate) +{ + Assert_ret(maxrate > 0); + Assert_ret(rate >= 0); + if (rate == maxrate) + return value; + if (rate == 0) + return 0; + return (int)(value * (int64)rate / maxrate); +} + //----------------------------------------------------- // custom timestamp formatting (from eApp) //----------------------------------------------------- diff --git a/src/common/utils.h b/src/common/utils.h index da2a29317..c5f64124f 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -24,6 +24,9 @@ #include "common/hercules.h" #include <stdio.h> // FILE* +#ifndef WIN32 +# include <unistd.h> // sleep() +#endif /* [HCache] 1-byte key to ensure our method is the latest, we can modify to ensure the method matches */ #define HCACHE_KEY 'k' @@ -42,6 +45,9 @@ bool exists(const char* filename); /// calculates the value of A / B, in percent (rounded down) unsigned int get_percentage(const unsigned int A, const unsigned int B); +int64 apply_percentrate64(int64 value, int rate, int maxrate); +int apply_percentrate(int value, int rate, int maxrate); + const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format); ////////////////////////////////////////////////////////////////////////// |