Kaynağa Gözat

* Merge pull request #294 and its clean up
* Moved Bank Vault from `login` table (login-server level) to `global_reg_value` as #BANKVAULT (char-server level)
* IMPORTANT: Read & import upgrade_20150408.sql
* Follow up cbdc0127, another fix for Point Shop NPC.
* Follow up 022d7289, corrected picklog initial for bound items that removed when member of guild/party or guild/party is broken. Please import upgrade_20150408_log.sql

Signed-off-by: Cydh Ramdh <cydh@pservero.com>

Cydh Ramdh 10 yıl önce
ebeveyn
işleme
5ed75dc877

+ 1 - 0
conf/log_athena.conf

@@ -29,6 +29,7 @@
 //           rings deleted by divorce/pet egg (un)hatching/pet armor (un)equipping/Weapon Refine skill/Remove Trap skill)
 // 0x20000 - ($) Log cash transactions
 // 0x40000 - (K) Log account bank transactions
+// 0x80000 - (F) Removed bound items when guild/party is broken
 // Example: Log trades+vending+script items+created items: 1+2+32+1024 = 1059
 // Please note that moving items from inventory to cart and back is not logged by design.
 enable_logs: 0xFFFFF

+ 1 - 0
db/const.txt

@@ -432,6 +432,7 @@ Sitting	123	1
 CharMoves	124	1
 CharRename	125	1
 Font		126	1
+BankVault	127	1
 
 bMaxHP	6
 bMaxSP	8

+ 7 - 39
doc/packet_interserv.txt

@@ -99,9 +99,9 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket.
 
 0x2717
 	Type: AH
-	Structure: <cmd>.W <aid>.L <email>.40B <expiration_time>.L <group_id>.B <char_slots>.B <birthdate>.11B <pincode>.5B <pincode_change>.L <bank_vault>.L <isvip>.B <char_vip>.B <MAX_CHAR_BILLING>.B
-	index: 0,2,6,46,50,51,52,63,68,72,76,77,78
-	len: 79
+	Structure: <cmd>.W <aid>.L <email>.40B <expiration_time>.L <group_id>.B <char_slots>.B <birthdate>.11B <pincode>.5B <pincode_change>.L <isvip>.B <char_vip>.B <MAX_CHAR_BILLING>.B
+	index: 0,2,6,46,50,51,52,63,68,72,73,74
+	len: 75
 	parameter:
 		- cmd: packet identification (0x2717)
 		- aid: account identification
@@ -112,7 +112,6 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket.
 		- birthdate: birthdate of aid
 		- pincode: current pincode of aid
 		- pincode_change: new pincode of aid
-		- bank_vault: value in bank for this aid
 		- isvip: if this aid is currently vip or not
 		- char_vip: number of charslot that are vip (could only do creation on if you are vip)
 		- MAX_CHAR_BILLING: number of charslort that are for billing
@@ -437,31 +436,9 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket.
 0x273f
 	free
 
-0x2740:
-	Type: HA
-	Structure: <cmd>.W <aid>.L <type>.B <data>.L
-	index: 0,2,6,7
-	len: 11
-	parameter:
-		- cmd : packet identification (0x2740)
-		- aid: account identification
-		- type:
-		- data:
-	desc:
-		- Request to update bank_vault
-
-0x2741:
-	Type: AH
-	Structure: <cmd>.W <aid>.L <type>.B <data>.L
-	index: 0,2,6,7
-	len: 11
-	parameter:
-		- cmd : packet identification (0x2741)
-		- aid : account identification
-		- type : 1=select, 2=upd and save
-		- data : new bank vault
-	desc:
-		- Request the bank info of login
+0x2740
+0x2741
+	free
 
 0x2742:
 	Type: HA
