* 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:
FlavioJS 2007-06-02 20:19:40 +00:00
parent 51e85c5a80
commit f68f40f94d
7 changed files with 213 additions and 108 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;