浏览代码

Merged the PIN columns into main.sql
Some formating optimizations to parse_fromchar in login.c, credits to Ind for the idea.

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17185 54d463be-8e91-2dee-dedb-b68131a5f0ec

lemongrass3110 12 年之前
父节点
当前提交
ef8519546c
共有 2 个文件被更改,包括 333 次插入364 次删除
  1. 2 0
      sql-files/main.sql
  2. 331 364
      src/login/login.c

+ 2 - 0
sql-files/main.sql

@@ -439,6 +439,8 @@ CREATE TABLE IF NOT EXISTS `login` (
   `last_ip` varchar(100) NOT NULL default '',
   `birthdate` DATE NOT NULL DEFAULT '0000-00-00',
   `character_slots` tinyint(3) unsigned NOT NULL default '0',
+  `pincode` varchar(4) NOT NULL DEFAULT '',
+  `pincode_change` int(11) unsigned NOT NULL DEFAULT '0',
   PRIMARY KEY  (`account_id`),
   KEY `name` (`userid`)
 ) ENGINE=MyISAM AUTO_INCREMENT=2000000; 

+ 331 - 364
src/login/login.c

@@ -418,23 +418,20 @@ int parse_console(const char* command)
 //--------------------------------
 // Packet parsing for char-servers
 //--------------------------------
