diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/atomic.h | 5 | ||||
-rw-r--r-- | src/map/script.c | 116 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking.HPMHooksCore.inc | 4 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking.HookingPoints.inc | 1 | ||||
-rw-r--r-- | src/plugins/HPMHooking/HPMHooking.Hooks.inc | 25 |
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 ) { |