summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/HPM.c24
-rw-r--r--src/common/HPM.h2
-rw-r--r--src/common/HPMDataCheck.h2
-rw-r--r--src/common/Makefile.in2
-rw-r--r--src/common/cbasetypes.h2
-rw-r--r--src/common/conf.c288
-rw-r--r--src/common/conf.h154
-rw-r--r--src/common/console.c1
-rw-r--r--src/common/core.c5
-rw-r--r--src/common/db.c2
-rw-r--r--src/common/db.h4
-rw-r--r--src/common/ers.c6
-rw-r--r--src/common/ers.h14
-rw-r--r--src/common/md5calc.c6
-rw-r--r--src/common/memmgr.c99
-rw-r--r--src/common/memmgr.h4
-rw-r--r--src/common/mmo.h44
-rw-r--r--src/common/mutex.h4
-rw-r--r--src/common/showmsg.c11
-rw-r--r--src/common/showmsg.h7
-rw-r--r--src/common/socket.c39
-rw-r--r--src/common/socket.h48
-rw-r--r--src/common/sql.c7
-rw-r--r--src/common/sql.h4
-rw-r--r--src/common/sysinfo.c17
-rw-r--r--src/common/sysinfo.h1
-rw-r--r--src/common/thread.c2
-rw-r--r--src/common/timer.c64
-rw-r--r--src/common/utils.c43
-rw-r--r--src/common/utils.h6
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);
//////////////////////////////////////////////////////////////////////////