summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/socket.c2
-rw-r--r--src/map/log.c8
-rw-r--r--src/map/log.h17
-rw-r--r--src/map/script.c182
4 files changed, 139 insertions, 70 deletions
diff --git a/src/common/socket.c b/src/common/socket.c
index f8e65fb60..4e25abbb1 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -571,7 +571,7 @@ int WFIFOSET(int fd,int len)
if(s->wdata_size+len > s->max_wdata)
{ // actually there was a buffer overflow already
unsigned char *sin_addr = (unsigned char *)&s->client_addr.sin_addr;
- ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d byteson a %d/%d bytes buffer.\n", fd,
+ ShowFatalError("socket: Buffer Overflow. Connection %d (%d.%d.%d.%d) has written %d bytes on a %d/%d bytes buffer.\n", fd,
sin_addr[0], sin_addr[1], sin_addr[2], sin_addr[3], len, s->wdata_size, s->max_wdata);
ShowDebug("Likely command that caused it: 0x%x\n",
(*(unsigned short*)(s->wdata+s->wdata_size)));
diff --git a/src/map/log.c b/src/map/log.c
index 209b81d32..ff1487d0c 100644
--- a/src/map/log.c
+++ b/src/map/log.c
@@ -15,13 +15,9 @@
#include "log.h"
#ifndef SQL_DEBUG
-
-#define mysql_query(_x, _y) mysql_real_query(_x, _y, strlen(_y)) //supports ' in names and runs faster [Kevin]
-
+ #define mysql_query(_x, _y) mysql_real_query(_x, _y, strlen(_y)) //supports ' in names and runs faster [Kevin]
#else
-
-#define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
-
+ #define mysql_query(_x, _y) debug_mysql_query(__FILE__, __LINE__, _x, _y)
#endif
struct Log_Config log_config;
diff --git a/src/map/log.h b/src/map/log.h
index 1cc2247db..c9d88cc37 100644
--- a/src/map/log.h
+++ b/src/map/log.h
@@ -29,8 +29,23 @@ int log_config_read(char *cfgName);
int should_log_item(int filter, int nameid, int amount); //log filter check
+enum log_what {
+ LOG_ALL = 0xFFF,
+ LOG_TRADES = 0x002,
+ LOG_VENDING = 0x004,
+ LOG_PLAYER_ITEMS = 0x008, // dropped/picked
+ LOG_MONTER_ITEMS = 0x010, // dropped/looted
+ LOG_NPC_TRANSACTIONS = 0x020, // npc shops?
+ LOG_SCRIPT_TRANSACTIONS = 0x040,
+ LOG_STOLEN_ITEMS = 0x080, // stolen from mobs
+ LOG_USED_ITEMS = 0x100, // used by player
+ LOG_MVP_PRIZE = 0x200,
+ LOG_COMMAND_ITEMS = 0x400 // created/deleted through @/# commands
+};
+
extern struct Log_Config {
- int enable_logs, filter;
+ enum log_what enable_logs;
+ int filter;
int sql_logs;
int rare_items_log,refine_items_log,price_items_log,amount_items_log; //for filter
int branch, drop, mvpdrop, zeny, gm, npc, chat;
diff --git a/src/map/script.c b/src/map/script.c
index 8d338c6a4..0e1f03f16 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -53,9 +53,18 @@
#include "irc.h"
#include "pet.h"
+
+///////////////////////////////////////////////////////////////////////////////
+/// Returns the stack_data at the target index
+#define script_getdata(st,i) &((st)->stack->stack_data[(st)->start+(i)])
+/// Returns if the stack contains data at the target index
+#define script_hasdata(st,i) ( (st)->end > (st)->start + (i) )
+#define script_isstring(data) ( (data)->type == C_STR || (data)->type == C_CONSTSTR )
+#define script_isint(data) ( (data)->type == C_INT )
+
#define FETCH(n, t) \
- if(st->end>st->start+(n)) \
- (t)=conv_num(st,&(st->stack->stack_data[st->start+(n)]));
+ if( script_hasdata(st,n) ) \
+ (t)=conv_num(st,script_getdata(st,n));
#define SCRIPT_BLOCK_SIZE 512
enum { LABEL_NEXTLINE=1,LABEL_START };
@@ -158,8 +167,8 @@ int get_num(unsigned char *script,int *pos);
extern struct script_function {
int (*func)(struct script_state *st);
- char *name;
- char *arg;
+ const char *name;
+ const char *arg;
} buildin_func[];
static struct linkdb_node *sleep_db;
@@ -270,12 +279,13 @@ static void disp_error_message2(const char *mes,const char *pos,int report)
}
#define disp_error_message(mes,pos) disp_error_message2(mes,pos,1)
-static void check_event(struct script_state *st, const char *event){
- if(event != NULL && event[0] != '\0' && !stristr(event,"::On")){
- ShowError("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n",event);
+/// Checks event parameter validity
+static void check_event(struct script_state *st, const char *evt)
+{
+ if( evt != NULL && *evt != '\0' && !stristr(evt,"::On") ){
+ ShowError("NPC event parameter deprecated! Please use 'NPCNAME::OnEVENT' instead of '%s'.\n",evt);
report_src(st);
}
- return;
}
/*==========================================
@@ -657,7 +667,7 @@ static const char* parse_callfunc(const char *p, int require_paren)
}
--syntax.curly_count;
}
- if( *arg && *arg != '*' )
+ if( *arg && *arg != '?' && *arg != '*' )
disp_error_message2("parse_callfunc: not enough arguments, expected ','", p, script_config.warn_func_mismatch_paramnum);
if( syntax.curly[syntax.curly_count].type != TYPE_ARGLIST )
disp_error_message("parse_callfunc: DEBUG last curly is not an argument list",p);
@@ -1528,11 +1538,29 @@ const char* parse_syntax_close_sub(const char* p,int* flag) {
static void add_buildin_func(void)
{
int i,n;
- for(i=0;buildin_func[i].func;i++){
- n=add_str(buildin_func[i].name);
- str_data[n].type=C_FUNC;
- str_data[n].val=i;
- str_data[n].func=buildin_func[i].func;
+ const char* p;
+ for( i=0; buildin_func[i].func; i++ ){
+ /// arg must follow the pattern: (v|s|i|l)*\?*\*?
+ /// 'v' - value (either string or int)
+ /// 's' - string
+ /// 'i' - int
+ /// 'l' - label
+ /// '?' - one optional parameter
+ /// '*' - unknown number of optional parameters
+ p=buildin_func[i].arg;
+ while( *p == 'v' || *p == 's' || *p == 'i' || *p == 'l' ) ++p;
+ while( *p == '?' ) ++p;
+ if( *p == '*' ) ++p;
+ if( *p != 0){
+ ShowWarning("add_buildin_func: ignoring function \"%s\" with invalid arg \"%s\".\n", buildin_func[i].name, buildin_func[i].arg);
+ } else if( *skip_word(buildin_func[i].name) != 0 ){
+ ShowWarning("add_buildin_func: ignoring function with invalid name \"%s\" (must be a word).\n", buildin_func[i].name);
+ } else {
+ n=add_str(buildin_func[i].name);
+ str_data[n].type=C_FUNC;
+ str_data[n].val=i;
+ str_data[n].func=buildin_func[i].func;
+ }
}
}
@@ -3778,7 +3806,7 @@ struct script_function buildin_func[] = {
{buildin_getarraysize,"getarraysize","i"},
{buildin_deletearray,"deletearray","ii"},
{buildin_getelementofarray,"getelementofarray","ii"},
- {buildin_getitem,"getitem","ii**"},
+ {buildin_getitem,"getitem","vi?"},
{buildin_getitem2,"getitem2","iiiiiiiii*"},
{buildin_getnameditem,"getnameditem","is"},
{buildin_grouprandomitem,"groupranditem","i"},
@@ -3948,7 +3976,7 @@ struct script_function buildin_func[] = {
{buildin_soundeffect,"soundeffect","si"},
{buildin_soundeffectall,"soundeffectall","si*"}, // SoundEffectAll [Codemaster]
{buildin_strmobinfo,"strmobinfo","ii"}, // display mob data [Valaris]
- {buildin_guardian,"guardian","siisii*i"}, // summon guardians
+ {buildin_guardian,"guardian","siisii??"}, // summon guardians
{buildin_guardianinfo,"guardianinfo","i"}, // display guardian data [Valaris]
{buildin_petskillbonus,"petskillbonus","iiii"}, // [Valaris]
{buildin_petrecovery,"petrecovery","ii"}, // [Valaris]
@@ -5282,66 +5310,77 @@ int buildin_checkweight(struct script_state *st)
}
/*==========================================
- *
+ * getitem <item id>,<amount>{,<character ID>};
+ * getitem "<item name>",<amount>{,<character ID>};
*------------------------------------------
*/
int buildin_getitem(struct script_state *st)
{
int nameid,amount,flag = 0;
- struct item item_tmp;
+ struct item it;
struct map_session_data *sd;
struct script_data *data;
- sd = script_rid2sd(st);
-
- data=&(st->stack->stack_data[st->start+2]);
+ data=script_getdata(st,2);
get_val(st,data);
- if( data->type==C_STR || data->type==C_CONSTSTR ){
+ if( script_isstring(data) )
+ {// "<item name>"
const char *name=conv_str(st,data);
struct item_data *item_data = itemdb_searchname(name);
- if( item_data == NULL) {
- ShowWarning("buildin_getitem: Nonexistant item %s requested.\n", name);
+ if( item_data == NULL ){
+ ShowError("buildin_getitem: Nonexistant item %s requested.\n", name);
+ report_src(st);
return 1; //No item created.
}
nameid=item_data->nameid;
- }else
+ } else if( script_isint(data) )
+ {// <item id>
nameid=conv_num(st,data);
+ //Violet Box, Blue Box, etc - random item pick
+ if( nameid < 0 ) {
+ nameid=itemdb_searchrandomid(-nameid);
+ flag = 1;
+ }
+ if( nameid <= 0 || !itemdb_exists(nameid) ){
+ ShowError("buildin_getitem: Nonexistant item %d requested.\n", nameid);
+ report_src(st);
+ return 1; //No item created.
+ }
+ } else {
+ ShowError("buildin_getitem: invalid data type for argument #1 (%d).", data->type);
+ report_src(st);
+ return 1;
+ }
- if ( ( amount=conv_num(st,& (st->stack->stack_data[st->start+3])) ) <= 0)
+ // <amount>
+ if( (amount=conv_num(st, script_getdata(st,3))) <= 0)
return 0; //return if amount <=0, skip the useles iteration
- //Violet Box, Blue Box, etc - random item pick
- if(nameid <0) {
- nameid=itemdb_searchrandomid(-nameid);
- flag = 1;
- }
-
- if(nameid <= 0 || !itemdb_exists(nameid)) {
- ShowWarning("buildin_getitem: Nonexistant item %d requested.\n", nameid);
- return 1; //No item created.
- }
-
- malloc_set(&item_tmp,0,sizeof(item_tmp));
- item_tmp.nameid=nameid;
+ malloc_set(&it,0,sizeof(it));
+ it.nameid=nameid;
if(!flag)
- item_tmp.identify=1;
+ it.identify=1;
else
- item_tmp.identify=itemdb_isidentified(nameid);
- if( st->end>st->start+5 ) //アイテムを指定したIDに渡す
- sd=map_id2sd(conv_num(st,& (st->stack->stack_data[st->start+5])));
- if(sd == NULL) //アイテムを渡す相手がいなかったらお帰り
+ it.identify=itemdb_isidentified(nameid);
+ if( script_hasdata(st,4) )
+ {// <character ID>
+ sd=map_id2sd(conv_num(st,script_getdata(st,4)));
+ } else
+ {// attached player
+ sd=script_rid2sd(st);
+ }
+ if( sd == NULL ) // no target
return 0;
- if(pet_create_egg(sd, nameid))
+ if( pet_create_egg(sd, nameid) )
amount = 1; //This is a pet!
- else
- if((flag = pc_additem(sd,&item_tmp,amount))) {
+ else if( (flag=pc_additem(sd,&it,amount)) ){
clif_additem(sd,0,0,flag);
- if (pc_candrop(sd, &item_tmp))
- map_addflooritem(&item_tmp,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
+ if( pc_candrop(sd,&it) )
+ map_addflooritem(&it,amount,sd->bl.m,sd->bl.x,sd->bl.y,NULL,NULL,NULL,0);
}
//Logs items, got from (N)PC scripts [Lupus]
- if(log_config.enable_logs&0x40)
+ if(log_config.enable_logs&LOG_SCRIPT_TRANSACTIONS)
log_pick_pc(sd, "N", nameid, amount, NULL);
return 0;
@@ -9550,26 +9589,45 @@ int buildin_strmobinfo(struct script_state *st)
/*==========================================
* Summon guardians [Valaris]
+ * guardian "<map name>",<x>,<y>,"<name to show>",<mob id>,<amount>{,"<event label>"}{,<guardian index>};
*------------------------------------------
*/
int buildin_guardian(struct script_state *st)
{
int class_=0,amount=1,x=0,y=0,guardian=0;
- char *str,*map,*event="";
+ char *str,*map,*evt="";
+ struct script_data *data;
- map =conv_str(st,& (st->stack->stack_data[st->start+2]));
- x =conv_num(st,& (st->stack->stack_data[st->start+3]));
- y =conv_num(st,& (st->stack->stack_data[st->start+4]));
- str =conv_str(st,& (st->stack->stack_data[st->start+5]));
- class_=conv_num(st,& (st->stack->stack_data[st->start+6]));
- amount=conv_num(st,& (st->stack->stack_data[st->start+7]));
- event=conv_str(st,& (st->stack->stack_data[st->start+8]));
- if( st->end>st->start+9 )
- guardian=conv_num(st,& (st->stack->stack_data[st->start+9]));
+ map =conv_str(st,script_getdata(st,2));
+ x =conv_num(st,script_getdata(st,3));
+ y =conv_num(st,script_getdata(st,4));
+ str =conv_str(st,script_getdata(st,5));
+ class_=conv_num(st,script_getdata(st,6));
+ amount=conv_num(st,script_getdata(st,7));
+
+ if( script_hasdata(st,9) )
+ {// "<event label>",<guardian index>
+ evt=conv_str(st,script_getdata(st,8));
+ guardian=conv_num(st,script_getdata(st,9));
+ } else if( script_hasdata(st,8) ){
+ data=script_getdata(st,8);
+ get_val(st,data);
+ if( script_isstring(data) )
+ {// "<event label>"
+ evt=conv_str(st,script_getdata(st,8));
+ } else if( script_isint(data) )
+ {// <guardian index>
+ guardian=conv_num(st,script_getdata(st,8));
+ } else {
+ ShowError("buildin_guardian: invalid data type for argument #8 (%d).", data->type);
+ report_src(st);
+ return 1;
+ }
+ }
- check_event(st, event);
+ check_event(st, evt);
- mob_spawn_guardian(map_id2sd(st->rid),map,x,y,str,class_,amount,event,guardian);
+ mob_spawn_guardian(map_id2sd(st->rid),map,x,y,str,class_,amount,evt,guardian);
return 0;
}