Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/.gitignore b/.gitignore
- index 8c735b6..f78af28 100644
- --- a/.gitignore
- +++ b/.gitignore
- @@ -1,3 +1,7 @@
- +/autom4te.cache/output.1
- +/autom4te.cache/traces.1
- +/autom4te.cache/output.1
- +/autom4te.cache/traces.1
- /autom4te.cache/output.0
- /autom4te.cache/requests
- /autom4te.cache/traces.0
- diff --git a/conf/battle/player.conf b/conf/battle/player.conf
- index b587839..ffb4444 100644
- --- a/conf/battle/player.conf
- +++ b/conf/battle/player.conf
- @@ -5,6 +5,8 @@
- //--------------------------------------------------------------
- // Note 1: Value is a config switch (on/off, yes/no or 1/0)
- // Note 2: Value is in percents (100 means 100%)
- +// Note 3: Value is a bit field. If no description is given,
- +// assume unit types (1: Pc, 2: Mob, 4: Pet, 8: Homun)
- //--------------------------------------------------------------
- // Players' maximum HP rate? (Default is 100)
- @@ -141,4 +143,49 @@ idle_no_autoloot: 0
- // Minimum distance a vending/chat room must be from a NPC in order to be placed.
- // Default: 3 (0: disabled).
- -min_npc_vendchat_distance: 3
- \ No newline at end of file
- +min_npc_vendchat_distance: 3
- +
- +
- +// Storage slot increase. Setting to 0 will disable.
- +// Give more storage slots above the MIN_STORAGE limit.
- +// Note: MIN_STORAGE + storage_increase cannot exceed MAX_STORAGE.
- +// Default: 300
- +vip_storage_increase: 300
- +
- +// Base EXP rate increase. Setting to 0 will disable. (Note 2)
- +// Default: 50
- +vip_base_exp_increase: 50
- +
- +// Exp. penalty rate multiplier for Non-VIP accounts
- +// Multiplies the 'death_penalty_base' and 'death_penalty_job' settings in 'conf/battle/exp.conf'.
- +// Default: 3 (3*100 = 3% penalty)
- +vip_exp_penalty_base_normal: 3
- +vip_exp_penalty_job_normal: 3
- +
- +// Exp. penalty rate multiplier for VIP accounts
- +// Multiplies the 'death_penalty_base' and 'death_penalty_job' settings in 'conf/battle/exp.conf'.
- +// Default: 1 (1*100 = 1% penalty)
- +vip_exp_penalty_base: 1
- +vip_exp_penalty_job: 1
- +
- +// Job EXP rate increase. Setting to 0 will disable. (Note 2)
- +// Default: 50
- +vip_job_exp_increase: 50
- +
- +// Battle Manual EXP increase. Setting to 0 will disable.
- +// - Regular/Thick Battle Manual: 50+(50/X) = 75%
- +// - HE Battle Manual: 100+(100/X) = 150%
- +// - Battle Manual x3: 200+(200/X) = 300%
- +// Note: X is what the config is set to.
- +// Default: 2
- +vip_bm_increase: 2
- +
- +// Item drop increase. Setting to 0 will disable.
- +// Note: 50 = 0.5%
- +// Default: 50
- +vip_drop_increase: 50
- +
- +// GemStone requirement. Setting to false will disable.
- +// Can the VIP Group ignore GemStone requirement for skills?
- +// Default: true
- +vip_gemstone: true
- diff --git a/conf/char_athena.conf b/conf/char_athena.conf
- index c05d157..4dc80ca 100644
- --- a/conf/char_athena.conf
- +++ b/conf/char_athena.conf
- @@ -140,11 +140,6 @@ char_name_option: 1
- // Note: Don't add spaces unless you mean to add 'space' to the list.
- char_name_letters: abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
- -// How many Characters are allowed per Account ? (0 = disabled)
- -// You can not exceed the limit of MAX_CHARS slots, defined in mmo.h
- -// Doing that, chars_per_account will be default to MAX_CHARS.
- -chars_per_account: 0
- -
- // Restrict character deletion by BaseLevel
- // 0: no restriction (players can delete characters of any level)
- // -X: you can't delete chars with BaseLevel <= X
- diff --git a/conf/groups.conf b/conf/groups.conf
- index 63ccdf8..1ff3853 100644
- --- a/conf/groups.conf
- +++ b/conf/groups.conf
- @@ -220,6 +220,19 @@ groups: (
- }
- },
- {
- + id: 5
- + name: "VIP"
- + inherit: ( "Player" ) /* can do everything Players can */
- + level: 0
- + commands: {
- + rates: true
- + who: true
- + }
- + permissions: {
- + /* no permissions by default */
- + }
- +},
- +{
- id: 10
- name: "Law Enforcement"
- inherit: ( "Support" )
- diff --git a/conf/login_athena.conf b/conf/login_athena.conf
- index 6a9002b..cc0b0ef 100644
- --- a/conf/login_athena.conf
- +++ b/conf/login_athena.conf
- @@ -73,6 +73,23 @@ group_id_to_connect: -1
- // 0 or more: group id
- min_group_id_to_connect: -1
- +// Which group (ID) will be denoted as the VIP Group?
- +// Default: 5
- +vip_group: 5
- +
- +// How many Characters are allowed per Account ? (0 = disabled)
- +// You can not exceed the limit of MAX_CHARS slots, defined in mmo.h
- +// Doing that, chars_per_account will be default to MAX_CHARS.
- +// If setting to 0 MIN_CHARS value will be used
- +chars_per_account: 0
- +
- +// Max character limit increase. Setting to 0 will disable.
- +// Increase MAX_CHAR if you want to increase char_increase.
- +// Note: MAX_CHARS - chars_per_account = Amount of VIP Chars (char_increase value in login table).
- +// Note2: this setting need to be set after chars_per_account
- +// Default: 6
- +vip_char_increase: 6
- +
- // Starting additional sec from now for the limited time at creation of account
- // -1: new account are created with UNlimited time (default value)
- // 0 or more: new accounts was created by addition of the value (in sec) to the actual time (to set first limited time)
- diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf
- index 976535f..f281e90 100644
- --- a/conf/msg_conf/map_msg.conf
- +++ b/conf/msg_conf/map_msg.conf
- @@ -693,6 +693,16 @@
- 694: Hanbok
- 695: Rebellion
- +// @vip
- +700: Usage: @vip <time> <character name>
- +701: Invalid time for VIP command.
- +702: Time parameter format is +/-<value> to alter. y/a = Year, m = Month, d/j = Day, h = Hour, n/mn = Minute, s = Second.
- +703: GM has removed your VIP time.
- +704: Player is no longer VIP.
- +705: %s is VIP for %d years, %d months, %d days, %d hours and %d minutes.
- +706: This player is now VIP for %d years, %d months, %d days, %d hours and %d minutes.
- +707: You are VIP until
- +//708-899 free
- //------------------------------------
- // More atcommands message
- diff --git a/sql-files/main.sql b/sql-files/main.sql
- index ffa5bbe..bbfe083 100644
- --- a/sql-files/main.sql
- +++ b/sql-files/main.sql
- @@ -460,6 +460,8 @@ CREATE TABLE IF NOT EXISTS `login` (
- `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`),
- KEY `name` (`userid`)
- ) ENGINE=MyISAM AUTO_INCREMENT=2000000;
- diff --git a/src/char/char.c b/src/char/char.c
- index 052a8b2..c0edce3 100644
- --- a/src/char/char.c
- +++ b/src/char/char.c
- @@ -111,7 +111,6 @@ struct mmo_map_server {
- #define TRIM_CHARS "\255\xA0\032\t\x0A\x0D " //The following characters are trimmed regardless because they cause confusion and problems on the servers. [Skotlex]
- char char_name_letters[1024] = ""; // list of letters/symbols allowed (or not) in a character name. by [Yor]
- -int char_per_account = 0; //Maximum chars per account (default unlimited) [Sirius]
- int char_del_level = 0; //From which level u can delete character [Lupus]
- int char_del_delay = 86400;
- @@ -133,7 +132,9 @@ struct char_session_data {
- char email[40]; // e-mail (default: a@a.com) by [Yor]
- time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
- int group_id; // permission
- - uint8 char_slots;
- + uint8 char_slots; //total char that sd can create
- + uint8 chars_vip;
- + uint8 chars_billing;
- uint32 version;
- uint8 clienttype;
- char new_name[NAME_LENGTH];
- @@ -146,6 +147,7 @@ struct char_session_data {
- // Addon system
- int bank_vault;
- unsigned int char_moves[MAX_CHARS]; // character moves left
- + uint8 isvip;
- };
- struct startitem {
- @@ -183,6 +185,11 @@ struct startitem {
- void pincode_decrypt( uint32 userSeed, char* pin );
- int pincode_compare( int fd, struct char_session_data* sd, char* pin );
- +int mapif_parse_vipactive(int fd);
- +int mapif_vipack(uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid);
- +int logif_reqviddata(uint32 aid, uint8 type, uint32 add_vip_time);
- +int logif_parse_vipack(int fd);
- +
- // Addon system
- bool char_move_enabled = true;
- bool char_movetoused = true;
- @@ -1441,8 +1448,6 @@ int mmo_char_sql_init(void)
- {
- char_db_= idb_alloc(DB_OPT_RELEASE_DATA);
- - ShowStatus("Characters per Account: '%d'.\n", char_per_account);
- -
- //the 'set offline' part is now in check_login_conn ...
- //if the server connects to loginserver
- //it will dc all off players
- @@ -1579,11 +1584,12 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag
- if( flag < 0 )
- return flag;
- + ShowInfo("make_new_char_sql slot=%d, sd->char_slots=%d \n",slot,sd->char_slots);
- //check other inputs
- #if PACKETVER >= 20120307
- - if(slot >= sd->char_slots)
- + if(slot < 0 || slot >= sd->char_slots)
- #else
- - if((slot >= sd->char_slots) // slots
- + if((slot < 0 || slot >= sd->char_slots) // slots
- || (str + agi + vit + int_ + dex + luk != 6*5 ) // stats
- || (str < 1 || str > 9 || agi < 1 || agi > 9 || vit < 1 || vit > 9 || int_ < 1 || int_ > 9 || dex < 1 || dex > 9 || luk < 1 || luk > 9) // individual stat values
- || (str + int_ != 10 || agi + luk != 10 || vit + dex != 10) ) // pairs
- @@ -1596,12 +1602,10 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag
- // check the number of already existing chars in this account
- - if( char_per_account != 0 ) {
- - if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) )
- - Sql_ShowDebug(sql_handle);
- - if( Sql_NumRows(sql_handle) >= char_per_account )
- - return -2; // character account limit exceeded
- - }
- + if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) )
- + Sql_ShowDebug(sql_handle);
- + if( Sql_NumRows(sql_handle) >= sd->char_slots )
- + return -2; // character account limit exceeded
- // check char slot
- if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d' AND `char_num` = '%d' LIMIT 1", char_db, sd->account_id, slot) )
- @@ -1979,7 +1983,11 @@ void char_parse_req_charlist(int fd, struct char_session_data* sd){
- //----------------------------------------
- int mmo_char_send006b(int fd, struct char_session_data* sd){
- int j, offset = 0;
- - bool newvers = (sd->version >= (uint32)date2version(20100413));
- + bool newvers = (sd->version >= date2version(20100413));
- +
- + ShowInfo("mmo_char_send006b, sd.charslot=%d, nbmaxchars=%d, nbpremium=%d, nbbilling=%d, isvip=%d \n",
- + sd->char_slots,MAX_CHARS,sd->chars_vip,sd->chars_billing,sd->isvip);
- +
- if(newvers) //20100413
- offset += 3;
- if (save_log)
- @@ -1989,11 +1997,16 @@ int mmo_char_send006b(int fd, struct char_session_data* sd){
- WFIFOHEAD(fd,j + MAX_CHARS*MAX_CHAR_BUF);
- WFIFOW(fd,0) = 0x6b;
- if(newvers){ //20100413
- - WFIFOB(fd,4) = MAX_CHARS; // Max slots.
- - WFIFOB(fd,5) = sd->char_slots; // Available slots. (PremiumStartSlot)
- - WFIFOB(fd,6) = MAX_CHARS; // Premium slots. (Any existent chars past sd->char_slots but within MAX_CHARS will show a 'Premium Service' in red)
- - }
- - memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes
- + WFIFOB(fd,4) = MAX_CHARS; // Max slots. 15
- + WFIFOB(fd,5) = MAX_CHARS-sd->chars_billing-sd->chars_vip; // PremiumStartSlot
- + WFIFOB(fd,6) = MAX_CHARS-sd->chars_billing; // PremiumEndSlot // 9-15
- + /* this+0x7 char dummy1_beginbilling */
- + /* this+0x8 unsigned long code */
- + /* this+0xc unsigned long time1 */
- + /* this+0x10 unsigned long time2 */
- + /* this+0x14 char dummy2_endbilling[7] */
- + }
- + memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes 4-24 7-27
- j+=mmo_chars_fromsql(sd, WFIFOP(fd,j));
- WFIFOW(fd,2) = j; // packet len
- WFIFOSET(fd,j);
- @@ -2007,21 +2020,25 @@ int mmo_char_send006b(int fd, struct char_session_data* sd){
- void mmo_char_send082d(int fd, struct char_session_data* sd) {
- if (save_log)
- ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
- +
- + ShowInfo("mmo_char_send082d, sd.charslot=%d, nbmaxchars=%d, nbpremium=%d, nbbilling=%d, isvip=%d\n",
- + sd->char_slots,MAX_CHARS,sd->chars_vip,sd->chars_billing,sd->isvip);
- +
- WFIFOHEAD(fd,29);
- WFIFOW(fd,0) = 0x82d;
- WFIFOW(fd,2) = 29;
- - WFIFOB(fd,4) = sd->char_slots;
- - WFIFOB(fd,5) = MAX_CHARS - sd->char_slots;
- - WFIFOB(fd,6) = MAX_CHARS - sd->char_slots;
- - WFIFOB(fd,7) = sd->char_slots;
- - WFIFOB(fd,8) = sd->char_slots;
- + WFIFOB(fd,4) = sd->char_slots-sd->chars_vip; //NormalSlotNum
- + WFIFOB(fd,5) = sd->chars_vip; //PremiumSlotNum
- + WFIFOB(fd,6) = sd->chars_billing; //BillingSlotNum
- + WFIFOB(fd,7) = sd->char_slots; //ProducibleSlotNum
- + WFIFOB(fd,8) = sd->char_slots; //ValidSlotNum
- memset(WFIFOP(fd,9), 0, 20); // unused bytes
- WFIFOSET(fd,29);
- }
- void mmo_char_send(int fd, struct char_session_data* sd){
- - //ShowInfo("sd->version = %d\n",sd->version);
- - if(sd->version > (uint32)date2version(20130000) ){
- + ShowInfo("sd->version = %d\n",sd->version);
- + if(sd->version > date2version(20130000) ){
- mmo_char_send082d(fd,sd);
- char_charlist_notify(fd,sd);
- char_block_character(fd,sd);
- @@ -2170,7 +2187,7 @@ int loginif_BankingReq(int32 account_id, int8 type, int32 data){
- WFIFOB(login_fd,6) = type;
- WFIFOL(login_fd,7) = data;
- WFIFOSET(login_fd,11);
- - return 1;
- + return 1;
- }
- return 0;
- }
- @@ -2239,6 +2256,76 @@ int mapif_parse_ReqBankInfo(int fd){
- return 1;
- }
- +/*
- + * ZH 0x2b2c
- + * HA 0x2742
- + * We received an request vip_info from map-server.
- + * Transmit it to login-serv as it's the one knowing the info
- + */
- +int mapif_parse_vipactive(int fd) {
- +#ifdef VIP_ENABLE
- + uint32 aid = RFIFOL(fd,2); //aid
- + uint8 type = RFIFOB(fd,6); //type
- + uint32 adddur = RFIFOL(fd,7); //req_inc_duration
- + RFIFOSKIP(fd,11);
- + logif_reqviddata(aid, type, adddur);
- +#endif
- + return 0;
- +}
- +
- +/*
- + * HZ 0x2b2b
- + * Transmist vip data to mapserv
- + */
- +int mapif_vipack(uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid){
- +#ifdef VIP_ENABLE
- + uint8 buf[16];
- + WBUFW(buf,0) = 0x2b2b;
- + WBUFL(buf,2) = aid;
- + WBUFL(buf,6) = vip_time;
- + WBUFB(buf,10) = isvip;
- + WBUFL(buf,11) = groupid;
- + mapif_sendall(buf,15); // inform all map-servers attached.
- +#endif
- + return 0;
- +}
- +
- +/*
- + * HZ 0x2b2b
- + * Request to ask vip data from loginserv
- + */
- +int logif_reqviddata(uint32 aid, uint8 type, uint32 add_vip_time){
- +#ifdef VIP_ENABLE
- + WFIFOHEAD(login_fd,11);
- + WFIFOW(login_fd,0) = 0x2742;
- + WFIFOL(login_fd,2) = aid; //aid
- + WFIFOB(login_fd,6) = type; //type
- + WFIFOL(login_fd,7) = add_vip_time; //req_inc_duration
- + WFIFOSET(login_fd,11);
- +#endif
- + return 0;
- +}
- +
- +/*
- + * AH 0x2743
- + * We received the info from login-serv, ask to transmit it to map
- + */
- +int logif_parse_vipack(int fd){
- +#ifdef VIP_ENABLE
- + if (RFIFOREST(fd) < 15)
- + return 0;
- + else {
- + uint32 aid = RFIFOL(fd,2); //aid
- + uint32 vip_time = RFIFOL(fd,6); //vip_time
- + uint8 isvip = RFIFOB(fd,10); //isvip
- + uint32 groupid = RFIFOL(fd,11); //new group id
- + RFIFOSKIP(fd,15);
- + mapif_vipack(aid,vip_time,isvip,groupid);
- + }
- +#endif
- + return 1;
- +}
- +
- /// Resets all the data.
- void loginif_reset(void)
- @@ -2288,31 +2375,30 @@ void loginif_on_ready(void)
- int logif_parse_reqpincode(int fd, struct char_session_data *sd){
- #if PACKETVER >= 20110309
- - if( pincode_enabled ){
- - // PIN code system enabled
- - if( strlen( sd->pincode ) <= 0 ){
- - // No PIN code has been set yet
- - if( pincode_force ) pincode_sendstate( fd, sd, PINCODE_NEW );
- - else pincode_sendstate( fd, sd, PINCODE_PASSED );
- - } else {
- - if( !pincode_changetime || ( sd->pincode_change + pincode_changetime ) > time(NULL) ){
- - struct online_char_data* node = (struct online_char_data*)idb_get( online_char_db, sd->account_id );
- -
- - if( node != NULL && node->pincode_success ){ // User has already passed the check
- - pincode_sendstate( fd, sd, PINCODE_PASSED );
- - }else{
- - // Ask user for his PIN code
- - pincode_sendstate( fd, sd, PINCODE_ASK );
- - }
- - }else{ // User hasnt changed his PIN code too long
- - pincode_sendstate( fd, sd, PINCODE_EXPIRED );
- - }
- - }
- - } else { // PIN code system disabled
- - pincode_sendstate( fd, sd, PINCODE_OK );
- - }
- + if( pincode_enabled ){
- + // PIN code system enabled
- + if( strlen( sd->pincode ) <= 0 ){
- + // No PIN code has been set yet
- + if( pincode_force ) pincode_sendstate( fd, sd, PINCODE_NEW );
- + else pincode_sendstate( fd, sd, PINCODE_PASSED );
- + } else {
- + if( !pincode_changetime || ( sd->pincode_change + pincode_changetime ) > time(NULL) ){
- + struct online_char_data* node = (struct online_char_data*)idb_get( online_char_db, sd->account_id );
- + if( node != NULL && node->pincode_success ){ // User has already passed the check
- + pincode_sendstate( fd, sd, PINCODE_PASSED );
- + }else{
- + // Ask user for his PIN code
- + pincode_sendstate( fd, sd, PINCODE_ASK );
- + }
- + }else{ // User hasnt changed his PIN code too long
- + pincode_sendstate( fd, sd, PINCODE_EXPIRED );
- + }
- + }
- + } else { // PIN code system disabled
- + pincode_sendstate( fd, sd, PINCODE_OK );
- + }
- #endif
- - return 0;
- + return 0;
- }
- int parse_fromlogin(int fd) {
- @@ -2352,6 +2438,7 @@ int parse_fromlogin(int fd) {
- switch( command )
- {
- case 0x2741: loginif_parse_BankingAck(fd); break;
- + case 0x2743: logif_parse_vipack(fd); break;
- // acknowledgement of connect-to-loginserver request
- case 0x2711:
- @@ -2415,7 +2502,7 @@ int parse_fromlogin(int fd) {
- break;
- case 0x2717: // account data
- - if (RFIFOREST(fd) < 76)
- + if (RFIFOREST(fd) < 79)
- return 0;
- // find the authenticated session with this account id
- @@ -2431,11 +2518,15 @@ int parse_fromlogin(int fd) {
- ShowError("Account '%d' `character_slots` column is higher than supported MAX_CHARS (%d), update MAX_CHARS in mmo.h! capping to MAX_CHARS...\n",sd->account_id,sd->char_slots);
- sd->char_slots = MAX_CHARS;/* cap to maximum */
- } else if ( !sd->char_slots )/* no value aka 0 in sql */
- - sd->char_slots = MAX_CHARS;/* cap to maximum */
- + sd->char_slots = MIN_CHARS;/* cap to minimum */
- 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);
- +
- ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] );
- // continued from char_auth_ok...
- if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359
- @@ -2452,7 +2543,7 @@ int parse_fromlogin(int fd) {
- logif_parse_reqpincode(i, sd);
- }
- }
- - RFIFOSKIP(fd,76);
- + RFIFOSKIP(fd,79);
- break;
- // login-server alive packet
- @@ -2641,7 +2732,7 @@ int parse_fromlogin(int fd) {
- RFIFOSKIP(fd,2);
- }
- break;
- -
- +
- default:
- ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command);
- set_eof(fd);
- @@ -3680,7 +3771,7 @@ int parse_frommap(int fd)
- case 0x2b28: mapif_parse_UpdBankInfo(fd); break;
- case 0x2b2a: mapif_parse_ReqBankInfo(fd); break;
- -
- + case 0x2b2c: mapif_parse_vipactive(fd); break;
- case 0x2b2d: //Load data
- if (RFIFOREST(fd) < 6)
- return 0;
- @@ -5382,13 +5473,6 @@ int char_config_read(const char* cfgName)
- char_name_option = atoi(w2);
- } else if (strcmpi(w1, "char_name_letters") == 0) {
- safestrncpy(char_name_letters, w2, sizeof(char_name_letters));
- - } else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
- - char_per_account = atoi(w2);
- - if( char_per_account == 0 || char_per_account > MAX_CHARS ) {
- - if( char_per_account > MAX_CHARS )
- - ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", char_per_account, MAX_CHARS);
- - char_per_account = MAX_CHARS;
- - }
- } else if (strcmpi(w1, "char_del_level") == 0) { //disable/enable char deletion by its level condition [Lupus]
- char_del_level = atoi(w2);
- } else if (strcmpi(w1, "char_del_delay") == 0) {
- diff --git a/src/common/mmo.h b/src/common/mmo.h
- index 8b184c5..efaa8ba 100644
- --- a/src/common/mmo.h
- +++ b/src/common/mmo.h
- @@ -48,6 +48,7 @@
- #ifndef PACKETVER
- #define PACKETVER 20130807
- + //#define PACKETVER 20130320
- //#define PACKETVER 20120410
- #endif
- @@ -71,7 +72,8 @@
- #define MAX_MAP_PER_SERVER 1500 // Increased to allow creation of Instance Maps
- #define MAX_INVENTORY 100
- //Max number of characters per account. Note that changing this setting alone is not enough if the client is not hexed to support more characters as well.
- -#define MAX_CHARS 9
- +//max value tested was 265
- +#define MAX_CHARS 9
- //Number of slots carded equipment can have. Never set to less than 4 as they are also used to keep the data of forged items/equipment. [Skotlex]
- //Note: The client seems unable to receive data for more than 4 slots due to all related packets having a fixed size.
- #define MAX_SLOTS 4
- @@ -90,7 +92,7 @@
- #define DEFAULT_WALK_SPEED 150
- #define MIN_WALK_SPEED 0
- #define MAX_WALK_SPEED 1000
- -#define MAX_STORAGE 600
- +#define MAX_STORAGE 600 /// Max number of storage slots the client can support. Used as a cap for the VIP System.
- #define MAX_GUILD_STORAGE 600
- #define MAX_PARTY 12
- #define MAX_GUILD 16+10*6 // increased max guild members +6 per 1 extension levels [Lupus]
- diff --git a/src/common/utils.c b/src/common/utils.c
- index 9729fcb..cec87f4 100644
- --- a/src/common/utils.c
- +++ b/src/common/utils.c
- @@ -259,7 +259,7 @@ uint32 MakeDWord(uint16 word0, uint16 word1)
- ( (uint32)(word1 << 0x10) );
- }
- -int date2version(int date){
- +uint32 date2version(int date){
- if(date < 20040906) return 5;
- else if(date < 20040920) return 10;
- else if(date < 20041005) return 11;
- diff --git a/src/common/utils.h b/src/common/utils.h
- index 6ce1639..3fc5634 100644
- --- a/src/common/utils.h
- +++ b/src/common/utils.h
- @@ -29,6 +29,6 @@ extern uint16 GetWord(uint32 val, int idx);
- extern uint16 MakeWord(uint8 byte0, uint8 byte1);
- extern uint32 MakeDWord(uint16 word0, uint16 word1);
- -int date2version(int date);
- +uint32 date2version(int date);
- #endif /* _UTILS_H_ */
- diff --git a/src/config/core.h b/src/config/core.h
- index 66b1ec6..93caad2 100644
- --- a/src/config/core.h
- +++ b/src/config/core.h
- @@ -72,6 +72,24 @@
- /// Comment to disable the job HP/SP tables and use formulas instead
- #define HP_SP_TABLES
- +/// Uncomment to disable vip system.
- +//#define VIP_ENABLE
- +#ifdef VIP_ENABLE
- + #define MIN_STORAGE 300 // Default number of storage slots.
- + #define MIN_CHARS 3 // Default number of characters per account.
- + #define MAX_CHAR_VIP 6 //this must be below MAX_CHARS
- + #define MAX_CHAR_BILLING 0 //this must be below MAX_CHARS
- +#else
- + #define MIN_STORAGE 600 //if sys disable the min = max for storage slot
- + #define MIN_CHARS 9 // Default number of characters per account.
- + #define MAX_CHAR_BILLING 0
- + #define MAX_CHAR_VIP 0
- +#endif
- +#if (MIN_CHARS+MAX_CHAR_VIP+MAX_CHAR_BILLING)>MAX_CHARS
- + #error "Config of MAX_CHARS is invalid"
- +#endif
- +#define VIP_SCRIPT 0 //enable or disable scripts (require vip_enable)
- +
- /**
- * No settings past this point
- **/
- diff --git a/src/login/account.h b/src/login/account.h
- index 3d7acef..9121c58 100644
- --- a/src/login/account.h
- +++ b/src/login/account.h
- @@ -34,8 +34,7 @@ AccountDB* ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_4)(void);
- #endif
- -struct mmo_account
- -{
- +struct mmo_account {
- int account_id;
- char userid[NAME_LENGTH];
- char pass[32+1]; // 23+1 for plaintext, 32+1 for md5-ed passwords
- @@ -54,6 +53,10 @@ struct mmo_account
- time_t pincode_change; // (timestamp): last time of pincode change
- int account_reg2_num;
- int bank_vault;
- +#ifdef VIP_ENABLE
- + int old_group;
- + int vip_time;
- +#endif
- struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
- };
- diff --git a/src/login/account_sql.c b/src/login/account_sql.c
- index 3478870..bc28b05 100644
- --- a/src/login/account_sql.c
- +++ b/src/login/account_sql.c
- @@ -7,6 +7,7 @@
- #include "../common/sql.h"
- #include "../common/strlib.h"
- #include "../common/timer.h"
- +#include "../config/core.h"
- #include "account.h"
- #include <stdlib.h>
- #include <string.h>
- @@ -522,7 +523,11 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
- // retrieve login entry for the specified account
- 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`, `bank_vault` FROM `%s` WHERE `account_id` = %d",
- +#ifdef VIP_ENABLE //FIXME query is only for mysql
- + "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",
- +#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",
- +#endif
- db->account_db, account_id )
- ) {
- Sql_ShowDebug(sql_handle);
- @@ -552,10 +557,14 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
- 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);
- + ShowInfo("mmo_auth_fromsql vip_time=%d, old_ground=%d\n",acc->vip_time,acc->old_group);
- +#endif
- Sql_FreeResult(sql_handle);
- -
- -
- +
- +
- // retrieve account regs for the specified user
- if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `str`,`value` FROM `%s` WHERE `type`='1' AND `account_id`='%d'", db->accreg_db, acc->account_id) )
- {
- @@ -597,10 +606,17 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
- break;
- }
- +#ifdef VIP_ENABLE
- + ShowInfo("mmo_auth_tosql vip_time=%d, old_ground=%d\n",acc->vip_time,acc->old_group);
- +#endif
- if( is_new )
- {// 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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
- +#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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
- +#endif
- db->account_db)
- || 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))
- @@ -619,6 +635,10 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
- || 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))
- +#endif
- || SQL_SUCCESS != SqlStmt_Execute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- @@ -627,7 +647,13 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
- }
- else
- {// 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`=?, `bank_vault`=? WHERE `account_id` = '%d'", db->account_db, acc->account_id)
- + 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'",
- +#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'",
- +#endif
- + 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, 1, SQLDT_STRING, (void*)acc->pass, strlen(acc->pass))
- || SQL_SUCCESS != SqlStmt_BindParam(stmt, 2, SQLDT_ENUM, (void*)&acc->sex, sizeof(acc->sex))
- @@ -644,6 +670,10 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
- || 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))
- +#endif
- || SQL_SUCCESS != SqlStmt_Execute(stmt)
- ) {
- SqlStmt_ShowDebug(stmt);
- diff --git a/src/login/login.c b/src/login/login.c
- index daa8dca..06232f1 100644
- --- a/src/login/login.c
- +++ b/src/login/login.c
- @@ -13,6 +13,9 @@
- #include "../common/msg_conf.h"
- #include "../common/cli.h"
- #include "../common/ers.h"
- +#include "../common/utils.h"
- +#include "../common/mmo.h"
- +#include "../config/core.h"
- #include "account.h"
- #include "ipban.h"
- #include "login.h"
- @@ -294,11 +297,16 @@ bool check_password(const char* md5key, int passwdenc, const char* passwd, const
- }
- -//-----------------------------------------------------
- -// custom timestamp formatting (from eApp)
- -//-----------------------------------------------------
- -const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
- -{
- +/**
- + * Converting a timestamp is a srintf according to format
- + * safefr then strftime as it ensure \0 at end of string
- + * @param str, pointer to the destination string
- + * @param size, max length of the string
- + * @param timestamp, see unix epoch
- + * @param format, format to convert timestamp on, see strftime format
- + * @return the string of timestamp
- + */
- +const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format){
- size_t len = strftime(str, size, format, localtime(×tamp));
- memset(str + len, '\0', size - len);
- return str;
- @@ -428,6 +436,139 @@ int parse_console(const char* buf){
- return 0;
- }
- +int chrif_send_accdata(int fd, uint32 aid){
- + struct mmo_account acc;
- + time_t expiration_time = 0;
- + char email[40] = "";
- + 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;
- +
- + memset(pincode,0,PINCODE_LENGTH+1);
- + if( !accounts->load_num(accounts, &acc, aid) )
- + return -1;
- + else{
- + safestrncpy(email, acc.email, sizeof(email));
- + expiration_time = acc.expiration_time;
- + group_id = acc.group_id;
- +
- + safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
- + safestrncpy(pincode, acc.pincode, sizeof(pincode));
- + bank_vault = acc.bank_vault;
- +#ifdef VIP_ENABLE
- + ShowInfo("chrif_send_accdata now=%d, vip_time=%d, acc.vip_time > time = %d\n",
- + time(NULL),acc.vip_time,acc.vip_time > time(NULL));
- + if(acc.vip_time > time(NULL)){
- + isvip=true;
- + char_slots = login_config.char_per_account+login_config.vip_sys.char_increase;
- + char_vip = login_config.vip_sys.char_increase;
- + }
- + else
- + char_slots = login_config.char_per_account;
- +#endif
- + }
- +
- + WFIFOHEAD(fd,79);
- + WFIFOW(fd,0) = 0x2717;
- + WFIFOL(fd,2) = aid;
- + safestrncpy((char*)WFIFOP(fd,6), email, 40);
- + WFIFOL(fd,46) = (uint32)expiration_time;
- + WFIFOB(fd,50) = (unsigned char)group_id;
- + WFIFOB(fd,51) = char_slots;
- + safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
- + safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
- + WFIFOL(fd,68) = (uint32)acc.pincode_change;
- + 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);
- + return 0;
- +}
- +
- +int chrif_parse_reqaccdata(int fd, int cid, char *ip){
- + if( RFIFOREST(fd) < 6 )
- + return 0;
- + else{
- + uint32 aid = RFIFOL(fd,2);
- + RFIFOSKIP(fd,6);
- + if(chrif_send_accdata(fd,aid) < 0)
- + ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[cid].name, aid, ip);
- + }
- + return 0;
- +}
- +
- +
- +int chrif_sendvipdata(int fd, struct mmo_account acc, char isvip){
- +#ifdef VIP_ENABLE
- + uint8 buf[16];
- +
- + WBUFW(buf,0) = 0x2743;
- + WBUFL(buf,2) = acc.account_id;
- + WBUFL(buf,6) = acc.vip_time;
- + WBUFB(buf,10) = isvip;
- + WBUFL(buf,11) = acc.group_id; //new group id
- + charif_sendallwos(-1,buf,15); //inform all char-servs of result
- + ShowInfo("chrif_sendvipdata aid=%d, vip_time=%d, isvip=%d\n",
- + acc.account_id,acc.vip_time,isvip);
- +
- + chrif_send_accdata(fd,acc.account_id); //refresh char with new setting
- +#endif
- + return 1;
- +}
- +
- +/**
- + * Received a vip data reqest from char \n
- + * type is the query to perform \n
- + * &1 : Select info and update old_groupid \n
- + * &2 : Update vip time
- + * @param fd link to charserv
- + * @return 0 missing data, 1 succeed
- + */
- +int chrif_parse_reqvipdata(int fd){
- +#ifdef VIP_ENABLE
- + if( RFIFOREST(fd) < 11 )
- + return 0;
- + else { //request vip info
- + struct mmo_account acc;
- + int aid = RFIFOL(fd,2);
- + int8 type = RFIFOB(fd,6);
- + uint32 req_duration = RFIFOL(fd,7);
- + RFIFOSKIP(fd,11);
- +
- + ShowInfo("chrif_parse_reqvipdata aid=%d, type=%d, req_duration=%d\n",
- + aid,type,req_duration);
- + if( accounts->load_num(accounts, &acc, aid ) ){
- + time_t now = time(NULL);
- + time_t vip_time = acc.vip_time;
- + bool isvip = false;
- +
- + if( type&2 ) vip_time = now+req_duration; // set new duration
- + if(now < vip_time){ //isvip
- + if(acc.group_id != login_config.vip_sys.group) //only upd this if we're not vip already
- + acc.old_group = acc.group_id;
- + acc.group_id = login_config.vip_sys.group;
- + acc.char_slots = login_config.char_per_account+login_config.vip_sys.char_increase;
- + isvip = true;
- + } else { //expired
- + vip_time = 0;
- + acc.group_id = acc.old_group;
- + acc.old_group = 0;
- + acc.char_slots = login_config.char_per_account;
- + }
- + acc.vip_time = (int)vip_time;
- + accounts->save(accounts,&acc);
- +
- + chrif_sendvipdata(fd,acc,isvip);
- + }
- + }
- +#endif
- + return 1;
- +}
- +
- //--------------------------------
- // Packet parsing for char-servers
- @@ -555,54 +696,10 @@ int parse_fromchar(int fd){
- }
- break;
- - case 0x2716: // request account data
- - if( RFIFOREST(fd) < 6 )
- - return 0;
- - else{
- - struct mmo_account acc;
- - time_t expiration_time = 0;
- - char email[40] = "";
- - uint8 char_slots = 0;
- - int group_id = 0;
- - char birthdate[10+1] = "";
- - char pincode[PINCODE_LENGTH+1];
- - int account_id = RFIFOL(fd,2);
- - int bank_vault = 0;
- -
- - memset(pincode,0,PINCODE_LENGTH+1);
- -
- - RFIFOSKIP(fd,6);
- -
- - if( !accounts->load_num(accounts, &acc, account_id) )
- - ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
- - else{
- - safestrncpy(email, acc.email, sizeof(email));
- - expiration_time = acc.expiration_time;
- - group_id = acc.group_id;
- - char_slots = acc.char_slots;
- - safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
- - safestrncpy(pincode, acc.pincode, sizeof(pincode));
- - bank_vault = acc.bank_vault;
- - }
- -
- - WFIFOHEAD(fd,76);
- - WFIFOW(fd,0) = 0x2717;
- - WFIFOL(fd,2) = account_id;
- - safestrncpy((char*)WFIFOP(fd,6), email, 40);
- - WFIFOL(fd,46) = (uint32)expiration_time;
- - WFIFOB(fd,50) = (unsigned char)group_id;
- - WFIFOB(fd,51) = char_slots;
- - safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
- - safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
- - WFIFOL(fd,68) = (uint32)acc.pincode_change;
- - WFIFOL(fd,72) = bank_vault;
- - WFIFOSET(fd,76);
- - }
- - break;
- + case 0x2716: chrif_parse_reqaccdata(fd,id,ip); break; // request account data
- case 0x2719: // ping request from charserver
- RFIFOSKIP(fd,2);
- -
- WFIFOHEAD(fd,2);
- WFIFOW(fd,0) = 0x2718;
- WFIFOSET(fd,2);
- @@ -973,6 +1070,8 @@ int parse_fromchar(int fd){
- }
- break;
- + case 0x2742: chrif_parse_reqvipdata(fd); break; //Vip sys
- +
- default:
- ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);
- set_eof(fd);
- @@ -1026,10 +1125,12 @@ int mmo_auth_new(const char* userid, const char* pass, const char sex, const cha
- safestrncpy(acc.birthdate, "0000-00-00", sizeof(acc.birthdate));
- safestrncpy(acc.pincode, "", sizeof(acc.pincode));
- acc.pincode_change = 0;
- -
- - acc.char_slots = 0;
- + acc.char_slots = MIN_CHARS;
- acc.bank_vault = 0;
- -
- +#ifdef VIP_ENABLE
- + acc.vip_time = 0;
- + acc.old_group = 0;
- +#endif
- if( !accounts->create(accounts, &acc) )
- return 0;
- @@ -1638,8 +1739,7 @@ int parse_login(int fd)
- }
- -void login_set_defaults()
- -{
- +void login_set_defaults(){
- login_config.login_ip = INADDR_ANY;
- login_config.login_port = 6900;
- login_config.ipban_cleanup_interval = 60;
- @@ -1666,6 +1766,11 @@ void login_set_defaults()
- login_config.client_hash_check = 0;
- login_config.client_hash_nodes = NULL;
- + login_config.char_per_account = MAX_CHARS-MAX_CHAR_VIP-MAX_CHAR_BILLING;
- +#ifdef VIP_ENABLE
- + login_config.vip_sys.char_increase = MAX_CHAR_VIP;
- + login_config.vip_sys.group = 5;
- +#endif
- }
- //-----------------------------------
- @@ -1767,14 +1872,31 @@ int login_config_read(const char* cfgName)
- login_config.client_hash_nodes = nnode;
- }
- + } else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
- + login_config.char_per_account = atoi(w2);
- + if( login_config.char_per_account <= 0 || login_config.char_per_account > MAX_CHARS ) {
- + if( login_config.char_per_account > MAX_CHARS ){
- + ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", login_config.char_per_account, MAX_CHARS);
- + login_config.char_per_account = MAX_CHARS;
- + }
- + login_config.char_per_account = MIN_CHARS;
- + }
- }
- +#ifdef VIP_ENABLE
- + else if(strcmpi(w1,"vip_group")==0)
- + login_config.vip_sys.group = cap_value(atoi(w2),0,99);
- + else if(strcmpi(w1,"vip_char_increase")==0){
- + if(login_config.vip_sys.char_increase > (unsigned int) MAX_CHARS-login_config.char_per_account)
- + ShowWarning("vip_char_increase too high, can only go up to %d, according to your char_per_account config %d\n",
- + MAX_CHARS-login_config.char_per_account,login_config.char_per_account);
- + login_config.vip_sys.char_increase = cap_value(atoi(w2),0,MAX_CHARS-login_config.char_per_account);
- + }
- +#endif
- else if(!strcmpi(w1, "import"))
- login_config_read(w2);
- - else
- - if(!strcmpi(w1, "account.engine"))
- + else if(!strcmpi(w1, "account.engine"))
- safestrncpy(login_config.account_engine, w2, sizeof(login_config.account_engine));
- - else
- - {// try the account engines
- + else {// try the account engines
- int i;
- for( i = 0; account_engines[i].constructor; ++i )
- {
- diff --git a/src/login/login.h b/src/login/login.h
- index 427ece6..d10282f 100644
- --- a/src/login/login.h
- +++ b/src/login/login.h
- @@ -6,6 +6,7 @@
- #include "../common/mmo.h" // NAME_LENGTH,SEX_*
- #include "../common/core.h" // CORE_ST_LAST
- +#include "../config/core.h"
- enum E_LOGINSERVER_ST
- {
- @@ -58,7 +59,6 @@ struct client_hash_node {
- };
- struct Login_Config {
- -
- uint32 login_ip; // the address to bind to
- uint16 login_port; // the port to bind to
- unsigned int ipban_cleanup_interval; // interval (in seconds) to clean up expired IP bans
- @@ -86,6 +86,13 @@ struct Login_Config {
- int client_hash_check; // flags for checking client md5
- struct client_hash_node *client_hash_nodes; // linked list containg md5 hash for each gm group
- + int char_per_account; //number of char an account can have
- +#ifdef VIP_ENABLE
- + struct {
- + unsigned int group;
- + unsigned int char_increase;
- + } vip_sys;
- +#endif
- };
- #define sex_num2str(num) ( (num == SEX_FEMALE ) ? 'F' : (num == SEX_MALE ) ? 'M' : 'S' )
- @@ -100,7 +107,7 @@ const char* login_msg_txt(int msg_number);
- void login_do_final_msg(void);
- -#define MAX_SERVERS 30
- +#define MAX_SERVERS 30 //number of charserv loginserv can handle
- extern struct mmo_char_server server[MAX_SERVERS];
- extern struct Login_Config login_config;
- diff --git a/src/map/atcommand.c b/src/map/atcommand.c
- index 4a78633..131aa67 100644
- --- a/src/map/atcommand.c
- +++ b/src/map/atcommand.c
- @@ -7546,24 +7546,33 @@ static int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
- }
- -ACMD_FUNC(rates)
- -{
- +ACMD_FUNC(rates) {
- char buf[CHAT_SIZE_MAX];
- + int base_exp_rate = 0, job_exp_rate = 0, item_rate = 0;
- nullpo_ret(sd);
- memset(buf, '\0', sizeof(buf));
- +#ifdef VIP_ENABLE
- + // Display EXP and item rate increase for VIP.
- + if( pc_isvip(sd) && ( battle_config.vip_base_exp_increase || battle_config.vip_job_exp_increase || battle_config.vip_drop_increase )) {
- + base_exp_rate += battle_config.vip_base_exp_increase;
- + job_exp_rate += battle_config.vip_job_exp_increase;
- + item_rate += battle_config.vip_drop_increase;
- + }
- +#endif
- +
- snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1298), // Experience rates: Base %.2fx / Job %.2fx
- - battle_config.base_exp_rate/100., battle_config.job_exp_rate/100.);
- + (battle_config.base_exp_rate+base_exp_rate)/100., (battle_config.job_exp_rate+job_exp_rate)/100.);
- clif_displaymessage(fd, buf);
- snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1299), // Normal Drop Rates: Common %.2fx / Healing %.2fx / Usable %.2fx / Equipment %.2fx / Card %.2fx
- - battle_config.item_rate_common/100., battle_config.item_rate_heal/100., battle_config.item_rate_use/100., battle_config.item_rate_equip/100., battle_config.item_rate_card/100.);
- + (battle_config.item_rate_common+item_rate)/100., (battle_config.item_rate_heal+item_rate)/100., (battle_config.item_rate_use+item_rate)/100., (battle_config.item_rate_equip+item_rate)/100., (battle_config.item_rate_card+item_rate)/100.);
- clif_displaymessage(fd, buf);
- snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1300), // Boss Drop Rates: Common %.2fx / Healing %.2fx / Usable %.2fx / Equipment %.2fx / Card %.2fx
- - battle_config.item_rate_common_boss/100., battle_config.item_rate_heal_boss/100., battle_config.item_rate_use_boss/100., battle_config.item_rate_equip_boss/100., battle_config.item_rate_card_boss/100.);
- + (battle_config.item_rate_common_boss+item_rate)/100., (battle_config.item_rate_heal_boss+item_rate)/100., (battle_config.item_rate_use_boss+item_rate)/100., (battle_config.item_rate_equip_boss+item_rate)/100., (battle_config.item_rate_card_boss+item_rate)/100.);
- clif_displaymessage(fd, buf);
- snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1301), // Other Drop Rates: MvP %.2fx / Card-Based %.2fx / Treasure %.2fx
- - battle_config.item_rate_mvp/100., battle_config.item_rate_adddrop/100., battle_config.item_rate_treasure/100.);
- + (battle_config.item_rate_mvp+item_rate)/100., (battle_config.item_rate_adddrop+item_rate)/100., (battle_config.item_rate_treasure+item_rate)/100.);
- clif_displaymessage(fd, buf);
- return 0;
- @@ -8295,7 +8304,7 @@ static int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
- {
- location = "storage";
- items = sd->status.storage.items;
- - size = MAX_STORAGE;
- + size = sd->storage_size;
- }
- else
- if( strcmp(command+1, "cartlist") == 0 )
- @@ -9181,6 +9190,68 @@ static inline void atcmd_channel_help(struct map_session_data *sd, const char *c
- return -1;
- }
- +#ifdef VIP_ENABLE
- +ACMD_FUNC(vip) {
- + struct map_session_data *pl_sd = NULL;
- + char * modif_p;
- + int viptime = 0;
- + nullpo_retr(-1, sd);
- +
- + if (!message || !*message || sscanf(message, "%255s %23[^\n]",atcmd_output,atcmd_player_name) < 2) {
- + clif_displaymessage(fd, msg_txt(sd,700)); //Usage: @vip <time> <character name>
- + return -1;
- + }
- +
- + atcmd_output[sizeof(atcmd_output)-1] = '\0';
- +
- + modif_p = atcmd_output;
- + viptime = (int)solve_time(modif_p)/60; // Change to minutes
- + if(viptime==0) {
- + clif_displaymessage(fd, msg_txt(sd,701)); // Invalid time for vip command.
- + clif_displaymessage(fd, msg_txt(sd,702)); // Time parameter format is +/-<value> to alter. y/a = Year, m = Month, d/j = Day, h = Hour, n/mn = Minute, s = Second.
- + return -1;
- + }
- +
- + if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
- + clif_displaymessage(fd, msg_txt(sd,3)); // Character not found.
- + return -1;
- + }
- +
- + if (pc_get_group_level(pl_sd) > pc_get_group_level(sd)) {
- + clif_displaymessage(fd, msg_txt(sd,81)); // Your GM level don't authorise you to do this action on this player.
- + return -1;
- + }
- +
- + if(pc_isvip(pl_sd) && pl_sd->vip.time){ //Update the player's VIP time
- + pl_sd->vip.time += viptime;
- + if (pl_sd->vip.time <= 0) {
- + pl_sd->vip.time = 0;
- + pl_sd->vip.enabled = 0;
- + clif_displaymessage(pl_sd->fd, msg_txt(sd,703)); // GM has removed your VIP time.
- + clif_displaymessage(fd, msg_txt(sd,704)); // Player is no longer VIP.
- + chrif_req_vipActive(pl_sd, viptime, 3);
- + } else {
- + int year,month,day,hour,minute,second;
- + char timestr[128];
- + split_time(pl_sd->vip.time*60,&year,&month,&day,&hour,&minute,&second);
- + sprintf(atcmd_output,msg_txt(sd,704),msg_txt(sd,705),year,month,day,hour,minute); //%s is VIP for %d years, %d months, %d days, %d hours and %d minutes.
- + clif_displaymessage(pl_sd->fd, atcmd_output);
- + sprintf(atcmd_output,msg_txt(sd,705),msg_txt(sd,706),year,month,day,hour,minute); //This player is now VIP for %d years, %d months, %d days, %d hours and %d minutes.
- + clif_displaymessage(fd, atcmd_output);
- + time2str(timestr,"%Y-%m-%d %H:%M",pl_sd->vip.time*60);
- + sprintf(atcmd_output,"%s : %s",msg_txt(sd,707),timestr); //You are VIP until :
- + clif_displaymessage(pl_sd->fd, atcmd_output);
- + clif_displaymessage(fd, atcmd_output);
- + }
- + } else {
- + clif_displaymessage(fd, msg_txt(sd,704));
- + return -1;
- + }
- +
- + return 0;
- +}
- +#endif
- +
- #include "../custom/atcommand.inc"
- /**
- @@ -9461,6 +9532,9 @@ void atcommand_basecommands(void) {
- ACMD_DEF(channel),
- ACMD_DEF(fontcolor),
- ACMD_DEF(langtype),
- +#ifdef VIP_ENABLE
- + ACMD_DEF(vip),
- +#endif
- };
- AtCommandInfo* atcommand;
- int i;
- diff --git a/src/map/battle.c b/src/map/battle.c
- index 11ed206..3003551 100644
- --- a/src/map/battle.c
- +++ b/src/map/battle.c
- @@ -7233,6 +7233,18 @@ bool battle_check_range(struct block_list *src, struct block_list *bl, int range
- { "bowling_bash_area", &battle_config.bowling_bash_area, 0, 0, 20, },
- { "drop_rateincrease", &battle_config.drop_rateincrease, 0, 0, 1, },
- { "feature.banking", &battle_config.feature_banking, 1, 0, 1, },
- +#ifdef VIP_ENABLE
- + { "vip_storage_increase", &battle_config.vip_storage_increase, 0, 0, MAX_STORAGE-MIN_STORAGE, },
- + { "vip_base_exp_increase", &battle_config.vip_base_exp_increase, 0, 0, INT_MAX, },
- + { "vip_job_exp_increase", &battle_config.vip_job_exp_increase, 0, 0, INT_MAX, },
- + { "vip_exp_penalty_base_normal", &battle_config.vip_exp_penalty_base_normal, 0, 0, INT_MAX, },
- + { "vip_exp_penalty_job_normal", &battle_config.vip_exp_penalty_job_normal, 0, 0, INT_MAX, },
- + { "vip_exp_penalty_base", &battle_config.vip_exp_penalty_base, 0, 0, INT_MAX, },
- + { "vip_exp_penalty_job", &battle_config.vip_exp_penalty_job, 0, 0, INT_MAX, },
- + { "vip_bm_increase", &battle_config.vip_bm_increase, 0, 0, INT_MAX, },
- + { "vip_drop_increase", &battle_config.vip_drop_increase, 0, 0, INT_MAX, },
- + { "vip_gemstone", &battle_config.vip_gemstone, 0, 0, 1, },
- +#endif
- { "mon_trans_disable_in_gvg", &battle_config.mon_trans_disable_in_gvg, 0, 0, 1, },
- { "homunculus_S_growth_level", &battle_config.hom_S_growth_level, 99, 0, MAX_LEVEL, },
- { "emblem_woe_change", &battle_config.emblem_woe_change, 0, 0, 1, },
- diff --git a/src/map/battle.h b/src/map/battle.h
- index a52e373..f0667f3 100644
- --- a/src/map/battle.h
- +++ b/src/map/battle.h
- @@ -496,6 +496,18 @@ extern struct Battle_Config
- int bowling_bash_area;
- int drop_rateincrease;
- int feature_banking;
- +#ifdef VIP_ENABLE
- + int vip_storage_increase;
- + int vip_base_exp_increase;
- + int vip_job_exp_increase;
- + int vip_bm_increase;
- + int vip_drop_increase;
- + int vip_gemstone;
- + int vip_exp_penalty_base_normal;
- + int vip_exp_penalty_base;
- + int vip_exp_penalty_job_normal;
- + int vip_exp_penalty_job;
- +#endif
- int mon_trans_disable_in_gvg;
- int emblem_woe_change;
- int emblem_transparency_limit;
- diff --git a/src/map/chrif.c b/src/map/chrif.c
- index 933b5ce..57e4829 100644
- --- a/src/map/chrif.c
- +++ b/src/map/chrif.c
- @@ -46,7 +46,7 @@
- 11,10,10, 0,11, -1,266,10, // 2b10-2b17: U->2b10, U->2b11, U->2b12, F->2b13, U->2b14, U->2b15, U->2b16, U->2b17
- 2,10, 2,-1,-1,-1, 2, 7, // 2b18-2b1f: U->2b18, U->2b19, U->2b1a, U->2b1b, U->2b1c, U->2b1d, U->2b1e, U->2b1f
- -1,10, 8, 2, 2,14,19,19, // 2b20-2b27: U->2b20, U->2b21, U->2b22, U->2b23, U->2b24, U->2b25, U->2b26, U->2b27
- - 10,10, 6, 0, 0, 6, -1, -1, // 2b28-2b2f: U->2b28, U->2b29, U->2b2a, F->2b2b, F->2b2c, U->2b2d, U->2b2e, U->2b2f
- + 10,10, 6,15,11, 6,-1,-1, // 2b28-2b2f: U->2b28, U->2b29, U->2b2a, U->2b2b, U->2b2c, U->2b2d, U->2b2e, U->2b2f
- };
- //Used Packets:
- @@ -101,8 +101,8 @@
- //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'
- -//2b2b: FREE
- -//2b2c: FREE
- +//2b2b: Incoming, chrif_parse_ack_vipActive -> vip info result
- +//2b2c: Outgoing, chrif_req_vipActive -> request vip info
- //2b2d: Outgoing, chrif_bsdata_request -> request bonus_script for pc_authok'ed char.
- //2b2e: Outgoing, chrif_save_bsdata -> Send bonus_script of player for saving.
- //2b2f: Incoming, chrif_load_bsdata -> received bonus_script of player for loading.
- @@ -1513,6 +1513,49 @@ void chrif_keepalive(int fd) {
- void chrif_keepalive_ack(int fd) {
- session[fd]->flag.ping = 0;/* reset ping state, we received a packet */
- }
- +
- +void chrif_parse_ack_vipActive(int fd) {
- +#ifdef VIP_ENABLE
- + int aid = RFIFOL(char_fd,2);
- + uint32 vip_time = RFIFOL(char_fd,6);
- + bool isvip = RFIFOB(char_fd,10);
- + uint32 groupid = RFIFOL(char_fd,11);
- + TBL_PC *sd = map_id2sd(aid);
- +
- + if (sd && isvip) {
- + sd->vip.enabled = 1;
- + sd->vip.time = vip_time;
- + sd->group_id = groupid;
- + pc_group_pc_load(sd);
- +
- + // Increase storage size for VIP.
- + sd->storage_size = battle_config.vip_storage_increase + MIN_STORAGE;
- + if( sd->storage_size > MAX_STORAGE ) {
- + ShowError("intif_parse_ack_vipActive: Storage size for player %s (%d:%d) is larger than MAX_STORAGE. Storage size has been set to MAX_STORAGE.\n", sd->status.name, sd->status.account_id, sd->status.char_id);
- + sd->storage_size = MAX_STORAGE;
- + }
- + // Magic Stone requirement avoidance for VIP.
- + if( battle_config.vip_gemstone && pc_isvip(sd) )
- + sd->special_state.no_gemstone = 2; //need to be done after status_calc_bl(bl,first);
- + }
- +#endif
- +}
- +
- +int chrif_req_vipActive(TBL_PC *sd, int8 req_duration, int8 type) {
- +#ifdef VIP_ENABLE
- + if (CheckForCharServer() || sd == NULL)
- + return 0;
- +
- + WFIFOHEAD(char_fd,11);
- + WFIFOW(char_fd,0) = 0x2b2c;
- + WFIFOL(char_fd,2) = sd->bl.id; // AID
- + WFIFOB(char_fd,6) = type; // type&1 - SQL SELECT, type&2 - SQL UPDATE
- + WFIFOL(char_fd,7) = req_duration;
- + WFIFOSET(char_fd,11);
- +#endif
- + return 0;
- +}
- +
- /*==========================================
- *
- *------------------------------------------*/
- @@ -1590,6 +1633,7 @@ int chrif_parse(int fd) {
- 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_load_bsdata(fd); break;
- default:
- ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
- diff --git a/src/map/chrif.h b/src/map/chrif.h
- index 70a4a95..c3ec498 100644
- --- a/src/map/chrif.h
- +++ b/src/map/chrif.h
- @@ -67,6 +67,9 @@ int chrif_divorce(int partner_id1, int partner_id2);
- int chrif_removefriend(int char_id, int friend_id);
- int chrif_send_report(char* buf, int len);
- +void chrif_parse_ack_vipActive(int fd);
- +int chrif_req_vipActive(struct map_session_data *sd, int8 req_duration, int8 type);
- +
- int chrif_bsdata_request(int char_id);
- int chrif_save_bsdata(struct map_session_data *sd);
- int chrif_load_bsdata(int fd);
- diff --git a/src/map/clif.c b/src/map/clif.c
- index 00f8658..05e7c97 100644
- --- a/src/map/clif.c
- +++ b/src/map/clif.c
- @@ -9544,7 +9544,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
- clif_updatestatus(sd,SP_JOBEXP);
- clif_updatestatus(sd,SP_NEXTJOBEXP);
- clif_updatestatus(sd,SP_SKILLPOINT);
- - clif_initialstatus(sd);
- + clif_initialstatus(sd);
- +#ifdef VIP_ENABLE
- + if(pc_isvip(sd)) { // Display client information to VIP.
- + clif_vip_display_info(sd); //TODO wtf that should do
- + clif_vip_display_info2(sd);
- + }
- +#endif
- if (sd->sc.option&OPTION_FALCON)
- clif_status_load(&sd->bl, SI_FALCON, 1);
- @@ -16933,6 +16939,49 @@ void clif_update_rankingpoint(struct map_session_data *sd, int rankingtype, int
- #endif
- }
- +/// 0x8cb <packet len>.W <exp>.W <death>.W <drop>.W (ZC_PERSONAL_INFOMATION)
- +/// 0x97b <packet len>.W <exp>.L <death>.L <drop>.L (ZC_PERSONAL_INFOMATION2)
- +void clif_vip_display_info(struct map_session_data *sd) {
- +#ifdef VIP_ENABLE
- + nullpo_retv(sd);
- + sd->fd = (int)sd->fd;
- +
- + WFIFOHEAD(sd->fd,17);
- +
- + if(sd->packet_ver < date2version(20130320))
- + WFIFOW(sd->fd,0) = 0x8cb;
- + else
- + WFIFOW(sd->fd,0) = 0x97b;
- + WFIFOW(sd->fd,2) = 17;
- + WFIFOW(sd->fd,4) = battle_config.base_exp_rate;
- + WFIFOW(sd->fd,6) = battle_config.death_penalty_base;
- + WFIFOW(sd->fd,8) = battle_config.item_rate_common;
- + WFIFOB(sd->fd,10) = 0;
- + WFIFOW(sd->fd,11) = battle_config.vip_base_exp_increase;
- + WFIFOW(sd->fd,13) = battle_config.death_penalty_base*battle_config.vip_exp_penalty_base;
- + WFIFOW(sd->fd,15) = battle_config.vip_drop_increase;
- + WFIFOSET(sd->fd,17);
- +#endif
- +}
- +
- +/// 0981 <packet len>.W <exp>.W <death>.W <drop>.W <activity rate>.W (ZC_PERSONAL_INFOMATION_CHN)
- +void clif_vip_display_info2(struct map_session_data* sd) {
- +#ifdef VIP_ENABLE
- + nullpo_retv(sd);
- + sd->fd = (int)sd->fd;
- +
- + WFIFOHEAD(sd->fd,12);
- + WFIFOW(sd->fd,0) = 0x981;
- + WFIFOW(sd->fd,2) = 12;
- + WFIFOW(sd->fd,4) = battle_config.vip_base_exp_increase;
- + WFIFOW(sd->fd,6) = battle_config.death_penalty_base*battle_config.vip_exp_penalty_base;
- + WFIFOW(sd->fd,8) = battle_config.vip_drop_increase;
- + WFIFOW(sd->fd,10) = 0; // ?
- + WFIFOSET(sd->fd,12);
- +#endif
- +}
- +
- +
- #ifdef DUMP_UNKNOWN_PACKET
- void DumpUnknow(int fd,TBL_PC *sd,int cmd,int packet_len){
- const char* packet_txt = "save/packet.txt";
- diff --git a/src/map/clif.h b/src/map/clif.h
- index 3deedb9..daf13f8 100644
- --- a/src/map/clif.h
- +++ b/src/map/clif.h
- @@ -773,6 +773,9 @@ void clif_search_store_info_click_ack(struct map_session_data* sd, short x, shor
- void clif_cashshop_result( struct map_session_data* sd, uint16 item_id, uint16 result );
- void clif_cashshop_open( struct map_session_data* sd );
- +void clif_vip_display_info(struct map_session_data *sd);
- +void clif_vip_display_info2(struct map_session_data *sd);
- +
- /**
- * 3CeAM
- **/
- diff --git a/src/map/mob.c b/src/map/mob.c
- index 69ed2f8..477eb4d 100644
- --- a/src/map/mob.c
- +++ b/src/map/mob.c
- @@ -2249,13 +2249,25 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
- if (map[m].flag.nobaseexp || !md->db->base_exp)
- base_exp = 0;
- - else
- - base_exp = (unsigned int)cap_value(md->db->base_exp * per * bonus/100. * map[m].adjust.bexp/100., 1, UINT_MAX);
- + else {
- + int vip_bonus=0;
- +#ifdef VIP_ENABLE // Increase base EXP rate for VIP.
- + if( battle_config.vip_base_exp_increase && ( sd && pc_isvip(sd) ) )
- + vip_bonus += battle_config.vip_base_exp_increase;
- +#endif
- + base_exp = (unsigned int)cap_value(md->db->base_exp * per * (bonus+vip_bonus)/100. * map[m].adjust.bexp/100., 1, UINT_MAX);
- + }
- if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost.
- job_exp = 0;
- - else
- - job_exp = (unsigned int)cap_value(md->db->job_exp * per * bonus/100. * map[m].adjust.jexp/100., 1, UINT_MAX);
- + else {
- + int vip_bonus=0;
- +#ifdef VIP_ENABLE // Increase job EXP rate for VIP.
- + if( battle_config.vip_job_exp_increase && ( sd && pc_isvip(sd) ) )
- + vip_bonus += battle_config.vip_job_exp_increase;
- +#endif
- + job_exp = (unsigned int)cap_value(md->db->job_exp * per * (bonus+vip_bonus)/100. * map[m].adjust.jexp/100., 1, UINT_MAX);
- + }
- if ( ( temp = tmpsd[i]->status.party_id)>0 ) {
- int j;
- @@ -2371,6 +2383,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
- // Increase drop rate if user has SC_ITEMBOOST
- if (sd && sd->sc.data[SC_ITEMBOOST]) // now rig the drop rate to never be over 90% unless it is originally >90%.
- drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*(sd->sc.data[SC_ITEMBOOST]->val1)/100.),0,9000));
- +#ifdef VIP_ENABLE // Increase item drop rate for VIP.
- + if( battle_config.vip_drop_increase && ( sd && pc_isvip(sd) ) )
- + drop_rate += (int)(0.5+(drop_rate*battle_config.vip_drop_increase)/10000.);
- + drop_rate = min(drop_rate,10000); //cap it to 100%
- +#endif
- #ifdef RENEWAL_DROP
- if( drop_modifier != 100 ) {
- drop_rate = drop_rate * drop_modifier / 100;
- diff --git a/src/map/pc.c b/src/map/pc.c
- index b7f801c..567a867 100644
- --- a/src/map/pc.c
- +++ b/src/map/pc.c
- @@ -1276,6 +1276,10 @@ int pc_reg_received(struct map_session_data *sd)
- chrif_skillcooldown_request(sd->status.account_id, sd->status.char_id);
- chrif_bankdata_request(sd->status.account_id, sd->status.char_id);
- chrif_bsdata_request(sd->status.char_id);
- + sd->storage_size = MIN_STORAGE; //default to min
- +#ifdef VIP_ENABLE
- + chrif_req_vipActive(sd, 0, 1); // request VIP informations
- +#endif
- intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
- intif_request_questlog(sd);
- @@ -2489,7 +2493,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
- sd->special_state.no_misc_damage = cap_value(val,0,100);
- break;
- case SP_NO_GEMSTONE:
- - if(sd->state.lr_flag != 2)
- + if(sd->state.lr_flag != 2 && sd->special_state.no_gemstone != 2)
- sd->special_state.no_gemstone = 1;
- break;
- case SP_INTRAVISION: // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG]
- @@ -5877,8 +5881,13 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
- (int)(status_get_lv(src) - sd->status.base_level) >= 20)
- bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]
- - if (sd->sc.data[SC_EXPBOOST])
- - bonus += sd->sc.data[SC_EXPBOOST]->val1;
- + if (sd->sc.data[SC_EXPBOOST]) {
- + bonus += sd->sc.data[SC_EXPBOOST]->val1;
- +#ifdef VIP_ENABLE
- + if( battle_config.vip_bm_increase && pc_isvip(sd) ) // Increase Battle Manual EXP rate for VIP.
- + bonus += ( sd->sc.data[SC_EXPBOOST]->val1 / battle_config.vip_bm_increase );
- +#endif
- + }
- *base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * bonus/100., 1, UINT_MAX);
- @@ -6928,37 +6937,38 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
- && !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
- && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE])
- {
- - unsigned int base_penalty =0;
- - if (battle_config.death_penalty_base > 0) {
- + unsigned int base_penalty = battle_config.death_penalty_base, job_penalty = battle_config.death_penalty_job;
- +#ifdef VIP_ENABLE
- + if(pc_isvip(sd)){
- + base_penalty = base_penalty*battle_config.vip_exp_penalty_base;
- + job_penalty = job_penalty*battle_config.vip_exp_penalty_job;
- + }
- + else {
- + base_penalty = base_penalty*battle_config.vip_exp_penalty_base_normal;
- + job_penalty = job_penalty*battle_config.vip_exp_penalty_job_normal;
- + }
- +#endif
- + if (base_penalty > 0) {
- switch (battle_config.death_penalty_type) {
- - case 1:
- - base_penalty = (unsigned int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
- - break;
- - case 2:
- - base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
- - break;
- + case 1: base_penalty = (uint32) ((double)(pc_nextbaseexp(sd) * base_penalty)/10000); break;
- + case 2: base_penalty = (uint32) ((double)(sd->status.base_exp * base_penalty)/10000); break;
- }
- - if(base_penalty) {
- + if (base_penalty > 0){ //recheck after altering to speedup
- if (battle_config.pk_mode && src && src->type==BL_PC)
- base_penalty*=2;
- sd->status.base_exp -= min(sd->status.base_exp, base_penalty);
- clif_updatestatus(sd,SP_BASEEXP);
- }
- }
- - if(battle_config.death_penalty_job > 0) {
- - base_penalty = 0;
- + if(job_penalty > 0) {
- switch (battle_config.death_penalty_type) {
- - case 1:
- - base_penalty = (unsigned int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
- - break;
- - case 2:
- - base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
- - break;
- + case 1: job_penalty = (uint32) ((double)(pc_nextjobexp(sd) * job_penalty)/10000); break;
- + case 2: job_penalty = (uint32) ((double)(sd->status.job_exp * job_penalty)/10000); break;
- }
- - if(base_penalty) {
- + if(job_penalty) {
- if (battle_config.pk_mode && src && src->type==BL_PC)
- - base_penalty*=2;
- - sd->status.job_exp -= min(sd->status.job_exp, base_penalty);
- + job_penalty*=2;
- + sd->status.job_exp -= min(sd->status.job_exp, job_penalty);
- clif_updatestatus(sd,SP_JOBEXP);
- }
- }
- @@ -9087,7 +9097,7 @@ int pc_check_available_item(struct map_session_data *sd) {
- }
- if( battle_config.item_check&4 ) { // Check for invalid(ated) items in storage.
- - for( i = 0; i < MAX_STORAGE; i++ ) {
- + for( i = 0; i < sd->storage_size; i++ ) {
- it = sd->status.storage.items[i].nameid;
- if( it && !itemdb_available(it) ) {
- diff --git a/src/map/pc.h b/src/map/pc.h
- index 6e2693e..b602a3d 100644
- --- a/src/map/pc.h
- +++ b/src/map/pc.h
- @@ -201,7 +201,7 @@ struct map_session_data {
- unsigned int no_castcancel : 1;
- unsigned int no_castcancel2 : 1;
- unsigned int no_sizefix : 1;
- - unsigned int no_gemstone : 1;
- + unsigned int no_gemstone : 2;
- unsigned int intravision : 1; // Maya Purple Card effect [DracoRPG]
- unsigned int perfect_hiding : 1; // [Valaris]
- unsigned int no_knockback : 1;
- @@ -213,7 +213,7 @@ struct map_session_data {
- unsigned int permissions;/* group permissions */
- int langtype;
- - int packet_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18
- + uint32 packet_ver; // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18
- struct mmo_charstatus status;
- struct registry save_reg;
- @@ -550,6 +550,15 @@ struct map_session_data {
- uint8 count; //Count of target for skill like RL_D_TAIL
- } c_marker;
- bool flicker;
- +
- + // Holds player storage size (VIP system).
- + int storage_size;
- +#ifdef VIP_ENABLE
- + struct {
- + unsigned int enabled;
- + unsigned int time;
- + } vip;
- +#endif
- //Timed bonus 'bonus_script' struct [Cydh]
- struct s_script {
- @@ -562,6 +571,7 @@ struct map_session_data {
- } bonus_script[MAX_PC_BONUS_SCRIPT];
- };
- +
- enum weapon_type {
- W_FIST, //Bare hands
- W_DAGGER, //1
- @@ -683,7 +693,9 @@ struct {
- #define pc_ishiding(sd) ( (sd)->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) )
- #define pc_iscloaking(sd) ( !((sd)->sc.option&OPTION_CHASEWALK) && ((sd)->sc.option&OPTION_CLOAK) )
- #define pc_ischasewalk(sd) ( (sd)->sc.option&OPTION_CHASEWALK )
- -
- +#ifdef VIP_ENABLE
- + #define pc_isvip(sd) ( sd->vip.enabled ? 1 : 0 )
- +#endif
- #ifdef NEW_CARTS
- #define pc_iscarton(sd) ( (sd)->sc.data[SC_PUSH_CART] )
- #else
- diff --git a/src/map/script.c b/src/map/script.c
- index f05dda5..5defc72 100644
- --- a/src/map/script.c
- +++ b/src/map/script.c
- @@ -18010,6 +18010,7 @@ static int atcommand_cleanfloor_sub(struct block_list *bl, va_list ap)
- case 7: script_pushint(st,MAX_GUILDLEVEL); break;
- case 8: script_pushint(st,MAX_GUILD_STORAGE); break;
- case 9: script_pushint(st,MAX_BG_MEMBERS); break;
- + case 10: script_pushint(st,VIP_SCRIPT); break;
- default:
- ShowWarning("buildin_getserverdef: unknown type %d.\n", type);
- script_pushint(st,0);
- @@ -18018,6 +18019,76 @@ static int atcommand_cleanfloor_sub(struct block_list *bl, va_list ap)
- return 0;
- }
- +#ifdef VIP_ENABLE
- +/* Returns various information about a player's VIP status.
- + * vip_status <type>,{"<character name>"};
- + * Note: VIP System needs to be enabled.
- + */
- +BUILDIN_FUNC(vip_status) {
- + TBL_PC *sd;
- + char *vip_str = (char *)aMalloc(24*sizeof(char));
- + time_t now = time(NULL);
- + int type = script_getnum(st, 2);
- +
- + if( script_hasdata(st, 3) )
- + sd = map_nick2sd(script_getstr(st, 3));
- + else
- + sd = script_rid2sd(st);
- +
- + if( sd == NULL )
- + return 0;
- +
- + switch(type) {
- + case 0: // Get VIP status.
- + script_pushint(st, pc_isvip(sd));
- + break;
- + case 1: // Get VIP expire date.
- + if( pc_isvip(sd) ) {
- + time_t viptime= (time_t)sd->vip.time;
- + strftime(vip_str, 24, "%Y-%m-%d %H:%M", localtime(&viptime));
- + vip_str[24]='\0';
- + script_pushstr(st, vip_str);
- + } else
- + script_pushint(st, 0);
- + break;
- + case 2: // Get remaining time.
- + if( pc_isvip(sd) ) {
- + time_t viptime= (time_t)sd->vip.time;
- + strftime(vip_str, 24, "%Y-%m-%d %H:%M", localtime(&viptime - now));
- + vip_str[24]='\0';
- + script_pushstr(st, vip_str);
- + } else
- + script_pushint(st, 0);
- + break;
- + }
- + return 0;
- +}
- +
- +
- +/* Adds or removes VIP time in minutes.
- + * vip_time <time>,{"<character name>"};
- + * If time < 0 remove time, else add time.
- + * Note: VIP System needs to be enabled.
- + */
- +BUILDIN_FUNC(vip_time) {
- + TBL_PC *sd;
- + int time = script_getnum(st, 2) * 60; // Convert since it's given in minutes.
- +
- + if( script_hasdata(st, 3) )
- + sd = map_nick2sd(script_getstr(st, 3));
- + else
- + sd = script_rid2sd(st);
- +
- + if( sd == NULL )
- + return 0;
- +
- + if( pc_isvip(sd) )
- + chrif_req_vipActive(sd, time, 2);
- +
- + return 0;
- +}
- +#endif
- +
- /*==========================================
- * Turns a player into a monster and grants SC attribute effect. [malufett/Hercules]
- * montransform <monster name/ID>, <duration>, <sc type>, <val1>, <val2>, <val3>, <val4>;
- @@ -18636,6 +18707,10 @@ struct script_function buildin_func[] = {
- BUILDIN_DEF(is_clientver,"ii?"),
- BUILDIN_DEF(getserverdef,"i"),
- BUILDIN_DEF2(montransform, "transform", "vii????"), // Monster Transform [malufett/Hercules]
- +#ifdef VIP_ENABLE
- + BUILDIN_DEF(vip_status,"i?"),
- + BUILDIN_DEF(vip_time,"i?"),
- +#endif
- BUILDIN_DEF(bonus_script,"si???"),
- #include "../custom/script_def.inc"
- diff --git a/src/map/skill.c b/src/map/skill.c
- index f7c8ea0..4497292 100644
- --- a/src/map/skill.c
- +++ b/src/map/skill.c
- @@ -13712,7 +13712,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
- * Warlock
- **/
- case WL_COMET:
- - if( skill_check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0
- + if( skill_check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0 && require.itemid[0]
- && sd->special_state.no_gemstone == 0
- && ((i = pc_search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0]) ) {
- //clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]);
- @@ -14448,11 +14448,11 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
- continue;
- break;
- case AB_ADORAMUS:
- - if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2) )
- + if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && ( sd->special_state.no_gemstone==2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2)) )
- continue;
- break;
- case WL_COMET:
- - if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0) )
- + if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && ( sd->special_state.no_gemstone==2 || skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0)) )
- continue;
- break;
- case GN_FIRE_EXPANSION:
- @@ -14475,21 +14475,25 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
- req.itemid[i] = skill_db[idx].require.itemid[i];
- req.amount[i] = skill_db[idx].require.amount[i];
- - if( itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN )
- - {
- - if( sd->special_state.no_gemstone )
- - { // All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
- - if( skill_id != SA_ABRACADABRA )
- - req.itemid[i] = req.amount[i] = 0;
- - else if( --req.amount[i] < 1 )
- - req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
- - }
- - if(sc && sc->data[SC_INTOABYSS])
- - {
- - if( skill_id != SA_ABRACADABRA )
- - req.itemid[i] = req.amount[i] = 0;
- - else if( --req.amount[i] < 1 )
- - req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
- + //check requirement for gemstone
- + if( itemid_isgemstone(req.itemid[i])){
- + if( sd->special_state.no_gemstone == 2 ) // Remove all Magic Stone required for all skills for VIP.
- + req.itemid[i] = req.amount[i] = 0;
- + else {
- + if( sd->special_state.no_gemstone )
- + { // All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
- + if( skill_id != SA_ABRACADABRA )
- + req.itemid[i] = req.amount[i] = 0;
- + else if( --req.amount[i] < 1 )
- + req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
- + }
- + if(sc && sc->data[SC_INTOABYSS])
- + {
- + if( skill_id != SA_ABRACADABRA )
- + req.itemid[i] = req.amount[i] = 0;
- + else if( --req.amount[i] < 1 )
- + req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
- + }
- }
- }
- if( skill_id >= HT_SKIDTRAP && skill_id <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0){
- diff --git a/src/map/status.c b/src/map/status.c
- index 48925e5..696729d 100644
- --- a/src/map/status.c
- +++ b/src/map/status.c
- @@ -2636,10 +2636,10 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
- wa->atk2 = refine_info[wlv].bonus[r-1] / 100;
- #ifdef RENEWAL
- - wa->matk += sd->inventory_data[index]->matk;
- - wa->wlv = wlv;
- - if( r ) // Renewal magic attack refine bonus
- - wa->matk += refine_info[wlv].bonus[r-1] / 100;
- + wa->matk += sd->inventory_data[index]->matk;
- + wa->wlv = wlv;
- + if( r ) // renewal magic attack refine bonus
- + wa->matk += refine_info[wlv].bonus[r-1] / 100;
- #endif
- // Overrefine bonus.
- @@ -4057,12 +4057,12 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
- unit_stop_walking(bl,1);
- }
- - /**
- + /*
- * No status changes alter these yet.
- * if(flag&SCB_SIZE)
- * if(flag&SCB_RACE)
- * if(flag&SCB_RANGE)
- - **/
- + */
- if(flag&SCB_MAXHP) {
- if( bl->type&BL_PC ) {
- @@ -4105,10 +4105,10 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
- status->matk_min = status_base_matk_min(status) + (sd?sd->bonus.ematk:0);
- status->matk_max = status_base_matk_max(status) + (sd?sd->bonus.ematk:0);
- #else
- - /**
- + /*
- * RE MATK Formula (from irowiki:http:// irowiki.org/wiki/MATK)
- * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
- - **/
- + */
- status->matk_min = status->matk_max = status_base_matk(status, status_get_lv(bl));
- if( bl->type&BL_PC ) {
- int wMatk = 0;
- @@ -4984,7 +4984,7 @@ static unsigned short status_calc_ematk(struct block_list *bl, struct status_cha
- matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; // 70 lvl1, 100lvl2
- if(sc->data[SC_IZAYOI])
- matk += 50 * sc->data[SC_IZAYOI]->val1;
- - return (unsigned short)cap_value(matk,0,USHRT_MAX);
- + return (unsigned short)cap_value(matk,0,USHRT_MAX);
- }
- #endif
- /**
- diff --git a/src/map/storage.c b/src/map/storage.c
- index 72a8b3f..cf4b65f 100644
- --- a/src/map/storage.c
- +++ b/src/map/storage.c
- @@ -107,7 +107,7 @@ int storage_storageopen(struct map_session_data *sd)
- sd->state.storage_flag = 1;
- storage_sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- clif_storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
- - clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
- + clif_updatestorageamount(sd, sd->status.storage.storage_amount, sd->storage_size);
- return 0;
- }
- @@ -162,7 +162,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
- if( itemdb_isstackable2(data) )
- {//Stackable
- - for( i = 0; i < MAX_STORAGE; i++ )
- + for( i = 0; i < sd->storage_size; i++ )
- {
- if( compare_item(&stor->items[i], item_data) )
- {// existing items found, stack them
- @@ -176,8 +176,8 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
- }
- // find free slot
- - ARR_FIND( 0, MAX_STORAGE, i, stor->items[i].nameid == 0 );
- - if( i >= MAX_STORAGE )
- + ARR_FIND( 0, sd->storage_size, i, stor->items[i].nameid == 0 );
- + if( i >= sd->storage_size )
- return 1;
- // add item to slot
- @@ -185,7 +185,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
- stor->storage_amount++;
- stor->items[i].amount = amount;
- clif_storageitemadded(sd,&stor->items[i],i,amount);
- - clif_updatestorageamount(sd, stor->storage_amount, MAX_STORAGE);
- + clif_updatestorageamount(sd, stor->storage_amount, sd->storage_size);
- return 0;
- }
- @@ -203,7 +203,7 @@ int storage_delitem(struct map_session_data* sd, int n, int amount)
- {
- memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
- sd->status.storage.storage_amount--;
- - if( sd->state.storage_flag == 1 ) clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
- + if( sd->state.storage_flag == 1 ) clif_updatestorageamount(sd, sd->status.storage.storage_amount, sd->storage_size);
- }
- if( sd->state.storage_flag == 1 ) clif_storageitemremoved(sd,n,amount);
- return 0;
- @@ -220,7 +220,7 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount)
- {
- nullpo_ret(sd);
- - if( sd->status.storage.storage_amount > MAX_STORAGE )
- + if( sd->status.storage.storage_amount > sd->storage_size )
- return 0; // storage full
- if( index < 0 || index >= MAX_INVENTORY )
- @@ -253,7 +253,7 @@ int storage_storageget(struct map_session_data* sd, int index, int amount)
- {
- int flag;
- - if( index < 0 || index >= MAX_STORAGE )
- + if( index < 0 || index >= sd->storage_size )
- return 0;
- if( sd->status.storage.items[index].nameid <= 0 )
- @@ -281,11 +281,11 @@ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amoun
- {
- nullpo_ret(sd);
- - if( sd->status.storage.storage_amount > MAX_STORAGE )
- - return 0; // storage full / storage closed
- + if( sd->status.storage.storage_amount > sd->storage_size )
- + return 0; // storage full / storage closed
- if( index < 0 || index >= MAX_CART )
- - return 0;
- + return 0;
- if( sd->status.cart[index].nameid <= 0 )
- return 0; //No item there.
- @@ -311,7 +311,7 @@ int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
- short flag;
- nullpo_ret(sd);
- - if( index < 0 || index >= MAX_STORAGE )
- + if( index < 0 || index >= sd->storage_size )
- return 0;
- if( sd->status.storage.items[index].nameid <= 0 )
- diff --git a/src/map/unit.c b/src/map/unit.c
- index bd17ad1..589ffc3 100644
- --- a/src/map/unit.c
- +++ b/src/map/unit.c
- @@ -2191,7 +2191,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
- return 0;
- if (sd && (sd->special_state.no_castcancel2 ||
- - ((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground))) // fixed flags being read the wrong way around [blackhole89]
- + ((sd->sc.data[SC_UNLIMITEDHUMMINGVOICE] || sd->special_state.no_castcancel) && !map_flag_gvg(bl->m) && !map[bl->m].flag.battleground))) // fixed flags being read the wrong way around [blackhole89]
- return 0;
- }
- diff --git a/vcproj-10/char-server_sql.vcxproj b/vcproj-10/char-server_sql.vcxproj
- index abed05b..36f94fc 100644
- --- a/vcproj-10/char-server_sql.vcxproj
- +++ b/vcproj-10/char-server_sql.vcxproj
- @@ -138,6 +138,7 @@
- <ClInclude Include="..\3rdparty\libconfig\wincompat.h" />
- <ClInclude Include="..\3rdparty\mt19937ar\mt19937ar.h" />
- <ClInclude Include="..\src\common\cbasetypes.h" />
- + <ClInclude Include="..\src\common\conf.h" />
- <ClInclude Include="..\src\common\core.h" />
- <ClInclude Include="..\src\common\db.h" />
- <ClInclude Include="..\src\common\ers.h" />
- @@ -179,6 +180,7 @@
- <ClCompile Include="..\3rdparty\libconfig\scanner.c" />
- <ClCompile Include="..\3rdparty\libconfig\strbuf.c" />
- <ClCompile Include="..\3rdparty\mt19937ar\mt19937ar.c" />
- + <ClCompile Include="..\src\common\conf.c" />
- <ClCompile Include="..\src\common\core.c" />
- <ClCompile Include="..\src\common\db.c" />
- <ClCompile Include="..\src\common\ers.c" />
- @@ -214,4 +216,4 @@
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
- -</Project>
- \ No newline at end of file
- +</Project>
- diff --git a/vcproj-10/char-server_sql.vcxproj.filters b/vcproj-10/char-server_sql.vcxproj.filters
- index 06f69e3..7dee36f 100644
- --- a/vcproj-10/char-server_sql.vcxproj.filters
- +++ b/vcproj-10/char-server_sql.vcxproj.filters
- @@ -106,6 +106,11 @@
- <ClCompile Include="..\src\common\raconf.c">
- <Filter>common</Filter>
- </ClCompile>
- + <ClCompile Include="..\src\common\msg_conf.c" />
- + <ClCompile Include="..\src\common\cli.c" />
- + <ClCompile Include="..\src\common\conf.c">
- + <Filter>common</Filter>
- + </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\src\common\cbasetypes.h">
- @@ -228,6 +233,11 @@
- <ClInclude Include="..\src\common\raconf.h">
- <Filter>common</Filter>
- </ClInclude>
- + <ClInclude Include="..\src\common\msg_conf.h" />
- + <ClInclude Include="..\src\common\cli.h" />
- + <ClInclude Include="..\src\common\conf.h">
- + <Filter>common</Filter>
- + </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <Filter Include="common">
- @@ -246,4 +256,4 @@
- <UniqueIdentifier>{9e8badd7-548f-4eb4-9e87-613e87e772ff}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- -</Project>
- \ No newline at end of file
- +</Project>
- diff --git a/vcproj-10/login-server_sql.vcxproj b/vcproj-10/login-server_sql.vcxproj
- index 0315ac3..e0d9f92 100644
- --- a/vcproj-10/login-server_sql.vcxproj
- +++ b/vcproj-10/login-server_sql.vcxproj
- @@ -138,6 +138,7 @@
- <ClInclude Include="..\3rdparty\libconfig\scanner.h" />
- <ClInclude Include="..\3rdparty\libconfig\strbuf.h" />
- <ClInclude Include="..\3rdparty\libconfig\wincompat.h" />
- + <ClInclude Include="..\src\common\conf.h" />
- <ClInclude Include="..\src\common\mempool.h" />
- <ClInclude Include="..\src\common\mutex.h" />
- <ClInclude Include="..\src\common\raconf.h" />
- @@ -172,6 +173,7 @@
- <ClCompile Include="..\3rdparty\libconfig\scanctx.c" />
- <ClCompile Include="..\3rdparty\libconfig\scanner.c" />
- <ClCompile Include="..\3rdparty\libconfig\strbuf.c" />
- + <ClCompile Include="..\src\common\conf.c" />
- <ClCompile Include="..\src\common\mempool.c" />
- <ClCompile Include="..\src\common\mutex.c" />
- <ClCompile Include="..\src\common\raconf.c" />
- @@ -200,4 +202,4 @@
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
- -</Project>
- \ No newline at end of file
- +</Project>
- diff --git a/vcproj-10/login-server_sql.vcxproj.filters b/vcproj-10/login-server_sql.vcxproj.filters
- index f4280a0..3b682ce 100644
- --- a/vcproj-10/login-server_sql.vcxproj.filters
- +++ b/vcproj-10/login-server_sql.vcxproj.filters
- @@ -82,6 +82,11 @@
- <ClCompile Include="..\src\common\raconf.c">
- <Filter>common</Filter>
- </ClCompile>
- + <ClCompile Include="..\src\common\msg_conf.c" />
- + <ClCompile Include="..\src\common\cli.c" />
- + <ClCompile Include="..\src\common\conf.c">
- + <Filter>common</Filter>
- + </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\src\login\account.h">
- @@ -180,6 +185,11 @@
- <ClInclude Include="..\src\common\raconf.h">
- <Filter>common</Filter>
- </ClInclude>
- + <ClInclude Include="..\src\common\msg_conf.h" />
- + <ClInclude Include="..\src\common\cli.h" />
- + <ClInclude Include="..\src\common\conf.h">
- + <Filter>common</Filter>
- + </ClInclude>
- </ItemGroup>
- <ItemGroup>
- <Filter Include="common">
- @@ -198,4 +208,4 @@
- <UniqueIdentifier>{779e8145-9bb2-4a88-9149-60586ab0bdd4}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- -</Project>
- \ No newline at end of file
- +</Project>
- diff --git a/vcproj-12/char-server_sql.vcxproj b/vcproj-12/char-server_sql.vcxproj
- index 6cfd004..e76a799 100644
- --- a/vcproj-12/char-server_sql.vcxproj
- +++ b/vcproj-12/char-server_sql.vcxproj
- @@ -142,6 +142,7 @@
- <ClInclude Include="..\3rdparty\mt19937ar\mt19937ar.h" />
- <ClInclude Include="..\src\common\cbasetypes.h" />
- <ClInclude Include="..\src\common\core.h" />
- + <ClInclude Include="..\src\common\conf.h" />
- <ClInclude Include="..\src\common\db.h" />
- <ClInclude Include="..\src\common\ers.h" />
- <ClInclude Include="..\src\common\malloc.h" />
- @@ -183,6 +184,7 @@
- <ClCompile Include="..\3rdparty\libconfig\strbuf.c" />
- <ClCompile Include="..\3rdparty\mt19937ar\mt19937ar.c" />
- <ClCompile Include="..\src\common\core.c" />
- + <ClCompile Include="..\src\common\conf.c" />
- <ClCompile Include="..\src\common\db.c" />
- <ClCompile Include="..\src\common\ers.c" />
- <ClCompile Include="..\src\common\malloc.c" />
- @@ -217,4 +219,4 @@
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
- -</Project>
- \ No newline at end of file
- +</Project>
- diff --git a/vcproj-12/char-server_sql.vcxproj.filters b/vcproj-12/char-server_sql.vcxproj.filters
- index 06f69e3..ba4d82c 100644
- --- a/vcproj-12/char-server_sql.vcxproj.filters
- +++ b/vcproj-12/char-server_sql.vcxproj.filters
- @@ -4,6 +4,9 @@
- <ClCompile Include="..\src\common\core.c">
- <Filter>common</Filter>
- </ClCompile>
- + <ClCompile Include="..\src\common\conf.c">
- + <Filter>common</Filter>
- + </ClCompile>
- <ClCompile Include="..\src\common\db.c">
- <Filter>common</Filter>
- </ClCompile>
- @@ -114,6 +117,9 @@
- <ClInclude Include="..\src\common\core.h">
- <Filter>common</Filter>
- </ClInclude>
- + <ClInclude Include="..\src\common\conf.h">
- + <Filter>common</Filter>
- + </ClInclude>
- <ClInclude Include="..\src\common\db.h">
- <Filter>common</Filter>
- </ClInclude>
- @@ -246,4 +252,4 @@
- <UniqueIdentifier>{9e8badd7-548f-4eb4-9e87-613e87e772ff}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- -</Project>
- \ No newline at end of file
- +</Project>
- diff --git a/vcproj-12/login-server_sql.vcxproj b/vcproj-12/login-server_sql.vcxproj
- index 7a0a298..c4d9c89 100644
- --- a/vcproj-12/login-server_sql.vcxproj
- +++ b/vcproj-12/login-server_sql.vcxproj
- @@ -153,6 +153,7 @@
- <ClInclude Include="..\src\login\loginlog.h" />
- <ClInclude Include="..\src\common\cbasetypes.h" />
- <ClInclude Include="..\src\common\core.h" />
- + <ClInclude Include="..\src\common\conf.h" />
- <ClInclude Include="..\src\common\db.h" />
- <ClInclude Include="..\src\common\ers.h" />
- <ClInclude Include="..\src\common\malloc.h" />
- @@ -185,6 +186,7 @@
- <ClCompile Include="..\src\login\login.c" />
- <ClCompile Include="..\src\login\loginlog_sql.c" />
- <ClCompile Include="..\src\common\core.c" />
- + <ClCompile Include="..\src\common\conf.c" />
- <ClCompile Include="..\src\common\db.c" />
- <ClCompile Include="..\src\common\ers.c" />
- <ClCompile Include="..\src\common\malloc.c" />
- @@ -204,4 +206,4 @@
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
- -</Project>
- \ No newline at end of file
- +</Project>
- diff --git a/vcproj-12/login-server_sql.vcxproj.filters b/vcproj-12/login-server_sql.vcxproj.filters
- index f4280a0..d9ad6fc 100644
- --- a/vcproj-12/login-server_sql.vcxproj.filters
- +++ b/vcproj-12/login-server_sql.vcxproj.filters
- @@ -16,6 +16,9 @@
- <ClCompile Include="..\src\common\core.c">
- <Filter>common</Filter>
- </ClCompile>
- + <ClCompile Include="..\src\common\conf.c">
- + <Filter>common</Filter>
- + </ClCompile>
- <ClCompile Include="..\src\common\db.c">
- <Filter>common</Filter>
- </ClCompile>
- @@ -102,6 +105,9 @@
- <ClInclude Include="..\src\common\core.h">
- <Filter>common</Filter>
- </ClInclude>
- + <ClInclude Include="..\src\common\conf.h">
- + <Filter>common</Filter>
- + </ClInclude>
- <ClInclude Include="..\src\common\db.h">
- <Filter>common</Filter>
- </ClInclude>
- @@ -198,4 +204,4 @@
- <UniqueIdentifier>{779e8145-9bb2-4a88-9149-60586ab0bdd4}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- -</Project>
- \ No newline at end of file
- +</Project>
- diff --git a/vcproj-9/login-server_sql.vcproj b/vcproj-9/login-server_sql.vcproj
- index ed310a6..03d72ef 100644
- --- a/vcproj-9/login-server_sql.vcproj
- +++ b/vcproj-9/login-server_sql.vcproj
- @@ -405,7 +405,7 @@
- <File
- RelativePath="..\src\common\cli.c"
- >
- - </File>
- + </File>
- <File
- RelativePath="..\src\common\msg_conf.h"
- >
- @@ -413,7 +413,7 @@
- <File
- RelativePath="..\src\common\msg_conf.c"
- >
- - </File>
- + </File>
- </Filter>
- <Filter
Add Comment
Please, Sign In to add comment