diff options
Diffstat (limited to 'src/map/mail.c')
-rw-r--r-- | src/map/mail.c | 375 |
1 files changed, 66 insertions, 309 deletions
diff --git a/src/map/mail.c b/src/map/mail.c index 6e6dc0a91..371e11f8e 100644 --- a/src/map/mail.c +++ b/src/map/mail.c @@ -3,365 +3,122 @@ #ifndef TXT_ONLY -#include "../common/strlib.h" -#include "../common/socket.h" -#include "../common/timer.h" #include "../common/nullpo.h" -#include "../common/showmsg.h" -#include "map.h" +#include "mail.h" +#include "itemdb.h" #include "clif.h" -#include "chrif.h" -#include "intif.h" -#include "atcommand.h" #include "pc.h" -#include "mail.h" -#include <stdio.h> -#include <stdlib.h> +#include <time.h> #include <string.h> - -int MAIL_CHECK_TIME = 120000; -int mail_timer; - -/// type: 0 - mail check at login, silent if there aren't any new messages -/// 1 - @checkmail, just print the number of messages -/// 2 - @listmail, shows both read and unread messages -/// 3 - @listnewmail, shows only unread messages -int mail_check(struct map_session_data* sd, int type) +time_t mail_calctimes(void) { - int i = 0, new_ = 0, priority = 0; // counters - char message[80]; - - nullpo_retr (0, sd); - - // retrieve all existing messages for this player - if( SQL_ERROR == Sql_Query(mail_handle, "SELECT `message_id`,`to_account_id`,`from_char_name`,`read_flag`,`priority`,`check_flag` FROM `%s` WHERE `to_account_id` = %d ORDER by `message_id`", mail_db, sd->status.account_id) ) - { - Sql_ShowDebug(mail_handle); - return 0; - } - - if( Sql_NumRows(mail_handle) == 0) - { - clif_displaymessage(sd->fd, msg_txt(516)); // "You have no messages." - Sql_FreeResult(mail_handle); - return 0; - } - - while( SQL_SUCCESS == Sql_NextRow(mail_handle) ) - { - char* data; - int message_id; - int to_account_id; - char from_char_name[NAME_LENGTH]; - bool read_flag, priority_flag, check_flag; - - Sql_GetData(mail_handle, 0, &data, NULL); message_id = atoi(data); - Sql_GetData(mail_handle, 1, &data, NULL); to_account_id = atoi(data); - Sql_GetData(mail_handle, 2, &data, NULL); safestrncpy(from_char_name, data, sizeof(from_char_name)); - Sql_GetData(mail_handle, 3, &data, NULL); read_flag = (bool) atoi(data); - Sql_GetData(mail_handle, 4, &data, NULL); priority_flag = (bool) atoi(data); - Sql_GetData(mail_handle, 5, &data, NULL); check_flag = (bool) atoi(data); - - i++; - - if( !check_flag ) - { - // mark this message as checked - if( SQL_ERROR == Sql_Query(mail_handle, "UPDATE `%s` SET `check_flag` = 1 WHERE `message_id` = %d", mail_db, message_id) ) - Sql_ShowDebug(mail_handle); - } - - if( !read_flag ) - { - new_++; - if(priority_flag) - priority++; - - if( type == 2 || type == 3 ) - { - if( priority_flag ) - { - snprintf(message, 80, msg_txt(511), i, from_char_name); - clif_displaymessage(sd->fd, message); // "%d - From : %s (New - Priority)" - } - else - { - snprintf(message, 80, msg_txt(512), i, from_char_name); - clif_displaymessage(sd->fd, message); // "%d - From : %s (New)" - } - } - } - else if( type == 2 ) - { - snprintf(message, 80, msg_txt(513), i, from_char_name); - clif_displaymessage(sd->fd, message); // "%d - From : %s" - } - } - - Sql_FreeResult(mail_handle); - - if( new_ > 0 && (type == 0 || type == 1) ) - { - sprintf(message, msg_txt(514), new_); - clif_displaymessage(sd->fd, message); // "You have %d unread messages." - if (priority > 0) - { - sprintf(message, msg_txt(515), priority); - clif_displaymessage(sd->fd, message); // "You have %d unread priority messages." - } - } - if( new_ == 0 && type != 0 ) - { - clif_displaymessage(sd->fd, msg_txt(516)); // "You have no unread messages." - } - - return 0; + time_t temp = time(NULL); + return mktime(localtime(&temp)); } -/// displays the selected message -int mail_read(struct map_session_data* sd, int index) +int mail_removeitem(struct map_session_data *sd, short flag) { - char* data; - int message_id; - char from_char_name[NAME_LENGTH]; - char message[80]; - bool read_flag, priority_flag, check_flag; - char output[100]; - - nullpo_retr(0, sd); - - // retrieve the 'index'-th message - if( SQL_ERROR == Sql_Query(mail_handle, "SELECT `message_id`,`from_char_name`,`message`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = %d ORDER by `message_id` LIMIT %d, 1", mail_db, sd->status.account_id, index-1) ) - { - Sql_ShowDebug(mail_handle); - return 0; - } + nullpo_retr(0,sd); - if( 0 == Sql_NumRows(mail_handle) ) + if( sd->mail.amount ) { - clif_displaymessage(sd->fd, msg_txt(517)); // "Message not found." - Sql_FreeResult(mail_handle); - return 0; + if (flag) + pc_delitem(sd, sd->mail.index, sd->mail.amount, 1); + else + clif_additem(sd, sd->mail.index, sd->mail.amount, 0); } - if( SQL_ERROR == Sql_NextRow(mail_handle) ) - { - Sql_ShowDebug(mail_handle); - Sql_FreeResult(mail_handle); - return 0; - } - - Sql_GetData(mail_handle, 0, &data, NULL); message_id = atoi(data); - Sql_GetData(mail_handle, 1, &data, NULL); safestrncpy(from_char_name, data, sizeof(from_char_name)); - Sql_GetData(mail_handle, 2, &data, NULL); safestrncpy(message, data, sizeof(message)); - Sql_GetData(mail_handle, 3, &data, NULL); read_flag = (bool) atoi(data); - Sql_GetData(mail_handle, 4, &data, NULL); priority_flag = (bool) atoi(data); - Sql_GetData(mail_handle, 5, &data, NULL); check_flag = (bool) atoi(data); - - Sql_FreeResult(mail_handle); + sd->mail.index = 0; + sd->mail.amount = 0; + return 1; +} - // mark mail as checked - if( !check_flag ) - { - if( SQL_ERROR == Sql_Query(mail_handle, "UPDATE `%s` SET `check_flag` = 1 WHERE `message_id` = %d", mail_db, message_id) ) - Sql_ShowDebug(mail_handle); - } +int mail_removezeny(struct map_session_data *sd, short flag) +{ + nullpo_retr(0,sd); - sprintf(output, msg_txt(518), from_char_name); - clif_displaymessage(sd->fd, output); // "Reading message from %s" - clif_displaymessage(sd->fd, message); + if (flag && sd->mail.zeny > 0) + sd->status.zeny -= sd->mail.zeny; - if( SQL_ERROR == Sql_Query(mail_handle, "UPDATE `%s` SET `read_flag` = 1 WHERE `message_id` = %d", mail_db, message_id) ) - { - Sql_ShowDebug(mail_handle); - } + sd->mail.zeny = 0; + clif_updatestatus(sd, SP_ZENY); - return 0; + return 1; } -/// message deletion -int mail_delete(struct map_session_data* sd, int index) +char mail_setitem(struct map_session_data *sd, int idx, int amount) { - char* data; - int message_id; - bool read_flag, priority_flag, check_flag; + nullpo_retr(-1,sd); - nullpo_retr (0, sd); + if (idx == 0) + { // Zeny Transfer + if (amount < 0) + return 2; + if (amount > sd->status.zeny) + amount = sd->status.zeny; - if( SQL_ERROR == Sql_Query(mail_handle, "SELECT `message_id`,`read_flag`,`priority`,`check_flag` from `%s` WHERE `to_account_id` = %d ORDER by `message_id` LIMIT %d, 1", mail_db, sd->status.account_id, index-1) ) - { - Sql_ShowDebug(mail_handle); - return 0; - } - - if( 0 == Sql_NumRows(mail_handle) ) - { - clif_displaymessage(sd->fd, msg_txt(517)); // "Message not found." - Sql_FreeResult(mail_handle); - return 0; + sd->mail.zeny = amount; + clif_updatestatus(sd, SP_ZENY); } + else + { // Item Transfer + idx -= 2; + mail_removeitem(sd, 0); - if( SQL_ERROR == Sql_NextRow(mail_handle) ) - { - Sql_ShowDebug(mail_handle); - Sql_FreeResult(mail_handle); - return 0; - } - - Sql_GetData(mail_handle, 0, &data, NULL); message_id = atoi(data); - Sql_GetData(mail_handle, 1, &data, NULL); read_flag = (bool)atoi(data); - Sql_GetData(mail_handle, 2, &data, NULL); priority_flag = (bool)atoi(data); - Sql_GetData(mail_handle, 3, &data, NULL); check_flag = (bool)atoi(data); - - Sql_FreeResult(mail_handle); + if( idx < 0 || idx > MAX_INVENTORY ) + return 2; + if( amount < 0 || amount > sd->status.inventory[idx].amount ) + return 2; + if( itemdb_isdropable(&sd->status.inventory[idx], pc_isGM(sd)) == 0 ) + return 2; - if( !read_flag && priority_flag ) - { - clif_displaymessage(sd->fd,msg_txt(519)); // "Cannot delete unread priority mail." - return 0; - } + sd->mail.index = idx; + sd->mail.amount = amount; - if( !check_flag ) - { - clif_displaymessage(sd->fd,msg_txt(520)); // "You have received new mail, use @listmail before deleting." - return 0; - } + clif_delitem(sd, idx, amount); - if( SQL_ERROR == Sql_Query(mail_handle, "DELETE FROM `%s` WHERE `message_id` = %d", mail_db, message_id) ) - { - Sql_ShowDebug(mail_handle); return 0; } - clif_displaymessage(sd->fd,msg_txt(521)); // "Message deleted." - - return 0; + return -1; } -/// for sending normal and priority messages -int mail_send(struct map_session_data* sd, char* name, char* message, int flag) +int mail_getattach(struct map_session_data *sd, struct mail_message *msg) { - SqlStmt* stmt; - - nullpo_retr (0, sd); + int n; + + nullpo_retr(0,sd); + nullpo_retr(0,msg); - if( pc_isGM(sd) < 80 && sd->mail_counter > 0 ) - { - clif_displaymessage(sd->fd,msg_txt(522)); // "You must wait 10 minutes before sending another message" + if( sd->mail.zeny < 0 || sd->mail.zeny > sd->status.zeny ) return 0; - } - if( strcmp(name,"*") == 0 && pc_isGM(sd) < 80 ) + n = sd->mail.index; + if( sd->mail.amount ) { - clif_displaymessage(sd->fd, msg_txt(523)); // "Access Denied." - return 0; - } - - if( strcmp(name,"*") == 0 ) - { - if( SQL_ERROR == Sql_Query(mail_handle, "SELECT DISTINCT `account_id` FROM `%s` WHERE `account_id` != '%d' ORDER BY `account_id`", char_db, sd->status.account_id) ) - { - Sql_ShowDebug(mail_handle); - return 0; - } - } - else - { - char name_[2*NAME_LENGTH]; - Sql_EscapeString(mail_handle, name_, name); - if( SQL_ERROR == Sql_Query(mail_handle, "SELECT `account_id` FROM `%s` WHERE `name` = '%s'", char_db, name_) ) - { - Sql_ShowDebug(mail_handle); + if( sd->status.inventory[n].amount < sd->mail.amount ) return 0; - } - } - if( 0 == Sql_NumRows(mail_handle) ) - { - clif_displaymessage(sd->fd,msg_txt(524)); // "Character does not exist." - Sql_FreeResult(mail_handle); - return 0; + memcpy(&msg->item, &sd->status.inventory[n], sizeof(struct item)); + msg->item.amount = sd->mail.amount; } - stmt = SqlStmt_Malloc(mail_handle); - SqlStmt_Prepare(stmt, "INSERT DELAYED INTO `%s` (`to_account_id`,`to_char_name`,`from_account_id`,`from_char_name`,`message`,`priority`) VALUES (?, ?, '%d', ?, ?, '%d')", mail_db, sd->status.account_id, flag); - SqlStmt_BindParam(stmt, 1, SQLDT_STRING, name, strnlen(name, NAME_LENGTH)); - SqlStmt_BindParam(stmt, 2, SQLDT_STRING, sd->status.name, strnlen(sd->status.name, NAME_LENGTH)); - SqlStmt_BindParam(stmt, 3, SQLDT_STRING, message, strnlen(message, 80)); - - while( SQL_SUCCESS == Sql_NextRow(mail_handle) ) - { - int id; - char* data; - Sql_GetData(mail_handle, 0, &data, NULL); id = atoi(data); - SqlStmt_BindParam(stmt, 0, SQLDT_INT, &id, sizeof(id)); - if( SQL_ERROR == SqlStmt_Execute(stmt) ) - SqlStmt_ShowDebug(stmt); - } - Sql_FreeResult(mail_handle); - SqlStmt_Free(stmt); - - if(pc_isGM(sd) < 80) - sd->mail_counter = 5; - - clif_displaymessage(sd->fd,msg_txt(525)); // "Mail has been sent." + msg->zeny = sd->mail.zeny; - return 0; -} - -/// invoked every MAIL_CHECK_TIME ms, decreases the send blocking counter -static int mail_check_timer_sub(struct map_session_data* sd, va_list va) -{ - if(sd->mail_counter > 0) - sd->mail_counter--; - return 0; + return 1; } -/// periodically checks for new messages and notifies about them -int mail_check_timer(int tid, unsigned int tick, int id, int data) +int mail_openmail(struct map_session_data *sd) { - if(mail_timer != tid) - return 0; + nullpo_retr(0,sd); - mail_timer = add_timer(gettick() + MAIL_CHECK_TIME, mail_check_timer, 0, 0); - - // fetch account ids of people who received new mail since the last iteration - if( SQL_ERROR == Sql_Query(mail_handle, "SELECT DISTINCT `to_account_id` FROM `%s` WHERE `read_flag` = '0' AND `check_flag` = '0'", mail_db) ) - { - Sql_ShowDebug(mail_handle); + if( sd->state.finalsave == 1 || sd->state.storage_flag || sd->vender_id || sd->state.trading ) return 0; - } - - while( SQL_SUCCESS == Sql_NextRow(mail_handle) ) - { - char* id; - struct map_session_data* sd; - Sql_GetData(mail_handle, 0, &id, NULL); - if( (sd = map_id2sd(atoi(id))) != NULL ) - clif_displaymessage(sd->fd, msg_txt(526)); // "You have new mail." - } - - Sql_FreeResult(mail_handle); - // decrease the send-blocking counter - clif_foreachclient(mail_check_timer_sub); - - // The 'check_flag' indicates whether the player was informed about the message. - // All online players were notified by the above code, and offline players will get the notice at next login. - // Therefore it is safe to simply set the flag to '1' for all existing mails. - if( SQL_ERROR == Sql_Query(mail_handle, "UPDATE `%s` SET `check_flag` = 1 WHERE `check_flag` = 0", mail_db) ) - Sql_ShowDebug(mail_handle); - - return 0; -} - -int do_init_mail(void) -{ - add_timer_func_list(mail_check_timer, "mail_check_timer"); - mail_timer = add_timer(gettick() + MAIL_CHECK_TIME, mail_check_timer, 0, 0); + clif_Mail_openmail(sd->fd); return 0; } |