-Follow up r17236

-- Add timeout option for windows. linked to bugreport:7670
-- remove unuse variable (Akinari) bugreport:7672
-- upd script_command documentation (Akinari)
-- cleanup checkweight (remove hardcode change msg).
- Add new packets definition (Shaktoh)

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17327 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
glighta 2013-05-10 18:31:31 +00:00
parent b770bb52e7
commit f67f82c472
7 changed files with 132 additions and 134 deletions

View File

@ -1802,66 +1802,64 @@ packet_ver: 33
//2013-03-20Ragexe (Judas) //2013-03-20Ragexe (Judas)
packet_ver: 34 packet_ver: 34
0x01FD,15,repairitem,2 0x01fd,15,repairitem,2
0x086D,26,partyinvite2,2 //0x0281,-1,itemlistwindowselected,2:4:8
0x0897,5,changedir,2:4 0x035f,6,reqclickbuyingstore,2
0x0947,36,storagepassword,0
0x086F,26,friendslistadd,2
0x0888,19,wanttoconnection,2:6:10:14:18
0x088E,7,actionrequest,2:6
0x089B,10,useskilltoid,2:4:6
0x0881,5,walktoxy,2
0x0363,6,ticksend,2 0x0363,6,ticksend,2
0x093F,5,hommenu,2:4 0x0365,12,searchstoreinfolistitemclick,2:6:10
0x0933,6,takeitem,2
0x0438,6,dropitem,2:4 0x0438,6,dropitem,2:4
0x85d,18,bookingregreq,2:4 0x0447,2
0x08AC,8,movetokafra,2:4 0x0844,2,cashshopopen,0
0x0848,-1,cashshopbuy,0
0x084a,2,cashshopclose,0
0x084b,19 //fallitem4
0x085a,90,useskilltoposinfo,2:4:6:8:10
0x085d,18,bookingregreq,2:4
0x0868,-1,itemlistwindowselected,2:4:8
0x086d,26,partyinvite2,2
0x086f,26,friendslistadd,2
0x0874,8,movefromkafra,2:4 0x0874,8,movefromkafra,2:4
0x0959,10,useskilltopos,2:4:6:8 0x0881,5,walktoxy,2
0x085A,90,useskilltoposinfo,2:4:6:8:10 0x0886,2,reqclosebuyingstore,0
0x0888,19,wanttoconnection,2:6:10:14:18
0x088e,7,actionrequest,2:6
0x0897,5,changedir,2:4
0x0898,6,getcharnamerequest,2 0x0898,6,getcharnamerequest,2
0x094C,6,solvecharname,2 0x089b,10,useskilltoid,2:4:6
0x08ac,8,movetokafra,2:4
0x08c9,4,cashshopitemlist,0
0x08cf,10 //Amulet spirits
0x08d2,10
0x0907,5,moveitem,2:4 0x0907,5,moveitem,2:4
0x0908,5 0x0908,5
0x08CF,10 //Amulet spirits
0x08d2,10
0x0977,14 //Monster HP Bar
0x0998,8,equipitem,2:4
//0x0281,-1,itemlistwindowselected,2:4:8
0x0938,-1,reqopenbuyingstore,2:4:8:9:89
0x0886,2,reqclosebuyingstore,0
0x035f,6,reqclickbuyingstore,2
0x0922,-1,reqtradebuyingstore,2:4:8:12
0x094E,-1,searchstoreinfo,2:4:5:9:13:14:15
//0x0835,2,searchstoreinfonextpage,0
//0x0838,12,searchstoreinfolistitemclick,2:6:10
0x0447,2
0x990,31 //additem
0x99b,8 //maptypeproperty2
0x84b,19 //fallitem4
0x090f,-1 // notify_newentry7 0x090f,-1 // notify_newentry7
0x914,-1 // notify_moveentry 0x0914,-1 // notify_moveentry
0x915,-1 // notify_standentry 0x0915,-1 // notify_standentry
0x978,6,reqworldinfo,2 0x0922,-1,reqtradebuyingstore,2:4:8:12
0x979,50 //ackworldinfo //0x092e,2,searchstoreinfonextpage,0
0x991,-1 //inv itemlist normal 0x0933,6,takeitem,2
0x992,-1 //inv itemlist equip 0x0938,-1,reqopenbuyingstore,2:4:8:9:89
0x993,-1 //cart itemlist normal 0x093f,5,hommenu,2:4
0x994,-1 //cart itemlist equip 0x0947,36,storagepassword,0
0x995,-1 //store itemlist normal 0x094c,6,solvecharname,2
0x996,-1 //store itemlist equip 0x094e,-1,searchstoreinfo,2:4:5:9:13:14:15
0x997,-1 //ZC_EQUIPWIN_MICROSCOPE_V5 0x0959,10,useskilltopos,2:4:6:8
0x998,8,equipitem,2:4 //0x095a,8,mailsetattach,2:4
0x999,11 // cz_wear_equipv5 0x0977,14 //Monster HP Bar
0x99a,9 // take_off_equipv5 0x0978,6,reqworldinfo,2
0x0979,50 //ackworldinfo
0x0990,31 //additem
// New cashshop 0x0991,-1 //inv itemlist normal
0x0844,2,cashshopopen,0 0x0992,-1 //inv itemlist equip
0x084a,2,cashshopclose,0 0x0993,-1 //cart itemlist normal
0x08c9,4,cashshopitemlist,0 0x0994,-1 //cart itemlist equip
0x0848,-1,cashshopbuy,0 0x0995,-1 //store itemlist normal
0x0996,-1 //store itemlist equip
0x0997,-1 //ZC_EQUIPWIN_MICROSCOPE_V5
0x0998,8,equipitem,2:4
0x0999,11 // cz_wear_equipv5
0x099a,9 // take_off_equipv5
0x099b,8 //maptypeproperty2
//Add new packets here //Add new packets here
//packet_ver: 35 //packet_ver: 35

