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 năm trước cách đây
mục cha
commit
4684090de9
12 tập tin đã thay đổi với 436 bổ sung428 xóa
  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).