Adding banking support

This commit is contained in:
lighta 2013-11-05 13:41:42 -05:00
parent cd3cb9fa95
commit 1290826be2
25 changed files with 644 additions and 97 deletions

View File

@ -18,3 +18,7 @@ feature.search_stores: on
// Atcommand suggestions (Note 1) // Atcommand suggestions (Note 1)
// If one type incomplete atcommand, it will suggest the complete ones. // If one type incomplete atcommand, it will suggest the complete ones.
feature.atcommand_suggestions: off feature.atcommand_suggestions: off
// Banking (Note 1)
// Requires: 2013-07-24aRagexe or later
feature.banking: on

View File

@ -103,6 +103,7 @@ mercenary_db: mercenary
mercenary_owner_db: mercenary_owner mercenary_owner_db: mercenary_owner
elemental_db: elemental elemental_db: elemental
ragsrvinfo_db: ragsrvinfo ragsrvinfo_db: ragsrvinfo
skillcooldown_db: skillcooldown
// Map Database Tables // Map Database Tables
item_db_db: item_db item_db_db: item_db

View File

@ -28,6 +28,7 @@
// 0x10000 - (X) Log all other transactions (rentals expiring/inserting cards/items removed by item_check/ // 0x10000 - (X) Log all other transactions (rentals expiring/inserting cards/items removed by item_check/
// rings deleted by divorce/pet egg (un)hatching/pet armor (un)equipping/Weapon Refine skill/Remove Trap skill) // rings deleted by divorce/pet egg (un)hatching/pet armor (un)equipping/Weapon Refine skill/Remove Trap skill)
// 0x20000 - ($) Log cash transactions // 0x20000 - ($) Log cash transactions
// 0x40000 - (K) Log account bank transactions
// Example: Log trades+vending+script items+created items: 1+2+32+1024 = 1059 // 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. // Please note that moving items from inventory to cart and back is not logged by design.
enable_logs: 0xFFFFF enable_logs: 0xFFFFF

View File

@ -101,11 +101,12 @@ minsave_time: 100
// 16: After successfully sending a mail with attachment // 16: After successfully sending a mail with attachment
// 32: After successfully submitting an item for auction // 32: After successfully submitting an item for auction
// 64: After successfully get/delete/complete a quest // 64: After successfully get/delete/complete a quest
// 128: After every bank transaction (deposit/withdraw)
// NOTE: These settings decrease the chance of dupes/lost items when there's a // NOTE: These settings decrease the chance of dupes/lost items when there's a
// server crash at the expense of increasing the map/char server lag. If your // server crash at the expense of increasing the map/char server lag. If your
// server rarely crashes, but experiences interserver lag, you may want to set // server rarely crashes, but experiences interserver lag, you may want to set
// these off. // these off.
save_settings: 127 save_settings: 255
// Message of the day file, when a character logs on, this message is displayed. // Message of the day file, when a character logs on, this message is displayed.
motd_txt: conf/motd.txt motd_txt: conf/motd.txt

View File

@ -1493,5 +1493,9 @@
1490: Item types on your autoloottype list: 1490: Item types on your autoloottype list:
1491: Your autoloottype list has been reset. 1491: Your autoloottype list has been reset.
//Banking
1492: You can't withdraw that much money
1493: Banking is disabled
//Custom translations //Custom translations
//import: conf/msg_conf/import/map_msg_eng_conf.txt //import: conf/msg_conf/import/map_msg_eng_conf.txt

View File

@ -2190,3 +2190,45 @@ packet_ver: 44
0x0863,26,friendslistadd,2 0x0863,26,friendslistadd,2
0x088A,5,hommenu,2:4 0x088A,5,hommenu,2:4
0x095B,36,storagepassword,2:4:20 0x095B,36,storagepassword,2:4:20
0x09A6,12,ZC_BANKING_CHECK,2:10
0x09A7,10,bankdeposit,2:6
0x09A8,16,ZC_ACK_BANKING_DEPOSIT,2:4:12
0x09A9,10,bankwithdrawal,2:6
0x09AA,16,ZC_ACK_BANKING_WITHDRAW,2:4:12
0x09AB,6,bankcheck,2
0x09B6,6,bankopen,2
0x09B7,4,ZC_ACK_OPEN_BANKING,2
0x09B8,6,bankclose,2
0x09B9,4,ZC_ACK_CLOSE_BANKING,2
//2013-08-07Ragexe (Shakto)
packet_ver: 45
0x0369,7,actionrequest,2:6
0x083C,10,useskilltoid,2:4:6
0x0437,5,walktoxy,2
0x035F,6,ticksend,2
0x0202,5,changedir,2:4
0x07E4,6,takeitem,2
0x0362,6,dropitem,2:4
0x07EC,8,movetokafra,2:4
0x0364,8,movefromkafra,2:4
0x0438,10,useskilltopos,2:4:6:8
0x0366,90,useskilltoposinfo,2:4:6:8:10
0x096A,6,getcharnamerequest,2
0x0368,6,solvecharname,2
0x0838,12,searchstoreinfolistitemclick,2:6:10
0x0835,2,searchstoreinfonextpage,0
0x0819,-1,searchstoreinfo,2:4:5:9:13:14:15
0x0811,-1,reqtradebuyingstore,2:4:8:12
0x0360,6,reqclickbuyingstore,2
0x0817,2,reqclosebuyingstore,0
0x0815,-1,reqopenbuyingstore,2:4:8:9:89
0x0365,18,bookingregreq,2:4:6
// 0x363,8 CZ_JOIN_BATTLE_FIELD
0x0281,-1,itemlistwindowselected,2:4:8:12
0x022D,19,wanttoconnection,2:6:10:14:18
0x0802,26,partyinvite2,2
// 0x436,4 CZ_GANGSI_RANK
0x023B,26,friendslistadd,2
0x0361,5,hommenu,2:4
0x0887,36,storagepassword,2:4:20

View File

@ -459,6 +459,7 @@ CREATE TABLE IF NOT EXISTS `login` (
`character_slots` tinyint(3) unsigned NOT NULL default '0', `character_slots` tinyint(3) unsigned NOT NULL default '0',
`pincode` varchar(4) NOT NULL DEFAULT '', `pincode` varchar(4) NOT NULL DEFAULT '',
`pincode_change` int(11) unsigned NOT NULL DEFAULT '0', `pincode_change` int(11) unsigned NOT NULL DEFAULT '0',
`bank_vault` BIGINT(64) NOT NULL DEFAULT '0',
PRIMARY KEY (`account_id`), PRIMARY KEY (`account_id`),
KEY `name` (`userid`) KEY `name` (`userid`)
) ENGINE=MyISAM AUTO_INCREMENT=2000000; ) ENGINE=MyISAM AUTO_INCREMENT=2000000;

View File

@ -0,0 +1 @@
ALTER TABLE `login` ADD `bank_vault` BIGINT( 64 ) NOT NULL DEFAULT '0';

View File

