瀏覽代碼

- The last, i hope, fix to the mail system.

* kRO have a possible way to read mail by just sending the open mail window packet to the client.
This protection adds a mapflag town, to set the only maps that allow mail operations.
because there is no way to know when client closes the mail inbox window. *

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@12279 54d463be-8e91-2dee-dedb-b68131a5f0ec
zephyrus 17 年之前
父節點
當前提交
84ffdd36bf
共有 7 個文件被更改,包括 61 次插入2 次删除
  1. 27 2
      npc/other/mail.txt
  2. 1 0
      src/map/atcommand.h
  3. 15 0
      src/map/clif.c
  4. 14 0
      src/map/mail.c
  5. 1 0
      src/map/mail.h
  6. 1 0
      src/map/map.h
  7. 2 0
      src/map/npc.c

+ 27 - 2
npc/other/mail.txt

@@ -3,7 +3,7 @@
 //===== By: ==================================================
 //= L0ne_W0lf
 //===== Current Version: =====================================
-//= 1.3a
+//= 1.4
 //===== Compatible With: =====================================
 //= eAthena SVN
 //===== Description: ========================================= 
@@ -15,7 +15,32 @@
 //= 1.2 Swapped "atcommand" for "Openmail". [L0ne_W0lf]
 //= 1.3 Added Veins mail box. [L0ne_W0lf]
 //= 1.3a Corrected a typo error. (bugreport:798) [Samuray22]
-//============================================================
+//= 1.4 Added a Mapflag to prevent mail operations in other maps [Zephyrus]
+//============================================================
+
+// Allow Mail Inbox reading from
+//============================================================
+prontera	mapflag	town
+izlude	mapflag	town
+morocc	mapflag	town
+geffen	mapflag	town
+payon	mapflag	town
+pay_arche	mapflag	town
+alberta	mapflag	town
+aldebaran	mapflag	town
+yuno	mapflag	town
+lighthalzen	mapflag	town
+einbroch	mapflag	town
+einbech	mapflag	town
+comodo	mapflag	town
+umbala	mapflag	town
+amatsu	mapflag	town
+gonryun	mapflag	town
+ayothaya	mapflag	town
+louyang	mapflag	town
+hugel	mapflag	town
+rachel	mapflag	town
+veins	mapflag	town
 
 // Prontera
 //============================================================

+ 1 - 0
src/map/atcommand.h

@@ -24,6 +24,7 @@ void do_init_atcommand(void);
 void do_final_atcommand(void);
 int atcommand_config_read(const char *cfgName);
 
+int atcommand_mail(const int fd, struct map_session_data* sd,const char* command, const char* message);
 int atcommand_item(const int fd, struct map_session_data* sd,const char* command, const char* message);
 int atcommand_mapmove(const int fd, struct map_session_data* sd,const char* command, const char* message);
 int atcommand_monster(const int fd, struct map_session_data* sd, const char* command, const char* message);

+ 15 - 0
src/map/clif.c

@@ -11441,6 +11441,9 @@ void clif_parse_Mail_refreshinbox(int fd, struct map_session_data *sd)
 {
 	struct mail_data* md = &sd->mail.inbox;
 
+	if( mail_invalid_operation(sd) )
+		return;
+
 	if( md->amount < MAIL_MAX_INBOX && (md->full || md->changed) )
 		intif_Mail_requestinbox(sd->status.char_id, 1);
 	else
@@ -11517,6 +11520,9 @@ void clif_Mail_read(struct map_session_data *sd, int mail_id)
 
 void clif_parse_Mail_read(int fd, struct map_session_data *sd)
 {
+	if( mail_invalid_operation(sd) )
+		return;
+
 	clif_Mail_read(sd, RFIFOL(fd,2));
 }
 
@@ -11528,6 +11534,9 @@ void clif_parse_Mail_getattach(int fd, struct map_session_data *sd)
 	int i, mail_id = RFIFOL(fd,2);
 	bool fail = false;
 
+	if( mail_invalid_operation(sd) )
+		return;
+
 	ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
 	if( i == MAIL_MAX_INBOX )
 		return;
@@ -11580,6 +11589,9 @@ void clif_parse_Mail_delete(int fd, struct map_session_data *sd)
 {
 	int i, mail_id = RFIFOL(fd,2);
 
+	if( mail_invalid_operation(sd) )
+		return;
+
 	ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
 	if (i < MAIL_MAX_INBOX)
 	{
@@ -11602,6 +11614,9 @@ void clif_parse_Mail_return(int fd, struct map_session_data *sd)
 {
 	int i, mail_id = RFIFOL(fd,2);
 
+	if( mail_invalid_operation(sd) )
+		return;
+
 	ARR_FIND(0, MAIL_MAX_INBOX, i, sd->mail.inbox.msg[i].id == mail_id);
 	if (i < MAIL_MAX_INBOX)
 		intif_Mail_return(sd->status.char_id, mail_id);

+ 14 - 0
src/map/mail.c

@@ -4,8 +4,10 @@
 #ifndef TXT_ONLY
 
 #include "../common/nullpo.h"
+#include "../common/showmsg.h"
 
 #include "mail.h"
+#include "atcommand.h"
 #include "itemdb.h"
 #include "clif.h"
 #include "pc.h"
@@ -177,4 +179,16 @@ void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg)
 	clif_Mail_send(sd->fd, true);
 }
 
+// This function only check if the mail operations are valid
+bool mail_invalid_operation(struct map_session_data *sd)
+{
+	if( !map[sd->bl.m].flag.town && pc_isGM(sd) < get_atcommand_level(atcommand_mail) )
+	{
+		ShowWarning("clif_parse_Mail: char '%s' trying to do invalid mail operations.\n", sd->status.name);
+		return true;
+	}
+
+	return false;
+}
+
 #endif

+ 1 - 0
src/map/mail.h

@@ -16,5 +16,6 @@ bool mail_setattachment(struct map_session_data *sd, struct mail_message *msg);
 void mail_getattachment(struct map_session_data* sd, int zeny, struct item* item);
 int mail_openmail(struct map_session_data *sd);
 void mail_deliveryfail(struct map_session_data *sd, struct mail_message *msg);
+bool mail_invalid_operation(struct map_session_data *sd);
 
 #endif /* _MAIL_H_ */

+ 1 - 0
src/map/map.h

@@ -1164,6 +1164,7 @@ struct map_data {
 	int npc_num;
 	int users;
 	struct map_flag {
+		unsigned town : 1; // [Suggestion to protect Mail System]
 		unsigned autotrade : 1;
 		unsigned allowks : 1; // [Kill Steal Protection]
 		unsigned nomemo : 1;

+ 2 - 0
src/map/npc.c

@@ -2414,6 +2414,8 @@ static const char* npc_parse_mapflag(char* w1, char* w2, char* w3, char* w4, con
 		map[m].flag.autotrade=state;
 	else if (!strcmpi(w3,"allowks"))
 		map[m].flag.allowks=state; // [Kill Steal Protection]
+	else if (!strcmpi(w3,"town"))
+		map[m].flag.town=state;
 	else if (!strcmpi(w3,"nomemo"))
 		map[m].flag.nomemo=state;
 	else if (!strcmpi(w3,"noteleport"))