summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/atomic.h5
-rw-r--r--src/map/script.c116
-rw-r--r--src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking.HookingPoints.inc1
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Hooks.inc25
5 files changed, 113 insertions, 38 deletions
diff --git a/src/common/atomic.h b/src/common/atomic.h
index b1a4bda92..5a2ddb4f0 100644
--- a/src/common/atomic.h
+++ b/src/common/atomic.h
@@ -19,6 +19,9 @@
#if defined(_MSC_VER)
#include "../common/winapi.h"
+// This checks if C/C++ Compiler Version is 18.00
+#if _MSC_VER < 1800
+
#if !defined(_M_X64)
// When compiling for windows 32bit, the 8byte interlocked operations are not provided by microsoft
// (because they need at least i586 so its not generic enough.. ... )
@@ -80,6 +83,8 @@ forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 v
#endif //endif 32bit windows
+#endif //endif _msc_ver check
+
#elif defined(__GNUC__)
#if !defined(__x86_64__) && !defined(__i386__)
diff --git a/src/map/script.c b/src/map/script.c
index cf3c3fb50..53b5bbe16 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -858,50 +858,87 @@ const char* parse_variable(const char* p) {
return p;
}
+/*
+ * Checks whether the gives string is a number literal
+ *
+ * Mainly necessary to differentiate between number literals and NPC name
+ * constants, since several of those start with a digit.
+ *
+ * All this does is to check if the string begins with an optional + or - sign,
+ * followed by a hexadecimal or decimal number literal literal and is NOT
+ * followed by a underscore or letter.
+ *
+ * @param p Pointer to the string to check
+ * @return Whether the string is a number literal
+ */
+bool is_number(const char *p) {
+ const char *np;
+ if (!p)
+ return false;
+ if (*p == '-' || *p == '+')
+ p++;
+ np = p;
+ if (*p == '0' && p[1] == 'x') {
+ p+=2;
+ np = p;
+ // Hexadecimal
+ while (ISXDIGIT(*np))
+ np++;
+ } else {
+ // Decimal
+ while (ISDIGIT(*np))
+ np++;
+ }
+ if (p != np && *np != '_' && !ISALPHA(*np)) // At least one digit, and next isn't a letter or _
+ return true;
+ return false;
+}
+
/*==========================================
* Analysis section
*------------------------------------------*/
-const char* parse_simpleexpr(const char *p)
-{
- long long i;
+const char* parse_simpleexpr(const char *p) {
+ int i;
p=script->skip_space(p);
if(*p==';' || *p==',')
disp_error_message("parse_simpleexpr: unexpected end of expression",p);
- if(*p=='('){
+ if(*p=='(') {
if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST )
++script->syntax.curly[i].count;
p=script->parse_subexpr(p+1,-1);
p=script->skip_space(p);
- if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST &&
- script->syntax.curly[i].flag == ARGLIST_UNDEFINED && --script->syntax.curly[i].count == 0
- ){
- if( *p == ',' ){
+ if( (i=script->syntax.curly_count-1) >= 0 && script->syntax.curly[i].type == TYPE_ARGLIST
+ && script->syntax.curly[i].flag == ARGLIST_UNDEFINED && --script->syntax.curly[i].count == 0
+ ) {
+ if( *p == ',' ) {
script->syntax.curly[i].flag = ARGLIST_PAREN;
return p;
- } else
+ } else {
script->syntax.curly[i].flag = ARGLIST_NO_PAREN;
+ }
}
if( *p != ')' )
disp_error_message("parse_simpleexpr: unmatched ')'",p);
++p;
- } else if(ISDIGIT(*p) || ((*p=='-' || *p=='+') && ISDIGIT(p[1]))){
+ } else if(is_number(p)) {
char *np;
- while(*p == '0' && ISDIGIT(p[1])) p++;
- i=strtoll(p,&np,0);
- if( i < INT_MIN ) {
- i = INT_MIN;
+ long long lli;
+ while(*p == '0' && ISDIGIT(p[1])) p++; // Skip leading zeros, we don't support octal literals
+ lli=strtoll(p,&np,0);
+ if( lli < INT_MIN ) {
+ lli = INT_MIN;
script->disp_warning_message("parse_simpleexpr: underflow detected, capping value to INT_MIN",p);
- } else if( i > INT_MAX ) {
- i = INT_MAX;
+ } else if( lli > INT_MAX ) {
+ lli = INT_MAX;
script->disp_warning_message("parse_simpleexpr: overflow detected, capping value to INT_MAX",p);
}
- script->addi((int)i);
+ script->addi((int)lli); // Cast is safe, as it's already been checked for overflows
p=np;
- } else if(*p=='"'){
+ } else if(*p=='"') {
script->addc(C_STR);
p++;
- while( *p && *p != '"' ){
+ while( *p && *p != '"' ) {
if( (unsigned char)p[-1] <= 0x7e && *p == '\\' ) {
char buf[8];
size_t len = sv->skip_escaped_c(p) - p;
@@ -911,8 +948,9 @@ const char* parse_simpleexpr(const char *p)
p += len;
script->addb(*buf);
continue;
- } else if( *p == '\n' )
+ } else if( *p == '\n' ) {
disp_error_message("parse_simpleexpr: unexpected newline @ string",p);
+ }
script->addb(*p++);
}
if(!*p)
@@ -928,24 +966,24 @@ const char* parse_simpleexpr(const char *p)
disp_error_message("parse_simpleexpr: unexpected character",p);
l=script->add_word(p);
- if( script->str_data[l].type == C_FUNC || script->str_data[l].type == C_USERFUNC || script->str_data[l].type == C_USERFUNC_POS)
+ if( script->str_data[l].type == C_FUNC || script->str_data[l].type == C_USERFUNC || script->str_data[l].type == C_USERFUNC_POS) {
return script->parse_callfunc(p,1,0);
#ifdef SCRIPT_CALLFUNC_CHECK
- else {
+ } else {
const char* name = script->get_str(l);
if( strdb_get(script->userfunc_db,name) != NULL ) {
return script->parse_callfunc(p,1,1);
}
- }
#endif
+ }
- if( (pv = script->parse_variable(p)) )
- {// successfully processed a variable assignment
+ if( (pv = script->parse_variable(p)) ) {
+ // successfully processed a variable assignment
return pv;
}
p=script->skip_word(p);
- if( *p == '[' ){
+ if( *p == '[' ) {
// array(name[i] => getelementofarray(name,i) )
script->addl(script->buildin_getelementofarray_ref);
script->addc(C_ARG);
@@ -957,8 +995,9 @@ const char* parse_simpleexpr(const char *p)
disp_error_message("parse_simpleexpr: unmatched ']'",p);
++p;
script->addc(C_FUNC);
- }else
+ } else {
script->addl(l);
+ }
}
@@ -1229,8 +1268,16 @@ const char* parse_syntax(const char* p)
disp_error_message("parse_syntax: expect space ' '",p);
}
// check whether case label is integer or not
- v = strtol(p,&np,0);
- if(np == p) { //Check for constants
+ if(is_number(p)) {
+ //Numeric value
+ v = strtol(p,&np,0);
+ if((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word
+ p++;
+ p = script->skip_word(p);
+ if(np != p)
+ disp_error_message("parse_syntax: 'case' label is not an integer",np);
+ } else {
+ //Check for constants
p2 = script->skip_word(p);
v = p2-p; // length of word at p2
memcpy(label,p,v);
@@ -1238,12 +1285,6 @@ const char* parse_syntax(const char* p)
if( !script->get_constant(label, &v) )
disp_error_message("parse_syntax: 'case' label is not an integer",p);
p = script->skip_word(p);
- } else { //Numeric value
- if((*p == '-' || *p == '+') && ISDIGIT(p[1])) // pre-skip because '-' can not skip_word
- p++;
- p = script->skip_word(p);
- if(np != p)
- disp_error_message("parse_syntax: 'case' label is not an integer",np);
}
p = script->skip_space(p);
if(*p != ':')
@@ -1918,8 +1959,7 @@ void script_errorwarning_sub(StringBuf *buf, const char* src, const char* file,
int j;
int line = start_line;
const char *p, *error_linepos;
- const char *linestart[CONTEXTLINES];
- memset(linestart, '\0', sizeof(linestart));
+ const char *linestart[CONTEXTLINES] = { NULL };
for(p=src;p && *p;line++){
const char *lineend=strchr(p,'\n');
@@ -13043,7 +13083,7 @@ BUILDIN(equip)
ShowError("wrong item ID : equipitem(%i)\n",nameid);
return false;
}
- ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid );
+ ARR_FIND( 0, MAX_INVENTORY, i, sd->status.inventory[i].nameid == nameid && sd->status.inventory[i].equip == 0 );
if( i < MAX_INVENTORY )
pc->equipitem(sd,i,item_data->equip);
diff --git a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
index a4609ceed..cb9422a0b 100644
--- a/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc
@@ -1279,6 +1279,8 @@ struct {
struct HPMHookPoint *HP_clif_bank_deposit_post;
struct HPMHookPoint *HP_clif_bank_withdraw_pre;
struct HPMHookPoint *HP_clif_bank_withdraw_post;
+ struct HPMHookPoint *HP_clif_show_modifiers_pre;
+ struct HPMHookPoint *HP_clif_show_modifiers_post;
struct HPMHookPoint *HP_clif_pWantToConnection_pre;
struct HPMHookPoint *HP_clif_pWantToConnection_post;
struct HPMHookPoint *HP_clif_pLoadEndAck_pre;
@@ -6206,6 +6208,8 @@ struct {
int HP_clif_bank_deposit_post;
int HP_clif_bank_withdraw_pre;
int HP_clif_bank_withdraw_post;
+ int HP_clif_show_modifiers_pre;
+ int HP_clif_show_modifiers_post;
int HP_clif_pWantToConnection_pre;
int HP_clif_pWantToConnection_post;
int HP_clif_pLoadEndAck_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
index 7e357b142..0009b0b39 100644
--- a/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking.HookingPoints.inc
@@ -649,6 +649,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->chsys_gleave, HP_clif_chsys_gleave) },
{ HP_POP(clif->bank_deposit, HP_clif_bank_deposit) },
{ HP_POP(clif->bank_withdraw, HP_clif_bank_withdraw) },
+ { HP_POP(clif->show_modifiers, HP_clif_show_modifiers) },
{ HP_POP(clif->pWantToConnection, HP_clif_pWantToConnection) },
{ HP_POP(clif->pLoadEndAck, HP_clif_pLoadEndAck) },
{ HP_POP(clif->pTickSend, HP_clif_pTickSend) },
diff --git a/src/plugins/HPMHooking/HPMHooking.Hooks.inc b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
index 6ad4d4199..947b51186 100644
--- a/src/plugins/HPMHooking/HPMHooking.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Hooks.inc
@@ -16248,6 +16248,31 @@ void HP_clif_bank_withdraw(struct map_session_data *sd, enum e_BANKING_WITHDRAW_
}
return;
}
+void HP_clif_show_modifiers(struct map_session_data *sd) {
+ int hIndex = 0;
+ if( HPMHooks.count.HP_clif_show_modifiers_pre ) {
+ void (*preHookFunc) (struct map_session_data *sd);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_show_modifiers_pre; hIndex++ ) {
+ preHookFunc = HPMHooks.list.HP_clif_show_modifiers_pre[hIndex].func;
+ preHookFunc(sd);
+ }
+ if( *HPMforce_return ) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.show_modifiers(sd);
+ }
+ if( HPMHooks.count.HP_clif_show_modifiers_post ) {
+ void (*postHookFunc) (struct map_session_data *sd);
+ for(hIndex = 0; hIndex < HPMHooks.count.HP_clif_show_modifiers_post; hIndex++ ) {
+ postHookFunc = HPMHooks.list.HP_clif_show_modifiers_post[hIndex].func;
+ postHookFunc(sd);
+ }
+ }
+ return;
+}
void HP_clif_pWantToConnection(int fd, struct map_session_data *sd) {
int hIndex = 0;
if( HPMHooks.count.HP_clif_pWantToConnection_pre ) {