- Replaced @send with the version I use for testing packets.

Can display the packet length. Supports dynamic packets, quoted strings 
  with escaped characters and fixed/variable length, and normal/hex 
  byte/word/long data types. The number of fields is not limited, but it 
  automatically stops parsing when the packet is full.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@9387 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
FlavioJS 2006-12-02 04:21:35 +00:00
parent 7935fd82c4
commit b522ca0cdc
4 changed files with 23118 additions and 22946 deletions

View File

@ -3,6 +3,12 @@ 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.
2006/12/02
* Replaced @send with the version I use for testing packets.
Can display the packet length. Supports dynamic packets, quoted strings
with escaped characters and fixed/variable length, and normal/hex
byte/word/long data types. The number of fields is not limited, but it
automatically stops parsing when the packet is full. [FlavioJS]
2006/12/01
* Fixed passive mobs becoming increasingly unlikely to retaliate to attacks
after they got inflicted by a disabling status change. [Skotlex]

View File

@ -72,6 +72,10 @@ extern time_t stall_time;
#define WBUFW(p,pos) (*(unsigned short*)((p) + (pos)))
#define WBUFL(p,pos) (*(unsigned long*)((p) + (pos)))
#define TOB(n) ((unsigned char)(n))
#define TOW(n) ((unsigned short)(n))
#define TOL(n) ((unsigned long)(n))
//FD_SETSIZE must be modified on the project files/Makefile, since a change here won't affect
// dependant windows libraries.
/*

View File

@ -1070,31 +1070,234 @@ int atcommand_send(
const int fd, struct map_session_data* sd,
const char* command, const char* message)
{
int type=0;
int info[20];
int len=0,off,end,type;
long num;
(void)command; // not used
malloc_tsetdword(info,0,sizeof(info));
if (!message || !*message || sscanf(message,
"%x %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
&type,
&info[0], &info[1], &info[2], &info[3], &info[4],
&info[5], &info[6], &info[7], &info[8], &info[9],
&info[10], &info[11], &info[12], &info[13], &info[14],
&info[15], &info[16], &info[17], &info[18], &info[19]) < 1)
{
clif_displaymessage(fd, "Please enter a packet number, and - if required - up to 20 additional values.");
return -1;
}
if (!clif_send_debug(sd, type, info, sizeof(info)/sizeof(int)))
// read message type as hex number (without the 0x)
if(!message || !*message ||
!((sscanf(message, "len %x", &type)==1 && (len=1))
|| sscanf(message, "%x", &type)==1) )
{
clif_displaymessage(fd, msg_txt(259));
clif_displaymessage(fd, "Usage:");
clif_displaymessage(fd, " @send len <packet hex number>");
clif_displaymessage(fd, " @send <packet hex number> {<value>}*");
clif_displaymessage(fd, " Value: <type=B(default),W,L><number> or S<length>\"<string>\"");
return -1;
}
sprintf (atcmd_output, msg_txt(258), type, type);
#define PARSE_ERROR(error,p) \
{\
clif_displaymessage(fd, (error));\
sprintf(atcmd_output, ">%s", (p));\
clif_displaymessage(fd, atcmd_output);\
}
//define PARSE_ERROR
#define CHECK_EOS(p) \
if(*(p) == 0){\
clif_displaymessage(fd, "Unexpected end of string");\
return -1;\
}
//define CHECK_EOS
#define SKIP_VALUE(p) \
{\
while(*(p) && !isspace(*(p))) ++(p); /* non-space */\
while(*(p) && isspace(*(p))) ++(p); /* space */\
}
//define SKIP_VALUE
#define GET_VALUE(p,num) \
{\
if(sscanf((p), "x%lx", &(num)) < 1 && sscanf((p), "%ld ", &(num)) < 1){\
PARSE_ERROR("Invalid number in:",(p));\
return -1;\
}\
}
//define GET_VALUE
if (type > 0 && type < MAX_PACKET_DB) {
if(len)
{// show packet length
sprintf(atcmd_output, "Packet 0x%x length: %d", type, packet_db[sd->packet_ver][type].len);
clif_displaymessage(fd, atcmd_output);
return 0;
}
len=packet_db[sd->packet_ver][type].len;
off=2;
if(len == 0)
{// unknown packet - ERROR
sprintf(atcmd_output, "Unknown packet: 0x%x", type);
clif_displaymessage(fd, atcmd_output);
return -1;
} else if(len == -1)
{// dynamic packet
len=SHRT_MAX-4; // maximum length
off=4;
}
WFIFOHEAD(fd, len);
WFIFOW(fd,0)=TOW(type);
// parse packet contents
SKIP_VALUE(message);
while(*message != 0 && off < len){
if(isdigit(*message) || *message == '-' || *message == '+')
{// default (byte)
GET_VALUE(message,num);
WFIFOB(fd,off)=TOB(num);
++off;
} else if(toupper(*message) == 'B')
{// byte
++message;
GET_VALUE(message,num);
WFIFOB(fd,off)=TOB(num);
++off;
} else if(toupper(*message) == 'W')
{// word (2 bytes)
++message;
GET_VALUE(message,num);
WFIFOW(fd,off)=TOW(num);
off+=2;
} else if(toupper(*message) == 'L')
{// long word (4 bytes)
++message;
GET_VALUE(message,num);
WFIFOL(fd,off)=TOL(num);
off+=4;
} else if(toupper(*message) == 'S')
{// string - escapes are valid
// get string length - num <= 0 means not fixed length (default)
++message;
if(*message == '"'){
num=0;
} else {
GET_VALUE(message,num);
while(*message != '"')
{// find start of string
if(*message == 0 || isspace(*message)){
PARSE_ERROR("Not a string:",message);
return -1;
}
++message;
}
}
// parse string
++message;
CHECK_EOS(message);
end=(num<=0? 0: min(off+((int)num),len));
for(; *message != '"' && (off < end || end == 0); ++off){
if(*message == '\\'){
++message;
CHECK_EOS(message);
switch(*message){
case 'a': num=0x07; break; // Bell
case 'b': num=0x08; break; // Backspace
case 't': num=0x09; break; // Horizontal tab
case 'n': num=0x0A; break; // Line feed
case 'v': num=0x0B; break; // Vertical tab
case 'f': num=0x0C; break; // Form feed
case 'r': num=0x0D; break; // Carriage return
case 'e': num=0x1B; break; // Escape
default: num=*message; break;
case 'x': // Hexadecimal
{
++message;
CHECK_EOS(message);
if(!isxdigit(*message)){
PARSE_ERROR("Not a hexadecimal digit:",message);
return -1;
}
num=(isdigit(*message)?*message-'0':tolower(*message)-'a'+10);
if(isxdigit(*message)){
++message;
CHECK_EOS(message);
num<<=8;
num+=(isdigit(*message)?*message-'0':tolower(*message)-'a'+10);
}
WFIFOB(fd,off)=TOB(num);
++message;
CHECK_EOS(message);
continue;
}
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7': // Octal
{
num=*message-'0'; // 1st octal digit
++message;
CHECK_EOS(message);
if(isdigit(*message) && *message < '8'){
num<<=3;
num+=*message-'0'; // 2nd octal digit
++message;
CHECK_EOS(message);
if(isdigit(*message) && *message < '8'){
num<<=3;
num+=*message-'0'; // 3rd octal digit
++message;
CHECK_EOS(message);
}
}
WFIFOB(fd,off)=TOB(num);
continue;
}
}
} else
num=*message;
WFIFOB(fd,off)=TOB(num);
++message;
CHECK_EOS(message);
}//for
while(*message != '"')
{// ignore extra characters
++message;
CHECK_EOS(message);
}
// terminate the string
if(off < end)
{// fill the rest with 0's
memset(WFIFOP(fd,off),0,end-off);
off=end;
}
} else
{// unknown
PARSE_ERROR("Unknown type of value in:",message);
return -1;
}
SKIP_VALUE(message);
}
if(packet_db[sd->packet_ver][type].len == -1)
{// send dynamic packet
WFIFOW(fd,2)=TOW(off);
WFIFOSET(fd,off);
} else
{// send static packet
if(off < len)
memset(WFIFOP(fd,off),0,len-off);
WFIFOSET(fd,len);
}
} else {
clif_displaymessage(fd, msg_txt(259)); // Invalid packet
return -1;
}
sprintf (atcmd_output, msg_txt(258), type, type); // Sent packet 0x%x (%d)
clif_displaymessage(fd, atcmd_output);
return 0;
#undef PARSE_ERROR
#undef CHECK_EOS
#undef SKIP_VALUE
#undef GET_VALUE
}
// @rura

