* Displaying op names instead of numbers in script engine errors.
* Fixed a bug introduced in the last rework of the fame ranking. * Created safestrncpy that ensures the string is nul-terminated. git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@10667 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
51e85c5a80
commit
f68f40f94d
@ -3,6 +3,10 @@ Date Added
|
||||
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK.
|
||||
IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
|
||||
|
||||
2007/06/02
|
||||
* Displaying op names instead of numbers in script engine errors.
|
||||
* Fixed a bug introduced in the last rework of the fame ranking.
|
||||
* Created safestrncpy that ensures the string is nul-terminated. [FlavioJS]
|
||||
2007/06/01
|
||||
* Updated sql files [Playtester]
|
||||
* Fixed ircbot not processing new users
|
||||
|
@ -3123,7 +3123,9 @@ int parse_frommap(int fd)
|
||||
char type = RFIFOB(fd, 10);
|
||||
int size;
|
||||
struct fame_list* list;
|
||||
|
||||
int player_pos;
|
||||
int fame_pos;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 1: size = fame_list_size_smith; list = smith_fame_list; break;
|
||||
@ -3131,56 +3133,33 @@ int parse_frommap(int fd)
|
||||
case 3: size = fame_list_size_taekwon; list = taekwon_fame_list; break;
|
||||
default: size = 0; list = NULL; break;
|
||||
}
|
||||
if( size == 0 )
|
||||
{// No list
|
||||
RFIFOSKIP(fd,11);
|
||||
break;
|
||||
|
||||
ARR_FIND(0, size, player_pos, list[player_pos].id == cid);
|
||||
ARR_FIND(0, size, fame_pos, list[fame_pos].fame <= fame);
|
||||
|
||||
if( player_pos == size && fame_pos == size )
|
||||
;// not on list and not enough fame to get on it
|
||||
else if( fame_pos == player_pos )
|
||||
{// same position
|
||||
list[player_pos].fame = fame;
|
||||
char_update_fame_list(type, player_pos, fame);
|
||||
}
|
||||
for( i = 0; i < size; ++i )
|
||||
{
|
||||
if( list[i].id != cid )
|
||||
continue;
|
||||
// player found, update position
|
||||
if( i > 0 && fame >= list[i - 1].fame )
|
||||
{// moved up
|
||||
struct fame_list entry;
|
||||
int t;
|
||||
for( t = 0; fame < list[t].fame ; ++t )
|
||||
;// get target position (always < i)
|
||||
memcpy(&entry, &list[i], sizeof(struct fame_list));
|
||||
entry.fame = fame;
|
||||
memmove(&list[t + 1], &list[t], (t - i)*sizeof(struct fame_list));
|
||||
memcpy(&list[t], &entry, sizeof(struct fame_list));
|
||||
char_send_fame_list(-1);
|
||||
}
|
||||
else if( i < size - 1 && fame < list[i + 1].fame )
|
||||
{// moved down - always stays in the list
|
||||
struct fame_list entry;
|
||||
int t;
|
||||
for( t = i + 2; t < size && fame < list[t].fame ; ++t )
|
||||
;// get target position
|
||||
--t;
|
||||
memcpy(&entry, &list[i], sizeof(struct fame_list));
|
||||
entry.fame = fame;
|
||||
memmove(&list[i], &list[i + 1], (t - i)*sizeof(struct fame_list));
|
||||
memcpy(&list[t], &entry, sizeof(struct fame_list));
|
||||
char_send_fame_list(-1);
|
||||
else
|
||||
{// move in the list
|
||||
if( player_pos == size )
|
||||
{// new ranker - not in the list
|
||||
ARR_MOVE(size - 1, fame_pos, list, struct fame_list);
|
||||
list[fame_pos].id = cid;
|
||||
list[fame_pos].fame = fame;
|
||||
char_loadName(cid, list[fame_pos].name);
|
||||
}
|
||||
else
|
||||
{// same position
|
||||
list[i].fame = fame;
|
||||
char_update_fame_list(type, i, fame);
|
||||
{// already in the list
|
||||
if( fame_pos == size )
|
||||
--fame_pos;// move to the end of the list
|
||||
ARR_MOVE(player_pos, fame_pos, list, struct fame_list);
|
||||
list[fame_pos].fame = fame;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == size && fame >= list[size - 1].fame )
|
||||
{// not on list and has enough fame
|
||||
for( i = 0; fame < list[i].fame; ++i )
|
||||
;// get target position
|
||||
list[i].id = cid;
|
||||
list[i].fame = fame;
|
||||
char_loadName(list[i].id, list[i].name);
|
||||
char_send_fame_list(-1);
|
||||
}
|
||||
|
||||
|
@ -2822,6 +2822,8 @@ int parse_frommap(int fd)
|
||||
char type = RFIFOB(fd, 10);
|
||||
int size;
|
||||
struct fame_list* list;
|
||||
int player_pos;
|
||||
int fame_pos;
|
||||
|
||||
switch(type)
|
||||
{
|
||||
@ -2830,56 +2832,33 @@ int parse_frommap(int fd)
|
||||
case 3: size = fame_list_size_taekwon; list = taekwon_fame_list; break;
|
||||
default: size = 0; list = NULL; break;
|
||||
}
|
||||
if( size == 0 )
|
||||
{// No list
|
||||
RFIFOSKIP(fd,11);
|
||||
break;
|
||||
|
||||
ARR_FIND(0, size, player_pos, list[player_pos].id == cid);
|
||||
ARR_FIND(0, size, fame_pos, list[fame_pos].fame <= fame);
|
||||
|
||||
if( player_pos == size && fame_pos == size )
|
||||
;// not on list and not enough fame to get on it
|
||||
else if( fame_pos == player_pos )
|
||||
{// same position
|
||||
list[player_pos].fame = fame;
|
||||
char_update_fame_list(type, player_pos, fame);
|
||||
}
|
||||
for( i = 0; i < size; ++i )
|
||||
{
|
||||
if( list[i].id != cid )
|
||||
continue;
|
||||
// player found, update position
|
||||
if( i > 0 && fame >= list[i - 1].fame )
|
||||
{// moved up
|
||||
struct fame_list entry;
|
||||
int t;
|
||||
for( t = 0; fame < list[t].fame ; ++t )
|
||||
;// get target position (always < i)
|
||||
memcpy(&entry, &list[i], sizeof(struct fame_list));
|
||||
entry.fame = fame;
|
||||
memmove(&list[t + 1], &list[t], (t - i)*sizeof(struct fame_list));
|
||||
memcpy(&list[t], &entry, sizeof(struct fame_list));
|
||||
char_send_fame_list(-1);
|
||||
}
|
||||
else if( i < size - 1 && fame < list[i + 1].fame )
|
||||
{// moved down - always stays in the list
|
||||
struct fame_list entry;
|
||||
int t;
|
||||
for( t = i + 2; t < size && fame < list[t].fame ; ++t )
|
||||
;// get target position
|
||||
--t;
|
||||
memcpy(&entry, &list[i], sizeof(struct fame_list));
|
||||
entry.fame = fame;
|
||||
memmove(&list[i], &list[i + 1], (t - i)*sizeof(struct fame_list));
|
||||
memcpy(&list[t], &entry, sizeof(struct fame_list));
|
||||
char_send_fame_list(-1);
|
||||
else
|
||||
{// move in the list
|
||||
if( player_pos == size )
|
||||
{// new ranker - not in the list
|
||||
ARR_MOVE(size - 1, fame_pos, list, struct fame_list);
|
||||
list[fame_pos].id = cid;
|
||||
list[fame_pos].fame = fame;
|
||||
char_loadName(cid, list[fame_pos].name);
|
||||
}
|
||||
else
|
||||
{// same position
|
||||
list[i].fame = fame;
|
||||
char_update_fame_list(type, i, fame);
|
||||
{// already in the list
|
||||
if( fame_pos == size )
|
||||
--fame_pos;// move to the end of the list
|
||||
ARR_MOVE(player_pos, fame_pos, list, struct fame_list);
|
||||
list[fame_pos].fame = fame;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( i == size && fame >= list[size - 1].fame )
|
||||
{// not on list and has enough fame
|
||||
for( i = 0; fame < list[i].fame; ++i )
|
||||
;// get target position
|
||||
list[i].id = cid;
|
||||
list[i].fame = fame;
|
||||
char_loadName(list[i].id, list[i].name);
|
||||
char_send_fame_list(-1);
|
||||
}
|
||||
|
||||
|
@ -691,4 +691,81 @@ void* linkdb_search ( struct linkdb_node** head, void *key);
|
||||
void* linkdb_erase ( struct linkdb_node** head, void *key);
|
||||
void linkdb_final ( struct linkdb_node** head );
|
||||
|
||||
|
||||
|
||||
/// Finds an entry in an array.
|
||||
/// ex: ARR_FIND(0, size, i, list[i] == target);
|
||||
///
|
||||
/// @param __start Starting index (ex: 0)
|
||||
/// @param __end End index (ex: size of the array)
|
||||
/// @param __var Index variable
|
||||
/// @param __cmp Expression that returns true when the target entry is found
|
||||
#define ARR_FIND(__start, __end, __var, __cmp) \
|
||||
do{ \
|
||||
for( (__var) = (__start); (__var) < (__end); ++(__var) ) \
|
||||
if( __cmp ) \
|
||||
break; \
|
||||
}while(0)
|
||||
|
||||
|
||||
|
||||
/// Moves an entry of the array.
|
||||
/// Use ARR_MOVERIGHT/ARR_MOVELEFT if __from and __to are direct numbers.
|
||||
/// ex: ARR_MOVE(i, 0, list, int);// move index i to index 0
|
||||
///
|
||||
///
|
||||
/// @param __from Initial index of the entry
|
||||
/// @param __end Target index of the entry
|
||||
/// @param __arr Array
|
||||
/// @param __type Type of entry
|
||||
#define ARR_MOVE(__from, __to, __arr, __type) \
|
||||
do{ \
|
||||
if( (__from) != (__to) ) \
|
||||
{ \
|
||||
__type __backup__; \
|
||||
memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
|
||||
if( (__from) < (__to) ) \
|
||||
memmove((__arr)+(__from), (__arr)+(__from)+1, ((__to)-(__from))*sizeof(__type)); \
|
||||
else if( (__from) > (__to) ) \
|
||||
memmove((__arr)+(__to)+1, (__arr)+(__to), ((__from)-(__to))*sizeof(__type)); \
|
||||
memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
|
||||
} \
|
||||
}while(0)
|
||||
|
||||
|
||||
|
||||
/// Moves an entry of the array to the right.
|
||||
/// ex: ARR_MOVERIGHT(1, 4, list, int);// move index 1 to index 4
|
||||
///
|
||||
/// @param __from Initial index of the entry
|
||||
/// @param __end Target index of the entry
|
||||
/// @param __arr Array
|
||||
/// @param __type Type of entry
|
||||
#define ARR_MOVERIGHT(__from, __to, __arr, __type) \
|
||||
do{ \
|
||||
__type __backup__; \
|
||||
memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
|
||||
memmove((__arr)+(__from), (__arr)+(__from)+1, ((__to)-(__from))*sizeof(__type)); \
|
||||
memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
|
||||
}while(0)
|
||||
|
||||
|
||||
|
||||
/// Moves an entry of the array to the left.
|
||||
/// ex: ARR_MOVELEFT(3, 0, list, int);// move index 3 to index 0
|
||||
///
|
||||
/// @param __from Initial index of the entry
|
||||
/// @param __end Target index of the entry
|
||||
/// @param __arr Array
|
||||
/// @param __type Type of entry
|
||||
#define ARR_MOVELEFT(__from, __to, __arr, __type) \
|
||||
do{ \
|
||||
__type __backup__; \
|
||||
memmove(&__backup__, (__arr)+(__from), sizeof(__type)); \
|
||||
memmove((__arr)+(__to)+1, (__arr)+(__to), ((__from)-(__to))*sizeof(__type)); \
|
||||
memmove((__arr)+(__to), &__backup__, sizeof(__type)); \
|
||||
}while(0)
|
||||
|
||||
|
||||
|
||||
#endif /* _DB_H_ */
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#include "../common/cbasetypes.h"
|
||||
#include "../common/malloc.h"
|
||||
#include "../common/utils.h"
|
||||
#include "strlib.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "strlib.h"
|
||||
#include "../common/cbasetypes.h"
|
||||
#include "../common/utils.h"
|
||||
#include "../common/malloc.h"
|
||||
|
||||
|
||||
#define J_MAX_MALLOC_SIZE 65535
|
||||
@ -299,3 +300,13 @@ int config_switch(const char* str)
|
||||
|
||||
return (int)strtol(str, NULL, 0);
|
||||
}
|
||||
|
||||
/// always nul-terminates the string
|
||||
char* safestrncpy(char* dst, const char* src, size_t n)
|
||||
{
|
||||
char* ret;
|
||||
ret = strncpy(dst, src, n);
|
||||
if( ret != NULL )
|
||||
ret[n - 1] = '\0';
|
||||
return ret;
|
||||
}
|
||||
|
@ -4,7 +4,9 @@
|
||||
#ifndef _STRLIB_H_
|
||||
#define _STRLIB_H_
|
||||
|
||||
#include <stddef.h> // size_t
|
||||
#ifndef _CBASETYPES_H_
|
||||
#include "../common/cbasetypes.h"
|
||||
#endif
|
||||
|
||||
char* jstrescape (char* pt);
|
||||
char* jstrescapecpy (char* pt, const char* spt);
|
||||
@ -15,7 +17,7 @@ char* trim(char* str);
|
||||
char* normalize_name(char* str,const char* delims);
|
||||
const char *stristr(const char *haystack, const char *needle);
|
||||
|
||||
#ifdef __WIN32
|
||||
#ifdef WIN32
|
||||
#define HAVE_STRTOK_R
|
||||
#define strtok_r(s,delim,save_ptr) _strtok_r((s),(delim),(save_ptr))
|
||||
char* _strtok_r(char* s1, const char* s2, char** lasts);
|
||||
@ -28,4 +30,7 @@ size_t strnlen (const char* string, size_t maxlen);
|
||||
int e_mail_check(char* email);
|
||||
int config_switch(const char* str);
|
||||
|
||||
/// always nul-terminates the string
|
||||
char* safestrncpy(char* dst, const char* src, size_t n);
|
||||
|
||||
#endif /* _STRLIB_H_ */
|
||||
|
@ -314,6 +314,56 @@ enum {
|
||||
MF_GUILDLOCK
|
||||
};
|
||||
|
||||
const char* script_op2name(int op)
|
||||
{
|
||||
#define RETURN_OP_NAME(type) case type: return #type
|
||||
switch( op )
|
||||
{
|
||||
RETURN_OP_NAME(C_NOP);
|
||||
RETURN_OP_NAME(C_POS);
|
||||
RETURN_OP_NAME(C_INT);
|
||||
RETURN_OP_NAME(C_PARAM);
|
||||
RETURN_OP_NAME(C_FUNC);
|
||||
RETURN_OP_NAME(C_STR);
|
||||
RETURN_OP_NAME(C_CONSTSTR);
|
||||
RETURN_OP_NAME(C_ARG);
|
||||
RETURN_OP_NAME(C_NAME);
|
||||
RETURN_OP_NAME(C_EOL);
|
||||
RETURN_OP_NAME(C_RETINFO);
|
||||
RETURN_OP_NAME(C_USERFUNC);
|
||||
RETURN_OP_NAME(C_USERFUNC_POS);
|
||||
|
||||
// operators
|
||||
RETURN_OP_NAME(C_OP3);
|
||||
RETURN_OP_NAME(C_LOR);
|
||||
RETURN_OP_NAME(C_LAND);
|
||||
RETURN_OP_NAME(C_LE);
|
||||
RETURN_OP_NAME(C_LT);
|
||||
RETURN_OP_NAME(C_GE);
|
||||
RETURN_OP_NAME(C_GT);
|
||||
RETURN_OP_NAME(C_EQ);
|
||||
RETURN_OP_NAME(C_NE);
|
||||
RETURN_OP_NAME(C_XOR);
|
||||
RETURN_OP_NAME(C_OR);
|
||||
RETURN_OP_NAME(C_AND);
|
||||
RETURN_OP_NAME(C_ADD);
|
||||
RETURN_OP_NAME(C_SUB);
|
||||
RETURN_OP_NAME(C_MUL);
|
||||
RETURN_OP_NAME(C_DIV);
|
||||
RETURN_OP_NAME(C_MOD);
|
||||
RETURN_OP_NAME(C_NEG);
|
||||
RETURN_OP_NAME(C_LNOT);
|
||||
RETURN_OP_NAME(C_NOT);
|
||||
RETURN_OP_NAME(C_R_SHIFT);
|
||||
RETURN_OP_NAME(C_L_SHIFT);
|
||||
|
||||
default:
|
||||
ShowDebug("script_op2name: unexpected op=%d\n", op);
|
||||
return "???";
|
||||
}
|
||||
#undef RETURN_OP_NAME
|
||||
}
|
||||
|
||||
//Reports on the console the src of a script error.
|
||||
static void report_src(struct script_state *st)
|
||||
{
|
||||
@ -2392,7 +2442,7 @@ void op_3(struct script_state* st, int op)
|
||||
flag = data->u.num;
|
||||
else
|
||||
{
|
||||
ShowError("script:op_3: invalid type of data op:%d data:%d\n", op, data->type);
|
||||
ShowError("script:op_3: invalid type of data op:%s data:%s\n", script_op2name(op), script_op2name(data->type));
|
||||
report_src(st);
|
||||
script_removetop(st, -3, 0);
|
||||
script_pushnil(st);
|
||||
@ -2433,7 +2483,7 @@ void op_2str(struct script_state* st, int op, const char* s1, const char* s2)
|
||||
return;
|
||||
}
|
||||
default:
|
||||
ShowError("script:op2_str: unexpected string operator op:%d\n", op);
|
||||
ShowError("script:op2_str: unexpected string operator op:%s\n", script_op2name(op));
|
||||
report_src(st);
|
||||
script_pushnil(st);
|
||||
st->state = END;
|
||||
@ -2469,7 +2519,7 @@ void op_2num(struct script_state* st, int op, int i1, int i2)
|
||||
case C_MOD:
|
||||
if( i2 == 0 )
|
||||
{
|
||||
ShowError("script:op_2num: division by zero detected op:%d\n", op);
|
||||
ShowError("script:op_2num: division by zero detected op:%s\n", script_op2name(op));
|
||||
report_src(st);
|
||||
script_pushnil(st);
|
||||
st->state = END;
|
||||
@ -2487,20 +2537,20 @@ void op_2num(struct script_state* st, int op, int i1, int i2)
|
||||
case C_SUB: ret = i1 - i2; ret_double = (double)i1 - (double)i2; break;
|
||||
case C_MUL: ret = i1 * i2; ret_double = (double)i1 * (double)i2; break;
|
||||
default:
|
||||
ShowError("script:op_2num: unexpected number operator op:%d\n", op);
|
||||
ShowError("script:op_2num: unexpected number operator op:%s\n", script_op2name(op));
|
||||
report_src(st);
|
||||
script_pushnil(st);
|
||||
return;
|
||||
}
|
||||
if( ret_double < INT_MIN )
|
||||
{
|
||||
ShowWarning("script:op_2num: underflow detected op:%d\n", op);
|
||||
ShowWarning("script:op_2num: underflow detected op:%s\n", script_op2name(op));
|
||||
report_src(st);
|
||||
ret = INT_MIN;
|
||||
}
|
||||
else if( ret_double > INT_MAX )
|
||||
{
|
||||
ShowWarning("script:op_2num: overflow detected op:%d\n", op);
|
||||
ShowWarning("script:op_2num: overflow detected op:%s\n", script_op2name(op));
|
||||
report_src(st);
|
||||
ret = INT_MAX;
|
||||
}
|
||||
@ -2546,7 +2596,7 @@ void op_2(struct script_state *st, int op)
|
||||
}
|
||||
else
|
||||
{// invalid argument
|
||||
ShowError("script:op_2: invalid type of data op:%d left:%d right:%d\n", op, left->type, right->type);
|
||||
ShowError("script:op_2: invalid type of data op:%s left:%s right:%s\n", script_op2name(op), script_op2name(left->type), script_op2name(right->type));
|
||||
report_src(st);
|
||||
script_removetop(st, -2, 0);
|
||||
script_pushnil(st);
|
||||
@ -2568,7 +2618,7 @@ void op_1(struct script_state* st, int op)
|
||||
|
||||
if( !data_isint(data) )
|
||||
{// not a number
|
||||
ShowError("script:op_1: invalid type of data op:%d data:%d\n", op, data->type);
|
||||
ShowError("script:op_1: invalid type of data op:%s data:%s\n", script_op2name(op), script_op2name(data->type));
|
||||
report_src(st);
|
||||
script_pushnil(st);
|
||||
st->state = END;
|
||||
@ -2583,7 +2633,7 @@ void op_1(struct script_state* st, int op)
|
||||
case C_NOT: i1 = ~i1; break;
|
||||
case C_LNOT: i1 = !i1; break;
|
||||
default:
|
||||
ShowError("script:op_1: unexpected operator op:%d\n", op);
|
||||
ShowError("script:op_1: unexpected operator op:%s\n", script_op2name(op));
|
||||
report_src(st);
|
||||
script_pushnil(st);
|
||||
st->state = END;
|
||||
|
Loading…
x
Reference in New Issue
Block a user