@@ -2467,16 +2444,7 @@ Currently the max packet size is 0xFFFF (see 'WFIFOSET()' in 'src/common/socket.
 		- Client authentication failed
 
 0x2b29
-	Type: AZ
-	Structure: <cmd>.W <aid>.L <bank_vault>.L
-	index: 0,2,6
-	len: 10
-	parameter:
-		- cmd : packet identification (0x2b29)
-		- aid
-		- bank_vault
-	desc:
-		- Received bank data for player to be loaded
+	free
 
 0x2b2b
 	Type: AZ

+ 3 - 3
sql-files/logs.sql

@@ -2,7 +2,7 @@
 # Players (T)rade Give/Take, Players (V)ending Sell/Take, (S)hop Sell/Take, (N)PC Give/Take,
 # (C)onsumable Items, (A)dministrators Create/Delete, Sto(R)age, (G)uild Storage,
 # (E)mail attachment,(B)uying Store, Pr(O)duced Items/Ingredients, Auct(I)oned Items,
-# (X) Other, (D) Stolen from mobs, (U) MVP Prizes
+# (X) Other, (D) Stolen from mobs, (U) MVP Prizes, F:Guild/Party Bound retrieval
 
 #Database: ragnarok
 #Table: picklog
@@ -10,7 +10,7 @@ CREATE TABLE IF NOT EXISTS `picklog` (
   `id` int(11) NOT NULL auto_increment,
   `time` datetime NOT NULL default '0000-00-00 00:00:00',
   `char_id` int(11) NOT NULL default '0',
-  `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U','$') NOT NULL default 'P',
+  `type` enum('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U','$','F') NOT NULL default 'P',
   `nameid` smallint(5) unsigned NOT NULL default '0',
   `amount` int(11) NOT NULL default '1',
   `refine` tinyint(3) unsigned NOT NULL default '0',
@@ -25,7 +25,7 @@ CREATE TABLE IF NOT EXISTS `picklog` (
   INDEX (`type`)
 ) ENGINE=MyISAM AUTO_INCREMENT=1 ;
 
-#ZenyLog types (M)onsters,(T)rade,(V)ending Sell/Buy,(S)hop Sell/Buy,(N)PC Change amount,(A)dministrators,(E)Mail,(B)uying Store
+#ZenyLog types (M)onsters,(T)rade,(V)ending Sell/Buy,(S)hop Sell/Buy,(N)PC Change amount,(A)dministrators,(E)Mail,(B)uying Store,Ban(K) Transactions
 #Database: ragnarok
 #Table: zenylog
 CREATE TABLE IF NOT EXISTS `zenylog` (

+ 0 - 1
sql-files/main.sql

@@ -462,7 +462,6 @@ CREATE TABLE IF NOT EXISTS `login` (
   `character_slots` tinyint(3) unsigned NOT NULL default '0',
   `pincode` varchar(4) NOT NULL DEFAULT '',
   `pincode_change` int(11) unsigned NOT NULL DEFAULT '0',
-  `bank_vault` int(11) NOT NULL DEFAULT '0',
   `vip_time` int(11) unsigned NOT NULL default '0',
   `old_group` tinyint(3) NOT NULL default '0',
   PRIMARY KEY  (`account_id`),

+ 9 - 0
sql-files/upgrades/upgrade_20150408.sql

@@ -0,0 +1,9 @@
+-- Move `bank_vault` value from `login` to `global_reg_value`.
+-- Please be careful if you're running multi char-server, better you do this step manually to move the `bank_vault`
+-- to proper `global_reg_value` tables of char-servers used.
+INSERT INTO `global_reg_value` (`char_id`, `str`, `value`, `type`, `account_id`)
+    SELECT '0', '#BANKVAULT', `bank_vault`, '2', `account_id`
+	    FROM `login` WHERE `bank_vault` != 0;
+
+-- Remove `bank_vault` from `login` table, login-server side.
+ALTER TABLE `login` DROP `bank_vault`;

+ 1 - 0
sql-files/upgrades/upgrade_20150408_log.sql

@@ -0,0 +1 @@
+ALTER TABLE `picklog` CHANGE `type` `type` ENUM('M','P','L','T','V','S','N','C','A','R','G','E','B','O','I','X','D','U','$','F') NOT NULL DEFAULT 'P';

+ 0 - 1
src/char/char.h

@@ -198,7 +198,6 @@ struct char_session_data {
 	time_t pincode_change;
 	uint16 pincode_try;
 	// Addon system
-	int bank_vault;
 	unsigned int char_moves[MAX_CHARS]; // character moves left
 	uint8 isvip;
 	time_t unban_time[MAX_CHARS];

+ 5 - 46
src/char/char_logif.c

@@ -291,7 +291,7 @@ int chlogif_parse_ackaccreq(int fd, struct char_session_data* sd){
 
 int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
 	int u_fd; //user fd
-	if (RFIFOREST(fd) < 79)
+	if (RFIFOREST(fd) < 75)
 		return 0;
 
 	// find the authenticated session with this account id
@@ -311,10 +311,9 @@ int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
 		safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate));
                 safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode));
                 sd->pincode_change = (time_t)RFIFOL(fd,68);
-                sd->bank_vault = RFIFOL(fd,72);
-                sd->isvip = RFIFOB(fd,76);
-                sd->chars_vip = RFIFOB(fd,77);
-                sd->chars_billing = RFIFOB(fd,78);
+                sd->isvip = RFIFOB(fd,72);
+                sd->chars_vip = RFIFOB(fd,73);
+                sd->chars_billing = RFIFOB(fd,74);
 		ARR_FIND( 0, ARRAYLENGTH(map_server), server_id, map_server[server_id].fd > 0 && map_server[server_id].map[0] );
 		// continued from char_auth_ok...
 		if( server_id == ARRAYLENGTH(map_server) || //server not online, bugreport:2359
@@ -329,7 +328,7 @@ int chlogif_parse_reqaccdata(int fd, struct char_session_data* sd){
 				chlogif_pincode_start(u_fd,sd);
 		}
 	}
-	RFIFOSKIP(fd,79);
+	RFIFOSKIP(fd,75);
 	return 1;
 }
 
@@ -517,45 +516,6 @@ int chlogif_parse_updip(int fd, struct char_session_data* sd){
 	return 1;
 }
 
-/**
- * Send to login-serv the request of banking operation from map
- * HA 0x2740<aid>L <type>B <data>L
- * @param account_id
- * @param type : 0 = select, 1 = update
- * @param data
- * @return
- */
-int chlogif_BankingReq(int32 account_id, int8 type, int32 data){
-	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
- */
-int chlogif_parse_BankingAck(int fd){
-	if (RFIFOREST(fd) < 11)
-            return 0;
-	else {
-		uint32 aid = RFIFOL(fd,2);
-		int32 bank_vault = RFIFOL(fd,6);
-		char not_fw = RFIFOB(fd,10);
-		RFIFOSKIP(fd,11);
-
-		if(not_fw==0) chmapif_BankingAck(aid, bank_vault);
-	}
-	return 1;
-}
-
 /*
  * AH 0x2743
  * We received the info from login-serv, transmit it to map
@@ -679,7 +639,6 @@ int chlogif_parse(int fd) {
 		uint16 command = RFIFOW(fd,0);
 		switch( command )
 		{
-			case 0x2741: next = chlogif_parse_BankingAck(fd); break;
 			case 0x2743: next = chlogif_parse_vipack(fd); break;
 			// acknowledgement of connect-to-loginserver request
 			case 0x2711: next = chlogif_parse_ackconnect(fd,sd); break;

+ 0 - 2
src/char/char_logif.h

@@ -36,8 +36,6 @@ int chlogif_parse_accbannotification(int fd, struct char_session_data* sd);
 int chlogif_parse_askkick(int fd, struct char_session_data* sd);
 int chlogif_parse_updip(int fd, struct char_session_data* sd);
 
-int chlogif_BankingReq(int32 account_id, int8 type, int32 data);
-int chlogif_parse_BankingAck(int fd);
 int chlogif_parse_vipack(int fd);
 int chlogif_reqvipdata(uint32 aid, uint8 type, int32 timediff, int mapfd);
 int chlogif_req_accinfo(int fd, int u_fd, int u_aid, int u_group, int account_id, int8 type);

+ 40 - 54
src/char/char_mapif.c

@@ -730,7 +730,7 @@ int chmapif_parse_fwlog_changestatus(int fd){
 
 		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-vip, 7-bank
+		int operation = RFIFOW(fd,30); // type of operation: 1-block, 2-ban, 3-unblock, 4-unban, 5-changesex, 6-vip
 		int32 timediff = RFIFOL(fd,32);
 		int val1 = RFIFOL(fd,36);
 		int val2 = RFIFOL(fd,40);
@@ -757,50 +757,47 @@ int chmapif_parse_fwlog_changestatus(int fd){
 			//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
+			//! NOTE: See src/char/chrif.h::enum chrif_req_op for the number
 			else {
 				switch( operation ) {
-				case 1: // block
-					WFIFOHEAD(login_fd,10);
-					WFIFOW(login_fd,0) = 0x2724;
-					WFIFOL(login_fd,2) = t_aid;
-					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) = t_aid;
-					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) = t_aid;
-					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) = t_aid;
-					WFIFOSET(login_fd,6);
-				break;
-				case 5: // changesex
-					answer = false;
-					WFIFOHEAD(login_fd,6);
-					WFIFOW(login_fd,0) = 0x2727;
-					WFIFOL(login_fd,2) = t_aid;
-					WFIFOSET(login_fd,6);
-				break;
-				case 6:
-					answer = (val1&4); // vip_req val1=type, &1 login send return, &2 update timestamp, &4 map send answer
-					chlogif_reqvipdata(t_aid, val1, timediff, fd);
-					break;
-				case 7:
-					answer = (val1&1); //val&1 request answer, val1&2 save data
-					chlogif_BankingReq(aid, val1, val2);
-					break;
+					case 1: // block
+						WFIFOHEAD(login_fd,10);
+						WFIFOW(login_fd,0) = 0x2724;
+						WFIFOL(login_fd,2) = t_aid;
+						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) = t_aid;
+						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) = t_aid;
+						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) = t_aid;
+						WFIFOSET(login_fd,6);
+						break;
+					case 5: // changesex
+						answer = false;
+						WFIFOHEAD(login_fd,6);
+						WFIFOW(login_fd,0) = 0x2727;
+						WFIFOL(login_fd,2) = t_aid;
+						WFIFOSET(login_fd,6);
+						break;
+					case 6:
+						answer = (val1&4); // vip_req val1=type, &1 login send return, &2 update timestamp, &4 map send answer
+						chlogif_reqvipdata(t_aid, val1, timediff, fd);
+						break;
 				} //end switch operation
 			} //login is connected
 		}
@@ -1183,17 +1180,6 @@ int chmapif_parse_updfamelist(int fd){
     return 1;
 }
 
-//HZ 0x2b29 <aid>L <bank_vault>L
-int chmapif_BankingAck(int32 account_id, int32 bank_vault){
-	unsigned char buf[11];
-	WBUFW(buf,0) = 0x2b29;
-	WBUFL(buf,2) = account_id;
-	WBUFL(buf,6) = bank_vault;
-	chmapif_sendall(buf, 10); //inform all maps-attached
-	return 1;
-}
-
-
 /*
  * HZ 0x2b2b
  * Transmist vip data to mapserv

+ 0 - 1
src/char/char_mapif.h

@@ -47,7 +47,6 @@ int chmapif_parse_reqauth(int fd, int id);
 int chmapif_parse_updmapip(int fd, int id);
 int chmapif_parse_fw_configstats(int fd);
 
-int chmapif_BankingAck(int32 account_id, int32 bank_vault);
 int chmapif_vipack(int mapfd, uint32 aid, uint32 vip_time, uint8 isvip, uint8 isgm, uint32 groupid);
 int chmapif_parse_reqcharban(int fd);
 int chmapif_parse_reqcharunban(int fd);

+ 0 - 1
src/common/mmo.h

@@ -379,7 +379,6 @@ struct mmo_charstatus {
 
 	unsigned int base_exp,job_exp;
 	int zeny;
-	int bank_vault;
 
 	short class_;
 	unsigned int status_point,skill_point;

+ 12 - 15
src/login/account.c

@@ -496,9 +496,9 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, uint32
 	// retrieve login entry for the specified account
 	if( SQL_ERROR == Sql_Query(sql_handle,
 #ifdef VIP_ENABLE
-		"SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change`, `bank_vault`, `vip_time`, `old_group` FROM `%s` WHERE `account_id` = %d",
+		"SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change`, `vip_time`, `old_group` FROM `%s` WHERE `account_id` = %d",
 #else
-		"SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change`, `bank_vault` FROM `%s` WHERE `account_id` = %d",
+		"SELECT `account_id`,`userid`,`user_pass`,`sex`,`email`,`group_id`,`state`,`unban_time`,`expiration_time`,`logincount`,`lastlogin`,`last_ip`,`birthdate`,`character_slots`,`pincode`, `pincode_change` FROM `%s` WHERE `account_id` = %d",
 #endif
 		db->account_db, account_id )
 	) {
@@ -528,10 +528,9 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, uint32
 	Sql_GetData(sql_handle, 13, &data, NULL); acc->char_slots = atoi(data);
 	Sql_GetData(sql_handle, 14, &data, NULL); safestrncpy(acc->pincode, data, sizeof(acc->pincode));
 	Sql_GetData(sql_handle, 15, &data, NULL); acc->pincode_change = atol(data);
-	Sql_GetData(sql_handle, 16, &data, NULL); acc->bank_vault = atoi(data);
 #ifdef VIP_ENABLE
-	Sql_GetData(sql_handle, 17, &data, NULL); acc->vip_time = atol(data);
-	Sql_GetData(sql_handle, 18, &data, NULL); acc->old_group = atoi(data);
+	Sql_GetData(sql_handle, 16, &data, NULL); acc->vip_time = atol(data);
+	Sql_GetData(sql_handle, 17, &data, NULL); acc->old_group = atoi(data);
 #endif
 	Sql_FreeResult(sql_handle);
 	
@@ -586,9 +585,9 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
 	{// insert into account table
 		if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
 #ifdef VIP_ENABLE
-			"INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`, `bank_vault`, `vip_time`, `old_group` ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+			"INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`, `vip_time`, `old_group` ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
 #else
-			"INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`, `bank_vault`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+			"INSERT INTO `%s` (`account_id`, `userid`, `user_pass`, `sex`, `email`, `group_id`, `state`, `unban_time`, `expiration_time`, `logincount`, `lastlogin`, `last_ip`, `birthdate`, `character_slots`, `pincode`, `pincode_change`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
 #endif
 			db->account_db)
 		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_INT,       (void*)&acc->account_id,      sizeof(acc->account_id))
