Browse Source

InterPacket_rearrange

-Move charban and charunban packet out of 0x2b0e and mark that fonction
reserved for login request purpose.
(Charban and charunban now use 0x2b28 and 0x2b2a)
-Move chrif_savebankdata, chrif_datarequest, chrif_req_vipactive into
0x2b0e (as their some login operation request)
-Harmonize vip_time data type and fix some case where he would have get
INT_MAX value.
-Small revert on a3f0aedf @vip for vip_time alteration as the duration
should be able to get reduced.
-Fix vip_status(3) args of aFree 0x18E2777C is overflowed pointer
and incorect data returned, (altough dunno if we want this as returned
presentation string)
-fix bugreport:8289 where VIP_request anwser was broadcasted to all
mapserv
-Upd split_time month and year factor for a better approximation of
date. (splitting timestamp into years, month, days ...)
-Add loginif_isconnected to check if the loginserv is connected to char.
lighta 11 years ago
parent
commit
4684090de9
12 changed files with 436 additions and 428 deletions
  1. 1 1
      conf/msg_conf/map_msg.conf
  2. 281 276
      src/char/char.c
  3. 2 2
      src/common/timer.c
  4. 1 1
      src/login/account.h
  5. 23 19
      src/login/login.c
  6. 24 20
      src/map/atcommand.c
  7. 66 75
      src/map/chrif.c
  8. 7 5
      src/map/chrif.h
  9. 6 2
      src/map/pc.c
  10. 2 2
      src/map/pc.h
  11. 21 23
      src/map/script.c
  12. 2 2
      src/map/trade.c

+ 1 - 1
conf/msg_conf/map_msg.conf

@@ -441,7 +441,7 @@
 420: Your account has not more authorised.
 421: Your account has been totally erased.
 423: Your %s has been banished until %s 
-424: %s has been asked to %s the player '%.*s'.
+424: login-serv has been asked to %s the player '%.*s'.
 425: The player '%.*s' doesn't exist.
 426: Your GM level don't authorise you to %s the player '%.*s'.
 427: Login-server is offline. Impossible to %s the player '%.*s'.

+ 281 - 276
src/char/char.c

@@ -186,10 +186,9 @@ void pincode_notifyLoginPinError( int account_id );
 void pincode_decrypt( uint32 userSeed, char* pin );
 int pincode_compare( int fd, struct char_session_data* sd, char* pin );
 
-int mapif_parse_vipactive(int fd);
-int mapif_vipack(uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid);
-int logif_reqviddata(uint32 aid, uint8 type, uint32 add_vip_time);
-int logif_parse_vipack(int fd);
+int mapif_vipack(int mapfd, uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid);
+int loginif_reqviddata(uint32 aid, uint8 type, int add_vip_time, int mapfd);
+int loginif_parse_vipack(int fd);
 
 // Addon system
 bool char_move_enabled = true;
@@ -202,8 +201,6 @@ void moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short ind
 int loginif_BankingReq(int32 account_id, int8 type, int32 data);
 int loginif_parse_BankingAck(int fd);
 int mapif_BankingAck(int32 account_id, int32 bank_vault);
-int mapif_parse_UpdBankInfo(int fd);
-int mapif_parse_ReqBankInfo(int fd);
 
 //Custom limits for the fame lists. [Skotlex]
 int fame_list_size_chemist = MAX_FAME_LIST;
@@ -266,6 +263,9 @@ static DBMap* online_char_db; // int account_id -> struct online_char_data*
 static int chardb_waiting_disconnect(int tid, unsigned int tick, int id, intptr_t data);
 int delete_char_sql(int char_id);
 
+int loginif_isconnected();
+#define loginif_check(a) { if(!loginif_isconnected()) return a; }
+
 /**
  * @see DBCreateData
  */
@@ -299,7 +299,7 @@ void set_char_charselect(int account_id)
 		character->waiting_disconnect = INVALID_TIMER;
 	}
 
-	if (login_fd > 0 && !session[login_fd]->flag.eof)
+	if (loginif_isconnected())
 	{
 		WFIFOHEAD(login_fd,6);
 		WFIFOW(login_fd,0) = 0x272b;
@@ -345,7 +345,7 @@ void set_char_online(int map_id, int char_id, int account_id)
 	inter_guild_CharOnline(char_id, cp?cp->guild_id:-1);
 
 	//Notify login server
-	if (login_fd > 0 && !session[login_fd]->flag.eof)
+	if (loginif_isconnected())
 	{
 		WFIFOHEAD(login_fd,6);
 		WFIFOW(login_fd,0) = 0x272b;
@@ -397,7 +397,7 @@ void set_char_offline(int char_id, int account_id)
 	}
 
 	//Remove char if 1- Set all offline, or 2- character is no longer connected to char-server.
-	if (login_fd > 0 && !session[login_fd]->flag.eof && (char_id == -1 || character == NULL || character->fd == -1))
+	if (loginif_isconnected() && (char_id == -1 || character == NULL || character->fd == -1))
 	{
 		WFIFOHEAD(login_fd,6);
 		WFIFOW(login_fd,0) = 0x272c;
@@ -455,7 +455,7 @@ void set_all_offline(int id)
 		ShowNotice("Sending users of map-server %d offline.\n",id);
 	online_char_db->foreach(online_char_db,char_db_kickoffline,id);
 
-	if (id >= 0 || login_fd <= 0 || session[login_fd]->flag.eof)
+	if (id >= 0 || !loginif_isconnected())
 		return;
 	//Tell login-server to also mark all our characters as offline.
 	WFIFOHEAD(login_fd,2);
@@ -572,7 +572,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		} else
 			strcat(save_status, " status");
 	}
-	
+
 	//Values that will seldom change (to speed up saving)
 	if (
 		(p->hair != cp->hair) || (p->hair_color != cp->hair_color) || (p->clothes_color != cp->clothes_color) ||
@@ -611,7 +611,7 @@ int mmo_char_tosql(int char_id, struct mmo_charstatus* p)
 		else
 			errors++;
 	}
-	
+
 	//memo points
 	if( memcmp(p->memo_point, cp->memo_point, sizeof(p->memo_point)) )
 	{
@@ -1969,7 +1969,7 @@ void char_block_character( int fd, struct char_session_data* sd ){
 	int i=0, len=4;
 	char szExpireDate[20];
 	time_t now = time(NULL);
-	
+
 	ARR_FIND(0, MAX_CHARS, i, sd->unban_time[i] > now); //should we use MAX_CHARS or sd->charslot
 	if(i < MAX_CHARS){
 		memset(szExpireDate,'\0',20);
@@ -2058,7 +2058,7 @@ void mmo_char_send(int fd, struct char_session_data* sd){
 		char_charlist_notify(fd,sd);
 		char_block_character(fd,sd);
 	}
-	//else 
+	//else
 	//@FIXME dump from kro doesn't show 6b transmission
 	mmo_char_send006b(fd,sd);
 }
@@ -2137,7 +2137,7 @@ void disconnect_player(int account_id)
 	struct char_session_data* sd;
 
 	// disconnect player if online on char-server
-	ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == account_id );
+	ARR_FIND( 0, fd_max, i, session[i] && (sd = (struct char_session_data*)session[i]->session_data) && sd->account_id == account_id);
 	if( i < fd_max )
 		set_eof(i);
 }
@@ -2170,7 +2170,7 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
 		character->fd = fd;
 	}
 