@ -143,6 +143,7 @@ struct char_session_data {
time_t pincode_change; time_t pincode_change;
uint16 pincode_try; uint16 pincode_try;
// Addon system // Addon system
int bank_vault;
unsigned int char_moves[MAX_CHARS]; // character moves left unsigned int char_moves[MAX_CHARS]; // character moves left
}; };
@ -189,6 +190,12 @@ bool char_moves_unlimited = false;
void moveCharSlot( int fd, struct char_session_data* sd, unsigned short from, unsigned short to ); void moveCharSlot( int fd, struct char_session_data* sd, unsigned short from, unsigned short to );
void moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short index, short reason ); void moveCharSlotReply( int fd, struct char_session_data* sd, unsigned short index, short reason );
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] //Custom limits for the fame lists. [Skotlex]
int fame_list_size_chemist = MAX_FAME_LIST; int fame_list_size_chemist = MAX_FAME_LIST;
int fame_list_size_smith = MAX_FAME_LIST; int fame_list_size_smith = MAX_FAME_LIST;
@ -2146,6 +2153,83 @@ static void char_auth_ok(int fd, struct char_session_data *sd)
int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data); int send_accounts_tologin(int tid, unsigned int tick, int id, intptr_t data);
void mapif_server_reset(int id); void mapif_server_reset(int id);
/*
* HA 0x2740<aid>L <type>B <data>L
* type:
* 0 = select
* 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;
}
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 loginif_parse_BankingAck(int fd){
if (RFIFOREST(fd) < 11)
return 0;
uint32 aid = RFIFOL(fd,2);
int32 bank_vault = RFIFOL(fd,6);
char not_fw = RFIFOB(fd,10);
RFIFOSKIP(fd,11);
if(!not_fw) mapif_BankingAck(aid, bank_vault);
return 1;
}
//HZ 0x2b29 <aid>L <bank_vault>L
int mapif_BankingAck(int32 account_id, int32 bank_vault){
unsigned char buf[14];
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;
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;
uint32 aid = RFIFOL(fd,2);
RFIFOSKIP(fd,6);
loginif_BankingReq(aid, 1, 0);
return 1;
}
/// Resets all the data. /// Resets all the data.
void loginif_reset(void) void loginif_reset(void)
@ -2230,6 +2314,7 @@ int parse_fromlogin(int fd) {
switch( command ) switch( command )
{ {
case 0x2741: loginif_parse_BankingAck(fd); break;
// acknowledgement of connect-to-loginserver request // acknowledgement of connect-to-loginserver request
case 0x2711: case 0x2711:
@ -2289,7 +2374,7 @@ int parse_fromlogin(int fd) {
break; break;
case 0x2717: // account data case 0x2717: // account data
if (RFIFOREST(fd) < 72) if (RFIFOREST(fd) < 76)
return 0; return 0;
// find the authenticated session with this account id // find the authenticated session with this account id
@ -2309,6 +2394,7 @@ int parse_fromlogin(int fd) {
safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate)); safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate));
safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode)); safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode));
sd->pincode_change = (time_t)RFIFOL(fd,68); sd->pincode_change = (time_t)RFIFOL(fd,68);
sd->bank_vault = RFIFOL(fd,72);
ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] ); ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] );
// continued from char_auth_ok... // continued from char_auth_ok...
if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359 if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359
@ -2355,7 +2441,7 @@ int parse_fromlogin(int fd) {
#endif #endif
} }
} }
RFIFOSKIP(fd,72); RFIFOSKIP(fd,76);
break; break;
// login-server alive packet // login-server alive packet
@ -3580,6 +3666,9 @@ int parse_frommap(int fd)
} }
break; break;
case 0x2b28: mapif_parse_UpdBankInfo(fd); break;
case 0x2b2a: mapif_parse_ReqBankInfo(fd); break;
default: default:
{ {
// inter server - packet // inter server - packet

View File

@ -47,7 +47,7 @@
// 20120307 - 2012-03-07aRagexeRE+ - 0x970 // 20120307 - 2012-03-07aRagexeRE+ - 0x970
#ifndef PACKETVER #ifndef PACKETVER
#define PACKETVER 20120410 #define PACKETVER 20130724
//#define PACKETVER 20130320 //#define PACKETVER 20130320
//#define PACKETVER 20111116 //#define PACKETVER 20111116
#endif #endif
@ -79,6 +79,7 @@
//Max amount of a single stacked item //Max amount of a single stacked item
#define MAX_AMOUNT 30000 #define MAX_AMOUNT 30000
#define MAX_ZENY 1000000000 #define MAX_ZENY 1000000000
#define MAX_BANK_ZENY SINT32_MAX
#define MAX_FAME 1000000000 #define MAX_FAME 1000000000
#define MAX_CART 100 #define MAX_CART 100
#define MAX_SKILL 5020 #define MAX_SKILL 5020
@ -351,6 +352,7 @@ struct mmo_charstatus {
unsigned int base_exp,job_exp; unsigned int base_exp,job_exp;
int zeny; int zeny;
int bank_vault;
short class_; short class_;
unsigned int status_point,skill_point; unsigned int status_point,skill_point;

View File

@ -53,6 +53,7 @@ struct mmo_account
char pincode[PINCODE_LENGTH+1]; // pincode system char pincode[PINCODE_LENGTH+1]; // pincode system
time_t pincode_change; // (timestamp): last time of pincode change time_t pincode_change; // (timestamp): last time of pincode change
int account_reg2_num; int account_reg2_num;
int bank_vault;
struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server) struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
}; };

View File

@ -522,7 +522,7 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
// retrieve login entry for the specified account // retrieve login entry for the specified account
if( SQL_ERROR == Sql_Query(sql_handle, if( SQL_ERROR == Sql_Query(sql_handle,
"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", "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",
db->account_db, account_id ) db->account_db, account_id )
) { ) {
Sql_ShowDebug(sql_handle); Sql_ShowDebug(sql_handle);
@ -551,6 +551,7 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
Sql_GetData(sql_handle, 13, &data, NULL); acc->char_slots = atoi(data); 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, 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, 15, &data, NULL); acc->pincode_change = atol(data);
Sql_GetData(sql_handle, 16, &data, NULL); acc->bank_vault = atoi(data);
Sql_FreeResult(sql_handle); Sql_FreeResult(sql_handle);
@ -599,24 +600,25 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
if( is_new ) if( is_new )
{// insert into account table {// insert into account table
if( SQL_SUCCESS != SqlStmt_Prepare(stmt, if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
"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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", "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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
db->account_db) db->account_db)
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_INT, (void*)&acc->account_id, sizeof(acc->account_id)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_INT, (void*)&acc->account_id, sizeof(acc->account_id))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_STRING, (void*)&acc->email, strlen(acc->email)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_STRING, (void*)&acc->email, strlen(acc->email))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_INT, (void*)&acc->expiration_time, sizeof(acc->expiration_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_INT, (void*)&acc->expiration_time, sizeof(acc->expiration_time))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_UCHAR, (void*)&acc->char_slots, sizeof(acc->char_slots)) || 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, 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, 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))
|| SQL_SUCCESS != SqlStmt_Execute(stmt) || SQL_SUCCESS != SqlStmt_Execute(stmt)
) { ) {
SqlStmt_ShowDebug(stmt); SqlStmt_ShowDebug(stmt);
@ -625,22 +627,23 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
} }
else else
{// update account table {// update account table
if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "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'", db->account_db, acc->account_id) if( SQL_SUCCESS != SqlStmt_Prepare(stmt, "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'", db->account_db, acc->account_id)
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 0, SQLDT_STRING, (void*)acc->userid, strlen(acc->userid))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 1, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, (void*)acc->email, strlen(acc->email)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 3, SQLDT_STRING, (void*)acc->email, strlen(acc->email))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 4, SQLDT_INT, (void*)&acc->group_id, sizeof(acc->group_id))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 5, SQLDT_UINT, (void*)&acc->state, sizeof(acc->state))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 6, SQLDT_LONG, (void*)&acc->unban_time, sizeof(acc->unban_time))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void*)&acc->expiration_time, sizeof(acc->expiration_time)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 7, SQLDT_LONG, (void*)&acc->expiration_time, sizeof(acc->expiration_time))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 8, SQLDT_UINT, (void*)&acc->logincount, sizeof(acc->logincount))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 9, SQLDT_STRING, (void*)&acc->lastlogin, strlen(acc->lastlogin))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 10, SQLDT_STRING, (void*)&acc->last_ip, strlen(acc->last_ip))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate)) || SQL_SUCCESS != SqlStmt_BindParam(stmt, 11, SQLDT_STRING, (void*)&acc->birthdate, strlen(acc->birthdate))
|| SQL_SUCCESS != SqlStmt_BindParam(stmt, 12, SQLDT_UCHAR, (void*)&acc->char_slots, sizeof(acc->char_slots)) || 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, 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, 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))
|| SQL_SUCCESS != SqlStmt_Execute(stmt) || SQL_SUCCESS != SqlStmt_Execute(stmt)
) { ) {
SqlStmt_ShowDebug(stmt); SqlStmt_ShowDebug(stmt);

View File

@ -567,6 +567,7 @@ int parse_fromchar(int fd){
char birthdate[10+1] = ""; char birthdate[10+1] = "";
char pincode[PINCODE_LENGTH+1]; char pincode[PINCODE_LENGTH+1];
int account_id = RFIFOL(fd,2); int account_id = RFIFOL(fd,2);
int bank_vault = 0;
memset(pincode,0,PINCODE_LENGTH+1); memset(pincode,0,PINCODE_LENGTH+1);
@ -581,9 +582,10 @@ int parse_fromchar(int fd){
char_slots = acc.char_slots; char_slots = acc.char_slots;
safestrncpy(birthdate, acc.birthdate, sizeof(birthdate)); safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
safestrncpy(pincode, acc.pincode, sizeof(pincode)); safestrncpy(pincode, acc.pincode, sizeof(pincode));
bank_vault = acc.bank_vault;
} }
WFIFOHEAD(fd,72); WFIFOHEAD(fd,76);
WFIFOW(fd,0) = 0x2717; WFIFOW(fd,0) = 0x2717;
WFIFOL(fd,2) = account_id; WFIFOL(fd,2) = account_id;
safestrncpy((char*)WFIFOP(fd,6), email, 40); safestrncpy((char*)WFIFOP(fd,6), email, 40);
@ -593,7 +595,8 @@ int parse_fromchar(int fd){
safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1); safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 ); safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
WFIFOL(fd,68) = (uint32)acc.pincode_change; WFIFOL(fd,68) = (uint32)acc.pincode_change;
WFIFOSET(fd,72); WFIFOL(fd,72) = bank_vault;
WFIFOSET(fd,76);
} }
break; break;
@ -907,13 +910,11 @@ int parse_fromchar(int fd){
return 0; return 0;
else{ else{
struct mmo_account acc; struct mmo_account acc;
if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ){ if( accounts->load_num(accounts, &acc, RFIFOL(fd,2) ) ){
strncpy( acc.pincode, (char*)RFIFOP(fd,6), 5 ); strncpy( acc.pincode, (char*)RFIFOP(fd,6), 5 );
acc.pincode_change = time( NULL ); acc.pincode_change = time( NULL );
accounts->save(accounts, &acc); accounts->save(accounts, &acc);
} }
RFIFOSKIP(fd,11); RFIFOSKIP(fd,11);
} }
break; break;
@ -941,6 +942,35 @@ int parse_fromchar(int fd){
} }
break; break;
case 0x2740: // req upd bank_vault
if( RFIFOREST(fd) < 11 )
return 0;
else{
struct mmo_account acc;
int account_id = RFIFOL(fd,2);
char type = RFIFOB(fd,6);
int32 data = RFIFOL(fd,7);
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", server[id].name, account_id, ip);
else{
unsigned char buf[11];
if(type==2){ // upd and Save
acc.bank_vault = data;
accounts->save(accounts, &acc);
WBUFB(buf,10) = 1;
}
// announce to other servers
WBUFW(buf,0) = 0x2741;
WBUFL(buf,2) = account_id;
WBUFL(buf,6) = acc.bank_vault;
charif_sendallwos(-1, buf, 11);
}
}
break;
default: default:
ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command); ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);
set_eof(fd); set_eof(fd);
@ -996,6 +1026,7 @@ int mmo_auth_new(const char* userid, const char* pass, const char sex, const cha
acc.pincode_change = 0; acc.pincode_change = 0;
acc.char_slots = 0; acc.char_slots = 0;
acc.bank_vault = 0;
if( !accounts->create(accounts, &acc) ) if( !accounts->create(accounts, &acc) )
return 0; return 0;

View File

@ -7138,6 +7138,7 @@ static const struct _battle_data {
{ "item_flooritem_check", &battle_config.item_onfloor, 1, 0, 1, }, { "item_flooritem_check", &battle_config.item_onfloor, 1, 0, 1, },
{ "bowling_bash_area", &battle_config.bowling_bash_area, 0, 0, 20, }, { "bowling_bash_area", &battle_config.bowling_bash_area, 0, 0, 20, },
{ "drop_rateincrease", &battle_config.drop_rateincrease, 0, 0, 1, }, { "drop_rateincrease", &battle_config.drop_rateincrease, 0, 0, 1, },
{ "feature.banking", &battle_config.feature_banking, 1, 0, 1, },
}; };
#ifndef STATS_OPT_OUT #ifndef STATS_OPT_OUT
/** /**
@ -7352,6 +7353,13 @@ void battle_adjust_conf()
} }
#endif #endif
#if PACKETVER < 20130724
if( battle_config.feature_banking ) {
ShowWarning("conf/battle/feature.conf banking is enabled but it requires PACKETVER 2013-07-24 or newer, disabling...\n");
battle_config.feature_banking = 0;
}
#endif
#ifndef CELL_NOSTACK #ifndef CELL_NOSTACK
if (battle_config.cell_stack_limit != 1) if (battle_config.cell_stack_limit != 1)
ShowWarning("Battle setting 'cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n"); ShowWarning("Battle setting 'cell_stack_limit' takes no effect as this server was compiled without Cell Stack Limit support.\n");

View File

@ -494,6 +494,7 @@ extern struct Battle_Config
int item_onfloor; // Whether to drop an undroppable item on the map or destroy it if inventory is full. int item_onfloor; // Whether to drop an undroppable item on the map or destroy it if inventory is full.
int bowling_bash_area; int bowling_bash_area;
int drop_rateincrease; int drop_rateincrease;
int feature_banking;
} battle_config; } battle_config;

View File

@ -101,6 +101,7 @@ int channel_delete(struct Channel *channel) {
} }
default: default:
strdb_remove(channel_db, channel->name); strdb_remove(channel_db, channel->name);
aFree(channel);
break; break;
} }
return 0; return 0;

View File

@ -34,6 +34,7 @@
#include <time.h> #include <time.h>
static int check_connect_char_server(int tid, unsigned int tick, int id, intptr_t data); 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 struct eri *auth_db_ers; //For reutilizing player login structures.
static DBMap* auth_db; // int id -> struct auth_node* static DBMap* auth_db; // int id -> struct auth_node*
@ -45,7 +46,8 @@ 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 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 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, 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, 0, 0, 0, 0, 0, // 2b28-2b2f: U->2b28, U->2b29, U->2b2a, F->2b2b, F->2b2c, F->2b2d, F->2b2e, F->2b2f
};
//Used Packets: //Used Packets:
//2af8: Outgoing, chrif_connect -> 'connect to charserver / auth @ charserver' //2af8: Outgoing, chrif_connect -> 'connect to charserver / auth @ charserver'
@ -66,8 +68,8 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b07: Outgoing, chrif_removefriend -> 'Tell charserver to remove friend_id from char_id friend list' //2b07: Outgoing, chrif_removefriend -> 'Tell charserver to remove friend_id from char_id friend list'
//2b08: Outgoing, chrif_searchcharid -> '...' //2b08: Outgoing, chrif_searchcharid -> '...'
//2b09: Incoming, map_addchariddb -> 'Adds a name to the nick db' //2b09: Incoming, map_addchariddb -> 'Adds a name to the nick db'
//2b0a: FREE //2b0a: Outgoing, chrif_skillcooldown_request -> requesting the list of skillcooldown for char
//2b0b: FREE //2b0b: Incoming, chrif_skillcooldown_load -> received the list of cooldown for char
//2b0c: Outgoing, chrif_changeemail -> 'change mail address ...' //2b0c: Outgoing, chrif_changeemail -> 'change mail address ...'
//2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY' //2b0d: Incoming, chrif_changedsex -> 'Change sex of acc XY'
//2b0e: Outgoing, chrif_char_ask_name -> 'Do some operations (change sex, ban / unban etc)' //2b0e: Outgoing, chrif_char_ask_name -> 'Do some operations (change sex, ban / unban etc)'
@ -77,7 +79,7 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b12: Incoming, chrif_divorceack -> 'divorce chars //2b12: Incoming, chrif_divorceack -> 'divorce chars
//2b13: FREE //2b13: FREE
//2b14: Incoming, chrif_accountban -> 'not sure: kick the player with message XY' //2b14: Incoming, chrif_accountban -> 'not sure: kick the player with message XY'
//2b15: FREE //2b15: Outgoing, chrif_skillcooldown_save -> request to save skillcooldown
//2b16: Outgoing, chrif_ragsrvinfo -> 'sends base / job / drop rates ....' //2b16: Outgoing, chrif_ragsrvinfo -> 'sends base / job / drop rates ....'
//2b17: Outgoing, chrif_char_offline -> 'tell the charserver that the char is now offline' //2b17: Outgoing, chrif_char_offline -> 'tell the charserver that the char is now offline'
//2b18: Outgoing, chrif_char_reset_offline -> 'set all players OFF!' //2b18: Outgoing, chrif_char_reset_offline -> 'set all players OFF!'
@ -96,6 +98,9 @@ static const int packet_len_table[0x3d] = { // U - used, F - free
//2b25: Incoming, chrif_deadopt -> 'Removes baby from Father ID and Mother ID' //2b25: Incoming, chrif_deadopt -> 'Removes baby from Father ID and Mother ID'
//2b26: Outgoing, chrif_authreq -> 'client authentication request' //2b26: Outgoing, chrif_authreq -> 'client authentication request'
//2b27: Incoming, chrif_authfail -> 'client authentication failed' //2b27: Incoming, chrif_authfail -> 'client authentication failed'
//2b28: Outgoing, chrif_save_bankdata -> 'send bank data to be saved'
//2b29: Incoming, chrif_load_bankdata -> 'received bank data for playeer to be loaded'
//2b2a: Outgoing, chrif_bankdata_request -> 'request bank data for charid'
int chrif_connected = 0; int chrif_connected = 0;
int char_fd = -1; int char_fd = -1;
@ -275,10 +280,11 @@ int chrif_save(struct map_session_data *sd, int flag) {
if (flag && sd->state.active) { //Store player data which is quitting if (flag && sd->state.active) { //Store player data which is quitting
//FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex] //FIXME: SC are lost if there's no connection at save-time because of the way its related data is cleared immediately after this function. [Skotlex]
if (chrif_isconnected()) { if (chrif_isconnected()) {
chrif_save_scdata(sd); chrif_save_scdata(sd);
chrif_skillcooldown_save(sd); chrif_skillcooldown_save(sd);
} chrif_save_bankdata(sd);
}
if ( !chrif_auth_logout(sd,flag == 1 ? ST_LOGOUT : ST_MAPCHANGE) ) 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); ShowError("chrif_save: Failed to set up player %d:%d for proper quitting!\n", sd->status.account_id, sd->status.char_id);
} }
@ -577,20 +583,20 @@ int chrif_scdata_request(int account_id, int char_id) {
WFIFOL(char_fd,6) = char_id; WFIFOL(char_fd,6) = char_id;
WFIFOSET(char_fd,10); WFIFOSET(char_fd,10);
#endif #endif
return 0; return 0;
} }
/*========================================== /*==========================================
* Request skillcooldown from charserver * Request skillcooldown from charserver
*------------------------------------------*/ *------------------------------------------*/
int chrif_skillcooldown_request(int account_id, int char_id) { int chrif_skillcooldown_request(int account_id, int char_id) {
chrif_check(-1); chrif_check(-1);
WFIFOHEAD(char_fd, 10); WFIFOHEAD(char_fd, 10);
WFIFOW(char_fd, 0) = 0x2b0a; WFIFOW(char_fd, 0) = 0x2b0a;
WFIFOL(char_fd, 2) = account_id; WFIFOL(char_fd, 2) = account_id;
WFIFOL(char_fd, 6) = char_id; WFIFOL(char_fd, 6) = char_id;
WFIFOSET(char_fd, 10); WFIFOSET(char_fd, 10);
return 0; return 0;
} }
/*========================================== /*==========================================
@ -1184,6 +1190,45 @@ int chrif_updatefamelist_ack(int fd) {
return 1; 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;
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_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] 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 #ifdef ENABLE_SC_SAVING
@ -1228,7 +1273,7 @@ int chrif_save_scdata(struct map_session_data *sd) { //parses the sc_data of the
WFIFOW(char_fd,2) = 14 +count*sizeof(struct status_change_data); //Total packet size WFIFOW(char_fd,2) = 14 +count*sizeof(struct status_change_data); //Total packet size
WFIFOSET(char_fd,WFIFOW(char_fd,2)); WFIFOSET(char_fd,WFIFOW(char_fd,2));
#endif #endif
return 0; return 0;
} }
int chrif_skillcooldown_save(struct map_session_data *sd) { int chrif_skillcooldown_save(struct map_session_data *sd) {
@ -1300,35 +1345,35 @@ int chrif_load_scdata(int fd) {
status_change_start(NULL,&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 1|2|4|8); status_change_start(NULL,&sd->bl, (sc_type)data->type, 10000, data->val1, data->val2, data->val3, data->val4, data->tick, 1|2|4|8);
} }
#endif #endif
return 0; return 0;
} }
//Retrieve and load skillcooldown for a player //Retrieve and load skillcooldown for a player
int chrif_skillcooldown_load(int fd) { int chrif_skillcooldown_load(int fd) {
struct map_session_data *sd; struct map_session_data *sd;
struct skill_cooldown_data *data; struct skill_cooldown_data *data;
int aid, cid, i, count; int aid, cid, i, count;
aid = RFIFOL(fd, 4); aid = RFIFOL(fd, 4);
cid = RFIFOL(fd, 8); cid = RFIFOL(fd, 8);
sd = map_id2sd(aid); sd = map_id2sd(aid);
if (!sd) { if (!sd) {
ShowError("chrif_skillcooldown_load: Player of AID %d not found!\n", aid); ShowError("chrif_skillcooldown_load: Player of AID %d not found!\n", aid);
return -1; return -1;
} }
if (sd->status.char_id != cid) { if (sd->status.char_id != cid) {
ShowError("chrif_skillcooldown_load: Receiving data for account %d, char id does not matches (%d != %d)!\n", aid, sd->status.char_id, cid); ShowError("chrif_skillcooldown_load: Receiving data for account %d, char id does not matches (%d != %d)!\n", aid, sd->status.char_id, cid);
return -1; return -1;
} }
count = RFIFOW(fd, 12); //sc_count count = RFIFOW(fd, 12); //sc_count
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
data = (struct skill_cooldown_data*) RFIFOP(fd, 14 + i * sizeof (struct skill_cooldown_data)); data = (struct skill_cooldown_data*) RFIFOP(fd, 14 + i * sizeof (struct skill_cooldown_data));
skill_blockpc_start(sd, data->skill_id, data->tick); skill_blockpc_start(sd, data->skill_id, data->tick);
} }
return 0; return 0;
} }
/*========================================== /*==========================================
@ -1522,7 +1567,7 @@ int chrif_parse(int fd) {
case 0x2b04: chrif_recvmap(fd); break; case 0x2b04: chrif_recvmap(fd); break;
case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break; case 0x2b06: chrif_changemapserverack(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10), RFIFOL(fd,14), RFIFOW(fd,18), RFIFOW(fd,20), RFIFOW(fd,22), RFIFOL(fd,24), RFIFOW(fd,28)); break;
case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break; case 0x2b09: map_addnickdb(RFIFOL(fd,2), (char*)RFIFOP(fd,6)); break;
case 0x2b0b: chrif_skillcooldown_load(fd); break; case 0x2b0b: chrif_skillcooldown_load(fd); break;
case 0x2b0d: chrif_changedsex(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_char_ask_name_answer(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 0x2b12: chrif_divorceack(RFIFOL(fd,2), RFIFOL(fd,6)); break;
@ -1537,6 +1582,7 @@ int chrif_parse(int fd) {
case 0x2b24: chrif_keepalive_ack(fd); break; case 0x2b24: chrif_keepalive_ack(fd); break;
case 0x2b25: chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break; case 0x2b25: chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
case 0x2b27: chrif_authfail(fd); break; case 0x2b27: chrif_authfail(fd); break;
case 0x2b29: chrif_load_bankdata(fd); break;
default: default:
ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd); ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
set_eof(fd); set_eof(fd);

View File

@ -41,6 +41,9 @@ int chrif_scdata_request(int account_id, int char_id);
int chrif_skillcooldown_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_save(struct map_session_data *sd);
int chrif_skillcooldown_load(int fd); 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_save(struct map_session_data* sd, int flag);
int chrif_charselectreq(struct map_session_data* sd, uint32 s_ip); 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_changemapserver(struct map_session_data* sd, uint32 ip, uint16 port);

View File

@ -55,8 +55,8 @@
/* for clif_clearunit_delayed */ /* for clif_clearunit_delayed */
static struct eri *delay_clearunit_ers; static struct eri *delay_clearunit_ers;
//#define DUMP_UNKNOWN_PACKET #define DUMP_UNKNOWN_PACKET
//#define DUMP_INVALID_PACKET #define DUMP_INVALID_PACKET
struct Clif_Config { struct Clif_Config {
int packet_db_ver; //Preferred packet version. int packet_db_ver; //Preferred packet version.
@ -64,6 +64,7 @@ struct Clif_Config {
} clif_config; } clif_config;
struct s_packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB + 1]; struct s_packet_db packet_db[MAX_PACKET_VER + 1][MAX_PACKET_DB + 1];
int packet_db_ack[MAX_PACKET_VER + 1][MAX_ACK_FUNC + 1];
//Converts item type in case of pet eggs. //Converts item type in case of pet eggs.
static inline int itemtype(int type) { static inline int itemtype(int type) {
@ -6116,8 +6117,14 @@ void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail)
#endif #endif
} }
// [Ind/Hercules] - Data Thanks to Yommy // [Ind/Hercules] - Data Thanks to Yommy (ZC_ACK_ADDITEM_TO_CART)
void clif_cart_additem_ack(struct map_session_data *sd, int flag) /* Acknowledge an item have been added to cart
* 012c <result>B
* result :
* 0 = ADDITEM_TO_CART_FAIL_WEIGHT
* 1 = ADDITEM_TO_CART_FAIL_COUNT
*/
void clif_cart_additem_ack(struct map_session_data *sd, uint8 flag)
{ {
int fd; int fd;
unsigned char *buf; unsigned char *buf;
@ -6126,10 +6133,208 @@ void clif_cart_additem_ack(struct map_session_data *sd, int flag)
fd = sd->fd; fd = sd->fd;
buf = WFIFOP(fd,0); buf = WFIFOP(fd,0);
WBUFW(buf,0) = 0x12c; WBUFW(buf,0) = 0x12c;
WBUFL(buf,2) = flag; WBUFB(buf,2) = flag;
clif_send(buf,packet_len(0x12c),&sd->bl,SELF); clif_send(buf,packet_len(0x12c),&sd->bl,SELF);
} }
// 09B7 <unknow data> (ZC_ACK_OPEN_BANKING)
void clif_bank_open(struct map_session_data *sd){
int fd = sd->fd;
WFIFOHEAD(fd,4);
WFIFOW(fd,0) = 0x09b7;
WFIFOW(fd,2) = 0;
WFIFOSET(fd,4);
return; //TODO found out what going on here
}
/*
* Request to Open the banking system
* 09B6 <aid>L ??? (dunno just wild guess checkme)
*/
void clif_parse_BankOpen(int fd, struct map_session_data* sd) {
//TODO check if preventing trade or stuff like that
//also mark something in case char ain't available for saving, should we check now ?
if( !battle_config.feature_banking ) {
clif_colormes(sd,color_table[COLOR_RED],msg_txt(sd,1483));
return;
}
else {
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
int aid = RFIFOL(fd,info->pos[0]); //unused should we check vs fd ?
sd->state.banking = 1;
}
//request save ?
// chrif_bankdata_request(sd->status.account_id, sd->status.char_id);
//on succes open bank ?
clif_bank_open(sd);
return;
}
// 09B9 <unknow data> (ZC_ACK_CLOSE_BANKING)
void clif_bank_close(struct map_session_data *sd){
int fd = sd->fd;
WFIFOHEAD(fd,4);
WFIFOW(fd,0) = 0x09B9;
WFIFOW(fd,2) = 0;
WFIFOSET(fd,4);
return; //TODO found out what going on here
}
/*
* Request to close the banking system
* 09B8 <aid>L ??? (dunno just wild guess checkme)
*/
void clif_parse_BankClose(int fd, struct map_session_data* sd) {
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
int aid = RFIFOL(fd,info->pos[0]); //unused should we check vs fd ?
if( !battle_config.feature_banking ) {
clif_colormes(sd,color_table[COLOR_RED],msg_txt(sd,1483));
//still allow to go trough to not stuck player if we have disable it while they was in
}
sd->state.banking = 0;
clif_bank_close(sd);
return;
}
/*
* Display how much we got in bank (I suppose)
09A6 <Bank_Vault>Q <Reason>W (PACKET_ZC_BANKING_CHECK)
*/
void clif_Bank_Check(struct map_session_data* sd) {
unsigned char buf[13];
struct s_packet_db* info;
int16 len;
int cmd = 0;
nullpo_retv(sd);
cmd = packet_db_ack[sd->packet_ver][ZC_BANKING_CHECK];
if(!cmd) cmd = 0x09A6; //default
info = &packet_db[sd->packet_ver][cmd];
len = info->len;
// sd->state.banking = 1; //mark opening and closing
WBUFW(buf,0) = cmd;
WBUFQ(buf,info->pos[0]) = sd->status.bank_vault; //testig value
WBUFW(buf,info->pos[1]) = 0; //reason
clif_send(buf,len,&sd->bl,SELF);
}
/*
* Requesting the data in bank
* 09AB <aid>L (PACKET_CZ_REQ_BANKING_CHECK)
*/
void clif_parse_BankCheck(int fd, struct map_session_data* sd) {
nullpo_retv(sd);
if( !battle_config.feature_banking ) {
clif_colormes(sd,color_table[COLOR_RED],msg_txt(sd,1483));
return;
}
else {
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
int aid = RFIFOL(fd,info->pos[0]); //unused should we check vs fd ?
if(sd->status.account_id == aid) //since we have it let check it for extra security
clif_Bank_Check(sd);
}
}
/*
* Acknowledge of deposit some money in bank
09A8 <Reason>W <Money>Q <balance>L (PACKET_ZC_ACK_BANKING_DEPOSIT)
*/
void clif_bank_deposit(struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason) {
unsigned char buf[17];
struct s_packet_db* info;
int16 len;
int cmd =0;
nullpo_retv(sd);
cmd = packet_db_ack[sd->packet_ver][ZC_ACK_BANKING_DEPOSIT];
if(!cmd) cmd = 0x09A8;
info = &packet_db[sd->packet_ver][cmd];
len = info->len;
WBUFW(buf,0) = cmd;
WBUFW(buf,info->pos[0]) = (short)reason;
WBUFQ(buf,info->pos[1]) = sd->status.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);
}
/*
* Request saving some money in bank
* @author : original [Yommy/Hercules]
* 09A7 <AID>L <Money>L (PACKET_CZ_REQ_BANKING_DEPOSIT)
*/
void clif_parse_BankDeposit(int fd, struct map_session_data* sd) {
if( !battle_config.feature_banking ) {
clif_colormes(sd,color_table[COLOR_RED],msg_txt(sd,1483));
return;
}
else {
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
int aid = RFIFOL(fd,info->pos[0]); //unused should we check vs fd ?
int money = RFIFOL(fd,info->pos[1]);
if(sd->status.account_id == aid){
money = max(0,money);
enum e_BANKING_DEPOSIT_ACK reason = pc_bank_deposit(sd,money);
clif_bank_deposit(sd,reason);
}
}
}
/*
* Acknowledge of withdrawing some money from bank
09AA <Reason>W <Money>Q <balance>L (PACKET_ZC_ACK_BANKING_WITHDRAW)
*/
void clif_bank_withdraw(struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason) {
unsigned char buf[17];
struct s_packet_db* info;
int16 len;
int cmd;
nullpo_retv(sd);
cmd = packet_db_ack[sd->packet_ver][ZC_ACK_BANKING_WITHDRAW];
if(!cmd) cmd = 0x09AA;
info = &packet_db[sd->packet_ver][cmd];
len = info->len;
WBUFW(buf,0) = cmd;
WBUFW(buf,info->pos[0]) = (short)reason;
WBUFQ(buf,info->pos[1]) = sd->status.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);
}
/*
* Request Withdrawing some money from bank
* 09A9 <AID>L <Money>L (PACKET_CZ_REQ_BANKING_WITHDRAW)
*/
void clif_parse_BankWithdraw(int fd, struct map_session_data* sd) {
if( !battle_config.feature_banking ) {
clif_colormes(sd,color_table[COLOR_RED],msg_txt(sd,1483));
return;
}
else {
struct s_packet_db* info = &packet_db[sd->packet_ver][RFIFOW(fd,0)];
int aid = RFIFOL(fd,info->pos[0]); //unused should we check vs fd ?
int money = RFIFOL(fd,info->pos[1]);
if(sd->status.account_id == aid){
money = max(0,money);
enum e_BANKING_WITHDRAW_ACK reason = pc_bank_withdraw(sd,money);
clif_bank_withdraw(sd,reason);
}
}
}
/// Deletes an item from character's cart (ZC_DELETE_ITEM_FROM_CART). /// Deletes an item from character's cart (ZC_DELETE_ITEM_FROM_CART).
/// 0125 <index>.W <amount>.L /// 0125 <index>.W <amount>.L
void clif_cart_delitem(struct map_session_data *sd,int n,int amount) void clif_cart_delitem(struct map_session_data *sd,int n,int amount)
@ -17069,9 +17274,9 @@ void packetdb_readdb(void)
0, 0, 0, 0, 0, 0, 0, 14, 6, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 6, 50, 0, 0, 0, 0, 0, 0,
//#0x0980 //#0x0980
0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
31, 0, 0, 0, 0, 0, 0, -1, 8, 11, 9, 8, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, -1, 8, 11, 9, 8, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 10, 14, 10, 14, 6, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 4, 6, 4, 0, 0, 0, 0, 0, 0,
}; };
struct { struct {
@ -17261,6 +17466,12 @@ void packetdb_readdb(void)
{clif_parse_PartyBookingUpdateReq,"bookingupdatereq"}, {clif_parse_PartyBookingUpdateReq,"bookingupdatereq"},
{clif_parse_PartyBookingDeleteReq,"bookingdelreq"}, {clif_parse_PartyBookingDeleteReq,"bookingdelreq"},
#endif #endif
{clif_parse_BankCheck,"bankcheck"},
{clif_parse_BankDeposit,"bankdeposit"},
{clif_parse_BankWithdraw,"bankwithdrawal"},
{clif_parse_BankOpen,"bankopen"},
{clif_parse_BankClose,"bankclose"},
{clif_parse_PVPInfo,"pvpinfo"}, {clif_parse_PVPInfo,"pvpinfo"},
{clif_parse_LessEffect,"lesseffect"}, {clif_parse_LessEffect,"lesseffect"},
// Buying Store // Buying Store
@ -17288,6 +17499,15 @@ void packetdb_readdb(void)
{ clif_parse_ranklist, "ranklist"}, { clif_parse_ranklist, "ranklist"},
{NULL,NULL} {NULL,NULL}
}; };
struct {
char *name; //function name
int funcidx; //
} clif_ack_func[]={ //hash
{ "ZC_ACK_OPEN_BANKING", ZC_ACK_OPEN_BANKING},
{ "ZC_ACK_BANKING_DEPOSIT", ZC_ACK_BANKING_DEPOSIT},
{ "ZC_ACK_BANKING_WITHDRAW", ZC_ACK_BANKING_WITHDRAW},
{ "ZC_BANKING_CHECK", ZC_BANKING_CHECK},
};
// initialize packet_db[SERVER] from hardcoded packet_len_table[] values // initialize packet_db[SERVER] from hardcoded packet_len_table[] values
memset(packet_db,0,sizeof(packet_db)); memset(packet_db,0,sizeof(packet_db));
@ -17344,6 +17564,7 @@ void packetdb_readdb(void)
// copy from previous version into new version and continue // copy from previous version into new version and continue
// - indicating all following packets should be read into the newer version // - indicating all following packets should be read into the newer version
memcpy(&packet_db[packet_ver], &packet_db[prev_ver], sizeof(packet_db[0])); memcpy(&packet_db[packet_ver], &packet_db[prev_ver], sizeof(packet_db[0]));
memcpy(&packet_db_ack[packet_ver], &packet_db_ack[prev_ver], sizeof(packet_db_ack[0]));
continue; continue;
} else if(strcmpi(w1,"packet_db_ver")==0) { } else if(strcmpi(w1,"packet_db_ver")==0) {
if(strcmpi(w2,"default")==0) //This is the preferred version. if(strcmpi(w2,"default")==0) //This is the preferred version.
@ -17390,6 +17611,14 @@ void packetdb_readdb(void)
ARR_FIND( 0, ARRAYLENGTH(clif_parse_func), j, clif_parse_func[j].name != NULL && strcmp(str[2],clif_parse_func[j].name)==0 ); ARR_FIND( 0, ARRAYLENGTH(clif_parse_func), j, clif_parse_func[j].name != NULL && strcmp(str[2],clif_parse_func[j].name)==0 );
if( j < ARRAYLENGTH(clif_parse_func) ) if( j < ARRAYLENGTH(clif_parse_func) )
packet_db[packet_ver][cmd].func = clif_parse_func[j].func; packet_db[packet_ver][cmd].func = clif_parse_func[j].func;
else { //search if it's a mapped ack func
ARR_FIND( 0, ARRAYLENGTH(clif_ack_func), j, clif_ack_func[j].name != NULL && strcmp(str[2],clif_ack_func[j].name)==0 );
if( j < ARRAYLENGTH(clif_ack_func)) {
int fidx = clif_ack_func[j].funcidx;
packet_db_ack[packet_ver][fidx] = cmd;
ShowInfo("Added %s, <=> %X i=%d for v=%d\n",clif_ack_func[j].name,cmd,fidx,packet_ver);
}
}
// set the identifying cmd for the packet_db version // set the identifying cmd for the packet_db version
if (strcmp(str[2],"wanttoconnection")==0) if (strcmp(str[2],"wanttoconnection")==0)

View File

@ -35,20 +35,42 @@ struct party_booking_ad_info;
enum enum
{// packet DB {// packet DB
MAX_PACKET_DB = 0xf00, MAX_PACKET_DB = 0xf00,
MAX_PACKET_VER = 44, MAX_PACKET_VER = 45,
MAX_PACKET_POS = 20, MAX_PACKET_POS = 20,
}; };
enum e_packet_ack {
ZC_ACK_OPEN_BANKING = 0,
ZC_ACK_BANKING_DEPOSIT,
ZC_ACK_BANKING_WITHDRAW,
ZC_BANKING_CHECK,
MAX_ACK_FUNC //auto upd len
};
struct s_packet_db { struct s_packet_db {
short len; short len;
void (*func)(int, struct map_session_data *); void (*func)(int, struct map_session_data *);
short pos[MAX_PACKET_POS]; short pos[MAX_PACKET_POS];
}; };
enum e_BANKING_DEPOSIT_ACK {
BDA_SUCCESS = 0x0,
BDA_ERROR = 0x1,
BDA_NO_MONEY = 0x2,
BDA_OVERFLOW = 0x3,
};
enum e_BANKING_WITHDRAW_ACK {
BWA_SUCCESS = 0x0,
BWA_NO_MONEY = 0x1,
BWA_UNKNOWN_ERROR = 0x2,
};
// packet_db[SERVER] is reserved for server use // packet_db[SERVER] is reserved for server use
#define SERVER 0 #define SERVER 0
#define packet_len(cmd) packet_db[SERVER][cmd].len #define packet_len(cmd) packet_db[SERVER][cmd].len
extern struct s_packet_db packet_db[MAX_PACKET_VER+1][MAX_PACKET_DB+1]; extern struct s_packet_db packet_db[MAX_PACKET_VER+1][MAX_PACKET_DB+1];
extern int packet_db_ack[MAX_PACKET_VER + 1][MAX_ACK_FUNC + 1];
// local define // local define
typedef enum send_target { typedef enum send_target {
@ -58,7 +80,7 @@ typedef enum send_target {
AREA_WOS, // area, without self AREA_WOS, // area, without self
AREA_WOC, // area, without chatrooms AREA_WOC, // area, without chatrooms
AREA_WOSC, // area, without own chatroom AREA_WOSC, // area, without own chatroom
AREA_CHAT_WOC, // hearable area, without chatrooms AREA_CHAT_WOC, // hearable area, without chatrooms
CHAT, // current chatroom CHAT, // current chatroom
CHAT_WOS, // current chatroom, without self CHAT_WOS, // current chatroom, without self
PARTY, PARTY,
@ -488,7 +510,7 @@ void clif_inventorylist(struct map_session_data *sd);
void clif_equiplist(struct map_session_data *sd); void clif_equiplist(struct map_session_data *sd);
void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail); void clif_cart_additem(struct map_session_data *sd,int n,int amount,int fail);
void clif_cart_additem_ack(struct map_session_data *sd, int flag); void clif_cart_additem_ack(struct map_session_data *sd, uint8 flag);
void clif_cart_delitem(struct map_session_data *sd,int n,int amount); void clif_cart_delitem(struct map_session_data *sd,int n,int amount);
void clif_cartlist(struct map_session_data *sd); void clif_cartlist(struct map_session_data *sd);
void clif_clearcart(int fd); void clif_clearcart(int fd);
@ -715,6 +737,15 @@ void clif_PartyBookingUpdateNotify(struct map_session_data* sd, struct party_boo
void clif_PartyBookingDeleteNotify(struct map_session_data* sd, int index); void clif_PartyBookingDeleteNotify(struct map_session_data* sd, int index);
void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad); void clif_PartyBookingInsertNotify(struct map_session_data* sd, struct party_booking_ad_info* pb_ad);
/* Bank System [Yommy/Hercules] */
void clif_bank_deposit (struct map_session_data *sd, enum e_BANKING_DEPOSIT_ACK reason);
void clif_bank_withdraw (struct map_session_data *sd,enum e_BANKING_WITHDRAW_ACK reason);
void clif_parse_BankDeposit (int fd, struct map_session_data *sd);
void clif_parse_BankWithdraw (int fd, struct map_session_data *sd);
void clif_parse_BankCheck (int fd, struct map_session_data *sd);
void clif_parse_BankOpen (int fd, struct map_session_data *sd);
void clif_parse_BankClose (int fd, struct map_session_data *sd);
void clif_showdigit(struct map_session_data* sd, unsigned char type, int value); void clif_showdigit(struct map_session_data* sd, unsigned char type, int value);
/// Buying Store System /// Buying Store System

View File

@ -73,6 +73,7 @@ static char log_picktype2char(e_log_pick_type type)
case LOG_TYPE_AUCTION: return 'I'; // Auct(I)on case LOG_TYPE_AUCTION: return 'I'; // Auct(I)on
case LOG_TYPE_BUYING_STORE: return 'B'; // (B)uying Store case LOG_TYPE_BUYING_STORE: return 'B'; // (B)uying Store
case LOG_TYPE_LOOT: return 'L'; // (L)oot (consumed monster pick/drop) case LOG_TYPE_LOOT: return 'L'; // (L)oot (consumed monster pick/drop)
case LOG_TYPE_BANK: return 'K'; // Ban(K) Transactions
case LOG_TYPE_OTHER: return 'X'; // Other case LOG_TYPE_OTHER: return 'X'; // Other
case LOG_TYPE_CASH: return '$'; // Cash case LOG_TYPE_CASH: return '$'; // Cash
} }

View File

@ -45,6 +45,7 @@ typedef enum e_log_pick_type
LOG_TYPE_BUYING_STORE = 0x08000, LOG_TYPE_BUYING_STORE = 0x08000,
LOG_TYPE_OTHER = 0x10000, LOG_TYPE_OTHER = 0x10000,
LOG_TYPE_CASH = 0x20000, LOG_TYPE_CASH = 0x20000,
LOG_TYPE_BANK = 0x40000,
// combinations // combinations
LOG_TYPE_LOOT = LOG_TYPE_PICKDROP_MONSTER|LOG_TYPE_CONSUME, LOG_TYPE_LOOT = LOG_TYPE_PICKDROP_MONSTER|LOG_TYPE_CONSUME,
// all // all

View File

@ -1292,6 +1292,7 @@ int pc_reg_received(struct map_session_data *sd)
status_calc_pc(sd,1); status_calc_pc(sd,1);
chrif_scdata_request(sd->status.account_id, sd->status.char_id); chrif_scdata_request(sd->status.account_id, sd->status.char_id);
chrif_skillcooldown_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);
intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
intif_request_questlog(sd); intif_request_questlog(sd);
@ -4343,6 +4344,7 @@ int pc_isUseitem(struct map_session_data *sd,int n)
sd->sc.data[SC_TRICKDEAD] || sd->sc.data[SC_TRICKDEAD] ||
sd->sc.data[SC_HIDING] || sd->sc.data[SC_HIDING] ||
sd->sc.data[SC__SHADOWFORM] || sd->sc.data[SC__SHADOWFORM] ||
sd->sc.data[SC__INVISIBILITY] ||
sd->sc.data[SC__MANHOLE] || sd->sc.data[SC__MANHOLE] ||
sd->sc.data[SC_KAGEHUMI] || sd->sc.data[SC_KAGEHUMI] ||
(sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM) (sd->sc.data[SC_NOCHAT] && sd->sc.data[SC_NOCHAT]->val1&MANNER_NOITEM)
@ -10248,6 +10250,46 @@ void pc_damage_log_clear(struct map_session_data *sd, int id)
} }
} }
enum e_BANKING_DEPOSIT_ACK pc_bank_deposit(struct map_session_data *sd, int money) {
unsigned int limit_check = money+sd->status.bank_vault;
if( money <= 0 || limit_check > MAX_BANK_ZENY ) {
return BDA_OVERFLOW;
} else if ( money > sd->status.zeny ) {
return BDA_NO_MONEY;
}
if( pc_payzeny(sd,money, LOG_TYPE_BANK, NULL) )
return BDA_NO_MONEY;
sd->status.bank_vault += money;
if( save_settings&256 )
chrif_save(sd,0);
return BDA_SUCCESS;
}
enum e_BANKING_WITHDRAW_ACK pc_bank_withdraw(struct map_session_data *sd, int money) {
unsigned int limit_check = money+sd->status.zeny;
if( money <= 0 ) {
return BWA_UNKNOWN_ERROR;
} else if ( money > sd->status.bank_vault ) {
return BWA_NO_MONEY;
} else if ( limit_check > MAX_ZENY ) {
/* no official response for this scenario exists. */
clif_colormes(sd,COLOR_RED,msg_txt(sd,1482));
return BWA_UNKNOWN_ERROR;
}
if( pc_getzeny(sd,money, LOG_TYPE_BANK, NULL) )
return BWA_NO_MONEY;
sd->status.bank_vault -= money;
if( save_settings&256 )
chrif_save(sd,0);
return BWA_SUCCESS;
}
/*========================================== /*==========================================
* pc Init/Terminate * pc Init/Terminate
*------------------------------------------*/ *------------------------------------------*/