@@ -607,10 +606,9 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
 		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_UCHAR,     (void*)&acc->char_slots,      sizeof(acc->char_slots))
 		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_STRING,    (void*)&acc->pincode,         strlen(acc->pincode))
 		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_LONG,      (void*)&acc->pincode_change,  sizeof(acc->pincode_change))
-		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 16, SQLDT_INT,       (void*)&acc->bank_vault,      sizeof(acc->bank_vault))
 #ifdef VIP_ENABLE
-		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 17, SQLDT_LONG,       (void*)&acc->vip_time,         sizeof(acc->vip_time))
-		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 18, SQLDT_INT,       (void*)&acc->old_group,        sizeof(acc->old_group))
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 16, SQLDT_LONG,       (void*)&acc->vip_time,         sizeof(acc->vip_time))
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 17, SQLDT_INT,        (void*)&acc->old_group,        sizeof(acc->old_group))
 #endif
 		||  SQL_SUCCESS != SqlStmt_Execute(stmt)
 		) {
@@ -622,9 +620,9 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
 	{// update account table
 		if( SQL_SUCCESS != SqlStmt_Prepare(stmt, 
 #ifdef VIP_ENABLE
-			"UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=?, `bank_vault`=?, `vip_time`=?, `old_group`=? WHERE `account_id` = '%d'",
+			"UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=?, `vip_time`=?, `old_group`=? WHERE `account_id` = '%d'",
 #else
-			"UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=?, `bank_vault`=? WHERE `account_id` = '%d'",
+			"UPDATE `%s` SET `userid`=?,`user_pass`=?,`sex`=?,`email`=?,`group_id`=?,`state`=?,`unban_time`=?,`expiration_time`=?,`logincount`=?,`lastlogin`=?,`last_ip`=?,`birthdate`=?,`character_slots`=?,`pincode`=?, `pincode_change`=? WHERE `account_id` = '%d'",
 #endif
 			db->account_db, acc->account_id)
 		||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_STRING,    (void*)acc->userid,           strlen(acc->userid))
@@ -642,10 +640,9 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
 		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_UCHAR,     (void*)&acc->char_slots,      sizeof(acc->char_slots))
 		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_STRING,    (void*)&acc->pincode,         strlen(acc->pincode))
 		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_LONG,      (void*)&acc->pincode_change,  sizeof(acc->pincode_change))
