summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorzephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-10-22 20:38:26 +0000
committerzephyrus <zephyrus@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-10-22 20:38:26 +0000
commit38b5e25fd06a5d03413f59e3e37c6ffc21d0d02d (patch)
tree2ac7f91b25ed1c8da6e0e8bae0bb1e24b2c144d9 /src/map
parent256a7ebe4e172686f547cf406fd642d6e76e4ed4 (diff)
downloadhercules-38b5e25fd06a5d03413f59e3e37c6ffc21d0d02d.tar.gz
hercules-38b5e25fd06a5d03413f59e3e37c6ffc21d0d02d.tar.bz2
hercules-38b5e25fd06a5d03413f59e3e37c6ffc21d0d02d.tar.xz
hercules-38b5e25fd06a5d03413f59e3e37c6ffc21d0d02d.zip
- Added the new mail system. Requires optimization and tests.
- Updated the maildb sql structure. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11548 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map')
-rw-r--r--src/map/atcommand.c108
-rw-r--r--src/map/atcommand.h8
-rw-r--r--src/map/clif.c423
-rw-r--r--src/map/clif.h10
-rw-r--r--src/map/intif.c281
-rw-r--r--src/map/intif.h9
-rw-r--r--src/map/mail.c375
-rw-r--r--src/map/mail.h13
-rw-r--r--src/map/map.c67
-rw-r--r--src/map/map.h14
-rw-r--r--src/map/pc.c10
-rw-r--r--src/map/script.c16
12 files changed, 841 insertions, 493 deletions
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 5bcd80590..5ed008419 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -270,13 +270,7 @@ ACMD_FUNC(homshuffle); //[Skotlex]
ACMD_FUNC(showmobs); //KarLaeda
ACMD_FUNC(feelreset); //[HiddenDragon]
#ifndef TXT_ONLY
-ACMD_FUNC(checkmail); // [Valaris]
-ACMD_FUNC(listmail); // [Valaris]
-ACMD_FUNC(listnewmail); // [Valaris]
-ACMD_FUNC(readmail); // [Valaris]
-ACMD_FUNC(deletemail); // [Valaris]
-ACMD_FUNC(sendmail); // [Valaris]
-ACMD_FUNC(sendprioritymail); // [Valaris]
+ACMD_FUNC(mail); // [MAIL SYSTEM]
ACMD_FUNC(refreshonline); // [Valaris]
#endif
#ifdef DMALLOC
@@ -574,13 +568,7 @@ static AtCommandInfo atcommand_info[] = {
{ AtCommand_ShowMobs, "@showmobs", 10, atcommand_showmobs }, //KarLaeda
{ AtCommand_FeelReset, "@feelreset", 10, atcommand_feelreset }, //[HiddenDragon]
#ifndef TXT_ONLY // sql-only commands
- { AtCommand_CheckMail, "@checkmail", 1, atcommand_listmail }, // [Valaris]
- { AtCommand_ListMail, "@listmail", 1, atcommand_listmail }, // [Valaris]
- { AtCommand_ListNewMail, "@listnewmail", 1, atcommand_listmail }, // [Valaris]
- { AtCommand_ReadMail, "@readmail", 1, atcommand_readmail }, // [Valaris]
- { AtCommand_DeleteMail, "@deletemail", 1, atcommand_deletemail }, // [Valaris]
- { AtCommand_SendMail, "@sendmail", 1, atcommand_sendmail }, // [Valaris]
- { AtCommand_SendPriorityMail, "@sendprioritymail",80, atcommand_sendmail }, // [Valaris]
+ { AtCommand_Mail, "@mail", 1, atcommand_mail }, // [Mail System]
{ AtCommand_RefreshOnline, "@refreshonline", 99, atcommand_refreshonline }, // [Valaris]
#endif
#ifdef DMALLOC
@@ -7893,97 +7881,13 @@ int atcommand_killid2(const int fd, struct map_session_data* sd, const char* com
#ifndef TXT_ONLY /* Begin SQL-Only commands */
/*==========================================
- * Mail System commands by [Valaris]
+ * MAIL SYSTEM
*------------------------------------------*/
-int atcommand_listmail(const int fd, struct map_session_data* sd, const char* command, const char* message)
+int atcommand_mail(const int fd, struct map_session_data* sd, const char* command, const char* message)
{
- if(!mail_server_enable)
- return 0;
-
- nullpo_retr(-1, sd);
-
- if(strlen(command)==12) // @listnewmail
- mail_check(sd,3);
- else if(strlen(command)==9) // @listmail
- mail_check(sd,2);
- else // @checkmail
- mail_check(sd,1);
- return 0;
-}
-
-int atcommand_readmail(const int fd, struct map_session_data* sd, const char* command, const char* message)
-{
- int index;
- if(!mail_server_enable)
- return 0;
-
- nullpo_retr(-1, sd);
-
- if (!message || !*message) {
- clif_displaymessage(sd->fd,"You must specify a message number.");
- return 0;
- }
-
- index = atoi(message);
- if (index < 1) {
- clif_displaymessage(sd->fd,"Message number cannot be negative or zero.");
- return 0;
- }
-
- mail_read(sd,index);
-
- return 0;
-}
-
-int atcommand_deletemail(const int fd, struct map_session_data* sd, const char* command, const char* message)
-{
- int index;
- if(!mail_server_enable)
- return 0;
-
- nullpo_retr(-1, sd);
-
- if (!message || !*message) {
- clif_displaymessage(sd->fd,"You must specify a message number.");
- return 0;
- }
-
- index = atoi(message);
- if (index < 1) {
- clif_displaymessage(sd->fd,"Message number cannot be negative or zero.");
- return 0;
- }
-
- mail_delete(sd,index);
-
- return 0;
-}
-
-int atcommand_sendmail(const int fd, struct map_session_data* sd, const char* command, const char* message)
-{
- char name[NAME_LENGTH],text[80];
-
- if(!mail_server_enable)
- return 0;
-
- nullpo_retr(-1, sd);
-
- if (!message || !*message) {
- clif_displaymessage(sd->fd,"You must specify a recipient and a message.");
- return 0;
- }
-
- if ((sscanf(message, "\"%23[^\"]\" %79[^\n]", name, text) < 2) &&
- (sscanf(message, "%23s %79[^\n]", name, text) < 2)) {
- clif_displaymessage(sd->fd,"You must specify a recipient and a message.");
- return 0;
- }
-
- if(strlen(command)==17) // @sendprioritymail
- mail_send(sd,name,text,1);
- else
- mail_send(sd,name,text,0);
+ nullpo_retr(0,sd);
+ mail_openmail(sd);
return 0;
}
diff --git a/src/map/atcommand.h b/src/map/atcommand.h
index 6b94d9061..d2532fda7 100644
--- a/src/map/atcommand.h
+++ b/src/map/atcommand.h
@@ -255,13 +255,7 @@ enum AtCommandType {
AtCommand_HappyHappyJoyJoy,
// SQL-only commands start
#ifndef TXT_ONLY
- AtCommand_CheckMail, // [Valaris]
- AtCommand_ListMail, // [Valaris]
- AtCommand_ListNewMail, // [Valaris]
- AtCommand_ReadMail, // [Valaris]
- AtCommand_SendMail, // [Valaris]
- AtCommand_DeleteMail, // [Valaris]
- AtCommand_SendPriorityMail, // [Valaris]
+ AtCommand_Mail, // [Mail System]
AtCommand_RefreshOnline, // [Valaris]
// SQL-only commands end
#endif
diff --git a/src/map/clif.c b/src/map/clif.c
index 82f7aaa6f..956a5751e 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -36,6 +36,7 @@
#include "log.h"
#include "irc.h"
#include "clif.h"
+#include "mail.h"
#include <stdio.h>
#include <stdlib.h>
@@ -2500,7 +2501,7 @@ int clif_updatestatus(struct map_session_data *sd,int type)
case SP_ZENY:
WFIFOW(fd,0)=0xb1;
- WFIFOL(fd,4)=sd->status.zeny;
+ WFIFOL(fd,4)=sd->status.zeny - sd->mail.zeny;
break;
case SP_BASEEXP:
WFIFOW(fd,0)=0xb1;
@@ -11294,6 +11295,409 @@ void clif_parse_AutoRevive(int fd, struct map_session_data *sd)
pc_delitem(sd, item_position, 1, 0);
}
+#ifndef TXT_ONLY
+
+/*==========================================
+ * MAIL SYSTEM
+ * By Zephyrus
+ *------------------------------------------
+ * Opens Mail Window on Client
+ *------------------------------------------*/
+void clif_Mail_openmail(int fd)
+{
+ WFIFOHEAD(fd,packet_len(0x260));
+ WFIFOW(fd,0) = 0x260;
+ WFIFOL(fd,2) = 0;
+ WFIFOSET(fd,packet_len(0x260));
+}
+/*------------------------------------------
+ * Send Inbox Data to Client
+ *------------------------------------------*/
+void clif_Mail_refreshinbox(struct map_session_data *sd)
+{
+ int fd = sd->fd;
+ struct mail_data *md = &sd->mail.inbox;
+ struct mail_message *msg;
+ int len, i, j;
+
+ len = 8 + (73 * md->amount);
+
+ WFIFOHEAD(fd,len);
+ WFIFOW(fd,0) = 0x240;
+ WFIFOW(fd,2) = len;
+ WFIFOL(fd,4) = md->amount;
+ for( i = j = 0; i < MAX_MAIL_INBOX && j < md->amount; i++ )
+ {
+ msg = &md->msg[i];
+ if (msg->id < 1)
+ continue; // Deleted Message
+
+ WFIFOL(fd,8+73*j) = msg->id;
+ memcpy(WFIFOP(fd,12+73*j), msg->title, MAIL_TITLE_LENGTH);
+ WFIFOB(fd,52+73*j) = msg->read;
+ memcpy(WFIFOP(fd,53+73*j), msg->send_name, NAME_LENGTH);
+ WFIFOL(fd,77+73*j) = msg->timestamp;
+ j++;
+ }
+ WFIFOSET(fd,len);
+}
+/*------------------------------------------
+ * Client Request Inbox List
+ *------------------------------------------*/
+void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd)
+{
+ struct mail_data *md;
+
+ nullpo_retv(sd);
+ md = &sd->mail.inbox;
+
+ if( md->amount < MAX_MAIL_INBOX && (md->satured || md->changed) )
+ intif_Mail_requestinbox(sd->status.char_id, 1);
+ else
+ clif_Mail_refreshinbox(sd);
+
+ mail_removeitem(sd, 0);
+ mail_removezeny(sd, 0);
+}
+
+/*------------------------------------------
+ * Read Message
+ *------------------------------------------*/
+void clif_Mail_read(struct map_session_data *sd, int mail_id)
+{
+ int i, fd = sd->fd;
+
+ ARR_FIND(0, MAX_MAIL_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if (i < MAX_MAIL_INBOX)
+ {
+ struct mail_message *msg = &sd->mail.inbox.msg[i];
+ struct item *item = &msg->item;
+ struct item_data *data;
+ int msg_len = strlen(msg->body), len;
+
+ if( msg_len == 0 ) {
+ strcpy(msg->body, "(no message)");
+ msg_len = strlen(msg->body);
+ }
+
+ len = 101 + msg_len;
+
+ WFIFOHEAD(fd,len);
+ WFIFOW(fd,0) = 0x242;
+ WFIFOW(fd,2) = len;
+ WFIFOL(fd,4) = msg->id;
+ memcpy(WFIFOP(fd, 8), msg->title, MAIL_TITLE_LENGTH);
+ memcpy(WFIFOP(fd,48), msg->send_name, NAME_LENGTH);
+ WFIFOL(fd,72) = 0;
+ WFIFOL(fd,76) = msg->zeny;
+
+ if (item->nameid)
+ {
+ WFIFOL(fd,80) = item->amount;
+ if ((data = itemdb_search(item->nameid)) != NULL)
+ 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;
+ }
+ else
+ {
+ WFIFOL(fd,80) = 0;
+ WFIFOW(fd,84) = 0;
+ WFIFOW(fd,86) = 0;
+ }
+
+ 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;
+ memcpy(WFIFOP(fd,100), msg->body, msg_len);
+ WFIFOB(fd,len - 1) = 0x00;
+ WFIFOSET(fd,len);
+
+ if (!msg->read) {
+ msg->read = 1;
+ intif_Mail_read(mail_id);
+ clif_parse_Mail_refreshinbox(fd, sd);
+ }
+ }
+ else
+ ShowWarning("clif_parse_Mail_read: account %d trying to read a message not the inbox.\n", sd->status.account_id);
+}
+
+void clif_parse_Mail_read(int fd, struct map_session_data *sd)
+{
+ nullpo_retv(sd);
+ clif_Mail_read(sd, RFIFOL(fd,2));
+}
+
+/*------------------------------------------
+ * Get Attachment from Message
+ *------------------------------------------*/
+void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
+{
+ int i, mail_id = RFIFOL(fd,2);
+ nullpo_retv(sd);
+
+ ARR_FIND(0, MAX_MAIL_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if (i < MAX_MAIL_INBOX)
+ {
+ if (sd->mail.inbox.msg[i].zeny < 1 && (sd->mail.inbox.msg[i].item.nameid < 1 || sd->mail.inbox.msg[i].item.amount < 1))
+ return;
+
+ if (sd->mail.inbox.msg[i].item.nameid > 0)
+ {
+ struct item_data *data;
+ unsigned int weight;
+
+ if ((data = itemdb_search(sd->mail.inbox.msg[i].item.nameid)) == NULL)
+ return;
+
+ weight = data->weight * sd->mail.inbox.msg[i].item.amount;
+ if (weight > sd->max_weight - sd->weight)
+ {
+ clif_displaymessage(fd, "Attachment to heavy for you...");
+ return;
+ }
+ }
+
+ sd->mail.inbox.msg[i].zeny = 0;
+ memset(&sd->mail.inbox.msg[i].item, 0, sizeof(struct item));
+ 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);
+ }
+}
+/*------------------------------------------
+ * Delete Message
+ *------------------------------------------*/
+void clif_Mail_delete(struct map_session_data *sd, int mail_id, short flag)
+{
+ int fd = sd->fd;
+
+ if (!flag)
+ {
+ int i;
+ ARR_FIND(0, MAX_MAIL_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if( i < MAX_MAIL_INBOX )
+ {
+ memset(&sd->mail.inbox.msg[i], 0, sizeof(struct mail_message));
+ sd->mail.inbox.amount--;
+ }
+ }
+
+ WFIFOHEAD(fd, packet_len(0x257));
+ WFIFOW(fd,0) = 0x257;
+ WFIFOL(fd,2) = mail_id;
+ WFIFOW(fd,6) = flag;
+ WFIFOSET(fd, packet_len(0x257));
+
+ if( !flag && sd->mail.inbox.satured )
+ intif_Mail_requestinbox(sd->status.char_id, 1); // Reload the Mail Inbox
+}
+
+void clif_parse_Mail_delete(int fd, struct map_session_data *sd)
+{
+ int i, mail_id = RFIFOL(fd,2);
+ nullpo_retv(sd);
+
+ ARR_FIND(0, MAX_MAIL_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if (i < MAX_MAIL_INBOX)
+ {
+ struct mail_message *msg = &sd->mail.inbox.msg[i];
+
+ if( (msg->item.nameid > 0 && msg->item.amount > 0) || msg->zeny > 0 )
+ {
+ clif_Mail_delete(sd, mail_id, 1);
+ return;
+ }
+
+ 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
+ *------------------------------------------*/
+void clif_parse_Mail_return(int fd, struct map_session_data *sd)
+{
+ int i, mail_id = RFIFOL(fd,2);
+ nullpo_retv(sd);
+
+ ARR_FIND(0, MAX_MAIL_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if (i < MAX_MAIL_INBOX)
+ intif_Mail_return(sd->status.char_id, mail_id);
+}
+
+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, MAX_MAIL_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
+ if (i < MAX_MAIL_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));
+}
+
+/*------------------------------------------
+ * Set Attachment
+ *------------------------------------------*/
+void clif_parse_Mail_setattach(int fd, struct map_session_data *sd)
+{
+ int idx = RFIFOW(fd,2), amount = RFIFOL(fd,4);
+ char flag;
+
+ nullpo_retv(sd);
+ if (idx < 0 || amount < 0)
+ return;
+
+ flag = mail_setitem(sd, idx, amount);
+ if (flag > -1)
+ {
+ WFIFOHEAD(fd,packet_len(0x245));
+ WFIFOW(fd,0) = 0x245;
+ WFIFOB(fd,2) = flag;
+ WFIFOSET(fd,packet_len(0x245));
+ }
+}
+
+/*------------------------------------------
+ * Mail Window Operation
+ *------------------------------------------*/
+void clif_parse_Mail_winopen(int fd, struct map_session_data *sd)
+{
+ int flag = RFIFOW(fd,2);
+ nullpo_retv(sd);
+
+ if (!flag || flag == 1)
+ mail_removeitem(sd, 0);
+ if (!flag || flag == 2)
+ 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));
+}
+
+void clif_parse_Mail_send(int fd, struct map_session_data *sd)
+{
+ struct map_session_data *rd;
+ struct mail_message *msg;
+ int body_len;
+ nullpo_retv(sd);
+
+ if( RFIFOW(fd,2) < 69 ) {
+ ShowWarning("Invalid Msg Len from account %d.\n", sd->status.account_id);
+ return;
+ }
+
+ if( DIFF_TICK(sd->cansendmail_tick, gettick()) > 0 )
+ {
+ clif_displaymessage(sd->fd,"Cannot send mails too fast!!.");
+ clif_Mail_send(fd, 1);
+ return;
+ }
+
+ body_len = RFIFOB(fd,68);
+ rd = map_nick2sd_nocase(RFIFOP(fd,4));
+
+ if (rd && rd == sd) {
+ clif_Mail_send(fd, 1);
+ mail_removeitem(sd,0);
+ mail_removezeny(sd,0);
+ return;
+ }
+
+ if (body_len > MAIL_BODY_LENGTH)
+ body_len = MAIL_BODY_LENGTH;
+
+ msg = (struct mail_message*)aCalloc(sizeof(struct mail_message), 1);
+
+ if (mail_getattach(sd, msg))
+ {
+ msg->send_id = sd->status.char_id;
+ safestrncpy(msg->send_name, sd->status.name, NAME_LENGTH);
+
+ if (rd) {
+ msg->dest_id = rd->status.char_id;
+ safestrncpy(msg->dest_name, rd->status.name, NAME_LENGTH);
+ } else {
+ msg->dest_id = 0;
+ safestrncpy(msg->dest_name, RFIFOP(fd,4), NAME_LENGTH);
+ }
+
+ memcpy(msg->title, RFIFOP(fd,28), MAIL_TITLE_LENGTH);
+
+ if (body_len)
+ memcpy(msg->body, RFIFOP(fd,69), body_len);
+ else
+ memset(msg->body, 0x00, MAIL_BODY_LENGTH);
+
+ msg->timestamp = (int)mail_calctimes();
+ intif_Mail_send(sd->status.account_id, msg);
+
+ sd->cansendmail_tick = gettick() + 1000; // 5 Seconds flood Protection
+ }
+ else
+ {
+ mail_removeitem(sd,0);
+ mail_removezeny(sd,0);
+ clif_Mail_send(sd->fd, 1); // Fail
+ }
+
+ aFree(msg);
+}
+
+#endif
+
/*==========================================
* パケットデバッグ
*------------------------------------------*/
@@ -11551,10 +11955,10 @@ static int packetdb_readdb(void)
//#0x0240
-1, -1, -1, -1, -1, 3, 4, 8, -1, 3, 70, 4, 8, 12, 4, 10,
3, 32, -1, 3, 3, 5, 5, 8, 2, 3, -1, -1, 4, -1, 4, 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,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
//#0x0280
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 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,191, 0, 0, 0, 0, 0, 0,
@@ -11705,6 +12109,17 @@ static int packetdb_readdb(void)
{clif_parse_StoragePassword,"storagepassword"},
{clif_parse_Hotkey,"hotkey"},
{clif_parse_AutoRevive,"autorevive"},
+#ifndef TXT_ONLY
+ // MAIL SYSTEM
+ {clif_parse_Mail_refreshinbox,"mailrefresh"},
+ {clif_parse_Mail_read,"mailread"},
+ {clif_parse_Mail_getattach,"mailgetattach"},
+ {clif_parse_Mail_delete,"maildelete"},
+ {clif_parse_Mail_return,"mailreturn"},
+ {clif_parse_Mail_setattach,"mailsetattach"},
+ {clif_parse_Mail_winopen,"mailwinopen"},
+ {clif_parse_Mail_send,"mailsend"},
+#endif
{NULL,NULL}
};
diff --git a/src/map/clif.h b/src/map/clif.h
index 543a17da1..117c7fb24 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -382,5 +382,15 @@ int clif_send(const uint8* buf, int len, struct block_list* bl, enum send_target
int do_final_clif(void);
int do_init_clif(void);
+#ifndef TXT_ONLY
+// MAIL SYSTEM
+void clif_Mail_openmail(int fd);
+void clif_Mail_read(struct map_session_data *sd, int mail_id);
+void clif_Mail_delete(struct map_session_data *sd, int mail_id, short flag);
+void clif_Mail_return(struct map_session_data *sd, int mail_id, int new_mail);
+void clif_Mail_send(int fd, unsigned char flag);
+void clif_Mail_new(int fd, int mail_id, const char *sender, const char *title);
+void clif_Mail_refreshinbox(struct map_session_data *sd);
+#endif
#endif /* _CLIF_H_ */
diff --git a/src/map/intif.c b/src/map/intif.c
index 3bf2d45ae..e6fe15242 100644
--- a/src/map/intif.c
+++ b/src/map/intif.c
@@ -18,6 +18,7 @@
#include "pet.h"
#include "atcommand.h"
#include "mercenary.h" //albator
+#include "mail.h"
#include <sys/types.h>
#include <stdio.h>
@@ -32,7 +33,7 @@ static const int packet_len_table[]={
-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
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, 0, 0, 0, 0, 0, 0, 0, 0, //0x3840
+ 9, 9,-1,14, 0, 0, 0, 0, -1, 0,-1,12, 14,-1, 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,
@@ -1458,6 +1459,275 @@ int intif_parse_DeleteHomunculusOk(int fd)
return 0;
}
+
+/*==========================================
+ * MAIL SYSTEM
+ * By Zephyrus
+ *------------------------------------------
+ * Inbox Request
+ * flag: 0 Update Inbox | 1 OpenMail
+ *------------------------------------------*/
+#ifndef TXT_ONLY
+
+int intif_Mail_requestinbox(int char_id, unsigned char flag)
+{
+ if (CheckForCharServer())
+ return 0;
+
+ WFIFOHEAD(inter_fd,7);
+ WFIFOW(inter_fd,0) = 0x3048;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOB(inter_fd,6) = flag;
+ WFIFOSET(inter_fd,7);
+
+ return 0;
+}
+
+int intif_parse_Mail_inboxreceived(int fd)
+{
+ struct map_session_data *sd;
+ unsigned char flag = RFIFOB(fd,8);
+
+ sd = map_charid2sd( RFIFOL(fd,4) );
+
+ if (sd == NULL)
+ {
+ if (battle_config.error_log)
+ ShowError("intif_parse_Mail_inboxreceived: char not found %d\n",RFIFOL(fd,4));
+ return 1;
+ }
+
+ if (sd->state.finalsave)
+ return 1;
+
+ if (RFIFOW(fd,2) - 9 != sizeof(struct mail_data))
+ {
+ if (battle_config.error_log)
+ ShowError("intif_parse_Mail_inboxreceived: data size error %d %d\n", RFIFOW(fd,2) - 9, sizeof(struct mail_data));
+ return 1;
+ }
+
+ memset(&sd->mail.inbox, 0, sizeof(struct mail_data));
+ memcpy(&sd->mail.inbox, RFIFOP(fd,9), sizeof(struct mail_data));
+
+ if (flag)
+ clif_Mail_refreshinbox(sd);
+ else
+ {
+ char output[128];
+ sprintf(output, "You have %d new emails (%d unreaded)", sd->mail.inbox.unchecked, sd->mail.inbox.unreaded + sd->mail.inbox.unchecked);
+ clif_disp_onlyself(sd, output, strlen(output));
+ }
+ return 0;
+}
+/*------------------------------------------
+ * Mail Readed
+ *------------------------------------------*/
+int intif_Mail_read(int mail_id)
+{
+ if (CheckForCharServer())
+ return 0;
+
+ WFIFOHEAD(inter_fd,6);
+ WFIFOW(inter_fd,0) = 0x3049;
+ WFIFOL(inter_fd,2) = mail_id;
+ WFIFOSET(inter_fd,6);
+
+ return 0;
+}
+/*------------------------------------------
+ * Get Attachment
+ *------------------------------------------*/
+int intif_Mail_getattach(int char_id, int mail_id)
+{
+ if (CheckForCharServer())
+ return 0;
+
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x304a;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOL(inter_fd,6) = mail_id;
+ WFIFOSET(inter_fd, 10);
+
+ return 0;
+}
+
+int intif_parse_Mail_getattach(int fd)
+{
+ struct map_session_data *sd;
+ struct item *item;
+ int zeny = RFIFOL(fd,8);
+
+ sd = map_charid2sd( RFIFOL(fd,4) );
+
+ if (sd == NULL)
+ {
+ if (battle_config.error_log)
+ ShowError("intif_parse_Mail_getattach: char not found %d\n",RFIFOL(fd,4));
+ return 1;
+ }
+
+ if (sd->state.finalsave)
+ return 1;
+
+ if (RFIFOW(fd,2) - 12 != sizeof(struct item))
+ {
+ if (battle_config.error_log)
+ ShowError("intif_parse_Mail_getattach: data size error %d %d\n", RFIFOW(fd,2) - 16, sizeof(struct item));
+ return 1;
+ }
+
+ if (zeny > 0)
+ {
+ sd->status.zeny += zeny;
+ clif_updatestatus(sd, SP_ZENY);
+ }
+
+ item = (struct item*)aCalloc(sizeof(struct item), 1);
+ memcpy(item, RFIFOP(fd,12), sizeof(struct item));
+ if (item->nameid > 0 && item->amount > 0)
+ pc_additem(sd, item, item->amount);
+
+ aFree(item);
+
+ return 0;
+}
+/*------------------------------------------
+ * Delete Message
+ *------------------------------------------*/
+int intif_Mail_delete(int char_id, int mail_id)
+{
+ if (CheckForCharServer())
+ return 0;
+
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x304b;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOL(inter_fd,6) = mail_id;
+ WFIFOSET(inter_fd,10);
+
+ return 0;
+}
+
+int intif_parse_Mail_delete(int fd)
+{
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
+ int mail_id = RFIFOL(fd,6);
+ short flag = RFIFOW(fd,10);
+
+ if (sd == NULL)
+ {
+ if (battle_config.error_log)
+ ShowError("intif_parse_Mail_delete: char not found %d\n",RFIFOL(fd,2));
+ return 1;
+ }
+
+ if (sd->state.finalsave)
+ return 1;
+
+ clif_Mail_delete(sd, mail_id, flag);
+ return 0;
+}
+/*------------------------------------------
+ * Return Message
+ *------------------------------------------*/
+int intif_Mail_return(int char_id, int mail_id)
+{
+ if (CheckForCharServer())
+ return 0;
+
+ WFIFOHEAD(inter_fd,10);
+ WFIFOW(inter_fd,0) = 0x304c;
+ WFIFOL(inter_fd,2) = char_id;
+ WFIFOL(inter_fd,6) = mail_id;
+ WFIFOSET(inter_fd,10);
+
+ return 0;
+}
+
+int intif_parse_Mail_return(int fd)
+{
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,2));
+ int mail_id = RFIFOL(fd,6), new_mail = RFIFOL(fd,10);
+
+ if (sd == NULL)
+ {
+ if (battle_config.error_log)
+ ShowError("intif_parse_Mail_return: char not found %d\n",RFIFOL(fd,2));
+ return 1;
+ }
+
+ if (sd->state.finalsave)
+ return 1;
+
+ clif_Mail_return(sd, mail_id, new_mail);
+ return 0;
+}
+/*------------------------------------------
+ * Send Mail
+ *------------------------------------------*/
+int intif_Mail_send(int account_id, struct mail_message *msg)
+{
+ int len = sizeof(struct mail_message) + 8;
+
+ if (CheckForCharServer())
+ return 0;
+
+ WFIFOHEAD(inter_fd,len);
+ WFIFOW(inter_fd,0) = 0x304d;
+ WFIFOW(inter_fd,2) = len;
+ WFIFOL(inter_fd,4) = account_id;
+ memcpy(WFIFOP(inter_fd,8), msg, sizeof(struct mail_message));
+ WFIFOSET(inter_fd,len);
+
+ return 0;
+}
+
+int intif_parse_Mail_send(int fd)
+{
+ struct map_session_data *sd = map_charid2sd(RFIFOL(fd,4));
+ int mail_id = RFIFOL(fd,8);
+ int dest_id = RFIFOL(fd,12);
+
+ if (sd == NULL && mail_id > 0)
+ {
+ if (battle_config.error_log)
+ ShowError("intif_parse_Mail_send: char not found %d\n",RFIFOL(fd,2));
+
+ // If sd = NULL attachment haven't been removed from sender inventory.
+ intif_Mail_delete(dest_id, mail_id);
+ return 0;
+ }
+
+ if (mail_id > 0)
+ {
+ struct map_session_data *rd = map_charid2sd(dest_id);
+
+ mail_removeitem(sd, 1);
+ mail_removezeny(sd, 1);
+
+ if (rd != NULL)
+ {
+ char title[MAIL_TITLE_LENGTH];
+ memcpy(title, RFIFOP(fd,16), RFIFOW(fd,2) - 16);
+
+ rd->mail.inbox.changed = 1;
+ clif_Mail_new(rd->fd, mail_id, sd->status.name, title);
+ }
+ }
+ else
+ { // Return the items to the owner
+ mail_removeitem(sd, 0);
+ mail_removezeny(sd, 0);
+ }
+
+ clif_Mail_send(sd->fd, (mail_id > 0)?0:1);
+
+ return 0;
+}
+
+#endif
+
//-----------------------------------------------------------------
// inter serverからの通信
// エラーがあれば0(false)を返すこと
@@ -1528,6 +1798,15 @@ int intif_parse(int fd)
case 0x3841: intif_parse_GuildCastleDataSave(fd); break;
case 0x3842: intif_parse_GuildCastleAllDataLoad(fd); break;
case 0x3843: intif_parse_GuildMasterChanged(fd); break;
+// Mail System
+#ifndef TXT_ONLY
+ case 0x3848: intif_parse_Mail_inboxreceived(fd); break;
+ case 0x384a: intif_parse_Mail_getattach(fd); break;
+ case 0x384b: intif_parse_Mail_delete(fd); break;
+ case 0x384c: intif_parse_Mail_return(fd); break;
+ case 0x384d: intif_parse_Mail_send(fd); break;
+#endif
+// End of Mail System
case 0x3880: intif_parse_CreatePet(fd); break;
case 0x3881: intif_parse_RecvPetData(fd); break;
case 0x3882: intif_parse_SavePetOk(fd); break;
diff --git a/src/map/intif.h b/src/map/intif.h
index 5487d5725..793c6bc3e 100644
--- a/src/map/intif.h
+++ b/src/map/intif.h
@@ -74,6 +74,15 @@ int intif_homunculus_requestload(int account_id, int homun_id);
int intif_homunculus_requestsave(int account_id, struct s_homunculus* sh);
int intif_homunculus_requestdelete(int homun_id);
+#ifndef TXT_ONLY
+// MAIL SYSTEM
+int intif_Mail_requestinbox(int char_id, unsigned char flag);
+int intif_Mail_read(int mail_id);
+int intif_Mail_getattach(int char_id, int mail_id);
+int intif_Mail_delete(int char_id, int mail_id);
+int intif_Mail_return(int char_id, int mail_id);
+int intif_Mail_send(int account_id, struct mail_message *msg);
+#endif
int CheckForCharServer(void);
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;
}
diff --git a/src/map/mail.h b/src/map/mail.h
index f753d827b..1f05edfce 100644
--- a/src/map/mail.h
+++ b/src/map/mail.h
@@ -4,11 +4,14 @@
#ifndef _MAIL_H_
#define _MAIL_H_
-int mail_check(struct map_session_data *sd, int type);
-int mail_read(struct map_session_data *sd, int index);
-int mail_delete(struct map_session_data *sd, int index);
-int mail_send(struct map_session_data *sd, char *name, char *message, int flag);
+#include "../common/mmo.h"
-int do_init_mail(void);
+time_t mail_calctimes(void);
+
+int mail_removeitem(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);
+int mail_getattach(struct map_session_data *sd, struct mail_message *msg);
+int mail_openmail(struct map_session_data *sd);
#endif /* _MAIL_H_ */
diff --git a/src/map/map.c b/src/map/map.c
index db4f7d077..929ee7c36 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -75,16 +75,6 @@ char log_db_pw[32] = "ragnarok";
char log_db[32] = "log";
Sql* logmysql_handle;
-// mail system
-int mail_server_enable = 0;
-char mail_server_ip[32] = "127.0.0.1";
-int mail_server_port = 3306;
-char mail_server_id[32] = "ragnarok";
-char mail_server_pw[32] = "ragnarok";
-char mail_server_db[32] = "ragnarok";
-char mail_db[32] = "mail";
-Sql* mail_handle;
-
#endif /* not TXT_ONLY */
int lowest_gm_level = 1;
@@ -1857,6 +1847,21 @@ struct map_session_data * map_nick2sd(const char *nick)
return NULL;
}
+struct map_session_data * map_nick2sd_nocase(const char *nick)
+{
+ int i, users;
+ struct map_session_data **pl_allsd;
+
+ pl_allsd = map_getallusers(&users);
+ for (i = 0; i < users; i++)
+ {
+ if ( !strcmp(pl_allsd[i]->status.name, nick) )
+ return pl_allsd[i];
+ }
+
+ return NULL;
+}
+
/*==========================================
* id番?の物を探す
* 一三bjectの場合は配列を引くのみ
@@ -2888,22 +2893,6 @@ int inter_config_read(char *cfgName)
strcpy(log_db_pw, w2);
} else if(strcmpi(w1,"log_db_port")==0) {
log_db_port = atoi(w2);
- // Mail Server SQL
- } else if(strcmpi(w1,"mail_server_enable")==0){
- mail_server_enable = config_switch(w2);
- ShowStatus ("Using Mail Server: %s\n",w2);
- } else if(strcmpi(w1,"mail_server_ip")==0){
- strcpy(mail_server_ip, w2);
- } else if(strcmpi(w1,"mail_server_port")==0){
- mail_server_port=atoi(w2);
- } else if(strcmpi(w1,"mail_server_id")==0){
- strcpy(mail_server_id, w2);
- } else if(strcmpi(w1,"mail_server_pw")==0){
- strcpy(mail_server_pw, w2);
- } else if(strcmpi(w1,"mail_server_db")==0){
- strcpy(mail_server_db, w2);
- } else if(strcmpi(w1,"mail_db")==0) {
- strcpy(mail_db, w2);
#endif
//support the import command, just like any other config
} else if(strcmpi(w1,"import")==0){
@@ -2933,20 +2922,6 @@ int map_sql_init(void)
if ( SQL_ERROR == Sql_SetEncoding(mmysql_handle, default_codepage) )
Sql_ShowDebug(mmysql_handle);
- if(mail_server_enable)
- {
- // mail system
- mail_handle = Sql_Malloc();
-
- ShowInfo("Connecting to the Mail DB Server....\n");
- if( SQL_ERROR == Sql_Connect(mail_handle, mail_server_id, mail_server_pw, mail_server_ip, mail_server_port, mail_server_db) )
- exit(EXIT_FAILURE);
-
- if( strlen(default_codepage) > 0 )
- if ( SQL_ERROR == Sql_SetEncoding(mail_handle, default_codepage) )
- Sql_ShowDebug(mail_handle);
- }
-
return 0;
}
@@ -2963,13 +2938,6 @@ int map_sql_close(void)
logmysql_handle = NULL;
}
- if(mail_server_enable)
- {
- ShowStatus("Close Mail DB Connection....\n");
- Sql_Free(mail_handle);
- mail_handle = NULL;
- }
-
return 0;
}
@@ -2999,8 +2967,6 @@ int map_sql_ping(int tid, unsigned int tick, int id, int data)
Sql_Ping(mmysql_handle);
if (log_config.sql_logs)
Sql_Ping(logmysql_handle);
- if(mail_server_enable)
- Sql_Ping(mail_handle);
return 0;
}
@@ -3382,9 +3348,6 @@ int do_init(int argc, char *argv[])
do_init_npc();
do_init_unit();
#ifndef TXT_ONLY /* mail system [Valaris] */
- if(mail_server_enable)
- do_init_mail();
-
if (log_config.sql_logs)
log_sql_init();
diff --git a/src/map/map.h b/src/map/map.h
index 95c1d120d..b0f823d8e 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -633,6 +633,7 @@ struct map_session_data {
unsigned int canlog_tick;
unsigned int canuseitem_tick; // [Skotlex]
unsigned int cantalk_tick;
+ unsigned int cansendmail_tick; // [Mail System Flood Protection]
short weapontype1,weapontype2;
short disguise; // [Valaris]
@@ -799,15 +800,16 @@ struct map_session_data {
char fakename[NAME_LENGTH]; // fake names [Valaris]
-#ifndef TXT_ONLY
- int mail_counter; // mail counter for mail system (antiflood protection)
-#endif
-
int duel_group; // duel vars [LuzZza]
int duel_invite;
char away_message[128]; // [LuzZza]
+ // Mail System [Zephyrus]
+ struct {
+ int index, amount, zeny;
+ struct mail_data inbox;
+ } mail;
};
struct {
@@ -1342,6 +1344,7 @@ struct map_session_data** map_getallusers(int *users);
void map_foreachpc(int (*func)(DBKey,void*,va_list),...);
int map_foreachiddb(int (*)(DBKey,void*,va_list),...);
struct map_session_data * map_nick2sd(const char*);
+struct map_session_data * map_nick2sd_nocase(const char *);
// その他
int map_check_dir(int s_dir,int t_dir);
@@ -1412,18 +1415,15 @@ extern char main_chat_nick[16];
#include "../common/sql.h"
extern int db_use_sqldbs;
-extern int mail_server_enable;
extern Sql* mmysql_handle;
extern Sql* logmysql_handle;
-extern Sql* mail_handle;
extern char item_db_db[32];
extern char item_db2_db[32];
extern char mob_db_db[32];
extern char mob_db2_db[32];
extern char char_db[32];
-extern char mail_db[32];
#endif /* not TXT_ONLY */
diff --git a/src/map/pc.c b/src/map/pc.c
index 733f31d0a..a984796ae 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -633,6 +633,7 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
sd->canuseitem_tick = tick;
sd->cantalk_tick = tick;
+ sd->cansendmail_tick = tick;
for(i = 0; i < MAX_SKILL_LEVEL; i++)
sd->spirit_timer[i] = -1;
@@ -743,11 +744,6 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t
clif_displaymessage(sd->fd, motd_text[i]);
}
-#ifndef TXT_ONLY
- if(mail_server_enable)
- mail_check(sd,0); // check mail at login [Valaris]
-#endif
-
// message of the limited time of the account
if (connect_until_time != 0) { // don't display if it's unlimited or unknow value
char tmpstr[1024];
@@ -886,7 +882,9 @@ int pc_reg_received(struct map_session_data *sd)
status_calc_pc(sd,1);
chrif_scdata_request(sd->status.account_id, sd->status.char_id);
-
+#ifndef TXT_ONLY
+ intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
+#endif
if (!sd->state.connect_new && sd->fd)
{ //Character already loaded map! Gotta trigger LoadEndAck manually.
sd->state.connect_new = 1;
diff --git a/src/map/script.c b/src/map/script.c
index 9de888e31..0e4144605 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -39,6 +39,7 @@
#include "unit.h"
#include "irc.h"
#include "pet.h"
+#include "mail.h"
#include "script.h"
#include <stdio.h>
@@ -4052,6 +4053,10 @@ BUILDIN_FUNC(getmonsterinfo); // [Lupus]
BUILDIN_FUNC(checkvending); // check vending [Nab4]
BUILDIN_FUNC(checkchatting); // check chatting [Marka]
+#ifndef TXT_ONLY
+BUILDIN_FUNC(openmail); // [Mail System]
+#endif
+
#ifdef PCRE_SUPPORT
BUILDIN_FUNC(defpattern); // MouseJstr
BUILDIN_FUNC(activatepset); // MouseJstr
@@ -4390,6 +4395,9 @@ struct script_function buildin_func[] = {
BUILDIN_DEF(roclass,"i*"), //[Skotlex]
BUILDIN_DEF(checkvending,"*"),
BUILDIN_DEF(checkchatting,"*"),
+#ifndef TXT_ONLY
+ BUILDIN_DEF(openmail,""),
+#endif
{NULL,NULL,NULL},
};
@@ -13446,3 +13454,11 @@ BUILDIN_FUNC(warpportal)
return 0;
}
+
+#ifndef TXT_ONLY
+BUILDIN_FUNC(openmail)
+{
+ mail_openmail(script_rid2sd(st));
+ return 0;
+}
+#endif