View File

@ -4851,40 +4851,48 @@ Used in reset NPC's (duh!)
*sc_start4 <effect type>,<ticks>,<value 1>,<value 2>,<value 3>,<value 4>{,<rate>,<flag>,<GID>}; *sc_start4 <effect type>,<ticks>,<value 1>,<value 2>,<value 3>,<value 4>{,<rate>,<flag>,<GID>};
*sc_end <effect type>{,<GID>}; *sc_end <effect type>{,<GID>};
These command bestow a status effect on the invoking character. This command is These commands give a character a status effect. Optionally, <rate> and <flag> can be defined.
used a lot in the item scripts.
// This would poison them for 10 min <effect type> is which status change to invoke. This can be a number or SC name.
sc_start SC_Poison,600000,0; A list of these are in the file 'db/const.txt' with the 'SC_' prefix.
Effect type is a number of effect, 'db/const.txt' lists the common (mostly A number of <ticks> refers to how long the status change should last. (1000 = 1 sec)
negative) status effect types as constants, starting with 'SC_'. You can also <value 1> is used on certain status changes, generally modifying player stats by
use this to give someone an effect of a player-cast spell: the given value or a percentage.
// This will bless someone as if with Bless 10: Optional value <rate> is on a scale of 0-10000, with 0 being no chance to invoke
the status change, and 10000 being 100% chance. NPCs given a <rate> without
defining a flag will ignore the value. However, items can be given a rate
and don't require a flag to be given for the rate to be ignored.
Optional value <flag> allows the setting of how the status change start should
be handled. These can be added together like a configuration parameter.
<flag>: *Default 2*
1: Cannot be avoided (it has to start)
2: Tick should not be reduced (by vit, luk, lv, etc)
4: sc_data loaded, no value has to be altered.
8: rate should not be reduced
<GID> will cause the status effect to appear on a specified character, instead of the
one attached to the running script. This can only be defined after setting <rate> and <flag>.
Using sc_start2 or sc_start4, extra arguments are able to be given when an
effect can take them. Extra argument's meaning differs depending on the effect type, for
most effects caused by a player skill the extra argument means the level of the skill
that would have been used to create that effect, for others it might have no meaning
whatsoever.
Examples:
// This would poison them for 10 min at 50% chance
sc_start SC_Poison,600000,0,5000;
// This will bless someone with Bless 10
sc_start 10,240000,10; sc_start 10,240000,10;
Extra argument's meaning differs depending on the effect type, for most effects // elemental armor defense takes the following four values
caused by a player skill the extra argument means the level of the skill that // val1 is the first element, val2 is the resistance to the element val1.
would have been used to create that effect, for others it might have no meaning // val3 is the second element, val4 is the resistance to said element.
whatsoever. You can actually bless someone with a 0 bless spell level this way, sc_start4 SC_DefEle,60000,Ele_Fire,20,Ele_Water,-15;
which is fun, but weird.
The GID, if given, will cause the status effect to appear on a
specified character, instead of the one attached to the running script. This has
not been properly tested.
'sc_start2' is perfectly equivalent, but unlike 'sc_start', a status change
effect will only occur with a specified percentage chance. 10000 given as the
chance is equivalent to a 100% chance, 0 is a zero.
'sc_start4' is just like sc_start, however it takes four parameters for the
status change instead of one. What these values are depends on the status
change in question. For example, elemental armor defense takes the following
four values:
- val1 is the first element, val2 is the resistance to the element val1.
- val3 is the second element, val4 is the resistance to said element.
eg: sc_start4 SC_DefEle,60000,Ele_Fire,20,Ele_Water,-15;
'sc_end' will remove a specified status effect. If SC_All is used (-1), it will 'sc_end' will remove a specified status effect. If SC_All is used (-1), it will
do a complete removal of all statuses (although permanent ones will re-apply). do a complete removal of all statuses (although permanent ones will re-apply).

View File

@ -3431,7 +3431,7 @@ int parse_frommap(int fd)
int sfd;/* stat server fd */ int sfd;/* stat server fd */
RFIFOSKIP(fd, 2);/* we skip first 2 bytes which are the 0x3008, so we end up with a buffer equal to the one we send */ RFIFOSKIP(fd, 2);/* we skip first 2 bytes which are the 0x3008, so we end up with a buffer equal to the one we send */
if( (sfd = make_connection(host2ip("stats.rathena.org"),(uint16)25421,true) ) == -1 ) { if( (sfd = make_connection(host2ip("stats.rathena.org"),(uint16)25421,true,10) ) == -1 ) {
RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */ RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */
break;/* connection not possible, we drop the report */ break;/* connection not possible, we drop the report */
} }
@ -4520,7 +4520,7 @@ int check_connect_login_server(int tid, unsigned int tick, int id, intptr_t data
return 0; return 0;
ShowInfo("Attempt to connect to login-server...\n"); ShowInfo("Attempt to connect to login-server...\n");
login_fd = make_connection(login_ip, login_port, false); login_fd = make_connection(login_ip, login_port, false,10);
if (login_fd == -1) if (login_fd == -1)
{ //Try again later. [Skotlex] { //Try again later. [Skotlex]
login_fd = 0; login_fd = 0;

View File

@ -279,14 +279,9 @@ void set_nonblocking(int fd, unsigned long yes)
ShowError("set_nonblocking: Failed to set socket #%d to non-blocking mode (%s) - Please report this!!!\n", fd, error_msg()); ShowError("set_nonblocking: Failed to set socket #%d to non-blocking mode (%s) - Please report this!!!\n", fd, error_msg());
} }
void setsocketopts(int fd) void setsocketopts(int fd,int delay_timeout){
{
struct timeval timeout;
int yes = 1; // reuse fix int yes = 1; // reuse fix
timeout.tv_sec = 10;
timeout.tv_usec = 0;
#if !defined(WIN32) #if !defined(WIN32)
// set SO_REAUSEADDR to true, unix only. on windows this option causes // set SO_REAUSEADDR to true, unix only. on windows this option causes
// the previous owner of the socket to give up, which is not desirable // the previous owner of the socket to give up, which is not desirable
@ -297,11 +292,6 @@ void setsocketopts(int fd)
#endif #endif
#endif #endif
if (setsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
ShowError("setsockopt failed\n");
if (setsockopt (fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
ShowError("setsockopt failed\n");
// Set the socket into no-delay mode; otherwise packets get delayed for up to 200ms, likely creating server-side lag. // Set the socket into no-delay mode; otherwise packets get delayed for up to 200ms, likely creating server-side lag.
// The RO protocol is mainly single-packet request/response, plus the FIFO model already does packet grouping anyway. // The RO protocol is mainly single-packet request/response, plus the FIFO model already does packet grouping anyway.
sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes)); sSetsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&yes, sizeof(yes));
@ -315,6 +305,16 @@ void setsocketopts(int fd)
if( sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&opt, sizeof(opt)) ) if( sSetsockopt(fd, SOL_SOCKET, SO_LINGER, (char*)&opt, sizeof(opt)) )
ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd); ShowWarning("setsocketopts: Unable to set SO_LINGER mode for connection #%d!\n", fd);
} }
if(delay_timeout){
struct timeval timeout;
timeout.tv_sec = delay_timeout;
timeout.tv_usec = 0;
if (sSetsockopt (fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
ShowError("setsocketopts: Unable to set SO_RCVTIMEO timeout for connection #%d!\n");
if (sSetsockopt (fd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout,sizeof(timeout)) < 0)
ShowError("setsocketopts: Unable to set SO_SNDTIMEO timeout for connection #%d!\n");
}
} }
/*====================================== /*======================================
@ -439,7 +439,7 @@ int connect_client(int listen_fd)
return -1; return -1;
} }
setsocketopts(fd); setsocketopts(fd,0);
set_nonblocking(fd, 1); set_nonblocking(fd, 1);
#ifndef MINICORE #ifndef MINICORE
@ -484,7 +484,7 @@ int make_listen_bind(uint32 ip, uint16 port)
return -1; return -1;
} }
setsocketopts(fd); setsocketopts(fd,0);
set_nonblocking(fd, 1); set_nonblocking(fd, 1);
server_address.sin_family = AF_INET; server_address.sin_family = AF_INET;
@ -512,7 +512,7 @@ int make_listen_bind(uint32 ip, uint16 port)
return fd; return fd;
} }
int make_connection(uint32 ip, uint16 port, bool silent) { int make_connection(uint32 ip, uint16 port, bool silent,int timeout) {
struct sockaddr_in remote_address; struct sockaddr_in remote_address;
int fd; int fd;
int result; int result;
@ -536,7 +536,7 @@ int make_connection(uint32 ip, uint16 port, bool silent) {
return -1; return -1;
} }
setsocketopts(fd); setsocketopts(fd,timeout);
remote_address.sin_family = AF_INET; remote_address.sin_family = AF_INET;
remote_address.sin_addr.s_addr = htonl(ip); remote_address.sin_addr.s_addr = htonl(ip);
@ -1163,7 +1163,7 @@ void socket_final(void)
if(session[i]) if(session[i])
do_close(i); do_close(i);
// session[0] のダミーデータを削除 // session[0] <EFBFBD>̃_<EFBFBD>~<7E>[<5B>f<EFBFBD>[<5B>^<5E><><EFBFBD>
aFree(session[0]->rdata); aFree(session[0]->rdata);
aFree(session[0]->wdata); aFree(session[0]->wdata);
aFree(session[0]); aFree(session[0]);

View File

@ -113,7 +113,7 @@ extern bool session_isActive(int fd);
// Function prototype declaration // Function prototype declaration
int make_listen_bind(uint32 ip, uint16 port); int make_listen_bind(uint32 ip, uint16 port);
int make_connection(uint32 ip, uint16 port, bool silent); int make_connection(uint32 ip, uint16 port, bool silent, int timeout);
int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size); int realloc_fifo(int fd, unsigned int rfifo_size, unsigned int wfifo_size);
int realloc_writefifo(int fd, size_t addition); int realloc_writefifo(int fd, size_t addition);
int WFIFOSET(int fd, size_t len); int WFIFOSET(int fd, size_t len);

View File

@ -1511,7 +1511,7 @@ static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_
} }
chrif_state = 0; chrif_state = 0;
char_fd = make_connection(char_ip, char_port,false); char_fd = make_connection(char_ip, char_port,false,10);
if (char_fd == -1)//Attempt to connect later. [Skotlex] if (char_fd == -1)//Attempt to connect later. [Skotlex]
return 0; return 0;
@ -1554,13 +1554,9 @@ void chrif_send_report(char* buf, int len) {
#ifndef STATS_OPT_OUT #ifndef STATS_OPT_OUT
WFIFOHEAD(char_fd,len + 2); WFIFOHEAD(char_fd,len + 2);
WFIFOW(char_fd,0) = 0x3008; WFIFOW(char_fd,0) = 0x3008;
memcpy(WFIFOP(char_fd,2), buf, len); memcpy(WFIFOP(char_fd,2), buf, len);
WFIFOSET(char_fd,len + 2); WFIFOSET(char_fd,len + 2);
flush_fifo(char_fd); /* ensure it's sent now. */ flush_fifo(char_fd); /* ensure it's sent now. */
#endif #endif