View File

@ -620,47 +620,6 @@ int clif_send (unsigned char *buf, int len, struct block_list *bl, int type) {
return 0;
}
//For use in the @send command.
int clif_send_debug(struct map_session_data *sd, int cmd, int* args, int args_num)
{
int fd = sd->fd;
int len;
if (cmd < 0 || cmd >= MAX_PACKET_DB)
return 0;
len = packet_db[sd->packet_ver][cmd].len;
if (!fd || !len || len == -1) //len -1, variable width, not supported!
return 0;
switch (cmd)
{
case 0x209:
{
WFIFOHEAD(fd, len);
WFIFOW(fd,0) = 0x209;
WFIFOW(fd,2) = 2;
memcpy(WFIFOP(fd, 12), sd->status.name, NAME_LENGTH);
WFIFOSET(fd, len);
break;
}
default:
{
int i;
WFIFOHEAD(fd, len);
memset(WFIFOP(fd,0), 0, len);
WFIFOW(fd,0) = cmd;
//Packet can only have len/2 arguments. Since each arg is a Word
if (args_num > len/2 -2)
args_num = len/2 -2;
for(i=0; i<args_num; i++)
WFIFOW(fd,i+1) = args[i];
WFIFOSET(fd, len);
break;
}
}
return 1;
}
//
// パケット作って送信
//