Преглед изворни кода

Cleaned up `char_del_option` checks

This is a squash commit for @cydh's pull request #1299.

Cleaned up the `char_del_option` checks.
Added a comment for `char_del_option`, that only work for clients that send delete request by using 0x0068 or 0x01fb.
Added an enum for values.
Added a function to validate and adjust configuration data.
Resolved character deletion not working properly for clients 2015-10-01 and higher (fixes #1189)
Delete date should be sent as remaining time on some client versions.
Adjusted some comment wording.
Added empty/default birthdate deletion.
Made email deletion case insensitive.
Cydh Ramdh пре 8 година
родитељ
комит
2a1aebaf64
5 измењених фајлова са 65 додато и 12 уклоњено
  1. 4 1
      conf/char_athena.conf
  2. 16 3
      src/char/char.c
  3. 5 0
      src/char/char.h
  4. 37 8
      src/char/char_clif.c
  5. 3 0
      src/common/mmo.h

+ 4 - 1
conf/char_athena.conf

@@ -172,11 +172,14 @@ char_del_delay: 86400
 
 // Restrict character deletion by email address or birthdate.
 // This restricts players from changing the langtype and deleting characters.
-// For birthdate, the client must be 20100803 or newer.
 // Defaults based on client date.
 // 1: Email address
 // 2: Birthdate
 // 3: Email address or Birthdate
+// IMPORTANT!
+// - This config only works for clients that send 0x0068 or 0x01fb for delete request.
+// - Use langtype 1 for newer clients (2013+), to use 0x01fb.
+// - Clients that are not using 0x0068 or 0x01fb, only use birthdate (YYMMDD) as default.
 char_del_option: 2
 
 // What folder the DB files are in (item_db.txt, etc.)

+ 16 - 3
src/char/char.c

@@ -1804,7 +1804,7 @@ int char_mmo_char_tobuf(uint8* buffer, struct mmo_charstatus* p)
 	offset += MAP_NAME_LENGTH_EXT;
 #endif
 #if PACKETVER >= 20100803
-#if (PACKETVER > 20130000 && PACKETVER < 20141016) || (PACKETVER >= 20150826 && PACKETVER < 20151001) || PACKETVER >= 20151104
+#if PACKETVER_CHAR_DELETEDATE
 	WBUFL(buf,124) = (p->delete_date?TOL(p->delete_date-time(NULL)):0);
 #else
 	WBUFL(buf,124) = TOL(p->delete_date);
@@ -2640,9 +2640,9 @@ void char_set_defaults(){
 	charserv_config.char_config.char_del_level = 0; //From which level u can delete character [Lupus]
 	charserv_config.char_config.char_del_delay = 86400;
 #if PACKETVER >= 20100803
-	charserv_config.char_config.char_del_option = 2;
+	charserv_config.char_config.char_del_option = CHAR_DEL_BIRTHDATE;
 #else
-	charserv_config.char_config.char_del_option = 1;
+	charserv_config.char_config.char_del_option = CHAR_DEL_EMAIL;
 #endif
 
 //	charserv_config.userid[24];
@@ -2986,6 +2986,18 @@ bool char_config_read(const char* cfgName, bool normal){
 	return true;
 }
 
+/**
+ * Checks for values out of range.
+ */
+static void char_config_adjust() {
+#if PACKETVER < 20100803
+	if (charserv_config.char_config.char_del_option&CHAR_DEL_BIRTHDATE) {
+		ShowWarning("conf/char_athena.conf:char_del_option birthdate is enabled but it requires PACKETVER 2010-08-03 or newer, defaulting to email...\n");
+		charserv_config.char_config.char_del_option &= ~CHAR_DEL_BIRTHDATE;
+	}
+#endif
+}
+
 /*
  * Message conf function
  */
@@ -3081,6 +3093,7 @@ int do_init(int argc, char **argv)
 
 	char_set_defaults();
 	char_config_read(CHAR_CONF_NAME, true);
+	char_config_adjust();
 	char_lan_config_read(LAN_CONF_NAME);
 	char_set_default_sql();
 	char_sql_config_read(SQL_CONF_NAME);

+ 5 - 0
src/char/char.h

@@ -32,6 +32,11 @@ enum {
 	TABLE_GUILD_STORAGE,
 };
 
+enum e_char_delete {
+	CHAR_DEL_EMAIL = 1,
+	CHAR_DEL_BIRTHDATE
+};
+
 struct Schema_Config {
 	int db_use_sqldbs;
 	char db_path[1024];

+ 37 - 8
src/char/char_clif.c

@@ -417,7 +417,11 @@ void chclif_char_delete2_ack(int fd, uint32 char_id, uint32 result, time_t delet
 	WFIFOW(fd,0) = 0x828;
 	WFIFOL(fd,2) = char_id;
 	WFIFOL(fd,6) = result;
+#if PACKETVER_CHAR_DELETEDATE
 	WFIFOL(fd,10) = TOL(delete_date-time(NULL));
+#else
+	WFIFOL(fd,10) = TOL(delete_date);
+#endif
 	WFIFOSET(fd,14);
 }
 
@@ -523,6 +527,37 @@ int chclif_parse_char_delete2_req(int fd, struct char_session_data* sd) {
 	return 1;
 }
 
+/**
+ * Check char deletion code
+ * @param sd
+ * @param delcode E-mail or birthdate
+ * @param flag Delete flag
+ * @return true:Success, false:Failure
+ **/
+static bool chclif_delchar_check(struct char_session_data *sd, char *delcode, uint8 flag) {
+	// E-Mail check
+	if (flag&CHAR_DEL_EMAIL && (
+			!stricmp(delcode, sd->email) || //email does not match or
+			(
+				!stricmp("a@a.com", sd->email) && //it is default email and
+				!strcmp("", delcode) //user sent an empty email
+			))) {
+			ShowInfo(""CL_RED"Char Deleted"CL_RESET" "CL_GREEN"(E-Mail)"CL_RESET".\n");
+			return true;
+	}
+	// Birthdate (YYMMDD)
+	if (flag&CHAR_DEL_BIRTHDATE && (
+		!strcmp(sd->birthdate+2, delcode) || // +2 to cut off the century
+		(
+			!strcmp("0000-00-00", sd->birthdate) && // it is default birthdate and
+			!strcmp("",delcode) // user sent an empty birthdate
+		))) {
+		ShowInfo(""CL_RED"Char Deleted"CL_RESET" "CL_GREEN"(Birthdate)"CL_RESET".\n");
+		return true;
+	}
+	return false;
+}
+
 // CH: <0829>.W <char id>.L <birth date:YYMMDD>.6B
 int chclif_parse_char_delete2_accept(int fd, struct char_session_data* sd) {
 	FIFOSD_CHECK(12)
@@ -572,8 +607,7 @@ int chclif_parse_char_delete2_accept(int fd, struct char_session_data* sd) {
 			return 1;
 		}
 
-		if( strcmp(sd->birthdate+2, birthdate) )  // +2 to cut off the century
-		{// birth date is wrong
+		if (!chclif_delchar_check(sd, birthdate, CHAR_DEL_BIRTHDATE)) { // Only check for birthdate
 			chclif_char_delete2_accept_ack(fd, char_id, 5);
 			return 1;
 		}
@@ -983,12 +1017,7 @@ int chclif_parse_delchar(int fd,struct char_session_data* sd, int cmd){
 		memcpy(email, RFIFOP(fd,6), 40);
 		RFIFOSKIP(fd,( cmd == 0x68) ? 46 : 56);
 
-		// Check if e-mail is correct
-		if(strcmpi(email, sd->email) && //email does not matches and
-			(strcmp("a@a.com", sd->email) || //it is not default email, or
-			(strcmp("a@a.com", email) && strcmp("", email)) //email sent does not matches default
-			))
-		{	//Fail
+		if (!chclif_delchar_check(sd, email, charserv_config.char_config.char_del_option)) {
 			chclif_refuse_delchar(fd,0); // 00 = Incorrect Email address
 			return 1;
 		}

+ 3 - 0
src/common/mmo.h

@@ -28,6 +28,9 @@
 // Check if the specified packetversion supports the pincode system
 #define PACKETVER_SUPPORTS_PINCODE PACKETVER>=20110309
 
+/// Check if the client needs delete_date as remaining time and not the actual delete_date (actually it was tested for clients since 2013)
+#define PACKETVER_CHAR_DELETEDATE (PACKETVER > 20130000 && PACKETVER < 20141016) || PACKETVER >= 20150826
+
 ///Remove/Comment this line to disable sc_data saving. [Skotlex]
 #define ENABLE_SC_SAVING
 /** Remove/Comment this line to disable server-side hot-key saving support [Skotlex]