View File

@ -192,6 +192,7 @@ struct map_session_data {
unsigned int prevend : 1;//used to flag wheather you've spent 40sp to open the vending or not. unsigned int prevend : 1;//used to flag wheather you've spent 40sp to open the vending or not.
unsigned int warping : 1;//states whether you're in the middle of a warp processing unsigned int warping : 1;//states whether you're in the middle of a warp processing
unsigned int permanent_speed : 1; // When 1, speed cannot be changed through status_calc_pc(). unsigned int permanent_speed : 1; // When 1, speed cannot be changed through status_calc_pc().
unsigned int banking : 1; //1 when we using the banking system 0 when closed
} state; } state;
struct { struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage; unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
@ -1010,6 +1011,9 @@ void pc_baselevelchanged(struct map_session_data *sd);
void pc_damage_log_add(struct map_session_data *sd, int id); void pc_damage_log_add(struct map_session_data *sd, int id);
void pc_damage_log_clear(struct map_session_data *sd, int id); void pc_damage_log_clear(struct map_session_data *sd, int id);
enum e_BANKING_DEPOSIT_ACK pc_bank_deposit(struct map_session_data *sd, int money);
enum e_BANKING_WITHDRAW_ACK pc_bank_withdraw(struct map_session_data *sd, int money);
#if defined(RENEWAL_DROP) || defined(RENEWAL_EXP) #if defined(RENEWAL_DROP) || defined(RENEWAL_EXP)
int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_race, uint32 mob_mode, int type); int pc_level_penalty_mod(struct map_session_data *sd, int mob_level, uint32 mob_race, uint32 mob_mode, int type);
#endif #endif

View File

@ -1212,7 +1212,6 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in
status_change_end(target, SC_CLOAKING, INVALID_TIMER); status_change_end(target, SC_CLOAKING, INVALID_TIMER);
status_change_end(target, SC_CHASEWALK, INVALID_TIMER); status_change_end(target, SC_CHASEWALK, INVALID_TIMER);
status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER); status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
status_change_end(target, SC__INVISIBILITY, INVALID_TIMER);
status_change_end(target, SC_DEEPSLEEP, INVALID_TIMER); status_change_end(target, SC_DEEPSLEEP, INVALID_TIMER);
if ((sce=sc->data[SC_ENDURE]) && !sce->val4) { if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
//Endure count is only reduced by non-players on non-gvg maps. //Endure count is only reduced by non-players on non-gvg maps.