-		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_INT,       (void*)&acc->bank_vault,      sizeof(acc->bank_vault))
 #ifdef VIP_ENABLE
-		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 16, SQLDT_LONG,      (void*)&acc->vip_time,        sizeof(acc->vip_time))
-		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 17, SQLDT_INT,       (void*)&acc->old_group,       sizeof(acc->old_group))
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_LONG,      (void*)&acc->vip_time,        sizeof(acc->vip_time))
+		||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 16, SQLDT_INT,       (void*)&acc->old_group,       sizeof(acc->old_group))
 #endif
 		||  SQL_SUCCESS != SqlStmt_Execute(stmt)
 		) {

+ 0 - 1
src/login/account.h

@@ -39,7 +39,6 @@ struct mmo_account {
 	char pincode[PINCODE_LENGTH+1];		// pincode system
 	time_t pincode_change;	// (timestamp): last time of pincode change
 	int account_reg2_num;
-	int bank_vault;
 #ifdef VIP_ENABLE
 	int old_group;
 	time_t vip_time;

+ 0 - 1
src/login/login.c

@@ -243,7 +243,6 @@ int login_mmo_auth_new(const char* userid, const char* pass, const char sex, con
 	safestrncpy(acc.pincode, "", sizeof(acc.pincode));
 	acc.pincode_change = 0;
 	acc.char_slots = MIN_CHARS;
-	acc.bank_vault = 0;
 #ifdef VIP_ENABLE
 	acc.vip_time = 0;
 	acc.old_group = 0;

+ 7 - 53
src/login/loginchrif.c

@@ -184,8 +184,8 @@ int logchrif_parse_updmail(int fd, int id, char* ip){
 
 /**
  * Transmit account data to char_server
- * S 2717 aid.W email.40B exp_time.L group_id.B char_slot.B birthdate.11B pincode.5B pincode_change.L bank_vault.L
- *  isvip.1B char_vip.1B max_billing.1B (tot 79)  
+ * S 2717 aid.W email.40B exp_time.L group_id.B char_slot.B birthdate.11B pincode.5B pincode_change.L
+ *  isvip.1B char_vip.1B max_billing.1B (tot 75)  
  * @return -1 : account not found, 1:sucess
  */
 int logchrif_send_accdata(int fd, uint32 aid) {
@@ -195,7 +195,6 @@ int logchrif_send_accdata(int fd, uint32 aid) {
 	int group_id = 0;
 	char birthdate[10+1] = "";
 	char pincode[PINCODE_LENGTH+1];
-	int bank_vault = 0;
 	char isvip = false;
 	uint8 char_slots = MIN_CHARS, char_vip = 0;
 	AccountDB* accounts = login_get_accounts_db();
@@ -210,7 +209,6 @@ int logchrif_send_accdata(int fd, uint32 aid) {
 
 		safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
 		safestrncpy(pincode, acc.pincode, sizeof(pincode));
-		bank_vault = acc.bank_vault;
 #ifdef VIP_ENABLE
 		char_vip = login_config.vip_sys.char_increase;
 		if( acc.vip_time > time(NULL) ) {
@@ -221,7 +219,7 @@ int logchrif_send_accdata(int fd, uint32 aid) {
 #endif
 	}
 
-	WFIFOHEAD(fd,79);
+	WFIFOHEAD(fd,75);
 	WFIFOW(fd,0) = 0x2717;
 	WFIFOL(fd,2) = aid;
 	safestrncpy((char*)WFIFOP(fd,6), email, 40);
@@ -231,11 +229,10 @@ int logchrif_send_accdata(int fd, uint32 aid) {
 	safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
 	safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
 	WFIFOL(fd,68) = (uint32)acc.pincode_change;
-	WFIFOL(fd,72) = bank_vault;
-	WFIFOB(fd,76) = isvip;
-	WFIFOB(fd,77) = char_vip;
-	WFIFOB(fd,78) = MAX_CHAR_BILLING; //TODO create a config for this
-	WFIFOSET(fd,79);
+	WFIFOB(fd,72) = isvip;
+	WFIFOB(fd,73) = char_vip;
+	WFIFOB(fd,74) = MAX_CHAR_BILLING; //TODO create a config for this
+	WFIFOSET(fd,75);
 	return 1;
 }
 
@@ -720,48 +717,6 @@ int logchrif_parse_pincode_authfail(int fd){
 	return 1;
 }
 
-/**
- * Request the bank info of login
- * @param fd: fd to parse from (char-serv)
- * @param id: char serv id
- * @param ip: char-serv ip (used for info)
- * @return 0 fail (packet does not have enough data), 1 success (continue parsing)
- */
-int logchrif_parse_bankvault(int fd, int id, char* ip){
-	if( RFIFOREST(fd) < 11 )
-		return 0;
-	else {
-		struct mmo_account acc;
-
-
-		uint32 account_id = RFIFOL(fd,2);
-		char type = RFIFOB(fd,6);
-		int32 data = RFIFOL(fd,7);
-		AccountDB* accounts = login_get_accounts_db();
-
-		RFIFOSKIP(fd,11);
-
-		if( !accounts->load_num(accounts, &acc, account_id) )
-			ShowNotice("Char-server '%s': Error on banking  (account: %d not found, ip: %s).\n", ch_server[id].name, account_id, ip);
-		else{
-			unsigned char buf[12];
-			if(type==2){ // upd and Save
-				acc.bank_vault = data;
-				accounts->save(accounts, &acc);
-				WBUFB(buf,10) = 1;
-			} else {
-				WBUFB(buf,10) = 0;
-			}
-			// announce to other servers
-			WBUFW(buf,0) = 0x2741;
-			WBUFL(buf,2) = account_id;
-			WBUFL(buf,6) = acc.bank_vault;
-			logchrif_sendallwos(-1, buf, 11);
-		}
-	}
-	return 1;
-}
-
 /**
  * Received a vip data reqest from char
  * type is the query to perform
@@ -931,7 +886,6 @@ int logchrif_parse(int fd){
 		case 0x2737: next = logchrif_parse_setalloffline(fd,cid); break;
 		case 0x2738: next = logchrif_parse_updpincode(fd); break;
 		case 0x2739: next = logchrif_parse_pincode_authfail(fd); break;
-		case 0x2740: next = logchrif_parse_bankvault(fd,cid,ip); break;
 		case 0x2742: next = logchrif_parse_reqvipdata(fd); break; //Vip sys
 		default:
 			ShowError("logchrif_parse: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);

+ 2 - 27
src/map/chrif.c

@@ -27,7 +27,6 @@
 #include <stdlib.h>
 
 static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data);
-int chrif_save_bankdata(struct map_session_data *sd);
 
 static struct eri *auth_db_ers; //For reutilizing player login structures.
 static DBMap* auth_db; // int id -> struct auth_node*
@@ -39,7 +38,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
 	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
-	-1,10, 6,16, 0, 6,-1,-1,	// 2b28-2b2f: U->2b28, U->2b29, U->2b2a, U->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
+	-1, 0, 6,16, 0, 6,-1,-1,	// 2b28-2b2f: U->2b28, F->2b29, U->2b2a, U->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
  };
 
 //Used Packets:
@@ -92,7 +91,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
 //2b26: Outgoing, chrif_authreq -> 'client authentication request'
 //2b27: Incoming, chrif_authfail -> 'client authentication failed'
 //2b28: Outgoing, chrif_req_charban -> 'ban a specific char '
-//2b29: Incoming, chrif_load_bankdata -> 'received bank data for playeer to be loaded'
+//2b29: FREE
 //2b2a: Outgoing, chrif_req_charunban -> 'unban a specific char '
 //2b2b: Incoming, chrif_parse_ack_vipActive -> vip info result
 //2b2c: FREE
@@ -282,7 +281,6 @@ int chrif_save(struct map_session_data *sd, int flag) {
 		if (chrif_isconnected()) {
 			chrif_save_scdata(sd);
 			chrif_skillcooldown_save(sd);
-			chrif_req_login_operation(sd->status.account_id, sd->status.name, CHRIF_OP_LOGIN_BANK, 0, 2, sd->status.bank_vault); //save Bank data
 		}
 		if ( flag != 3 && !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);
@@ -926,11 +924,6 @@ static void chrif_ack_login_req(int aid, const char* player_name, uint16 type, u
 				return;
 			snprintf(action,25,"%s",msg_txt(sd,436)); //VIP
 			break;
-		case CHRIF_OP_LOGIN_BANK:
-			if (!battle_config.disp_serverbank_msg)
-				return;
-			snprintf(action,25,"%s","bank");
-			break;
 		default:
 			snprintf(action,25,"???");
 			break;
@@ -1281,23 +1274,6 @@ int chrif_updatefamelist_ack(int fd) {
 	return 1;
 }
 
-int chrif_load_bankdata(int fd){
-	struct map_session_data *sd;
-	int aid, bank_vault;
-
-	aid = RFIFOL(fd,2); //Player Account ID
-	bank_vault = RFIFOL(fd,6); //Player money in bank
-
-	sd = map_id2sd(aid);
-
-	if ( !sd ) {
-		ShowError("chrif_load_bankdata: Player of AID %d not found!\n", aid);
-		return -1;
-	}
-	sd->status.bank_vault = bank_vault;
- 	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;
@@ -1819,7 +1795,6 @@ int chrif_parse(int fd) {
 			case 0x2b24: chrif_keepalive_ack(fd); break;
 			case 0x2b25: chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
 			case 0x2b27: chrif_authfail(fd); break;
-			case 0x2b29: chrif_load_bankdata(fd); break;
 			case 0x2b2b: chrif_parse_ack_vipActive(fd); break;
 			case 0x2b2f: chrif_bsdata_received(fd); break;
 			default:

+ 0 - 3
src/map/chrif.h

@@ -27,7 +27,6 @@ enum chrif_req_op {
 	CHRIF_OP_LOGIN_UNBAN,
 	CHRIF_OP_LOGIN_CHANGESEX,
 	CHRIF_OP_LOGIN_VIP,
-	CHRIF_OP_LOGIN_BANK,
 
 	// Char-server operation
 	CHRIF_OP_BAN,
@@ -86,8 +85,6 @@ void chrif_parse_ack_vipActive(int fd);
 int chrif_req_charban(int aid, const char* character_name, int timediff);
 int chrif_req_charunban(int aid, const char* character_name);
 
-int chrif_load_bankdata(int fd);
-
 int chrif_bsdata_request(uint32 char_id);
 int chrif_bsdata_save(struct map_session_data *sd, bool quit);
 

+ 3 - 3
src/map/clif.c

@@ -6526,7 +6526,7 @@ void clif_Bank_Check(struct map_session_data* sd) {
 	// sd->state.banking = 1; //mark opening and closing
 
 	WBUFW(buf,0) = cmd;
-	WBUFQ(buf,info->pos[0]) = sd->status.bank_vault; //testig value
+	WBUFQ(buf,info->pos[0]) = sd->bank_vault; //value
 	WBUFW(buf,info->pos[1]) = 0; //reason
 	clif_send(buf,len,&sd->bl,SELF);
 }
@@ -6570,7 +6570,7 @@ void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK r
 
 	WBUFW(buf,0) = cmd;
 	WBUFW(buf,info->pos[0]) = (short)reason;
-	WBUFQ(buf,info->pos[1]) = sd->status.bank_vault;/* money in the bank */
+	WBUFQ(buf,info->pos[1]) = sd->bank_vault;/* money in the bank */
 	WBUFL(buf,info->pos[2]) = sd->status.zeny;/* how much zeny char has after operation */
 	clif_send(buf,len,&sd->bl,SELF);
 }
@@ -6618,7 +6618,7 @@ void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK
 
 	WBUFW(buf,0) = cmd;
 	WBUFW(buf,info->pos[0]) = (short)reason;
-	WBUFQ(buf,info->pos[1]) = sd->status.bank_vault;/* money in the bank */
+	WBUFQ(buf,info->pos[1]) = sd->bank_vault;/* money in the bank */
 	WBUFL(buf,info->pos[2]) = sd->status.zeny;/* how much zeny char has after operation */
 
 	clif_send(buf,len,&sd->bl,SELF);

+ 1 - 1
src/map/log.c

@@ -74,7 +74,7 @@ static char log_picktype2char(e_log_pick_type type)
 		case LOG_TYPE_BANK:             return 'K';  // Ban(K) Transactions
 		case LOG_TYPE_OTHER:			return 'X';  // Other
 		case LOG_TYPE_CASH:				return '$';  // Cash
-		case LOG_TYPE_BOUND_REMOVAL:	return 'B';  // Removed bound items when guild/party is broken
+		case LOG_TYPE_BOUND_REMOVAL:	return 'F';  // Removed bound items when guild/party is broken
 	}
 
 	// should not get here, fallback

+ 1 - 0
src/map/map.h

@@ -448,6 +448,7 @@ enum _sp {
 	SP_CHARMOVE=124,
 	SP_CHARRENAME=125,
 	SP_CHARFONT=126,
+	SP_BANK_VAULT = 127,
 
 	// Mercenaries
 	SP_MERCFLEE=165, SP_MERCKILLS=189, SP_MERCFAITH=190,

+ 2 - 26
src/map/npc.c

@@ -1671,20 +1671,7 @@ uint8 npc_buylist(struct map_session_data* sd, uint16 n, struct s_npc_buy_list *
 			}
 			break;
 		case NPCTYPE_POINTSHOP:
-			switch(nd->u.shop.pointshop_str[0]) {
-				case '#':
-					if (nd->u.shop.pointshop_str[1] == '#')
-						count = pc_readaccountreg2(sd, nd->u.shop.pointshop_str);
-					else
-						count = pc_readaccountreg(sd, nd->u.shop.pointshop_str);
-					break;
-				case '@':
-					count = pc_readreg(sd, add_str(nd->u.shop.pointshop_str));
-					break;
-				default:
-					count = pc_readglobalreg(sd, nd->u.shop.pointshop_str);
-					break;
-			}
+			count = pc_readreg2(sd, nd->u.shop.pointshop_str);
 			if (z > (double)count) {
 				sprintf(output,msg_txt(sd,713),nd->u.shop.pointshop_str); // You do not have enough '%s'.
 				clif_colormes(sd,color_table[COLOR_RED],output);
@@ -1707,18 +1694,7 @@ uint8 npc_buylist(struct map_session_data* sd, uint16 n, struct s_npc_buy_list *
 			pc_delitem(sd, pc_search_inventory(sd, nd->u.shop.itemshop_nameid), (int)z, 0, 0, LOG_TYPE_NPC);
 			break;
 		case NPCTYPE_POINTSHOP:
-			switch(nd->u.shop.pointshop_str[0]) {
-				case '#':
-					if (nd->u.shop.pointshop_str[1] == '#')
-						pc_setaccountreg2(sd, nd->u.shop.pointshop_str, count - (int)z);
-					else
-						pc_setaccountreg(sd, nd->u.shop.pointshop_str, count - (int)z);
-					break;
-				case '@':
-				default:
-					pc_setglobalreg(sd, nd->u.shop.pointshop_str, count - (int)z);
-					break;
-			}
+			pc_setreg2(sd, nd->u.shop.pointshop_str, count - (int)z);
 			break;
 	}
 

+ 83 - 7
src/map/pc.c

@@ -1341,6 +1341,9 @@ void pc_reg_received(struct map_session_data *sd)
 		sd->mission_count = pc_readglobalreg(sd,"TK_MISSION_COUNT");
 	}
 
+	if (battle_config.feature_banking)
+		sd->bank_vault = pc_readreg2(sd, BANK_VAULT_VAR);
+
 	//SG map and mob read [Komurka]
 	for(i=0;i<MAX_PC_FEELHATE;i++) { //for now - someone need to make reading from txt/sql
 		uint16 j;
@@ -1410,8 +1413,6 @@ void pc_reg_received(struct map_session_data *sd)
 	chrif_skillcooldown_request(sd->status.account_id, sd->status.char_id);
 	chrif_bsdata_request(sd->status.char_id);
 	sd->storage_size = MIN_STORAGE; //default to min
-	if(battle_config.feature_banking)
-		chrif_req_login_operation(sd->status.account_id, sd->status.name, CHRIF_OP_LOGIN_BANK, 0, 1, 0); //request Bank data
 #ifdef VIP_ENABLE
 	sd->vip.time = 0;
 	sd->vip.enabled = 0;
@@ -7625,6 +7626,7 @@ int pc_readparam(struct map_session_data* sd,int type)
 		case SP_CHARMOVE:		 val = sd->status.character_moves; break;
 		case SP_CHARRENAME:		 val = sd->status.rename; break;
 		case SP_CHARFONT:		 val = sd->status.font; break;
+		case SP_BANK_VAULT:			 val = sd->bank_vault; break;
 		case SP_CRITICAL:        val = sd->battle_status.cri/10; break;
 		case SP_ASPD:            val = (2000-sd->battle_status.amotion)/10; break;
 		case SP_BASE_ATK:	     val = sd->battle_status.batk; break;
@@ -7876,6 +7878,13 @@ bool pc_setparam(struct map_session_data *sd,int type,int val)
 		sd->status.font = val;
 		clif_font(sd);
 		return true;
+	case SP_BANK_VAULT:
+		if (val < 0)
+			return false;
+		log_zeny(sd, LOG_TYPE_BANK, sd, -(sd->bank_vault - cap_value(val, 0, MAX_BANK_ZENY)));
+		sd->bank_vault = cap_value(val, 0, MAX_BANK_ZENY);
+		pc_setreg2(sd, BANK_VAULT_VAR, sd->bank_vault);
+		return true;
 	default:
 		ShowError("pc_setparam: Attempted to set unknown parameter '%d'.\n", type);
 		return false;
@@ -8869,6 +8878,71 @@ bool pc_setregistry_str(struct map_session_data *sd,const char *reg,const char *
 	return false;
 }
 
+/**
+ * Set value of player variable
+ * @param sd Player
+ * @param reg Variable name
+ * @param value
+ * @return True if success, false if failed.
+ **/
+bool pc_setreg2(struct map_session_data *sd, const char *reg, int val) {
+	char prefix = reg[0];
+
+	nullpo_retr(false, sd);
+
+	if (reg[strlen(reg)-1] == '$') {
+		ShowError("pc_setreg2: Invalid variable scope '%s'\n", reg);
+		return false;
+	}
+
+	val = cap_value(val, 0, INT_MAX);
+
+	switch (prefix) {
+		case '.':
+		case '\'':
+		case '$':
+			ShowError("pc_setreg2: Invalid variable scope '%s'\n", reg);
+			return false;
+		case '@':
+			return pc_setreg(sd, add_str(reg), val);
+		case '#':
+			return (reg[1] == '#') ? pc_setaccountreg2(sd, reg, val) : pc_setaccountreg(sd, reg, val);
+	}
+
+	return false;
+}
+
+/**
+ * Get value of player variable
+ * @param sd Player
+ * @param reg Variable name
+ * @return Variable value or 0 if failed.
+ **/
+int pc_readreg2(struct map_session_data *sd, const char *reg) {
+	char prefix = reg[0];
+
+	nullpo_ret(sd);
+
+	if (reg[strlen(reg)-1] == '$') {
+		ShowError("pc_readreg2: Invalid variable scope '%s'\n", reg);
+		return 0;
+	}
+
+	switch (prefix) {
+		case '.':
+		case '\'':
+		case '$':
+			ShowError("pc_readreg2: Invalid variable scope '%s'\n", reg);
+			return 0;
+		case '@':
+			return pc_readreg(sd, add_str(reg));
+		case '#':
+			return (reg[1] == '#') ? pc_readaccountreg2(sd, reg) : pc_readaccountreg(sd, reg);
+	}
+
+	return 0;
+}
+
 /*==========================================
  * Exec eventtimer for player sd (retrieved from map_session (id))
  *------------------------------------------*/
@@ -11028,7 +11102,7 @@ void pc_expire_check(struct map_session_data *sd) {
 * @param money Amount of money to deposit
 **/
 enum e_BANKING_DEPOSIT_ACK pc_bank_deposit(struct map_session_data *sd, int money) {
-	unsigned int limit_check = money+sd->status.bank_vault;
+	unsigned int limit_check = money + sd->bank_vault;
 
 	if( money <= 0 || limit_check > MAX_BANK_ZENY ) {
 		return BDA_OVERFLOW;
@@ -11039,7 +11113,8 @@ enum e_BANKING_DEPOSIT_ACK pc_bank_deposit(struct map_session_data *sd, int mone
 	if( pc_payzeny(sd,money, LOG_TYPE_BANK, NULL) )
 		return BDA_NO_MONEY;
 
-	sd->status.bank_vault += money;
+	sd->bank_vault += money;
+	pc_setreg2(sd, BANK_VAULT_VAR, sd->bank_vault);
 	if( save_settings&CHARSAVE_BANK )
 		chrif_save(sd,0);
 	return BDA_SUCCESS;
@@ -11051,11 +11126,11 @@ enum e_BANKING_DEPOSIT_ACK pc_bank_deposit(struct map_session_data *sd, int mone
 * @param money Amount of money that will be withdrawn
 **/
 enum e_BANKING_WITHDRAW_ACK pc_bank_withdraw(struct map_session_data *sd, int money) {
-	unsigned int limit_check = money+sd->status.zeny;
+	unsigned int limit_check = money + sd->status.zeny;
 	
 	if( money <= 0 ) {
 		return BWA_UNKNOWN_ERROR;
-	} else if ( money > sd->status.bank_vault ) {
+	} else if ( money > sd->bank_vault ) {
 		return BWA_NO_MONEY;
 	} else if ( limit_check > MAX_ZENY ) {
 		/* no official response for this scenario exists. */
@@ -11066,7 +11141,8 @@ enum e_BANKING_WITHDRAW_ACK pc_bank_withdraw(struct map_session_data *sd, int mo
 	if( pc_getzeny(sd,money, LOG_TYPE_BANK, NULL) )
 		return BWA_NO_MONEY;
 	
-	sd->status.bank_vault -= money;
+	sd->bank_vault -= money;
+	pc_setreg2(sd, BANK_VAULT_VAR, sd->bank_vault);
 	if( save_settings&CHARSAVE_BANK )
 		chrif_save(sd,0);
 	return BWA_SUCCESS;

+ 7 - 0
src/map/pc.h

@@ -29,6 +29,8 @@
 #define MAX_SPIRITBALL 15 /// Max spirit balls
 #define MAX_DEVOTION 5 /// Max Devotion slots
 
+#define BANK_VAULT_VAR "#BANKVAULT"
+
 //Update this max as necessary. 55 is the value needed for Super Baby currently
 //Raised to 84 since Expanded Super Novice needs it.
 #define MAX_SKILL_TREE 84
@@ -627,6 +629,8 @@ struct map_session_data {
 	short last_addeditem_index; /// Index of latest item added
 	int autotrade_tid;
 
+	int bank_vault; ///< Bank Vault
+
 #ifdef PACKET_OBFUSCATION
 	unsigned int cryptKey; ///< Packet obfuscation key to be used for the next received packet
 #endif
@@ -1023,6 +1027,9 @@ bool pc_setregistry(struct map_session_data*,const char*,int,int);
 char *pc_readregistry_str(struct map_session_data*,const char*,int);
 bool pc_setregistry_str(struct map_session_data*,const char*,const char*,int);
 
+bool pc_setreg2(struct map_session_data *sd, const char *reg, int val);
+int pc_readreg2(struct map_session_data *sd, const char *reg);
+
 bool pc_addeventtimer(struct map_session_data *sd,int tick,const char *name);
 bool pc_deleventtimer(struct map_session_data *sd,const char *name);
 void pc_cleareventtimer(struct map_session_data *sd);