- Improvements to the mail system.

- Added a sql patch, renaming "read_flag" column to "status" on the mail db.
- Need more testing.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@11583 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
zephyrus 2007-10-27 06:34:04 +00:00
parent 9ec6519201
commit 284222a415
11 changed files with 318 additions and 230 deletions

View File

@ -3,6 +3,8 @@ Date Added
AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO INTO TRUNK. 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. IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK.
2007/10/27
* Improvements to the mail system. Need Testing, [Zephyrus]
2007/10/26 2007/10/26
* Moved the new novending cell check from the internal code to the * Moved the new novending cell check from the internal code to the
client-server interface (allows server to force-open shop if needed) client-server interface (allows server to force-open shop if needed)

View File

@ -0,0 +1 @@
ALTER TABLE `mail` CHANGE `read_flag` `status` SMALLINT(2) NOT NULL default 0;

View File

@ -34,11 +34,12 @@ static int mail_fromsql(int char_id, struct mail_data* md)
md->full = false; md->full = false;
StringBuf_Init(&buf); StringBuf_Init(&buf);
StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`read_flag`," StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`status`,"
"`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`"); "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`");
for (i = 0; i < MAX_SLOTS; i++) for (i = 0; i < MAX_SLOTS; i++)
StringBuf_Printf(&buf, ",`card%d`", i); StringBuf_Printf(&buf, ",`card%d`", i);
StringBuf_Printf(&buf, " FROM `%s` WHERE `dest_id`='%d' ORDER BY `id` LIMIT %d", mail_db, char_id, MAIL_MAX_INBOX + 1); StringBuf_Printf(&buf, " FROM `%s` WHERE `dest_id`='%d' AND `status` > -1 AND `status` < 3 "
"ORDER BY `id` LIMIT %d", mail_db, char_id, MAIL_MAX_INBOX + 1);
if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) ) if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) )
Sql_ShowDebug(sql_handle); Sql_ShowDebug(sql_handle);
@ -56,7 +57,7 @@ static int mail_fromsql(int char_id, struct mail_data* md)
Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(msg->title, data, MAIL_TITLE_LENGTH); Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(msg->title, data, MAIL_TITLE_LENGTH);
Sql_GetData(sql_handle, 6, &data, NULL); safestrncpy(msg->body, data, MAIL_BODY_LENGTH); Sql_GetData(sql_handle, 6, &data, NULL); safestrncpy(msg->body, data, MAIL_BODY_LENGTH);
Sql_GetData(sql_handle, 7, &data, NULL); msg->timestamp = atoi(data); Sql_GetData(sql_handle, 7, &data, NULL); msg->timestamp = atoi(data);
Sql_GetData(sql_handle, 8, &data, NULL); msg->read = atoi(data); Sql_GetData(sql_handle, 8, &data, NULL); msg->status = atoi(data);
Sql_GetData(sql_handle, 9, &data, NULL); msg->zeny = atoi(data); Sql_GetData(sql_handle, 9, &data, NULL); msg->zeny = atoi(data);
item = &msg->item; item = &msg->item;
Sql_GetData(sql_handle,10, &data, NULL); item->amount = (short)atoi(data); Sql_GetData(sql_handle,10, &data, NULL); item->amount = (short)atoi(data);
@ -83,17 +84,16 @@ static int mail_fromsql(int char_id, struct mail_data* md)
for (i = 0; i < md->amount; i++) for (i = 0; i < md->amount; i++)
{ {
msg = &md->msg[i]; msg = &md->msg[i];
if( msg->read == 0 ) if( msg->status == MAIL_NEW )
{ {
if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `read_flag` = '1' WHERE `id` = '%d'", mail_db, msg->id) ) if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_UNREAD, msg->id) )
Sql_ShowDebug(sql_handle); Sql_ShowDebug(sql_handle);
msg->status = MAIL_UNREAD;
md->unchecked++; md->unchecked++;
} }
else if ( msg->read == 1 ) else if ( msg->status == MAIL_UNREAD )
md->unread++; md->unread++;
msg->read = (msg->read < 2)?0:1;
} }
ShowInfo("mail load complete from DB - id: %d (total: %d)\n", char_id, md->amount); ShowInfo("mail load complete from DB - id: %d (total: %d)\n", char_id, md->amount);
@ -110,11 +110,11 @@ static int mail_savemessage(struct mail_message* msg)
// build message save query // build message save query
StringBuf_Init(&buf); StringBuf_Init(&buf);
StringBuf_Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `read_flag`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`", mail_db); StringBuf_Printf(&buf, "INSERT INTO `%s` (`send_name`, `send_id`, `dest_name`, `dest_id`, `title`, `message`, `time`, `status`, `zeny`, `amount`, `nameid`, `refine`, `attribute`, `identify`", mail_db);
for (j = 0; j < MAX_SLOTS; j++) for (j = 0; j < MAX_SLOTS; j++)
StringBuf_Printf(&buf, ", `card%d`", j); StringBuf_Printf(&buf, ", `card%d`", j);
StringBuf_Printf(&buf, ") VALUES (?, '%d', ?, '%d', ?, ?, '%d', '0', '%d', '%d', '%d', '%d', '%d', '%d'", StringBuf_Printf(&buf, ") VALUES (?, '%d', ?, '%d', ?, ?, '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'",
msg->send_id, msg->dest_id, msg->timestamp, msg->zeny, msg->item.amount, msg->item.nameid, msg->item.refine, msg->item.attribute, msg->item.identify); msg->send_id, msg->dest_id, msg->timestamp, msg->status, msg->zeny, msg->item.amount, msg->item.nameid, msg->item.refine, msg->item.attribute, msg->item.identify);
for (j = 0; j < MAX_SLOTS; j++) for (j = 0; j < MAX_SLOTS; j++)
StringBuf_Printf(&buf, ", '%d'", msg->item.card[j]); StringBuf_Printf(&buf, ", '%d'", msg->item.card[j]);
StringBuf_AppendStr(&buf, ")"); StringBuf_AppendStr(&buf, ")");
@ -141,17 +141,17 @@ static int mail_savemessage(struct mail_message* msg)
/// Retrieves a single message from the database. /// Retrieves a single message from the database.
/// Returns true if the operation succeeds (or false if it fails). /// Returns true if the operation succeeds (or false if it fails).
static bool mail_loadmessage(int char_id, int mail_id, struct mail_message* msg) static bool mail_loadmessage(int mail_id, struct mail_message* msg)
{ {
int j; int j;
StringBuf buf; StringBuf buf;
StringBuf_Init(&buf); StringBuf_Init(&buf);
StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`read_flag`," StringBuf_AppendStr(&buf, "SELECT `id`,`send_name`,`send_id`,`dest_name`,`dest_id`,`title`,`message`,`time`,`status`,"
"`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`"); "`zeny`,`amount`,`nameid`,`refine`,`attribute`,`identify`");
for( j = 0; j < MAX_SLOTS; j++ ) for( j = 0; j < MAX_SLOTS; j++ )
StringBuf_Printf(&buf, ",`card%d`", j); StringBuf_Printf(&buf, ",`card%d`", j);
StringBuf_Printf(&buf, " FROM `%s` WHERE `dest_id` = '%d' AND `id` = '%d'", mail_db, char_id, mail_id); StringBuf_Printf(&buf, " FROM `%s` WHERE `id` = '%d'", mail_db, mail_id);
if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf)) if( SQL_ERROR == Sql_Query(sql_handle, StringBuf_Value(&buf))
|| SQL_SUCCESS != Sql_NextRow(sql_handle) ) || SQL_SUCCESS != Sql_NextRow(sql_handle) )
@ -173,7 +173,7 @@ static bool mail_loadmessage(int char_id, int mail_id, struct mail_message* msg)
Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(msg->title, data, MAIL_TITLE_LENGTH); Sql_GetData(sql_handle, 5, &data, NULL); safestrncpy(msg->title, data, MAIL_TITLE_LENGTH);
Sql_GetData(sql_handle, 6, &data, NULL); safestrncpy(msg->body, data, MAIL_BODY_LENGTH); Sql_GetData(sql_handle, 6, &data, NULL); safestrncpy(msg->body, data, MAIL_BODY_LENGTH);
Sql_GetData(sql_handle, 7, &data, NULL); msg->timestamp = atoi(data); Sql_GetData(sql_handle, 7, &data, NULL); msg->timestamp = atoi(data);
Sql_GetData(sql_handle, 8, &data, NULL); msg->read = atoi(data); Sql_GetData(sql_handle, 8, &data, NULL); msg->status = atoi(data);
Sql_GetData(sql_handle, 9, &data, NULL); msg->zeny = atoi(data); Sql_GetData(sql_handle, 9, &data, NULL); msg->zeny = atoi(data);
Sql_GetData(sql_handle,10, &data, NULL); msg->item.amount = (short)atoi(data); Sql_GetData(sql_handle,10, &data, NULL); msg->item.amount = (short)atoi(data);
Sql_GetData(sql_handle,11, &data, NULL); msg->item.nameid = atoi(data); Sql_GetData(sql_handle,11, &data, NULL); msg->item.nameid = atoi(data);
@ -190,15 +190,6 @@ static bool mail_loadmessage(int char_id, int mail_id, struct mail_message* msg)
StringBuf_Destroy(&buf); StringBuf_Destroy(&buf);
Sql_FreeResult(sql_handle); Sql_FreeResult(sql_handle);
// this thing converts the database value (0,1,2) into a boolean yes/no
//TODO: provide decent enum instead of using 'magic' values
if (msg->read == 1)
{
msg->read = 0;
}
else
msg->read = 1;
return true; return true;
} }
@ -231,7 +222,7 @@ static void mapif_parse_Mail_requestinbox(int fd)
static void mapif_parse_Mail_read(int fd) static void mapif_parse_Mail_read(int fd)
{ {
int mail_id = RFIFOL(fd,2); int mail_id = RFIFOL(fd,2);
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `read_flag` = '2' WHERE `id` = '%d'", mail_db, mail_id) ) if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `read_flag` = '%d' WHERE `id` = '%d'", mail_db, MAIL_READED, mail_id) )
Sql_ShowDebug(sql_handle); Sql_ShowDebug(sql_handle);
} }
@ -265,7 +256,13 @@ static void mapif_Mail_getattach(int fd, int char_id, int mail_id)
{ {
struct mail_message msg; struct mail_message msg;
if( !mail_loadmessage(char_id, mail_id, &msg) ) if( !mail_loadmessage(mail_id, &msg) )
return;
if( msg.dest_id != char_id )
return;
if( msg.status != MAIL_READED )
return; return;
if( (msg.item.nameid < 1 || msg.item.amount < 1) && msg.zeny < 1 ) if( (msg.item.nameid < 1 || msg.item.amount < 1) && msg.zeny < 1 )
@ -294,7 +291,7 @@ static void mapif_parse_Mail_getattach(int fd)
static void mapif_Mail_delete(int fd, int char_id, int mail_id) static void mapif_Mail_delete(int fd, int char_id, int mail_id)
{ {
bool failed = false; bool failed = false;
if ( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) ) if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_DELETED, mail_id) )
{ {
Sql_ShowDebug(sql_handle); Sql_ShowDebug(sql_handle);
failed = true; failed = true;
@ -313,6 +310,26 @@ static void mapif_parse_Mail_delete(int fd)
mapif_Mail_delete(fd, RFIFOL(fd,2), RFIFOL(fd,6)); mapif_Mail_delete(fd, RFIFOL(fd,2), RFIFOL(fd,6));
} }
/*==========================================
* Report New Mail to Map Server
*------------------------------------------*/
static void mapif_Mail_new(int mail_id)
{
struct mail_message msg;
if( mail_loadmessage(mail_id, &msg) )
{
unsigned char buf[74];
WBUFW(buf,0) = 0x3849;
WBUFL(buf,2) = msg.dest_id;
WBUFL(buf,6) = mail_id;
memcpy(WBUFP(buf,10), msg.send_name, NAME_LENGTH);
memcpy(WBUFP(buf,34), msg.title, MAIL_TITLE_LENGTH);
mapif_sendall(buf, 74);
}
}
/*========================================== /*==========================================
* Return Mail * Return Mail
*------------------------------------------*/ *------------------------------------------*/
@ -321,9 +338,11 @@ static void mapif_Mail_return(int fd, int char_id, int mail_id)
struct mail_message msg; struct mail_message msg;
int new_mail = 0; int new_mail = 0;
if( mail_loadmessage(char_id, mail_id, &msg) ) if( mail_loadmessage(mail_id, &msg) )
{ {
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) ) if( msg.dest_id != char_id)
return;
else if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_RETURNED, mail_id) )
Sql_ShowDebug(sql_handle); Sql_ShowDebug(sql_handle);
else else
{ {
@ -339,18 +358,20 @@ static void mapif_Mail_return(int fd, int char_id, int mail_id)
snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title); snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title);
safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH); safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH);
msg.status = MAIL_NEW;
msg.timestamp = (unsigned int)calc_times(); msg.timestamp = (unsigned int)calc_times();
new_mail = mail_savemessage(&msg); new_mail = mail_savemessage(&msg);
mapif_Mail_new(new_mail);
} }
} }
WFIFOHEAD(fd,14); WFIFOHEAD(fd,11);
WFIFOW(fd,0) = 0x384c; WFIFOW(fd,0) = 0x384c;
WFIFOL(fd,2) = char_id; WFIFOL(fd,2) = char_id;
WFIFOL(fd,6) = mail_id; WFIFOL(fd,6) = mail_id;
WFIFOL(fd,10) = new_mail; WFIFOB(fd,10) = (new_mail == 0);
WFIFOSET(fd,14); WFIFOSET(fd,11);
} }
static void mapif_parse_Mail_return(int fd) static void mapif_parse_Mail_return(int fd)
@ -358,18 +379,16 @@ static void mapif_parse_Mail_return(int fd)
mapif_Mail_return(fd, RFIFOL(fd,2), RFIFOL(fd,6)); mapif_Mail_return(fd, RFIFOL(fd,2), RFIFOL(fd,6));
} }
/*==========================================
* Send Mail
*------------------------------------------*/
static void mapif_Mail_send(int fd, struct mail_message* msg) static void mapif_Mail_send(int fd, struct mail_message* msg)
{ {
int len = strlen(msg->title); WFIFOHEAD(fd,10);
WFIFOHEAD(fd,len);
WFIFOW(fd,0) = 0x384d; WFIFOW(fd,0) = 0x384d;
WFIFOW(fd,2) = len + 16; WFIFOL(fd,2) = msg->send_id;
WFIFOL(fd,4) = msg->send_id; WFIFOL(fd,6) = msg->id;
WFIFOL(fd,8) = msg->id; WFIFOSET(fd,10);
WFIFOL(fd,12) = msg->dest_id;
safestrncpy((char*)WFIFOP(fd,16), msg->title, len);
WFIFOSET(fd,WFIFOW(fd,2));
} }
static void mapif_parse_Mail_send(int fd) static void mapif_parse_Mail_send(int fd)
@ -381,9 +400,8 @@ static void mapif_parse_Mail_send(int fd)
if(RFIFOW(fd,2) != 8 + sizeof(struct mail_message)) if(RFIFOW(fd,2) != 8 + sizeof(struct mail_message))
return; return;
memcpy(&msg, RFIFOP(fd,8), sizeof(struct mail_message));
account_id = RFIFOL(fd,4); account_id = RFIFOL(fd,4);
memcpy(&msg, RFIFOP(fd,8), sizeof(struct mail_message));
// Try to find the Dest Char by Name // Try to find the Dest Char by Name
Sql_EscapeStringLen(sql_handle, esc_name, msg.dest_name, strnlen(msg.dest_name, NAME_LENGTH)); Sql_EscapeStringLen(sql_handle, esc_name, msg.dest_name, strnlen(msg.dest_name, NAME_LENGTH));
@ -403,13 +421,35 @@ static void mapif_parse_Mail_send(int fd)
Sql_FreeResult(sql_handle); Sql_FreeResult(sql_handle);
if( msg.dest_id > 0 ) if( msg.dest_id > 0 )
{
msg.status = MAIL_UNVERIFIED;
msg.id = mail_savemessage(&msg); msg.id = mail_savemessage(&msg);
}
else else
msg.id = 0; msg.id = 0;
mapif_Mail_send(fd, &msg); mapif_Mail_send(fd, &msg);
} }
static void mapif_parse_Mail_confirmation(int fd)
{
int mail_id = RFIFOL(fd,2);
bool fail = RFIFOB(fd,6);
if( fail )
{
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_INVALID, mail_id) )
Sql_ShowDebug(sql_handle);
}
else
{
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", mail_db, MAIL_NEW, mail_id) )
Sql_ShowDebug(sql_handle);
else
mapif_Mail_new(mail_id);
}
}
/*========================================== /*==========================================
* Packets From Map Server * Packets From Map Server
*------------------------------------------*/ *------------------------------------------*/
@ -423,6 +463,7 @@ int inter_mail_parse_frommap(int fd)
case 0x304b: mapif_parse_Mail_delete(fd); break; case 0x304b: mapif_parse_Mail_delete(fd); break;
case 0x304c: mapif_parse_Mail_return(fd); break; case 0x304c: mapif_parse_Mail_return(fd); break;
case 0x304d: mapif_parse_Mail_send(fd); break; case 0x304d: mapif_parse_Mail_send(fd); break;
case 0x304e: mapif_parse_Mail_confirmation(fd); break;
default: default:
return 0; return 0;
} }

View File

@ -54,7 +54,7 @@ int inter_send_packet_length[] = {
-1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, // 3810- -1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, // 3810-
35,-1,11,15, 34,29, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, // 3820- 35,-1,11,15, 34,29, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, // 3820-
10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, // 3830- 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, // 3830-
9, 9,-1, 0, 0, 0, 0, 0, -1, 0,-1,12, 14,-1, 0, 0, // 3840- 9, 9,-1, 0, 0, 0, 0, 0, -1,74,-1,11, 11,10, 0, 0, // 3840-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3850- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3850-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3860- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3860-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3870- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3870-
@ -66,7 +66,7 @@ int inter_recv_packet_length[] = {
6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010- 6,-1, 0, 0, 0, 0, 0, 0, 10,-1, 0, 0, 0, 0, 0, 0, // 3010-
-1, 6,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020- -1, 6,-1,14, 14,19, 6,-1, 14,14, 0, 0, 0, 0, 0, 0, // 3020-
-1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 14,19,186,-1, // 3030- -1, 6,-1,-1, 55,19, 6,-1, 14,-1,-1,-1, 14,19,186,-1, // 3030-
5, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 0, 0, // 3040- 5, 9, 0, 0, 0, 0, 0, 0, 7, 6,10,10, 10,-1, 7, 0, // 3040-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3050-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3060-
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3070- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 3070-

View File

@ -250,7 +250,7 @@ struct mail_message {
char title[MAIL_TITLE_LENGTH]; char title[MAIL_TITLE_LENGTH];
char body[MAIL_BODY_LENGTH]; char body[MAIL_BODY_LENGTH];
unsigned char read; short status;
unsigned int timestamp; // marks when the message was sent unsigned int timestamp; // marks when the message was sent
int zeny; int zeny;
@ -415,6 +415,16 @@ enum {
GBI_SKILLLV, // ギルドスキルLv GBI_SKILLLV, // ギルドスキルLv
}; };
enum {
MAIL_UNVERIFIED = -1,
MAIL_NEW,
MAIL_UNREAD,
MAIL_READED,
MAIL_DELETED,
MAIL_RETURNED,
MAIL_INVALID,
};
enum { enum {
GMI_POSITION =0, // メンバーの役職変更 GMI_POSITION =0, // メンバーの役職変更
GMI_EXP, GMI_EXP,

View File

@ -11300,6 +11300,77 @@ void clif_parse_AutoRevive(int fd, struct map_session_data *sd)
* By Zephyrus * By Zephyrus
*==========================================*/ *==========================================*/
/*------------------------------------------
* Reply to an Attachment operation
* 0 : From inventory to Attachment OK
* 1 : Fail to set the attachment
* 2 : Weight Problems (when get the attachment)
*------------------------------------------*/
void clif_Mail_attachment(int fd, unsigned char flag)
{
WFIFOHEAD(fd,packet_len(0x245));
WFIFOW(fd,0) = 0x245;
WFIFOB(fd,2) = flag;
WFIFOSET(fd,packet_len(0x245));
}
/*------------------------------------------
* Send Mail ack
* 0 : Message Send Ok
* 1 : Destination char not found
*------------------------------------------*/
void clif_Mail_send(int fd, bool fail)
{
WFIFOHEAD(fd,packet_len(0x249));
WFIFOW(fd,0) = 0x249;
WFIFOB(fd,2) = fail;
WFIFOSET(fd,packet_len(0x249));
}
/*------------------------------------------
* Delete Mail ack
* 0 : Delete ok
* 1 : Delete failed
*------------------------------------------*/
void clif_Mail_delete(int fd, int mail_id, short fail)
{
WFIFOHEAD(fd, packet_len(0x257));
WFIFOW(fd,0) = 0x257;
WFIFOL(fd,2) = mail_id;
WFIFOW(fd,6) = fail;
WFIFOSET(fd, packet_len(0x257));
}
/*------------------------------------------
* Return Mail ack
* 0 : Mail returned to the sender
* 1 : The mail does not exist
*------------------------------------------*/
void clif_Mail_return(int fd, int mail_id, short fail)
{
WFIFOHEAD(fd,packet_len(0x274));
WFIFOW(fd,0) = 0x274;
WFIFOL(fd,2) = mail_id;
WFIFOW(fd,6) = fail;
WFIFOSET(fd,packet_len(0x274));
}
/*------------------------------------------
* You have New Mail
*------------------------------------------*/
void clif_Mail_new(struct map_session_data *sd, int mail_id, const char *sender, const char *title)
{
int fd = sd->fd;
sd->mail.inbox.changed = true;
WFIFOHEAD(fd,packet_len(0x24a));
WFIFOW(fd,0) = 0x24a;
WFIFOL(fd,2) = mail_id;
memcpy(WFIFOP(fd,6), sender, NAME_LENGTH);
memcpy(WFIFOP(fd,30), title, MAIL_TITLE_LENGTH);
WFIFOSET(fd,packet_len(0x24a));
}
/*------------------------------------------ /*------------------------------------------
* Opens Mail Window on Client * Opens Mail Window on Client
*------------------------------------------*/ *------------------------------------------*/
@ -11331,25 +11402,26 @@ void clif_Mail_refreshinbox(struct map_session_data *sd)
{ {
msg = &md->msg[i]; msg = &md->msg[i];
if (msg->id < 1) if (msg->id < 1)
continue; // Deleted Message continue;
WFIFOL(fd,8+73*j) = msg->id; WFIFOL(fd,8+73*j) = msg->id;
memcpy(WFIFOP(fd,12+73*j), msg->title, MAIL_TITLE_LENGTH); memcpy(WFIFOP(fd,12+73*j), msg->title, MAIL_TITLE_LENGTH);
WFIFOB(fd,52+73*j) = msg->read; WFIFOB(fd,52+73*j) = (msg->status == MAIL_UNREAD);
memcpy(WFIFOP(fd,53+73*j), msg->send_name, NAME_LENGTH); memcpy(WFIFOP(fd,53+73*j), msg->send_name, NAME_LENGTH);
WFIFOL(fd,77+73*j) = msg->timestamp; WFIFOL(fd,77+73*j) = msg->timestamp;
j++; j++;
} }
WFIFOSET(fd,len); WFIFOSET(fd,len);
} }
/*------------------------------------------ /*------------------------------------------
* Client Request Inbox List * Client Request Inbox List
*------------------------------------------*/ *------------------------------------------*/
void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd) void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd)
{ {
struct mail_data *md; struct mail_data *md;
nullpo_retv(sd); nullpo_retv(sd);
md = &sd->mail.inbox; md = &sd->mail.inbox;
if( md->amount < MAIL_MAX_INBOX && (md->full || md->changed) ) if( md->amount < MAIL_MAX_INBOX && (md->full || md->changed) )
@ -11371,6 +11443,7 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id)
ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
if( i == MAIL_MAX_INBOX ) if( i == MAIL_MAX_INBOX )
{ {
clif_Mail_return(sd->fd, mail_id, 1); // Mail don't exists
ShowWarning("clif_parse_Mail_read: account %d trying to read a message not the inbox.\n", sd->status.account_id); ShowWarning("clif_parse_Mail_read: account %d trying to read a message not the inbox.\n", sd->status.account_id);
return; return;
} }
@ -11397,36 +11470,26 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id)
WFIFOL(fd,72) = 0; WFIFOL(fd,72) = 0;
WFIFOL(fd,76) = msg->zeny; WFIFOL(fd,76) = msg->zeny;
if (item->nameid) if( item->nameid && (data = itemdb_search(item->nameid)) != NULL )
{ {
WFIFOL(fd,80) = item->amount; WFIFOL(fd,80) = item->amount;
if ((data = itemdb_search(item->nameid)) != NULL) WFIFOW(fd,84) = (data->view_id)?data->view_id:item->nameid;
WFIFOW(fd,84) = (data->view_id)?data->view_id:item->nameid;
else
ShowWarning("clif_parse_Mail_read: Invalid attachment on message %d.\n", msg->id);
WFIFOW(fd,86) = data->type; WFIFOW(fd,86) = data->type;
} WFIFOB(fd,88) = item->identify;
else WFIFOB(fd,89) = item->attribute;
{ WFIFOB(fd,90) = item->refine;
WFIFOL(fd,80) = 0; WFIFOW(fd,91) = item->card[0];
WFIFOW(fd,84) = 0; WFIFOW(fd,93) = item->card[1];
WFIFOW(fd,86) = 0; WFIFOW(fd,95) = item->card[2];
WFIFOW(fd,97) = item->card[3];
} }
WFIFOB(fd,88) = item->identify;
WFIFOB(fd,89) = item->attribute;
WFIFOB(fd,90) = item->refine;
WFIFOW(fd,91) = item->card[0];
WFIFOW(fd,93) = item->card[1];
WFIFOW(fd,95) = item->card[2];
WFIFOW(fd,97) = item->card[3];
WFIFOB(fd,99) = (unsigned char)msg_len; WFIFOB(fd,99) = (unsigned char)msg_len;
safestrncpy((char*)WFIFOP(fd,100), msg->body, msg_len); safestrncpy((char*)WFIFOP(fd,100), msg->body, msg_len);
WFIFOSET(fd,len); WFIFOSET(fd,len);
if (!msg->read) { if (msg->status == MAIL_UNREAD) {
msg->read = 1; msg->status = MAIL_READED;
intif_Mail_read(mail_id); intif_Mail_read(mail_id);
clif_parse_Mail_refreshinbox(fd, sd); clif_parse_Mail_refreshinbox(fd, sd);
} }
@ -11465,10 +11528,7 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
weight = data->weight * sd->mail.inbox.msg[i].item.amount; weight = data->weight * sd->mail.inbox.msg[i].item.amount;
if (weight > sd->max_weight - sd->weight) if (weight > sd->max_weight - sd->weight)
{ {
WFIFOHEAD(fd,packet_len(0x245)); clif_Mail_attachment(fd, 2);
WFIFOW(fd,0) = 0x245;
WFIFOB(fd,2) = 2;
WFIFOSET(fd,packet_len(0x245));
return; return;
} }
} }
@ -11477,39 +11537,12 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
memset(&sd->mail.inbox.msg[i].item, 0, sizeof(struct item)); memset(&sd->mail.inbox.msg[i].item, 0, sizeof(struct item));
clif_Mail_read(sd, mail_id); clif_Mail_read(sd, mail_id);
// Send the request for Char Server to delete the attachment
// If it is done, the client will receive it.
intif_Mail_getattach(sd->status.char_id, mail_id); intif_Mail_getattach(sd->status.char_id, mail_id);
} }
/*------------------------------------------ /*------------------------------------------
* Delete Message * Delete Message
*------------------------------------------*/ *------------------------------------------*/
void clif_Mail_delete(struct map_session_data *sd, int mail_id, bool failed)
{
int fd = sd->fd;
if( !failed )
{
int i;
ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
if( i < MAIL_MAX_INBOX )
{
memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
sd->mail.inbox.amount--;
}
if( sd->mail.inbox.full )
intif_Mail_requestinbox(sd->status.char_id, 1); // Reload the Mail Inbox
}
WFIFOHEAD(fd, packet_len(0x257));
WFIFOW(fd,0) = 0x257;
WFIFOL(fd,2) = mail_id;
WFIFOW(fd,6) = failed;
WFIFOSET(fd, packet_len(0x257));
}
void clif_parse_Mail_delete(int fd, struct map_session_data *sd) void clif_parse_Mail_delete(int fd, struct map_session_data *sd)
{ {
int i, mail_id = RFIFOL(fd,2); int i, mail_id = RFIFOL(fd,2);
@ -11522,25 +11555,13 @@ void clif_parse_Mail_delete(int fd, struct map_session_data *sd)
if( (msg->item.nameid > 0 && msg->item.amount > 0) || msg->zeny > 0 ) if( (msg->item.nameid > 0 && msg->item.amount > 0) || msg->zeny > 0 )
{ {
clif_Mail_delete(sd, mail_id, 1); clif_Mail_delete(sd->fd, mail_id, 1);
return; return;
} }
intif_Mail_delete(sd->status.char_id, mail_id); intif_Mail_delete(sd->status.char_id, mail_id);
} }
} }
/*------------------------------------------
* You have Mail Message
*------------------------------------------*/
void clif_Mail_new(int fd, int mail_id, const char *sender, const char *title)
{
WFIFOHEAD(fd,packet_len(0x24a));
WFIFOW(fd,0) = 0x24a;
WFIFOL(fd,2) = mail_id;
memcpy(WFIFOP(fd,6), sender, NAME_LENGTH);
memcpy(WFIFOP(fd,30), title, MAIL_TITLE_LENGTH);
WFIFOSET(fd,packet_len(0x24a));
}
/*------------------------------------------ /*------------------------------------------
* Return Mail Message * Return Mail Message
@ -11553,38 +11574,8 @@ void clif_parse_Mail_return(int fd, struct map_session_data *sd)
ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id); ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
if (i < MAIL_MAX_INBOX) if (i < MAIL_MAX_INBOX)
intif_Mail_return(sd->status.char_id, mail_id); intif_Mail_return(sd->status.char_id, mail_id);
} else
clif_Mail_return(sd->fd, mail_id, 1);
void clif_Mail_return(struct map_session_data *sd, int mail_id, int new_mail)
{
int fd = sd->fd;
if (new_mail > 0)
{
int i;
ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
if (i < MAIL_MAX_INBOX)
{
struct map_session_data *rd = map_charid2sd(sd->mail.inbox.msg[i].send_id);
if (rd)
{
char title[MAIL_TITLE_LENGTH];
snprintf(title, MAIL_TITLE_LENGTH, "RE:%s", sd->mail.inbox.msg[i].title);
rd->mail.inbox.changed = 1;
clif_Mail_new(rd->fd, new_mail, sd->status.name, title);
}
memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
sd->mail.inbox.amount--;
}
}
WFIFOHEAD(fd,packet_len(0x274));
WFIFOW(fd,0) = 0x274;
WFIFOL(fd,2) = mail_id;
WFIFOW(fd,6) = (new_mail > 0)?0:1;
WFIFOSET(fd,packet_len(0x274));
} }
/*------------------------------------------ /*------------------------------------------
@ -11594,7 +11585,7 @@ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd)
{ {
int idx = RFIFOW(fd,2); int idx = RFIFOW(fd,2);
int amount = RFIFOL(fd,4); int amount = RFIFOL(fd,4);
char flag; unsigned char flag;
nullpo_retv(sd); nullpo_retv(sd);
if (idx < 0 || amount < 0) if (idx < 0 || amount < 0)
@ -11602,12 +11593,7 @@ void clif_parse_Mail_setattach(int fd, struct map_session_data *sd)
flag = mail_setitem(sd, idx, amount); flag = mail_setitem(sd, idx, amount);
if (flag > -1) if (flag > -1)
{ clif_Mail_attachment(fd,flag);
WFIFOHEAD(fd,packet_len(0x245));
WFIFOW(fd,0) = 0x245;
WFIFOB(fd,2) = flag;
WFIFOSET(fd,packet_len(0x245));
}
} }
/*------------------------------------------ /*------------------------------------------
@ -11624,16 +11610,6 @@ void clif_parse_Mail_winopen(int fd, struct map_session_data *sd)
mail_removezeny(sd, 0); mail_removezeny(sd, 0);
} }
/*------------------------------------------
* Send Mail
*------------------------------------------*/
void clif_Mail_send(int fd, unsigned char flag)
{
WFIFOHEAD(fd,packet_len(0x249));
WFIFOW(fd,0) = 0x249;
WFIFOB(fd,2) = flag;
WFIFOSET(fd,packet_len(0x249));
}
/// S 0248 <packet len>.w <nick>.24B <title>.40B <body len>.B <message>.?B /// S 0248 <packet len>.w <nick>.24B <title>.40B <body len>.B <message>.?B
void clif_parse_Mail_send(int fd, struct map_session_data *sd) void clif_parse_Mail_send(int fd, struct map_session_data *sd)
@ -11642,6 +11618,9 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd)
int body_len; int body_len;
nullpo_retv(sd); nullpo_retv(sd);
if( sd->state.trading )
return;
if( RFIFOW(fd,2) < 69 ) { if( RFIFOW(fd,2) < 69 ) {
ShowWarning("Invalid Msg Len from account %d.\n", sd->status.account_id); ShowWarning("Invalid Msg Len from account %d.\n", sd->status.account_id);
return; return;
@ -11681,7 +11660,7 @@ void clif_parse_Mail_send(int fd, struct map_session_data *sd)
msg.timestamp = (int)mail_calctimes(); msg.timestamp = (int)mail_calctimes();
intif_Mail_send(sd->status.account_id, &msg); intif_Mail_send(sd->status.account_id, &msg);
sd->cansendmail_tick = gettick() + 1000; // 5 Seconds flood Protection sd->cansendmail_tick = gettick() + 1000; // 1 Second flood Protection
} }
#endif #endif

View File

@ -386,10 +386,10 @@ int do_init_clif(void);
// MAIL SYSTEM // MAIL SYSTEM
void clif_Mail_openmail(int fd); void clif_Mail_openmail(int fd);
void clif_Mail_read(struct map_session_data *sd, int mail_id); void clif_Mail_read(struct map_session_data *sd, int mail_id);
void clif_Mail_delete(struct map_session_data *sd, int mail_id, bool failed); void clif_Mail_delete(int fd, int mail_id, short fail);
void clif_Mail_return(struct map_session_data *sd, int mail_id, int new_mail); void clif_Mail_return(int fd, int mail_id, short fail);
void clif_Mail_send(int fd, unsigned char flag); void clif_Mail_send(int fd, bool fail);
void clif_Mail_new(int fd, int mail_id, const char *sender, const char *title); void clif_Mail_new(struct map_session_data *sd, int mail_id, const char *sender, const char *title);
void clif_Mail_refreshinbox(struct map_session_data *sd); void clif_Mail_refreshinbox(struct map_session_data *sd);
#endif #endif

View File

@ -34,7 +34,7 @@ static const int packet_len_table[]={
-1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810 -1, 7, 0, 0, 0, 0, 0, 0, -1,11, 0, 0, 0, 0, 0, 0, //0x3810
39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820 39,-1,15,15, 14,19, 7,-1, 0, 0, 0, 0, 0, 0, 0, 0, //0x3820
10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830 10,-1,15, 0, 79,19, 7,-1, 0,-1,-1,-1, 14,67,186,-1, //0x3830
9, 9,-1,14, 0, 0, 0, 0, -1, 0,-1,11, 14,-1, 0, 0, //0x3840 9, 9,-1,14, 0, 0, 0, 0, -1,74,-1,11, 11,10, 0, 0, //0x3840
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -1538,7 +1538,7 @@ int intif_Mail_getattach(int char_id, int mail_id)
int intif_parse_Mail_getattach(int fd) int intif_parse_Mail_getattach(int fd)
{ {
struct map_session_data *sd; struct map_session_data *sd;
struct item *item; struct item item;
int zeny = RFIFOL(fd,8); int zeny = RFIFOL(fd,8);
sd = map_charid2sd( RFIFOL(fd,4) ); sd = map_charid2sd( RFIFOL(fd,4) );
@ -1566,12 +1566,9 @@ int intif_parse_Mail_getattach(int fd)
clif_updatestatus(sd, SP_ZENY); clif_updatestatus(sd, SP_ZENY);
} }
item = (struct item*)aCalloc(sizeof(struct item), 1); memcpy(&item, RFIFOP(fd,12), sizeof(struct item));
memcpy(item, RFIFOP(fd,12), sizeof(struct item)); if (item.nameid > 0 && item.amount > 0)
if (item->nameid > 0 && item->amount > 0) pc_additem(sd, &item, item.amount);
pc_additem(sd, item, item->amount);
aFree(item);
return 0; return 0;
} }
@ -1609,7 +1606,21 @@ int intif_parse_Mail_delete(int fd)
if (sd->state.finalsave) if (sd->state.finalsave)
return 1; return 1;
clif_Mail_delete(sd, mail_id, failed); if (!failed)
{
int i;
ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
if( i < MAIL_MAX_INBOX )
{
memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
sd->mail.inbox.amount--;
}
if( sd->mail.inbox.full )
intif_Mail_requestinbox(sd->status.char_id, 1); // Free space is available for new mails
}
clif_Mail_delete(sd->fd, mail_id, failed);
return 0; return 0;
} }
/*------------------------------------------ /*------------------------------------------
@ -1632,19 +1643,31 @@ int intif_Mail_return(int char_id, int mail_id)
int intif_parse_Mail_return(int fd) int intif_parse_Mail_return(int fd)
{ {
struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2)); struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
int mail_id = RFIFOL(fd,6), new_mail = RFIFOL(fd,10); int mail_id = RFIFOL(fd,6);
short fail = RFIFOB(fd,10);
if (sd == NULL) if( sd == NULL )
{ {
if (battle_config.error_log) if (battle_config.error_log)
ShowError("intif_parse_Mail_return: char not found %d\n",RFIFOL(fd,2)); ShowError("intif_parse_Mail_return: char not found %d\n",RFIFOL(fd,2));
return 1; return 1;
} }
if (sd->state.finalsave) if( sd->state.finalsave )
return 1; return 1;
clif_Mail_return(sd, mail_id, new_mail); if( !fail )
{
int i;
ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
if (i < MAIL_MAX_INBOX)
{
memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
sd->mail.inbox.amount--;
}
}
clif_Mail_return(sd->fd, mail_id, fail);
return 0; return 0;
} }
/*------------------------------------------ /*------------------------------------------
@ -1669,44 +1692,49 @@ int intif_Mail_send(int account_id, struct mail_message *msg)
int intif_parse_Mail_send(int fd) int intif_parse_Mail_send(int fd)
{ {
struct map_session_data* sd = map_charid2sd(RFIFOL(fd,4)); struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
int mail_id = RFIFOL(fd,8); int mail_id = RFIFOL(fd,6);
int dest_id = RFIFOL(fd,12); bool fail = false;
struct map_session_data* rd;
if( mail_id == 0 ) if( mail_id > 0 )
{// nick->charid lookup failed, no such char
// Return the items to the owner
mail_removeitem(sd, 0);
mail_removezeny(sd, 0);
clif_Mail_send(sd->fd, 1); // failed
return 0;
}
if( sd == NULL )
{// original sender disconnected, item cannot be deleted!
if( battle_config.error_log )
ShowError("intif_parse_Mail_send: char not found %d\n",RFIFOL(fd,2));
// the best thing we can do at this point is requesting removal of the mail with the duped item
intif_Mail_delete(dest_id, mail_id);
return 0;
}
// physically delete the item
mail_removeitem(sd, 1);
mail_removezeny(sd, 1);
clif_Mail_send(sd->fd, 0); // success
// notify recipient about new mail
rd = map_charid2sd(dest_id);
if( rd != NULL )
{ {
char title[MAIL_TITLE_LENGTH]; if( sd == NULL )
memcpy(title, RFIFOP(fd,16), RFIFOW(fd,2) - 16); fail = true;
rd->mail.inbox.changed = 1; if( !mail_checkattach(sd) )
clif_Mail_new(rd->fd, mail_id, sd->status.name, title); {
fail = true;
mail_removeitem(sd, 0);
mail_removezeny(sd, 0);
}
WFIFOHEAD(inter_fd,7);
WFIFOW(inter_fd,0) = 0x304e;
WFIFOL(inter_fd,2) = mail_id;
WFIFOB(inter_fd,6) = fail;
WFIFOSET(inter_fd,7);
clif_Mail_send(sd->fd, fail);
}
else
clif_Mail_send(sd->fd, true);
return 0;
}
int intif_parse_Mail_new(int fd)
{
struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
if( sd != NULL )
{
char sender_name[NAME_LENGTH], title[MAIL_TITLE_LENGTH];
int mail_id = RFIFOL(fd,6);
safestrncpy(sender_name, RFIFOP(fd,10), NAME_LENGTH);
safestrncpy(title, RFIFOP(fd,34), MAIL_TITLE_LENGTH);
clif_Mail_new(sd, mail_id, sender_name, title);
} }
return 0; return 0;
@ -1787,6 +1815,7 @@ int intif_parse(int fd)
// Mail System // Mail System
#ifndef TXT_ONLY #ifndef TXT_ONLY
case 0x3848: intif_parse_Mail_inboxreceived(fd); break; case 0x3848: intif_parse_Mail_inboxreceived(fd); break;
case 0x3849: intif_parse_Mail_new(fd); break;
case 0x384a: intif_parse_Mail_getattach(fd); break; case 0x384a: intif_parse_Mail_getattach(fd); break;
case 0x384b: intif_parse_Mail_delete(fd); break; case 0x384b: intif_parse_Mail_delete(fd); break;
case 0x384c: intif_parse_Mail_return(fd); break; case 0x384c: intif_parse_Mail_return(fd); break;

View File

@ -31,6 +31,7 @@ int mail_removeitem(struct map_session_data *sd, short flag)
clif_additem(sd, sd->mail.index, sd->mail.amount, 0); clif_additem(sd, sd->mail.index, sd->mail.amount, 0);
} }
sd->mail.nameid = 0;
sd->mail.index = 0; sd->mail.index = 0;
sd->mail.amount = 0; sd->mail.amount = 0;
return 1; return 1;
@ -49,10 +50,8 @@ int mail_removezeny(struct map_session_data *sd, short flag)
return 1; return 1;
} }
char mail_setitem(struct map_session_data *sd, int idx, int amount) unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount)
{ {
nullpo_retr(-1,sd);
if (idx == 0) if (idx == 0)
{ // Zeny Transfer { // Zeny Transfer
if (amount < 0) if (amount < 0)
@ -69,15 +68,15 @@ char mail_setitem(struct map_session_data *sd, int idx, int amount)
mail_removeitem(sd, 0); mail_removeitem(sd, 0);
if( idx < 0 || idx > MAX_INVENTORY ) if( idx < 0 || idx > MAX_INVENTORY )
return 2; return 1;
if( amount < 0 || amount > sd->status.inventory[idx].amount ) if( amount < 0 || amount > sd->status.inventory[idx].amount )
return 2; return 1;
if( itemdb_isdropable(&sd->status.inventory[idx], pc_isGM(sd)) == 0 ) if( !itemdb_isdropable(&sd->status.inventory[idx], pc_isGM(sd)) )
return 2; return 1;
sd->mail.index = idx; sd->mail.index = idx;
sd->mail.nameid = sd->status.inventory[idx].nameid;
sd->mail.amount = amount; sd->mail.amount = amount;
clif_delitem(sd, idx, amount); clif_delitem(sd, idx, amount);
return 0; return 0;
@ -86,7 +85,7 @@ char mail_setitem(struct map_session_data *sd, int idx, int amount)
return -1; return -1;
} }
int mail_getattach(struct map_session_data *sd, struct mail_message *msg) bool mail_getattach(struct map_session_data *sd, struct mail_message *msg)
{ {
int n; int n;
@ -94,13 +93,16 @@ int mail_getattach(struct map_session_data *sd, struct mail_message *msg)
nullpo_retr(0,msg); nullpo_retr(0,msg);
if( sd->mail.zeny < 0 || sd->mail.zeny > sd->status.zeny ) if( sd->mail.zeny < 0 || sd->mail.zeny > sd->status.zeny )
return 0; return false;
n = sd->mail.index; n = sd->mail.index;
if( sd->mail.amount ) if( sd->mail.amount )
{ {
if( sd->status.inventory[n].nameid != sd->mail.nameid )
return false;
if( sd->status.inventory[n].amount < sd->mail.amount ) if( sd->status.inventory[n].amount < sd->mail.amount )
return 0; return false;
memcpy(&msg->item, &sd->status.inventory[n], sizeof(struct item)); memcpy(&msg->item, &sd->status.inventory[n], sizeof(struct item));
msg->item.amount = sd->mail.amount; msg->item.amount = sd->mail.amount;
@ -108,7 +110,29 @@ int mail_getattach(struct map_session_data *sd, struct mail_message *msg)
msg->zeny = sd->mail.zeny; msg->zeny = sd->mail.zeny;
return 1; return true;
}
bool mail_checkattach(struct map_session_data *sd)
{
nullpo_retr(false,sd);
if( sd->mail.zeny > 0 && sd->status.zeny < sd->status.zeny )
return false;
if( sd->mail.amount > 0 )
{
if( sd->status.inventory[sd->mail.index].nameid != sd->mail.nameid )
return false;
if( sd->status.inventory[sd->mail.index].amount < sd->mail.amount )
return false;
}
mail_removeitem(sd,1);
mail_removezeny(sd,1);
return true;
} }
int mail_openmail(struct map_session_data *sd) int mail_openmail(struct map_session_data *sd)

View File

@ -10,8 +10,9 @@ time_t mail_calctimes(void);
int mail_removeitem(struct map_session_data *sd, short flag); int mail_removeitem(struct map_session_data *sd, short flag);
int mail_removezeny(struct map_session_data *sd, short flag); int mail_removezeny(struct map_session_data *sd, short flag);
char mail_setitem(struct map_session_data *sd, int idx, int amount); unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount);
int mail_getattach(struct map_session_data *sd, struct mail_message *msg); bool mail_getattach(struct map_session_data *sd, struct mail_message *msg);
bool mail_checkattach(struct map_session_data *sd);
int mail_openmail(struct map_session_data *sd); int mail_openmail(struct map_session_data *sd);
#endif /* _MAIL_H_ */ #endif /* _MAIL_H_ */

View File

@ -803,6 +803,7 @@ struct map_session_data {
// Mail System [Zephyrus] // Mail System [Zephyrus]
struct { struct {
short nameid;
int index, amount, zeny; int index, amount, zeny;
struct mail_data inbox; struct mail_data inbox;
} mail; } mail;