static void mapif_Mail_getattach(int fd, int char_id, int mail_id) { struct mail_message msg; if( !mail_loadmessage(mail_id, &msg) ) return; if( msg.dest_id != char_id ) return; if( msg.status != MAIL_READ ) return; if( (msg.item.nameid < 1 || msg.item.amount < 1) && msg.zeny < 1 ) return; // No Attachment if( !mail_DeleteAttach(mail_id) ) return; WFIFOHEAD(fd, sizeof(struct item) + 12); WFIFOW(fd,0) = 0x384a; WFIFOW(fd,2) = sizeof(struct item) + 12; WFIFOL(fd,4) = char_id; WFIFOL(fd,8) = (msg.zeny > 0)?msg.zeny:0; memcpy(WFIFOP(fd,12), &msg.item, sizeof(struct item)); WFIFOSET(fd,WFIFOW(fd,2)); }
static void mapif_Mail_getattach(int fd, int char_id, int mail_id, int type) { struct mail_message msg; if( !(type&MAIL_ATT_ALL) ) return; if( !mail_loadmessage(mail_id, &msg) ) return; if( msg.dest_id != char_id ) return; if( msg.status != MAIL_READ ) return; if( type&MAIL_ATT_ZENY ) { if( msg.zeny > 0 ) { if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `zeny` = 0 WHERE `id` = '%d'", mail_db, mail_id) ) { Sql_ShowDebug(sql_handle); return; } } else type &= ~MAIL_ATT_ZENY; } if( type&MAIL_ATT_ITEM ) { int i; ARR_FIND(0, MAIL_MAX_ITEM, i, (msg.item[i].nameid > 0 && msg.item[i].amount > 0)); if( i == MAIL_MAX_ITEM ) // No item was found type &= ~MAIL_ATT_ITEM; else { if( !mail_DeleteAttach(mail_id) ) return; } } if( type == MAIL_ATT_NONE ) return; // No Attachment WFIFOHEAD(fd,sizeof(struct item) * MAIL_MAX_ITEM + 16); WFIFOW(fd,0) = 0x384a; WFIFOW(fd,2) = sizeof(struct item) * MAIL_MAX_ITEM + 16; WFIFOL(fd,4) = char_id; WFIFOL(fd,8) = mail_id; if( type&MAIL_ATT_ZENY ) WFIFOL(fd,12) = msg.zeny; else WFIFOL(fd,12) = 0; if( type&MAIL_ATT_ITEM ) memcpy(WFIFOP(fd,16), &msg.item, sizeof(struct item) * MAIL_MAX_ITEM); else memset(WFIFOP(fd,16), 0, sizeof(struct item) * MAIL_MAX_ITEM); WFIFOSET(fd,WFIFOW(fd,2)); }
int mail_fromsql(uint32 char_id, struct mail_data* md) { int i; char *data; memset(md, 0, sizeof(struct mail_data)); md->amount = 0; md->full = false; // First we prefill the msg ids if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id` FROM `%s` WHERE `dest_id`='%d' AND `status` < 3 ORDER BY `id` LIMIT %d", schema_config.mail_db, char_id, MAIL_MAX_INBOX + 1) ){ Sql_ShowDebug(sql_handle); return 0; } md->full = (Sql_NumRows(sql_handle) > MAIL_MAX_INBOX); for( i = 0; i < MAIL_MAX_INBOX && SQL_SUCCESS == Sql_NextRow(sql_handle); i++ ){ Sql_GetData(sql_handle, 0, &data, NULL); md->msg[i].id = atoi(data); } md->amount = i; Sql_FreeResult(sql_handle); // Now we load them for( i = 0; i < md->amount; i++ ){ if( !mail_loadmessage( md->msg[i].id, &md->msg[i] ) ){ return 0; } } md->unchecked = 0; md->unread = 0; for (i = 0; i < md->amount; i++) { struct mail_message *msg = &md->msg[i]; if( msg->status == MAIL_NEW ) { if ( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `status` = '%d' WHERE `id` = '%d'", schema_config.mail_db, MAIL_UNREAD, msg->id) ) Sql_ShowDebug(sql_handle); msg->status = MAIL_UNREAD; md->unchecked++; } else if ( msg->status == MAIL_UNREAD ) md->unread++; } ShowInfo("mail load complete from DB - id: %d (total: %d)\n", char_id, md->amount); return 1; }
/*========================================== * Return Mail *------------------------------------------*/ void mapif_Mail_return(int fd, uint32 char_id, int mail_id) { struct mail_message msg; int new_mail = 0; if( mail_loadmessage(mail_id, &msg) ) { if( msg.dest_id != char_id) return; else if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", schema_config.mail_db, mail_id) || SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", schema_config.mail_attachment_db, mail_id) ) Sql_ShowDebug(sql_handle); // If it was not sent by the server, since we do not want to return mails to the server else if( msg.send_id != 0 ) { char temp_[MAIL_TITLE_LENGTH + 3]; // swap sender and receiver SWAP(msg.send_id, msg.dest_id); safestrncpy(temp_, msg.send_name, NAME_LENGTH); safestrncpy(msg.send_name, msg.dest_name, NAME_LENGTH); safestrncpy(msg.dest_name, temp_, NAME_LENGTH); // set reply message title snprintf(temp_, sizeof(temp_), "RE:%s", msg.title); safestrncpy(msg.title, temp_, sizeof(temp_)); msg.status = MAIL_NEW; msg.type = MAIL_INBOX_RETURNED; msg.timestamp = time(NULL); new_mail = mail_savemessage(&msg); mapif_Mail_new(&msg); } } // Only if the request came from a map-server and was not timer triggered for an offline character if( fd <= 0 ){ return; } WFIFOHEAD(fd,11); WFIFOW(fd,0) = 0x384c; WFIFOL(fd,2) = char_id; WFIFOL(fd,6) = mail_id; WFIFOB(fd,10) = (new_mail == 0); WFIFOSET(fd,11); }
/*========================================== * Return Mail *------------------------------------------*/ static void mapif_Mail_return(int fd, int char_id, int mail_id) { struct mail_message msg; int new_mail = 0; if( mail_loadmessage(mail_id, &msg) ) { if( msg.dest_id != char_id) return; else if( SQL_ERROR == SQL->Query(sql_handle, "DELETE FROM `%s` WHERE `id` = '%d'", mail_db, mail_id) ) Sql_ShowDebug(sql_handle); else { char temp_[MAIL_TITLE_LENGTH]; // swap sender and receiver swap(msg.send_id, msg.dest_id); safestrncpy(temp_, msg.send_name, NAME_LENGTH); safestrncpy(msg.send_name, msg.dest_name, NAME_LENGTH); safestrncpy(msg.dest_name, temp_, NAME_LENGTH); // set reply message title snprintf(temp_, MAIL_TITLE_LENGTH, "RE:%s", msg.title); safestrncpy(msg.title, temp_, MAIL_TITLE_LENGTH); msg.status = MAIL_NEW; msg.timestamp = time(NULL); new_mail = mail_savemessage(&msg); mapif_Mail_new(&msg); } } WFIFOHEAD(fd,11); WFIFOW(fd,0) = 0x384c; WFIFOL(fd,2) = char_id; WFIFOL(fd,6) = mail_id; WFIFOB(fd,10) = (new_mail == 0); WFIFOSET(fd,11); }