-int parse_fromchar(int fd)
-{
+int parse_fromchar(int fd){
 	int j, id;
 	uint32 ipl;
 	char ip[16];
 
 	ARR_FIND( 0, ARRAYLENGTH(server), id, server[id].fd == fd );
-	if( id == ARRAYLENGTH(server) )
-	{// not a char server
+	if( id == ARRAYLENGTH(server) ){// not a char server
 		ShowDebug("parse_fromchar: Disconnecting invalid session #%d (is not a char-server)\n", fd);
 		set_eof(fd);
 		do_close(fd);
 		return 0;
 	}
 
-	if( session[fd]->flag.eof )
-	{
+	if( session[fd]->flag.eof ){
 		do_close(fd);
 		server[id].fd = -1;
 		chrif_on_disconnect(id);
@@ -444,152 +441,145 @@ int parse_fromchar(int fd)
 	ipl = server[id].ip;
 	ip2str(ipl, ip);
 
-	while( RFIFOREST(fd) >= 2 )
-	{
+	while( RFIFOREST(fd) >= 2 ){
 		uint16 command = RFIFOW(fd,0);
 
-		switch( command )
-		{
+		switch( command ){
 
 		case 0x2712: // request from char-server to authenticate an account
 			if( RFIFOREST(fd) < 23 )
 				return 0;
-		{
-			struct auth_node* node;
-
-			int account_id = RFIFOL(fd,2);
-			uint32 login_id1 = RFIFOL(fd,6);
-			uint32 login_id2 = RFIFOL(fd,10);
-			uint8 sex = RFIFOB(fd,14);
-			//uint32 ip_ = ntohl(RFIFOL(fd,15));
-			int request_id = RFIFOL(fd,19);
-			RFIFOSKIP(fd,23);
-
-			node = (struct auth_node*)idb_get(auth_db, account_id);
-			if( runflag == LOGINSERVER_ST_RUNNING &&
-				node != NULL &&
-				node->account_id == account_id &&
-				node->login_id1  == login_id1 &&
-				node->login_id2  == login_id2 &&
-				node->sex        == sex_num2str(sex) /*&&
-				node->ip         == ip_*/ )
-			{// found
-				//ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
-
-				// send ack
-				WFIFOHEAD(fd,25);
-				WFIFOW(fd,0) = 0x2713;
-				WFIFOL(fd,2) = account_id;
-				WFIFOL(fd,6) = login_id1;
-				WFIFOL(fd,10) = login_id2;
-				WFIFOB(fd,14) = sex;
-				WFIFOB(fd,15) = 0;// ok
-				WFIFOL(fd,16) = request_id;
-				WFIFOL(fd,20) = node->version;
-				WFIFOB(fd,24) = node->clienttype;
-				WFIFOSET(fd,25);
-
-				// each auth entry can only be used once
-				idb_remove(auth_db, account_id);
-			}
-			else
-			{// authentication not found
-				ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
-				WFIFOHEAD(fd,25);
-				WFIFOW(fd,0) = 0x2713;
-				WFIFOL(fd,2) = account_id;
-				WFIFOL(fd,6) = login_id1;
-				WFIFOL(fd,10) = login_id2;
-				WFIFOB(fd,14) = sex;
-				WFIFOB(fd,15) = 1;// auth failed
-				WFIFOL(fd,16) = request_id;
-				WFIFOL(fd,20) = 0;
-				WFIFOB(fd,24) = 0;
-				WFIFOSET(fd,25);
+			else{
+				struct auth_node* node;
+
+				int account_id = RFIFOL(fd,2);
+				uint32 login_id1 = RFIFOL(fd,6);
+				uint32 login_id2 = RFIFOL(fd,10);
+				uint8 sex = RFIFOB(fd,14);
+				//uint32 ip_ = ntohl(RFIFOL(fd,15));
+				int request_id = RFIFOL(fd,19);
+				RFIFOSKIP(fd,23);
+
+				node = (struct auth_node*)idb_get(auth_db, account_id);
+				if( runflag == LOGINSERVER_ST_RUNNING &&
+					node != NULL &&
+					node->account_id == account_id &&
+					node->login_id1  == login_id1 &&
+					node->login_id2  == login_id2 &&
+					node->sex        == sex_num2str(sex) /*&&
+					node->ip         == ip_*/ ){// found
+					//ShowStatus("Char-server '%s': authentication of the account %d accepted (ip: %s).\n", server[id].name, account_id, ip);
+
+					// send ack
+					WFIFOHEAD(fd,25);
+					WFIFOW(fd,0) = 0x2713;
+					WFIFOL(fd,2) = account_id;
+					WFIFOL(fd,6) = login_id1;
+					WFIFOL(fd,10) = login_id2;
+					WFIFOB(fd,14) = sex;
+					WFIFOB(fd,15) = 0;// ok
+					WFIFOL(fd,16) = request_id;
+					WFIFOL(fd,20) = node->version;
+					WFIFOB(fd,24) = node->clienttype;
+					WFIFOSET(fd,25);
+
+					// each auth entry can only be used once
+					idb_remove(auth_db, account_id);
+				}else{// authentication not found
+					ShowStatus("Char-server '%s': authentication of the account %d REFUSED (ip: %s).\n", server[id].name, account_id, ip);
+					WFIFOHEAD(fd,25);
+					WFIFOW(fd,0) = 0x2713;
+					WFIFOL(fd,2) = account_id;
+					WFIFOL(fd,6) = login_id1;
+					WFIFOL(fd,10) = login_id2;
+					WFIFOB(fd,14) = sex;
+					WFIFOB(fd,15) = 1;// auth failed
+					WFIFOL(fd,16) = request_id;
+					WFIFOL(fd,20) = 0;
+					WFIFOB(fd,24) = 0;
+					WFIFOSET(fd,25);
+				}
 			}
-		}
 		break;
 
 		case 0x2714:
 			if( RFIFOREST(fd) < 6 )
 				return 0;
-		{
-			int users = RFIFOL(fd,2);
-			RFIFOSKIP(fd,6);
+			else{
+				int users = RFIFOL(fd,2);
+				RFIFOSKIP(fd,6);
 
-			// how many users on world? (update)
-			if( server[id].users != users )
-			{
-				ShowStatus("set users %s : %d\n", server[id].name, users);
+				// how many users on world? (update)
+				if( server[id].users != users ){
+					ShowStatus("set users %s : %d\n", server[id].name, users);
 
-				server[id].users = users;
+					server[id].users = users;
+				}
 			}
-		}
 		break;
 
 		case 0x2715: // request from char server to change e-email from default "a@a.com"
 			if (RFIFOREST(fd) < 46)
 				return 0;
-		{
-			struct mmo_account acc;
-			char email[40];
-
-			int account_id = RFIFOL(fd,2);
-			safestrncpy(email, (char*)RFIFOP(fd,6), 40); remove_control_chars(email);
-			RFIFOSKIP(fd,46);
-
-			if( e_mail_check(email) == 0 )
-				ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
-			else
-			if( !accounts->load_num(accounts, &acc, account_id) || strcmp(acc.email, "a@a.com") == 0 || acc.email[0] == '\0' )
-				ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, account_id, ip);
-			else {
-				memcpy(acc.email, email, 40);
-				ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, account_id, email, ip);
-				// Save
-				accounts->save(accounts, &acc);
+			else{
+				struct mmo_account acc;
+				char email[40];
+
+				int account_id = RFIFOL(fd,2);
+				safestrncpy(email, (char*)RFIFOP(fd,6), 40); remove_control_chars(email);
+				RFIFOSKIP(fd,46);
+
+				if( e_mail_check(email) == 0 )
+					ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - e-mail is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+				else if( !accounts->load_num(accounts, &acc, account_id) || strcmp(acc.email, "a@a.com") == 0 || acc.email[0] == '\0' )
+					ShowNotice("Char-server '%s': Attempt to create an e-mail on an account with a default e-mail REFUSED - account doesn't exist or e-mail of account isn't default e-mail (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+				else{
+					memcpy(acc.email, email, 40);
+					ShowNotice("Char-server '%s': Create an e-mail on an account with a default e-mail (account: %d, new e-mail: %s, ip: %s).\n", server[id].name, account_id, email, ip);
+					// Save
+					accounts->save(accounts, &acc);
+				}
 			}
-		}
 		break;
 
 		case 0x2716: // request account data
 			if( RFIFOREST(fd) < 6 )
 				return 0;
-		{
-			struct mmo_account acc;
-			time_t expiration_time = 0;
-			char email[40] = "";
-			uint8 char_slots = 0;
-			int group_id = 0;
-			char birthdate[10+1] = "";
-			char pincode[4+1] = "";
-
-			int account_id = RFIFOL(fd,2);
-			RFIFOSKIP(fd,6);
+			else{
+				struct mmo_account acc;
+				time_t expiration_time = 0;
+				char email[40] = "";
+				uint8 char_slots = 0;
+				int group_id = 0;
+				char birthdate[10+1] = "";
+				char pincode[4+1] = "";
+
+				int account_id = RFIFOL(fd,2);
+				RFIFOSKIP(fd,6);
+
+				if( !accounts->load_num(accounts, &acc, account_id) )
+					ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
+				else{
+					safestrncpy(email, acc.email, sizeof(email));
+					expiration_time = acc.expiration_time;
+					group_id = acc.group_id;
+					char_slots = acc.char_slots;
+					safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
+					safestrncpy(pincode, acc.pincode, sizeof(pincode));
+				}
 
-			if( !accounts->load_num(accounts, &acc, account_id) )
-				ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
-			else {
-				safestrncpy(email, acc.email, sizeof(email));
-				expiration_time = acc.expiration_time;
-				group_id = acc.group_id;
-				char_slots = acc.char_slots;
-				safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
-				safestrncpy(pincode, acc.pincode, sizeof(pincode));
+				WFIFOHEAD(fd,72);
+				WFIFOW(fd,0) = 0x2717;
+				WFIFOL(fd,2) = account_id;
+				safestrncpy((char*)WFIFOP(fd,6), email, 40);
+				WFIFOL(fd,46) = (uint32)expiration_time;
+				WFIFOB(fd,50) = (unsigned char)group_id;
+				WFIFOB(fd,51) = char_slots;
+				safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
+				safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
+				WFIFOL(fd,68) = (uint32)acc.pincode_change;
+				WFIFOSET(fd,72);
 			}
-
-			WFIFOHEAD(fd,72);
-			WFIFOW(fd,0) = 0x2717;
-			WFIFOL(fd,2) = account_id;
-			safestrncpy((char*)WFIFOP(fd,6), email, 40);
-			WFIFOL(fd,46) = (uint32)expiration_time;
-			WFIFOB(fd,50) = (unsigned char)group_id;
-			WFIFOB(fd,51) = char_slots;
-			safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
-			safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
-			WFIFOL(fd,68) = (uint32)acc.pincode_change;
-			WFIFOSET(fd,72);
-		}
 		break;
 
 		case 0x2719: // ping request from charserver
@@ -604,228 +594,214 @@ int parse_fromchar(int fd)
 		case 0x2722:	// 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
 			if (RFIFOREST(fd) < 86)
 				return 0;
-		{
-			struct mmo_account acc;
-			char actual_email[40];
-			char new_email[40];
-
-			int account_id = RFIFOL(fd,2);
-			safestrncpy(actual_email, (char*)RFIFOP(fd,6), 40);
-			safestrncpy(new_email, (char*)RFIFOP(fd,46), 40);
-			RFIFOSKIP(fd, 86);
-
-			if( e_mail_check(actual_email) == 0 )
-				ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
-			else
-			if( e_mail_check(new_email) == 0 )
-				ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
-			else
-			if( strcmpi(new_email, "a@a.com") == 0 )
-				ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
-			else
-			if( !accounts->load_num(accounts, &acc, account_id) )
-				ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", server[id].name, account_id, ip);
-			else
-			if( strcmpi(acc.email, actual_email) != 0 )
-				ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
-			else {
-				safestrncpy(acc.email, new_email, 40);
-				ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, new_email, ip);
-				// Save
-				accounts->save(accounts, &acc);
+			else{
+				struct mmo_account acc;
+				char actual_email[40];
+				char new_email[40];
+
+				int account_id = RFIFOL(fd,2);
+				safestrncpy(actual_email, (char*)RFIFOP(fd,6), 40);
+				safestrncpy(new_email, (char*)RFIFOP(fd,46), 40);
+				RFIFOSKIP(fd, 86);
+
+				if( e_mail_check(actual_email) == 0 )
+					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual email is invalid (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+				else if( e_mail_check(new_email) == 0 )
+					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a invalid new e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+				else if( strcmpi(new_email, "a@a.com") == 0 )
+					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command) with a default e-mail (account: %d, ip: %s)\n", server[id].name, account_id, ip);
+				else if( !accounts->load_num(accounts, &acc, account_id) )
+					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but account doesn't exist (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+				else if( strcmpi(acc.email, actual_email) != 0 )
+					ShowNotice("Char-server '%s': Attempt to modify an e-mail on an account (@email GM command), but actual e-mail is incorrect (account: %d (%s), actual e-mail: %s, proposed e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, acc.email, actual_email, ip);
+				else{
+					safestrncpy(acc.email, new_email, 40);
+					ShowNotice("Char-server '%s': Modify an e-mail on an account (@email GM command) (account: %d (%s), new e-mail: %s, ip: %s).\n", server[id].name, account_id, acc.userid, new_email, ip);
+					// Save
+					accounts->save(accounts, &acc);
+				}
 			}
-		}
 		break;
 
 		case 0x2724: // Receiving an account state update request from a map-server (relayed via char-server)
 			if (RFIFOREST(fd) < 10)
 				return 0;
-		{
-			struct mmo_account acc;
+			else{
+				struct mmo_account acc;
 
-			int account_id = RFIFOL(fd,2);
-			unsigned int state = RFIFOL(fd,6);
-			RFIFOSKIP(fd,10);
+				int account_id = RFIFOL(fd,2);
+				unsigned int state = RFIFOL(fd,6);
+				RFIFOSKIP(fd,10);
 
-			if( !accounts->load_num(accounts, &acc, account_id) )
-				ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n", server[id].name, account_id, state, ip);
-			else
-			if( acc.state == state )
-				ShowNotice("Char-server '%s':  Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n", server[id].name, account_id, state, ip);
-			else {
-				ShowNotice("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n", server[id].name, account_id, state, ip);
-
-				acc.state = state;
-				// Save
-				accounts->save(accounts, &acc);
-
-				// notify other servers
-				if (state != 0) {
-					uint8 buf[11];
-					WBUFW(buf,0) = 0x2731;
-					WBUFL(buf,2) = account_id;
-					WBUFB(buf,6) = 0; // 0: change of state, 1: ban
-					WBUFL(buf,7) = state; // status or final date of a banishment
-					charif_sendallwos(-1, buf, 11);
+				if( !accounts->load_num(accounts, &acc, account_id) )
+					ShowNotice("Char-server '%s': Error of Status change (account: %d not found, suggested status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+				else if( acc.state == state )
+					ShowNotice("Char-server '%s':  Error of Status change - actual status is already the good status (account: %d, status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+				else{
+					ShowNotice("Char-server '%s': Status change (account: %d, new status %d, ip: %s).\n", server[id].name, account_id, state, ip);
+
+					acc.state = state;
+					// Save
+					accounts->save(accounts, &acc);
+
+					// notify other servers
+					if (state != 0){
+						uint8 buf[11];
+						WBUFW(buf,0) = 0x2731;
+						WBUFL(buf,2) = account_id;
+						WBUFB(buf,6) = 0; // 0: change of state, 1: ban
+						WBUFL(buf,7) = state; // status or final date of a banishment
+						charif_sendallwos(-1, buf, 11);
+					}
 				}
 			}
-		}
 		break;
 
 		case 0x2725: // Receiving of map-server via char-server a ban request
 			if (RFIFOREST(fd) < 18)
 				return 0;
-		{
-			struct mmo_account acc;
-
-			int account_id = RFIFOL(fd,2);
-			int year = (short)RFIFOW(fd,6);
-			int month = (short)RFIFOW(fd,8);
-			int mday = (short)RFIFOW(fd,10);
-			int hour = (short)RFIFOW(fd,12);
-			int min = (short)RFIFOW(fd,14);
-			int sec = (short)RFIFOW(fd,16);
-			RFIFOSKIP(fd,18);
-
-			if( !accounts->load_num(accounts, &acc, account_id) )
-				ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
-			else
-			{
-				time_t timestamp;
-				struct tm *tmtime;
-				if (acc.unban_time == 0 || acc.unban_time < time(NULL))
-					timestamp = time(NULL); // new ban
-				else
-					timestamp = acc.unban_time; // add to existing ban
-				tmtime = localtime(&timestamp);
-				tmtime->tm_year = tmtime->tm_year + year;
-				tmtime->tm_mon  = tmtime->tm_mon + month;
-				tmtime->tm_mday = tmtime->tm_mday + mday;
-				tmtime->tm_hour = tmtime->tm_hour + hour;
-				tmtime->tm_min  = tmtime->tm_min + min;
-				tmtime->tm_sec  = tmtime->tm_sec + sec;
-				timestamp = mktime(tmtime);
-				if (timestamp == -1)
-					ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", server[id].name, account_id, ip);
-				else
-				if( timestamp <= time(NULL) || timestamp == 0 )
-					ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", server[id].name, account_id, ip);
-				else
-				{
-					uint8 buf[11];
-					char tmpstr[24];
-					timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login_config.date_format);
-					ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %d (%s), ip: %s).\n", server[id].name, account_id, timestamp, tmpstr, ip);
-
-					acc.unban_time = timestamp;
-
-					// Save
-					accounts->save(accounts, &acc);
-
-					WBUFW(buf,0) = 0x2731;
-					WBUFL(buf,2) = account_id;
-					WBUFB(buf,6) = 1; // 0: change of status, 1: ban
-					WBUFL(buf,7) = (uint32)timestamp; // status or final date of a banishment
-					charif_sendallwos(-1, buf, 11);
+			else{
+				struct mmo_account acc;
+
+				int account_id = RFIFOL(fd,2);
+				int year = (short)RFIFOW(fd,6);
+				int month = (short)RFIFOW(fd,8);
+				int mday = (short)RFIFOW(fd,10);
+				int hour = (short)RFIFOW(fd,12);
+				int min = (short)RFIFOW(fd,14);
+				int sec = (short)RFIFOW(fd,16);
+				RFIFOSKIP(fd,18);
+
+				if( !accounts->load_num(accounts, &acc, account_id) )
+					ShowNotice("Char-server '%s': Error of ban request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+				else{
+					time_t timestamp;
+					struct tm *tmtime;
+					if (acc.unban_time == 0 || acc.unban_time < time(NULL))
+						timestamp = time(NULL); // new ban
+					else
+						timestamp = acc.unban_time; // add to existing ban
+					tmtime = localtime(&timestamp);
+					tmtime->tm_year = tmtime->tm_year + year;
+					tmtime->tm_mon  = tmtime->tm_mon + month;
+					tmtime->tm_mday = tmtime->tm_mday + mday;
+					tmtime->tm_hour = tmtime->tm_hour + hour;
+					tmtime->tm_min  = tmtime->tm_min + min;
+					tmtime->tm_sec  = tmtime->tm_sec + sec;
+					timestamp = mktime(tmtime);
+					if (timestamp == -1)
+						ShowNotice("Char-server '%s': Error of ban request (account: %d, invalid date, ip: %s).\n", server[id].name, account_id, ip);
+					else if( timestamp <= time(NULL) || timestamp == 0 )
+						ShowNotice("Char-server '%s': Error of ban request (account: %d, new date unbans the account, ip: %s).\n", server[id].name, account_id, ip);
+					else{
+						uint8 buf[11];
+						char tmpstr[24];
+						timestamp2string(tmpstr, sizeof(tmpstr), timestamp, login_config.date_format);
+						ShowNotice("Char-server '%s': Ban request (account: %d, new final date of banishment: %d (%s), ip: %s).\n", server[id].name, account_id, timestamp, tmpstr, ip);
+
+						acc.unban_time = timestamp;
+
+						// Save
+						accounts->save(accounts, &acc);
+
+						WBUFW(buf,0) = 0x2731;
+						WBUFL(buf,2) = account_id;
+						WBUFB(buf,6) = 1; // 0: change of status, 1: ban
+						WBUFL(buf,7) = (uint32)timestamp; // status or final date of a banishment
+						charif_sendallwos(-1, buf, 11);
+					}
 				}
 			}
-		}
 		break;
 
 		case 0x2727: // Change of sex (sex is reversed)
 			if( RFIFOREST(fd) < 6 )
 				return 0;
-		{
-			struct mmo_account acc;
+			else{
+				struct mmo_account acc;
 
-			int account_id = RFIFOL(fd,2);
-			RFIFOSKIP(fd,6);
+				int account_id = RFIFOL(fd,2);
+				RFIFOSKIP(fd,6);
 
-			if( !accounts->load_num(accounts, &acc, account_id) )
-				ShowNotice("Char-server '%s': Error of sex change (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
-			else
-			if( acc.sex == 'S' )
-				ShowNotice("Char-server '%s': Error of sex change - account to change is a Server account (account: %d, ip: %s).\n", server[id].name, account_id, ip);
-			else
-			{
-				unsigned char buf[7];
-				char sex = ( acc.sex == 'M' ) ? 'F' : 'M'; //Change gender
+				if( !accounts->load_num(accounts, &acc, account_id) )
+					ShowNotice("Char-server '%s': Error of sex change (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+				else if( acc.sex == 'S' )
+					ShowNotice("Char-server '%s': Error of sex change - account to change is a Server account (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+				else{
+					unsigned char buf[7];
+					char sex = ( acc.sex == 'M' ) ? 'F' : 'M'; //Change gender
 
-				ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", server[id].name, account_id, sex, ip);
+					ShowNotice("Char-server '%s': Sex change (account: %d, new sex %c, ip: %s).\n", server[id].name, account_id, sex, ip);
 
-				acc.sex = sex;
-				// Save
-				accounts->save(accounts, &acc);
+					acc.sex = sex;
+					// Save
+					accounts->save(accounts, &acc);
 
-				// announce to other servers
-				WBUFW(buf,0) = 0x2723;
-				WBUFL(buf,2) = account_id;
-				WBUFB(buf,6) = sex_str2num(sex);
-				charif_sendallwos(-1, buf, 7);
+					// announce to other servers
+					WBUFW(buf,0) = 0x2723;
+					WBUFL(buf,2) = account_id;
+					WBUFB(buf,6) = sex_str2num(sex);
+					charif_sendallwos(-1, buf, 7);
+				}
 			}
-		}
 		break;
 
 		case 0x2728:	// We receive account_reg2 from a char-server, and we send them to other map-servers.
 			if( RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2) )
 				return 0;
-		{
-			struct mmo_account acc;
+			else{
+				struct mmo_account acc;
+
+				int account_id = RFIFOL(fd,4);
+
+				if( !accounts->load_num(accounts, &acc, account_id) )
+					ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+				else{
+					int len;
+					int p;
+					ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+					for( j = 0, p = 13; j < ACCOUNT_REG2_NUM && p < RFIFOW(fd,2); ++j ){
+						sscanf((char*)RFIFOP(fd,p), "%31c%n", acc.account_reg2[j].str, &len);
+						acc.account_reg2[j].str[len]='\0';
+						p +=len+1; //+1 to skip the '\0' between strings.
+						sscanf((char*)RFIFOP(fd,p), "%255c%n", acc.account_reg2[j].value, &len);
+						acc.account_reg2[j].value[len]='\0';
+						p +=len+1;
+						remove_control_chars(acc.account_reg2[j].str);
+						remove_control_chars(acc.account_reg2[j].value);
+					}
+					acc.account_reg2_num = j;
 
-			int account_id = RFIFOL(fd,4);
+					// Save
+					accounts->save(accounts, &acc);
 
-			if( !accounts->load_num(accounts, &acc, account_id) )
-				ShowStatus("Char-server '%s': receiving (from the char-server) of account_reg2 (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
-			else
-			{
-				int len;
-				int p;
-				ShowNotice("char-server '%s': receiving (from the char-server) of account_reg2 (account: %d, ip: %s).\n", server[id].name, account_id, ip);
-				for( j = 0, p = 13; j < ACCOUNT_REG2_NUM && p < RFIFOW(fd,2); ++j )
-				{
-					sscanf((char*)RFIFOP(fd,p), "%31c%n", acc.account_reg2[j].str, &len);
-					acc.account_reg2[j].str[len]='\0';
-					p +=len+1; //+1 to skip the '\0' between strings.
-					sscanf((char*)RFIFOP(fd,p), "%255c%n", acc.account_reg2[j].value, &len);
-					acc.account_reg2[j].value[len]='\0';
-					p +=len+1;
-					remove_control_chars(acc.account_reg2[j].str);
-					remove_control_chars(acc.account_reg2[j].value);
+					// Sending information towards the other char-servers.
+					RFIFOW(fd,0) = 0x2729;// reusing read buffer
+					charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2));
 				}
-				acc.account_reg2_num = j;
-
-				// Save
-				accounts->save(accounts, &acc);
-
-				// Sending information towards the other char-servers.
-				RFIFOW(fd,0) = 0x2729;// reusing read buffer
-				charif_sendallwos(fd, RFIFOP(fd,0), RFIFOW(fd,2));
+				RFIFOSKIP(fd,RFIFOW(fd,2));
 			}
-			RFIFOSKIP(fd,RFIFOW(fd,2));
-		}
 		break;
 
 		case 0x272a:	// Receiving of map-server via char-server an unban request
 			if( RFIFOREST(fd) < 6 )
 				return 0;
-		{
-			struct mmo_account acc;
-
-			int account_id = RFIFOL(fd,2);
-			RFIFOSKIP(fd,6);
-
-			if( !accounts->load_num(accounts, &acc, account_id) )
-				ShowNotice("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
-			else
-			if( acc.unban_time == 0 )
-				ShowNotice("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n", server[id].name, account_id, ip);
-			else
-			{
-				ShowNotice("Char-server '%s': UnBan request (account: %d, ip: %s).\n", server[id].name, account_id, ip);
-				acc.unban_time = 0;
-				accounts->save(accounts, &acc);
+			else{
+				struct mmo_account acc;
+
+				int account_id = RFIFOL(fd,2);
+				RFIFOSKIP(fd,6);
+
+				if( !accounts->load_num(accounts, &acc, account_id) )
+					ShowNotice("Char-server '%s': Error of UnBan request (account: %d not found, ip: %s).\n", server[id].name, account_id, ip);
+				else if( acc.unban_time == 0 )
+					ShowNotice("Char-server '%s': Error of UnBan request (account: %d, no change for unban date, ip: %s).\n", server[id].name, account_id, ip);
+				else{
+					ShowNotice("Char-server '%s': UnBan request (account: %d, ip: %s).\n", server[id].name, account_id, ip);
+					acc.unban_time = 0;
+					accounts->save(accounts, &acc);
+				}
 			}
-		}
 		break;
 
 		case 0x272b:    // Set account_id to online [Wizputer]
@@ -845,7 +821,7 @@ int parse_fromchar(int fd)
 		case 0x272d:	// Receive list of all online accounts. [Skotlex]
 			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
 				return 0;
-			{
+			else{
 				struct online_login_data *p;
 				int aid;
 				uint32 i, users;
@@ -855,49 +831,46 @@ int parse_fromchar(int fd)
 					aid = RFIFOL(fd,6+i*4);
 					p = idb_ensure(online_db, aid, create_online_user);
 					p->char_server = id;
-					if (p->waiting_disconnect != INVALID_TIMER)
-					{
+					if (p->waiting_disconnect != INVALID_TIMER){
 						delete_timer(p->waiting_disconnect, waiting_disconnect_timer);
 						p->waiting_disconnect = INVALID_TIMER;
 					}
 				}
+
+				RFIFOSKIP(fd,RFIFOW(fd,2));
 			}
-			RFIFOSKIP(fd,RFIFOW(fd,2));
 		break;
 
 		case 0x272e: //Request account_reg2 for a character.
 			if (RFIFOREST(fd) < 10)
 				return 0;
-		{
-			struct mmo_account acc;
-			size_t off;
-
-			int account_id = RFIFOL(fd,2);
-			int char_id = RFIFOL(fd,6);
-			RFIFOSKIP(fd,10);
-
-			WFIFOHEAD(fd,ACCOUNT_REG2_NUM*sizeof(struct global_reg));
-			WFIFOW(fd,0) = 0x2729;
-			WFIFOL(fd,4) = account_id;
-			WFIFOL(fd,8) = char_id;
-			WFIFOB(fd,12) = 1; //Type 1 for Account2 registry
-
-			off = 13;
-			if( accounts->load_num(accounts, &acc, account_id) )
-			{
-				for( j = 0; j < acc.account_reg2_num; j++ )
-				{
-					if( acc.account_reg2[j].str[0] != '\0' )
-					{
-						off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].str)+1; //We add 1 to consider the '\0' in place.
-						off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].value)+1;
+			else{
+				struct mmo_account acc;
+				size_t off;
+
+				int account_id = RFIFOL(fd,2);
+				int char_id = RFIFOL(fd,6);
+				RFIFOSKIP(fd,10);
+
+				WFIFOHEAD(fd,ACCOUNT_REG2_NUM*sizeof(struct global_reg));
+				WFIFOW(fd,0) = 0x2729;
+				WFIFOL(fd,4) = account_id;
+				WFIFOL(fd,8) = char_id;
+				WFIFOB(fd,12) = 1; //Type 1 for Account2 registry
+
+				off = 13;
+				if( accounts->load_num(accounts, &acc, account_id) ){
+					for( j = 0; j < acc.account_reg2_num; j++ ){
+						if( acc.account_reg2[j].str[0] != '\0' ){
+							off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].str)+1; //We add 1 to consider the '\0' in place.
+							off += sprintf((char*)WFIFOP(fd,off), "%s", acc.account_reg2[j].value)+1;
+						}
 					}
 				}
-			}
 
-			WFIFOW(fd,2) = (uint16)off;
-			WFIFOSET(fd,WFIFOW(fd,2));
-		}
+				WFIFOW(fd,2) = (uint16)off;
+				WFIFOSET(fd,WFIFOW(fd,2));
+			}
 		break;
 
 		case 0x2736: // WAN IP update from char-server
@@ -917,49 +890,43 @@ int parse_fromchar(int fd)
 		case 0x2738: //Change PIN Code for a account
 			if( RFIFOREST(fd) < 15 )
 				return 0;
-
-		{
-			struct mmo_account acc;
-
-			if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) )
-			{
-				strncpy( acc.pincode, (char*)RFIFOP(fd,6), 5 );
-				acc.pincode_change = RFIFOL(fd,11);
-				if( acc.pincode_change > 0 ){
-					acc.pincode_change += time( NULL );
+			else{
+				struct mmo_account acc;
+
+				if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ){
+					strncpy( acc.pincode, (char*)RFIFOP(fd,6), 5 );
+					acc.pincode_change = RFIFOL(fd,11);
+					if( acc.pincode_change > 0 ){
+						acc.pincode_change += time( NULL );
+					}
+					accounts->save(accounts, &acc);
 				}
-				accounts->save(accounts, &acc);
-			}
 
-			
-		}
-			RFIFOSKIP(fd,15);
+				RFIFOSKIP(fd,15);
+			}
 		break;
 
 		case 0x2739: // PIN Code was entered wrong too often
 			if( RFIFOREST(fd) < 6 )
 				return 0;
+			else{
+				struct mmo_account acc;
 
-		{
-			
-			struct mmo_account acc;
+				if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ){
+					struct online_login_data* ld;
 
-			if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) )
-			{
-				struct online_login_data* ld;
+					ld = (struct online_login_data*)idb_get(online_db,acc.account_id);
 
-				ld = (struct online_login_data*)idb_get(online_db,acc.account_id);
+					if( ld == NULL )
+						return 0;
 
-				if( ld == NULL )
-					return 0;
+					login_log( host2ip(acc.last_ip), acc.userid, 100, "PIN Code check failed" );
+				}
 
-				login_log( host2ip(acc.last_ip), acc.userid, 100, "PIN Code check failed" );
-			}
+				remove_online_user(acc.account_id);
 
-			remove_online_user(acc.account_id);
-		}
-			
-			RFIFOSKIP(fd,6);
+				RFIFOSKIP(fd,6);
+			}
 		break;
 
 		default: