Lighta

Ra_Vip_sys

Nov 15th, 2013
496
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 88.86 KB | None | 0 0
  1. diff --git a/.gitignore b/.gitignore
  2. index 8c735b6..f78af28 100644
  3. --- a/.gitignore
  4. +++ b/.gitignore
  5. @@ -1,3 +1,7 @@
  6. +/autom4te.cache/output.1
  7. +/autom4te.cache/traces.1
  8. +/autom4te.cache/output.1
  9. +/autom4te.cache/traces.1
  10.  /autom4te.cache/output.0
  11.  /autom4te.cache/requests
  12.  /autom4te.cache/traces.0
  13. diff --git a/conf/battle/player.conf b/conf/battle/player.conf
  14. index b587839..ffb4444 100644
  15. --- a/conf/battle/player.conf
  16. +++ b/conf/battle/player.conf
  17. @@ -5,6 +5,8 @@
  18.  //--------------------------------------------------------------
  19.  // Note 1: Value is a config switch (on/off, yes/no or 1/0)
  20.  // Note 2: Value is in percents (100 means 100%)
  21. +// Note 3: Value is a bit field. If no description is given,
  22. +//         assume unit types (1: Pc, 2: Mob, 4: Pet, 8: Homun)
  23.  //--------------------------------------------------------------
  24.  
  25.  // Players' maximum HP rate? (Default is 100)
  26. @@ -141,4 +143,49 @@ idle_no_autoloot: 0
  27.  
  28.  // Minimum distance a vending/chat room must be from a NPC in order to be placed.
  29.  // Default: 3 (0: disabled).
  30. -min_npc_vendchat_distance: 3
  31. \ No newline at end of file
  32. +min_npc_vendchat_distance: 3
  33. +
  34. +
  35. +// Storage slot increase. Setting to 0 will disable.
  36. +// Give more storage slots above the MIN_STORAGE limit.
  37. +// Note: MIN_STORAGE + storage_increase cannot exceed MAX_STORAGE.
  38. +// Default: 300
  39. +vip_storage_increase: 300
  40. +
  41. +// Base EXP rate increase. Setting to 0 will disable. (Note 2)
  42. +// Default: 50
  43. +vip_base_exp_increase: 50
  44. +
  45. +// Exp. penalty rate multiplier for Non-VIP accounts
  46. +// Multiplies the 'death_penalty_base' and 'death_penalty_job' settings in 'conf/battle/exp.conf'.
  47. +// Default: 3 (3*100 = 3% penalty)
  48. +vip_exp_penalty_base_normal: 3
  49. +vip_exp_penalty_job_normal: 3
  50. +
  51. +// Exp. penalty rate multiplier for VIP accounts
  52. +// Multiplies the 'death_penalty_base' and 'death_penalty_job' settings in 'conf/battle/exp.conf'.
  53. +// Default: 1 (1*100 = 1% penalty)
  54. +vip_exp_penalty_base: 1
  55. +vip_exp_penalty_job: 1
  56. +
  57. +// Job EXP rate increase. Setting to 0 will disable. (Note 2)
  58. +// Default: 50
  59. +vip_job_exp_increase: 50
  60. +
  61. +// Battle Manual EXP increase. Setting to 0 will disable.
  62. +// - Regular/Thick Battle Manual: 50+(50/X) = 75%
  63. +// - HE Battle Manual: 100+(100/X) = 150%
  64. +// - Battle Manual x3: 200+(200/X) = 300%
  65. +// Note: X is what the config is set to.
  66. +// Default: 2
  67. +vip_bm_increase: 2
  68. +
  69. +// Item drop increase. Setting to 0 will disable.
  70. +// Note: 50 = 0.5%
  71. +// Default: 50
  72. +vip_drop_increase: 50
  73. +
  74. +// GemStone requirement. Setting to false will disable.
  75. +// Can the VIP Group ignore GemStone requirement for skills?
  76. +// Default: true
  77. +vip_gemstone: true
  78. diff --git a/conf/char_athena.conf b/conf/char_athena.conf
  79. index c05d157..4dc80ca 100644
  80. --- a/conf/char_athena.conf
  81. +++ b/conf/char_athena.conf
  82. @@ -140,11 +140,6 @@ char_name_option: 1
  83.  // Note: Don't add spaces unless you mean to add 'space' to the list.
  84.  char_name_letters: abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
  85.  
  86. -// How many Characters are allowed per Account ? (0 = disabled)
  87. -// You can not exceed the limit of MAX_CHARS slots, defined in mmo.h
  88. -// Doing that, chars_per_account will be default to MAX_CHARS.
  89. -chars_per_account: 0
  90. -
  91.  // Restrict character deletion by BaseLevel
  92.  // 0: no restriction (players can delete characters of any level)
  93.  // -X: you can't delete chars with BaseLevel <= X
  94. diff --git a/conf/groups.conf b/conf/groups.conf
  95. index 63ccdf8..1ff3853 100644
  96. --- a/conf/groups.conf
  97. +++ b/conf/groups.conf
  98. @@ -220,6 +220,19 @@ groups: (
  99.     }
  100.  },
  101.  {
  102. +   id: 5
  103. +   name: "VIP"
  104. +   inherit: ( "Player" ) /* can do everything Players can */
  105. +   level: 0
  106. +   commands: {
  107. +       rates: true
  108. +       who: true
  109. +   }
  110. +   permissions: {
  111. +       /* no permissions by default */
  112. +   }
  113. +},
  114. +{
  115.     id: 10
  116.     name: "Law Enforcement"
  117.     inherit: ( "Support" )
  118. diff --git a/conf/login_athena.conf b/conf/login_athena.conf
  119. index 6a9002b..cc0b0ef 100644
  120. --- a/conf/login_athena.conf
  121. +++ b/conf/login_athena.conf
  122. @@ -73,6 +73,23 @@ group_id_to_connect: -1
  123.  // 0 or more: group id
  124.  min_group_id_to_connect: -1
  125.  
  126. +// Which group (ID) will be denoted as the VIP Group?
  127. +// Default: 5
  128. +vip_group: 5
  129. +
  130. +// How many Characters are allowed per Account ? (0 = disabled)
  131. +// You can not exceed the limit of MAX_CHARS slots, defined in mmo.h
  132. +// Doing that, chars_per_account will be default to MAX_CHARS.
  133. +// If setting to 0 MIN_CHARS value will be used
  134. +chars_per_account: 0
  135. +
  136. +// Max character limit increase. Setting to 0 will disable.
  137. +// Increase MAX_CHAR if you want to increase char_increase.
  138. +// Note: MAX_CHARS - chars_per_account = Amount of VIP Chars (char_increase value in login table).
  139. +// Note2: this setting need to be set after chars_per_account
  140. +// Default: 6
  141. +vip_char_increase: 6
  142. +
  143.  // Starting additional sec from now for the limited time at creation of account
  144.  // -1: new account are created with UNlimited time (default value)
  145.  // 0 or more: new accounts was created by addition of the value (in sec) to the actual time (to set first limited time)
  146. diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf
  147. index 976535f..f281e90 100644
  148. --- a/conf/msg_conf/map_msg.conf
  149. +++ b/conf/msg_conf/map_msg.conf
  150. @@ -693,6 +693,16 @@
  151.  694: Hanbok
  152.  695: Rebellion
  153.  
  154. +// @vip
  155. +700: Usage: @vip <time> <character name>
  156. +701: Invalid time for VIP command.
  157. +702: Time parameter format is +/-<value> to alter. y/a = Year, m = Month, d/j = Day, h = Hour, n/mn = Minute, s = Second.
  158. +703: GM has removed your VIP time.
  159. +704: Player is no longer VIP.
  160. +705: %s is VIP for %d years, %d months, %d days, %d hours and %d minutes.
  161. +706: This player is now VIP for %d years, %d months, %d days, %d hours and %d minutes.
  162. +707: You are VIP until
  163. +//708-899 free
  164.  
  165.  //------------------------------------
  166.  // More atcommands message
  167. diff --git a/sql-files/main.sql b/sql-files/main.sql
  168. index ffa5bbe..bbfe083 100644
  169. --- a/sql-files/main.sql
  170. +++ b/sql-files/main.sql
  171. @@ -460,6 +460,8 @@ CREATE TABLE IF NOT EXISTS `login` (
  172.    `pincode` varchar(4) NOT NULL DEFAULT '',
  173.    `pincode_change` int(11) unsigned NOT NULL DEFAULT '0',
  174.    `bank_vault` int(11) NOT NULL DEFAULT '0',
  175. +  `vip_time` int(11) unsigned NOT NULL default '0',
  176. +  `old_group` tinyint(3) NOT NULL default '0',
  177.    PRIMARY KEY  (`account_id`),
  178.    KEY `name` (`userid`)
  179.  ) ENGINE=MyISAM AUTO_INCREMENT=2000000;
  180. diff --git a/src/char/char.c b/src/char/char.c
  181. index 052a8b2..c0edce3 100644
  182. --- a/src/char/char.c
  183. +++ b/src/char/char.c
  184. @@ -111,7 +111,6 @@ struct mmo_map_server {
  185.  #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]
  186.  char char_name_letters[1024] = ""; // list of letters/symbols allowed (or not) in a character name. by [Yor]
  187.  
  188. -int char_per_account = 0; //Maximum chars per account (default unlimited) [Sirius]
  189.  int char_del_level = 0; //From which level u can delete character [Lupus]
  190.  int char_del_delay = 86400;
  191.  
  192. @@ -133,7 +132,9 @@ struct char_session_data {
  193.     char email[40]; // e-mail (default: a@a.com) by [Yor]
  194.     time_t expiration_time; // # of seconds 1/1/1970 (timestamp): Validity limit of the account (0 = unlimited)
  195.     int group_id; // permission
  196. -   uint8 char_slots;
  197. +   uint8 char_slots; //total char that sd can create
  198. +   uint8 chars_vip;
  199. +   uint8 chars_billing;
  200.     uint32 version;
  201.     uint8 clienttype;
  202.     char new_name[NAME_LENGTH];
  203. @@ -146,6 +147,7 @@ struct char_session_data {
  204.     // Addon system
  205.     int bank_vault;
  206.     unsigned int char_moves[MAX_CHARS]; // character moves left
  207. +   uint8 isvip;
  208.  };
  209.  
  210.  struct startitem {
  211. @@ -183,6 +185,11 @@ struct startitem {
  212.  void pincode_decrypt( uint32 userSeed, char* pin );
  213.  int pincode_compare( int fd, struct char_session_data* sd, char* pin );
  214.  
  215. +int mapif_parse_vipactive(int fd);
  216. +int mapif_vipack(uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid);
  217. +int logif_reqviddata(uint32 aid, uint8 type, uint32 add_vip_time);
  218. +int logif_parse_vipack(int fd);
  219. +
  220.  // Addon system
  221.  bool char_move_enabled = true;
  222.  bool char_movetoused = true;
  223. @@ -1441,8 +1448,6 @@ int mmo_char_sql_init(void)
  224.  {
  225.     char_db_= idb_alloc(DB_OPT_RELEASE_DATA);
  226.  
  227. -   ShowStatus("Characters per Account: '%d'.\n", char_per_account);
  228. -
  229.     //the 'set offline' part is now in check_login_conn ...
  230.     //if the server connects to loginserver
  231.     //it will dc all off players
  232. @@ -1579,11 +1584,12 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag
  233.     if( flag < 0 )
  234.         return flag;
  235.  
  236. +   ShowInfo("make_new_char_sql slot=%d, sd->char_slots=%d \n",slot,sd->char_slots);
  237.     //check other inputs
  238.  #if PACKETVER >= 20120307
  239. -   if(slot >= sd->char_slots)
  240. +   if(slot < 0 || slot >= sd->char_slots)
  241.  #else
  242. -   if((slot >= sd->char_slots) // slots
  243. +   if((slot < 0 || slot >= sd->char_slots) // slots
  244.     || (str + agi + vit + int_ + dex + luk != 6*5 ) // stats
  245.     || (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
  246.     || (str + int_ != 10 || agi + luk != 10 || vit + dex != 10) ) // pairs
  247. @@ -1596,12 +1602,10 @@ int make_new_char_sql(struct char_session_data* sd, char* name_, int str, int ag
  248.  
  249.  
  250.     // check the number of already existing chars in this account
  251. -   if( char_per_account != 0 ) {
  252. -       if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) )
  253. -           Sql_ShowDebug(sql_handle);
  254. -       if( Sql_NumRows(sql_handle) >= char_per_account )
  255. -           return -2; // character account limit exceeded
  256. -   }
  257. +   if( SQL_ERROR == Sql_Query(sql_handle, "SELECT 1 FROM `%s` WHERE `account_id` = '%d'", char_db, sd->account_id) )
  258. +       Sql_ShowDebug(sql_handle);
  259. +   if( Sql_NumRows(sql_handle) >= sd->char_slots )
  260. +       return -2; // character account limit exceeded
  261.  
  262.     // check char slot
  263.     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) )
  264. @@ -1979,7 +1983,11 @@ void char_parse_req_charlist(int fd, struct char_session_data* sd){
  265.  //----------------------------------------
  266.  int mmo_char_send006b(int fd, struct char_session_data* sd){
  267.     int j, offset = 0;
  268. -   bool newvers = (sd->version >= (uint32)date2version(20100413));
  269. +   bool newvers = (sd->version >= date2version(20100413));
  270. +  
  271. +   ShowInfo("mmo_char_send006b, sd.charslot=%d, nbmaxchars=%d, nbpremium=%d, nbbilling=%d, isvip=%d \n",
  272. +       sd->char_slots,MAX_CHARS,sd->chars_vip,sd->chars_billing,sd->isvip);
  273. +  
  274.     if(newvers) //20100413
  275.         offset += 3;
  276.     if (save_log)
  277. @@ -1989,11 +1997,16 @@ int mmo_char_send006b(int fd, struct char_session_data* sd){
  278.     WFIFOHEAD(fd,j + MAX_CHARS*MAX_CHAR_BUF);
  279.     WFIFOW(fd,0) = 0x6b;
  280.     if(newvers){ //20100413
  281. -       WFIFOB(fd,4) = MAX_CHARS; // Max slots.
  282. -       WFIFOB(fd,5) = sd->char_slots; // Available slots. (PremiumStartSlot)
  283. -       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)
  284. -   }
  285. -   memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes
  286. +       WFIFOB(fd,4) = MAX_CHARS; // Max slots. 15
  287. +       WFIFOB(fd,5) = MAX_CHARS-sd->chars_billing-sd->chars_vip; // PremiumStartSlot
  288. +       WFIFOB(fd,6) = MAX_CHARS-sd->chars_billing; // PremiumEndSlot // 9-15
  289. +       /* this+0x7  char dummy1_beginbilling */
  290. +       /* this+0x8  unsigned long code */
  291. +       /* this+0xc  unsigned long time1 */
  292. +       /* this+0x10  unsigned long time2 */
  293. +       /* this+0x14  char dummy2_endbilling[7] */
  294. +   }
  295. +   memset(WFIFOP(fd,4 + offset), 0, 20); // unknown bytes 4-24 7-27
  296.     j+=mmo_chars_fromsql(sd, WFIFOP(fd,j));
  297.     WFIFOW(fd,2) = j; // packet len
  298.     WFIFOSET(fd,j);
  299. @@ -2007,21 +2020,25 @@ int mmo_char_send006b(int fd, struct char_session_data* sd){
  300.  void mmo_char_send082d(int fd, struct char_session_data* sd) {
  301.     if (save_log)
  302.         ShowInfo("Loading Char Data ("CL_BOLD"%d"CL_RESET")\n",sd->account_id);
  303. +  
  304. +   ShowInfo("mmo_char_send082d, sd.charslot=%d, nbmaxchars=%d, nbpremium=%d, nbbilling=%d, isvip=%d\n",
  305. +       sd->char_slots,MAX_CHARS,sd->chars_vip,sd->chars_billing,sd->isvip);
  306. +  
  307.     WFIFOHEAD(fd,29);
  308.     WFIFOW(fd,0) = 0x82d;
  309.     WFIFOW(fd,2) = 29;
  310. -   WFIFOB(fd,4) = sd->char_slots;
  311. -   WFIFOB(fd,5) = MAX_CHARS - sd->char_slots;
  312. -   WFIFOB(fd,6) = MAX_CHARS - sd->char_slots;
  313. -   WFIFOB(fd,7) = sd->char_slots;
  314. -   WFIFOB(fd,8) = sd->char_slots;
  315. +   WFIFOB(fd,4) = sd->char_slots-sd->chars_vip; //NormalSlotNum
  316. +   WFIFOB(fd,5) = sd->chars_vip; //PremiumSlotNum
  317. +   WFIFOB(fd,6) = sd->chars_billing; //BillingSlotNum
  318. +   WFIFOB(fd,7) = sd->char_slots; //ProducibleSlotNum
  319. +   WFIFOB(fd,8) = sd->char_slots; //ValidSlotNum
  320.     memset(WFIFOP(fd,9), 0, 20); // unused bytes
  321.     WFIFOSET(fd,29);
  322.  }
  323.  
  324.  void mmo_char_send(int fd, struct char_session_data* sd){
  325. -   //ShowInfo("sd->version = %d\n",sd->version);
  326. -   if(sd->version > (uint32)date2version(20130000) ){
  327. +   ShowInfo("sd->version = %d\n",sd->version);
  328. +   if(sd->version > date2version(20130000) ){
  329.         mmo_char_send082d(fd,sd);
  330.         char_charlist_notify(fd,sd);
  331.         char_block_character(fd,sd);
  332. @@ -2170,7 +2187,7 @@ int loginif_BankingReq(int32 account_id, int8 type, int32 data){
  333.         WFIFOB(login_fd,6) = type;
  334.         WFIFOL(login_fd,7) = data;
  335.         WFIFOSET(login_fd,11);
  336. -       return 1;
  337. +       return 1;
  338.     }
  339.     return 0;
  340.  }
  341. @@ -2239,6 +2256,76 @@ int mapif_parse_ReqBankInfo(int fd){
  342.     return 1;
  343.  }
  344.  
  345. +/*
  346. + * ZH 0x2b2c
  347. + * HA 0x2742
  348. + * We received an request vip_info from map-server.
  349. + * Transmit it to login-serv as it's the one knowing the info
  350. + */
  351. +int mapif_parse_vipactive(int fd) {
  352. +#ifdef VIP_ENABLE
  353. +   uint32 aid = RFIFOL(fd,2); //aid
  354. +   uint8 type = RFIFOB(fd,6); //type
  355. +   uint32 adddur = RFIFOL(fd,7); //req_inc_duration
  356. +   RFIFOSKIP(fd,11);
  357. +   logif_reqviddata(aid, type, adddur);
  358. +#endif
  359. +   return 0;
  360. +}
  361. +
  362. +/*
  363. + * HZ 0x2b2b
  364. + * Transmist vip data to mapserv
  365. + */
  366. +int mapif_vipack(uint32 aid, uint32 vip_time, uint8 isvip, uint32 groupid){
  367. +#ifdef VIP_ENABLE
  368. +   uint8 buf[16];
  369. +   WBUFW(buf,0) = 0x2b2b;
  370. +   WBUFL(buf,2) = aid;
  371. +   WBUFL(buf,6) = vip_time;
  372. +   WBUFB(buf,10) = isvip;
  373. +   WBUFL(buf,11) = groupid;
  374. +   mapif_sendall(buf,15);  // inform all map-servers attached.
  375. +#endif
  376. +   return 0;
  377. +}
  378. +
  379. +/*
  380. + * HZ 0x2b2b
  381. + * Request to ask vip data from loginserv
  382. + */
  383. +int logif_reqviddata(uint32 aid, uint8 type, uint32 add_vip_time){
  384. +#ifdef VIP_ENABLE
  385. +   WFIFOHEAD(login_fd,11);
  386. +   WFIFOW(login_fd,0) = 0x2742;
  387. +   WFIFOL(login_fd,2) =  aid; //aid
  388. +   WFIFOB(login_fd,6) = type; //type
  389. +   WFIFOL(login_fd,7) =  add_vip_time; //req_inc_duration
  390. +   WFIFOSET(login_fd,11);
  391. +#endif
  392. +   return 0;
  393. +}
  394. +
  395. +/*
  396. + * AH 0x2743
  397. + * We received the info from login-serv, ask to transmit it to map
  398. + */
  399. +int logif_parse_vipack(int fd){
  400. +#ifdef VIP_ENABLE
  401. +   if (RFIFOREST(fd) < 15)
  402. +       return 0;
  403. +   else {
  404. +       uint32 aid = RFIFOL(fd,2); //aid
  405. +       uint32 vip_time = RFIFOL(fd,6); //vip_time
  406. +       uint8 isvip = RFIFOB(fd,10); //isvip
  407. +       uint32 groupid = RFIFOL(fd,11); //new group id
  408. +       RFIFOSKIP(fd,15);
  409. +       mapif_vipack(aid,vip_time,isvip,groupid);
  410. +   }
  411. +#endif
  412. +   return 1;
  413. +}
  414. +
  415.  
  416.  /// Resets all the data.
  417.  void loginif_reset(void)
  418. @@ -2288,31 +2375,30 @@ void loginif_on_ready(void)
  419.  
  420.  int logif_parse_reqpincode(int fd, struct char_session_data *sd){
  421.  #if PACKETVER >=  20110309
  422. -    if( pincode_enabled ){
  423. -            // PIN code system enabled
  424. -            if( strlen( sd->pincode ) <= 0 ){
  425. -                // No PIN code has been set yet
  426. -                if( pincode_force ) pincode_sendstate( fd, sd, PINCODE_NEW );
  427. -                else pincode_sendstate( fd, sd, PINCODE_PASSED );
  428. -            } else {
  429. -                    if( !pincode_changetime || ( sd->pincode_change + pincode_changetime ) > time(NULL) ){
  430. -                            struct online_char_data* node = (struct online_char_data*)idb_get( online_char_db, sd->account_id );
  431. -
  432. -                            if( node != NULL && node->pincode_success ){ // User has already passed the check                    
  433. -                                    pincode_sendstate( fd, sd, PINCODE_PASSED );
  434. -                            }else{
  435. -                                    // Ask user for his PIN code
  436. -                                    pincode_sendstate( fd, sd, PINCODE_ASK );
  437. -                            }
  438. -                    }else{ // User hasnt changed his PIN code too long
  439. -                            pincode_sendstate( fd, sd, PINCODE_EXPIRED );
  440. -                    }
  441. -            }
  442. -    } else { // PIN code system disabled
  443. -            pincode_sendstate( fd, sd, PINCODE_OK );
  444. -    }
  445. +   if( pincode_enabled ){
  446. +       // PIN code system enabled
  447. +       if( strlen( sd->pincode ) <= 0 ){
  448. +           // No PIN code has been set yet
  449. +           if( pincode_force ) pincode_sendstate( fd, sd, PINCODE_NEW );
  450. +           else pincode_sendstate( fd, sd, PINCODE_PASSED );
  451. +       } else {
  452. +           if( !pincode_changetime || ( sd->pincode_change + pincode_changetime ) > time(NULL) ){
  453. +               struct online_char_data* node = (struct online_char_data*)idb_get( online_char_db, sd->account_id );
  454. +               if( node != NULL && node->pincode_success ){ // User has already passed the check                    
  455. +                   pincode_sendstate( fd, sd, PINCODE_PASSED );
  456. +               }else{
  457. +                   // Ask user for his PIN code
  458. +                   pincode_sendstate( fd, sd, PINCODE_ASK );
  459. +               }
  460. +           }else{ // User hasnt changed his PIN code too long
  461. +               pincode_sendstate( fd, sd, PINCODE_EXPIRED );
  462. +           }
  463. +       }
  464. +   } else { // PIN code system disabled
  465. +       pincode_sendstate( fd, sd, PINCODE_OK );
  466. +   }
  467.  #endif
  468. -    return 0;
  469. +   return 0;
  470.  }
  471.  
  472.  int parse_fromlogin(int fd) {
  473. @@ -2352,6 +2438,7 @@ int parse_fromlogin(int fd) {
  474.         switch( command )
  475.         {
  476.         case 0x2741: loginif_parse_BankingAck(fd); break;
  477. +       case 0x2743: logif_parse_vipack(fd); break;
  478.  
  479.         // acknowledgement of connect-to-loginserver request
  480.         case 0x2711:
  481. @@ -2415,7 +2502,7 @@ int parse_fromlogin(int fd) {
  482.         break;
  483.  
  484.         case 0x2717: // account data
  485. -           if (RFIFOREST(fd) < 76)
  486. +           if (RFIFOREST(fd) < 79)
  487.                 return 0;
  488.  
  489.             // find the authenticated session with this account id
  490. @@ -2431,11 +2518,15 @@ int parse_fromlogin(int fd) {
  491.                     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);
  492.                     sd->char_slots = MAX_CHARS;/* cap to maximum */
  493.                 } else if ( !sd->char_slots )/* no value aka 0 in sql */
  494. -                   sd->char_slots = MAX_CHARS;/* cap to maximum */
  495. +                   sd->char_slots = MIN_CHARS;/* cap to minimum */
  496.                 safestrncpy(sd->birthdate, (const char*)RFIFOP(fd,52), sizeof(sd->birthdate));
  497.                 safestrncpy(sd->pincode, (const char*)RFIFOP(fd,63), sizeof(sd->pincode));
  498.                 sd->pincode_change = (time_t)RFIFOL(fd,68);
  499.                 sd->bank_vault = RFIFOL(fd,72);
  500. +               sd->isvip = RFIFOB(fd,76);
  501. +               sd->chars_vip = RFIFOB(fd,77);
  502. +               sd->chars_billing = RFIFOB(fd,78);
  503. +              
  504.                 ARR_FIND( 0, ARRAYLENGTH(server), server_id, server[server_id].fd > 0 && server[server_id].map[0] );
  505.                 // continued from char_auth_ok...
  506.                 if( server_id == ARRAYLENGTH(server) || //server not online, bugreport:2359
  507. @@ -2452,7 +2543,7 @@ int parse_fromlogin(int fd) {
  508.                     logif_parse_reqpincode(i, sd);
  509.                 }
  510.             }
  511. -           RFIFOSKIP(fd,76);
  512. +           RFIFOSKIP(fd,79);
  513.         break;
  514.  
  515.         // login-server alive packet
  516. @@ -2641,7 +2732,7 @@ int parse_fromlogin(int fd) {
  517.             RFIFOSKIP(fd,2);
  518.         }
  519.         break;
  520. -
  521. +      
  522.         default:
  523.             ShowError("Unknown packet 0x%04x received from login-server, disconnecting.\n", command);
  524.             set_eof(fd);
  525. @@ -3680,7 +3771,7 @@ int parse_frommap(int fd)
  526.        
  527.         case 0x2b28: mapif_parse_UpdBankInfo(fd); break;
  528.         case 0x2b2a: mapif_parse_ReqBankInfo(fd); break;
  529. -          
  530. +       case 0x2b2c: mapif_parse_vipactive(fd); break; 
  531.         case 0x2b2d: //Load data
  532.             if (RFIFOREST(fd) < 6)
  533.                 return 0;
  534. @@ -5382,13 +5473,6 @@ int char_config_read(const char* cfgName)
  535.             char_name_option = atoi(w2);
  536.         } else if (strcmpi(w1, "char_name_letters") == 0) {
  537.             safestrncpy(char_name_letters, w2, sizeof(char_name_letters));
  538. -       } else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
  539. -           char_per_account = atoi(w2);
  540. -           if( char_per_account == 0 || char_per_account > MAX_CHARS ) {
  541. -               if( char_per_account > MAX_CHARS )
  542. -                   ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", char_per_account, MAX_CHARS);
  543. -               char_per_account = MAX_CHARS;
  544. -           }
  545.         } else if (strcmpi(w1, "char_del_level") == 0) { //disable/enable char deletion by its level condition [Lupus]
  546.             char_del_level = atoi(w2);
  547.         } else if (strcmpi(w1, "char_del_delay") == 0) {
  548. diff --git a/src/common/mmo.h b/src/common/mmo.h
  549. index 8b184c5..efaa8ba 100644
  550. --- a/src/common/mmo.h
  551. +++ b/src/common/mmo.h
  552. @@ -48,6 +48,7 @@
  553.  
  554.  #ifndef PACKETVER
  555.     #define PACKETVER 20130807
  556. +   //#define PACKETVER 20130320
  557.     //#define PACKETVER 20120410
  558.  #endif
  559.  
  560. @@ -71,7 +72,8 @@
  561.  #define MAX_MAP_PER_SERVER 1500 // Increased to allow creation of Instance Maps
  562.  #define MAX_INVENTORY 100
  563.  //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.
  564. -#define MAX_CHARS 9
  565. +//max value tested was 265
  566. +#define MAX_CHARS 9
  567.  //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]
  568.  //Note: The client seems unable to receive data for more than 4 slots due to all related packets having a fixed size.
  569.  #define MAX_SLOTS 4
  570. @@ -90,7 +92,7 @@
  571.  #define DEFAULT_WALK_SPEED 150
  572.  #define MIN_WALK_SPEED 0
  573.  #define MAX_WALK_SPEED 1000
  574. -#define MAX_STORAGE 600
  575. +#define MAX_STORAGE 600 /// Max number of storage slots the client can support. Used as a cap for the VIP System.
  576.  #define MAX_GUILD_STORAGE 600
  577.  #define MAX_PARTY 12
  578.  #define MAX_GUILD 16+10*6  // increased max guild members +6 per 1 extension levels [Lupus]
  579. diff --git a/src/common/utils.c b/src/common/utils.c
  580. index 9729fcb..cec87f4 100644
  581. --- a/src/common/utils.c
  582. +++ b/src/common/utils.c
  583. @@ -259,7 +259,7 @@ uint32 MakeDWord(uint16 word0, uint16 word1)
  584.         ( (uint32)(word1 << 0x10) );
  585.  }
  586.  
  587. -int date2version(int date){
  588. +uint32 date2version(int date){
  589.     if(date < 20040906) return 5;
  590.     else if(date < 20040920) return 10;
  591.     else if(date < 20041005) return 11;
  592. diff --git a/src/common/utils.h b/src/common/utils.h
  593. index 6ce1639..3fc5634 100644
  594. --- a/src/common/utils.h
  595. +++ b/src/common/utils.h
  596. @@ -29,6 +29,6 @@ extern uint16 GetWord(uint32 val, int idx);
  597.  extern uint16 MakeWord(uint8 byte0, uint8 byte1);
  598.  extern uint32 MakeDWord(uint16 word0, uint16 word1);
  599.  
  600. -int date2version(int date);
  601. +uint32 date2version(int date);
  602.  
  603.  #endif /* _UTILS_H_ */
  604. diff --git a/src/config/core.h b/src/config/core.h
  605. index 66b1ec6..93caad2 100644
  606. --- a/src/config/core.h
  607. +++ b/src/config/core.h
  608. @@ -72,6 +72,24 @@
  609.  /// Comment to disable the job HP/SP tables and use formulas instead
  610.  #define HP_SP_TABLES
  611.  
  612. +/// Uncomment to disable vip system.
  613. +//#define VIP_ENABLE
  614. +#ifdef VIP_ENABLE
  615. +   #define MIN_STORAGE 300 // Default number of storage slots.
  616. +   #define MIN_CHARS 3 // Default number of characters per account.
  617. +   #define MAX_CHAR_VIP 6 //this must be below MAX_CHARS
  618. +   #define MAX_CHAR_BILLING 0 //this must be below MAX_CHARS
  619. +#else
  620. +   #define MIN_STORAGE 600 //if sys disable the min = max for storage slot
  621. +   #define MIN_CHARS 9 // Default number of characters per account.
  622. +   #define MAX_CHAR_BILLING 0
  623. +   #define MAX_CHAR_VIP 0
  624. +#endif
  625. +#if (MIN_CHARS+MAX_CHAR_VIP+MAX_CHAR_BILLING)>MAX_CHARS
  626. +   #error "Config of MAX_CHARS is invalid"
  627. +#endif
  628. +#define VIP_SCRIPT 0 //enable or disable scripts (require vip_enable)
  629. +
  630.  /**
  631.   * No settings past this point
  632.   **/
  633. diff --git a/src/login/account.h b/src/login/account.h
  634. index 3d7acef..9121c58 100644
  635. --- a/src/login/account.h
  636. +++ b/src/login/account.h
  637. @@ -34,8 +34,7 @@ AccountDB* ACCOUNTDB_CONSTRUCTOR(ACCOUNTDB_ENGINE_4)(void);
  638.  #endif
  639.  
  640.  
  641. -struct mmo_account
  642. -{
  643. +struct mmo_account {
  644.     int account_id;
  645.     char userid[NAME_LENGTH];
  646.     char pass[32+1];        // 23+1 for plaintext, 32+1 for md5-ed passwords
  647. @@ -54,6 +53,10 @@ struct mmo_account
  648.     time_t pincode_change;  // (timestamp): last time of pincode change
  649.     int account_reg2_num;
  650.     int bank_vault;
  651. +#ifdef VIP_ENABLE
  652. +   int old_group;
  653. +   int vip_time;
  654. +#endif
  655.     struct global_reg account_reg2[ACCOUNT_REG2_NUM]; // account script variables (stored on login server)
  656.  };
  657.  
  658. diff --git a/src/login/account_sql.c b/src/login/account_sql.c
  659. index 3478870..bc28b05 100644
  660. --- a/src/login/account_sql.c
  661. +++ b/src/login/account_sql.c
  662. @@ -7,6 +7,7 @@
  663.  #include "../common/sql.h"
  664.  #include "../common/strlib.h"
  665.  #include "../common/timer.h"
  666. +#include "../config/core.h"
  667.  #include "account.h"
  668.  #include <stdlib.h>
  669.  #include <string.h>
  670. @@ -522,7 +523,11 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
  671.  
  672.     // retrieve login entry for the specified account
  673.     if( SQL_ERROR == Sql_Query(sql_handle,
  674. -       "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",
  675. +#ifdef VIP_ENABLE //FIXME query is only for mysql
  676. +       "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",
  677. +#else
  678. +       "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",
  679. +#endif
  680.         db->account_db, account_id )
  681.     ) {
  682.         Sql_ShowDebug(sql_handle);
  683. @@ -552,10 +557,14 @@ static bool mmo_auth_fromsql(AccountDB_SQL* db, struct mmo_account* acc, int acc
  684.     Sql_GetData(sql_handle, 14, &data, NULL); safestrncpy(acc->pincode, data, sizeof(acc->pincode));
  685.     Sql_GetData(sql_handle, 15, &data, NULL); acc->pincode_change = atol(data);
  686.     Sql_GetData(sql_handle, 16, &data, NULL); acc->bank_vault = atoi(data);
  687. -
  688. +#ifdef VIP_ENABLE
  689. +   Sql_GetData(sql_handle, 17, &data, NULL); acc->vip_time = atol(data);
  690. +   Sql_GetData(sql_handle, 18, &data, NULL); acc->old_group = atoi(data);
  691. +   ShowInfo("mmo_auth_fromsql vip_time=%d, old_ground=%d\n",acc->vip_time,acc->old_group);
  692. +#endif
  693.     Sql_FreeResult(sql_handle);
  694. -
  695. -
  696. +  
  697. +  
  698.     // retrieve account regs for the specified user
  699.     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) )
  700.     {
  701. @@ -597,10 +606,17 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
  702.         break;
  703.     }
  704.  
  705. +#ifdef VIP_ENABLE 
  706. +   ShowInfo("mmo_auth_tosql vip_time=%d, old_ground=%d\n",acc->vip_time,acc->old_group);
  707. +#endif
  708.     if( is_new )
  709.     {// insert into account table
  710.         if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
  711. +#ifdef VIP_ENABLE
  712. +           "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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
  713. +#else
  714.             "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 (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
  715. +#endif
  716.             db->account_db)
  717.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_INT,       (void*)&acc->account_id,      sizeof(acc->account_id))
  718.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_STRING,    (void*)acc->userid,           strlen(acc->userid))
  719. @@ -619,6 +635,10 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
  720.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_STRING,    (void*)&acc->pincode,         strlen(acc->pincode))
  721.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_LONG,      (void*)&acc->pincode_change,  sizeof(acc->pincode_change))
  722.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 16, SQLDT_INT,       (void*)&acc->bank_vault,      sizeof(acc->bank_vault))
  723. +#ifdef VIP_ENABLE
  724. +       ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 17, SQLDT_LONG,       (void*)&acc->vip_time,         sizeof(acc->vip_time))
  725. +       ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 18, SQLDT_INT,       (void*)&acc->old_group,        sizeof(acc->old_group))
  726. +#endif
  727.         ||  SQL_SUCCESS != SqlStmt_Execute(stmt)
  728.         ) {
  729.             SqlStmt_ShowDebug(stmt);
  730. @@ -627,7 +647,13 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
  731.     }
  732.     else
  733.     {// update account table
  734. -       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)
  735. +       if( SQL_SUCCESS != SqlStmt_Prepare(stmt,
  736. +#ifdef VIP_ENABLE
  737. +           "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'",
  738. +#else
  739. +           "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'",
  740. +#endif
  741. +           db->account_db, acc->account_id)
  742.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  0, SQLDT_STRING,    (void*)acc->userid,           strlen(acc->userid))
  743.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  1, SQLDT_STRING,    (void*)acc->pass,             strlen(acc->pass))
  744.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt,  2, SQLDT_ENUM,      (void*)&acc->sex,             sizeof(acc->sex))
  745. @@ -644,6 +670,10 @@ static bool mmo_auth_tosql(AccountDB_SQL* db, const struct mmo_account* acc, boo
  746.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 13, SQLDT_STRING,    (void*)&acc->pincode,         strlen(acc->pincode))
  747.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 14, SQLDT_LONG,      (void*)&acc->pincode_change,  sizeof(acc->pincode_change))
  748.         ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 15, SQLDT_INT,       (void*)&acc->bank_vault,      sizeof(acc->bank_vault))
  749. +#ifdef VIP_ENABLE
  750. +       ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 16, SQLDT_LONG,       (void*)&acc->vip_time,        sizeof(acc->vip_time))
  751. +       ||  SQL_SUCCESS != SqlStmt_BindParam(stmt, 17, SQLDT_INT,       (void*)&acc->old_group,       sizeof(acc->old_group))
  752. +#endif
  753.         ||  SQL_SUCCESS != SqlStmt_Execute(stmt)
  754.         ) {
  755.             SqlStmt_ShowDebug(stmt);
  756. diff --git a/src/login/login.c b/src/login/login.c
  757. index daa8dca..06232f1 100644
  758. --- a/src/login/login.c
  759. +++ b/src/login/login.c
  760. @@ -13,6 +13,9 @@
  761.  #include "../common/msg_conf.h"
  762.  #include "../common/cli.h"
  763.  #include "../common/ers.h"
  764. +#include "../common/utils.h"
  765. +#include "../common/mmo.h"
  766. +#include "../config/core.h"
  767.  #include "account.h"
  768.  #include "ipban.h"
  769.  #include "login.h"
  770. @@ -294,11 +297,16 @@ bool check_password(const char* md5key, int passwdenc, const char* passwd, const
  771.  }
  772.  
  773.  
  774. -//-----------------------------------------------------
  775. -// custom timestamp formatting (from eApp)
  776. -//-----------------------------------------------------
  777. -const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format)
  778. -{
  779. +/**
  780. + * Converting a timestamp is a srintf according to format
  781. + * safefr then strftime as it ensure \0 at end of string
  782. + * @param str, pointer to the destination string
  783. + * @param size, max length of the string
  784. + * @param timestamp, see unix epoch
  785. + * @param format, format to convert timestamp on, see strftime format
  786. + * @return the string of timestamp
  787. + */
  788. +const char* timestamp2string(char* str, size_t size, time_t timestamp, const char* format){
  789.     size_t len = strftime(str, size, format, localtime(&timestamp));
  790.     memset(str + len, '\0', size - len);
  791.     return str;
  792. @@ -428,6 +436,139 @@ int parse_console(const char* buf){
  793.     return 0;
  794.  }
  795.  
  796. +int chrif_send_accdata(int fd, uint32 aid){
  797. +   struct mmo_account acc;
  798. +   time_t expiration_time = 0;
  799. +   char email[40] = "";   
  800. +   int group_id = 0;
  801. +   char birthdate[10+1] = "";
  802. +   char pincode[PINCODE_LENGTH+1];
  803. +   int bank_vault = 0;
  804. +   char isvip=false;
  805. +   uint8 char_slots = MIN_CHARS, char_vip=0;
  806. +
  807. +   memset(pincode,0,PINCODE_LENGTH+1);
  808. +   if( !accounts->load_num(accounts, &acc, aid) )
  809. +       return -1;
  810. +   else{
  811. +       safestrncpy(email, acc.email, sizeof(email));
  812. +       expiration_time = acc.expiration_time;
  813. +       group_id = acc.group_id;
  814. +      
  815. +       safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
  816. +       safestrncpy(pincode, acc.pincode, sizeof(pincode));
  817. +       bank_vault = acc.bank_vault;
  818. +#ifdef VIP_ENABLE
  819. +       ShowInfo("chrif_send_accdata now=%d, vip_time=%d, acc.vip_time > time = %d\n",
  820. +           time(NULL),acc.vip_time,acc.vip_time > time(NULL));
  821. +       if(acc.vip_time > time(NULL)){
  822. +           isvip=true;
  823. +           char_slots = login_config.char_per_account+login_config.vip_sys.char_increase;
  824. +           char_vip = login_config.vip_sys.char_increase;
  825. +       }
  826. +       else
  827. +           char_slots = login_config.char_per_account;
  828. +#endif    
  829. +   }
  830. +
  831. +   WFIFOHEAD(fd,79);
  832. +   WFIFOW(fd,0) = 0x2717;
  833. +   WFIFOL(fd,2) = aid;
  834. +   safestrncpy((char*)WFIFOP(fd,6), email, 40);
  835. +   WFIFOL(fd,46) = (uint32)expiration_time;
  836. +   WFIFOB(fd,50) = (unsigned char)group_id;
  837. +   WFIFOB(fd,51) = char_slots;
  838. +   safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
  839. +   safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
  840. +   WFIFOL(fd,68) = (uint32)acc.pincode_change;
  841. +   WFIFOL(fd,72) = bank_vault;
  842. +   WFIFOB(fd,76) = isvip;
  843. +   WFIFOB(fd,77) = char_vip;
  844. +   WFIFOB(fd,78) = MAX_CHAR_BILLING; //TODO create a config for this
  845. +   WFIFOSET(fd,79);
  846. +   return 0;
  847. +}
  848. +
  849. +int chrif_parse_reqaccdata(int fd, int cid, char *ip){
  850. +   if( RFIFOREST(fd) < 6 )
  851. +       return 0;
  852. +   else{
  853. +       uint32 aid = RFIFOL(fd,2);
  854. +       RFIFOSKIP(fd,6);
  855. +       if(chrif_send_accdata(fd,aid) < 0)
  856. +           ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[cid].name, aid, ip);
  857. +   }
  858. +   return 0;
  859. +}
  860. +
  861. +
  862. +int chrif_sendvipdata(int fd, struct mmo_account acc, char isvip){
  863. +#ifdef VIP_ENABLE
  864. +   uint8 buf[16];
  865. +
  866. +   WBUFW(buf,0) = 0x2743;
  867. +   WBUFL(buf,2) = acc.account_id;
  868. +   WBUFL(buf,6) = acc.vip_time;
  869. +   WBUFB(buf,10) = isvip;
  870. +   WBUFL(buf,11) = acc.group_id; //new group id
  871. +   charif_sendallwos(-1,buf,15); //inform all char-servs of result
  872. +   ShowInfo("chrif_sendvipdata aid=%d, vip_time=%d, isvip=%d\n",
  873. +       acc.account_id,acc.vip_time,isvip);
  874. +
  875. +   chrif_send_accdata(fd,acc.account_id); //refresh char with new setting
  876. +#endif
  877. +   return 1;
  878. +}
  879. +
  880. +/**
  881. + * Received a vip data reqest from char \n
  882. + * type is the query to perform \n
  883. + *  &1 : Select info and update old_groupid \n
  884. + *  &2 : Update vip time
  885. + * @param fd link to charserv
  886. + * @return 0 missing data, 1 succeed
  887. + */
  888. +int chrif_parse_reqvipdata(int fd){
  889. +#ifdef VIP_ENABLE
  890. +   if( RFIFOREST(fd) < 11 )
  891. +       return 0;
  892. +   else { //request vip info
  893. +       struct mmo_account acc;
  894. +       int aid = RFIFOL(fd,2);
  895. +       int8 type = RFIFOB(fd,6);
  896. +       uint32 req_duration = RFIFOL(fd,7);
  897. +       RFIFOSKIP(fd,11);
  898. +
  899. +       ShowInfo("chrif_parse_reqvipdata aid=%d, type=%d, req_duration=%d\n",
  900. +           aid,type,req_duration);
  901. +       if( accounts->load_num(accounts, &acc, aid ) ){
  902. +           time_t now = time(NULL);
  903. +           time_t vip_time = acc.vip_time;
  904. +           bool isvip = false;
  905. +
  906. +           if( type&2 ) vip_time = now+req_duration; // set new duration
  907. +           if(now < vip_time){ //isvip
  908. +               if(acc.group_id != login_config.vip_sys.group) //only upd this if we're not vip already
  909. +                   acc.old_group = acc.group_id;
  910. +               acc.group_id = login_config.vip_sys.group;
  911. +               acc.char_slots = login_config.char_per_account+login_config.vip_sys.char_increase;
  912. +               isvip = true;
  913. +           } else { //expired
  914. +               vip_time = 0;
  915. +               acc.group_id = acc.old_group;
  916. +               acc.old_group = 0;
  917. +               acc.char_slots = login_config.char_per_account;
  918. +           }
  919. +           acc.vip_time = (int)vip_time;
  920. +           accounts->save(accounts,&acc);
  921. +          
  922. +           chrif_sendvipdata(fd,acc,isvip);
  923. +       }
  924. +   }
  925. +#endif
  926. +   return 1;
  927. +}
  928. +
  929.  
  930.  //--------------------------------
  931.  // Packet parsing for char-servers
  932. @@ -555,54 +696,10 @@ int parse_fromchar(int fd){
  933.             }
  934.         break;
  935.  
  936. -       case 0x2716: // request account data
  937. -           if( RFIFOREST(fd) < 6 )
  938. -               return 0;
  939. -           else{
  940. -               struct mmo_account acc;
  941. -               time_t expiration_time = 0;
  942. -               char email[40] = "";
  943. -               uint8 char_slots = 0;
  944. -               int group_id = 0;
  945. -               char birthdate[10+1] = "";
  946. -               char pincode[PINCODE_LENGTH+1];
  947. -               int account_id = RFIFOL(fd,2);
  948. -               int bank_vault = 0;
  949. -
  950. -               memset(pincode,0,PINCODE_LENGTH+1);
  951. -
  952. -               RFIFOSKIP(fd,6);
  953. -
  954. -               if( !accounts->load_num(accounts, &acc, account_id) )
  955. -                   ShowNotice("Char-server '%s': account %d NOT found (ip: %s).\n", server[id].name, account_id, ip);
  956. -               else{
  957. -                   safestrncpy(email, acc.email, sizeof(email));
  958. -                   expiration_time = acc.expiration_time;
  959. -                   group_id = acc.group_id;
  960. -                   char_slots = acc.char_slots;
  961. -                   safestrncpy(birthdate, acc.birthdate, sizeof(birthdate));
  962. -                   safestrncpy(pincode, acc.pincode, sizeof(pincode));
  963. -                   bank_vault = acc.bank_vault;
  964. -               }
  965. -
  966. -               WFIFOHEAD(fd,76);
  967. -               WFIFOW(fd,0) = 0x2717;
  968. -               WFIFOL(fd,2) = account_id;
  969. -               safestrncpy((char*)WFIFOP(fd,6), email, 40);
  970. -               WFIFOL(fd,46) = (uint32)expiration_time;
  971. -               WFIFOB(fd,50) = (unsigned char)group_id;
  972. -               WFIFOB(fd,51) = char_slots;
  973. -               safestrncpy((char*)WFIFOP(fd,52), birthdate, 10+1);
  974. -               safestrncpy((char*)WFIFOP(fd,63), pincode, 4+1 );
  975. -               WFIFOL(fd,68) = (uint32)acc.pincode_change;
  976. -               WFIFOL(fd,72) = bank_vault;
  977. -               WFIFOSET(fd,76);
  978. -           }
  979. -       break;
  980. +       case 0x2716: chrif_parse_reqaccdata(fd,id,ip); break; // request account data
  981.  
  982.         case 0x2719: // ping request from charserver
  983.             RFIFOSKIP(fd,2);
  984. -
  985.             WFIFOHEAD(fd,2);
  986.             WFIFOW(fd,0) = 0x2718;
  987.             WFIFOSET(fd,2);
  988. @@ -973,6 +1070,8 @@ int parse_fromchar(int fd){
  989.             }
  990.         break;
  991.  
  992. +       case 0x2742: chrif_parse_reqvipdata(fd); break; //Vip sys
  993. +
  994.         default:
  995.             ShowError("parse_fromchar: Unknown packet 0x%x from a char-server! Disconnecting!\n", command);
  996.             set_eof(fd);
  997. @@ -1026,10 +1125,12 @@ int mmo_auth_new(const char* userid, const char* pass, const char sex, const cha
  998.     safestrncpy(acc.birthdate, "0000-00-00", sizeof(acc.birthdate));
  999.     safestrncpy(acc.pincode, "", sizeof(acc.pincode));
  1000.     acc.pincode_change = 0;
  1001. -
  1002. -   acc.char_slots = 0;
  1003. +   acc.char_slots = MIN_CHARS;
  1004.     acc.bank_vault = 0;
  1005. -
  1006. +#ifdef VIP_ENABLE
  1007. +   acc.vip_time = 0;
  1008. +   acc.old_group = 0;
  1009. +#endif
  1010.     if( !accounts->create(accounts, &acc) )
  1011.         return 0;
  1012.  
  1013. @@ -1638,8 +1739,7 @@ int parse_login(int fd)
  1014.  }
  1015.  
  1016.  
  1017. -void login_set_defaults()
  1018. -{
  1019. +void login_set_defaults(){
  1020.     login_config.login_ip = INADDR_ANY;
  1021.     login_config.login_port = 6900;
  1022.     login_config.ipban_cleanup_interval = 60;
  1023. @@ -1666,6 +1766,11 @@ void login_set_defaults()
  1024.  
  1025.     login_config.client_hash_check = 0;
  1026.     login_config.client_hash_nodes = NULL;
  1027. +   login_config.char_per_account = MAX_CHARS-MAX_CHAR_VIP-MAX_CHAR_BILLING;
  1028. +#ifdef VIP_ENABLE
  1029. +   login_config.vip_sys.char_increase = MAX_CHAR_VIP;
  1030. +   login_config.vip_sys.group = 5;
  1031. +#endif
  1032.  }
  1033.  
  1034.  //-----------------------------------
  1035. @@ -1767,14 +1872,31 @@ int login_config_read(const char* cfgName)
  1036.  
  1037.                 login_config.client_hash_nodes = nnode;
  1038.             }
  1039. +       } else if (strcmpi(w1, "chars_per_account") == 0) { //maxchars per account [Sirius]
  1040. +           login_config.char_per_account = atoi(w2);
  1041. +           if( login_config.char_per_account <= 0 || login_config.char_per_account > MAX_CHARS ) {
  1042. +               if( login_config.char_per_account > MAX_CHARS ){
  1043. +                   ShowWarning("Max chars per account '%d' exceeded limit. Defaulting to '%d'.\n", login_config.char_per_account, MAX_CHARS);
  1044. +                   login_config.char_per_account = MAX_CHARS;
  1045. +               }
  1046. +               login_config.char_per_account = MIN_CHARS;
  1047. +           }
  1048.         }
  1049. +#ifdef VIP_ENABLE
  1050. +       else if(strcmpi(w1,"vip_group")==0)
  1051. +           login_config.vip_sys.group = cap_value(atoi(w2),0,99);
  1052. +       else if(strcmpi(w1,"vip_char_increase")==0){
  1053. +           if(login_config.vip_sys.char_increase > (unsigned int) MAX_CHARS-login_config.char_per_account)
  1054. +               ShowWarning("vip_char_increase too high, can only go up to %d, according to your char_per_account config %d\n",
  1055. +                   MAX_CHARS-login_config.char_per_account,login_config.char_per_account);
  1056. +           login_config.vip_sys.char_increase =  cap_value(atoi(w2),0,MAX_CHARS-login_config.char_per_account);
  1057. +       }
  1058. +#endif    
  1059.         else if(!strcmpi(w1, "import"))
  1060.             login_config_read(w2);
  1061. -       else
  1062. -       if(!strcmpi(w1, "account.engine"))
  1063. +       else if(!strcmpi(w1, "account.engine"))
  1064.             safestrncpy(login_config.account_engine, w2, sizeof(login_config.account_engine));
  1065. -       else
  1066. -       {// try the account engines
  1067. +       else {// try the account engines
  1068.             int i;
  1069.             for( i = 0; account_engines[i].constructor; ++i )
  1070.             {
  1071. diff --git a/src/login/login.h b/src/login/login.h
  1072. index 427ece6..d10282f 100644
  1073. --- a/src/login/login.h
  1074. +++ b/src/login/login.h
  1075. @@ -6,6 +6,7 @@
  1076.  
  1077.  #include "../common/mmo.h" // NAME_LENGTH,SEX_*
  1078.  #include "../common/core.h" // CORE_ST_LAST
  1079. +#include "../config/core.h"
  1080.  
  1081.  enum E_LOGINSERVER_ST
  1082.  {
  1083. @@ -58,7 +59,6 @@ struct client_hash_node {
  1084.  };
  1085.  
  1086.  struct Login_Config {
  1087. -
  1088.     uint32 login_ip;                                // the address to bind to
  1089.     uint16 login_port;                              // the port to bind to
  1090.     unsigned int ipban_cleanup_interval;            // interval (in seconds) to clean up expired IP bans
  1091. @@ -86,6 +86,13 @@ struct Login_Config {
  1092.  
  1093.     int client_hash_check;                          // flags for checking client md5
  1094.     struct client_hash_node *client_hash_nodes;     // linked list containg md5 hash for each gm group
  1095. +   int char_per_account;               //number of char an account can have
  1096. +#ifdef VIP_ENABLE
  1097. +   struct {
  1098. +       unsigned int group;
  1099. +       unsigned int char_increase;
  1100. +   } vip_sys;
  1101. +#endif
  1102.  };
  1103.  
  1104.  #define sex_num2str(num) ( (num ==  SEX_FEMALE  ) ? 'F' : (num ==  SEX_MALE  ) ? 'M' : 'S' )
  1105. @@ -100,7 +107,7 @@ const char* login_msg_txt(int msg_number);
  1106.  void login_do_final_msg(void);
  1107.  
  1108.  
  1109. -#define MAX_SERVERS 30
  1110. +#define MAX_SERVERS 30 //number of charserv loginserv can handle
  1111.  extern struct mmo_char_server server[MAX_SERVERS];
  1112.  extern struct Login_Config login_config;
  1113.  
  1114. diff --git a/src/map/atcommand.c b/src/map/atcommand.c
  1115. index 4a78633..131aa67 100644
  1116. --- a/src/map/atcommand.c
  1117. +++ b/src/map/atcommand.c
  1118. @@ -7546,24 +7546,33 @@ static int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
  1119.  }
  1120.  
  1121.  
  1122. -ACMD_FUNC(rates)
  1123. -{
  1124. +ACMD_FUNC(rates) {
  1125.     char buf[CHAT_SIZE_MAX];
  1126. +   int base_exp_rate = 0, job_exp_rate = 0, item_rate = 0;
  1127.  
  1128.     nullpo_ret(sd);
  1129.     memset(buf, '\0', sizeof(buf));
  1130.  
  1131. +#ifdef VIP_ENABLE
  1132. +   // Display EXP and item rate increase for VIP.
  1133. +   if( pc_isvip(sd) && ( battle_config.vip_base_exp_increase || battle_config.vip_job_exp_increase || battle_config.vip_drop_increase )) {
  1134. +       base_exp_rate += battle_config.vip_base_exp_increase;
  1135. +       job_exp_rate += battle_config.vip_job_exp_increase;
  1136. +       item_rate += battle_config.vip_drop_increase;
  1137. +   }
  1138. +#endif
  1139. +      
  1140.     snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1298), // Experience rates: Base %.2fx / Job %.2fx
  1141. -       battle_config.base_exp_rate/100., battle_config.job_exp_rate/100.);
  1142. +       (battle_config.base_exp_rate+base_exp_rate)/100., (battle_config.job_exp_rate+job_exp_rate)/100.);
  1143.     clif_displaymessage(fd, buf);
  1144.     snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1299), // Normal Drop Rates: Common %.2fx / Healing %.2fx / Usable %.2fx / Equipment %.2fx / Card %.2fx
  1145. -       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.);
  1146. +       (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.);
  1147.     clif_displaymessage(fd, buf);
  1148.     snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1300), // Boss Drop Rates: Common %.2fx / Healing %.2fx / Usable %.2fx / Equipment %.2fx / Card %.2fx
  1149. -       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.);
  1150. +       (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.);
  1151.     clif_displaymessage(fd, buf);
  1152.     snprintf(buf, CHAT_SIZE_MAX, msg_txt(sd,1301), // Other Drop Rates: MvP %.2fx / Card-Based %.2fx / Treasure %.2fx
  1153. -       battle_config.item_rate_mvp/100., battle_config.item_rate_adddrop/100., battle_config.item_rate_treasure/100.);
  1154. +       (battle_config.item_rate_mvp+item_rate)/100., (battle_config.item_rate_adddrop+item_rate)/100., (battle_config.item_rate_treasure+item_rate)/100.);
  1155.     clif_displaymessage(fd, buf);
  1156.  
  1157.     return 0;
  1158. @@ -8295,7 +8304,7 @@ static int atcommand_mutearea_sub(struct block_list *bl,va_list ap)
  1159.     {
  1160.         location = "storage";
  1161.         items = sd->status.storage.items;
  1162. -       size = MAX_STORAGE;
  1163. +       size = sd->storage_size;
  1164.     }
  1165.     else
  1166.     if( strcmp(command+1, "cartlist") == 0 )
  1167. @@ -9181,6 +9190,68 @@ static inline void atcmd_channel_help(struct map_session_data *sd, const char *c
  1168.     return -1;
  1169.  }
  1170.  
  1171. +#ifdef VIP_ENABLE
  1172. +ACMD_FUNC(vip) {
  1173. +   struct map_session_data *pl_sd = NULL;
  1174. +   char * modif_p;
  1175. +   int viptime = 0;
  1176. +   nullpo_retr(-1, sd);
  1177. +
  1178. +   if (!message || !*message || sscanf(message, "%255s %23[^\n]",atcmd_output,atcmd_player_name) < 2) {
  1179. +       clif_displaymessage(fd, msg_txt(sd,700));   //Usage: @vip <time> <character name>
  1180. +       return -1;
  1181. +   }
  1182. +
  1183. +   atcmd_output[sizeof(atcmd_output)-1] = '\0';
  1184. +
  1185. +   modif_p = atcmd_output;
  1186. +   viptime = (int)solve_time(modif_p)/60; // Change to minutes
  1187. +   if(viptime==0) {
  1188. +       clif_displaymessage(fd, msg_txt(sd,701)); // Invalid time for vip command.
  1189. +       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.
  1190. +       return -1;
  1191. +   }
  1192. +
  1193. +   if ((pl_sd = map_nick2sd(atcmd_player_name)) == NULL) {
  1194. +       clif_displaymessage(fd, msg_txt(sd,3)); // Character not found.
  1195. +       return -1;
  1196. +   }
  1197. +
  1198. +   if (pc_get_group_level(pl_sd) > pc_get_group_level(sd)) {
  1199. +       clif_displaymessage(fd, msg_txt(sd,81)); // Your GM level don't authorise you to do this action on this player.
  1200. +       return -1;
  1201. +   }
  1202. +
  1203. +   if(pc_isvip(pl_sd) && pl_sd->vip.time){ //Update the player's VIP time
  1204. +       pl_sd->vip.time += viptime;
  1205. +       if (pl_sd->vip.time <= 0) {
  1206. +           pl_sd->vip.time = 0;
  1207. +           pl_sd->vip.enabled = 0;
  1208. +           clif_displaymessage(pl_sd->fd, msg_txt(sd,703)); // GM has removed your VIP time.
  1209. +           clif_displaymessage(fd, msg_txt(sd,704)); // Player is no longer VIP.
  1210. +           chrif_req_vipActive(pl_sd, viptime, 3);
  1211. +       } else {
  1212. +           int year,month,day,hour,minute,second;
  1213. +           char timestr[128];
  1214. +           split_time(pl_sd->vip.time*60,&year,&month,&day,&hour,&minute,&second);
  1215. +       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.
  1216. +           clif_displaymessage(pl_sd->fd, atcmd_output);
  1217. +           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.
  1218. +           clif_displaymessage(fd, atcmd_output);
  1219. +           time2str(timestr,"%Y-%m-%d %H:%M",pl_sd->vip.time*60);
  1220. +           sprintf(atcmd_output,"%s : %s",msg_txt(sd,707),timestr); //You are VIP until :
  1221. +           clif_displaymessage(pl_sd->fd, atcmd_output);
  1222. +           clif_displaymessage(fd, atcmd_output);
  1223. +       }
  1224. +   } else {
  1225. +       clif_displaymessage(fd, msg_txt(sd,704));
  1226. +       return -1;
  1227. +   }
  1228. +
  1229. +   return 0;
  1230. +}
  1231. +#endif
  1232. +
  1233.  #include "../custom/atcommand.inc"
  1234.  
  1235.  /**
  1236. @@ -9461,6 +9532,9 @@ void atcommand_basecommands(void) {
  1237.         ACMD_DEF(channel),
  1238.         ACMD_DEF(fontcolor),
  1239.         ACMD_DEF(langtype),
  1240. +#ifdef VIP_ENABLE
  1241. +       ACMD_DEF(vip),
  1242. +#endif
  1243.     };
  1244.     AtCommandInfo* atcommand;
  1245.     int i;
  1246. diff --git a/src/map/battle.c b/src/map/battle.c
  1247. index 11ed206..3003551 100644
  1248. --- a/src/map/battle.c
  1249. +++ b/src/map/battle.c
  1250. @@ -7233,6 +7233,18 @@ bool battle_check_range(struct block_list *src, struct block_list *bl, int range
  1251.     { "bowling_bash_area",                  &battle_config.bowling_bash_area,               0,      0,      20,             },
  1252.     { "drop_rateincrease",                  &battle_config.drop_rateincrease,               0,      0,      1,              },
  1253.     { "feature.banking",                    &battle_config.feature_banking,                 1,      0,      1,              },
  1254. +#ifdef VIP_ENABLE 
  1255. +   { "vip_storage_increase",               &battle_config.vip_storage_increase,            0,      0,   MAX_STORAGE-MIN_STORAGE, },
  1256. +   { "vip_base_exp_increase",              &battle_config.vip_base_exp_increase,           0,      0,      INT_MAX,         },
  1257. +   { "vip_job_exp_increase",               &battle_config.vip_job_exp_increase,            0,      0,      INT_MAX,         },
  1258. +   { "vip_exp_penalty_base_normal",        &battle_config.vip_exp_penalty_base_normal,     0,      0,      INT_MAX,         },
  1259. +   { "vip_exp_penalty_job_normal",         &battle_config.vip_exp_penalty_job_normal,      0,      0,      INT_MAX,         },
  1260. +   { "vip_exp_penalty_base",               &battle_config.vip_exp_penalty_base,            0,      0,      INT_MAX,         },
  1261. +   { "vip_exp_penalty_job",                &battle_config.vip_exp_penalty_job,             0,      0,      INT_MAX,         },
  1262. +   { "vip_bm_increase",                    &battle_config.vip_bm_increase,                 0,      0,      INT_MAX,         },
  1263. +   { "vip_drop_increase",                  &battle_config.vip_drop_increase,               0,      0,      INT_MAX,         },
  1264. +   { "vip_gemstone",                       &battle_config.vip_gemstone,                    0,      0,      1,               },
  1265. +#endif
  1266.     { "mon_trans_disable_in_gvg",           &battle_config.mon_trans_disable_in_gvg,        0,      0,      1,              },
  1267.     { "homunculus_S_growth_level",          &battle_config.hom_S_growth_level,              99,     0,      MAX_LEVEL,      },
  1268.     { "emblem_woe_change",                  &battle_config.emblem_woe_change,                0,     0,      1,              },
  1269. diff --git a/src/map/battle.h b/src/map/battle.h
  1270. index a52e373..f0667f3 100644
  1271. --- a/src/map/battle.h
  1272. +++ b/src/map/battle.h
  1273. @@ -496,6 +496,18 @@ extern struct Battle_Config
  1274.     int bowling_bash_area;
  1275.     int drop_rateincrease;
  1276.     int feature_banking;
  1277. +#ifdef VIP_ENABLE 
  1278. +   int vip_storage_increase;
  1279. +   int vip_base_exp_increase;
  1280. +   int vip_job_exp_increase;
  1281. +   int vip_bm_increase;
  1282. +   int vip_drop_increase;
  1283. +   int vip_gemstone;
  1284. +   int vip_exp_penalty_base_normal;
  1285. +   int vip_exp_penalty_base;
  1286. +   int vip_exp_penalty_job_normal;
  1287. +   int vip_exp_penalty_job;
  1288. +#endif
  1289.     int mon_trans_disable_in_gvg;
  1290.     int emblem_woe_change;
  1291.     int emblem_transparency_limit;
  1292. diff --git a/src/map/chrif.c b/src/map/chrif.c
  1293. index 933b5ce..57e4829 100644
  1294. --- a/src/map/chrif.c
  1295. +++ b/src/map/chrif.c
  1296. @@ -46,7 +46,7 @@
  1297.     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
  1298.      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
  1299.     -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
  1300. -   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
  1301. +   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
  1302.   };
  1303.  
  1304.  //Used Packets:
  1305. @@ -101,8 +101,8 @@
  1306.  //2b28: Outgoing, chrif_save_bankdata -> 'send bank data to be saved'
  1307.  //2b29: Incoming, chrif_load_bankdata -> 'received bank data for playeer to be loaded'
  1308.  //2b2a: Outgoing, chrif_bankdata_request -> 'request bank data for charid'
  1309. -//2b2b: FREE
  1310. -//2b2c: FREE
  1311. +//2b2b: Incoming, chrif_parse_ack_vipActive -> vip info result
  1312. +//2b2c: Outgoing, chrif_req_vipActive -> request vip info
  1313.  //2b2d: Outgoing, chrif_bsdata_request -> request bonus_script for pc_authok'ed char.
  1314.  //2b2e: Outgoing, chrif_save_bsdata -> Send bonus_script of player for saving.
  1315.  //2b2f: Incoming, chrif_load_bsdata -> received bonus_script of player for loading.
  1316. @@ -1513,6 +1513,49 @@ void chrif_keepalive(int fd) {
  1317.  void chrif_keepalive_ack(int fd) {
  1318.     session[fd]->flag.ping = 0;/* reset ping state, we received a packet */
  1319.  }
  1320. +
  1321. +void chrif_parse_ack_vipActive(int fd) {
  1322. +#ifdef VIP_ENABLE
  1323. +   int aid = RFIFOL(char_fd,2);
  1324. +   uint32 vip_time = RFIFOL(char_fd,6);
  1325. +   bool isvip = RFIFOB(char_fd,10);
  1326. +   uint32 groupid = RFIFOL(char_fd,11);
  1327. +   TBL_PC *sd = map_id2sd(aid);
  1328. +
  1329. +   if (sd && isvip) {
  1330. +       sd->vip.enabled = 1;
  1331. +       sd->vip.time = vip_time;
  1332. +       sd->group_id = groupid;
  1333. +       pc_group_pc_load(sd);
  1334. +      
  1335. +       // Increase storage size for VIP.
  1336. +       sd->storage_size = battle_config.vip_storage_increase + MIN_STORAGE;
  1337. +       if( sd->storage_size > MAX_STORAGE ) {
  1338. +           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);
  1339. +           sd->storage_size = MAX_STORAGE;
  1340. +       }
  1341. +       // Magic Stone requirement avoidance for VIP.
  1342. +       if( battle_config.vip_gemstone && pc_isvip(sd) )
  1343. +           sd->special_state.no_gemstone = 2; //need to be done after status_calc_bl(bl,first);
  1344. +       }
  1345. +#endif
  1346. +}
  1347. +
  1348. +int chrif_req_vipActive(TBL_PC *sd, int8 req_duration, int8 type) {
  1349. +#ifdef VIP_ENABLE
  1350. +   if (CheckForCharServer() || sd == NULL)
  1351. +       return 0;
  1352. +
  1353. +   WFIFOHEAD(char_fd,11);
  1354. +   WFIFOW(char_fd,0) = 0x2b2c;
  1355. +   WFIFOL(char_fd,2) = sd->bl.id; // AID
  1356. +   WFIFOB(char_fd,6) = type; // type&1 - SQL SELECT, type&2 - SQL UPDATE
  1357. +   WFIFOL(char_fd,7) = req_duration;
  1358. +   WFIFOSET(char_fd,11);
  1359. +#endif
  1360. +   return 0;
  1361. +}
  1362. +
  1363.  /*==========================================
  1364.   *
  1365.   *------------------------------------------*/
  1366. @@ -1590,6 +1633,7 @@ int chrif_parse(int fd) {
  1367.             case 0x2b25: chrif_deadopt(RFIFOL(fd,2), RFIFOL(fd,6), RFIFOL(fd,10)); break;
  1368.             case 0x2b27: chrif_authfail(fd); break;
  1369.             case 0x2b29: chrif_load_bankdata(fd); break;
  1370. +           case 0x2b2b: chrif_parse_ack_vipActive(fd); break;
  1371.             case 0x2b2f: chrif_load_bsdata(fd); break;
  1372.             default:
  1373.                 ShowError("chrif_parse : unknown packet (session #%d): 0x%x. Disconnecting.\n", fd, cmd);
  1374. diff --git a/src/map/chrif.h b/src/map/chrif.h
  1375. index 70a4a95..c3ec498 100644
  1376. --- a/src/map/chrif.h
  1377. +++ b/src/map/chrif.h
  1378. @@ -67,6 +67,9 @@ int chrif_divorce(int partner_id1, int partner_id2);
  1379.  int chrif_removefriend(int char_id, int friend_id);
  1380.  int chrif_send_report(char* buf, int len);
  1381.  
  1382. +void chrif_parse_ack_vipActive(int fd);
  1383. +int chrif_req_vipActive(struct map_session_data *sd, int8 req_duration, int8 type);
  1384. +
  1385.  int chrif_bsdata_request(int char_id);
  1386.  int chrif_save_bsdata(struct map_session_data *sd);
  1387.  int chrif_load_bsdata(int fd);
  1388. diff --git a/src/map/clif.c b/src/map/clif.c
  1389. index 00f8658..05e7c97 100644
  1390. --- a/src/map/clif.c
  1391. +++ b/src/map/clif.c
  1392. @@ -9544,7 +9544,13 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
  1393.         clif_updatestatus(sd,SP_JOBEXP);
  1394.         clif_updatestatus(sd,SP_NEXTJOBEXP);
  1395.         clif_updatestatus(sd,SP_SKILLPOINT);
  1396. -       clif_initialstatus(sd);
  1397. +       clif_initialstatus(sd);
  1398. +#ifdef VIP_ENABLE     
  1399. +       if(pc_isvip(sd)) { // Display client information to VIP.
  1400. +           clif_vip_display_info(sd); //TODO wtf that should do
  1401. +           clif_vip_display_info2(sd);
  1402. +       }
  1403. +#endif    
  1404.  
  1405.         if (sd->sc.option&OPTION_FALCON)
  1406.             clif_status_load(&sd->bl, SI_FALCON, 1);
  1407. @@ -16933,6 +16939,49 @@ void clif_update_rankingpoint(struct map_session_data *sd, int rankingtype, int
  1408.  #endif
  1409.  }
  1410.  
  1411. +/// 0x8cb <packet len>.W <exp>.W <death>.W <drop>.W (ZC_PERSONAL_INFOMATION)
  1412. +/// 0x97b <packet len>.W <exp>.L <death>.L <drop>.L (ZC_PERSONAL_INFOMATION2)
  1413. +void clif_vip_display_info(struct map_session_data *sd) {
  1414. +#ifdef VIP_ENABLE
  1415. +   nullpo_retv(sd);
  1416. +   sd->fd = (int)sd->fd;
  1417. +
  1418. +   WFIFOHEAD(sd->fd,17);
  1419. +
  1420. +   if(sd->packet_ver < date2version(20130320))
  1421. +       WFIFOW(sd->fd,0)  = 0x8cb;
  1422. +   else
  1423. +       WFIFOW(sd->fd,0)  = 0x97b;
  1424. +   WFIFOW(sd->fd,2)  = 17;
  1425. +   WFIFOW(sd->fd,4)  = battle_config.base_exp_rate;
  1426. +   WFIFOW(sd->fd,6)  = battle_config.death_penalty_base;
  1427. +   WFIFOW(sd->fd,8)  = battle_config.item_rate_common;
  1428. +   WFIFOB(sd->fd,10) = 0;
  1429. +   WFIFOW(sd->fd,11) = battle_config.vip_base_exp_increase;
  1430. +   WFIFOW(sd->fd,13) = battle_config.death_penalty_base*battle_config.vip_exp_penalty_base;
  1431. +   WFIFOW(sd->fd,15) = battle_config.vip_drop_increase;
  1432. +   WFIFOSET(sd->fd,17);
  1433. +#endif
  1434. +}
  1435. +
  1436. +/// 0981 <packet len>.W <exp>.W <death>.W <drop>.W <activity rate>.W (ZC_PERSONAL_INFOMATION_CHN)
  1437. +void clif_vip_display_info2(struct map_session_data* sd) {
  1438. +#ifdef VIP_ENABLE
  1439. +   nullpo_retv(sd);
  1440. +   sd->fd = (int)sd->fd;
  1441. +
  1442. +   WFIFOHEAD(sd->fd,12);
  1443. +   WFIFOW(sd->fd,0)  = 0x981;
  1444. +   WFIFOW(sd->fd,2)  = 12;
  1445. +   WFIFOW(sd->fd,4)  = battle_config.vip_base_exp_increase;
  1446. +   WFIFOW(sd->fd,6)  = battle_config.death_penalty_base*battle_config.vip_exp_penalty_base;
  1447. +   WFIFOW(sd->fd,8)  = battle_config.vip_drop_increase;
  1448. +   WFIFOW(sd->fd,10) = 0; // ?
  1449. +   WFIFOSET(sd->fd,12);
  1450. +#endif
  1451. +}
  1452. +
  1453. +
  1454.  #ifdef DUMP_UNKNOWN_PACKET
  1455.  void DumpUnknow(int fd,TBL_PC *sd,int cmd,int packet_len){
  1456.     const char* packet_txt = "save/packet.txt";
  1457. diff --git a/src/map/clif.h b/src/map/clif.h
  1458. index 3deedb9..daf13f8 100644
  1459. --- a/src/map/clif.h
  1460. +++ b/src/map/clif.h
  1461. @@ -773,6 +773,9 @@ void clif_search_store_info_click_ack(struct map_session_data* sd, short x, shor
  1462.  void clif_cashshop_result( struct map_session_data* sd, uint16 item_id, uint16 result );
  1463.  void clif_cashshop_open( struct map_session_data* sd );
  1464.  
  1465. +void clif_vip_display_info(struct map_session_data *sd);
  1466. +void clif_vip_display_info2(struct map_session_data *sd);
  1467. +
  1468.  /**
  1469.   * 3CeAM
  1470.   **/
  1471. diff --git a/src/map/mob.c b/src/map/mob.c
  1472. index 69ed2f8..477eb4d 100644
  1473. --- a/src/map/mob.c
  1474. +++ b/src/map/mob.c
  1475. @@ -2249,13 +2249,25 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
  1476.  
  1477.             if (map[m].flag.nobaseexp || !md->db->base_exp)
  1478.                 base_exp = 0;
  1479. -           else
  1480. -               base_exp = (unsigned int)cap_value(md->db->base_exp * per * bonus/100. * map[m].adjust.bexp/100., 1, UINT_MAX);
  1481. +               else {
  1482. +                   int vip_bonus=0;
  1483. +#ifdef VIP_ENABLE      // Increase base EXP rate for VIP.
  1484. +                   if( battle_config.vip_base_exp_increase && ( sd && pc_isvip(sd) ) )
  1485. +                       vip_bonus += battle_config.vip_base_exp_increase;
  1486. +#endif
  1487. +                   base_exp = (unsigned int)cap_value(md->db->base_exp * per * (bonus+vip_bonus)/100. * map[m].adjust.bexp/100., 1, UINT_MAX);
  1488. +           }
  1489.  
  1490.             if (map[m].flag.nojobexp || !md->db->job_exp || md->dmglog[i].flag == MDLF_HOMUN) //Homun earned job-exp is always lost.
  1491.                 job_exp = 0;
  1492. -           else
  1493. -               job_exp = (unsigned int)cap_value(md->db->job_exp * per * bonus/100. * map[m].adjust.jexp/100., 1, UINT_MAX);
  1494. +           else {
  1495. +               int vip_bonus=0;
  1496. +#ifdef VIP_ENABLE      // Increase job EXP rate for VIP.
  1497. +               if( battle_config.vip_job_exp_increase && ( sd && pc_isvip(sd) ) )
  1498. +                   vip_bonus += battle_config.vip_job_exp_increase;
  1499. +#endif
  1500. +               job_exp = (unsigned int)cap_value(md->db->job_exp * per * (bonus+vip_bonus)/100. * map[m].adjust.jexp/100., 1, UINT_MAX);
  1501. +           }
  1502.  
  1503.             if ( ( temp = tmpsd[i]->status.party_id)>0 ) {
  1504.                 int j;
  1505. @@ -2371,6 +2383,11 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
  1506.             // Increase drop rate if user has SC_ITEMBOOST
  1507.             if (sd && sd->sc.data[SC_ITEMBOOST]) // now rig the drop rate to never be over 90% unless it is originally >90%.
  1508.                 drop_rate = max(drop_rate,cap_value((int)(0.5+drop_rate*(sd->sc.data[SC_ITEMBOOST]->val1)/100.),0,9000));
  1509. +#ifdef VIP_ENABLE // Increase item drop rate for VIP.
  1510. +           if( battle_config.vip_drop_increase && ( sd && pc_isvip(sd) ) )
  1511. +               drop_rate += (int)(0.5+(drop_rate*battle_config.vip_drop_increase)/10000.);
  1512. +               drop_rate = min(drop_rate,10000); //cap it to 100%
  1513. +#endif
  1514.  #ifdef RENEWAL_DROP
  1515.             if( drop_modifier != 100 ) {
  1516.                 drop_rate = drop_rate * drop_modifier / 100;
  1517. diff --git a/src/map/pc.c b/src/map/pc.c
  1518. index b7f801c..567a867 100644
  1519. --- a/src/map/pc.c
  1520. +++ b/src/map/pc.c
  1521. @@ -1276,6 +1276,10 @@ int pc_reg_received(struct map_session_data *sd)
  1522.     chrif_skillcooldown_request(sd->status.account_id, sd->status.char_id);
  1523.     chrif_bankdata_request(sd->status.account_id, sd->status.char_id);
  1524.     chrif_bsdata_request(sd->status.char_id);
  1525. +   sd->storage_size = MIN_STORAGE; //default to min
  1526. +#ifdef VIP_ENABLE
  1527. +   chrif_req_vipActive(sd, 0, 1); // request VIP informations
  1528. +#endif
  1529.     intif_Mail_requestinbox(sd->status.char_id, 0); // MAIL SYSTEM - Request Mail Inbox
  1530.     intif_request_questlog(sd);
  1531.  
  1532. @@ -2489,7 +2493,7 @@ int pc_bonus(struct map_session_data *sd,int type,int val)
  1533.             sd->special_state.no_misc_damage = cap_value(val,0,100);
  1534.             break;
  1535.         case SP_NO_GEMSTONE:
  1536. -           if(sd->state.lr_flag != 2)
  1537. +           if(sd->state.lr_flag != 2 && sd->special_state.no_gemstone != 2)
  1538.                 sd->special_state.no_gemstone = 1;
  1539.             break;
  1540.         case SP_INTRAVISION: // Maya Purple Card effect allowing to see Hiding/Cloaking people [DracoRPG]
  1541. @@ -5877,8 +5881,13 @@ static void pc_calcexp(struct map_session_data *sd, unsigned int *base_exp, unsi
  1542.         (int)(status_get_lv(src) - sd->status.base_level) >= 20)
  1543.         bonus += 15; // pk_mode additional exp if monster >20 levels [Valaris]
  1544.  
  1545. -   if (sd->sc.data[SC_EXPBOOST])
  1546. -       bonus += sd->sc.data[SC_EXPBOOST]->val1;
  1547. +   if (sd->sc.data[SC_EXPBOOST]) {
  1548. +       bonus += sd->sc.data[SC_EXPBOOST]->val1;
  1549. +#ifdef VIP_ENABLE
  1550. +       if( battle_config.vip_bm_increase && pc_isvip(sd) ) // Increase Battle Manual EXP rate for VIP.
  1551. +           bonus += ( sd->sc.data[SC_EXPBOOST]->val1 / battle_config.vip_bm_increase );
  1552. +#endif    
  1553. +   }
  1554.  
  1555.     *base_exp = (unsigned int) cap_value(*base_exp + (double)*base_exp * bonus/100., 1, UINT_MAX);
  1556.  
  1557. @@ -6928,37 +6937,38 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
  1558.         && !map[sd->bl.m].flag.noexppenalty && !map_flag_gvg(sd->bl.m)
  1559.         && !sd->sc.data[SC_BABY] && !sd->sc.data[SC_LIFEINSURANCE])
  1560.     {
  1561. -       unsigned int base_penalty =0;
  1562. -       if (battle_config.death_penalty_base > 0) {
  1563. +       unsigned int base_penalty = battle_config.death_penalty_base, job_penalty = battle_config.death_penalty_job;
  1564. +#ifdef VIP_ENABLE
  1565. +       if(pc_isvip(sd)){
  1566. +           base_penalty = base_penalty*battle_config.vip_exp_penalty_base;
  1567. +           job_penalty = job_penalty*battle_config.vip_exp_penalty_job;
  1568. +       }
  1569. +       else {
  1570. +           base_penalty = base_penalty*battle_config.vip_exp_penalty_base_normal;
  1571. +           job_penalty = job_penalty*battle_config.vip_exp_penalty_job_normal;
  1572. +       }
  1573. +#endif
  1574. +       if (base_penalty > 0) {
  1575.             switch (battle_config.death_penalty_type) {
  1576. -               case 1:
  1577. -                   base_penalty = (unsigned int) ((double)pc_nextbaseexp(sd) * (double)battle_config.death_penalty_base/10000);
  1578. -               break;
  1579. -               case 2:
  1580. -                   base_penalty = (unsigned int) ((double)sd->status.base_exp * (double)battle_config.death_penalty_base/10000);
  1581. -               break;
  1582. +               case 1: base_penalty = (uint32) ((double)(pc_nextbaseexp(sd) * base_penalty)/10000); break;
  1583. +               case 2: base_penalty = (uint32) ((double)(sd->status.base_exp * base_penalty)/10000); break;
  1584.             }
  1585. -           if(base_penalty) {
  1586. +           if (base_penalty > 0){ //recheck after altering to speedup
  1587.                 if (battle_config.pk_mode && src && src->type==BL_PC)
  1588.                     base_penalty*=2;
  1589.                 sd->status.base_exp -= min(sd->status.base_exp, base_penalty);
  1590.                 clif_updatestatus(sd,SP_BASEEXP);
  1591.             }
  1592.         }
  1593. -       if(battle_config.death_penalty_job > 0) {
  1594. -           base_penalty = 0;
  1595. +       if(job_penalty > 0) {
  1596.             switch (battle_config.death_penalty_type) {
  1597. -               case 1:
  1598. -                   base_penalty = (unsigned int) ((double)pc_nextjobexp(sd) * (double)battle_config.death_penalty_job/10000);
  1599. -               break;
  1600. -               case 2:
  1601. -                   base_penalty = (unsigned int) ((double)sd->status.job_exp * (double)battle_config.death_penalty_job/10000);
  1602. -               break;
  1603. +               case 1: job_penalty = (uint32) ((double)(pc_nextjobexp(sd) * job_penalty)/10000); break;
  1604. +               case 2: job_penalty = (uint32) ((double)(sd->status.job_exp * job_penalty)/10000); break;
  1605.             }
  1606. -           if(base_penalty) {
  1607. +           if(job_penalty) {
  1608.                 if (battle_config.pk_mode && src && src->type==BL_PC)
  1609. -                   base_penalty*=2;
  1610. -               sd->status.job_exp -= min(sd->status.job_exp, base_penalty);
  1611. +                   job_penalty*=2;
  1612. +               sd->status.job_exp -= min(sd->status.job_exp, job_penalty);
  1613.                 clif_updatestatus(sd,SP_JOBEXP);
  1614.             }
  1615.         }
  1616. @@ -9087,7 +9097,7 @@ int pc_check_available_item(struct map_session_data *sd) {
  1617.     }
  1618.  
  1619.     if( battle_config.item_check&4 ) { // Check for invalid(ated) items in storage.
  1620. -       for( i = 0; i < MAX_STORAGE; i++ ) {
  1621. +       for( i = 0; i < sd->storage_size; i++ ) {
  1622.             it = sd->status.storage.items[i].nameid;
  1623.  
  1624.             if( it && !itemdb_available(it) ) {
  1625. diff --git a/src/map/pc.h b/src/map/pc.h
  1626. index 6e2693e..b602a3d 100644
  1627. --- a/src/map/pc.h
  1628. +++ b/src/map/pc.h
  1629. @@ -201,7 +201,7 @@ struct map_session_data {
  1630.         unsigned int no_castcancel : 1;
  1631.         unsigned int no_castcancel2 : 1;
  1632.         unsigned int no_sizefix : 1;
  1633. -       unsigned int no_gemstone : 1;
  1634. +       unsigned int no_gemstone : 2;
  1635.         unsigned int intravision : 1; // Maya Purple Card effect [DracoRPG]
  1636.         unsigned int perfect_hiding : 1; // [Valaris]
  1637.         unsigned int no_knockback : 1;
  1638. @@ -213,7 +213,7 @@ struct map_session_data {
  1639.     unsigned int permissions;/* group permissions */
  1640.  
  1641.     int langtype;
  1642. -   int packet_ver;  // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18
  1643. +   uint32 packet_ver;  // 5: old, 6: 7july04, 7: 13july04, 8: 26july04, 9: 9aug04/16aug04/17aug04, 10: 6sept04, 11: 21sept04, 12: 18oct04, 13: 25oct04 ... 18
  1644.     struct mmo_charstatus status;
  1645.     struct registry save_reg;
  1646.  
  1647. @@ -550,6 +550,15 @@ struct map_session_data {
  1648.         uint8 count; //Count of target for skill like RL_D_TAIL
  1649.     } c_marker;
  1650.     bool flicker;
  1651. +  
  1652. +   // Holds player storage size (VIP system).
  1653. +   int storage_size;
  1654. +#ifdef VIP_ENABLE
  1655. +   struct {
  1656. +       unsigned int enabled;
  1657. +       unsigned int time;
  1658. +   } vip;
  1659. +#endif
  1660.  
  1661.     //Timed bonus 'bonus_script' struct [Cydh]
  1662.     struct s_script {
  1663. @@ -562,6 +571,7 @@ struct map_session_data {
  1664.     } bonus_script[MAX_PC_BONUS_SCRIPT];
  1665.  };
  1666.  
  1667. +
  1668.  enum weapon_type {
  1669.     W_FIST, //Bare hands
  1670.     W_DAGGER,   //1
  1671. @@ -683,7 +693,9 @@ struct {
  1672.  #define pc_ishiding(sd)       ( (sd)->sc.option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK) )
  1673.  #define pc_iscloaking(sd)     ( !((sd)->sc.option&OPTION_CHASEWALK) && ((sd)->sc.option&OPTION_CLOAK) )
  1674.  #define pc_ischasewalk(sd)    ( (sd)->sc.option&OPTION_CHASEWALK )
  1675. -
  1676. +#ifdef VIP_ENABLE
  1677. +   #define pc_isvip(sd) ( sd->vip.enabled ? 1 : 0 )
  1678. +#endif
  1679.  #ifdef NEW_CARTS
  1680.     #define pc_iscarton(sd)       ( (sd)->sc.data[SC_PUSH_CART] )
  1681.  #else
  1682. diff --git a/src/map/script.c b/src/map/script.c
  1683. index f05dda5..5defc72 100644
  1684. --- a/src/map/script.c
  1685. +++ b/src/map/script.c
  1686. @@ -18010,6 +18010,7 @@ static int atcommand_cleanfloor_sub(struct block_list *bl, va_list ap)
  1687.         case 7: script_pushint(st,MAX_GUILDLEVEL); break;
  1688.         case 8: script_pushint(st,MAX_GUILD_STORAGE); break;
  1689.         case 9: script_pushint(st,MAX_BG_MEMBERS); break;
  1690. +       case 10: script_pushint(st,VIP_SCRIPT); break;
  1691.         default:
  1692.             ShowWarning("buildin_getserverdef: unknown type %d.\n", type);
  1693.             script_pushint(st,0);
  1694. @@ -18018,6 +18019,76 @@ static int atcommand_cleanfloor_sub(struct block_list *bl, va_list ap)
  1695.     return 0;
  1696.  }
  1697.  
  1698. +#ifdef VIP_ENABLE
  1699. +/* Returns various information about a player's VIP status.
  1700. + * vip_status <type>,{"<character name>"};
  1701. + * Note: VIP System needs to be enabled.
  1702. + */
  1703. +BUILDIN_FUNC(vip_status) {
  1704. +   TBL_PC *sd;
  1705. +   char *vip_str = (char *)aMalloc(24*sizeof(char));
  1706. +   time_t now = time(NULL);
  1707. +   int type = script_getnum(st, 2);
  1708. +
  1709. +   if( script_hasdata(st, 3) )
  1710. +       sd = map_nick2sd(script_getstr(st, 3));
  1711. +   else
  1712. +       sd = script_rid2sd(st);
  1713. +
  1714. +   if( sd == NULL )
  1715. +       return 0;
  1716. +
  1717. +   switch(type) {
  1718. +       case 0: // Get VIP status.
  1719. +           script_pushint(st, pc_isvip(sd));
  1720. +           break;
  1721. +       case 1: // Get VIP expire date.
  1722. +           if( pc_isvip(sd) ) {
  1723. +               time_t viptime= (time_t)sd->vip.time;
  1724. +               strftime(vip_str, 24, "%Y-%m-%d %H:%M", localtime(&viptime));
  1725. +               vip_str[24]='\0';
  1726. +               script_pushstr(st, vip_str);
  1727. +           } else
  1728. +               script_pushint(st, 0);
  1729. +           break;
  1730. +       case 2: // Get remaining time.
  1731. +           if( pc_isvip(sd) ) {
  1732. +               time_t viptime= (time_t)sd->vip.time;
  1733. +               strftime(vip_str, 24, "%Y-%m-%d %H:%M", localtime(&viptime - now));
  1734. +               vip_str[24]='\0';
  1735. +               script_pushstr(st, vip_str);
  1736. +           } else
  1737. +               script_pushint(st, 0);
  1738. +           break;
  1739. +   }
  1740. +   return 0;
  1741. +}
  1742. +
  1743. +
  1744. +/* Adds or removes VIP time in minutes.
  1745. + * vip_time <time>,{"<character name>"};
  1746. + * If time < 0 remove time, else add time.
  1747. + * Note: VIP System needs to be enabled.
  1748. + */
  1749. +BUILDIN_FUNC(vip_time) {
  1750. +   TBL_PC *sd;
  1751. +   int time = script_getnum(st, 2) * 60; // Convert since it's given in minutes.
  1752. +
  1753. +   if( script_hasdata(st, 3) )
  1754. +       sd = map_nick2sd(script_getstr(st, 3));
  1755. +   else
  1756. +       sd = script_rid2sd(st);
  1757. +
  1758. +   if( sd == NULL )
  1759. +       return 0;
  1760. +
  1761. +   if( pc_isvip(sd) )
  1762. +       chrif_req_vipActive(sd, time, 2);
  1763. +
  1764. +   return 0;
  1765. +}
  1766. +#endif
  1767. +
  1768.  /*==========================================
  1769.   * Turns a player into a monster and grants SC attribute effect. [malufett/Hercules]
  1770.   * montransform <monster name/ID>, <duration>, <sc type>, <val1>, <val2>, <val3>, <val4>;
  1771. @@ -18636,6 +18707,10 @@ struct script_function buildin_func[] = {
  1772.     BUILDIN_DEF(is_clientver,"ii?"),
  1773.     BUILDIN_DEF(getserverdef,"i"),
  1774.     BUILDIN_DEF2(montransform, "transform", "vii????"), // Monster Transform [malufett/Hercules]
  1775. +#ifdef VIP_ENABLE
  1776. +   BUILDIN_DEF(vip_status,"i?"),
  1777. +   BUILDIN_DEF(vip_time,"i?"),
  1778. +#endif
  1779.     BUILDIN_DEF(bonus_script,"si???"),
  1780.  
  1781.  #include "../custom/script_def.inc"
  1782. diff --git a/src/map/skill.c b/src/map/skill.c
  1783. index f7c8ea0..4497292 100644
  1784. --- a/src/map/skill.c
  1785. +++ b/src/map/skill.c
  1786. @@ -13712,7 +13712,7 @@ int skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_id
  1787.          * Warlock
  1788.          **/
  1789.         case WL_COMET:
  1790. -           if( skill_check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0
  1791. +           if( skill_check_pc_partner(sd,skill_id,&skill_lv,1,0) <= 0 && require.itemid[0]
  1792.                 && sd->special_state.no_gemstone == 0
  1793.                 && ((i = pc_search_inventory(sd,require.itemid[0])) < 0 || sd->status.inventory[i].amount < require.amount[0]) ) {
  1794.                 //clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_ITEM,require.amount[0],require.itemid[0]);
  1795. @@ -14448,11 +14448,11 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
  1796.                     continue;
  1797.                 break;
  1798.             case AB_ADORAMUS:
  1799. -               if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 2) )
  1800. +               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)) )
  1801.                     continue;
  1802.                 break;
  1803.             case WL_COMET:
  1804. -               if( itemid_isgemstone(skill_db[idx].require.itemid[i]) && skill_check_pc_partner(sd,skill_id,&skill_lv, 1, 0) )
  1805. +               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)) )
  1806.                     continue;
  1807.                 break;
  1808.             case GN_FIRE_EXPANSION:
  1809. @@ -14475,21 +14475,25 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
  1810.         req.itemid[i] = skill_db[idx].require.itemid[i];
  1811.         req.amount[i] = skill_db[idx].require.amount[i];
  1812.  
  1813. -       if( itemid_isgemstone(req.itemid[i]) && skill_id != HW_GANBANTEIN )
  1814. -       {
  1815. -           if( sd->special_state.no_gemstone )
  1816. -           {   // All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
  1817. -               if( skill_id != SA_ABRACADABRA )
  1818. -                   req.itemid[i] = req.amount[i] = 0;
  1819. -               else if( --req.amount[i] < 1 )
  1820. -                   req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
  1821. -           }
  1822. -           if(sc && sc->data[SC_INTOABYSS])
  1823. -           {
  1824. -               if( skill_id != SA_ABRACADABRA )
  1825. -                   req.itemid[i] = req.amount[i] = 0;
  1826. -               else if( --req.amount[i] < 1 )
  1827. -                   req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
  1828. +       //check requirement for gemstone
  1829. +       if( itemid_isgemstone(req.itemid[i])){
  1830. +           if( sd->special_state.no_gemstone == 2 ) // Remove all Magic Stone required for all skills for VIP.
  1831. +               req.itemid[i] = req.amount[i] = 0;
  1832. +           else {
  1833. +               if( sd->special_state.no_gemstone )
  1834. +               {   // All gem skills except Hocus Pocus and Ganbantein can cast for free with Mistress card -helvetica
  1835. +                   if( skill_id != SA_ABRACADABRA )
  1836. +                       req.itemid[i] = req.amount[i] = 0;
  1837. +                   else if( --req.amount[i] < 1 )
  1838. +                       req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
  1839. +               }
  1840. +               if(sc && sc->data[SC_INTOABYSS])
  1841. +               {
  1842. +                   if( skill_id != SA_ABRACADABRA )
  1843. +                       req.itemid[i] = req.amount[i] = 0;
  1844. +                   else if( --req.amount[i] < 1 )
  1845. +                       req.amount[i] = 1; // Hocus Pocus always use at least 1 gem
  1846. +               }
  1847.             }
  1848.         }
  1849.         if( skill_id >= HT_SKIDTRAP && skill_id <= HT_TALKIEBOX && pc_checkskill(sd, RA_RESEARCHTRAP) > 0){
  1850. diff --git a/src/map/status.c b/src/map/status.c
  1851. index 48925e5..696729d 100644
  1852. --- a/src/map/status.c
  1853. +++ b/src/map/status.c
  1854. @@ -2636,10 +2636,10 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
  1855.                 wa->atk2 = refine_info[wlv].bonus[r-1] / 100;
  1856.  
  1857.  #ifdef RENEWAL
  1858. -            wa->matk += sd->inventory_data[index]->matk;
  1859. -            wa->wlv = wlv;
  1860. -            if( r ) // Renewal magic attack refine bonus
  1861. -                wa->matk += refine_info[wlv].bonus[r-1] / 100;
  1862. +           wa->matk += sd->inventory_data[index]->matk;
  1863. +           wa->wlv = wlv;
  1864. +           if( r ) // renewal magic attack refine bonus
  1865. +               wa->matk += refine_info[wlv].bonus[r-1] / 100;
  1866.  #endif
  1867.  
  1868.             // Overrefine bonus.
  1869. @@ -4057,12 +4057,12 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
  1870.             unit_stop_walking(bl,1);
  1871.     }
  1872.  
  1873. -   /**
  1874. +   /*
  1875.     * No status changes alter these yet.
  1876.     * if(flag&SCB_SIZE)
  1877.     * if(flag&SCB_RACE)
  1878.     * if(flag&SCB_RANGE)
  1879. -   **/
  1880. +   */
  1881.  
  1882.     if(flag&SCB_MAXHP) {
  1883.         if( bl->type&BL_PC ) {
  1884. @@ -4105,10 +4105,10 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
  1885.         status->matk_min = status_base_matk_min(status) + (sd?sd->bonus.ematk:0);
  1886.         status->matk_max = status_base_matk_max(status) + (sd?sd->bonus.ematk:0);
  1887.  #else
  1888. -       /**
  1889. +       /*
  1890.          * RE MATK Formula (from irowiki:http:// irowiki.org/wiki/MATK)
  1891.          * MATK = (sMATK + wMATK + eMATK) * Multiplicative Modifiers
  1892. -        **/
  1893. +        */
  1894.         status->matk_min = status->matk_max = status_base_matk(status, status_get_lv(bl));
  1895.         if( bl->type&BL_PC ) {
  1896.             int wMatk = 0;
  1897. @@ -4984,7 +4984,7 @@ static unsigned short status_calc_ematk(struct block_list *bl, struct status_cha
  1898.         matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; // 70 lvl1, 100lvl2
  1899.     if(sc->data[SC_IZAYOI])
  1900.         matk += 50 * sc->data[SC_IZAYOI]->val1;
  1901. -    return (unsigned short)cap_value(matk,0,USHRT_MAX);
  1902. +   return (unsigned short)cap_value(matk,0,USHRT_MAX);
  1903.  }
  1904.  #endif
  1905.  /**
  1906. diff --git a/src/map/storage.c b/src/map/storage.c
  1907. index 72a8b3f..cf4b65f 100644
  1908. --- a/src/map/storage.c
  1909. +++ b/src/map/storage.c
  1910. @@ -107,7 +107,7 @@ int storage_storageopen(struct map_session_data *sd)
  1911.     sd->state.storage_flag = 1;
  1912.     storage_sortitem(sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
  1913.     clif_storagelist(sd, sd->status.storage.items, ARRAYLENGTH(sd->status.storage.items));
  1914. -   clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
  1915. +   clif_updatestorageamount(sd, sd->status.storage.storage_amount, sd->storage_size);
  1916.     return 0;
  1917.  }
  1918.  
  1919. @@ -162,7 +162,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
  1920.  
  1921.     if( itemdb_isstackable2(data) )
  1922.     {//Stackable
  1923. -       for( i = 0; i < MAX_STORAGE; i++ )
  1924. +       for( i = 0; i < sd->storage_size; i++ )
  1925.         {
  1926.             if( compare_item(&stor->items[i], item_data) )
  1927.             {// existing items found, stack them
  1928. @@ -176,8 +176,8 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
  1929.     }
  1930.  
  1931.     // find free slot
  1932. -   ARR_FIND( 0, MAX_STORAGE, i, stor->items[i].nameid == 0 );
  1933. -   if( i >= MAX_STORAGE )
  1934. +   ARR_FIND( 0, sd->storage_size, i, stor->items[i].nameid == 0 );
  1935. +   if( i >= sd->storage_size )
  1936.         return 1;
  1937.  
  1938.     // add item to slot
  1939. @@ -185,7 +185,7 @@ static int storage_additem(struct map_session_data* sd, struct item* item_data,
  1940.     stor->storage_amount++;
  1941.     stor->items[i].amount = amount;
  1942.     clif_storageitemadded(sd,&stor->items[i],i,amount);
  1943. -   clif_updatestorageamount(sd, stor->storage_amount, MAX_STORAGE);
  1944. +   clif_updatestorageamount(sd, stor->storage_amount, sd->storage_size);
  1945.  
  1946.     return 0;
  1947.  }
  1948. @@ -203,7 +203,7 @@ int storage_delitem(struct map_session_data* sd, int n, int amount)
  1949.     {
  1950.         memset(&sd->status.storage.items[n],0,sizeof(sd->status.storage.items[0]));
  1951.         sd->status.storage.storage_amount--;
  1952. -       if( sd->state.storage_flag == 1 ) clif_updatestorageamount(sd, sd->status.storage.storage_amount, MAX_STORAGE);
  1953. +       if( sd->state.storage_flag == 1 ) clif_updatestorageamount(sd, sd->status.storage.storage_amount, sd->storage_size);
  1954.     }
  1955.     if( sd->state.storage_flag == 1 ) clif_storageitemremoved(sd,n,amount);
  1956.     return 0;
  1957. @@ -220,7 +220,7 @@ int storage_storageadd(struct map_session_data* sd, int index, int amount)
  1958.  {
  1959.     nullpo_ret(sd);
  1960.  
  1961. -   if( sd->status.storage.storage_amount > MAX_STORAGE )
  1962. +   if( sd->status.storage.storage_amount > sd->storage_size )
  1963.         return 0; // storage full
  1964.  
  1965.     if( index < 0 || index >= MAX_INVENTORY )
  1966. @@ -253,7 +253,7 @@ int storage_storageget(struct map_session_data* sd, int index, int amount)
  1967.  {
  1968.     int flag;
  1969.  
  1970. -   if( index < 0 || index >= MAX_STORAGE )
  1971. +   if( index < 0 || index >= sd->storage_size )
  1972.         return 0;
  1973.  
  1974.     if( sd->status.storage.items[index].nameid <= 0 )
  1975. @@ -281,11 +281,11 @@ int storage_storageaddfromcart(struct map_session_data* sd, int index, int amoun
  1976.  {
  1977.     nullpo_ret(sd);
  1978.  
  1979. -   if( sd->status.storage.storage_amount > MAX_STORAGE )
  1980. -       return 0; // storage full / storage closed
  1981. +   if( sd->status.storage.storage_amount > sd->storage_size )
  1982. +       return 0; // storage full / storage closed
  1983.  
  1984.     if( index < 0 || index >= MAX_CART )
  1985. -       return 0;
  1986. +       return 0;
  1987.  
  1988.     if( sd->status.cart[index].nameid <= 0 )
  1989.         return 0; //No item there.
  1990. @@ -311,7 +311,7 @@ int storage_storagegettocart(struct map_session_data* sd, int index, int amount)
  1991.     short flag;
  1992.     nullpo_ret(sd);
  1993.  
  1994. -   if( index < 0 || index >= MAX_STORAGE )
  1995. +   if( index < 0 || index >= sd->storage_size )
  1996.         return 0;
  1997.  
  1998.     if( sd->status.storage.items[index].nameid <= 0 )
  1999. diff --git a/src/map/unit.c b/src/map/unit.c
  2000. index bd17ad1..589ffc3 100644
  2001. --- a/src/map/unit.c
  2002. +++ b/src/map/unit.c
  2003. @@ -2191,7 +2191,7 @@ int unit_skillcastcancel(struct block_list *bl,int type)
  2004.             return 0;
  2005.  
  2006.         if (sd && (sd->special_state.no_castcancel2 ||
  2007. -                ((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]
  2008. +           ((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]
  2009.             return 0;
  2010.     }
  2011.  
  2012. diff --git a/vcproj-10/char-server_sql.vcxproj b/vcproj-10/char-server_sql.vcxproj
  2013. index abed05b..36f94fc 100644
  2014. --- a/vcproj-10/char-server_sql.vcxproj
  2015. +++ b/vcproj-10/char-server_sql.vcxproj
  2016. @@ -138,6 +138,7 @@
  2017.      <ClInclude Include="..\3rdparty\libconfig\wincompat.h" />
  2018.      <ClInclude Include="..\3rdparty\mt19937ar\mt19937ar.h" />
  2019.      <ClInclude Include="..\src\common\cbasetypes.h" />
  2020. +    <ClInclude Include="..\src\common\conf.h" />
  2021.      <ClInclude Include="..\src\common\core.h" />
  2022.      <ClInclude Include="..\src\common\db.h" />
  2023.      <ClInclude Include="..\src\common\ers.h" />
  2024. @@ -179,6 +180,7 @@
  2025.      <ClCompile Include="..\3rdparty\libconfig\scanner.c" />
  2026.      <ClCompile Include="..\3rdparty\libconfig\strbuf.c" />
  2027.      <ClCompile Include="..\3rdparty\mt19937ar\mt19937ar.c" />
  2028. +    <ClCompile Include="..\src\common\conf.c" />
  2029.      <ClCompile Include="..\src\common\core.c" />
  2030.      <ClCompile Include="..\src\common\db.c" />
  2031.      <ClCompile Include="..\src\common\ers.c" />
  2032. @@ -214,4 +216,4 @@
  2033.    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  2034.    <ImportGroup Label="ExtensionTargets">
  2035.    </ImportGroup>
  2036. -</Project>
  2037. \ No newline at end of file
  2038. +</Project>
  2039. diff --git a/vcproj-10/char-server_sql.vcxproj.filters b/vcproj-10/char-server_sql.vcxproj.filters
  2040. index 06f69e3..7dee36f 100644
  2041. --- a/vcproj-10/char-server_sql.vcxproj.filters
  2042. +++ b/vcproj-10/char-server_sql.vcxproj.filters
  2043. @@ -106,6 +106,11 @@
  2044.      <ClCompile Include="..\src\common\raconf.c">
  2045.        <Filter>common</Filter>
  2046.      </ClCompile>
  2047. +    <ClCompile Include="..\src\common\msg_conf.c" />
  2048. +    <ClCompile Include="..\src\common\cli.c" />
  2049. +    <ClCompile Include="..\src\common\conf.c">
  2050. +      <Filter>common</Filter>
  2051. +    </ClCompile>
  2052.    </ItemGroup>
  2053.    <ItemGroup>
  2054.      <ClInclude Include="..\src\common\cbasetypes.h">
  2055. @@ -228,6 +233,11 @@
  2056.      <ClInclude Include="..\src\common\raconf.h">
  2057.        <Filter>common</Filter>
  2058.      </ClInclude>
  2059. +    <ClInclude Include="..\src\common\msg_conf.h" />
  2060. +    <ClInclude Include="..\src\common\cli.h" />
  2061. +    <ClInclude Include="..\src\common\conf.h">
  2062. +      <Filter>common</Filter>
  2063. +    </ClInclude>
  2064.    </ItemGroup>
  2065.    <ItemGroup>
  2066.      <Filter Include="common">
  2067. @@ -246,4 +256,4 @@
  2068.        <UniqueIdentifier>{9e8badd7-548f-4eb4-9e87-613e87e772ff}</UniqueIdentifier>
  2069.      </Filter>
  2070.    </ItemGroup>
  2071. -</Project>
  2072. \ No newline at end of file
  2073. +</Project>
  2074. diff --git a/vcproj-10/login-server_sql.vcxproj b/vcproj-10/login-server_sql.vcxproj
  2075. index 0315ac3..e0d9f92 100644
  2076. --- a/vcproj-10/login-server_sql.vcxproj
  2077. +++ b/vcproj-10/login-server_sql.vcxproj
  2078. @@ -138,6 +138,7 @@
  2079.      <ClInclude Include="..\3rdparty\libconfig\scanner.h" />
  2080.      <ClInclude Include="..\3rdparty\libconfig\strbuf.h" />
  2081.      <ClInclude Include="..\3rdparty\libconfig\wincompat.h" />
  2082. +    <ClInclude Include="..\src\common\conf.h" />
  2083.      <ClInclude Include="..\src\common\mempool.h" />
  2084.      <ClInclude Include="..\src\common\mutex.h" />
  2085.      <ClInclude Include="..\src\common\raconf.h" />
  2086. @@ -172,6 +173,7 @@
  2087.      <ClCompile Include="..\3rdparty\libconfig\scanctx.c" />
  2088.      <ClCompile Include="..\3rdparty\libconfig\scanner.c" />
  2089.      <ClCompile Include="..\3rdparty\libconfig\strbuf.c" />
  2090. +    <ClCompile Include="..\src\common\conf.c" />
  2091.      <ClCompile Include="..\src\common\mempool.c" />
  2092.      <ClCompile Include="..\src\common\mutex.c" />
  2093.      <ClCompile Include="..\src\common\raconf.c" />
  2094. @@ -200,4 +202,4 @@
  2095.    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  2096.    <ImportGroup Label="ExtensionTargets">
  2097.    </ImportGroup>
  2098. -</Project>
  2099. \ No newline at end of file
  2100. +</Project>
  2101. diff --git a/vcproj-10/login-server_sql.vcxproj.filters b/vcproj-10/login-server_sql.vcxproj.filters
  2102. index f4280a0..3b682ce 100644
  2103. --- a/vcproj-10/login-server_sql.vcxproj.filters
  2104. +++ b/vcproj-10/login-server_sql.vcxproj.filters
  2105. @@ -82,6 +82,11 @@
  2106.      <ClCompile Include="..\src\common\raconf.c">
  2107.        <Filter>common</Filter>
  2108.      </ClCompile>
  2109. +    <ClCompile Include="..\src\common\msg_conf.c" />
  2110. +    <ClCompile Include="..\src\common\cli.c" />
  2111. +    <ClCompile Include="..\src\common\conf.c">
  2112. +      <Filter>common</Filter>
  2113. +    </ClCompile>
  2114.    </ItemGroup>
  2115.    <ItemGroup>
  2116.      <ClInclude Include="..\src\login\account.h">
  2117. @@ -180,6 +185,11 @@
  2118.      <ClInclude Include="..\src\common\raconf.h">
  2119.        <Filter>common</Filter>
  2120.      </ClInclude>
  2121. +    <ClInclude Include="..\src\common\msg_conf.h" />
  2122. +    <ClInclude Include="..\src\common\cli.h" />
  2123. +    <ClInclude Include="..\src\common\conf.h">
  2124. +      <Filter>common</Filter>
  2125. +    </ClInclude>
  2126.    </ItemGroup>
  2127.    <ItemGroup>
  2128.      <Filter Include="common">
  2129. @@ -198,4 +208,4 @@
  2130.        <UniqueIdentifier>{779e8145-9bb2-4a88-9149-60586ab0bdd4}</UniqueIdentifier>
  2131.      </Filter>
  2132.    </ItemGroup>
  2133. -</Project>
  2134. \ No newline at end of file
  2135. +</Project>
  2136. diff --git a/vcproj-12/char-server_sql.vcxproj b/vcproj-12/char-server_sql.vcxproj
  2137. index 6cfd004..e76a799 100644
  2138. --- a/vcproj-12/char-server_sql.vcxproj
  2139. +++ b/vcproj-12/char-server_sql.vcxproj
  2140. @@ -142,6 +142,7 @@
  2141.      <ClInclude Include="..\3rdparty\mt19937ar\mt19937ar.h" />
  2142.      <ClInclude Include="..\src\common\cbasetypes.h" />
  2143.      <ClInclude Include="..\src\common\core.h" />
  2144. +    <ClInclude Include="..\src\common\conf.h" />
  2145.      <ClInclude Include="..\src\common\db.h" />
  2146.      <ClInclude Include="..\src\common\ers.h" />
  2147.      <ClInclude Include="..\src\common\malloc.h" />
  2148. @@ -183,6 +184,7 @@
  2149.      <ClCompile Include="..\3rdparty\libconfig\strbuf.c" />
  2150.      <ClCompile Include="..\3rdparty\mt19937ar\mt19937ar.c" />
  2151.      <ClCompile Include="..\src\common\core.c" />
  2152. +    <ClCompile Include="..\src\common\conf.c" />
  2153.      <ClCompile Include="..\src\common\db.c" />
  2154.      <ClCompile Include="..\src\common\ers.c" />
  2155.      <ClCompile Include="..\src\common\malloc.c" />
  2156. @@ -217,4 +219,4 @@
  2157.    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  2158.    <ImportGroup Label="ExtensionTargets">
  2159.    </ImportGroup>
  2160. -</Project>
  2161. \ No newline at end of file
  2162. +</Project>
  2163. diff --git a/vcproj-12/char-server_sql.vcxproj.filters b/vcproj-12/char-server_sql.vcxproj.filters
  2164. index 06f69e3..ba4d82c 100644
  2165. --- a/vcproj-12/char-server_sql.vcxproj.filters
  2166. +++ b/vcproj-12/char-server_sql.vcxproj.filters
  2167. @@ -4,6 +4,9 @@
  2168.      <ClCompile Include="..\src\common\core.c">
  2169.        <Filter>common</Filter>
  2170.      </ClCompile>
  2171. +    <ClCompile Include="..\src\common\conf.c">
  2172. +      <Filter>common</Filter>
  2173. +    </ClCompile>
  2174.      <ClCompile Include="..\src\common\db.c">
  2175.        <Filter>common</Filter>
  2176.      </ClCompile>
  2177. @@ -114,6 +117,9 @@
  2178.      <ClInclude Include="..\src\common\core.h">
  2179.        <Filter>common</Filter>
  2180.      </ClInclude>
  2181. +    <ClInclude Include="..\src\common\conf.h">
  2182. +      <Filter>common</Filter>
  2183. +    </ClInclude>
  2184.      <ClInclude Include="..\src\common\db.h">
  2185.        <Filter>common</Filter>
  2186.      </ClInclude>
  2187. @@ -246,4 +252,4 @@
  2188.        <UniqueIdentifier>{9e8badd7-548f-4eb4-9e87-613e87e772ff}</UniqueIdentifier>
  2189.      </Filter>
  2190.    </ItemGroup>
  2191. -</Project>
  2192. \ No newline at end of file
  2193. +</Project>
  2194. diff --git a/vcproj-12/login-server_sql.vcxproj b/vcproj-12/login-server_sql.vcxproj
  2195. index 7a0a298..c4d9c89 100644
  2196. --- a/vcproj-12/login-server_sql.vcxproj
  2197. +++ b/vcproj-12/login-server_sql.vcxproj
  2198. @@ -153,6 +153,7 @@
  2199.      <ClInclude Include="..\src\login\loginlog.h" />
  2200.      <ClInclude Include="..\src\common\cbasetypes.h" />
  2201.      <ClInclude Include="..\src\common\core.h" />
  2202. +    <ClInclude Include="..\src\common\conf.h" />
  2203.      <ClInclude Include="..\src\common\db.h" />
  2204.      <ClInclude Include="..\src\common\ers.h" />
  2205.      <ClInclude Include="..\src\common\malloc.h" />
  2206. @@ -185,6 +186,7 @@
  2207.      <ClCompile Include="..\src\login\login.c" />
  2208.      <ClCompile Include="..\src\login\loginlog_sql.c" />
  2209.      <ClCompile Include="..\src\common\core.c" />
  2210. +    <ClCompile Include="..\src\common\conf.c" />
  2211.      <ClCompile Include="..\src\common\db.c" />
  2212.      <ClCompile Include="..\src\common\ers.c" />
  2213.      <ClCompile Include="..\src\common\malloc.c" />
  2214. @@ -204,4 +206,4 @@
  2215.    <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  2216.    <ImportGroup Label="ExtensionTargets">
  2217.    </ImportGroup>
  2218. -</Project>
  2219. \ No newline at end of file
  2220. +</Project>
  2221. diff --git a/vcproj-12/login-server_sql.vcxproj.filters b/vcproj-12/login-server_sql.vcxproj.filters
  2222. index f4280a0..d9ad6fc 100644
  2223. --- a/vcproj-12/login-server_sql.vcxproj.filters
  2224. +++ b/vcproj-12/login-server_sql.vcxproj.filters
  2225. @@ -16,6 +16,9 @@
  2226.      <ClCompile Include="..\src\common\core.c">
  2227.        <Filter>common</Filter>
  2228.      </ClCompile>
  2229. +    <ClCompile Include="..\src\common\conf.c">
  2230. +      <Filter>common</Filter>
  2231. +    </ClCompile>
  2232.      <ClCompile Include="..\src\common\db.c">
  2233.        <Filter>common</Filter>
  2234.      </ClCompile>
  2235. @@ -102,6 +105,9 @@
  2236.      <ClInclude Include="..\src\common\core.h">
  2237.        <Filter>common</Filter>
  2238.      </ClInclude>
  2239. +    <ClInclude Include="..\src\common\conf.h">
  2240. +      <Filter>common</Filter>
  2241. +    </ClInclude>
  2242.      <ClInclude Include="..\src\common\db.h">
  2243.        <Filter>common</Filter>
  2244.      </ClInclude>
  2245. @@ -198,4 +204,4 @@
  2246.        <UniqueIdentifier>{779e8145-9bb2-4a88-9149-60586ab0bdd4}</UniqueIdentifier>
  2247.      </Filter>
  2248.    </ItemGroup>
  2249. -</Project>
  2250. \ No newline at end of file
  2251. +</Project>
  2252. diff --git a/vcproj-9/login-server_sql.vcproj b/vcproj-9/login-server_sql.vcproj
  2253. index ed310a6..03d72ef 100644
  2254. --- a/vcproj-9/login-server_sql.vcproj
  2255. +++ b/vcproj-9/login-server_sql.vcproj
  2256. @@ -405,7 +405,7 @@
  2257.             <File
  2258.                 RelativePath="..\src\common\cli.c"
  2259.                 >
  2260. -           </File>                    
  2261. +           </File>
  2262.             <File
  2263.                 RelativePath="..\src\common\msg_conf.h"
  2264.                 >
  2265. @@ -413,7 +413,7 @@
  2266.             <File
  2267.                 RelativePath="..\src\common\msg_conf.c"
  2268.                 >
  2269. -           </File>            
  2270. +           </File>
  2271.            
  2272.         </Filter>
  2273.         <Filter
Add Comment
Please, Sign In to add comment