summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/char/char.c73
-rw-r--r--src/char_sql/char.c71
-rw-r--r--src/common/db.h77
-rw-r--r--src/common/strlib.c19
-rw-r--r--src/common/strlib.h9
-rw-r--r--src/map/script.c68
6 files changed, 209 insertions, 108 deletions
diff --git a/src/char/char.c b/src/char/char.c
index 8ef7eaddd..ac3c1a1b2 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -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);
}
diff --git a/src/char_sql/char.c b/src/char_sql/char.c
index 9929be3a7..7cf41eec9 100644
--- a/src/char_sql/char.c
+++ b/src/char_sql/char.c
@@ -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);
}
diff --git a/src/common/db.h b/src/common/db.h
index 992469f66..5c7d42d87 100644
--- a/src/common/db.h
+++ b/src/common/db.h
@@ -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_ */
diff --git a/src/common/strlib.c b/src/common/strlib.c
index 977dc8306..a683dc100 100644
--- a/src/common/strlib.c
+++ b/src/common/strlib.c
@@ -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;
+}
diff --git a/src/common/strlib.h b/src/common/strlib.h
index a3753b918..42fb75ab2 100644
--- a/src/common/strlib.h
+++ b/src/common/strlib.h
@@ -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_ */
diff --git a/src/map/script.c b/src/map/script.c
index e2395aab4..f97fbc869 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -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;