-	if (login_fd > 0) {
+	if (loginif_isconnected()) {
 		// request account data
 		WFIFOHEAD(login_fd,6);
 		WFIFOW(login_fd,0) = 0x2716;
@@ -2197,22 +2197,21 @@ void mapif_server_reset(int id);
  *  1 = update
  */
 int loginif_BankingReq(int32 account_id, int8 type, int32 data){
-	if (login_fd > 0 && session[login_fd] && !session[login_fd]->flag.eof){
-		WFIFOHEAD(login_fd,11);
-		WFIFOW(login_fd,0) = 0x2740;
-		WFIFOL(login_fd,2) = account_id;
-		WFIFOB(login_fd,6) = type;
-		WFIFOL(login_fd,7) = data;
-		WFIFOSET(login_fd,11);
-		return 1;
-	}
+	loginif_check(-1);
+	
+	WFIFOHEAD(login_fd,11);
+	WFIFOW(login_fd,0) = 0x2740;
+	WFIFOL(login_fd,2) = account_id;
+	WFIFOB(login_fd,6) = type;
+	WFIFOL(login_fd,7) = data;
+	WFIFOSET(login_fd,11);
 	return 0;
 }
 
 /*
  * Received the banking data from login and transmit it to all map-serv
  * AH 0x2741<aid>L <bank_vault>L <not_fw>B
- * HZ 0x2b29 <aid>L <bank_vault>L 
+ * HZ 0x2b29 <aid>L <bank_vault>L
  */
 int loginif_parse_BankingAck(int fd){
 	if (RFIFOREST(fd) < 11)
@@ -2222,7 +2221,7 @@ int loginif_parse_BankingAck(int fd){
 		int32 bank_vault = RFIFOL(fd,6);
 		char not_fw = RFIFOB(fd,10);
 		RFIFOSKIP(fd,11);
- 	
+
 		if(not_fw==0) mapif_BankingAck(aid, bank_vault);
 	}
 	return 1;
@@ -2234,67 +2233,15 @@ int mapif_BankingAck(int32 account_id, int32 bank_vault){
 	WBUFW(buf,0) = 0x2b29;
 	WBUFL(buf,2) = account_id;
 	WBUFL(buf,6) = bank_vault;
-  	mapif_sendall(buf, 10); //inform all maps-attached
-	return 1;
-}
-
-/*
- *  Receive a map request to save banking
- * Fowarding it to login-serv
- * ZH 0x2b28 <aid>L <money>L
- * HA 0x2740<aid>L <type>B <money>L
- */
-int mapif_parse_UpdBankInfo(int fd){
-	if( RFIFOREST(fd) < 10 )
-		return 0;
-	else {
-		uint32 aid = RFIFOL(fd,2);
-		int money = RFIFOL(fd,6);
-		RFIFOSKIP(fd,10);
-		loginif_BankingReq(aid, 2, money);
-	}
-	return 1;
-}
-
-/*
- *  Receive a map request to get banking info
- * Fowarding it to login-serv
- * ZH 0x2b2a <aid>L
- * HA 0x2740<aid>L <type>B <money>L
- */
-int mapif_parse_ReqBankInfo(int fd){
-	if( RFIFOREST(fd) < 6 )
-		return 0;
-	else {
-		uint32 aid = RFIFOL(fd,2);
-		RFIFOSKIP(fd,6);
-		loginif_BankingReq(aid, 1, 0);  
-	}
+	mapif_sendall(buf, 10); //inform all maps-attached
 	return 1;
 }
 
-/*
- * ZH 0x2b2c
- * HA 0x2742
- * We received a request vip_info from map-server.
- * Transmit it to login-serv as it's the one knowing the info
- */
-int mapif_parse_vipactive(int fd) {
-#ifdef VIP_ENABLE
-	uint32 aid = RFIFOL(fd,2); //aid
-	uint8 type = RFIFOB(fd,6); //type
-	uint32 adddur = RFIFOL(fd,7); //req_inc_duration
-	RFIFOSKIP(fd,11);
-	logif_reqviddata(aid, type, adddur);
-#endif
-	return 0;
-}
-
 /*
  * HZ 0x2b2b
  * Transmist vip data to mapserv
  */
-int mapif_vipack(uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid) {
+int mapif_vipack(int mapfd, uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid) {
 #ifdef VIP_ENABLE
 	uint8 buf[16];
 	WBUFW(buf,0) = 0x2b2b;
@@ -2302,23 +2249,30 @@ int mapif_vipack(uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid) {
 	WBUFL(buf,6) = vip_time;
 	WBUFB(buf,10) = isvip;
 	WBUFL(buf,11) = groupid;
-	mapif_sendall(buf,15);  // inform all map-servers attached.
+	mapif_send(mapfd,buf,15);  // inform the mapserv back
 #endif
 	return 0;
 }
 
-/*
+/**
  * HZ 0x2b2b
  * Request vip data from loginserv
+ * @param aid : account_id to request the vip data
+ * @param type : &2 define new duration, &1 load info
+ * @param add_vip_time : tick to add to vip timestamp
+ * @param mapfd: link to mapserv for ack
+ * @return 0 if succes
  */
-int logif_reqviddata(uint32 aid, uint8 type, uint32 add_vip_time) {
+int loginif_reqviddata(uint32 aid, uint8 type, int add_vip_time, int mapfd) {
+	loginif_check(-1);
 #ifdef VIP_ENABLE
-	WFIFOHEAD(login_fd,11);
+	WFIFOHEAD(login_fd,15);
 	WFIFOW(login_fd,0) = 0x2742;
 	WFIFOL(login_fd,2) =  aid; //aid
 	WFIFOB(login_fd,6) = type; //type
 	WFIFOL(login_fd,7) =  add_vip_time; //req_inc_duration
-	WFIFOSET(login_fd,11);
+	WFIFOL(login_fd,11) =  mapfd; //req_inc_duration
+	WFIFOSET(login_fd,15);
 #endif
 	return 0;
 }
@@ -2327,23 +2281,28 @@ int logif_reqviddata(uint32 aid, uint8 type, uint32 add_vip_time) {
  * AH 0x2743
  * We received the info from login-serv, transmit it to map
  */
-int logif_parse_vipack(int fd) {
+int loginif_parse_vipack(int fd) {
 #ifdef VIP_ENABLE
-	if (RFIFOREST(fd) < 15)
+	if (RFIFOREST(fd) < 19)
 		return 0;
 	else {
 		uint32 aid = RFIFOL(fd,2); //aid
 		uint32 vip_time = RFIFOL(fd,6); //vip_time
 		uint8 isvip = RFIFOB(fd,10); //isvip
 		uint32 groupid = RFIFOL(fd,11); //new group id
-		RFIFOSKIP(fd,15);
-		mapif_vipack(aid,vip_time,isvip,groupid);
+		int mapfd = RFIFOL(fd,15); //link to mapserv for ack
+		RFIFOSKIP(fd,19);
+		mapif_vipack(mapfd,aid,vip_time,isvip,groupid);
 	}
 #endif
 	return 1;
 }
 
 
+int loginif_isconnected(){
+	return (login_fd > 0 && session[login_fd] && !session[login_fd]->flag.eof);
+}
+
 /// Resets all the data.
 void loginif_reset(void)
 {
@@ -2390,7 +2349,7 @@ void loginif_on_ready(void)
 		ShowStatus("Awaiting maps from map-server.\n");
 }
 
-int logif_parse_reqpincode(int fd, struct char_session_data *sd){
+int loginif_parse_reqpincode(int fd, struct char_session_data *sd){
 #if PACKETVER >=  20110309
 	if( pincode_enabled ){
 		// PIN code system enabled
@@ -2411,7 +2370,7 @@ int logif_parse_reqpincode(int fd, struct char_session_data *sd){
 				pincode_sendstate( fd, sd, PINCODE_EXPIRED );
 			}
 		}
-	} else { // PIN code system disabled 
+	} else { // PIN code system disabled
 		pincode_sendstate( fd, sd, PINCODE_OK );
 	}
 #endif
@@ -2455,7 +2414,7 @@ int parse_fromlogin(int fd) {
 		switch( command )
 		{
 		case 0x2741: loginif_parse_BankingAck(fd); break;
-		case 0x2743: logif_parse_vipack(fd); break;
+		case 0x2743: loginif_parse_vipack(fd); break;
 
 		// acknowledgement of connect-to-loginserver request
 		case 0x2711:
@@ -2501,7 +2460,7 @@ int parse_fromlogin(int fd) {
 				if(sd->version != date2version(PACKETVER))
 					ShowWarning("s aid=%d has an incorect version=%d in clientinfo. Server compiled for %d\n",
 						sd->account_id,sd->version,date2version(PACKETVER));
-				
+
 				switch( result )
 				{
 				case 0:// ok
@@ -2556,7 +2515,7 @@ int parse_fromlogin(int fd) {
 				} else {
 					// send characters to player
 					mmo_char_send(i, sd);
-					logif_parse_reqpincode(i, sd);
+					loginif_parse_reqpincode(i, sd);
 				}
 			}
 			RFIFOSKIP(fd,79);
@@ -2785,29 +2744,27 @@ void do_final_loginif(void)
 
 int request_accreg2(int account_id, int char_id)
 {
-	if (login_fd > 0) {
-		WFIFOHEAD(login_fd,10);
-		WFIFOW(login_fd,0) = 0x272e;
-		WFIFOL(login_fd,2) = account_id;
-		WFIFOL(login_fd,6) = char_id;
-		WFIFOSET(login_fd,10);
-		return 1;
-	}
-	return 0;
+	loginif_check(0);
+
+	WFIFOHEAD(login_fd,10);
+	WFIFOW(login_fd,0) = 0x272e;
+	WFIFOL(login_fd,2) = account_id;
+	WFIFOL(login_fd,6) = char_id;
+	WFIFOSET(login_fd,10);
+	return 1;
 }
 
 //Send packet forward to login-server for account saving
 int save_accreg2(unsigned char* buf, int len)
 {
-	if (login_fd > 0) {
-		WFIFOHEAD(login_fd,len+4);
-		memcpy(WFIFOP(login_fd,4), buf, len);
-		WFIFOW(login_fd,0) = 0x2728;
-		WFIFOW(login_fd,2) = len+4;
-		WFIFOSET(login_fd,len+4);
-		return 1;
-	}
-	return 0;
+	loginif_check(0);
+	
+	WFIFOHEAD(login_fd,len+4);
+	memcpy(WFIFOP(login_fd,4), buf, len);
+	WFIFOW(login_fd,0) = 0x2728;
+	WFIFOW(login_fd,2) = len+4;
+	WFIFOSET(login_fd,len+4);
+	return 1;
 }
 
 void char_read_fame_list(void)
@@ -2991,23 +2948,105 @@ void mapif_on_disconnect(int id)
 	ShowStatus("Map-server #%d has disconnected.\n", id);
 	mapif_server_reset(id);
 }
-/** 
+
+int mapif_parse_reqcharban(int fd){
+	if (RFIFOREST(fd) < 10)
+		return 0;
+	else {	
+		int cid = RFIFOL(fd,2);
+		int timediff = RFIFOL(fd,6);
+		RFIFOSKIP(fd,10);
+
+		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id` `unban_time` FROM `%s` WHERE `char_id` = '%d'", char_db, cid) )
+			Sql_ShowDebug(sql_handle);
+		else if( Sql_NumRows(sql_handle) == 0 ){
+			return -1; // 1-player not found
+		}
+		else if( SQL_SUCCESS != Sql_NextRow(sql_handle) ){
+			Sql_ShowDebug(sql_handle);
+			Sql_FreeResult(sql_handle);
+			return -1;
+		} else {
+			int aid;
+			char* data;
+			time_t unban_time;
+
+			Sql_GetData(sql_handle, 0, &data, NULL); aid = atoi(data);
+			Sql_GetData(sql_handle, 1, &data, NULL); unban_time = atol(data);
+			Sql_FreeResult(sql_handle);
+
+
+			if(timediff<0 && unban_time==0) return 0; //attemp to reduce time of a non banned account ?!?
+			else if(unban_time==0) unban_time=time(NULL); //new entry
+			unban_time += timediff;
+			// condition applies; send to all map-servers to disconnect the player
+			if( unban_time > time(NULL) ) {
+				unsigned char buf[11];
+				SqlStmt* stmt = SqlStmt_Malloc(sql_handle);
+				if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
+						  "UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1",
+						  char_db)
+					|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_LONG,   (void*)&unban_time,   sizeof(unban_time))
+					|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_INT,    (void*)&cid,     sizeof(cid))
+					|| SQL_SUCCESS != SqlStmt_Execute(stmt)
+
+					) {
+					SqlStmt_ShowDebug(stmt);
+					SqlStmt_Free(stmt);
+					return -1;
+				}
+				else {
+					WBUFW(buf,0) = 0x2b14;
+					WBUFL(buf,2) = aid;
+					WBUFB(buf,6) = 2;
+					WBUFL(buf,7) = (unsigned int)unban_time;
+					mapif_sendall(buf, 11);
+
+					// disconnect player if online on char-server
+					disconnect_player(aid);
+				}
+				SqlStmt_Free(stmt);
+			}
+		}
+	}
+	return 0;
+}
+
+int mapif_parse_reqcharunban(int fd){
+	if (RFIFOREST(fd) < 6)
+		return 0;
+	else {	
+		int cid = RFIFOL(fd,2);
+		RFIFOSKIP(fd,6);
+		
+		if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `unban_time` = '0' WHERE `char_id` = '%d' LIMIT 1", char_db, cid) ) {
+			Sql_ShowDebug(sql_handle);
+			return -1;
+		}
+	}
+	return 0;
+}
+
+/**
  * Request from map-server to change an account's status (will just be forwarded to login server)
  * ZH 2b0e <aid>L <charname>24B <opetype>W <timediff>L
  * @param fd: link to mapserv
- */	
+ */
 int mapif_parse_req_alter_acc(int fd){
-	if (RFIFOREST(fd) < 36)
+	if (RFIFOREST(fd) < 44)
 		return 0;
 	else {
 		int result = 0; // 0-login-server request done, 1-player not found, 2-gm level too low, 3-login-server offline
 		char esc_name[NAME_LENGTH*2+1];
+		char anwser=true;
 
-		int acc = RFIFOL(fd,2); // account_id of who ask (-1 if server itself made this request)
+		int aid = RFIFOL(fd,2); // account_id of who ask (-1 if server itself made this request)
 		const char* name = (char*)RFIFOP(fd,6); // name of the target character
-		int operation = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban,  5 changesex, 6 charban, 7 charunban
+		int operation = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban,  5 changesex, 6 vip, 7 bank
 		int timediff = RFIFOL(fd,32);
-		RFIFOSKIP(fd,36);
+		int val1 = RFIFOL(fd,36);
+		int val2 = RFIFOL(fd,40);
+		RFIFOSKIP(fd,44);
 
 		Sql_EscapeStringLen(sql_handle, esc_name, name, strnlen(name, NAME_LENGTH));
 		if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`char_id`,`unban_time` FROM `%s` WHERE `name` = '%s'", char_db, esc_name) )
@@ -3020,104 +3059,71 @@ int mapif_parse_req_alter_acc(int fd){
 			result = 1;
 		} else {
 			char name[NAME_LENGTH];
-			int account_id, char_id;
+			int account_id;
 			char* data;
-			time_t unban_time;
 
 			Sql_GetData(sql_handle, 0, &data, NULL); account_id = atoi(data);
 			Sql_GetData(sql_handle, 1, &data, NULL); safestrncpy(name, data, sizeof(name));
-			Sql_GetData(sql_handle, 2, &data, NULL); char_id = atoi(data);
-			Sql_GetData(sql_handle, 3, &data, NULL); unban_time = atol(data);;
 			Sql_FreeResult(sql_handle);
 
-			if(operation!=6 && operation!=7 && login_fd <= 0 ) //6-7 operation doesn't send to login
+			if(!loginif_isconnected())
 				result = 3; // 3-login-server offline
 			//FIXME: need to move this check to login server [ultramage]
 			//	if( acc != -1 && isGM(acc) < isGM(account_id) )
 			//		result = 2; // 2-gm level too low
-			else
-			switch( operation ) {
-			case 1: // block
-				WFIFOHEAD(login_fd,10);
-				WFIFOW(login_fd,0) = 0x2724;
-				WFIFOL(login_fd,2) = account_id;
-				WFIFOL(login_fd,6) = 5; // new account status
-				WFIFOSET(login_fd,10);
-			break;
-			case 2: // ban
-				WFIFOHEAD(login_fd,10);
-				WFIFOW(login_fd, 0) = 0x2725;
-				WFIFOL(login_fd, 2) = account_id;
-				WFIFOL(login_fd, 6) = timediff;
-				WFIFOSET(login_fd,10);
-			break;
-			case 3: // unblock
-				WFIFOHEAD(login_fd,10);
-				WFIFOW(login_fd,0) = 0x2724;
-				WFIFOL(login_fd,2) = account_id;
-				WFIFOL(login_fd,6) = 0; // new account status
-				WFIFOSET(login_fd,10);
-			break;
-			case 4: // unban
-				WFIFOHEAD(login_fd,6);
-				WFIFOW(login_fd,0) = 0x272a;
-				WFIFOL(login_fd,2) = account_id;
-				WFIFOSET(login_fd,6);
-			break;
-			case 5: // changesex
-				WFIFOHEAD(login_fd,6);
-				WFIFOW(login_fd,0) = 0x2727;
-				WFIFOL(login_fd,2) = account_id;
-				WFIFOSET(login_fd,6);
-			break;
-			case 6: //charban /* handled by char server, so no redirection */
-				if(timediff<0 && unban_time==0) break; //attemp to reduce time of a non banned account ?!? 
-				else if(unban_time==0) unban_time=time(NULL); //new entry
-				unban_time += timediff;
-				// condition applies; send to all map-servers to disconnect the player
-				if( unban_time > time(NULL) ) {
-					unsigned char buf[11];
-					SqlStmt* stmt = SqlStmt_Malloc(sql_handle);
-					if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
-							  "UPDATE `%s` SET `unban_time` = ? WHERE `char_id` = ? LIMIT 1",
-							  char_db)
-						|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_LONG,   (void*)&unban_time,   sizeof(unban_time))
-						|| SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_INT,    (void*)&char_id,     sizeof(char_id))
-						|| SQL_SUCCESS != SqlStmt_Execute(stmt)
-
-						) {
-						SqlStmt_ShowDebug(stmt);
-						result=1;
-					}
-					else {
-						WBUFW(buf,0) = 0x2b14;
-						WBUFL(buf,2) = account_id;
-						WBUFB(buf,6) = 2;
-						WBUFL(buf,7) = (unsigned int)unban_time;
-						mapif_sendall(buf, 11);
-
-						// disconnect player if online on char-server
-						disconnect_player(account_id);
-						result=4;
-					}
-					SqlStmt_Free(stmt);
-				}
-			break;
-			case 7: //char unban
-				/* handled by char server, so no redirection */
-				if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `unban_time` = '0' WHERE `char_id` = '%d' LIMIT 1", char_db, char_id) ) {
-					Sql_ShowDebug(sql_handle);
-					result = 1;
-				} else result=4;
-			break;
-			} //end switch operation
+			else {
+				switch( operation ) {
+				case 1: // block
+					WFIFOHEAD(login_fd,10);
+					WFIFOW(login_fd,0) = 0x2724;
+					WFIFOL(login_fd,2) = account_id;
+					WFIFOL(login_fd,6) = 5; // new account status
+					WFIFOSET(login_fd,10);
+				break;
+				case 2: // ban
+					WFIFOHEAD(login_fd,10);
+					WFIFOW(login_fd, 0) = 0x2725;
+					WFIFOL(login_fd, 2) = account_id;
+					WFIFOL(login_fd, 6) = timediff;
+					WFIFOSET(login_fd,10);
+				break;
+				case 3: // unblock
+					WFIFOHEAD(login_fd,10);
+					WFIFOW(login_fd,0) = 0x2724;
+					WFIFOL(login_fd,2) = account_id;
+					WFIFOL(login_fd,6) = 0; // new account status
+					WFIFOSET(login_fd,10);
+				break;
+				case 4: // unban
+					WFIFOHEAD(login_fd,6);
+					WFIFOW(login_fd,0) = 0x272a;
+					WFIFOL(login_fd,2) = account_id;
+					WFIFOSET(login_fd,6);
+				break;
+				case 5: // changesex
+					anwser=false;
+					WFIFOHEAD(login_fd,6);
+					WFIFOW(login_fd,0) = 0x2727;
+					WFIFOL(login_fd,2) = account_id;
+					WFIFOSET(login_fd,6);
+				break;
+				case 6: 
+					anwser=(val1&4); // vip_req val1=type, &1 login send return, &2 upd timestamp &4 map send awnser
+					loginif_reqviddata(aid, val1, timediff, fd); 
+					break; 
+				case 7: 
+					anwser=(val1&1); //val&1 request anwser, val1&2 save data
+					loginif_BankingReq(aid, val1, val2); 
+					break;
+				} //end switch operation
+			} //login is connected
 		}
 
 		// send answer if a player ask, not if the server ask
-		if( acc != -1 && operation != 5) { // Don't send answer for changesex
+		if( aid != -1 && anwser) { // Don't send answer for changesex
 			WFIFOHEAD(fd,34);
 			WFIFOW(fd, 0) = 0x2b0f;
-			WFIFOL(fd, 2) = acc;
+			WFIFOL(fd, 2) = aid;
 			safestrncpy((char*)WFIFOP(fd,6), name, NAME_LENGTH);
 			WFIFOW(fd,30) = operation;
 			WFIFOW(fd,32) = result;
@@ -3532,7 +3538,7 @@ int parse_frommap(int fd)
 		case 0x2b0c: // Map server send information to change an email of an account -> login-server
 			if (RFIFOREST(fd) < 86)
 				return 0;
-			if (login_fd > 0) { // don't send request if no login-server
+			if (!loginif_isconnected()) { // don't send request if no login-server or eof
 				WFIFOHEAD(login_fd,86);
 				memcpy(WFIFOP(login_fd,0), RFIFOP(fd,0),86); // 0x2722 <account_id>.L <actual_e-mail>.40B <new_e-mail>.40B
 				WFIFOW(login_fd,0) = 0x2722;
@@ -3817,21 +3823,12 @@ int parse_frommap(int fd)
 				RFIFOSKIP(fd, RFIFOW(fd,2) );/* skip this packet */
 		}
 		break;
-		
-		case 0x2b28: mapif_parse_UpdBankInfo(fd); break;
-		case 0x2b2a: mapif_parse_ReqBankInfo(fd); break;
-		case 0x2b2c: mapif_parse_vipactive(fd); break;
-		case 0x2b2d: //Load data
-			if (RFIFOREST(fd) < 6)
-				return 0;
-			bonus_script_get(fd);
-			break;
 
-		case 0x2b2e: //Save data
-			if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
-				return 0;
-			bonus_script_save(fd);
-			break;
+		case 0x2b28: mapif_parse_reqcharban(fd); break; //charban
+		case 0x2b2a: mapif_parse_reqcharunban(fd); break; //charunban
+		//case 0x2b2c: /*free*/; break;
+		case 0x2b2d: bonus_script_get(fd); break; //Load data
+		case 0x2b2e: bonus_script_save(fd); break;//Save data
 
 		default:
 		{
@@ -4231,7 +4228,7 @@ int parse_char(int fd)
 			}
 			else
 			{// authentication not found (coming from login server)
-				if (login_fd > 0) { // don't send request if no login-server
+				if (loginif_isconnected()) { // don't send request if no login-server
 					WFIFOHEAD(login_fd,23);
 					WFIFOW(login_fd,0) = 0x2712; // ask login-server to authentify an account
 					WFIFOL(login_fd,2) = sd->account_id;
@@ -4280,7 +4277,7 @@ int parse_char(int fd)
 
 			char_id = atoi(data);
 			Sql_FreeResult(sql_handle);
-			
+
 			/* client doesn't let it get to this point if you're banned, so its a forged packet */
 			if( sd->found_char[slot] == char_id && sd->unban_time[slot] > time(NULL) ) {
 				WFIFOHEAD(fd,3);
@@ -4870,7 +4867,7 @@ int broadcast_user_count(int tid, unsigned int tick, int id, intptr_t data)
 		return 0;
 	prev_users = users;
 
-	if( login_fd > 0 && session[login_fd] )
+	if( loginif_isconnected() )
 	{
 		// send number of user to login server
 		WFIFOHEAD(login_fd,6);
@@ -4907,7 +4904,7 @@ static int send_accounts_tologin_sub(DBKey key, DBData *data, va_list ap)
 
 int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data)
 {
-	if (login_fd > 0 && session[login_fd])
+	if (loginif_isconnected())
 	{
 		// send account list to login server
 		int users = online_char_db->size(online_char_db);
@@ -5149,44 +5146,48 @@ void moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short ind
 * @param fd
 */
 void bonus_script_get(int fd) {
-	int cid;
-	cid = RFIFOL(fd,2);
-
-	if (SQL_ERROR == Sql_Query(sql_handle,"SELECT `script`, `tick`, `flag`, `type` FROM `%s` WHERE `char_id`='%d'",
-		bonus_script_db,cid))
-	{
-		Sql_ShowDebug(sql_handle);
+	if (RFIFOREST(fd) < 6)
 		return;
-	}
-	if (Sql_NumRows(sql_handle) > 0) {
-		struct bonus_script_data bsdata;
-		int count;
-		char *data;
-
-		WFIFOHEAD(fd,10+50*sizeof(struct bonus_script_data));
-		WFIFOW(fd,0) = 0x2b2f;
-		WFIFOL(fd,4) = cid;
-		for (count = 0; count < 20 && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count) {
-			Sql_GetData(sql_handle,0,&data,NULL); memcpy(bsdata.script,data,strlen(data)+1);
-			Sql_GetData(sql_handle,1,&data,NULL); bsdata.tick = atoi(data);
-			Sql_GetData(sql_handle,2,&data,NULL); bsdata.flag = atoi(data);
-			Sql_GetData(sql_handle,3,&data,NULL); bsdata.type = atoi(data);
-			memcpy(WFIFOP(fd,10+count*sizeof(struct bonus_script_data)),&bsdata,sizeof(struct bonus_script_data));
-		}
-		if (count >= 50)
-			ShowWarning("Too many bonus_script for %d, some of them were not loaded.\n",cid);
-		if (count > 0) {
-			WFIFOW(fd,2) = 10 + count*sizeof(struct bonus_script_data);
-			WFIFOW(fd,8) = count;
-			WFIFOSET(fd,WFIFOW(fd,2));
+	else {
+		int cid;
+		cid = RFIFOL(fd,2);
+		RFIFOSKIP(fd,6);
 
-			//Clear the data once loaded.
-			if (SQL_ERROR == Sql_Query(sql_handle,"DELETE FROM `%s` WHERE `char_id`='%d'",bonus_script_db,cid))
-				Sql_ShowDebug(sql_handle);
+		if (SQL_ERROR == Sql_Query(sql_handle,"SELECT `script`, `tick`, `flag`, `type` FROM `%s` WHERE `char_id`='%d'",
+			bonus_script_db,cid))
+		{
+			Sql_ShowDebug(sql_handle);
+			return;
 		}
+		if (Sql_NumRows(sql_handle) > 0) {
+			struct bonus_script_data bsdata;
+			int count;
+			char *data;
+
+			WFIFOHEAD(fd,10+50*sizeof(struct bonus_script_data));
+			WFIFOW(fd,0) = 0x2b2f;
+			WFIFOL(fd,4) = cid;
+			for (count = 0; count < 20 && SQL_SUCCESS == Sql_NextRow(sql_handle); ++count) {
+				Sql_GetData(sql_handle,0,&data,NULL); memcpy(bsdata.script,data,strlen(data)+1);
+				Sql_GetData(sql_handle,1,&data,NULL); bsdata.tick = atoi(data);
+				Sql_GetData(sql_handle,2,&data,NULL); bsdata.flag = atoi(data);
+				Sql_GetData(sql_handle,3,&data,NULL); bsdata.type = atoi(data);
+				memcpy(WFIFOP(fd,10+count*sizeof(struct bonus_script_data)),&bsdata,sizeof(struct bonus_script_data));
+			}
+			if (count >= 50)
+				ShowWarning("Too many bonus_script for %d, some of them were not loaded.\n",cid);
+			if (count > 0) {
+				WFIFOW(fd,2) = 10 + count*sizeof(struct bonus_script_data);
+				WFIFOW(fd,8) = count;
+				WFIFOSET(fd,WFIFOW(fd,2));
+
+				//Clear the data once loaded.
+				if (SQL_ERROR == Sql_Query(sql_handle,"DELETE FROM `%s` WHERE `char_id`='%d'",bonus_script_db,cid))
+					Sql_ShowDebug(sql_handle);
+			}
+		}
+		Sql_FreeResult(sql_handle);
 	}
-	Sql_FreeResult(sql_handle);
-	RFIFOSKIP(fd,6);
 }
 
 /** [Cydh]
@@ -5194,31 +5195,35 @@ void bonus_script_get(int fd) {
 * @param fd
 */
 void bonus_script_save(int fd) {
-	int count, cid;
+	if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
+		return;
+	else {
+		int count, cid;
 
-	cid = RFIFOL(fd,4);
-	count = RFIFOW(fd,8);
+		cid = RFIFOL(fd,4);
+		count = RFIFOW(fd,8);
 
-	if (count > 0) {
-		struct bonus_script_data bs;
-		StringBuf buf;
-		int i;
-		char esc_script[MAX_BONUS_SCRIPT_LENGTH] = "";
-
-		StringBuf_Init(&buf);
-		StringBuf_Printf(&buf,"INSERT INTO `%s` (`char_id`, `script`, `tick`, `flag`, `type`) VALUES ",bonus_script_db);
-		for (i = 0; i < count; ++i) {
-			memcpy(&bs,RFIFOP(fd,10+i*sizeof(struct bonus_script_data)),sizeof(struct bonus_script_data));
-			Sql_EscapeString(sql_handle,esc_script,bs.script);
-			if (i > 0)
-				StringBuf_AppendStr(&buf,", ");
-			StringBuf_Printf(&buf,"(%d,'%s',%d,%d,%d)",cid,esc_script,bs.tick,bs.flag,bs.type);
+		if (count > 0) {
+			struct bonus_script_data bs;
+			StringBuf buf;
+			int i;
+			char esc_script[MAX_BONUS_SCRIPT_LENGTH] = "";
+
+			StringBuf_Init(&buf);
+			StringBuf_Printf(&buf,"INSERT INTO `%s` (`char_id`, `script`, `tick`, `flag`, `type`) VALUES ",bonus_script_db);
+			for (i = 0; i < count; ++i) {
+				memcpy(&bs,RFIFOP(fd,10+i*sizeof(struct bonus_script_data)),sizeof(struct bonus_script_data));
+				Sql_EscapeString(sql_handle,esc_script,bs.script);
+				if (i > 0)
+					StringBuf_AppendStr(&buf,", ");
+				StringBuf_Printf(&buf,"(%d,'%s',%d,%d,%d)",cid,esc_script,bs.tick,bs.flag,bs.type);
+			}
+			if (SQL_ERROR == Sql_QueryStr(sql_handle,StringBuf_Value(&buf)))
+				Sql_ShowDebug(sql_handle);
+			StringBuf_Destroy(&buf);
 		}
-		if (SQL_ERROR == Sql_QueryStr(sql_handle,StringBuf_Value(&buf)))
-			Sql_ShowDebug(sql_handle);
-		StringBuf_Destroy(&buf);
+		RFIFOSKIP(fd,RFIFOW(fd,2));
 	}
-	RFIFOSKIP(fd,RFIFOW(fd,2));
 }
 
 //------------------------------------------------

+ 2 - 2
src/common/timer.c

@@ -429,8 +429,8 @@ void split_time(int timein, int* year, int* month, int* day, int* hour, int* min
 	const int factor_min = 60;
 	const int factor_hour = factor_min*60;
 	const int factor_day = factor_hour*24;
-	const int factor_month = factor_day*30; // Approx
-	const int factor_year = factor_month*12; // Even worse approx
+	const int factor_month = 2629743; // Approx  (30.44 days) 
+	const int factor_year = 31556926; // Approx (365.24 days)
 
 	*year = timein/factor_year;
 	timein -= *year*factor_year;

+ 1 - 1
src/login/account.h

@@ -55,7 +55,7 @@ struct mmo_account {
 	int bank_vault;
 #ifdef VIP_ENABLE
 	int old_group;
-	int vip_time;
+	time_t vip_time;
 #endif
 	struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
 };

+ 23 - 19
src/login/login.c

@@ -483,17 +483,16 @@ int chrif_parse_reqaccdata(int fd, int cid, char *ip) {
 }
 
 
-int chrif_sendvipdata(int fd, struct mmo_account acc, char isvip) {
+int chrif_sendvipdata(int fd, struct mmo_account acc, char isvip, int mapfd) {
 #ifdef VIP_ENABLE
-	uint8 buf[16];
-
-	WBUFW(buf,0) = 0x2743;
-	WBUFL(buf,2) = acc.account_id;
-	WBUFL(buf,6) = acc.vip_time;
-	WBUFB(buf,10) = isvip;
-	WBUFL(buf,11) = acc.group_id; //new group id
-	charif_sendallwos(-1,buf,15); //inform all char-servs of result
-
+	WFIFOHEAD(fd,19);
+	WFIFOW(fd,0) = 0x2743;
+	WFIFOL(fd,2) = acc.account_id;
+	WFIFOL(fd,6) = acc.vip_time;
+	WFIFOB(fd,10) = isvip;
+	WFIFOL(fd,11) = acc.group_id; //new group id
+	WFIFOL(fd,15) = mapfd; //link to mapserv
+	WFIFOSET(fd,19);
 	chrif_send_accdata(fd,acc.account_id); //refresh char with new setting
 #endif
 	return 1;
@@ -509,15 +508,16 @@ int chrif_sendvipdata(int fd, struct mmo_account acc, char isvip) {
  */
 int chrif_parse_reqvipdata(int fd) {
 #ifdef VIP_ENABLE
-	if( RFIFOREST(fd) < 11 )
+	if( RFIFOREST(fd) < 15 )
 		return 0;
 	else { //request vip info
 		struct mmo_account acc;
 		int aid = RFIFOL(fd,2);
 		int8 type = RFIFOB(fd,6);
-		uint32 req_duration = RFIFOL(fd,7);
-		RFIFOSKIP(fd,11);
-
+		int req_duration = RFIFOL(fd,7);
+		int mapfd =  RFIFOL(fd,11);
+		RFIFOSKIP(fd,15);
+		
 		if( accounts->load_num(accounts, &acc, aid ) ){
 			time_t now = time(NULL);
 			time_t vip_time = acc.vip_time;
@@ -530,16 +530,16 @@ int chrif_parse_reqvipdata(int fd) {
 				acc.group_id = login_config.vip_sys.group;
 				acc.char_slots = login_config.char_per_account + login_config.vip_sys.char_increase;
 				isvip = true;
-			} else if (vip_time) { //expired
+			} else if (vip_time) { //expired or @vip -xx
 				vip_time = 0;
-				acc.group_id = acc.old_group;
+				if(acc.group_id == login_config.vip_sys.group) //prevent alteration in case we wasn't registered vip yet
+					acc.group_id = acc.old_group;
 				acc.old_group = 0;
 				acc.char_slots = login_config.char_per_account;
 			}
-			acc.vip_time = (int)vip_time;
+			acc.vip_time = vip_time;
 			accounts->save(accounts,&acc);
-			
-			chrif_sendvipdata(fd,acc,isvip);
+			if( type&1 ) chrif_sendvipdata(fd,acc,isvip,mapfd);
 		}
 	}
 #endif
@@ -1233,6 +1233,10 @@ int mmo_auth(struct login_session_data* sd, bool isServer) {
 	timestamp2string(acc.lastlogin, sizeof(acc.lastlogin), time(NULL), "%Y-%m-%d %H:%M:%S");
 	safestrncpy(acc.last_ip, ip, sizeof(acc.last_ip));
 	acc.unban_time = 0;
+#ifdef VIP_ENABLE
+	acc.vip_time = 0;
+	acc.old_group = 0;
+#endif	
 	acc.logincount++;
 
 	accounts->save(accounts, &acc);

+ 24 - 20
src/map/atcommand.c

@@ -2773,7 +2773,7 @@ ACMD_FUNC(char_block)
 		return -1;
 	}
 
-	chrif_ask_char_operation(sd->status.account_id, atcmd_player_name, 1, 0); // type: 1 - block
+	chrif_req_login_operation(sd->status.account_id, atcmd_player_name, 1, 0, 0, 0); // type: 1 - block
 	clif_displaymessage(fd, msg_txt(sd,88)); // Character name sent to char-server to ask it.
 
 	return 0;
@@ -2824,7 +2824,11 @@ ACMD_FUNC(char_ban)
 		return -1;
 	}
 	
-	chrif_ask_char_operation(sd->status.account_id, atcmd_player_name, bantype, timediff); // type: 2 - ban
+	if(bantype==2) 
+		chrif_req_login_operation(sd->status.account_id, atcmd_player_name, 2, timediff, 0, 0); // type: 2 - ban
+	else
+		chrif_req_charban(sd->status.char_id,timediff);
+	
 	safesnprintf(output,sizeof(output),msg_txt(sd,88),bantype==6?"char":"login"); // Sending request to %s server...
 	clif_displaymessage(fd, output);
 
@@ -2846,7 +2850,7 @@ ACMD_FUNC(char_unblock)
 	}
 
 	// send answer to login server via char-server
-	chrif_ask_char_operation(sd->status.account_id, atcmd_player_name, 3, 0); // type: 3 - unblock
+	chrif_req_login_operation(sd->status.account_id, atcmd_player_name, 3, 0, 0, 0); // type: 3 - unblock
 	clif_displaymessage(fd, msg_txt(sd,88)); // Character name sent to char-server to ask it.
 
 	return 0;
@@ -2869,10 +2873,10 @@ ACMD_FUNC(char_unban){
 		return -1;
 	} 
 	
-
-	ShowInfo("char_unban unbantype=%d\n",unbantype);
-	// send answer to login server via char-server
-	chrif_ask_char_operation(sd->status.account_id, atcmd_player_name, unbantype, 0); // type: 4 - unban
+	if(unbantype==4) // send answer to login server via char-server
+		chrif_req_login_operation(sd->status.account_id, atcmd_player_name, 4, 0, 0, 0); // type: 4 - unban
+	else //directly unban via char-serv
+		chrif_req_charunban(sd->status.char_id);
 	clif_displaymessage(fd, msg_txt(sd,88)); // Character name sent to char-server to ask it.
 
 	return 0;
@@ -9155,21 +9159,23 @@ ACMD_FUNC(langtype)
 ACMD_FUNC(vip) {
 	struct map_session_data *pl_sd = NULL;
 	char * modif_p;
-	int viptime = 0;
+	int vipdifftime = 0;
+	time_t now=time(NULL);
+	
 	nullpo_retr(-1, sd);
 
 	memset(atcmd_output, '\0', sizeof(atcmd_output));
 	
 	if (!message || !*message || sscanf(message, "%255s %23[^\n]",atcmd_output,atcmd_player_name) < 2) {
-		clif_displaymessage(fd, msg_txt(sd,700));	//Usage: @vip <time> <character name>
+		clif_displaymessage(fd, msg_txt(sd,700));	//Usage: @vip <timef> <character name>
 		return -1;
 	}
 
 	atcmd_output[sizeof(atcmd_output)-1] = '\0';
 
 	modif_p = atcmd_output;
-	viptime = (int)solve_time(modif_p)/60; // Change to minutes
-	if (viptime == 0) {
+	vipdifftime = (int)solve_time(modif_p);
+	if (vipdifftime == 0) {
 		clif_displaymessage(fd, msg_txt(sd,701)); // Invalid time for vip command.
 		clif_displaymessage(fd, msg_txt(sd,702)); // Time parameter format is +/-<value> to alter. y/a = Year, m = Month, d/j = Day, h = Hour, n/mn = Minute, s = Second.
 		return -1;
@@ -9184,8 +9190,10 @@ ACMD_FUNC(vip) {
 		clif_displaymessage(fd, msg_txt(sd,81)); // Your GM level don't authorise you to do this action on this player.
 		return -1;
 	}
+	if(pl_sd->vip.time==0) pl_sd->vip.time=now;
+	pl_sd->vip.time += vipdifftime; //increase or reduce VIP duration
 	
-	if (viptime <= 0) {
+	if (pl_sd->vip.time <= now) {
 		pl_sd->vip.time = 0;
 		pl_sd->vip.enabled = 0;
 		clif_displaymessage(pl_sd->fd, msg_txt(pl_sd,703)); // GM has removed your VIP time.
@@ -9193,14 +9201,11 @@ ACMD_FUNC(vip) {
 	} else {
 		int year,month,day,hour,minute,second;
 		char timestr[21];
-		time_t now=time(NULL);
-
-		pl_sd->vip.time += viptime;
-		split_time(pl_sd->vip.time*60,&year,&month,&day,&hour,&minute,&second);
-
+		
+		split_time(pl_sd->vip.time-now,&year,&month,&day,&hour,&minute,&second);
 		sprintf(atcmd_output,msg_txt(pl_sd,705),year,month,day,hour,minute); // Your VIP status is valid for %d years, %d months, %d days, %d hours and %d minutes.
 		clif_displaymessage(pl_sd->fd,atcmd_output);
-		timestamp2string(timestr,20,now+pl_sd->vip.time*60,"%Y-%m-%d %H:%M");
+		timestamp2string(timestr,20,pl_sd->vip.time,"%Y-%m-%d %H:%M");
 		sprintf(atcmd_output,msg_txt(pl_sd,707),timestr); // You are VIP until : %s
 		clif_displaymessage(pl_sd->fd,atcmd_output);
 
@@ -9211,8 +9216,7 @@ ACMD_FUNC(vip) {
 			clif_displaymessage(fd,atcmd_output);
 		}
 	}
-	chrif_req_vipActive(pl_sd, viptime, 3); //! FIXME, someone said, player will be kicked out after player get VIP status.
-
+	chrif_req_login_operation(pl_sd->status.account_id, pl_sd->status.name, 6, vipdifftime, 7, 0); 
 	return 0;
 }
 #endif

+ 66 - 75
src/map/chrif.c

@@ -42,11 +42,11 @@ static DBMap* auth_db; // int id -> struct auth_node*
 static const int packet_len_table[0x3d] = { // U - used, F - free
 	60, 3,-1,27,10,-1, 6,-1,	// 2af8-2aff: U->2af8, U->2af9, U->2afa, U->2afb, U->2afc, U->2afd, U->2afe, U->2aff
 	 6,-1,19, 7,-1,39,30, 10,	// 2b00-2b07: U->2b00, U->2b01, U->2b02, U->2b03, U->2b04, U->2b05, U->2b06, U->2b07
-	 6,30, 10, -1,86, 7,36,34,	// 2b08-2b0f: U->2b08, U->2b09, U->2b0a, U->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
+	 6,30, 10, -1,86, 7,44,34,	// 2b08-2b0f: U->2b08, U->2b09, U->2b0a, U->2b0b, U->2b0c, U->2b0d, U->2b0e, U->2b0f
 	11,10,10, 0,11, -1,266,10,	// 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, U->2b15, U->2b16, U->2b17
 	 2,10, 2,-1,-1,-1, 2, 7,	// 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
 	-1,10, 8, 2, 2,14,19,19,	// 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, U->2b24, U->2b25, U->2b26, U->2b27
-	10,10, 6,15,11, 6,-1,-1,	// 2b28-2b2f: U->2b28, U->2b29, U->2b2a, U->2b2b, U->2b2c, U->2b2d, U->2b2e, U->2b2f
+	10,10, 6,15, 0, 6,-1,-1,	// 2b28-2b2f: U->2b28, U->2b29, U->2b2a, U->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
  };
 
 //Used Packets:
@@ -72,8 +72,8 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
 //2b0b: Incoming, chrif_skillcooldown_load -> received the list of cooldown for char
 //2b0c: Outgoing, chrif_changeemail -> 'change mail address ...'
 //2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY'
-//2b0e: Outgoing, chrif_char_ask_name -> 'Do some operations (change sex, ban / unban etc)'
-//2b0f: Incoming, chrif_char_ask_name_answer -> 'answer of the 2b0e'
+//2b0e: Outgoing, chrif_req_login_operation -> 'Do some operations (change sex, ban / unban etc)'
+//2b0f: Incoming, chrif_ack_login_req -> 'answer of the 2b0e'
 //2b10: Outgoing, chrif_updatefamelist -> 'Update the fame ranking lists and send them'
 //2b11: Outgoing, chrif_divorce -> 'tell the charserver to do divorce'
 //2b12: Incoming, chrif_divorceack -> 'divorce chars
@@ -98,11 +98,11 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
 //2b25: Incoming, chrif_deadopt -> 'Removes baby from Father ID and Mother ID'
 //2b26: Outgoing, chrif_authreq -> 'client authentication request'
 //2b27: Incoming, chrif_authfail -> 'client authentication failed'
-//2b28: Outgoing, chrif_save_bankdata -> 'send bank data to be saved'
+//2b28: Outgoing, chrif_req_charban -> 'ban a specific char '
 //2b29: Incoming, chrif_load_bankdata -> 'received bank data for playeer to be loaded'
-//2b2a: Outgoing, chrif_bankdata_request -> 'request bank data for charid'
+//2b2a: Outgoing, chrif_req_charunban -> 'unban a specific char '
 //2b2b: Incoming, chrif_parse_ack_vipActive -> vip info result
-//2b2c: Outgoing, chrif_req_vipActive -> request vip info
+//2b2c: FREE
 //2b2d: Outgoing, chrif_bsdata_request -> request bonus_script for pc_authok'ed char.
 //2b2e: Outgoing, chrif_save_bsdata -> Send bonus_script of player for saving.
 //2b2f: Incoming, chrif_load_bsdata -> received bonus_script of player for loading.
@@ -288,8 +288,8 @@ int chrif_save(struct map_session_data *sd, int flag) {
 	if (chrif_isconnected()) {
 		chrif_save_scdata(sd);
 		chrif_skillcooldown_save(sd);
-		chrif_save_bankdata(sd);
 		chrif_save_bsdata(sd);
+		chrif_req_login_operation(sd->status.account_id, sd->status.name, 7, 0, 2, sd->status.bank_vault); //save Bank data
 	}
 		if ( !chrif_auth_logout(sd,flag == 1 ? ST_LOGOUT : ST_MAPCHANGE) )
 			ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id);
@@ -813,25 +813,31 @@ int chrif_changeemail(int id, const char *actual_email, const char *new_email) {
 	return 0;
 }
 
-/*==========================================
- * S 2b0e <accid>.l <name>.24B <operation_type>.w <timediff>L
+/**
+ * S 2b0e <accid>.l <name>.24B <operation_type>.w <timediff>L <val1>L <val2>L
  * Send an account modification request to the login server (via char server).
- * type of operation:
- *   1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6: charban, 7: charunban 
- *------------------------------------------*/
-int chrif_ask_char_operation(int acc, const char* character_name, unsigned short operation_type, int timediff) {
+ * @aid : Player account id
+ * @character_name : Player name
+ * @operation_type : 1: block, 2: ban, 3: unblock, 4: unban, 5: changesex (use next function for 5), 6 vip, 7 bank 
+ * @timediff : tick to add or remove to unixtimestamp
+ * @val1 : extra data value to transfer for operation
+ * @val2 : extra data value to transfer for operation
+ */
+int chrif_req_login_operation(int aid, const char* character_name, unsigned short operation_type, int timediff, int val1, int val2) {
 	chrif_check(-1);
 
-	WFIFOHEAD(char_fd,36);
+	WFIFOHEAD(char_fd,44);
 	WFIFOW(char_fd,0) = 0x2b0e;
-	WFIFOL(char_fd,2) = acc;
+	WFIFOL(char_fd,2) = aid;
 	safestrncpy((char*)WFIFOP(char_fd,6), character_name, NAME_LENGTH);
 	WFIFOW(char_fd,30) = operation_type;
 
 	if ( operation_type == 2 || operation_type == 6)
 		WFIFOL(char_fd,32) = timediff;
+	WFIFOL(char_fd,36) = val1;
+	WFIFOL(char_fd,40) = val2;
 
-	WFIFOSET(char_fd,36);
+	WFIFOSET(char_fd,44);
 	return 0;
 }
 
@@ -854,43 +860,45 @@ int chrif_changesex(struct map_session_data *sd) {
 	return 0;
 }
 
-/*==========================================
+/**
  * R 2b0f <accid>.l <name>.24B <type>.w <answer>.w
- * Processing a reply to chrif_char_ask_name() (request to modify an account).
- * type of operation:
- *   1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6: charban, 7: charunban
- * type of answer:
- *   0: login-server request done
- *   1: player not found
- *   2: gm level too low
+ * Processing a reply to chrif_req_login_operation() (request to modify an account).
+ * NB: That ack is received just after the char as sent the request to login and therefore didn't have login reply yet
+ * @param aid : player account id the request was concerning
+ * @param player_name : name the request was concerning
+ * @param type : code of operation done:
+ *   1: block, 2: ban, 3: unblock, 4: unban, 5: changesex, 6:vip
+ * @param awnser : type of anwser \n
+ *   0: login-server request done \n
+ *   1: player not found \n
+ *   2: gm level too low \n
  *   3: login-server offline
- *   4: char-server request done
- *------------------------------------------*/
-static void chrif_char_ask_name_answer(int acc, const char* player_name, uint16 type, uint16 answer) {
+ */
+static void chrif_ack_login_req(int aid, const char* player_name, uint16 type, uint16 answer) {
 	struct map_session_data* sd;
 	char action[25];
 	char output[256];
 
-	sd = map_id2sd(acc);
+	sd = map_id2sd(aid);
 
-	if( acc < 0 || sd == NULL ) {
-		ShowError("chrif_char_ask_name_answer failed - player not online.\n");
+	if( aid < 0 || sd == NULL ) {
+		ShowError("chrif_ack_login_req failed - player not online.\n");
 		return;
 	}
 
 	if( type > 0 && type <= 5 )
 		snprintf(action,25,"%s",msg_txt(sd,427+type)); //block|ban|unblock|unban|change the sex of
-	else if( type==6) snprintf(action,25,"%s","charban"); //TODO make some place for those type in msg_conf
-	else if( type==7) snprintf(action,25,"%s","charunban");
+	else if( type==6) snprintf(action,25,"%s","vip"); //TODO make some place for those type in msg_conf
+	else if( type==7) snprintf(action,25,"%s","bank");
 	else
 		snprintf(action,25,"???");
 
 	switch( answer ) {
-		case 0 : sprintf(output, msg_txt(sd,424), "login-serv", action, NAME_LENGTH, player_name); break; //%s has been asked to %s the player '%.*s'.
+		case 0 : sprintf(output, msg_txt(sd,424), action, NAME_LENGTH, player_name); break; //%s has been asked to %s the player '%.*s'.
 		case 1 : sprintf(output, msg_txt(sd,425), NAME_LENGTH, player_name); break;
 		case 2 : sprintf(output, msg_txt(sd,426), action, NAME_LENGTH, player_name); break;
 		case 3 : sprintf(output, msg_txt(sd,427), action, NAME_LENGTH, player_name); break;
-		case 4 : sprintf(output, msg_txt(sd,424), "char-serv", action, NAME_LENGTH, player_name); break;
+		case 4 : sprintf(output, msg_txt(sd,424), action, NAME_LENGTH, player_name); break;
 		default: output[0] = '\0'; break;
 	}
 
@@ -1020,7 +1028,7 @@ int chrif_deadopt(int father_id, int mother_id, int child_id) {
 }
 
 /*==========================================
- * Disconnection of a player (account has been banned of has a status, from login-server) by [Yor]
+ * Disconnection of a player (account has been banned of has a status, from login/char-server) by [Yor]
  *------------------------------------------*/
 int chrif_accountban(int fd) {
 	int acc, res=0;
@@ -1063,6 +1071,27 @@ int chrif_accountban(int fd) {
 	return 0;
 }
 
+int chrif_req_charban(int cid, int timediff){
+	chrif_check(-1);
+	
+	WFIFOHEAD(char_fd,10);
+	WFIFOW(char_fd,0) = 0x2b28;
+	WFIFOL(char_fd,2) = cid;
+	WFIFOL(char_fd,6) = timediff;
+	WFIFOSET(char_fd,10);
+	return 0;
+}
+
+int chrif_req_charunban(int cid){
+	chrif_check(-1);
+	
+	WFIFOHEAD(char_fd,6);
+	WFIFOW(char_fd,0) = 0x2b2a;
+	WFIFOL(char_fd,2) = cid;
+	WFIFOSET(char_fd,6);
+	return 0;
+}
+
 //Disconnect the player out of the game, simple packet
 //packet.w AID.L WHY.B 2+4+1 = 7byte
 int chrif_disconnectplayer(int fd) {
@@ -1196,17 +1225,6 @@ int chrif_updatefamelist_ack(int fd) {
 	return 1;
 }
 
-int chrif_bankdata_request(int account_id, int char_id) {
-
-	chrif_check(-1);
-
-	WFIFOHEAD(char_fd,6);
-	WFIFOW(char_fd,0) = 0x2b2a;
-	WFIFOL(char_fd,2) = account_id;
-	WFIFOSET(char_fd,6);
- 	return 0;
-}
-
 int chrif_load_bankdata(int fd){
 	struct map_session_data *sd;
 	int aid, bank_vault;
@@ -1224,19 +1242,7 @@ int chrif_load_bankdata(int fd){
  	return 1;
 }
 
-int chrif_save_bankdata(struct map_session_data *sd){
-	if( CheckForCharServer() )
-		return 0;
-	WFIFOHEAD(char_fd,10);
-	WFIFOW(char_fd,0) = 0x2b28;
-	WFIFOL(char_fd,2) = sd->status.account_id;
-	WFIFOL(char_fd,6) = sd->status.bank_vault;
-	WFIFOSET(char_fd,10);
- 	return 1;
-}
-
 int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the player and sends it to the char-server for saving. [Skotlex]
-
 #ifdef ENABLE_SC_SAVING
 	int i, count=0;
 	unsigned int tick;
@@ -1540,21 +1546,6 @@ void chrif_parse_ack_vipActive(int fd) {
 #endif
 }
 
-int chrif_req_vipActive(TBL_PC *sd, int8 req_duration, int8 type) {
-#ifdef VIP_ENABLE
-	if (CheckForCharServer() || sd == NULL)
-		return 0;
-
-	WFIFOHEAD(char_fd,11);
-	WFIFOW(char_fd,0) = 0x2b2c;
-	WFIFOL(char_fd,2) = sd->bl.id; // AID
-	WFIFOB(char_fd,6) = type; // type&1 - SQL SELECT, type&2 - SQL UPDATE
-	WFIFOL(char_fd,7) = req_duration;
-	WFIFOSET(char_fd,11);
-#endif
-	return 0;
-}
-
 /*==========================================
  *
  *------------------------------------------*/
@@ -1618,7 +1609,7 @@ int chrif_parse(int fd) {
 			case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
 			case 0x2b0b: chrif_skillcooldown_load(fd); break;
 			case 0x2b0d: chrif_changedsex(fd); break;
-			case 0x2b0f: chrif_char_ask_name_answer(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
+			case 0x2b0f: chrif_ack_login_req(RFIFOL(fd,2), (char*)RFIFOP(fd,6), RFIFOW(fd,30), RFIFOW(fd,32)); break;
 			case 0x2b12: chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break;
 			case 0x2b14: chrif_accountban(fd); break;
 			case 0x2b1b: chrif_recvfamelist(fd); break;

+ 7 - 5
src/map/chrif.h

@@ -41,16 +41,14 @@ int chrif_scdata_request(int account_id, int char_id);
 int chrif_skillcooldown_request(int account_id, int char_id);
 int chrif_skillcooldown_save(struct map_session_data *sd);
 int chrif_skillcooldown_load(int fd);
-int chrif_bankdata_request(int account_id, int char_id);
-int chrif_load_bankdata(int fd);
-int chrif_save_bankdata(struct map_session_data *sd);
+
 int chrif_save(struct map_session_data* sd, int flag);
 int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip);
 int chrif_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port);
 
 int chrif_searchcharid(int char_id);
 int chrif_changeemail(int id, const char *actual_email, const char *new_email);
-int chrif_ask_char_operation(int acc, const char* character_name, unsigned short operation_type, int timediff);
+int chrif_req_login_operation(int aid, const char* character_name, unsigned short operation_type, int timediff, int val1, int val2);
 int chrif_updatefamelist(struct map_session_data *sd);
 int chrif_buildfamelist(void);
 int chrif_save_scdata(struct map_session_data *sd);
@@ -68,7 +66,11 @@ int chrif_removefriend(int char_id, int friend_id);
 int chrif_send_report(char* buf, int len);
 
 void chrif_parse_ack_vipActive(int fd);
-int chrif_req_vipActive(struct map_session_data *sd, int8 req_duration, int8 type);
+
+int chrif_req_charban(int aid, int timediff);
+int chrif_req_charunban(int cid);
+
+int chrif_load_bankdata(int fd);
 
 int chrif_bsdata_request(int char_id);
 int chrif_save_bsdata(struct map_session_data *sd);

+ 6 - 2
src/map/pc.c

@@ -1274,10 +1274,14 @@ 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);
 	chrif_skillcooldown_request(sd->status.account_id, sd->status.char_id);
-	chrif_bankdata_request(sd->status.account_id, sd->status.char_id);
 	chrif_bsdata_request(sd->status.char_id);
 	sd->storage_size = MIN_STORAGE; //default to min
-	chrif_req_vipActive(sd, 0, 1); // request VIP informations
+	chrif_req_login_operation(sd->status.account_id, sd->status.name, 7, 0, 1, 0); //request Bank data
+#ifdef VIP_ENABLE
+	sd->vip.time = 0;
+	sd->vip.enabled = 0;
+	chrif_req_login_operation(sd->status.account_id, sd->status.name, 6, 0, 1, 0);  // request VIP informations
+#endif	
 	intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
 	intif_request_questlog(sd);
 

+ 2 - 2
src/map/pc.h

@@ -554,8 +554,8 @@ struct map_session_data {
 	int storage_size; // Holds player storage size (VIP system).
 #ifdef VIP_ENABLE
 	struct {
-		unsigned int enabled;
-		unsigned int time;
+		unsigned int enabled : 1;
+		time_t time;
 	} vip;
 #endif
 

+ 21 - 23
src/map/script.c

@@ -4408,7 +4408,6 @@ BUILDIN_FUNC(mes)
 	}
 
 	st->mes_active = 1; // Invoking character has a NPC dialog box open.
-
 	return 0;
 }
 
@@ -4886,7 +4885,6 @@ BUILDIN_FUNC(callfunc)
 	st->stack->defsp = st->stack->sp;
 	st->state = GOTO;
 	st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
-
 	return 0;
 }
 /*==========================================
@@ -4935,7 +4933,6 @@ BUILDIN_FUNC(callsub)
 	st->stack->defsp = st->stack->sp;
 	st->state = GOTO;
 	st->stack->var_function = idb_alloc(DB_OPT_RELEASE_DATA);
-
 	return 0;
 }
 
@@ -4968,7 +4965,6 @@ BUILDIN_FUNC(getarg)
 		st->state = END;
 		return 1;
 	}
-
 	return 0;
 }
 
@@ -5065,7 +5061,7 @@ BUILDIN_FUNC(warp)
 
 	if( ret ) {
 		ShowError("buildin_warp: moving player '%s' to \"%s\",%d,%d failed.\n", sd->status.name, str, x, y);
-		script_reportsrc(st);
+		return 1;
 	}
 
 	return 0;
@@ -5106,6 +5102,7 @@ static int buildin_areawarp_sub(struct block_list *bl,va_list ap)
 		pc_setpos((TBL_PC *)bl,index,x2,y2,CLR_OUTSIGHT);
 	return 0;
 }
+
 BUILDIN_FUNC(areawarp)
 {
 	int16 m, x0,y0,x1,y1, x2,y2,x3=0,y3=0;
@@ -5156,6 +5153,7 @@ static int buildin_areapercentheal_sub(struct block_list *bl,va_list ap)
 	pc_percentheal((TBL_PC *)bl,hp,sp);
 	return 0;
 }
+
 BUILDIN_FUNC(areapercentheal)
 {
 	int hp,sp,m;
@@ -5298,6 +5296,7 @@ BUILDIN_FUNC(warpparty)
 
 	return 0;
 }
+
 /*==========================================
  * Warpguild - [Fredzilla]
  * Syntax: warpguild "mapname",x,y,Guild_ID;
@@ -5359,6 +5358,7 @@ BUILDIN_FUNC(warpguild)
 
 	return 0;
 }
+
 /*==========================================
  * Force Heal a player (hp and sp)
  *------------------------------------------*/
@@ -5375,6 +5375,7 @@ BUILDIN_FUNC(heal)
 	status_heal(&sd->bl, hp, sp, 1);
 	return 0;
 }
+
 /*==========================================
  * Heal a player by item (get vit bonus etc)
  *------------------------------------------*/
@@ -5397,6 +5398,7 @@ BUILDIN_FUNC(itemheal)
 	pc_itemheal(sd,sd->itemid,hp,sp);
 	return 0;
 }
+
 /*==========================================
  *
  *------------------------------------------*/
@@ -6135,7 +6137,7 @@ BUILDIN_FUNC(countitem)
 				sd->status.inventory[i].attribute == attr && sd->status.inventory[i].card[0] == c1 &&
 				sd->status.inventory[i].card[1] == c2 && sd->status.inventory[i].card[2] == c3 &&
 				sd->status.inventory[i].card[3] == c4 )
-	 	                        count += sd->status.inventory[i].amount;
+					count += sd->status.inventory[i].amount;
 	}
 
 	script_pushint(st,count);
@@ -6292,7 +6294,6 @@ BUILDIN_FUNC(checkweight2){
 	} //end loop DO NOT break it prematurly we need to depop all stack
 
 	script_pushint(st,checkweight_sub(sd,nb_it,nameid,amount)); //push result of sub to script
-
 	return 0;
 }
 
@@ -6390,7 +6391,6 @@ BUILDIN_FUNC(getitem)
 			}
 		}
 	}
-
 	return 0;
 }
 
@@ -6501,7 +6501,6 @@ BUILDIN_FUNC(getitem2)
 			}
 		}
 	}
-
 	return 0;
 }
 
@@ -6561,7 +6560,6 @@ BUILDIN_FUNC(rentitem)
 		clif_additem(sd, 0, 0, flag);
 		return 1;
 	}
-
 	return 0;
 }
 
@@ -6699,7 +6697,6 @@ BUILDIN_FUNC(makeitem)
 
 		map_addflooritem(&item_tmp,amount,m,x,y,0,0,0,4);
 	}
-
 	return 0;
 }
 
@@ -16850,7 +16847,7 @@ BUILDIN_FUNC(instance_announce) {
 		map_foreachinmap(buildin_announce_sub, instance_data[instance_id].map[i].m, BL_PC,
 						 mes, strlen(mes)+1, flag&0xf0, fontColor, fontType, fontSize, fontAlign, fontY);
 
-	return true;
+	return 0;
 }
 
 /*==========================================
@@ -18027,7 +18024,7 @@ BUILDIN_FUNC(getserverdef) {
 BUILDIN_FUNC(vip_status) {
 #ifdef VIP_ENABLE
 	TBL_PC *sd;
-	char *vip_str = (char *)aMalloc(24*sizeof(char));
+	char vip_str[26];
 	time_t now = time(NULL);
 	int type = script_getnum(st, 2);
 
@@ -18045,19 +18042,20 @@ BUILDIN_FUNC(vip_status) {
 			break;
 		case 2: // Get VIP expire date.
 			if (pc_isvip(sd)) {
-				time_t viptime = (time_t)sd->vip.time;
+				time_t viptime = sd->vip.time;
 				strftime(vip_str, 24, "%Y-%m-%d %H:%M", localtime(&viptime));
-				vip_str[24] = '\0';
-				script_pushstr(st, vip_str);
+				vip_str[25] = '\0';
+				script_pushstrcopy(st, vip_str);
 			} else
 				script_pushint(st, 0);
 			break;
 		case 3: // Get remaining time.
 			if (pc_isvip(sd)) {
-				time_t viptime = (time_t)sd->vip.time;
-				strftime(vip_str, 24, "%Y-%m-%d %H:%M", localtime(&viptime - now));
-				vip_str[24] = '\0';
-				script_pushstr(st, vip_str);
+				time_t viptime_remain = sd->vip.time - now;
+				int year=0,month=0,day=0,hour=0,min=0,sec=0;
+				split_time(viptime_remain,&year,&month,&day,&hour,&min,&sec);
+				safesnprintf(vip_str,sizeof(vip_str),"%d-%d-%d %d:%d",year,month,day,hour,min);
+				script_pushstrcopy(st, vip_str);
 			} else
 				script_pushint(st, 0);
 			break;
@@ -18070,13 +18068,13 @@ BUILDIN_FUNC(vip_status) {
 
 #ifdef VIP_ENABLE
 /* Adds or removes VIP time in minutes.
- * vip_time <time>,{"<character name>"};
+ * vip_time <time in mn>,{"<character name>"};
  * If time < 0 remove time, else add time.
  * Note: VIP System needs to be enabled. 
  */
 BUILDIN_FUNC(vip_time) {
 	TBL_PC *sd;
-	int time = script_getnum(st, 2) * 60; // Convert since it's given in minutes.
+	int viptime = script_getnum(st, 2) * 60; // Convert since it's given in minutes.
 
 	if (script_hasdata(st, 3))
 		sd = map_nick2sd(script_getstr(st, 3));
@@ -18086,7 +18084,7 @@ BUILDIN_FUNC(vip_time) {
 	if (sd == NULL)
 		return 0;
 
-	chrif_req_vipActive(sd, time, 2);
+	chrif_req_login_operation(sd->status.account_id, sd->status.name, 6, viptime, 7, 0); 
 
 	return 0;
 }

+ 2 - 2
src/map/trade.c

@@ -207,13 +207,13 @@ int impossible_trade_check(struct map_session_data *sd)
 			intif_wis_message_to_gm(wisp_server_name, PC_PERM_RECEIVE_HACK_INFO, message_to_gm);
 			// if we block people
 			if (battle_config.ban_hack_trade < 0) {
-				chrif_ask_char_operation(-1, sd->status.name, 1, 0); // type: 1 - block
+				chrif_req_login_operation(-1, sd->status.name, 1, 0, 0, 0); // type: 1 - block
 				set_eof(sd->fd); // forced to disconnect because of the hack
 				// message about the ban
 				strcpy(message_to_gm, msg_txt(sd,540)); //  This player has been definitively blocked.
 			// if we ban people
 			} else if (battle_config.ban_hack_trade > 0) {
-				chrif_ask_char_operation(-1, sd->status.name, 2, battle_config.ban_hack_trade*60); // type: 2 - ban (year, month, day, hour, minute, second)
+				chrif_req_login_operation(-1, sd->status.name, 2, battle_config.ban_hack_trade*60, 0, 0); // type: 2 - ban (year, month, day, hour, minute, second)
 				set_eof(sd->fd); // forced to disconnect because of the hack
 				// message about the ban
 				sprintf(message_to_gm, msg_txt(sd,507), battle_config.ban_hack_trade); //  This player has been banned for %d minute(s).