View File

@ -6055,8 +6055,7 @@ BUILDIN_FUNC(viewpoint)
*------------------------------------------*/ *------------------------------------------*/
BUILDIN_FUNC(countitem) BUILDIN_FUNC(countitem)
{ {
int nameid, i; int i, count = 0;
int count = 0;
struct item_data* id = NULL; struct item_data* id = NULL;
struct script_data* data; struct script_data* data;
@ -6081,13 +6080,12 @@ BUILDIN_FUNC(countitem)
} }
if(script_lastdata(st) == 2) { // For countitem() function if(script_lastdata(st) == 2) { // For countitem() function
nameid = id->nameid; int nameid = id->nameid;
for(i = 0; i < MAX_INVENTORY; i++) for(i = 0; i < MAX_INVENTORY; i++)
if(sd->status.inventory[i].nameid == nameid) if(sd->status.inventory[i].nameid == nameid)
count += sd->status.inventory[i].amount; count += sd->status.inventory[i].amount;
} else { // For countitem2() function } else { // For countitem2() function
struct item tmp_it; struct item tmp_it;
int iden, ref, attr, c1, c2, c3, c4;
tmp_it.nameid = id->nameid; tmp_it.nameid = id->nameid;
tmp_it.identify = script_getnum(st, 3); tmp_it.identify = script_getnum(st, 3);
tmp_it.refine = script_getnum(st, 4); tmp_it.refine = script_getnum(st, 4);
@ -6109,7 +6107,7 @@ BUILDIN_FUNC(countitem)
return 0; return 0;
} }
int checkweight_sub(TBL_PC *sd,int nbargs,int *eitemid,int *eamount) int checkweight_sub(TBL_PC *sd,int nbargs,int32 *eitemid,int32 *eamount)
{ {
struct item_data* id = NULL; struct item_data* id = NULL;
int nameid,amount; int nameid,amount;
@ -6122,14 +6120,14 @@ int checkweight_sub(TBL_PC *sd,int nbargs,int *eitemid,int *eamount)
continue; continue;
id = itemdb_exists(eitemid[i]); id = itemdb_exists(eitemid[i]);
if( id == NULL ) { if( id == NULL ) {
ShowError("buildin_checkweight: Invalid item '%d'.\n", eitemid[i]); ShowError("checkweight_sub: Invalid item '%d'.\n", eitemid[i]);
return 0; return 0;
} }
nameid = id->nameid; nameid = id->nameid;
amount = eamount[i]; amount = eamount[i];
if( amount < 1 ) { if( amount < 1 ) {
ShowError("buildin_checkweight: Invalid amount '%d'.\n", eamount[i]); ShowError("checkweight_sub: Invalid amount '%d'.\n", eamount[i]);
return 0; return 0;
} }
@ -6167,7 +6165,7 @@ BUILDIN_FUNC(checkweight)
struct map_session_data* sd; struct map_session_data* sd;
struct script_data* data; struct script_data* data;
struct item_data* id = NULL; struct item_data* id = NULL;
int nameid[128], amount[128]; int32 nameid[SCRIPT_MAX_ARRAYSIZE], amount[SCRIPT_MAX_ARRAYSIZE];
uint16 nbargs,i,j=0; uint16 nbargs,i,j=0;
if( ( sd = script_rid2sd(st) ) == NULL ) if( ( sd = script_rid2sd(st) ) == NULL )
@ -6201,10 +6199,9 @@ BUILDIN_FUNC(checkweight)
return 0; return 0;
} }
BUILDIN_FUNC(checkweight2) BUILDIN_FUNC(checkweight2){
{
//variable sub checkweight //variable sub checkweight
int nameid[128], amount[128], i; int32 nameid[SCRIPT_MAX_ARRAYSIZE], amount[SCRIPT_MAX_ARRAYSIZE], i;
//variable for array parsing //variable for array parsing
struct script_data* data_it; struct script_data* data_it;
@ -6222,7 +6219,7 @@ BUILDIN_FUNC(checkweight2)
data_nb = script_getdata(st, 3); data_nb = script_getdata(st, 3);
if( !data_isreference(data_it) || !data_isreference(data_nb)) { if( !data_isreference(data_it) || !data_isreference(data_nb)) {
ShowError("script:checkweight2: parameter not a variable\n"); ShowError("buildin_checkweight2: parameter not a variable\n");
script_pushint(st,0); script_pushint(st,0);
return 1;// not a variable return 1;// not a variable
} }
@ -6235,19 +6232,19 @@ BUILDIN_FUNC(checkweight2)
name_nb = reference_getname(data_nb); name_nb = reference_getname(data_nb);
if( not_array_variable(*name_it) || not_array_variable(*name_nb)) { if( not_array_variable(*name_it) || not_array_variable(*name_nb)) {
ShowError("script:checkweight2: illegal scope\n"); ShowError("buildin_checkweight2: illegal scope\n");
script_pushint(st,0); script_pushint(st,0);
return 1;// not supported return 1;// not supported
} }
if(is_string_variable(name_it) || is_string_variable(name_nb)) { if(is_string_variable(name_it) || is_string_variable(name_nb)) {
ShowError("script:checkweight2: illegal type, need int\n"); ShowError("buildin_checkweight2: illegal type, need int\n");
script_pushint(st,0); script_pushint(st,0);
return 1;// not supported return 1;// not supported
} }
nb_it = getarraysize(st, id_it, idx_it, 0, reference_getref(data_it)); nb_it = getarraysize(st, id_it, idx_it, 0, reference_getref(data_it));
nb_nb = getarraysize(st, id_nb, idx_nb, 0, reference_getref(data_nb)); nb_nb = getarraysize(st, id_nb, idx_nb, 0, reference_getref(data_nb));
if(nb_it != nb_nb) { if(nb_it != nb_nb) {
ShowError("Size mistmatch: nb_it=%d, nb_nb=%d\n",nb_it,nb_nb); ShowError("buildin_checkweight2: Size mistmatch: nb_it=%d, nb_nb=%d\n",nb_it,nb_nb);
script_pushint(st,0); script_pushint(st,0);
return 1; return 1;
} }
@ -9842,8 +9839,7 @@ BUILDIN_FUNC(sc_start)
TBL_NPC * nd = map_id2nd(st->oid); TBL_NPC * nd = map_id2nd(st->oid);
struct block_list* bl; struct block_list* bl;
enum sc_type type; enum sc_type type;
int tick, val1, val2, val3, rate, flag, isitem; int tick, val1, val2, val3, val4=0, rate, flag, isitem;
int val4 = 0;
char start_type; char start_type;
const char* command = script_getfuncname(st); const char* command = script_getfuncname(st);
@ -9878,7 +9874,7 @@ BUILDIN_FUNC(sc_start)
} }
//solving if script from npc or item //solving if script from npc or item
isitem = (nd && nd->bl.id == fake_nd->bl.id || rate != 2)?true:false; isitem = (nd && nd->bl.id == fake_nd->bl.id || flag != 2)?true:false;
switch(start_type) { switch(start_type) {
case 1: case 1: