summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/Makefile.in9
-rw-r--r--src/char/char.c117
-rw-r--r--src/char/char.h2
-rw-r--r--src/char/int_storage.c78
-rw-r--r--src/common/HPM.c5
-rw-r--r--src/common/HPM.h2
-rw-r--r--src/common/HPMDataCheck.h5
-rw-r--r--src/common/HPMi.h16
-rw-r--r--src/common/Makefile.in24
-rw-r--r--src/common/console.c15
-rw-r--r--src/common/console.h4
-rw-r--r--src/common/core.c151
-rw-r--r--src/common/core.h14
-rw-r--r--src/common/des.h5
-rw-r--r--src/common/grfio.h4
-rw-r--r--src/common/malloc.c8
-rw-r--r--src/common/mmo.h142
-rw-r--r--src/common/socket.h2
-rw-r--r--src/common/sysinfo.c1022
-rw-r--r--src/common/sysinfo.h62
-rw-r--r--src/common/timer.h4
-rw-r--r--src/login/Makefile.in9
-rw-r--r--src/map/Makefile.in9
-rw-r--r--src/map/atcommand.c102
-rw-r--r--src/map/battle.c75
-rw-r--r--src/map/battle.h1
-rw-r--r--src/map/chrif.c57
-rw-r--r--src/map/clif.c46
-rw-r--r--src/map/guild.c1
-rw-r--r--src/map/map.c8
-rw-r--r--src/map/map.h2
-rw-r--r--src/map/npc.c17
-rw-r--r--src/map/pc.c33
-rw-r--r--src/map/pc.h28
-rw-r--r--src/map/script.c17
-rw-r--r--src/map/trade.h4
-rw-r--r--src/map/vending.h4
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Hooks.inc3
-rw-r--r--src/plugins/Makefile.in5
-rw-r--r--src/test/Makefile.in25
-rw-r--r--src/tool/Makefile.in29
41 files changed, 1662 insertions, 504 deletions
diff --git a/src/char/Makefile.in b/src/char/Makefile.in
index ab1e7c234..ecaad3602 100644
--- a/src/char/Makefile.in
+++ b/src/char/Makefile.in
@@ -1,9 +1,12 @@
+# Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+# See the LICENSE file
CONFIG_D = ../config
CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h)
COMMON_D = ../common
COMMON_H = $(wildcard $(COMMON_D)/*.h)
+SYSINFO_INC = $(COMMON_D)/sysinfo.inc
LIBCONFIG_D = ../../3rdparty/libconfig
LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \
@@ -27,7 +30,7 @@ CHAR_H = char.h inter.h int_auction.h int_elemental.h int_guild.h int_homun.h \
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
- CHAR_SERVER_SQL_DEPENDS=$(CHAR_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ)
+ CHAR_SERVER_SQL_DEPENDS=$(CHAR_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) $(SYSINFO_INC)
else
CHAR_SERVER_SQL_DEPENDS=needs_mysql
endif
@@ -66,6 +69,10 @@ help:
Makefile: Makefile.in
@$(MAKE) -C ../.. src/char/Makefile
+$(SYSINFO_INC): $(CHAR_C) $(CHAR_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H)
+ @echo " MAKE $@"
+ @$(MAKE) -C ../.. sysinfo
+
needs_mysql:
@echo "MySQL not found or disabled by the configure script"
@exit 1
diff --git a/src/char/char.c b/src/char/char.c
index a4bc9cef9..cf961fd93 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -2419,71 +2419,82 @@ int parse_fromlogin(int fd) {
{
unsigned char buf[7];
+ int char_id[MAX_CHARS];
+ int class_[MAX_CHARS];
+ int guild_id[MAX_CHARS];
+ int num;
+ int i;
+ char* data;
+ struct auth_node* node;
+
int acc = RFIFOL(fd,2);
int sex = RFIFOB(fd,6);
+
RFIFOSKIP(fd,7);
- if( acc > 0 )
- {// TODO: Is this even possible?
- int char_id[MAX_CHARS];
- int class_[MAX_CHARS];
- int guild_id[MAX_CHARS];
- int num;
- int i;
- char* data;
+ // This should _never_ happen
+ if( acc <= 0 ) {
+ ShowError("Received invalid account id from login server! (aid: %d)\n", acc);
+ return 0;
+ }
- struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc);
- if( node != NULL )
- node->sex = sex;
+ node = (struct auth_node*)idb_get(auth_db, acc);
+ if( node != NULL )
+ node->sex = sex;
- // get characters
- if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc) )
- Sql_ShowDebug(sql_handle);
- for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i )
+ // get characters
+ if( SQL_ERROR == SQL->Query(sql_handle, "SELECT `char_id`,`class`,`guild_id` FROM `%s` WHERE `account_id` = '%d'", char_db, acc) )
+ Sql_ShowDebug(sql_handle);
+ for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SQL->NextRow(sql_handle); ++i )
+ {
+ SQL->GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data);
+ SQL->GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data);
+ SQL->GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data);
+ }
+ num = i;
+ for( i = 0; i < num; ++i )
+ {
+ if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ||
+ class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ||
+ class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ||
+ class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ||
+ class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ||
+ class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ||
+ class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
{
- SQL->GetData(sql_handle, 0, &data, NULL); char_id[i] = atoi(data);
- SQL->GetData(sql_handle, 1, &data, NULL); class_[i] = atoi(data);
- SQL->GetData(sql_handle, 2, &data, NULL); guild_id[i] = atoi(data);
+ // job modification
+ if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER )
+ class_[i] = (sex ? JOB_BARD : JOB_DANCER);
+ else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY )
+ class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY);
+ else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER )
+ class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER);
+ else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER )
+ class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER);
+ else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T )
+ class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T);
+ else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER )
+ class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
+ else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
+ class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO);
}
- num = i;
- for( i = 0; i < num; ++i )
- {
- if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER ||
- class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY ||
- class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER ||
- class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER ||
- class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T ||
- class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER ||
- class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
- {
- // job modification
- if( class_[i] == JOB_BARD || class_[i] == JOB_DANCER )
- class_[i] = (sex ? JOB_BARD : JOB_DANCER);
- else if( class_[i] == JOB_CLOWN || class_[i] == JOB_GYPSY )
- class_[i] = (sex ? JOB_CLOWN : JOB_GYPSY);
- else if( class_[i] == JOB_BABY_BARD || class_[i] == JOB_BABY_DANCER )
- class_[i] = (sex ? JOB_BABY_BARD : JOB_BABY_DANCER);
- else if( class_[i] == JOB_MINSTREL || class_[i] == JOB_WANDERER )
- class_[i] = (sex ? JOB_MINSTREL : JOB_WANDERER);
- else if( class_[i] == JOB_MINSTREL_T || class_[i] == JOB_WANDERER_T )
- class_[i] = (sex ? JOB_MINSTREL_T : JOB_WANDERER_T);
- else if( class_[i] == JOB_BABY_MINSTREL || class_[i] == JOB_BABY_WANDERER )
- class_[i] = (sex ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
- else if( class_[i] == JOB_KAGEROU || class_[i] == JOB_OBORO )
- class_[i] = (sex ? JOB_KAGEROU : JOB_OBORO);
- }
- if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'", char_db, class_[i], char_id[i]) )
- Sql_ShowDebug(sql_handle);
+ if( SQL_ERROR == SQL->Query(sql_handle, "UPDATE `%s` SET `equip`='0' WHERE `char_id`='%d'", inventory_db, char_id[i]) )
+ Sql_ShowDebug(sql_handle);
- if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex]
- inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
- }
- SQL->FreeResult(sql_handle);
+ if( SQL_ERROR == SQL->Query(sql_handle,
+ "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', `head_top`='0', `head_mid`='0', "
+ "`head_bottom`='0' WHERE `char_id`='%d'",
+ char_db, class_[i], char_id[i]) )
+ Sql_ShowDebug(sql_handle);
- // disconnect player if online on char-server
- disconnect_player(acc);
+ if( guild_id[i] )// If there is a guild, update the guild_member data [Skotlex]
+ inter_guild_sex_changed(guild_id[i], acc, char_id[i], sex);
}
+ SQL->FreeResult(sql_handle);
+
+ // disconnect player if online on char-server
+ disconnect_player(acc);
// notify all mapservers about this change
WBUFW(buf,0) = 0x2b0d;
diff --git a/src/char/char.h b/src/char/char.h
index 372af91f7..2928929de 100644
--- a/src/char/char.h
+++ b/src/char/char.h
@@ -65,6 +65,8 @@ int mapif_sendallwos(int fd,unsigned char *buf,unsigned int len);
int mapif_send(int fd,unsigned char *buf,unsigned int len);
void mapif_on_parse_accinfo(int account_id,int u_fd, int aid, int castergroup, int map_fd);
+void disconnect_player(int account_id);
+
int char_married(int pl1,int pl2);
int char_child(int parent_id, int child_id);
int char_family(int pl1,int pl2,int pl3);
diff --git a/src/char/int_storage.c b/src/char/int_storage.c
index 0313f2a41..966e61bb3 100644
--- a/src/char/int_storage.c
+++ b/src/char/int_storage.c
@@ -258,8 +258,9 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd)
StringBuf buf;
SqlStmt* stmt;
struct item item;
- int j, i=0, s;
+ int j, i=0, s=0, bound_qt=0;
struct item items[MAX_INVENTORY];
+ unsigned int bound_item[MAX_INVENTORY] = {0};
int char_id = RFIFOL(fd,2);
int aid = RFIFOL(fd,6);
int guild_id = RFIFOW(fd,10);
@@ -313,6 +314,20 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd)
StrBuf->AppendStr(&buf, " OR");
StrBuf->Printf(&buf, " `id`=%d",items[j].id);
+
+ if( items[j].bound && items[j].equip ) {
+ // Only the items that are also stored in `char` `equip`
+ if( items[j].equip&EQP_HAND_R
+ || items[j].equip&EQP_HAND_L
+ || items[j].equip&EQP_HEAD_TOP
+ || items[j].equip&EQP_HEAD_MID
+ || items[j].equip&EQP_HEAD_LOW
+ || items[j].equip&EQP_GARMENT
+ ) {
+ bound_item[bound_qt] = items[j].equip;
+ bound_qt++;
+ }
+ }
}
if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
@@ -324,19 +339,63 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd)
return 1;
}
+ // Removes any view id that was set by an item that was removed
+ if( bound_qt ) {
+
+#define CHECK_REMOVE(var,mask,token) do { /* Verifies equip bitmasks (see item.equip) and handles the sql statement */ \
+ if ((var)&(mask)) { \
+ if ((var) != (mask) && s) StrBuf->AppendStr(&buf, ","); \
+ StrBuf->AppendStr(&buf,"`"#token"`='0'"); \
+ (var) &= ~(mask); \
+ s++; \
+ } \
+} while(0)
+
+ StrBuf->Clear(&buf);
+ StrBuf->Printf(&buf, "UPDATE `%s` SET ", char_db);
+ for( j = 0; j < bound_qt; j++ ) {
+ // Equips can be at more than one slot at the same time
+ CHECK_REMOVE(bound_item[j],EQP_HAND_R,weapon);
+ CHECK_REMOVE(bound_item[j],EQP_HAND_L,shield);
+ CHECK_REMOVE(bound_item[j],EQP_HEAD_TOP,head_top);
+ CHECK_REMOVE(bound_item[j],EQP_HEAD_MID,head_mid);
+ CHECK_REMOVE(bound_item[j],EQP_HEAD_LOW,head_bottom);
+ CHECK_REMOVE(bound_item[j],EQP_GARMENT,robe);
+ }
+ StrBuf->Printf(&buf, " WHERE `char_id`='%d'", char_id);
+
+ if( SQL_ERROR == SQL->StmtPrepareStr(stmt, StrBuf->Value(&buf))
+ || SQL_ERROR == SQL->StmtExecute(stmt) )
+ {
+ Sql_ShowDebug(sql_handle);
+ SQL->StmtFree(stmt);
+ StrBuf->Destroy(&buf);
+ return 1;
+ }
+#undef CHECK_REMOVE
+ }
+
//Now let's update the guild storage with those deleted items
+ /// TODO/FIXME:
+ /// This approach is basically the same as the one from memitemdata_to_sql, but
+ /// the latter compares current database values and this is not needed in this case
+ /// maybe sometime separate memitemdata_to_sql into different methods in order to use
+ /// call that function here as well [Panikon]
StrBuf->Clear(&buf);
- StrBuf->Printf(&buf, "INSERT INTO `%s` (`guild_id`, `nameid`, `amount`, `identify`, `refine`, `attribute`, `expire_time`, `bound`, `unique_id`", guild_storage_db);
- for( j = 0; j < MAX_SLOTS; ++j )
- StrBuf->Printf(&buf, ", `card%d`", j);
- StrBuf->AppendStr(&buf, ") VALUES ");
-
+ StrBuf->Printf(&buf,"INSERT INTO `%s` (`guild_id`,`nameid`,`amount`,`equip`,`identify`,`refine`,"
+ "`attribute`,`expire_time`,`bound`,`unique_id`",
+ guild_storage_db);
+ for( s = 0; s < MAX_SLOTS; ++s )
+ StrBuf->Printf(&buf, ", `card%d`", s);
+ StrBuf->AppendStr(&buf," ) VALUES ");
+
for( j = 0; j < i; ++j ) {
if( j )
StrBuf->AppendStr(&buf, ",");
- StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'",
- guild_id, items[j].nameid, items[j].amount, items[j].identify, items[j].refine, items[j].attribute, items[j].expire_time, items[j].bound, items[j].unique_id);
+ StrBuf->Printf(&buf, "('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'",
+ guild_id, items[j].nameid, items[j].amount, items[j].equip, items[j].identify, items[j].refine,
+ items[j].attribute, items[j].expire_time, items[j].bound, items[j].unique_id);
for( s = 0; s < MAX_SLOTS; ++s )
StrBuf->Printf(&buf, ", '%d'", items[j].card[s]);
StrBuf->AppendStr(&buf, ")");
@@ -356,6 +415,9 @@ int mapif_parse_ItemBoundRetrieve_sub(int fd)
//Finally reload storage and tell map we're done
mapif_load_guild_storage(fd,aid,guild_id,0);
+
+ // If character is logged in char, disconnect
+ disconnect_player(aid);
#endif
return 0;
}
diff --git a/src/common/HPM.c b/src/common/HPM.c
index 971eb83bd..9ffce87de 100644
--- a/src/common/HPM.c
+++ b/src/common/HPM.c
@@ -13,6 +13,7 @@
#include "../common/console.h"
#include "../common/strlib.h"
#include "../common/sql.h"
+#include "../common/sysinfo.h"
#include "HPM.h"
#include <stdio.h>
@@ -703,8 +704,6 @@ void hplugins_share_defaults(void) {
HPM->share(&arg_c,"arg_c");
HPM->share(SERVER_NAME,"SERVER_NAME");
HPM->share(&SERVER_TYPE,"SERVER_TYPE");
- HPM->share((void*)get_svn_revision,"get_svn_revision");
- HPM->share((void*)get_git_hash,"get_git_hash");
HPM->share(DB, "DB");
HPM->share(HPMiMalloc, "iMalloc");
/* socket */
@@ -719,6 +718,8 @@ void hplugins_share_defaults(void) {
HPM->share(timer,"timer");
/* libconfig */
HPM->share(libconfig,"libconfig");
+ /* sysinfo */
+ HPM->share(sysinfo,"sysinfo");
}
void hpm_init(void) {
diff --git a/src/common/HPM.h b/src/common/HPM.h
index b466cb4f3..0f0df4cda 100644
--- a/src/common/HPM.h
+++ b/src/common/HPM.h
@@ -1,7 +1,7 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
-#ifndef _COMMON_HPM_H_
+#ifndef _COMMON_HPM_H_
#define _COMMON_HPM_H_
#include "../common/cbasetypes.h"
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index 6eef028b2..f202ac306 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -51,6 +51,11 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
#else
#define _COMMON_STRLIB_H_
#endif // _COMMON_STRLIB_H_
+ #ifdef _COMMON_SYSINFO_H_
+ { "sysinfo_interface", sizeof(struct sysinfo_interface) },
+ #else
+ #define _COMMON_SYSINFO_H_
+ #endif // _COMMON_SYSINFO_H_
#ifdef _MAP_ATCOMMAND_H_
{ "AliasInfo", sizeof(struct AliasInfo) },
{ "atcommand_interface", sizeof(struct atcommand_interface) },
diff --git a/src/common/HPMi.h b/src/common/HPMi.h
index 95037fd14..19206aeca 100644
--- a/src/common/HPMi.h
+++ b/src/common/HPMi.h
@@ -1,7 +1,7 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
-#ifndef _COMMON_HPMI_H_
+#ifndef _COMMON_HPMI_H_
#define _COMMON_HPMI_H_
#include "../common/cbasetypes.h"
@@ -67,13 +67,13 @@ enum hp_event_types {
};
enum HPluginPacketHookingPoints {
- hpClif_Parse, /* map-server (client-map) */
- hpChrif_Parse, /* map-server (char-map) */
- hpParse_FromMap, /* char-server (map-char) */
- hpParse_FromLogin, /* char-server (login-char) */
- hpParse_Char, /* char-server (client-char) */
- hpParse_FromChar, /* login-server (char-login) */
- hpParse_Login, /* login-server (client-login) */
+ hpClif_Parse, ///< map-server (client-map)
+ hpChrif_Parse, ///< map-server (char-map)
+ hpParse_FromMap, ///< char-server (map-char)
+ hpParse_FromLogin, ///< char-server (login-char)
+ hpParse_Char, ///< char-server (client-char)
+ hpParse_FromChar, ///< login-server (char-login)
+ hpParse_Login, ///< login-server (client-login)
/* */
hpPHP_MAX,
};
diff --git a/src/common/Makefile.in b/src/common/Makefile.in
index 7bb9ae630..623c59c2e 100644
--- a/src/common/Makefile.in
+++ b/src/common/Makefile.in
@@ -1,3 +1,5 @@
+# Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+# See the LICENSE file
CONFIG_D = ../config
CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h)
@@ -15,8 +17,8 @@ MT19937AR_H = $(MT19937AR_D)/mt19937ar.h
MT19937AR_INCLUDE = -I$(MT19937AR_D)
COMMON_SHARED_C = conf.c db.c des.c ers.c grfio.c HPM.c mapindex.c md5calc.c \
- mutex.c nullpo.c random.c showmsg.c strlib.c thread.c \
- timer.c utils.c
+ mutex.c nullpo.c random.c showmsg.c strlib.c sysinfo.c \
+ thread.c timer.c utils.c
COMMON_C = $(COMMON_SHARED_C)
COMMON_SHARED_OBJ = $(patsubst %.c,%.o,$(COMMON_SHARED_C))
COMMON_OBJ = $(addprefix obj_all/, $(COMMON_SHARED_OBJ) \
@@ -27,11 +29,12 @@ COMMON_C += console.c core.c malloc.c socket.c
COMMON_H = atomic.h cbasetypes.h conf.h console.h core.h db.h des.h ers.h \
grfio.h HPM.h HPMi.h malloc.h mapindex.h md5calc.h mmo.h mutex.h \
nullpo.h random.h showmsg.h socket.h spinlock.h sql.h strlib.h \
- thread.h timer.h utils.h winapi.h
+ sysinfo.h thread.h timer.h utils.h winapi.h
COMMON_SQL_OBJ = obj_sql/sql.o
COMMON_SQL_H = sql.h
COMMON_C += sql.c
+SYSINFO_INC = sysinfo.inc
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
@@ -54,7 +57,7 @@ sql: $(SQL_DEPENDS)
buildclean:
@echo " CLEAN common (build temp files)"
- @rm -rf *.o obj_all obj_sql
+ @rm -rf *.o obj_all obj_sql sysinfo.inc
clean: buildclean
@echo " CLEAN common"
@@ -71,6 +74,10 @@ help:
Makefile: Makefile.in
@$(MAKE) -C ../.. src/common/Makefile
+$(SYSINFO_INC): $(COMMON_C) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H)
+ @echo " MAKE $@"
+ @$(MAKE) -C ../.. sysinfo
+
needs_mysql:
@echo "MySQL not found or disabled by the configure script"
@exit 1
@@ -103,19 +110,20 @@ common_mini: $(COMMON_MINI_OBJ) $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) obj_all/common
common_sql: $(COMMON_SQL_OBJ) obj_sql/common_sql.a Makefile
-obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj_all
+obj_all/sysinfo.o: sysinfo.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) $(SYSINFO_INC) | obj_all
+
+obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_all
@echo " CC $<"
@$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
-obj_all/mini%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj_all
+obj_all/mini%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_all
@echo " CC $<"
@$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) -DMINICORE @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
-obj_sql/%.o: %.c $(COMMON_H) $(COMMON_SQL_H) $(CONFIG_H) $(LIBCONFIG_H) | obj_sql
+obj_sql/%.o: %.c $(COMMON_H) $(COMMON_SQL_H) $(CONFIG_H) $(LIBCONFIG_H) | $(SYSINFO_INC) obj_sql
@echo " CC $<"
@$(CC) @CFLAGS@ $(LIBCONFIG_INCLUDE) @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
-
# missing object files
$(MT19937AR_OBJ):
@echo " MAKE $@"
diff --git a/src/common/console.c b/src/common/console.c
index ec228b563..d8f352c8a 100644
--- a/src/common/console.c
+++ b/src/common/console.c
@@ -5,6 +5,7 @@
#include "../common/cbasetypes.h"
#include "../common/showmsg.h"
#include "../common/core.h"
+#include "../common/sysinfo.h"
#include "../config/core.h"
#include "console.h"
@@ -41,8 +42,7 @@ struct console_interface console_s;
* CORE : Display title
*--------------------------------------*/
void display_title(void) {
- const char* svn = get_svn_revision();
- const char* git = get_git_hash();
+ const char *vcstype = sysinfo->vcstype();
ShowMessage("\n");
ShowMessage(""CL_BG_RED""CL_BT_WHITE" "CL_CLL""CL_NORMAL"\n");
@@ -57,10 +57,13 @@ void display_title(void) {
ShowMessage(""CL_BG_RED""CL_BT_WHITE" http://hercules.ws/board/ "CL_CLL""CL_NORMAL"\n");
ShowMessage(""CL_BG_RED""CL_BT_WHITE" "CL_CLL""CL_NORMAL"\n");
- if( git[0] != HERC_UNKNOWN_VER )
- ShowInfo("Git Hash: '"CL_WHITE"%s"CL_RESET"'\n", git);
- else if( svn[0] != HERC_UNKNOWN_VER )
- ShowInfo("SVN Revision: '"CL_WHITE"%s"CL_RESET"'\n", svn);
+ ShowInfo("Hercules %d-bit for %s\n", sysinfo->is64bit() ? 64 : 32, sysinfo->platform());
+ ShowInfo("%s revision (src): '"CL_WHITE"%s"CL_RESET"'\n", vcstype, sysinfo->vcsrevision_src());
+ ShowInfo("%s revision (scripts): '"CL_WHITE"%s"CL_RESET"'\n", vcstype, sysinfo->vcsrevision_scripts());
+ ShowInfo("OS version: '"CL_WHITE"%s"CL_RESET" [%s]'\n", sysinfo->osversion(), sysinfo->arch());
+ 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());
}
#ifdef CONSOLE_INPUT
#if defined(WIN32)
diff --git a/src/common/console.h b/src/common/console.h
index bd1de4cbf..3d19ddc9d 100644
--- a/src/common/console.h
+++ b/src/common/console.h
@@ -1,8 +1,8 @@
// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
// See the LICENSE file
-#ifndef _COMMON_CONSOLE_H_
-#define _COMMON_CONSOLE_H_
+#ifndef _COMMON_CONSOLE_H_
+#define _COMMON_CONSOLE_H_
#include "../common/thread.h"
#include "../common/mutex.h"
diff --git a/src/common/core.c b/src/common/core.c
index c6075da40..798c832f0 100644
--- a/src/common/core.c
+++ b/src/common/core.c
@@ -9,6 +9,7 @@
#include "core.h"
#include "../common/console.h"
#include "../common/random.h"
+#include "../common/sysinfo.h"
#ifndef MINICORE
#include "../common/db.h"
@@ -78,7 +79,7 @@ sigfunc *compat_signal(int signo, sigfunc *func) {
*--------------------------------------*/
#ifdef _WIN32
static BOOL WINAPI console_handler(DWORD c_event) {
- switch(c_event) {
+ switch(c_event) {
case CTRL_CLOSE_EVENT:
case CTRL_LOGOFF_EVENT:
case CTRL_SHUTDOWN_EVENT:
@@ -89,8 +90,8 @@ static BOOL WINAPI console_handler(DWORD c_event) {
break;
default:
return FALSE;
- }
- return TRUE;
+ }
+ return TRUE;
}
static void cevents_init() {
@@ -152,134 +153,21 @@ void signals_init (void) {
}
#endif
-const char* get_svn_revision(void) {
- static char svn_version_buffer[16] = "";
- FILE *fp;
-
- if( svn_version_buffer[0] != '\0' )
- return svn_version_buffer;
-
- // subversion 1.7 uses a sqlite3 database
- // FIXME this is hackish at best...
- // - ignores database file structure
- // - assumes the data in NODES.dav_cache column ends with "!svn/ver/<revision>/<path>)"
- // - since it's a cache column, the data might not even exist
- if( (fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL )
- {
- #ifndef SVNNODEPATH
- //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up
- #define SVNNODEPATH trunk
- #endif
- const char* prefix = "!svn/ver/";
- const char* postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this
- size_t prefix_len = strlen(prefix);
- size_t postfix_len = strlen(postfix);
- size_t i,j,len;
- char* buffer;
-
- // read file to buffer
- fseek(fp, 0, SEEK_END);
- len = ftell(fp);
- buffer = (char*)aMalloc(len + 1);
- fseek(fp, 0, SEEK_SET);
- len = fread(buffer, 1, len, fp);
- buffer[len] = '\0';
- fclose(fp);
-
- // parse buffer
- for( i = prefix_len + 1; i + postfix_len <= len; ++i ) {
- if( buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0 )
- continue; // postfix missmatch
- for( j = i; j > 0; --j ) {// skip digits
- if( !ISDIGIT(buffer[j - 1]) )
- break;
- }
- if( memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0 )
- continue; // prefix missmatch
- // done
- snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(buffer + j));
- break;
- }
- aFree(buffer);
-
- if( svn_version_buffer[0] != '\0' )
- return svn_version_buffer;
- }
-
- // subversion 1.6 and older?
- if ((fp = fopen(".svn/entries", "r")) != NULL) {
- char line[1024];
- int rev;
- // Check the version
- if (fgets(line, sizeof(line), fp)) {
- if(!ISDIGIT(line[0])) {
- // XML File format
- while (fgets(line,sizeof(line),fp))
- if (strstr(line,"revision=")) break;
- if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) {
- snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", rev);
- }
- } else {
- // Bin File format
- if ( fgets(line, sizeof(line), fp) == NULL ) { printf("Can't get bin name\n"); } // Get the name
- if ( fgets(line, sizeof(line), fp) == NULL ) { printf("Can't get entries kind\n"); } // Get the entries kind
- if(fgets(line, sizeof(line), fp)) { // Get the rev numver
- snprintf(svn_version_buffer, sizeof(svn_version_buffer), "%d", atoi(line));
- }
- }
- }
- fclose(fp);
-
- if( svn_version_buffer[0] != '\0' )
- return svn_version_buffer;
- }
-
- // fallback
- svn_version_buffer[0] = HERC_UNKNOWN_VER;
- return svn_version_buffer;
-}
-/* whats our origin */
-#define GIT_ORIGIN "refs/remotes/origin/master"
-/* Grabs the hash from the last time the user updated his working copy (last pull) */
-const char *get_git_hash (void) {
- static char HerculesGitHash[41] = "";//Sha(40) + 1
- FILE *fp;
-
- if( HerculesGitHash[0] != '\0' )
- return HerculesGitHash;
-
- if ( (fp = fopen (".git/"GIT_ORIGIN, "r")) != NULL) {
- char line[64];
- char *rev = malloc (sizeof (char) * 50);
-
- if (fgets (line, sizeof (line), fp) && sscanf (line, "%50s", rev))
- snprintf (HerculesGitHash, sizeof (HerculesGitHash), "%s", rev);
-
- free (rev);
- fclose (fp);
- } else {
- HerculesGitHash[0] = HERC_UNKNOWN_VER;
- }
-
- if (! (*HerculesGitHash)) {
- HerculesGitHash[0] = HERC_UNKNOWN_VER;
- }
-
- return HerculesGitHash;
-}
-// Warning if executed as superuser (root)
+/**
+ * Warns the user if executed as superuser (root)
+ */
void usercheck(void) {
-#ifndef _WIN32
- if (geteuid() == 0) {
- ShowWarning ("You are running Hercules with root privileges, it is not necessary.\n");
- }
-#endif
+ if (sysinfo->is_superuser()) {
+ ShowWarning("You are running Hercules with root privileges, it is not necessary.\n");
+ }
}
+
void core_defaults(void) {
#ifndef MINICORE
hpm_defaults();
HCache_defaults();
#endif
+ sysinfo_defaults();
console_defaults();
strlib_defaults();
malloc_defaults();
@@ -318,16 +206,18 @@ int main (int argc, char **argv) {
iMalloc->init();// needed for Show* in display_title() [FlavioJS]
+ sysinfo->init();
+
if (!(msg_silent&0x1))
console->display_title();
-
-#ifdef MINICORE // minimalist Core
+
usercheck();
+
+#ifdef MINICORE // minimalist Core
do_init(argc,argv);
do_final();
#else// not MINICORE
set_server_type();
- usercheck();
Sql_Init();
rathread_init();
@@ -348,10 +238,8 @@ int main (int argc, char **argv) {
HCache->init();
-#ifndef MINICORE
HPM->init();
-#endif
-
+
sockt->init();
do_init(argc,argv);
@@ -366,15 +254,14 @@ int main (int argc, char **argv) {
console->final();
do_final();
-#ifndef MINICORE
HPM->final();
-#endif
timer->final();
sockt->final();
DB->final();
rathread_final();
ers_final();
#endif
+ sysinfo->final();
iMalloc->final();
diff --git a/src/common/core.h b/src/common/core.h
index 72f956e1d..5c2f2c9a5 100644
--- a/src/common/core.h
+++ b/src/common/core.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _COMMON_CORE_H_
-#define _COMMON_CORE_H_
+#ifndef _COMMON_CORE_H_
+#define _COMMON_CORE_H_
#include "../common/db.h"
#include "../common/mmo.h"
@@ -24,16 +24,14 @@ extern int runflag;
extern char *SERVER_NAME;
enum server_types {
- SERVER_TYPE_UNKNOWN = 0x0,
- SERVER_TYPE_LOGIN = 0x1,
- SERVER_TYPE_CHAR = 0x2,
- SERVER_TYPE_MAP = 0x4,
+ SERVER_TYPE_UNKNOWN = 0x0,
+ SERVER_TYPE_LOGIN = 0x1,
+ SERVER_TYPE_CHAR = 0x2,
+ SERVER_TYPE_MAP = 0x4,
};
enum server_types SERVER_TYPE;
-const char *get_svn_revision(void);
-const char *get_git_hash (void);
extern int do_init(int,char**);
extern void set_server_type(void);
extern void do_abort(void);
diff --git a/src/common/des.h b/src/common/des.h
index 3f55448ba..0f908a15b 100644
--- a/src/common/des.h
+++ b/src/common/des.h
@@ -1,8 +1,9 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _COMMON_DES_H_
-#define _COMMON_DES_H_
+#ifndef _COMMON_DES_H_
+#define _COMMON_DES_H_
+#include "../common/cbasetypes.h"
/// One 64-bit block.
typedef struct BIT64 { uint8_t b[8]; } BIT64;
diff --git a/src/common/grfio.h b/src/common/grfio.h
index 4f5d0d6bc..930ed7e36 100644
--- a/src/common/grfio.h
+++ b/src/common/grfio.h
@@ -1,8 +1,8 @@
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
-#ifndef _COMMON_GRFIO_H_
-#define _COMMON_GRFIO_H_
+#ifndef _COMMON_GRFIO_H_
+#define _COMMON_GRFIO_H_
void grfio_init(const char* fname);
void grfio_final(void);
diff --git a/src/common/malloc.c b/src/common/malloc.c
index f7f108304..5b39cbab6 100644
--- a/src/common/malloc.c
+++ b/src/common/malloc.c
@@ -5,6 +5,7 @@
#include "../common/malloc.h"
#include "../common/core.h"
#include "../common/showmsg.h"
+#include "../common/sysinfo.h"
#include <stdio.h>
#include <stdlib.h>
@@ -574,17 +575,14 @@ static void memmgr_log (char *buf)
if( !log_fp ) {
time_t raw;
struct tm* t;
- const char* svn = get_svn_revision();
- const char* git = get_git_hash();
log_fp = fopen(memmer_logfile,"at");
if (!log_fp) log_fp = stdout;
time(&raw);
t = localtime(&raw);
- fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (rev %s).\n",
- (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec,
- git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown");
+ fprintf(log_fp, "\nMemory manager: Memory leaks found at %d/%02d/%02d %02dh%02dm%02ds (%s rev '%s').\n",
+ (t->tm_year+1900), (t->tm_mon+1), t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec, sysinfo->vcstype(), sysinfo->vcsrevision_src());
}
fprintf(log_fp, "%s", buf);
return;
diff --git a/src/common/mmo.h b/src/common/mmo.h
index 0dd8d0f09..07a05677f 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _COMMON_MMO_H_
-#define _COMMON_MMO_H_
+#ifndef _COMMON_MMO_H_
+#define _COMMON_MMO_H_
#include "cbasetypes.h"
#include "../common/db.h"
@@ -60,7 +60,7 @@
// Client support for experimental RagexeRE UI present in 2012-04-10 and 2012-04-18
#if defined(PACKETVER_RE) && ( PACKETVER == 20120410 || PACKETVER == 20120418 )
-#define PARTY_RECRUIT
+#define PARTY_RECRUIT
#endif // PACKETVER_RE && (PACKETVER == 20120410 || PACKETVER == 10120418)
// Comment the following line to disable sc_data saving. [Skotlex]
@@ -113,11 +113,11 @@
#define MAX_GUILDPOSITION 20 // Increased max guild positions to accomodate for all members [Valaris] (removed) [PoW]
#define MAX_GUILDEXPULSION 32
#define MAX_GUILDALLIANCE 16
-#define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan]
+#define MAX_GUILDSKILL 15 // Increased max guild skills because of new skills [Sara-chan]
#define MAX_GUILDLEVEL 50
#define MAX_GUARDIANS 8 // Local max per castle. [Skotlex]
#define MAX_QUEST_OBJECTIVES 3 // Max quest objectives for a quest
-#define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95]
+#define MAX_START_ITEMS 32 // Max number of items allowed to be given to a char whenever it's created. [mkbu95]
// for produce
#define MIN_ATTRIBUTE 0
@@ -158,7 +158,7 @@
// Base Homun skill.
#define HM_SKILLBASE 8001
#define MAX_HOMUNSKILL 43
-#define MAX_HOMUNCULUS_CLASS 52 // [orn] Increased to 60 from 16 to allow new Homun-S.
+#define MAX_HOMUNCULUS_CLASS 52 // [orn] Increased to 60 from 16 to allow new Homun-S.
#define HM_CLASS_BASE 6001
#define HM_CLASS_MAX (HM_CLASS_BASE+MAX_HOMUNCULUS_CLASS-1)
@@ -230,6 +230,32 @@ struct item {
uint64 unique_id;
};
+//Equip position constants
+enum equip_pos {
+ EQP_HEAD_LOW = 0x000001,
+ EQP_HEAD_MID = 0x000200, //512
+ EQP_HEAD_TOP = 0x000100, //256
+ EQP_HAND_R = 0x000002, //2
+ EQP_HAND_L = 0x000020, //32
+ EQP_ARMOR = 0x000010, //16
+ EQP_SHOES = 0x000040, //64
+ EQP_GARMENT = 0x000004, //4
+ EQP_ACC_L = 0x000008, //8
+ EQP_ACC_R = 0x000080, //128
+ EQP_COSTUME_HEAD_TOP = 0x000400, //1024
+ EQP_COSTUME_HEAD_MID = 0x000800, //2048
+ EQP_COSTUME_HEAD_LOW = 0x001000, //4096
+ EQP_COSTUME_GARMENT = 0x002000, //8192
+ //UNUSED_COSTUME_FLOOR = 0x004000, //16384
+ EQP_AMMO = 0x008000, //32768
+ EQP_SHADOW_ARMOR = 0x010000, //65536
+ EQP_SHADOW_WEAPON = 0x020000, //131072
+ EQP_SHADOW_SHIELD = 0x040000, //262144
+ EQP_SHADOW_SHOES = 0x080000, //524288
+ EQP_SHADOW_ACC_R = 0x100000, //1048576
+ EQP_SHADOW_ACC_L = 0x200000, //2097152
+};
+
struct point {
unsigned short map;
short x,y;
@@ -240,17 +266,17 @@ enum e_skill_flag
SKILL_FLAG_PERMANENT,
SKILL_FLAG_TEMPORARY,
SKILL_FLAG_PLAGIARIZED,
- SKILL_FLAG_UNUSED, /* needed to maintain the order since the values are saved, can be renamed and used if a new flag is necessary */
- SKILL_FLAG_PERM_GRANTED, // Permanent, granted through someway (e.g. script).
+ SKILL_FLAG_UNUSED, ///< needed to maintain the order since the values are saved, can be renamed and used if a new flag is necessary
+ SKILL_FLAG_PERM_GRANTED, ///< Permanent, granted through someway (e.g. script).
/* */
/* MUST be the last, because with it the flag value stores a dynamic value (flag+lv) */
SKILL_FLAG_REPLACED_LV_0, // Temporary skill overshadowing permanent skill of level 'N - SKILL_FLAG_REPLACED_LV_0',
};
enum e_mmo_charstatus_opt {
- OPT_NONE = 0x0,
- OPT_SHOW_EQUIP = 0x1,
- OPT_ALLOW_PARTY = 0x2,
+ OPT_NONE = 0x0,
+ OPT_SHOW_EQUIP = 0x1,
+ OPT_ALLOW_PARTY = 0x2,
};
enum e_item_bound_type {
@@ -319,14 +345,14 @@ struct s_pet {
char incuvate;
};
-struct s_homunculus { //[orn]
+struct s_homunculus { //[orn]
char name[NAME_LENGTH];
int hom_id;
int char_id;
short class_;
short prev_class;
int hp,max_hp,sp,max_sp;
- unsigned int intimacy; //[orn]
+ unsigned int intimacy;
short hunger;
struct s_skill hskill[MAX_HOMUNSKILL]; //albator
short skillpts;
@@ -503,7 +529,7 @@ struct party {
unsigned char count; //Count of online characters.
unsigned exp : 1,
item : 2; //&1: Party-Share (round-robin), &2: pickup style: shared.
- struct party_member member[MAX_PARTY];
+ struct party_member member[MAX_PARTY];
};
struct map_session_data;
@@ -607,14 +633,14 @@ enum fame_list_type {
};
enum { //Change Guild Infos
- GBI_EXP =1, // Guild Experience (EXP)
- GBI_GUILDLV, // Guild level
- GBI_SKILLPOINT, // Guild skillpoints
- GBI_SKILLLV, // Guild skill_lv ?? seem unused
+ GBI_EXP = 1, ///< Guild Experience (EXP)
+ GBI_GUILDLV, ///< Guild level
+ GBI_SKILLPOINT, ///< Guild skillpoints
+ GBI_SKILLLV, ///< Guild skill_lv ?? seem unused
};
enum { //Change Member Infos
- GMI_POSITION =0,
+ GMI_POSITION = 0,
GMI_EXP,
GMI_HAIR,
GMI_HAIR_COLOR,
@@ -811,50 +837,50 @@ enum {
};
enum weapon_type {
- W_FIST, //Bare hands
- W_DAGGER, //1
- W_1HSWORD, //2
- W_2HSWORD, //3
- W_1HSPEAR, //4
- W_2HSPEAR, //5
- W_1HAXE, //6
- W_2HAXE, //7
- W_MACE, //8
- W_2HMACE, //9 (unused)
- W_STAFF, //10
- W_BOW, //11
- W_KNUCKLE, //12
- W_MUSICAL, //13
- W_WHIP, //14
- W_BOOK, //15
- W_KATAR, //16
- W_REVOLVER, //17
- W_RIFLE, //18
- W_GATLING, //19
- W_SHOTGUN, //20
- W_GRENADE, //21
- W_HUUMA, //22
- W_2HSTAFF, //23
+ W_FIST, ///< Bare hands
+ W_DAGGER, //1
+ W_1HSWORD, //2
+ W_2HSWORD, //3
+ W_1HSPEAR, //4
+ W_2HSPEAR, //5
+ W_1HAXE, //6
+ W_2HAXE, //7
+ W_MACE, //8
+ W_2HMACE, //9 (unused)
+ W_STAFF, //10
+ W_BOW, //11
+ W_KNUCKLE, //12
+ W_MUSICAL, //13
+ W_WHIP, //14
+ W_BOOK, //15
+ W_KATAR, //16
+ W_REVOLVER, //17
+ W_RIFLE, //18
+ W_GATLING, //19
+ W_SHOTGUN, //20
+ W_GRENADE, //21
+ W_HUUMA, //22
+ W_2HSTAFF, //23
MAX_WEAPON_TYPE,
// dual-wield constants
- W_DOUBLE_DD, // 2 daggers
- W_DOUBLE_SS, // 2 swords
- W_DOUBLE_AA, // 2 axes
- W_DOUBLE_DS, // dagger + sword
- W_DOUBLE_DA, // dagger + axe
- W_DOUBLE_SA, // sword + axe
+ W_DOUBLE_DD, ///< 2 daggers
+ W_DOUBLE_SS, ///< 2 swords
+ W_DOUBLE_AA, ///< 2 axes
+ W_DOUBLE_DS, ///< dagger + sword
+ W_DOUBLE_DA, ///< dagger + axe
+ W_DOUBLE_SA, ///< sword + axe
};
enum ammo_type {
- A_ARROW = 1,
- A_DAGGER, //2
- A_BULLET, //3
- A_SHELL, //4
- A_GRENADE, //5
- A_SHURIKEN, //6
- A_KUNAI, //7
- A_CANNONBALL, //8
- A_THROWWEAPON //9
+ A_ARROW = 1,
+ A_DAGGER, //2
+ A_BULLET, //3
+ A_SHELL, //4
+ A_GRENADE, //5
+ A_SHURIKEN, //6
+ A_KUNAI, //7
+ A_CANNONBALL, //8
+ A_THROWWEAPON, //9
};
enum e_char_server_type {
diff --git a/src/common/socket.h b/src/common/socket.h
index ca9141716..75adde4cf 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -2,7 +2,7 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _COMMON_SOCKET_H_
+#ifndef _COMMON_SOCKET_H_
#define _COMMON_SOCKET_H_
#include "../common/cbasetypes.h"
diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c
new file mode 100644
index 000000000..a56896458
--- /dev/null
+++ b/src/common/sysinfo.c
@@ -0,0 +1,1022 @@
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Base Author: Haru @ http://hercules.ws
+
+/// See sysinfo.h for a description of this file
+
+#define _COMMON_SYSINFO_P_
+#include "sysinfo.h"
+#undef _COMMON_SYSINFO_P_
+
+#include "../common/cbasetypes.h"
+#include "../common/core.h"
+#include "../common/strlib.h"
+#include "../common/malloc.h"
+
+#ifdef WIN32
+#include <windows.h>
+#include <string.h> // strlen
+#else
+#include <unistd.h>
+#endif
+#include <stdio.h> // fopen
+#include <stdlib.h> // atoi
+
+/// sysinfo.c interface source
+struct sysinfo_interface sysinfo_s;
+struct sysinfo_private sysinfo_p;
+
+#define VCSTYPE_UNKNOWN 0
+#define VCSTYPE_GIT 1
+#define VCSTYPE_SVN 2
+#define VCSTYPE_NONE -1
+
+#ifdef WIN32
+/**
+ * Values to be used with GetProductInfo.
+ *
+ * These aren't defined in MSVC2008/WindowsXP, so we gotta define them here.
+ * Values from: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724358%28v=vs.85%29.aspx
+ */
+enum windows_product_type {
+ msPRODUCT_UNDEFINED = 0x00000000, ///< An unknown product
+ msPRODUCT_ULTIMATE = 0x00000001, ///< Ultimate
+ msPRODUCT_HOME_BASIC = 0x00000002, ///< Home Basic
+ msPRODUCT_HOME_PREMIUM = 0x00000003, ///< Home Premium
+ msPRODUCT_ENTERPRISE = 0x00000004, ///< Enterprise
+ msPRODUCT_HOME_BASIC_N = 0x00000005, ///< Home Basic N
+ msPRODUCT_BUSINESS = 0x00000006, ///< Business
+ msPRODUCT_STANDARD_SERVER = 0x00000007, ///< Server Standard
+ msPRODUCT_DATACENTER_SERVER = 0x00000008, ///< Server Datacenter (full installation)
+ msPRODUCT_SMALLBUSINESS_SERVER = 0x00000009, ///< Windows Small Business Server
+ msPRODUCT_ENTERPRISE_SERVER = 0x0000000A, ///< Server Enterprise (full installation)
+ msPRODUCT_STARTER = 0x0000000B, ///< Starter
+ msPRODUCT_DATACENTER_SERVER_CORE = 0x0000000C, ///< Server Datacenter (core installation)
+ msPRODUCT_ENTERPRISE_SERVER_CORE = 0x0000000E, ///< Server Enterprise (core installation)
+ msPRODUCT_STANDARD_SERVER_CORE = 0x0000000D, ///< Server Standard (core installation)
+ msPRODUCT_ENTERPRISE_SERVER_IA64 = 0x0000000F, ///< Server Enterprise for Itanium-based Systems
+ msPRODUCT_BUSINESS_N = 0x00000010, ///< Business N
+ msPRODUCT_WEB_SERVER = 0x00000011, ///< Web Server (full installation)
+ msPRODUCT_CLUSTER_SERVER = 0x00000012, ///< HPC Edition
+ msPRODUCT_HOME_SERVER = 0x00000013, ///< Windows Storage Server 2008 R2 Essentials
+ msPRODUCT_STORAGE_EXPRESS_SERVER = 0x00000014, ///< Storage Server Express
+ msPRODUCT_STORAGE_STANDARD_SERVER = 0x00000015, ///< Storage Server Standard
+ msPRODUCT_STORAGE_WORKGROUP_SERVER = 0x00000016, ///< Storage Server Workgroup
+ msPRODUCT_STORAGE_ENTERPRISE_SERVER = 0x00000017, ///< Storage Server Enterprise
+ msPRODUCT_SERVER_FOR_SMALLBUSINESS = 0x00000018, ///< Windows Server 2008 for Windows Essential Server Solutions
+ msPRODUCT_SMALLBUSINESS_SERVER_PREMIUM = 0x00000019, ///< Small Business Server Premium
+ msPRODUCT_HOME_PREMIUM_N = 0x0000001A, ///< Home Premium N
+ msPRODUCT_ENTERPRISE_N = 0x0000001B, ///< Enterprise N
+ msPRODUCT_ULTIMATE_N = 0x0000001C, ///< Ultimate N
+ msPRODUCT_WEB_SERVER_CORE = 0x0000001D, ///< Web Server (core installation)
+ msPRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT = 0x0000001E, ///< Windows Essential Business Server Management Server
+ msPRODUCT_MEDIUMBUSINESS_SERVER_SECURITY = 0x0000001F, ///< Windows Essential Business Server Security Server
+ msPRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING = 0x00000020, ///< Windows Essential Business Server Messaging Server
+ msPRODUCT_SERVER_FOUNDATION = 0x00000021, ///< Server Foundation
+ msPRODUCT_HOME_PREMIUM_SERVER = 0x00000022, ///< Windows Home Server 2011
+ msPRODUCT_SERVER_FOR_SMALLBUSINESS_V = 0x00000023, ///< Windows Server 2008 without Hyper-V for Windows Essential Server Solutions
+ msPRODUCT_STANDARD_SERVER_V = 0x00000024, ///< Server Standard without Hyper-V
+ msPRODUCT_DATACENTER_SERVER_V = 0x00000025, ///< Server Datacenter without Hyper-V (full installation)
+ msPRODUCT_ENTERPRISE_SERVER_V = 0x00000026, ///< Server Enterprise without Hyper-V (full installation)
+ msPRODUCT_DATACENTER_SERVER_CORE_V = 0x00000027, ///< Server Datacenter without Hyper-V (core installation)
+ msPRODUCT_STANDARD_SERVER_CORE_V = 0x00000028, ///< Server Standard without Hyper-V (core installation)
+ msPRODUCT_ENTERPRISE_SERVER_CORE_V = 0x00000029, ///< Server Enterprise without Hyper-V (core installation)
+ msPRODUCT_HYPERV = 0x0000002A, ///< Microsoft Hyper-V Server
+ msPRODUCT_STORAGE_EXPRESS_SERVER_CORE = 0x0000002B, ///< Storage Server Express (core installation)
+ msPRODUCT_STORAGE_STANDARD_SERVER_CORE = 0x0000002C, ///< Storage Server Standard (core installation)
+ msPRODUCT_STORAGE_WORKGROUP_SERVER_CORE = 0x0000002D, ///< Storage Server Workgroup (core installation)
+ msPRODUCT_STORAGE_ENTERPRISE_SERVER_CORE = 0x0000002E, ///< Storage Server Enterprise (core installation)
+ msPRODUCT_STARTER_N = 0x0000002F, ///< Starter N
+ msPRODUCT_PROFESSIONAL = 0x00000030, ///< Professional
+ msPRODUCT_PROFESSIONAL_N = 0x00000031, ///< Professional N
+ msPRODUCT_SB_SOLUTION_SERVER = 0x00000032, ///< Windows Small Business Server 2011 Essentials
+ msPRODUCT_SERVER_FOR_SB_SOLUTIONS = 0x00000033, ///< Server For SB Solutions
+ msPRODUCT_STANDARD_SERVER_SOLUTIONS = 0x00000034, ///< Server Solutions Premium
+ msPRODUCT_STANDARD_SERVER_SOLUTIONS_CORE = 0x00000035, ///< Server Solutions Premium (core installation)
+ msPRODUCT_SB_SOLUTION_SERVER_EM = 0x00000036, ///< Server For SB Solutions EM
+ msPRODUCT_SERVER_FOR_SB_SOLUTIONS_EM = 0x00000037, ///< Server For SB Solutions EM
+ msPRODUCT_SOLUTION_EMBEDDEDSERVER = 0x00000038, ///< Windows MultiPoint Server
+ msPRODUCT_ESSENTIALBUSINESS_SERVER_MGMT = 0x0000003B, ///< Windows Essential Server Solution Management
+ msPRODUCT_ESSENTIALBUSINESS_SERVER_ADDL = 0x0000003C, ///< Windows Essential Server Solution Additional
+ msPRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC = 0x0000003D, ///< Windows Essential Server Solution Management SVC
+ msPRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC = 0x0000003E, ///< Windows Essential Server Solution Additional SVC
+ msPRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE = 0x0000003F, ///< Small Business Server Premium (core installation)
+ msPRODUCT_CLUSTER_SERVER_V = 0x00000040, ///< Server Hyper Core V
+ msPRODUCT_STARTER_E = 0x00000042, ///< Not supported
+ msPRODUCT_HOME_BASIC_E = 0x00000043, ///< Not supported
+ msPRODUCT_HOME_PREMIUM_E = 0x00000044, ///< Not supported
+ msPRODUCT_PROFESSIONAL_E = 0x00000045, ///< Not supported
+ msPRODUCT_ENTERPRISE_E = 0x00000046, ///< Not supported
+ msPRODUCT_ULTIMATE_E = 0x00000047, ///< Not supported
+ msPRODUCT_ENTERPRISE_EVALUATION = 0x00000048, ///< Server Enterprise (evaluation installation)
+ msPRODUCT_MULTIPOINT_STANDARD_SERVER = 0x0000004C, ///< Windows MultiPoint Server Standard (full installation)
+ msPRODUCT_MULTIPOINT_PREMIUM_SERVER = 0x0000004D, ///< Windows MultiPoint Server Premium (full installation)
+ msPRODUCT_STANDARD_EVALUATION_SERVER = 0x0000004F, ///< Server Standard (evaluation installation)
+ msPRODUCT_DATACENTER_EVALUATION_SERVER = 0x00000050, ///< Server Datacenter (evaluation installation)
+ msPRODUCT_ENTERPRISE_N_EVALUATION = 0x00000054, ///< Enterprise N (evaluation installation)
+ msPRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER = 0x0000005F, ///< Storage Server Workgroup (evaluation installation)
+ msPRODUCT_STORAGE_STANDARD_EVALUATION_SERVER = 0x00000060, ///< Storage Server Standard (evaluation installation)
+ msPRODUCT_CORE_N = 0x00000062, ///< Windows 8 N
+ msPRODUCT_CORE_COUNTRYSPECIFIC = 0x00000063, ///< Windows 8 China
+ msPRODUCT_CORE_SINGLELANGUAGE = 0x00000064, ///< Windows 8 Single Language
+ msPRODUCT_CORE = 0x00000065, ///< Windows 8
+ msPRODUCT_PROFESSIONAL_WMC = 0x00000067, ///< Professional with Media Center
+};
+
+/**
+ * Values to be used with GetSystemMetrics.
+ *
+ * Values from http://msdn.microsoft.com/en-us/library/windows/desktop/ms724385%28v=vs.85%29.aspx
+ */
+enum windows_metrics {
+ msSM_SERVERR2 = 89, ///< Obtains the build number if the system is Windows Server 2003 R2; otherwise, 0.
+};
+
+/**
+ * Values to be used with OSVERSIONINFOEX.wSuiteMask.
+ *
+ * Values from http://msdn.microsoft.com/en-us/library/windows/desktop/ms724833%28v=vs.85%29.aspx
+ */
+enum windows_ver_suite {
+ msVER_SUITE_BLADE = 0x00000400, ///< Windows Server 2003, Web Edition is installed.
+ msVER_SUITE_STORAGE_SERVER = 0x00002000, ///< Windows Storage Server 2003 R2 or Windows Storage Server 2003 is installed.
+ msVER_SUITE_COMPUTE_SERVER = 0x00004000, ///< Windows Server 2003, Compute Cluster Edition is installed.
+ msVER_SUITE_WH_SERVER = 0x00008000, ///< Windows Home Server is installed.
+};
+
+#else // not WIN32
+// UNIX. Use build-time cached values
+#include "sysinfo.inc"
+#endif // WIN32
+
+// Compiler detection <http://sourceforge.net/p/predef/wiki/Compilers/>
+#if defined(__BORLANDC__)
+#define SYSINFO_COMPILER "Borland C++"
+#elif defined(__clang__)
+#define SYSINFO_COMPILER "Clang v" EXPAND_AND_QUOTE(__clang_major__) "." EXPAND_AND_QUOTE(__clang_minor__) "." EXPAND_AND_QUOTE(__clang_patchlevel__)
+#elif defined(__INTEL_COMPILER)
+#define SYSINFO_COMPILER "Intel CC v" EXPAND_AND_QUOTE(__INTEL_COMPILER)
+#elif defined(__MINGW32__)
+#if defined(__MINGW64__)
+#define SYSINFO_COMPILER "MinGW-w64 64 Bit v" EXPAND_AND_QUOTE(__MINGW64_VERSION_MAJOR) "." EXPAND_AND_QUOTE(__MINGW64_VERSION_MINOR) \
+ " (MinGW " EXPAND_AND_QUOTE(__MINGW32_MAJOR_VERSION) "." EXPAND_AND_QUOTE(__MINGW32_MINOR_VERSION) ")"
+#elif defined(__MINGW64_VERSION_MAJOR)
+#define SYSINFO_COMPILER "MinGW-w64 32 Bit v" EXPAND_AND_QUOTE(__MINGW64_VERSION_MAJOR) "." EXPAND_AND_QUOTE(__MINGW64_VERSION_MINOR) \
+ " (MinGW " EXPAND_AND_QUOTE(__MINGW32_MAJOR_VERSION) "." EXPAND_AND_QUOTE(__MINGW32_MINOR_VERSION) ")"
+#else
+#define SYSINFO_COMPILER "MinGW32 v" EXPAND_AND_QUOTE(__MINGW32_MAJOR_VERSION) "." EXPAND_AND_QUOTE(__MINGW32_MINOR_VERSION)
+#endif
+#elif defined(__GNUC__)
+#define SYSINFO_COMPILER "GCC v" EXPAND_AND_QUOTE(__GNUC__) "." EXPAND_AND_QUOTE(__GNUC_MINOR__) "." EXPAND_AND_QUOTE(__GNUC_PATCHLEVEL__)
+#elif defined(_MSC_VER)
+#if _MSC_VER >= 1300 && _MSC_VER < 1310
+#define SYSINFO_COMPILER "Microsoft Visual C++ 7.0 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#elif _MSC_VER >= 1310 && _MSC_VER < 1400
+#define SYSINFO_COMPILER "Microsoft Visual C++ 2003 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#elif _MSC_VER >= 1400 && _MSC_VER < 1500
+#define SYSINFO_COMPILER "Microsoft Visual C++ 2005 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#elif _MSC_VER >= 1500 && _MSC_VER < 1600
+#define SYSINFO_COMPILER "Microsoft Visual C++ 2008 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#elif _MSC_VER >= 1600 && _MSC_VER < 1700
+#define SYSINFO_COMPILER "Microsoft Visual C++ 2010 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#elif _MSC_VER >= 1700 && _MSC_VER < 1800
+#define SYSINFO_COMPILER "Microsoft Visual C++ 2012 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#elif _MSC_VER >= 1800 && _MSC_VER < 1900
+#define SYSINFO_COMPILER "Microsoft Visual C++ 2013 (v" EXPAND_AND_QUOTE(_MSC_VER) ")"
+#else // < 1300 || >= 1900
+#define SYSINFO_COMPILER "Microsoft Visual C++ v" EXPAND_AND_QUOTE(_MSC_VER)
+#endif
+#else
+#define SYSINFO_COMPILER "Unknown"
+#endif
+// end compiler detection
+
+/**
+ * Retrieves the current SVN revision.
+ *
+ * @param out[out] a string pointer to return the value (to be aFree()'d.)
+ * @retval true if a revision was correctly detected.
+ * @retval false if no revision was detected. out is set to NULL in this case.
+ */
+bool sysinfo_svn_get_revision(char **out) {
+ // Only include SVN support if detected it, or we're on MSVC
+#if !defined(SYSINFO_VCSTYPE) || SYSINFO_VCSTYPE == VCSTYPE_SVN || SYSINFO_VCSTYPE == VCSTYPE_UNKNOWN
+ FILE *fp;
+
+ // subversion 1.7 uses a sqlite3 database
+ // FIXME this is hackish at best...
+ // - ignores database file structure
+ // - assumes the data in NODES.dav_cache column ends with "!svn/ver/<revision>/<path>)"
+ // - since it's a cache column, the data might not even exist
+ if ((fp = fopen(".svn"PATHSEP_STR"wc.db", "rb")) != NULL || (fp = fopen(".."PATHSEP_STR".svn"PATHSEP_STR"wc.db", "rb")) != NULL) {
+
+#ifndef SVNNODEPATH //not sure how to handle branches, so i'll leave this overridable define until a better solution comes up
+#define SVNNODEPATH trunk
+#endif // SVNNODEPATH
+
+ const char* prefix = "!svn/ver/";
+ const char* postfix = "/"EXPAND_AND_QUOTE(SVNNODEPATH)")"; // there should exist only 1 entry like this
+ size_t prefix_len = strlen(prefix);
+ size_t postfix_len = strlen(postfix);
+ size_t i,j,flen;
+ char* buffer;
+
+ // read file to buffer
+ fseek(fp, 0, SEEK_END);
+ flen = ftell(fp);
+ buffer = (char*)aMalloc(flen + 1);
+ fseek(fp, 0, SEEK_SET);
+ flen = fread(buffer, 1, flen, fp);
+ buffer[flen] = '\0';
+ fclose(fp);
+
+ // parse buffer
+ for (i = prefix_len + 1; i + postfix_len <= flen; ++i) {
+ if (buffer[i] != postfix[0] || memcmp(buffer + i, postfix, postfix_len) != 0)
+ continue; // postfix mismatch
+ for (j = i; j > 0; --j) { // skip digits
+ if (!ISDIGIT(buffer[j - 1]))
+ break;
+ }
+ if (memcmp(buffer + j - prefix_len, prefix, prefix_len) != 0)
+ continue; // prefix mismatch
+ // done
+ if (*out != NULL)
+ aFree(*out);
+ *out = aCalloc(1, 8);
+ snprintf(*out, 8, "%d", atoi(buffer + j));
+ break;
+ }
+ aFree(buffer);
+
+ if (*out != NULL)
+ return true;
+ }
+
+ // subversion 1.6 and older?
+ if ((fp = fopen(".svn/entries", "r")) != NULL) {
+ char line[1024];
+ int rev;
+ // Check the version
+ if (fgets(line, sizeof(line), fp)) {
+ if (!ISDIGIT(line[0])) {
+ // XML File format
+ while (fgets(line,sizeof(line),fp))
+ if (strstr(line,"revision=")) break;
+ if (sscanf(line," %*[^\"]\"%d%*[^\n]", &rev) == 1) {
+ if (*out != NULL)
+ aFree(*out);
+ *out = aCalloc(1, 8);
+ snprintf(*out, 8, "%d", rev);
+ }
+ } else {
+ // Bin File format
+ if (fgets(line, sizeof(line), fp) == NULL) { printf("Can't get bin name\n"); } // Get the name
+ if (fgets(line, sizeof(line), fp) == NULL) { printf("Can't get entries kind\n"); } // Get the entries kind
+ if (fgets(line, sizeof(line), fp)) { // Get the rev numver
+ if (*out != NULL)
+ aFree(*out);
+ *out = aCalloc(1, 8);
+ snprintf(*out, 8, "%d", atoi(line));
+ }
+ }
+ }
+ fclose(fp);
+
+ if (*out != NULL)
+ return true;
+ }
+#endif
+ if (*out != NULL)
+ aFree(*out);
+ *out = NULL;
+ return false;
+}
+
+/**
+ * Retrieves the current Git revision.
+ *
+ * @param out[out] a string pointer to return the value (to be aFree()'d.)
+ * @retval true if a revision was correctly detected.
+ * @retval false if no revision was detected. out is set to NULL in this case.
+ */
+bool sysinfo_git_get_revision(char **out) {
+ // Only include Git support if we detected it, or we're on MSVC
+#if !defined(SYSINFO_VCSTYPE) || SYSINFO_VCSTYPE == VCSTYPE_GIT || SYSINFO_VCSTYPE == VCSTYPE_UNKNOWN
+ FILE *fp;
+ char ref[128], filepath[128], line[128];
+
+ strcpy(ref, "HEAD");
+
+ while (*ref) {
+ snprintf(filepath, sizeof(filepath), ".git/%s", ref);
+ if ((fp = fopen(filepath, "r")) != NULL) {
+ if (fgets(line, sizeof(line)-1, fp) == NULL) {
+ fclose(fp);
+ break;
+ }
+ fclose(fp);
+ if (sscanf(line, "ref: %127[^\n]", ref) == 1) {
+ continue;
+ } else if (sscanf(line, "%127[a-f0-9]", ref) == 1 && strlen(ref) == 40) {
+ if (*out != NULL)
+ aFree(*out);
+ *out = aStrdup(ref);
+ }
+ }
+ break;
+ }
+ if (*out != NULL)
+ return true;
+#else
+ if (*out != NULL)
+ aFree(*out);
+ *out = NULL;
+#endif
+ return false;
+}
+
+#ifdef WIN32
+
+/// Windows-specific runtime detection functions.
+
+typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);
+/**
+ * Retrieves the Operating System version (Windows only).
+ *
+ * Once retrieved, the version string is stored into sysinfo->p->osversion.
+ */
+void sysinfo_osversion_retrieve(void) {
+ OSVERSIONINFOEX osvi;
+ StringBuf buf;
+ ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
+ StrBuf->Init(&buf);
+
+ osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+ if (sysinfo->p->osversion != NULL) {
+ aFree(sysinfo->p->osversion);
+ sysinfo->p->osversion = NULL;
+ }
+
+ /*
+ * #pragma rantmode (on)
+ * Some engineer at Microsoft moronically decided that, since some applications use this information to do version checks and refuse to
+ * run if they detect a new, unknown version of Windows, now nobody will be able to rely on this information anymore, not even those who
+ * need it for reporting or logging.
+ * The correct fix was to let those applications break, and their developer fix them (and in the meanwhile let the users use the
+ * Compatibility settings to run them) but no, they decided they'd deprecate the API, and make it lie for those who use it, reporting
+ * windows 8 even if they're running on 8.1 or newer.
+ * The API wasn't broken, applications were. Now we have broken applications, and a broken API. Great move, Microsoft. Oh right,
+ * there's the Version API helper functions. Or maybe not, since you can only do 'are we running on at least version X?' checks with
+ * those, it's not what we need.
+ * You know what? I'll just silence your deprecation warning for the time being. Maybe by the time you release the next version of
+ * Windows, you'll have provided a less crippled API or something.
+ * #pragma rantmode (off)
+ */
+#pragma warning (push)
+#pragma warning (disable : 4996)
+ if (!GetVersionEx((OSVERSIONINFO*) &osvi)) {
+ sysinfo->p->osversion = aStrdup("Unknown Version");
+ return;
+ }
+#pragma warning (pop)
+
+ if (VER_PLATFORM_WIN32_NT == osvi.dwPlatformId // Windows NT Family
+ && ((osvi.dwMajorVersion > 4 && osvi.dwMajorVersion < 6) || (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 3)) // Between XP and 8.1
+ ) {
+ if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion <= 3) { // Between Vista and 8.1
+ PGPI pGPI;
+ DWORD dwType;
+ if (osvi.dwMinorVersion == 0) {
+ StrBuf->AppendStr(&buf, osvi.wProductType == VER_NT_WORKSTATION ? "Windows Vista" : "Windows Server 2008");
+ } else if (osvi.dwMinorVersion == 1) {
+ StrBuf->AppendStr(&buf, osvi.wProductType == VER_NT_WORKSTATION ? "Windows 7" : "Windows Server 2008 R2");
+ } else {
+ // If it's 2, it can be Windows 8, or any newer version (8.1 at the time of writing this) -- see above for the reason.
+ switch (osvi.dwMinorVersion) {
+ case 2:
+ {
+ ULONGLONG mask = 0;
+ OSVERSIONINFOEX osvi2;
+ ZeroMemory(&osvi2, sizeof(OSVERSIONINFOEX));
+ osvi2.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ osvi2.dwMajorVersion = 6;
+ osvi2.dwMinorVersion = 2;
+ VER_SET_CONDITION(mask, VER_MAJORVERSION, VER_LESS_EQUAL);
+ VER_SET_CONDITION(mask, VER_MINORVERSION, VER_LESS_EQUAL);
+ if (VerifyVersionInfo(&osvi2, VER_MAJORVERSION | VER_MINORVERSION, mask)) {
+ StrBuf->AppendStr(&buf, osvi.wProductType == VER_NT_WORKSTATION ? "Windows 8" : "Windows Server 2012");
+ break;
+ }
+ }
+ case 3:
+ StrBuf->AppendStr(&buf, osvi.wProductType == VER_NT_WORKSTATION ? "Windows 8.1" : "Windows Server 2012 R2");
+ }
+ }
+
+ pGPI = (PGPI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetProductInfo");
+
+ pGPI(osvi.dwMajorVersion, osvi.dwMinorVersion, 0, 0, &dwType);
+
+ switch (dwType) {
+ case msPRODUCT_ULTIMATE:
+ case msPRODUCT_ULTIMATE_N:
+ StrBuf->AppendStr(&buf, " Ultimate");
+ break;
+ case msPRODUCT_PROFESSIONAL:
+ case msPRODUCT_PROFESSIONAL_N:
+ case msPRODUCT_PROFESSIONAL_WMC:
+ StrBuf->AppendStr(&buf, " Professional");
+ break;
+ case msPRODUCT_HOME_PREMIUM:
+ case msPRODUCT_HOME_PREMIUM_N:
+ StrBuf->AppendStr(&buf, " Home Premium");
+ break;
+ case msPRODUCT_HOME_BASIC:
+ case msPRODUCT_HOME_BASIC_N:
+ StrBuf->AppendStr(&buf, " Home Basic");
+ break;
+ case msPRODUCT_ENTERPRISE:
+ case msPRODUCT_ENTERPRISE_N:
+ case msPRODUCT_ENTERPRISE_SERVER:
+ case msPRODUCT_ENTERPRISE_SERVER_CORE:
+ case msPRODUCT_ENTERPRISE_SERVER_IA64:
+ case msPRODUCT_ENTERPRISE_SERVER_V:
+ case msPRODUCT_ENTERPRISE_SERVER_CORE_V:
+ case msPRODUCT_ENTERPRISE_EVALUATION:
+ case msPRODUCT_ENTERPRISE_N_EVALUATION:
+ StrBuf->AppendStr(&buf, " Enterprise");
+ break;
+ case msPRODUCT_BUSINESS:
+ case msPRODUCT_BUSINESS_N:
+ StrBuf->AppendStr(&buf, " Business");
+ break;
+ case msPRODUCT_STARTER:
+ case msPRODUCT_STARTER_N:
+ StrBuf->AppendStr(&buf, " Starter");
+ break;
+ case msPRODUCT_CLUSTER_SERVER:
+ case msPRODUCT_CLUSTER_SERVER_V:
+ StrBuf->AppendStr(&buf, " Cluster Server");
+ break;
+ case msPRODUCT_DATACENTER_SERVER:
+ case msPRODUCT_DATACENTER_SERVER_CORE:
+ case msPRODUCT_DATACENTER_SERVER_V:
+ case msPRODUCT_DATACENTER_SERVER_CORE_V:
+ case msPRODUCT_DATACENTER_EVALUATION_SERVER:
+ StrBuf->AppendStr(&buf, " Datacenter");
+ break;
+ case msPRODUCT_SMALLBUSINESS_SERVER:
+ case msPRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
+ case msPRODUCT_SMALLBUSINESS_SERVER_PREMIUM_CORE:
+ StrBuf->AppendStr(&buf, " Small Business Server");
+ break;
+ case PRODUCT_STANDARD_SERVER:
+ case PRODUCT_STANDARD_SERVER_CORE:
+ case msPRODUCT_STANDARD_SERVER_V:
+ case msPRODUCT_STANDARD_SERVER_CORE_V:
+ case msPRODUCT_STANDARD_EVALUATION_SERVER:
+ StrBuf->AppendStr(&buf, " Standard");
+ break;
+ case msPRODUCT_WEB_SERVER:
+ case msPRODUCT_WEB_SERVER_CORE:
+ StrBuf->AppendStr(&buf, " Web Server");
+ break;
+ case msPRODUCT_STORAGE_EXPRESS_SERVER:
+ case msPRODUCT_STORAGE_STANDARD_SERVER:
+ case msPRODUCT_STORAGE_WORKGROUP_SERVER:
+ case msPRODUCT_STORAGE_ENTERPRISE_SERVER:
+ case msPRODUCT_STORAGE_EXPRESS_SERVER_CORE:
+ case msPRODUCT_STORAGE_STANDARD_SERVER_CORE:
+ case msPRODUCT_STORAGE_WORKGROUP_SERVER_CORE:
+ case msPRODUCT_STORAGE_ENTERPRISE_SERVER_CORE:
+ case msPRODUCT_STORAGE_WORKGROUP_EVALUATION_SERVER:
+ case msPRODUCT_STORAGE_STANDARD_EVALUATION_SERVER:
+ StrBuf->AppendStr(&buf, " Storage Server");
+ break;
+ case msPRODUCT_HOME_SERVER:
+ case msPRODUCT_SERVER_FOR_SMALLBUSINESS:
+ case msPRODUCT_MEDIUMBUSINESS_SERVER_MANAGEMENT:
+ case msPRODUCT_MEDIUMBUSINESS_SERVER_SECURITY:
+ case msPRODUCT_MEDIUMBUSINESS_SERVER_MESSAGING:
+ case msPRODUCT_SERVER_FOR_SMALLBUSINESS_V:
+ case msPRODUCT_SERVER_FOUNDATION:
+ case msPRODUCT_HOME_PREMIUM_SERVER:
+ case msPRODUCT_HYPERV:
+ case msPRODUCT_SB_SOLUTION_SERVER:
+ case msPRODUCT_SERVER_FOR_SB_SOLUTIONS:
+ case msPRODUCT_STANDARD_SERVER_SOLUTIONS:
+ case msPRODUCT_STANDARD_SERVER_SOLUTIONS_CORE:
+ case msPRODUCT_SB_SOLUTION_SERVER_EM:
+ case msPRODUCT_SERVER_FOR_SB_SOLUTIONS_EM:
+ case msPRODUCT_SOLUTION_EMBEDDEDSERVER:
+ case msPRODUCT_ESSENTIALBUSINESS_SERVER_MGMT:
+ case msPRODUCT_ESSENTIALBUSINESS_SERVER_ADDL:
+ case msPRODUCT_ESSENTIALBUSINESS_SERVER_MGMTSVC:
+ case msPRODUCT_ESSENTIALBUSINESS_SERVER_ADDLSVC:
+ case msPRODUCT_MULTIPOINT_STANDARD_SERVER:
+ case msPRODUCT_MULTIPOINT_PREMIUM_SERVER:
+ StrBuf->AppendStr(&buf, " Server (other)");
+ break;
+ case msPRODUCT_CORE_N:
+ case msPRODUCT_CORE_COUNTRYSPECIFIC:
+ case msPRODUCT_CORE_SINGLELANGUAGE:
+ case msPRODUCT_CORE:
+ StrBuf->AppendStr(&buf, " Workstation (other)");
+ break;
+ }
+
+ } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) { // XP x64 and Server 2003
+ if (osvi.wProductType == VER_NT_WORKSTATION) {
+ StrBuf->AppendStr(&buf, "Windows XP Professional");
+ } else {
+ if (GetSystemMetrics(msSM_SERVERR2))
+ StrBuf->AppendStr(&buf, "Windows Server 2003 R2");
+ else if (osvi.wSuiteMask & msVER_SUITE_STORAGE_SERVER)
+ StrBuf->AppendStr(&buf, "Windows Storage Server 2003");
+ else if (osvi.wSuiteMask & msVER_SUITE_WH_SERVER)
+ StrBuf->AppendStr(&buf, "Windows Home Server");
+ else
+ StrBuf->AppendStr(&buf, "Windows Server 2003");
+
+ // Test for the server type.
+ if (osvi.wSuiteMask & msVER_SUITE_COMPUTE_SERVER)
+ StrBuf->AppendStr(&buf, " Compute Cluster");
+ else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ StrBuf->AppendStr(&buf, " Datacenter");
+ else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ StrBuf->AppendStr(&buf, " Enterprise");
+ else if (osvi.wSuiteMask & msVER_SUITE_BLADE)
+ StrBuf->AppendStr(&buf, " Web");
+ else
+ StrBuf->AppendStr(&buf, " Standard");
+ }
+ } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) { // XP
+ StrBuf->AppendStr(&buf, "Windows XP");
+ if (osvi.wSuiteMask & VER_SUITE_EMBEDDEDNT)
+ StrBuf->AppendStr(&buf, " Embedded");
+ else if (osvi.wSuiteMask & VER_SUITE_PERSONAL)
+ StrBuf->AppendStr(&buf, " Home");
+ else
+ StrBuf->AppendStr(&buf, " Professional");
+ } else if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) { // 2000
+ StrBuf->AppendStr(&buf, "Windows 2000");
+
+ if (osvi.wProductType == VER_NT_WORKSTATION)
+ StrBuf->AppendStr(&buf, " Professional");
+ else if (osvi.wSuiteMask & VER_SUITE_DATACENTER)
+ StrBuf->AppendStr(&buf, " Datacenter Server");
+ else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE)
+ StrBuf->AppendStr(&buf, " Advanced Server");
+ else
+ StrBuf->AppendStr(&buf, " Server");
+ } else {
+ StrBuf->Printf(&buf, "Unknown Windows version %d.%d", osvi.dwMajorVersion, osvi.dwMinorVersion);
+ }
+ }
+
+ // Include service pack (if any) and build number.
+
+ if (strlen(osvi.szCSDVersion) > 0) {
+ StrBuf->Printf(&buf, " %s", osvi.szCSDVersion);
+ }
+
+ StrBuf->Printf(&buf, " (build %d)", osvi.dwBuildNumber);
+
+ sysinfo->p->osversion = aStrdup(StrBuf->Value(&buf));
+
+ StrBuf->Destroy(&buf);
+ return;
+}
+
+typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
+/**
+ * Retrieves the CPU type (Windows only).
+ *
+ * Once retrieved, the name is stored into sysinfo->p->cpu and the
+ * number of cores in sysinfo->p->cpucores.
+ */
+void sysinfo_cpu_retrieve(void) {
+ StringBuf buf;
+ PGNSI pGNSI;
+ SYSTEM_INFO si;
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+ StrBuf->Init(&buf);
+
+ if (sysinfo->p->cpu != NULL) {
+ aFree(sysinfo->p->cpu);
+ sysinfo->p->cpu = NULL;
+ }
+
+ // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
+ pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
+ if (NULL != pGNSI)
+ pGNSI(&si);
+ else
+ GetSystemInfo(&si);
+
+ if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL
+ || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64
+ ) {
+ StrBuf->Printf(&buf, "%s CPU, Family %d, Model %d, Stepping %d",
+ si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL ? "x86" : "x86_64",
+ si.wProcessorLevel,
+ (si.wProcessorRevision&0xff00)>>8,
+ (si.wProcessorRevision&0xff));
+ } else {
+ StrBuf->AppendStr(&buf, "Unknown");
+ }
+
+ sysinfo->p->cpu = aStrdup(StrBuf->Value(&buf));
+ sysinfo->p->cpucores = si.dwNumberOfProcessors;
+
+ StrBuf->Destroy(&buf);
+}
+
+/**
+ * Retrieves the OS architecture (Windows only).
+ *
+ * Once retrieved, the name is stored into sysinfo->p->arch.
+ */
+void sysinfo_arch_retrieve(void) {
+ PGNSI pGNSI;
+ SYSTEM_INFO si;
+ ZeroMemory(&si, sizeof(SYSTEM_INFO));
+
+ if (sysinfo->p->arch != NULL) {
+ aFree(sysinfo->p->arch);
+ sysinfo->p->arch = NULL;
+ }
+
+ // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.
+ pGNSI = (PGNSI) GetProcAddress(GetModuleHandle(TEXT("kernel32.dll")), "GetNativeSystemInfo");
+ if (NULL != pGNSI)
+ pGNSI(&si);
+ else
+ GetSystemInfo(&si);
+
+ if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) // x64
+ sysinfo->p->arch = aStrdup("x86_64");
+ else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) // x32
+ sysinfo->p->arch = aStrdup("x86");
+ else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM) // ARM
+ sysinfo->p->arch = aStrdup("ARM");
+ else if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) // Itanium
+ sysinfo->p->arch = aStrdup("IA-64");
+ else
+ sysinfo->p->arch = aStrdup("Unknown");
+}
+
+/**
+ * Retrieves the startup-time VCS revision information.
+ *
+ * Once retrieved, the value is stored in sysinfo->p->vcsrevision_src.
+ */
+void sysinfo_vcsrevision_src_retrieve(void) {
+ if (sysinfo->p->vcsrevision_src != NULL) {
+ aFree(sysinfo->p->vcsrevision_src);
+ sysinfo->p->vcsrevision_src = NULL;
+ }
+ // Try Git, then SVN
+ if (sysinfo_git_get_revision(&sysinfo->p->vcsrevision_src)) {
+ sysinfo->p->vcstype = VCSTYPE_GIT;
+ return;
+ }
+ if (sysinfo_svn_get_revision(&sysinfo->p->vcsrevision_src)) {
+ sysinfo->p->vcstype = VCSTYPE_SVN;
+ return;
+ }
+ sysinfo->p->vcstype = VCSTYPE_NONE;
+ sysinfo->p->vcsrevision_src = aStrdup("Unknown");
+}
+#endif // WIN32
+
+/**
+ * Retrieevs the VCS type name.
+ *
+ * Once retrieved, the value is stored in sysinfo->p->vcstype_name.
+ */
+void sysinfo_vcstype_name_retrieve(void) {
+ if (sysinfo->p->vcstype_name != NULL) {
+ aFree(sysinfo->p->vcstype_name);
+ sysinfo->p->vcstype_name = NULL;
+ }
+ switch (sysinfo->p->vcstype) {
+ case VCSTYPE_GIT:
+ sysinfo->p->vcstype_name = aStrdup("Git");
+ break;
+ case VCSTYPE_SVN:
+ sysinfo->p->vcstype_name = aStrdup("SVN");
+ break;
+ default:
+ sysinfo->p->vcstype_name = aStrdup("Exported");
+ break;
+ }
+}
+
+/**
+ * Returns the platform (OS type) this application is running on.
+ *
+ * This information is cached at compile time, since it's unlikely to change.
+ *
+ * @return the OS platform name.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: "Linux", "Darwin", "Windows", etc.
+ */
+const char *sysinfo_platform(void) {
+ return sysinfo->p->platform;
+}
+
+/**
+ * Returns the Operating System version the application is running on.
+ *
+ * On platforms other than Windows (MSVC), this information is cached at
+ * compile time, since it is uncommon that an application is compiled and runs
+ * on different machines.
+ *
+ * @return the OS name.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: "Windows 2008 Small Business Server", "OS X 10.8 Mountain Lion",
+ * "Gentoo Base System Release 2.2", "Debian GNU/Linux 6.0.6 (squeeze)", etc.
+ */
+const char *sysinfo_osversion(void) {
+ return sysinfo->p->osversion;
+}
+
+/**
+ * Returns the CPU model the application is running on.
+ *
+ * On platforms other than Windows (MSVC), this information is cached at
+ * compile time, since it is uncommon that an application is compiled and runs
+ * on different machines.
+ *
+ * @return the CPU model name.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: "Intel(R) Atom(TM) CPU D2500 @ 1.86GHz",
+ * "Intel(R) Xeon(R) CPU E5-1650 0 @ 3.20GHz", "Intel Core i7",
+ * "x86 CPU, Family 6, Model 54, Stepping 1", etc.
+ */
+const char *sysinfo_cpu(void) {
+ return sysinfo->p->cpu;
+}
+
+/**
+ * Returns the number of CPU cores available.
+ *
+ * On platforms other than Windows (MSVC), this information is cached at
+ * compile time, since it is uncommon that an application is compiled and runs
+ * on different machines.
+ *
+ * @return the number of CPU cores.
+ */
+int sysinfo_cpucores(void) {
+ return sysinfo->p->cpucores;
+}
+
+/**
+ * Returns the CPU architecture the application was compiled for.
+ *
+ * On platforms other than Windows (MSVC), this information is cached at
+ * compile time, since it is uncommon that an application is compiled and runs
+ * on different machines.
+ *
+ * @return the CPU architecture name.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: "x86", "x86_64", "IA-64", "ARM", etc.
+ */
+const char *sysinfo_arch(void) {
+ return sysinfo->p->arch;
+}
+
+/**
+ * Returns info about the 32 or 64 bit build of Hercules.
+ *
+ * @retval true if this is a 64 bit build.
+ * @retval false if this isn't a 64 bit build (i.e. it is a 32 bit build).
+ */
+bool sysinfo_is64bit(void) {
+#ifdef _LP64
+ return true;
+#else
+ return false;
+#endif
+}
+
+/**
+ * Returns the compiler the application was compiled with.
+ *
+ * @return the compiler name.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: "Microsoft Visual C++ 2012 (v170050727)",
+ * "Clang v5.0.0", "MinGW32 v3.20", "GCC v4.7.3", etc.
+ */
+const char *sysinfo_compiler(void) {
+ return sysinfo->p->compiler;
+}
+
+/**
+ * Returns the compiler flags the application was compiled with.
+ *
+ * On Windows (MSVC), an empty string is returned instead.
+ *
+ * @return the compiler flags.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: "-ggdb -O2 -flto -pipe -ffast-math ..."
+ */
+const char *sysinfo_cflags(void) {
+ return sysinfo->p->cflags;
+}
+
+/**
+ * Returns the Version Control System the application was downloaded with.
+ *
+ * On platforms other than Windows (MSVC), this information is cached at
+ * compile time. On Windows (MSVC), it is cached when the function is first
+ * called (most likely on server startup).
+ *
+ * @return the VCS type (numerical).
+ *
+ * @see VCSTYPE_NONE, VCSTYPE_GIT, VCSTYPE_SVN, VCSTYPE_UNKNOWN
+ */
+int sysinfo_vcstypeid(void) {
+ return sysinfo->p->vcstype;
+}
+
+/**
+ * Returns the Version Control System the application was downloaded with.
+ *
+ * On platforms other than Windows (MSVC), this information is cached at
+ * compile time. On Windows (MSVC), it is cached when the function is first
+ * called (most likely on server startup).
+ *
+ * @return the VCS type.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: "Git", "SVN", "Exported"
+ */
+const char *sysinfo_vcstype(void) {
+ return sysinfo->p->vcstype_name;
+}
+
+/**
+ * Returns the Version Control System revision.
+ *
+ * On platforms other than Windows (MSVC), this information is cached at
+ * compile time for better reliability. On Windows (MSVC), it is cached when
+ * the function is first called (most likely on server startup), so it may
+ * diverge from the actual revision that was compiled.
+ *
+ * @return the VCS revision.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: Git: "9128feccf3bddda94a7f8a170305565416815b40", SVN: "17546"
+ */
+const char *sysinfo_vcsrevision_src(void) {
+ return sysinfo->p->vcsrevision_src;
+}
+
+/**
+ * Returns the Version Control System revision.
+ *
+ * This information is cached during a script reload, so that it matches the
+ * version of the loaded scripts.
+ *
+ * @return the VCS revision.
+ *
+ * Note: Ownership is NOT transferred, the value should not be freed.
+ *
+ * Output example: Git: "9128feccf3bddda94a7f8a170305565416815b40", SVN: "17546"
+ */
+const char *sysinfo_vcsrevision_scripts(void) {
+ return sysinfo->p->vcsrevision_scripts;
+}
+
+/**
+ * Reloads the run-time (scripts) VCS revision information. To be used during
+ * script reloads to refresh the cached version.
+ */
+void sysinfo_vcsrevision_reload(void) {
+ if (sysinfo->p->vcsrevision_scripts != NULL) {
+ aFree(sysinfo->p->vcsrevision_scripts);
+ sysinfo->p->vcsrevision_scripts = NULL;
+ }
+ // Try Git, then SVN
+ if (sysinfo_git_get_revision(&sysinfo->p->vcsrevision_scripts)) {
+ return;
+ }
+ if (sysinfo_svn_get_revision(&sysinfo->p->vcsrevision_scripts)) {
+ return;
+ }
+ sysinfo->p->vcsrevision_scripts = aStrdup("Unknown");
+}
+
+/**
+ * Checks if we're running (unnecessarily) as superuser.
+ *
+ * @retval true if the current process is running as UNIX super-user.
+ * @retval false if the current process is running as regular user, or
+ * in any case under Windows.
+ */
+bool sysinfo_is_superuser(void) {
+#ifndef _WIN32
+ if (geteuid() == 0)
+ return true;
+#endif
+ return false;
+}
+
+/**
+ * Interface runtime initialization.
+ */
+void sysinfo_init(void) {
+ sysinfo->p->compiler = SYSINFO_COMPILER;
+#ifdef WIN32
+ sysinfo->p->platform = "Windows";
+ sysinfo->p->cflags = "N/A";
+ sysinfo_osversion_retrieve();
+ sysinfo_cpu_retrieve();
+ sysinfo_arch_retrieve();
+ sysinfo_vcsrevision_src_retrieve();
+#else
+ sysinfo->p->platform = SYSINFO_PLATFORM;
+ sysinfo->p->osversion = SYSINFO_OSVERSION;
+ sysinfo->p->cpucores = SYSINFO_CPUCORES;
+ sysinfo->p->cpu = SYSINFO_CPU;
+ sysinfo->p->arch = SYSINFO_ARCH;
+ sysinfo->p->cflags = SYSINFO_CFLAGS;
+ sysinfo->p->vcstype = SYSINFO_VCSTYPE;
+ sysinfo->p->vcsrevision_src = SYSINFO_VCSREV;
+#endif
+ sysinfo->vcsrevision_reload();
+ sysinfo_vcstype_name_retrieve(); // Must be called after setting vcstype
+}
+
+/**
+ * Interface shutdown cleanup.
+ */
+void sysinfo_final(void) {
+#ifdef WIN32
+ // Only need to be free'd in win32, they're #defined elsewhere
+ if (sysinfo->p->osversion)
+ aFree(sysinfo->p->osversion);
+ if (sysinfo->p->cpu)
+ aFree(sysinfo->p->cpu);
+ if (sysinfo->p->arch)
+ aFree(sysinfo->p->arch);
+ if (sysinfo->p->vcsrevision_src)
+ aFree(sysinfo->p->vcsrevision_src);
+#endif
+ sysinfo->p->platform = NULL;
+ sysinfo->p->osversion = NULL;
+ sysinfo->p->cpu = NULL;
+ sysinfo->p->arch = NULL;
+ sysinfo->p->vcsrevision_src = NULL;
+ sysinfo->p->cflags = NULL;
+ if (sysinfo->p->vcsrevision_scripts)
+ aFree(sysinfo->p->vcsrevision_scripts);
+ sysinfo->p->vcsrevision_scripts = NULL;
+ if (sysinfo->p->vcstype_name)
+ aFree(sysinfo->p->vcstype_name);
+ sysinfo->p->vcstype_name = NULL;
+}
+
+/**
+ * Interface default values initialization.
+ */
+void sysinfo_defaults(void) {
+ sysinfo = &sysinfo_s;
+ memset(&sysinfo_p, '\0', sizeof(sysinfo_p));
+ sysinfo->p = &sysinfo_p;
+
+ sysinfo->platform = sysinfo_platform;
+ sysinfo->osversion = sysinfo_osversion;
+ sysinfo->cpu = sysinfo_cpu;
+ sysinfo->cpucores = sysinfo_cpucores;
+ sysinfo->arch = sysinfo_arch;
+ sysinfo->is64bit = sysinfo_is64bit;
+ sysinfo->compiler = sysinfo_compiler;
+ sysinfo->cflags = sysinfo_cflags;
+ sysinfo->vcstype = sysinfo_vcstype;
+ sysinfo->vcstypeid = sysinfo_vcstypeid;
+ sysinfo->vcsrevision_src = sysinfo_vcsrevision_src;
+ sysinfo->vcsrevision_scripts = sysinfo_vcsrevision_scripts;
+ sysinfo->vcsrevision_reload = sysinfo_vcsrevision_reload;
+ sysinfo->is_superuser = sysinfo_is_superuser;
+ sysinfo->init = sysinfo_init;
+ sysinfo->final = sysinfo_final;
+}
diff --git a/src/common/sysinfo.h b/src/common/sysinfo.h
new file mode 100644
index 000000000..17faac26b
--- /dev/null
+++ b/src/common/sysinfo.h
@@ -0,0 +1,62 @@
+// Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+// See the LICENSE file
+// Base Author: Haru @ http://hercules.ws
+
+#ifndef _COMMON_SYSINFO_H_
+#define _COMMON_SYSINFO_H_
+
+/**
+ * Provides various bits of information about the system Hercules is running on
+ * (note: on unix systems, to avoid runtime detection, most of the data is
+ * cached at compile time)
+ */
+
+#include "../common/cbasetypes.h"
+
+#ifdef _COMMON_SYSINFO_P_
+struct sysinfo_private {
+ char *platform;
+ char *osversion;
+ char *cpu;
+ int cpucores;
+ char *arch;
+ char *compiler;
+ char *cflags;
+ char *vcstype_name;
+ int vcstype;
+ char *vcsrevision_src;
+ char *vcsrevision_scripts;
+};
+#else
+struct sysinfo_private;
+#endif
+
+/**
+ * sysinfo.c interface
+ **/
+struct sysinfo_interface {
+ struct sysinfo_private *p;
+
+ const char *(*platform) (void);
+ const char *(*osversion) (void);
+ const char *(*cpu) (void);
+ int (*cpucores) (void);
+ const char *(*arch) (void);
+ bool (*is64bit) (void);
+ const char *(*compiler) (void);
+ const char *(*cflags) (void);
+ const char *(*vcstype) (void);
+ int (*vcstypeid) (void);
+ const char *(*vcsrevision_src) (void);
+ const char *(*vcsrevision_scripts) (void);
+ void (*vcsrevision_reload) (void);
+ bool (*is_superuser) (void);
+ void (*init) (void);
+ void (*final) (void);
+};
+
+struct sysinfo_interface *sysinfo;
+
+void sysinfo_defaults(void);
+
+#endif /* _COMMON_SYSINFO_H_ */
diff --git a/src/common/timer.h b/src/common/timer.h
index ab3ffc21f..1ce8cf203 100644
--- a/src/common/timer.h
+++ b/src/common/timer.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _COMMON_TIMER_H_
-#define _COMMON_TIMER_H_
+#ifndef _COMMON_TIMER_H_
+#define _COMMON_TIMER_H_
#include "../common/cbasetypes.h"
diff --git a/src/login/Makefile.in b/src/login/Makefile.in
index fa5f92105..033dad25b 100644
--- a/src/login/Makefile.in
+++ b/src/login/Makefile.in
@@ -1,9 +1,12 @@
+# Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+# See the LICENSE file
CONFIG_D = ../config
CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h)
COMMON_D = ../common
COMMON_H = $(wildcard $(COMMON_D)/*.h)
+SYSINFO_INC = $(COMMON_D)/sysinfo.inc
LIBCONFIG_D = ../../3rdparty/libconfig
LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \
@@ -23,7 +26,7 @@ LOGIN_H = login.h account.h ipban.h loginlog.h
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
- LOGIN_SERVER_SQL_DEPENDS=$(LOGIN_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ)
+ LOGIN_SERVER_SQL_DEPENDS=$(LOGIN_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ $(SYSINFO_INC))
else
LOGIN_SERVER_SQL_DEPENDS=needs_mysql
endif
@@ -62,6 +65,10 @@ help:
Makefile: Makefile.in
@$(MAKE) -C ../.. src/login/Makefile
+$(SYSINFO_INC): $(LOGIN_C) $(LOGIN_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H)
+ @echo " MAKE $@"
+ @$(MAKE) -C ../.. sysinfo
+
needs_mysql:
@echo "MySQL not found or disabled by the configure script"
@exit 1
diff --git a/src/map/Makefile.in b/src/map/Makefile.in
index e3a47abeb..e4f2d9953 100644
--- a/src/map/Makefile.in
+++ b/src/map/Makefile.in
@@ -1,9 +1,12 @@
+# Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+# See the LICENSE file
CONFIG_D = ../config
CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h)
COMMON_D = ../common
COMMON_H = $(wildcard $(COMMON_D)/*.h)
+SYSINFO_INC = $(COMMON_D)/sysinfo.inc
LIBCONFIG_D = ../../3rdparty/libconfig
LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \
@@ -33,7 +36,7 @@ MAP_H = atcommand.h battle.h battleground.h buyingstore.h chat.h chrif.h \
HAVE_MYSQL=@HAVE_MYSQL@
ifeq ($(HAVE_MYSQL),yes)
- MAP_SERVER_SQL_DEPENDS=$(MAP_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ)
+ MAP_SERVER_SQL_DEPENDS=$(MAP_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ $(SYSINFO_INC))
else
MAP_SERVER_SQL_DEPENDS=needs_mysql
endif
@@ -79,6 +82,10 @@ help:
Makefile: Makefile.in
@$(MAKE) -C ../.. src/map/Makefile
+$(SYSINFO_INC): $(MAP_C) $(MAP_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H)
+ @echo " MAKE $@"
+ @$(MAKE) -C ../.. sysinfo
+
needs_mysql:
@echo "MySQL not found or disabled by the configure script"
@exit 1
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 09159c3f7..5fd0faf86 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -14,6 +14,7 @@
#include "../common/strlib.h"
#include "../common/utils.h"
#include "../common/conf.h"
+#include "../common/sysinfo.h"
#include "atcommand.h"
#include "battle.h"
@@ -403,6 +404,11 @@ ACMD(mapmove) {
clif->message(fd, msg_txt(1)); // Map not found.
return false;
}
+
+ if( sd->bl.m == m && sd->bl.x == x && sd->bl.y == y ) {
+ clif->message(fd, msg_txt(253)); // You already are at your destination!
+ return false;
+ }
if ((x || y) && map->getcell(m, x, y, CELL_CHKNOPASS) && pc_get_group_level(sd) < battle_config.gm_ignore_warpable_area) {
//This is to prevent the pc->setpos call from printing an error.
@@ -460,12 +466,22 @@ ACMD(where) {
*------------------------------------------*/
ACMD(jumpto) {
struct map_session_data *pl_sd = NULL;
-
+
if (!message || !*message) {
clif->message(fd, msg_txt(911)); // Please enter a player name (usage: @jumpto/@warpto/@goto <char name/ID>).
return false;
}
-
+
+ if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
+ clif->message(fd, msg_txt(248)); // You are not authorized to warp from your current map.
+ return false;
+ }
+
+ if( pc_isdead(sd) ) {
+ clif->message(fd, msg_txt(864)); // "You cannot use this command when dead."
+ return false;
+ }
+
if((pl_sd=map->nick2sd((char *)message)) == NULL && (pl_sd=map->charid2sd(atoi(message))) == NULL) {
clif->message(fd, msg_txt(3)); // Character not found.
return false;
@@ -475,21 +491,16 @@ ACMD(jumpto) {
clif->message(fd, msg_txt(247)); // You are not authorized to warp to this map.
return false;
}
-
- if (sd->bl.m >= 0 && map->list[sd->bl.m].flag.nowarp && !pc_has_permission(sd, PC_PERM_WARP_ANYWHERE)) {
- clif->message(fd, msg_txt(248)); // You are not authorized to warp from your current map.
- return false;
- }
-
- if( pc_isdead(sd) ) {
- clif->message(fd, msg_txt(864)); // "You cannot use this command when dead."
+
+ if( pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y ) {
+ clif->message(fd, msg_txt(253)); // You already are at your destination!
return false;
}
-
+
pc->setpos(sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);
sprintf(atcmd_output, msg_txt(4), pl_sd->status.name); // Jumped to %s
- clif->message(fd, atcmd_output);
-
+ clif->message(fd, atcmd_output);
+
return true;
}
@@ -520,6 +531,11 @@ ACMD(jump)
if (!map->search_freecell(NULL, sd->bl.m, &x, &y, 10, 10, 1))
x = y = 0; //Invalid cell, use random spot.
}
+
+ if( x && y && sd->bl.x == x && sd->bl.y == y ) {
+ clif->message(fd, msg_txt(253)); // You already are at your destination!
+ return false;
+ }
pc->setpos(sd, sd->mapindex, x, y, CLR_TELEPORT);
sprintf(atcmd_output, msg_txt(5), sd->bl.x, sd->bl.y); // Jumped to %d %d
@@ -824,7 +840,11 @@ ACMD(guildstorage)
return false;
}
- gstorage->open(sd);
+ if( gstorage->open(sd) ) {
+ clif->message(fd, msg_txt(1201)); // Your guild's storage has already been opened by another member, try again later.
+ return false;
+ }
+
clif->message(fd, msg_txt(920)); // Guild storage opened.
return true;
}
@@ -2353,7 +2373,11 @@ ACMD(zeny)
if((ret=pc->payzeny(sd,-zeny,LOG_TYPE_COMMAND,NULL)) == 1)
clif->message(fd, msg_txt(41)); // Unable to decrease the number/value.
}
- if(!ret) clif->message(fd, msg_txt(176)); //ret=0 mean cmd success
+
+ if( ret ) //ret != 0 means cmd failure
+ return false;
+
+ clif->message(fd, msg_txt(176));
return true;
}
@@ -5183,9 +5207,10 @@ ACMD(clearcart)
return false;
}
- if (sd->state.vending == 1) { //Somehow...
- return false;
- }
+ if( sd->state.vending == 1 ) {
+ clif->message(fd, msg_txt(548)); // You can't clean a cart while vending!
+ return false;
+ }
for( i = 0; i < MAX_CART; i++ )
if(sd->status.cart[i].nameid > 0)
@@ -6673,20 +6698,29 @@ ACMD(showmobs)
int number = 0;
struct s_mapiterator* it;
- if(sscanf(message, "%99[^\n]", mob_name) < 0)
+ if( sscanf(message, "%99[^\n]", mob_name) < 0 ) {
+ clif->message(fd, msg_txt(546)); // Please enter a mob name/id (usage: @showmobs <mob name/id>)
return false;
-
- if((mob_id = atoi(mob_name)) == 0)
+ }
+
+ if( (mob_id = atoi(mob_name)) == 0 )
mob_id = mob->db_searchname(mob_name);
+
+ if( mob_id == 0 ) {
+ snprintf(atcmd_output, sizeof atcmd_output, msg_txt(547), mob_name); // Invalid mob name %s!
+ clif->message(fd, atcmd_output);
+ return false;
+ }
+
if(mob_id > 0 && mob->db_checkid(mob_id) == 0){
snprintf(atcmd_output, sizeof atcmd_output, msg_txt(1250),mob_name); // Invalid mob id %s!
clif->message(fd, atcmd_output);
- return true;
+ return false;
}
if(mob->db(mob_id)->status.mode&MD_BOSS && !pc_has_permission(sd, PC_PERM_SHOW_BOSS)){ // If player group does not have access to boss mobs.
clif->message(fd, msg_txt(1251)); // Can't show boss mobs!
- return true;
+ return false;
}
if(mob_id == atoi(mob_name) && mob->db(mob_id)->jname)
@@ -7208,18 +7242,11 @@ ACMD(whereis)
}
ACMD(version) {
- const char *git = get_git_hash();
- const char *svn = get_svn_revision();
-
- if ( git[0] != HERC_UNKNOWN_VER ) {
- sprintf(atcmd_output,msg_txt(1295),git); // Git Hash '%s'
- clif->message(fd,atcmd_output);
- } else if ( svn[0] != HERC_UNKNOWN_VER ) {
- sprintf(atcmd_output,msg_txt(1294),git); // SVN r%s
- clif->message(fd,atcmd_output);
- } else
- clif->message(fd,msg_txt(1296)); // Cannot determine version
-
+ sprintf(atcmd_output, msg_txt(1296), sysinfo->is64bit() ? 64 : 32, sysinfo->platform()); // Hercules %d-bit for %s
+ clif->message(fd, atcmd_output);
+ sprintf(atcmd_output, msg_txt(1295), sysinfo->vcstype(), sysinfo->vcsrevision_src(), sysinfo->vcsrevision_scripts()); // %s revision '%s' (src) / '%s' (scripts)
+ clif->message(fd, atcmd_output);
+
return true;
}
@@ -9954,6 +9981,11 @@ bool atcommand_exec(const int fd, struct map_session_data *sd, const char *messa
//Attempt to use the command
if ( (info->func(fd, (*atcmd_msg == atcommand->at_symbol) ? sd : ssd, command, params,info) != true) ) {
+#ifdef AUTOTRADE_PERSISTENCY
+ // Autotrade was successful if standalone is set
+ if( ((*atcmd_msg == atcommand->at_symbol) ? sd->state.standalone : ssd->state.standalone) )
+ return true;
+#endif
sprintf(output,msg_txt(154), command); // %s failed.
clif->message(fd, output);
return true;
diff --git a/src/map/battle.c b/src/map/battle.c
index 2217ccecc..001553f1c 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -12,6 +12,7 @@
#include "../common/socket.h"
#include "../common/strlib.h"
#include "../common/utils.h"
+#include "../common/sysinfo.h"
#include "../common/HPM.h"
#include "map.h"
@@ -6711,8 +6712,9 @@ static const struct _battle_data {
/**
* rAthena
**/
- { "max_third_parameter", &battle_config.max_third_parameter, 120, 10, 10000, },
- { "max_baby_third_parameter", &battle_config.max_baby_third_parameter, 108, 10, 10000, },
+ { "max_third_parameter", &battle_config.max_third_parameter, 130, 10, 10000, },
+ { "max_baby_third_parameter", &battle_config.max_baby_third_parameter, 117, 10, 10000, },
+ { "max_extended_parameter", &battle_config.max_extended_parameter, 125, 10, 10000, },
{ "atcommand_max_stat_bypass", &battle_config.atcommand_max_stat_bypass, 0, 0, 100, },
{ "skill_amotion_leniency", &battle_config.skill_amotion_leniency, 90, 0, 300 },
{ "mvp_tomb_enabled", &battle_config.mvp_tomb_enabled, 1, 0, 1 },
@@ -6748,8 +6750,6 @@ static const struct _battle_data {
void Hercules_report(char* date, char *time_c) {
int i, bd_size = ARRAYLENGTH(battle_data);
unsigned int config = 0;
- const char *svn = get_svn_revision();
- const char *git = get_git_hash();
char timestring[25];
time_t curtime;
char* buf;
@@ -6757,7 +6757,7 @@ void Hercules_report(char* date, char *time_c) {
enum config_table {
C_CIRCULAR_AREA = 0x0001,
C_CELLNOSTACK = 0x0002,
- C_CONSOLE_INPUT = 0x0004,
+ C_CONSOLE_INPUT = 0x0004,
C_SCRIPT_CALLFUNC_CHECK = 0x0008,
C_OFFICIAL_WALKPATH = 0x0010,
C_RENEWAL = 0x0020,
@@ -6768,12 +6768,15 @@ void Hercules_report(char* date, char *time_c) {
C_RENEWAL_EDP = 0x0400,
C_RENEWAL_ASPD = 0x0800,
C_SECURE_NPCTIMEOUT = 0x1000,
- C_SQL_DBS = 0x2000,
+ C_SQL_DB_ITEM = 0x2000,
C_SQL_LOGS = 0x4000,
- C_MEMWATCH = 0x8000,
- C_DMALLOC = 0x10000,
- C_GCOLLECT = 0x20000,
- C_SEND_SHORTLIST = 0x40000,
+ C_MEMWATCH = 0x8000,
+ C_DMALLOC = 0x10000,
+ C_GCOLLECT = 0x20000,
+ C_SEND_SHORTLIST = 0x40000,
+ C_SQL_DB_MOB = 0x80000,
+ C_SQL_DB_MOBSKILL = 0x100000,
+ C_PACKETVER_RE = 0x200000,
};
/* we get the current time */
@@ -6831,10 +6834,18 @@ void Hercules_report(char* date, char *time_c) {
#ifdef SECURE_NPCTIMEOUT
config |= C_SECURE_NPCTIMEOUT;
#endif
+
+#ifdef PACKETVER_RE
+ config |= C_PACKETVER_RE
+#endif
/* non-define part */
- if( map->db_use_sql_item_db || map->db_use_sql_mob_db || map->db_use_sql_mob_skill_db )
- config |= C_SQL_DBS; //TODO: split this config into three.
+ if( map->db_use_sql_item_db )
+ config |= C_SQL_DB_ITEM;
+ if( map->db_use_sql_mob_db )
+ config |= C_SQL_DB_MOB;
+ if( map->db_use_sql_mob_skill_db )
+ config |= C_SQL_DB_MOBSKILL;
if( logs->config.sql_logs )
config |= C_SQL_LOGS;
@@ -6855,30 +6866,40 @@ void Hercules_report(char* date, char *time_c) {
#define BFLAG_LENGTH 35
- CREATE(buf, char, 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 );
+ CREATE(buf, char, 262 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) + 1 );
/* build packet */
WBUFW(buf,0) = 0x3000;
- WBUFW(buf,2) = 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) );
- WBUFW(buf,4) = 0x9e;
+ WBUFW(buf,2) = 262 + ( bd_size * ( BFLAG_LENGTH + 4 ) );
+ WBUFW(buf,4) = 0x9f;
safestrncpy((char*)WBUFP(buf,6), date, 12);
- safestrncpy((char*)WBUFP(buf,6 + 12), time_c, 9);
- safestrncpy((char*)WBUFP(buf,6 + 12 + 9), timestring, 24);
-
- safestrncpy((char*)WBUFP(buf,6 + 12 + 9 + 24), git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown", 41);
- WBUFL(buf,6 + 12 + 9 + 24 + 41) = map->getusers();
-
- WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4) = config;
- WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4 + 4) = bd_size;
-
+ safestrncpy((char*)WBUFP(buf,18), time_c, 9);
+ safestrncpy((char*)WBUFP(buf,27), timestring, 24);
+
+ safestrncpy((char*)WBUFP(buf,51), sysinfo->platform(), 16);
+ safestrncpy((char*)WBUFP(buf,67), sysinfo->osversion(), 50);
+ safestrncpy((char*)WBUFP(buf,117), sysinfo->cpu(), 32);
+ WBUFL(buf,149) = sysinfo->cpucores();
+ safestrncpy((char*)WBUFP(buf,153), sysinfo->arch(), 8);
+ WBUFB(buf,161) = sysinfo->vcstypeid();
+ WBUFB(buf,162) = sysinfo->is64bit();
+ safestrncpy((char*)WBUFP(buf,163), sysinfo->vcsrevision_src(), 41);
+ safestrncpy((char*)WBUFP(buf,204), sysinfo->vcsrevision_scripts(), 41);
+ WBUFB(buf,245) = (sysinfo->is_superuser()? 1 : 0);
+ WBUFL(buf,246) = map->getusers();
+
+ WBUFL(buf,250) = config;
+ WBUFL(buf,254) = PACKETVER;
+
+ WBUFL(buf,258) = bd_size;
for( i = 0; i < bd_size; i++ ) {
- safestrncpy((char*)WBUFP(buf,6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, 35);
- WBUFL(buf,6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val;
+ safestrncpy((char*)WBUFP(buf,262 + ( i * ( BFLAG_LENGTH + 4 ) ) ), battle_data[i].str, BFLAG_LENGTH);
+ WBUFL(buf,262 + BFLAG_LENGTH + ( i * ( BFLAG_LENGTH + 4 ) ) ) = *battle_data[i].val;
}
- chrif->send_report(buf, 6 + 12 + 9 + 24 + 41 + 4 + 4 + 4 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) );
+ chrif->send_report(buf, 262 + ( bd_size * ( BFLAG_LENGTH + 4 ) ) );
aFree(buf);
diff --git a/src/map/battle.h b/src/map/battle.h
index b57476cb4..88038ddb4 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -437,6 +437,7 @@ struct Battle_Config {
// rAthena
int max_third_parameter;
int max_baby_third_parameter;
+ int max_extended_parameter;
int atcommand_max_stat_bypass;
int max_third_aspd;
int vcast_stat_scale;
diff --git a/src/map/chrif.c b/src/map/chrif.c
index 80ee50a20..99a1935fd 100644
--- a/src/map/chrif.c
+++ b/src/map/chrif.c
@@ -841,57 +841,18 @@ bool chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, u
* Request char server to change sex of char (modified by Yor)
*------------------------------------------*/
void chrif_changedsex(int fd) {
- int acc, sex;
- struct map_session_data *sd;
-
- acc = RFIFOL(fd,2);
- sex = RFIFOL(fd,6);
+ int acc = RFIFOL(fd,2);
+ //int sex = RFIFOL(fd,6); // Dead store. Uncomment if needed again.
if ( battle_config.etc_log )
ShowNotice("chrif_changedsex %d.\n", acc);
-
- sd = map->id2sd(acc);
- if ( sd ) { //Normally there should not be a char logged on right now!
- if ( sd->status.sex == sex )
- return; //Do nothing? Likely safe.
- sd->status.sex = !sd->status.sex;
-
- // reset skill of some job
- if ((sd->class_&MAPID_UPPERMASK) == MAPID_BARDDANCER) {
- int i, idx = 0;
- // remove specifical skills of Bard classes
- for(i = 315; i <= 322; i++) {
- idx = skill->get_index(i);
- if (sd->status.skill[idx].id > 0 && sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) {
- sd->status.skill_point += sd->status.skill[idx].lv;
- sd->status.skill[idx].id = 0;
- sd->status.skill[idx].lv = 0;
- }
- }
- // remove specifical skills of Dancer classes
- for(i = 323; i <= 330; i++) {
- idx = skill->get_index(i);
- if (sd->status.skill[idx].id > 0 && sd->status.skill[idx].flag == SKILL_FLAG_PERMANENT) {
- sd->status.skill_point += sd->status.skill[idx].lv;
- sd->status.skill[idx].id = 0;
- sd->status.skill[idx].lv = 0;
- }
- }
- clif->updatestatus(sd, SP_SKILLPOINT);
- // change job if necessary
- if (sd->status.sex) //Changed from Dancer
- sd->status.class_ -= 1;
- else //Changed from Bard
- sd->status.class_ += 1;
- //sd->class_ needs not be updated as both Dancer/Bard are the same.
- }
- // save character
- sd->login_id1++; // change identify, because if player come back in char within the 5 seconds, he can change its characters
- // do same modify in login-server for the account, but no in char-server (it ask again login_id1 to login, and don't remember it)
- clif->message(sd->fd, msg_txt(409)); //"Your sex has been changed (disconnection required to complete the process)..."
- set_eof(sd->fd); // forced to disconnect for the change
- map->quit(sd); // Remove leftovers (e.g. autotrading) [Paradox924X]
- }
+
+ // Path to activate this response:
+ // Map(start) (0x2b0e) -> Char(0x2727) -> Login
+ // Login(0x2723) [ALL] -> Char (0x2b0d)[ALL] -> Map (HERE)
+ // Char will usually be "logged in" despite being forced to log-out in the begining
+ // of this process, but there's no need to perform map-server specific response
+ // as everything should've been changed through char-server [Panikon]
}
/*==========================================
* Request Char Server to Divorce Players
diff --git a/src/map/clif.c b/src/map/clif.c
index 2dbe7cb96..d0fb08486 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -3204,6 +3204,12 @@ void clif_changelook(struct block_list *bl,int type,int val)
break;
case LOOK_BASE:
if( !sd ) break;
+ // We shouldn't update LOOK_BASE if the player is disguised
+ // if we do so the client will think that the player class
+ // is really a mob and issues like 7725 will happen in every
+ // SC_ that alters class_ in any way [Panikon]
+ if( sd->disguise != -1 )
+ return;
if( sd->sc.option&OPTION_COSTUME )
vd->weapon = vd->shield = 0;
@@ -8474,6 +8480,26 @@ void clif_refresh(struct map_session_data *sd)
pc->disguise(sd, disguise);
}
+ // Notify the client that the storage is open
+ if( sd->state.storage_flag == 1 ) {
+ storage->sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
+ clif->storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
+ clif->updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
+ }
+ // Notify the client that the gstorage is open otherwise it will
+ // remain locked forever and nobody will be able to access it
+ if( sd->state.storage_flag == 2 ) {
+ struct guild_storage *gstor;
+ if( (gstor = gstorage->id2storage2(sd->status.guild_id)) == NULL) {
+ // Shouldn't happen... The information should already be at the map-server
+ intif->request_guild_storage(sd->status.account_id,sd->status.guild_id);
+ } else {
+ storage->sortitem(gstor->items, ARRAYLENGTH(gstor->items));
+ clif->storagelist(sd, gstor->items, ARRAYLENGTH(gstor->items));
+ clif->updatestorageamount(sd, gstor->storage_amount, MAX_GUILD_STORAGE);
+ }
+ }
+
}
@@ -9231,6 +9257,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
#if PACKETVER >= 20090218
int i;
#endif
+ bool first_time = false;
if(sd->bl.prev != NULL)
return;
@@ -9391,6 +9418,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
if(sd->state.connect_new) {
int lv;
+ first_time = true;
sd->state.connect_new = 0;
clif->skillinfoblock(sd);
clif->hotkeys(sd);
@@ -9531,6 +9559,10 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd) {
clif->weather_check(sd);
+ // This should be displayed last
+ if( sd->guild && first_time )
+ clif->guild_notice(sd, sd->guild);
+
// For automatic triggering of NPCs after map loading (so you don't need to walk 1 step first)
if (map->getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNPC))
npc->touch_areanpc(sd,sd->bl.m,sd->bl.x,sd->bl.y);
@@ -10089,7 +10121,7 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
return;
}
- if( pc_cant_act(sd) || sd->sc.option&OPTION_HIDE )
+ if( pc_cant_act(sd) || pc_issit(sd) || sd->sc.option&OPTION_HIDE )
return;
if( sd->sc.option&OPTION_COSTUME )
@@ -11321,8 +11353,18 @@ void clif_parse_UseSkillToId(int fd, struct map_session_data *sd)
#endif
return;
}
- if( pc_cant_act(sd) && skill_id != RK_REFRESH && !(skill_id == SR_GENTLETOUCH_CURE && (sd->sc.opt1 == OPT1_STONE || sd->sc.opt1 == OPT1_FREEZE || sd->sc.opt1 == OPT1_STUN)) )
+
+ if( pc_cant_act(sd)
+ && skill_id != RK_REFRESH
+ && !(skill_id == SR_GENTLETOUCH_CURE && (sd->sc.opt1 == OPT1_STONE || sd->sc.opt1 == OPT1_FREEZE || sd->sc.opt1 == OPT1_STUN))
+ && ( sd->state.storage_flag && !(tmp&INF_SELF_SKILL) ) // SELF skills can be used with the storage open, issue: 8027
+ )
return;
+
+ // Some self skills need to close the storage to work properly
+ if( skill_id == AL_TELEPORT && sd->state.storage_flag )
+ storage->close(sd);
+
if( pc_issit(sd) )
return;
diff --git a/src/map/guild.c b/src/map/guild.c
index 15d13da0b..99c74c217 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -954,7 +954,6 @@ int guild_send_memberinfoshort(struct map_session_data *sd,int online)
if(sd->state.connect_new)
{ //Note that this works because it is invoked in parse_LoadEndAck before connect_new is cleared.
clif->guild_belonginfo(sd,g);
- clif->guild_notice(sd,g);
sd->guild_emblem_id = g->emblem_id;
}
return 0;
diff --git a/src/map/map.c b/src/map/map.c
index 9e41bdca3..04ac8a239 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -3765,10 +3765,9 @@ struct map_zone_data *map_merge_zone(struct map_zone_data *main, struct map_zone
CREATE(zone->capped_skills, struct map_zone_skill_damage_cap_entry *, zone->capped_skills_count);
-
for(i = 0, cursor = 0; i < main->capped_skills_count; i++, cursor++ ) {
CREATE(zone->capped_skills[cursor], struct map_zone_skill_damage_cap_entry, 1);
- memcpy(zone->capped_skills[cursor], main->disabled_commands[i], sizeof(struct map_zone_skill_damage_cap_entry));
+ memcpy(zone->capped_skills[cursor], main->capped_skills[i], sizeof(struct map_zone_skill_damage_cap_entry));
}
for(i = 0; i < other->capped_skills_count; i++, cursor++ ) {
@@ -5373,9 +5372,6 @@ void map_helpscreen(bool do_exit)
* Map-Server Version Screen [MC Cameri]
*------------------------------------------------------*/
void map_versionscreen(bool do_exit) {
- const char *svn = get_svn_revision();
- const char *git = get_git_hash();
- ShowInfo(CL_WHITE"Hercules version: %s" CL_RESET"\n", git[0] != HERC_UNKNOWN_VER ? git : svn[0] != HERC_UNKNOWN_VER ? svn : "Unknown");
ShowInfo(CL_GREEN"Website/Forum:"CL_RESET"\thttp://hercules.ws/\n");
ShowInfo(CL_GREEN"IRC Channel:"CL_RESET"\tirc://irc.rizon.net/#Hercules\n");
ShowInfo("Open "CL_WHITE"readme.txt"CL_RESET" for more information.\n");
@@ -5808,7 +5804,7 @@ int do_init(int argc, char *argv[])
if (load_extras) {
aFree(load_extras);
load_extras = NULL;
- load_extras_count = 0;
+ //load_extras_count = 0; // Dead store. Uncomment if needed again.
}
if( minimal ) {
diff --git a/src/map/map.h b/src/map/map.h
index c1eaeb40d..7373b516d 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -36,7 +36,7 @@ enum E_MAPSERVER_ST {
#define NATURAL_HEAL_INTERVAL 500
#define MIN_FLOORITEM 2
#define MAX_FLOORITEM START_ACCOUNT_NUM
-#define MAX_LEVEL 150
+#define MAX_LEVEL 175
#define MAX_IGNORE_LIST 20 // official is 14
#define MAX_VENDING 12
#define MAX_MAP_SIZE (512*512) // Wasn't there something like this already? Can't find it.. [Shinryo]
diff --git a/src/map/npc.c b/src/map/npc.c
index 3018cceeb..ae374e961 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -1146,13 +1146,24 @@ int npc_click(struct map_session_data* sd, struct npc_data* nd)
{
nullpo_retr(1, sd);
+ // This usually happens when the player clicked on a NPC that has the view id
+ // of a mob, to activate this kind of npc it's needed to be in a 2,2 range
+ // from it. If the OnTouch area of a npc, coincides with the 2,2 range of
+ // another it's expected that the OnTouch event be put first in stack, because
+ // unit_walktoxy_timer is executed before any other function in this case.
+ // So it's best practice to put an 'end;' before OnTouch events in npcs that
+ // have view ids of mobs to avoid this "issue" [Panikon]
if (sd->npc_id != 0) {
- ShowError("npc_click: npc_id != 0\n");
+ // The player clicked a npc after entering an OnTouch area
+ if( sd->areanpc_id != sd->npc_id )
+ ShowError("npc_click: npc_id != 0\n");
+
return 1;
}
- if(!nd) return 1;
-
+ if( !nd )
+ return 1;
+
if ((nd = npc->checknear(sd,&nd->bl)) == NULL)
return 1;
diff --git a/src/map/pc.c b/src/map/pc.c
index f5327e0bd..ba66bf7db 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -14,6 +14,7 @@
#include "../common/utils.h"
#include "../common/conf.h"
#include "../common/mmo.h" //NAME_LENGTH
+#include "../common/sysinfo.h"
#include "pc.h"
#include "atcommand.h" // get_atcommand_level()
@@ -1147,15 +1148,8 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim
if( !changing_mapservers ) {
if (battle_config.display_version == 1) {
- const char* svn = get_svn_revision();
- const char* git = get_git_hash();
char buf[256];
- if( git[0] != HERC_UNKNOWN_VER )
- sprintf(buf,"Git Hash: %s", git);
- else if( svn[0] != HERC_UNKNOWN_VER )
- sprintf(buf,"SVN Revision: %s", svn);
- else
- sprintf(buf,"Unknown Version");
+ sprintf(buf, msg_txt(1295), sysinfo->vcstype(), sysinfo->vcsrevision_src(), sysinfo->vcsrevision_scripts()); // %s revision '%s' (src) / '%s' (scripts)
clif->message(sd->fd, buf);
}
@@ -1758,6 +1752,13 @@ int pc_disguise(struct map_session_data *sd, int class_) {
status->set_viewdata(&sd->bl, class_);
clif->changeoption(&sd->bl);
+ // We need to update the client so it knows that a costume is being used
+ if( sd->sc.option&OPTION_COSTUME ) {
+ clif->changelook(&sd->bl,LOOK_BASE,sd->vd.class_);
+ clif->changelook(&sd->bl,LOOK_WEAPON,0);
+ clif->changelook(&sd->bl,LOOK_SHIELD,0);
+ clif->changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->vd.cloth_color);
+ }
if (sd->bl.prev != NULL) {
clif->spawn(&sd->bl);
@@ -6832,13 +6833,14 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
int i=0,j=0;
int64 tick = timer->gettick();
- for(j = 0; j < 5; j++)
+ for(j = 0; j < 5; j++) {
if (sd->devotion[j]){
struct map_session_data *devsd = map->id2sd(sd->devotion[j]);
if (devsd)
status_change_end(&devsd->bl, SC_DEVOTION, INVALID_TIMER);
sd->devotion[j] = 0;
}
+ }
if(sd->status.pet_id > 0 && sd->pd) {
struct pet_data *pd = sd->pd;
@@ -7136,6 +7138,17 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
}
}
}
+
+ // Remove autotrade to prevent autotrading from save point
+ if( (sd->state.standalone || sd->state.autotrade)
+ && (map->list[sd->bl.m].flag.pvp || map->list[sd->bl.m].flag.gvg)
+ ) {
+ sd->state.autotrade = 0;
+ sd->state.standalone = 0;
+ pc->autotrade_update(sd,PAUC_REMOVE);
+ map->quit(sd);
+ }
+
// pvp
// disable certain pvp functions on pk_mode [Valaris]
if( map->list[sd->bl.m].flag.pvp && !battle_config.pk_mode && !map->list[sd->bl.m].flag.pvp_nocalcrank ) {
@@ -7165,10 +7178,10 @@ int pc_dead(struct map_session_data *sd,struct block_list *src) {
}
}
-
//Reset "can log out" tick.
if( battle_config.prevent_logout )
sd->canlog_tick = timer->gettick() - battle_config.prevent_logout;
+
return 1;
}
diff --git a/src/map/pc.h b/src/map/pc.h
index 90448fa1d..70df9ca56 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -545,32 +545,6 @@ struct map_session_data {
};
-//Equip position constants
-enum equip_pos {
- EQP_HEAD_LOW = 0x000001,
- EQP_HEAD_MID = 0x000200, //512
- EQP_HEAD_TOP = 0x000100, //256
- EQP_HAND_R = 0x000002, //2
- EQP_HAND_L = 0x000020, //32
- EQP_ARMOR = 0x000010, //16
- EQP_SHOES = 0x000040, //64
- EQP_GARMENT = 0x000004, //4
- EQP_ACC_L = 0x000008, //8
- EQP_ACC_R = 0x000080, //128
- EQP_COSTUME_HEAD_TOP = 0x000400, //1024
- EQP_COSTUME_HEAD_MID = 0x000800, //2048
- EQP_COSTUME_HEAD_LOW = 0x001000, //4096
- EQP_COSTUME_GARMENT = 0x002000, //8192
- //UNUSED_COSTUME_FLOOR = 0x004000, //16384
- EQP_AMMO = 0x008000, //32768
- EQP_SHADOW_ARMOR = 0x010000, //65536
- EQP_SHADOW_WEAPON = 0x020000, //131072
- EQP_SHADOW_SHIELD = 0x040000, //262144
- EQP_SHADOW_SHOES = 0x080000, //524288
- EQP_SHADOW_ACC_R = 0x100000, //1048576
- EQP_SHADOW_ACC_L = 0x200000, //2097152
-};
-
#define EQP_WEAPON EQP_HAND_R
#define EQP_SHIELD EQP_HAND_L
#define EQP_ARMS (EQP_HAND_R|EQP_HAND_L)
@@ -615,7 +589,7 @@ enum equip_pos {
#define pc_isinvisible(sd) ( (sd)->sc.option&OPTION_INVISIBLE )
#define pc_is50overweight(sd) ( (sd)->weight*100 >= (sd)->max_weight*battle_config.natural_heal_weight_rate )
#define pc_is90overweight(sd) ( (sd)->weight*10 >= (sd)->max_weight*9 )
-#define pc_maxparameter(sd) ( ((((sd)->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO) || (((sd)->class_&MAPID_UPPERMASK) == MAPID_REBELLION) || (sd)->class_&JOBL_THIRD ? ((sd)->class_&JOBL_BABY ? battle_config.max_baby_third_parameter : battle_config.max_third_parameter) : ((sd)->class_&JOBL_BABY ? battle_config.max_baby_parameter : battle_config.max_parameter)) )
+#define pc_maxparameter(sd) ( (((sd)->class_&MAPID_UPPERMASK) == MAPID_KAGEROUOBORO || ((sd)->class_&MAPID_UPPERMASK) == MAPID_REBELLION || ((sd)->class_&MAPID_THIRDMASK) == MAPID_SUPER_NOVICE_E) ? battle_config.max_extended_parameter : (sd)->class_&JOBL_THIRD ? ((sd)->class_&JOBL_BABY ? battle_config.max_baby_third_parameter : battle_config.max_third_parameter) : ((sd)->class_&JOBL_BABY ? battle_config.max_baby_parameter : battle_config.max_parameter) )
/**
* Ranger
**/
diff --git a/src/map/script.c b/src/map/script.c
index 312e40696..8ac657f93 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -12,6 +12,7 @@
#include "../common/strlib.h"
#include "../common/timer.h"
#include "../common/utils.h"
+#include "../common/sysinfo.h"
#include "map.h"
#include "path.h"
@@ -4499,6 +4500,8 @@ int script_reload(void) {
itemdb->name_constants();
+ sysinfo->vcsrevision_reload();
+
return 0;
}
/* returns name of current function being run, from within the stack [Ind/Hercules] */
@@ -17315,19 +17318,6 @@ BUILDIN(is_function) {
return true;
}
/**
- * get_revision() -> retrieves the current svn revision (if available)
- **/
-BUILDIN(get_revision) {
- const char *svn = get_svn_revision();
-
- if ( svn[0] != HERC_UNKNOWN_VER )
- script_pushint(st,atoi(svn));
- else
- script_pushint(st,-1);//unknown
-
- return true;
-}
-/**
* freeloop(<toggle>) -> toggles this script instance's looping-check ability
**/
BUILDIN(freeloop) {
@@ -19152,7 +19142,6 @@ void script_parse_builtin(void) {
BUILDIN_DEF(getargcount,""),
BUILDIN_DEF(getcharip,"?"),
BUILDIN_DEF(is_function,"s"),
- BUILDIN_DEF(get_revision,""),
BUILDIN_DEF(freeloop,"i"),
BUILDIN_DEF(getrandgroupitem,"ii"),
BUILDIN_DEF(cleanmap,"s"),
diff --git a/src/map/trade.h b/src/map/trade.h
index f2c0d4622..143f26d74 100644
--- a/src/map/trade.h
+++ b/src/map/trade.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _MAP_TRADE_H_
-#define _MAP_TRADE_H_
+#ifndef _MAP_TRADE_H_
+#define _MAP_TRADE_H_
//Max distance from traders to enable a trade to take place.
//TODO: battle_config candidate?
diff --git a/src/map/vending.h b/src/map/vending.h
index b2ba22955..a212f8385 100644
--- a/src/map/vending.h
+++ b/src/map/vending.h
@@ -2,8 +2,8 @@
// See the LICENSE file
// Portions Copyright (c) Athena Dev Teams
-#ifndef _MAP_VENDING_H_
-#define _MAP_VENDING_H_
+#ifndef _MAP_VENDING_H_
+#define _MAP_VENDING_H_
#include "../common/cbasetypes.h"
#include "../common/db.h"
diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
index f0932f518..626040e7a 100644
--- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
@@ -2863,9 +2863,8 @@ int HP_bg_afk_timer(int tid, int64 tick, int id, intptr_t data) {
return retVal___;
}
enum bg_queue_types HP_bg_str2teamtype(const char *str) {
-/* Unknown return type 'enum bg_queue_types'. Initializing to '0'. */
int hIndex = 0;
- enum bg_queue_types retVal___ = 0;
+ enum bg_queue_types retVal___ = BGQT_INVALID;
if( HPMHooks.count.HP_bg_str2teamtype_pre ) {
enum bg_queue_types (*preHookFunc) (const char *str);
for(hIndex = 0; hIndex < HPMHooks.count.HP_bg_str2teamtype_pre; hIndex++ ) {
diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in
index 0f1698d2a..11e93973d 100644
--- a/src/plugins/Makefile.in
+++ b/src/plugins/Makefile.in
@@ -1,3 +1,6 @@
+# Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+# See the LICENSE file
+
################ PLUGIN CONFIGURATION ##############################
# #
# When you add a plugin, add its name here: #
@@ -50,7 +53,7 @@ $(ALLPLUGINS): %: ../../plugins/%@DLLEXT@
buildclean:
@echo " CLEAN plugins (build temp files)"
@rm -rf *.o
-
+
clean: buildclean
@echo " CLEAN plugins"
@rm -rf ../../plugins/*@DLLEXT@
diff --git a/src/test/Makefile.in b/src/test/Makefile.in
index c70997c63..2ee4e29b7 100644
--- a/src/test/Makefile.in
+++ b/src/test/Makefile.in
@@ -1,9 +1,12 @@
+# Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+# See the LICENSE file
CONFIG_D = ../config
CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h)
COMMON_D = ../common
COMMON_H = $(wildcard $(COMMON_D)/*.h)
+SYSINFO_INC = $(COMMON_D)/sysinfo.inc
LIBCONFIG_D = ../../3rdparty/libconfig
LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \
@@ -17,9 +20,10 @@ MT19937AR_OBJ = $(MT19937AR_D)/mt19937ar.o
MT19937AR_H = $(MT19937AR_D)/mt19937ar.h
MT19937AR_INCLUDE = -I$(MT19937AR_D)
-TEST_SPINLOCK_OBJ=obj/test_spinlock.o
-TEST_SPINLOCK_H=
-TEST_SPINLOCK_DEPENDS=$(TEST_SPINLOCK_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ)
+TEST_SPINLOCK_OBJ = obj/test_spinlock.o
+TEST_SPINLOCK_C = test_spinlock.c
+TEST_SPINLOCK_H =
+TEST_SPINLOCK_DEPENDS = $(TEST_SPINLOCK_OBJ) $(COMMON_D)/obj_sql/common_sql.a $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ $(SYSINFO_INC))
@SET_MAKE@
@@ -44,22 +48,25 @@ clean: buildclean
Makefile: Makefile.in
@$(MAKE) -C ../.. src/test/Makefile
+$(SYSINFO_INC): $(TEST_SPINLOCK_C) $(TEST_SPINLOCK_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H)
+ @echo " MAKE $@"
+ @$(MAKE) -C ../.. sysinfo
+
# object directories
obj:
@echo " MKDIR obj"
@-mkdir obj
-
+
#executables
test_spinlock: $(TEST_SPINLOCK_DEPENDS) Makefile
@echo " LD $@"
- @$(CC) @LDFLAGS@ -o ../../test_spinlock@EXEEXT@ $(TEST_SPINLOCK_OBJ) $(COMMON_D)/obj_sql/common_sql.a \
- $(COMMON_D)/obj_all/common.a $(MT19937AR_OBJ) $(LIBCONFIG_OBJ) @LIBS@ @MYSQL_LIBS@
+ @$(CC) @LDFLAGS@ -o ../../test_spinlock@EXEEXT@ $(TEST_SPINLOCK_DEPENDS) @LIBS@ @MYSQL_LIBS@
-# login object files
+# object files
-obj/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj
+obj/%.o: %.c $(TEST_SPINLOCK_H) $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj
@echo " CC $<"
@$(CC) @CFLAGS@ $(MT19937AR_INCLUDE) $(LIBCONFIG_INCLUDE) -DWITH_SQL @MYSQL_CFLAGS@ @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
@@ -67,7 +74,7 @@ obj/%.o: %.c $(COMMON_H) $(CONFIG_H) $(MT19937AR_H) $(LIBCONFIG_H) | obj
$(COMMON_D)/obj_all/common.a:
@echo " MAKE $@"
@$(MAKE) -C $(COMMON_D) sql
-
+
$(COMMON_D)/obj_sql/common_sql.a:
@echo " MAKE $@"
@$(MAKE) -C $(COMMON_D) sql
diff --git a/src/tool/Makefile.in b/src/tool/Makefile.in
index 3d0de1122..07b03e334 100644
--- a/src/tool/Makefile.in
+++ b/src/tool/Makefile.in
@@ -1,12 +1,12 @@
+# Copyright (c) Hercules Dev Team, licensed under GNU GPL.
+# See the LICENSE file
CONFIG_D = ../config
CONFIG_H = $(wildcard $(CONFIG_D)/*.h) $(wildcard $(CONFIG_D)/*/*.h)
COMMON_D = ../common
-COMMON_OBJ = $(addprefix $(COMMON_D)/obj_all/, des.o grfio.o malloc.o \
- nullpo.o miniconsole.o minicore.o showmsg.o strlib.o utils.o)
-COMMON_H = $(addprefix $(COMMON_D)/, cbasetypes.h console.h core.h des.h \
- grfio.h malloc.h mmo.h nullpo.h showmsg.h strlib.h utils.h)
+COMMON_H = $(wildcard $(COMMON_D)/*.h)
+SYSINFO_INC = $(COMMON_D)/sysinfo.inc
LIBCONFIG_D = ../../3rdparty/libconfig
LIBCONFIG_OBJ = $(addprefix $(LIBCONFIG_D)/, libconfig.o grammar.o scanctx.o \
@@ -16,6 +16,9 @@ LIBCONFIG_H = $(addprefix $(LIBCONFIG_D)/, libconfig.h grammar.h parsectx.h \
LIBCONFIG_INCLUDE = -I$(LIBCONFIG_D)
MAPCACHE_OBJ = obj_all/mapcache.o
+MAPCACHE_C = mapcache.c
+MAPCACHE_H =
+MAPCACHE_DEPENDS = $(MAPCACHE_OBJ) $(COMMON_D)/obj_all/common_mini.a $(LIBCONFIG_OBJ $(SYSINFO_INC))
@SET_MAKE@
@@ -29,9 +32,9 @@ all: mapcache Makefile
mapcache: ../../mapcache@EXEEXT@
-../../mapcache@EXEEXT@: $(MAPCACHE_OBJ) $(COMMON_OBJ) $(LIBCONFIG_OBJ) Makefile
+../../mapcache@EXEEXT@: $(MAPCACHE_DEPENDS) Makefile
@echo " LD $(notdir $@)"
- @$(CC) @LDFLAGS@ $(LIBCONFIG_INCLUDE) -o ../../mapcache@EXEEXT@ $(MAPCACHE_OBJ) $(COMMON_OBJ) $(LIBCONFIG_OBJ) @LIBS@
+ @$(CC) @LDFLAGS@ -o ../../mapcache@EXEEXT@ $(MAPCACHE_DEPENDS) @LIBS@
buildclean:
@echo " CLEAN tool (build temp files)"
@@ -55,22 +58,22 @@ help:
Makefile: Makefile.in
@$(MAKE) -C ../.. src/tool/Makefile
+$(SYSINFO_INC): $(MAPCACHE_C) $(MAPCACHE_H) $(COMMON_H) $(CONFIG_H) $(LIBCONFIG_H)
+ @echo " MAKE $@"
+ @$(MAKE) -C ../.. sysinfo
+
obj_all:
@echo " MKDIR obj_all"
@-mkdir obj_all
-obj_all/%.o: %.c $(COMMON_H) $(CONFIG_H) $(LIBCONFIG_H) | obj_all
+obj_all/%.o: %.c $(MAPCACHE_H) $(COMMON_H) $(CONFIG_H) $(LIBCONFIG_H) | obj_all
@echo " CC $<"
@$(CC) @CFLAGS@ $(LIBCONFIG_INCLUDE) @CPPFLAGS@ -c $(OUTPUT_OPTION) $<
# missing common object files
-$(COMMON_D)/obj_all/%.o:
- @echo " MAKE $@"
- @$(MAKE) -C $(COMMON_D) sql
-
-$(COMMON_D)/obj_all/mini%.o:
+$(COMMON_D)/obj_all/common_mini.a:
@echo " MAKE $@"
- @$(MAKE) -C $(COMMON_D) sql
+ @$(MAKE) -C $(COMMON_D) common_mini
$(LIBCONFIG_OBJ):
@echo " MAKE $@"