Advertisement
Lighta

ra_cashshop_upd

Apr 9th, 2013
267
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 28.74 KB | None | 0 0
  1. Index: conf/log_athena.conf
  2. ===================================================================
  3. --- conf/log_athena.conf    (revision 17227)
  4. +++ conf/log_athena.conf    (working copy)
  5. @@ -27,6 +27,7 @@
  6.  // 0x08000 - (B) Log buying store transactions
  7.  // 0x10000 - (X) Log all other transcations (rentals expiring/inserting cards/items removed by item_check/
  8.  //           rings deleted by divorce/pet egg (un)hatching/pet armor (un)equipping/Weapon Refine skill/Remove Trap skill)
  9. +// 0x20000 - ($) Log cash transactions
  10.  // Example: Log trades+vending+script items+created items: 1+2+32+1024 = 1059
  11.  // Please note that moving items from inventory to cart and back is not logged by design.
  12.  enable_logs: 0xFFFFF
  13. @@ -80,6 +81,11 @@
  14.  // 0 - don't log; 1 - log any zeny changes; 2.....1000000 - minimal absolut logging zeny value
  15.  log_zeny: 0
  16.  
  17. +// Track Cash Changes
  18. +// 0 - don't log
  19. +// 1 - log any changes
  20. +log_cash: 1
  21. +
  22.  // Log MVP Monster Drops (Note 1)
  23.  // Outdated. Use Pick_Log instead. But this log could be useful to keep track slayed MVPs
  24.  log_mvpdrop: no
  25. @@ -121,6 +127,7 @@
  26.  // log_npc_db: log/npclog.log
  27.  // log_pick_db: log/picklog.log
  28.  // log_zeny_db: log/zenylog.log
  29. +// log_cash_db: log/cashlog.log
  30.  
  31.  log_gm_db: atcommandlog
  32.  log_branch_db: branchlog
  33. @@ -129,5 +136,6 @@
  34.  log_npc_db: npclog
  35.  log_pick_db: picklog
  36.  log_zeny_db: zenylog
  37. +log_cash_db: cashlog
  38.  
  39.  import: conf/import/log_conf.txt
  40. Index: db/item_cash_db2.txt
  41. ===================================================================
  42. --- db/item_cash_db2.txt    (revision 0)
  43. +++ db/item_cash_db2.txt    (working copy)
  44. @@ -0,0 +1,17 @@
  45. +// This file contains the items sold in the ingame cash shop
  46. +//
  47. +// The structure of the file is
  48. +// type, item ID, price
  49. +//
  50. +// type:
  51. +//    0: New
  52. +//    1: Hot
  53. +//    2: Limited
  54. +//    3: Rental
  55. +//    4: Gear
  56. +//    5: Buff
  57. +//    6: Heal
  58. +//    7: Other
  59. +//
  60. +// price:
  61. +//    price of the defined item in cash points
  62. \ No newline at end of file
  63. Index: db/packet_db.txt
  64. ===================================================================
  65. --- db/packet_db.txt    (revision 17227)
  66. +++ db/packet_db.txt    (working copy)
  67. @@ -1697,101 +1697,58 @@
  68.  0x0838,12,searchstoreinfolistitemclick,2:6:10
  69.  0x0439,8,useitem,2:4
  70.  
  71. -//2012-04-10aRagexeRE
  72. +//2013-03-20Ragexe (Judas)
  73.  packet_ver: 30
  74.  0x01FD,15,repairitem,2
  75. -0x089C,26,friendslistadd,2
  76. -0x0885,5,hommenu,2:4
  77. -0x0961,36,storagepassword,0
  78. -0x0288,-1,cashshopbuy,4:8
  79. -0x091C,26,partyinvite2,2
  80. -0x094B,19,wanttoconnection,2:6:10:14:18
  81. -0x0369,7,actionrequest,2:6
  82. -0x083C,10,useskilltoid,2:4:6
  83. -0x0439,8,useitem,2:4
  84. -0x0945,-1,itemlistwindowselected,2:4:8
  85. -0x0815,-1,reqopenbuyingstore,2:4:8:9:89
  86. -0x0817,2,reqclosebuyingstore,0
  87. -0x0360,6,reqclickbuyingstore,2
  88. -0x0811,-1,reqtradebuyingstore,2:4:8:12
  89. -0x0819,-1,searchstoreinfo,2:4:5:9:13:14:15
  90. -0x0835,2,searchstoreinfonextpage,0
  91. -0x0838,12,searchstoreinfolistitemclick,2:6:10
  92. -0x0437,5,walktoxy,2
  93. -0x0886,6,ticksend,2
  94. -0x0871,5,changedir,2:4
  95. -0x0938,6,takeitem,2
  96. -0x0891,6,dropitem,2:4
  97. -0x086C,8,movetokafra,2:4
  98. -0x08A6,8,movefromkafra,2:4
  99. -0x0438,10,useskilltopos,2:4:6:8
  100. -0x0366,90,useskilltoposinfo,2:4:6:8:10
  101. -0x0889,6,getcharnamerequest,2
  102. -0x0884,6,solvecharname,2
  103. -0x08E5,41,bookingregreq,2:4    //Added to prevent disconnections
  104. -0x08E6,4
  105. -0x08E7,10,bookingsearchreq,2
  106. -0x08E8,-1
  107. -0x08E9,2,bookingdelreq,2
  108. -0x08EA,4
  109. -0x08EB,39,bookingupdatereq,2
  110. -0x08EC,73
  111. -0x08ED,43
  112. -0x08EE,6
  113. -0x08EF,6,bookingignorereq,2
  114. -0x08F0,6
  115. -0x08F1,6,bookingjoinpartyreq,2
  116. -0x08F2,36
  117. -0x08F3,-1
  118. -0x08F4,6
  119. -0x08F5,-1,bookingsummonmember,2:4
  120. -0x08F6,22
  121. -0x08F7,3
  122. -0x08F8,7
  123. -0x08F9,6
  124. -0x08FA,6
  125. -0x08FB,6,bookingcanceljoinparty,2
  126. +0x086D,26,friendslistadd,2
  127. +0x0897,5,hommenu,2:4
  128. +0x0947,36,storagepassword,0
  129. +//0x0288,-1,cashshopbuy,4:8
  130. +0x086F,26,partyinvite2,2
  131. +0x0888,19,wanttoconnection,2:6:10:14:18
  132. +0x08c9,4
  133. +0x088E,7,actionrequest,2:6
  134. +0x089B,10,useskilltoid,2:4:6
  135. +0x0881,5,walktoxy,2
  136. +0x0363,6,ticksend,2
  137. +0x093F,5,changedir,2:4
  138. +0x0933,6,takeitem,2
  139. +0x0438,6,dropitem,2:4
  140. +0x08AC,8,movetokafra,2:4
  141. +0x0874,8,movefromkafra,2:4
  142. +0x0959,10,useskilltopos,2:4:6:8
  143. +0x085A,90,useskilltoposinfo,2:4:6:8:10
  144. +0x0898,6,getcharnamerequest,2
  145. +0x094C,6,solvecharname,2
  146.  0x0907,5,moveitem,2:4
  147.  0x0908,5
  148. -0x08D7,28,battlegroundreg,2:4 //Added to prevent disconnections
  149.  0x08CF,10 //Amulet spirits
  150. +0x08d2,10
  151.  0x0977,14 //Monster HP Bar
  152. +0x0998,8,equipitem,2:4
  153. +0x0938,-1,reqopenbuyingstore,2:4:8:9:89
  154. +//0x0817,2,reqclosebuyingstore,0
  155. +//0x0360,6,reqclickbuyingstore,2
  156. +0x0922,-1,reqtradebuyingstore,2:4:8:12
  157. +0x094E,-1,searchstoreinfo,2:4:5:9:13:14:15
  158. +//0x0835,2,searchstoreinfonextpage,0
  159. +0x0868,-1,itemlistwindowselected,2:4:8
  160. +0x0983,29
  161. +0x0984,28
  162. +0x0980,7
  163. +0x0981,-1
  164. +0x0982,7
  165. +0x0985,-1
  166. +0x0986,6
  167. +0x08ff,24
  168. +// Lemongrass
  169. +0x085d,18,bookingregreq,2:4:6
  170.  
  171. -//2012-04-18aRagexeRE [Special Thanks to Judas!]
  172. -packet_ver:31
  173. -0x023B,26,friendslistadd,2
  174. -0x0361,5,hommenu,2:4
  175. -0x08A8,36,storagepassword,0
  176. -0x0802,26,partyinvite2,2
  177. -0x022D,19,wanttoconnection,2:6:10:14:18
  178. -0x0281,-1,itemlistwindowselected,2:4:8
  179. -0x035F,6,ticksend,2
  180. -0x0202,5,changedir,2:4
  181. -0x07E4,6,takeitem,2
  182. -0x0362,6,dropitem,2:4
  183. -0x07EC,8,movetokafra,2:4
  184. -0x0364,8,movefromkafra,2:4
  185. -0x096A,6,getcharnamerequest,2
  186. -0x0368,6,solvecharname,2
  187. -0x08E5,41,bookingregreq,2:4     //Added to prevent disconnections
  188. -0x08d2,10
  189. +// New cashshop
  190. +0x0844,2,cashshopopen,0
  191. +0x084a,2,cashshopclose,0
  192. +0x08c9,4,cashshopitemlist,0
  193. +0x0848,-1,cashshopbuy,0
  194.  
  195. -//2012-07-02aRagexeRE (unstable)
  196. -packet_ver: 32
  197. -0x0363,19,wanttoconnection,2:6:10:14:18
  198. -0x0364,6,ticksend,2
  199. -0x085a,7,actionrequest,2:6
  200. -0x0861,8,movefromkafra,2:4
  201. -0x0862,10,useskilltoid,2:4:6
  202. -0x0863,10,useskilltopos,2:4:6:8
  203. -0x0886,6,solvecharname,2
  204. -0x0889,90,useskilltoposinfo,2:4:6:8:10
  205. -0x089e,6,dropitem,2:4
  206. -0x089f,6,takeitem,2
  207. -0x08a0,8,movetokafra,2:4
  208. -0x094a,6,getcharnamerequest,2
  209. -0x0953,5,walktoxy,2
  210. -0x0960,5,changedir,2:4
  211. -
  212.  //Add new packets here
  213. -//packet_ver: 33
  214. +//packet_ver: 34
  215. Index: db/pre-re/item_cash_db.txt
  216. ===================================================================
  217. --- db/pre-re/item_cash_db.txt  (revision 0)
  218. +++ db/pre-re/item_cash_db.txt  (working copy)
  219. @@ -0,0 +1,17 @@
  220. +// This file contains the items sold in the ingame cash shop
  221. +//
  222. +// The structure of the file is
  223. +// type, item ID, price
  224. +//
  225. +// type:
  226. +//    0: New
  227. +//    1: Hot
  228. +//    2: Limited
  229. +//    3: Rental
  230. +//    4: Gear
  231. +//    5: Buff
  232. +//    6: Heal
  233. +//    7: Other
  234. +//
  235. +// price:
  236. +//    price of the defined item in cash points
  237. \ No newline at end of file
  238. Index: db/re/item_cash_db.txt
  239. ===================================================================
  240. --- db/re/item_cash_db.txt  (revision 0)
  241. +++ db/re/item_cash_db.txt  (working copy)
  242. @@ -0,0 +1,17 @@
  243. +// This file contains the items sold in the ingame cash shop
  244. +//
  245. +// The structure of the file is
  246. +// type, item ID, price
  247. +//
  248. +// type:
  249. +//    0: New
  250. +//    1: Hot
  251. +//    2: Limited
  252. +//    3: Rental
  253. +//    4: Gear
  254. +//    5: Buff
  255. +//    6: Heal
  256. +//    7: Other
  257. +//
  258. +// price:
  259. +//    price of the defined item in cash points
  260. \ No newline at end of file
  261. Index: src/common/mmo.h
  262. ===================================================================
  263. --- src/common/mmo.h    (revision 17227)
  264. +++ src/common/mmo.h    (working copy)
  265. @@ -46,7 +46,7 @@
  266.  // 20120307 - 2012-03-07aRagexeRE+ - 0x970
  267.  
  268.  #ifndef PACKETVER
  269. -   #define PACKETVER 20120410
  270. +   #define PACKETVER 20130320
  271.     //#define PACKETVER 20111116
  272.  #endif
  273.  
  274. Index: src/map/cashshop.c
  275. ===================================================================
  276. --- src/map/cashshop.c  (revision 0)
  277. +++ src/map/cashshop.c  (working copy)
  278. @@ -0,0 +1,296 @@
  279. +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  280. +// For more information, see LICENCE in the main folder
  281. +
  282. +#include "../common/strlib.h" // sv_readdb
  283. +#include "../common/malloc.h" // CREATE, RECREATE, aFree
  284. +#include "../common/nullpo.h" // nullpo_retv
  285. +#include "../common/showmsg.h" // ShowWarning, ShowStatus
  286. +
  287. +#include "cashshop.h"
  288. +#include "clif.h" // clif_cashshop_result
  289. +#include "itemdb.h" // itemdb_exists, itemdb_isstackable, itemdb_weight, itemdb_type
  290. +#include "map.h" // struct map_session_data
  291. +#include "npc.h"
  292. +#include "pc.h" // pc_checkadditem, pc_paycash, pc_additem
  293. +#include "pet.h" // pet_create_egg
  294. +
  295. +#include <string.h> // memset
  296. +#include <stdlib.h> // atoi
  297. +
  298. +static int cashshop_parse_dbrow( char** str, const char* source, int line );
  299. +
  300. +struct cash_item_db cash_shop_items[CASHSHOP_TAB_SEARCH];
  301. +
  302. +static void cashshop_read_db_txt( void ){
  303. +   const char* filename[] = { DBPATH"item_cash_db.txt", "item_cash_db2.txt" };
  304. +   int fi;
  305. +
  306. +   for( fi = 0; fi < ARRAYLENGTH( filename ); ++fi ){
  307. +       uint32 lines = 0, count = 0;
  308. +       char line[1024];
  309. +
  310. +       char path[256];
  311. +       FILE* fp;
  312. +
  313. +       sprintf( path, "%s/%s", db_path, filename[fi] );
  314. +       fp = fopen( path, "r" );
  315. +       if( fp == NULL ) {
  316. +           ShowWarning( "itemdb_readdb: File not found \"%s\", skipping.\n", path );
  317. +           continue;
  318. +       }
  319. +
  320. +       while( fgets( line, sizeof( line ), fp ) ){
  321. +           char *str[3], *p;
  322. +           int i;
  323. +           lines++;
  324. +
  325. +           if( line[0] == '/' && line[1] == '/' )
  326. +               continue;
  327. +
  328. +           memset( str, 0, sizeof( str ) );
  329. +
  330. +           p = line;
  331. +           while( ISSPACE( *p ) )
  332. +               ++p;
  333. +           if( *p == '\0' )
  334. +               continue;
  335. +
  336. +           for( i = 0; i < 2; ++i ){
  337. +               str[i] = p;
  338. +               p = strchr( p, ',' );
  339. +
  340. +               if( p == NULL )
  341. +                   break;
  342. +
  343. +               *p = '\0';
  344. +               ++p;
  345. +           }
  346. +
  347. +           str[2] = p;
  348. +           while( !ISSPACE( *p ) && *p != '\0' && *p != '/' )
  349. +               ++p;
  350. +
  351. +           if( p == NULL ){
  352. +               ShowError("cashshop_read_db_txt: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi( str[0] ) );
  353. +               continue;
  354. +           }
  355. +
  356. +           if( !cashshop_parse_dbrow( str, path, lines ) )
  357. +               continue;
  358. +          
  359. +           count++;
  360. +       }
  361. +
  362. +       fclose(fp);
  363. +
  364. +       ShowStatus( "Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi] );
  365. +   }
  366. +}
  367. +
  368. +static int cashshop_read_db_sql( void ){
  369. +   const char* cash_db_name[] = { "cash_item_db", "cash_item_db2" };
  370. +   int fi;
  371. +  
  372. +   for( fi = 0; fi < ARRAYLENGTH( cash_db_name ); ++fi ){
  373. +       uint32 lines = 0, count = 0;
  374. +
  375. +       if( SQL_ERROR == Sql_Query( mmysql_handle, "SELECT `tab`, `item_id`, `price` FROM `%s`", cash_db_name[fi] ) ){
  376. +           Sql_ShowDebug( mmysql_handle );
  377. +           continue;
  378. +       }
  379. +
  380. +       while( SQL_SUCCESS == Sql_NextRow( mmysql_handle ) ){
  381. +           char* str[3];
  382. +           int i;
  383. +
  384. +           ++lines;
  385. +
  386. +           for( i = 0; i < 3; ++i ){
  387. +               Sql_GetData( mmysql_handle, i, &str[i], NULL );
  388. +
  389. +               if( str[i] == NULL ){
  390. +                   str[i] = "";
  391. +               }
  392. +           }
  393. +
  394. +           if( !cashshop_parse_dbrow( str, cash_db_name[fi], lines ) )
  395. +               continue;
  396. +
  397. +           ++count;
  398. +       }
  399. +
  400. +       Sql_FreeResult( mmysql_handle );
  401. +
  402. +       ShowStatus( "Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, cash_db_name[fi] );
  403. +   }
  404. +
  405. +   return 0;
  406. +}
  407. +
  408. +static void cashshop_read_db( void ){
  409. +   if( db_use_sqldbs ){
  410. +       cashshop_read_db_sql();
  411. +   }else{
  412. +       cashshop_read_db_txt();
  413. +   }
  414. +}
  415. +
  416. +static int cashshop_parse_dbrow( char** str, const char* source, int line ){
  417. +   uint32 nameid = atoi( str[1] );
  418. +
  419. +   if( itemdb_exists( nameid ) ){
  420. +       uint16 tab = atoi( str[0] );
  421. +       uint32 price = atoi( str[2] );
  422. +       struct cash_item_data* cid;
  423. +       int j;
  424. +
  425. +       if( tab > CASHSHOP_TAB_SEARCH ){
  426. +           ShowWarning( "cashshop_parse_dbrow: Invalid tab %d in line %d of \"%s\", skipping.\n", tab, line, source );
  427. +           return 0;
  428. +       }else if( price < 1 ){
  429. +           ShowWarning( "cashshop_parse_dbrow: Invalid price %d in line %d of \"%s\", skipping.\n", price, line, source );
  430. +           return 0;
  431. +       }
  432. +
  433. +       ARR_FIND( 0, cash_shop_items[tab].count, j, nameid == cash_shop_items[tab].item[j]->nameid );
  434. +
  435. +       if( j == cash_shop_items[tab].count ){
  436. +           RECREATE( cash_shop_items[tab].item, struct cash_item_data *, ++cash_shop_items[tab].count );
  437. +           CREATE( cash_shop_items[tab].item[ cash_shop_items[tab].count - 1], struct cash_item_data, 1 );
  438. +           cid = cash_shop_items[tab].item[ cash_shop_items[tab].count - 1];
  439. +       }else{
  440. +           cid = cash_shop_items[tab].item[j];
  441. +       }
  442. +
  443. +       cid->nameid = nameid;
  444. +       cid->price = price;
  445. +
  446. +       return 1;
  447. +   }else{
  448. +       ShowWarning( "cashshop_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source );
  449. +   }
  450. +
  451. +   return 0;
  452. +}
  453. +
  454. +void cashshop_buylist( struct map_session_data* sd, int n, uint16* item_list ){
  455. +   uint32 totalcash = 0;
  456. +   uint32 totalweight = 0;
  457. +   int i,new_;
  458. +
  459. +   nullpo_retv( sd );
  460. +   nullpo_retv( item_list );
  461. +
  462. +   if( sd->state.trading ){
  463. +       clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_PC_STATE );
  464. +       return;
  465. +   }
  466. +
  467. +   new_ = 0;
  468. +
  469. +   for( i = 0; i < n; ++i ){
  470. +       uint32 nameid = *( item_list + i * 5 );
  471. +       uint32 quantity = *( item_list + i * 5 + 2 );
  472. +       uint16 tab = *( item_list + i * 5 + 4 );
  473. +       int j;
  474. +
  475. +       if( tab > CASHSHOP_TAB_SEARCH ){
  476. +           clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_UNKNOWN );
  477. +           return;
  478. +       }
  479. +
  480. +       ARR_FIND( 0, cash_shop_items[tab].count, j, nameid == cash_shop_items[tab].item[j]->nameid );
  481. +
  482. +       if( j == cash_shop_items[tab].count || !itemdb_exists( nameid ) ){
  483. +           clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_UNKNOWN );
  484. +           return;
  485. +       }else if( !itemdb_isstackable( nameid ) && quantity > 1 ){
  486. +           uint32* quantity_ptr = (uint32*)item_list + i * 5 + 2;
  487. +           ShowWarning("Player %s (%d:%d) sent a hexed packet trying to buy %d of nonstackable cash item %d!\n", sd->status.name, sd->status.account_id, sd->status.char_id, quantity, nameid );
  488. +           *quantity_ptr = 1;
  489. +       }
  490. +
  491. +       switch( pc_checkadditem( sd, nameid, quantity ) ){
  492. +           case ADDITEM_EXIST:
  493. +               break;
  494. +
  495. +           case ADDITEM_NEW:
  496. +               new_++;
  497. +               break;
  498. +
  499. +           case ADDITEM_OVERAMOUNT:
  500. +               clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_OVER_PRODUCT_TOTAL_CNT );
  501. +               return;
  502. +       }
  503. +
  504. +       totalcash += cash_shop_items[tab].item[j]->price * quantity;
  505. +       totalweight += itemdb_weight( nameid ) * quantity;
  506. +   }
  507. +
  508. +   // TODO: add kafra points substraction
  509. +
  510. +   if( totalcash > sd->cashPoints ){
  511. +       clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_SHORTTAGE_CASH );
  512. +       return;
  513. +   }else if( ( totalweight + sd->weight ) > sd->max_weight ){
  514. +       clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT );
  515. +       return;
  516. +   }else if( pc_inventoryblank( sd ) < new_ ){
  517. +       clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_INVENTORY_ITEMCNT );
  518. +       return;
  519. +   }
  520. +
  521. +   pc_paycash( sd, totalcash, 0 );
  522. +
  523. +   for( i = 0; i < n; ++i ){
  524. +       uint32 nameid = *( item_list + i * 5 );
  525. +       uint32 quantity = *( item_list + i * 5 + 2 );
  526. +
  527. +       if( itemdb_type( nameid ) == IT_PETEGG ){
  528. +           pet_create_egg( sd, nameid );
  529. +       }else{
  530. +           struct item item_tmp;
  531. +           memset( &item_tmp, 0, sizeof( item_tmp ) );
  532. +
  533. +           item_tmp.nameid = nameid;
  534. +           item_tmp.identify = 1;
  535. +
  536. +           switch( pc_additem( sd, &item_tmp, quantity, LOG_TYPE_CASH ) ){
  537. +               case 2:
  538. +                   clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT );
  539. +                   return;
  540. +               case 4:
  541. +                   clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_INVENTORY_ITEMCNT );
  542. +                   return;
  543. +               case 5:
  544. +                   clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_OVER_PRODUCT_TOTAL_CNT );
  545. +                   return;
  546. +               case 7:
  547. +                   clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_RUNE_OVERCOUNT );
  548. +                   return;
  549. +           }
  550. +       }
  551. +   }
  552. +
  553. +   clif_cashshop_result( sd, 0, CASHSHOP_RESULT_SUCCESS );
  554. +}
  555. +
  556. +int do_final_cashshop( void ){
  557. +   int tab, i;
  558. +
  559. +   for( tab = CASHSHOP_TAB_NEW; tab < CASHSHOP_TAB_SEARCH; tab++ ){
  560. +       for( i = 0; i < cash_shop_items[tab].count; i++ ){
  561. +           aFree( cash_shop_items[tab].item[i] );
  562. +       }
  563. +
  564. +       aFree( cash_shop_items[tab].item );
  565. +   }
  566. +
  567. +   return 0;
  568. +}
  569. +
  570. +int do_init_cashshop( void ){
  571. +   cashshop_read_db();
  572. +
  573. +   return 0;
  574. +}
  575. \ No newline at end of file
  576. Index: src/map/cashshop.h
  577. ===================================================================
  578. --- src/map/cashshop.h  (revision 0)
  579. +++ src/map/cashshop.h  (working copy)
  580. @@ -0,0 +1,54 @@
  581. +// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
  582. +// For more information, see LICENCE in the main folder
  583. +
  584. +#ifndef _CASHSHOP_H_
  585. +#define _CASHSHOP_H_
  586. +
  587. +int do_init_cashshop( void );
  588. +int do_final_cashshop( void );
  589. +void cashshop_buylist( struct map_session_data* sd, int n, uint16* item_list );
  590. +
  591. +// Taken from AEGIS
  592. +enum CASH_SHOP_TAB_CODE{
  593. +   CASHSHOP_TAB_NEW =  0x0,
  594. +   CASHSHOP_TAB_POPULAR =  0x1,
  595. +   CASHSHOP_TAB_LIMITED =  0x2,
  596. +   CASHSHOP_TAB_RENTAL =  0x3,
  597. +   CASHSHOP_TAB_PERPETUITY =  0x4,
  598. +   CASHSHOP_TAB_BUFF =  0x5,
  599. +   CASHSHOP_TAB_RECOVERY =  0x6,
  600. +   CASHSHOP_TAB_ETC =  0x7,
  601. +   CASHSHOP_TAB_SEARCH =  0x8
  602. +};
  603. +
  604. +// PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT
  605. +enum CASHSHOP_BUY_RESULT{
  606. +   CASHSHOP_RESULT_SUCCESS =  0x0,
  607. +   CASHSHOP_RESULT_ERROR_SYSTEM =  0x1,
  608. +   CASHSHOP_RESULT_ERROR_SHORTTAGE_CASH =  0x2,
  609. +   CASHSHOP_RESULT_ERROR_UNKONWN_ITEM =  0x3,
  610. +   CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT =  0x4,
  611. +   CASHSHOP_RESULT_ERROR_INVENTORY_ITEMCNT =  0x5,
  612. +   CASHSHOP_RESULT_ERROR_PC_STATE =  0x6,
  613. +   CASHSHOP_RESULT_ERROR_OVER_PRODUCT_TOTAL_CNT =  0x7,
  614. +   CASHSHOP_RESULT_ERROR_SOME_BUY_FAILURE =  0x8,
  615. +   CASHSHOP_RESULT_ERROR_RUNE_OVERCOUNT =  0x9,
  616. +   CASHSHOP_RESULT_ERROR_EACHITEM_OVERCOUNT =  0xa,
  617. +   CASHSHOP_RESULT_ERROR_UNKNOWN =  0xb,
  618. +   CASHSHOP_RESULT_ERROR_BUSY =  0xc,
  619. +};
  620. +
  621. +
  622. +struct cash_item_data{
  623. +   uint32 nameid;
  624. +   uint32 price;
  625. +};
  626. +
  627. +struct cash_item_db{
  628. +   struct cash_item_data** item;
  629. +   uint32 count;
  630. +};
  631. +
  632. +extern struct cash_item_db cash_shop_items[CASHSHOP_TAB_SEARCH];
  633. +
  634. +#endif /* _CASHSHOP_H_ */
  635. \ No newline at end of file
  636. Index: src/map/clif.c
  637. ===================================================================
  638. --- src/map/clif.c  (revision 17227)
  639. +++ src/map/clif.c  (working copy)
  640. @@ -42,6 +42,7 @@
  641.  #include "clif.h"
  642.  #include "mail.h"
  643.  #include "quest.h"
  644. +#include "cashshop.h"
  645.  
  646.  #include <stdio.h>
  647.  #include <stdlib.h>
  648. @@ -14424,13 +14425,13 @@
  649.     WFIFOSET(fd, packet_len(0x289));
  650.  }
  651.  
  652. -
  653. +// TODO: change this
  654. +#if PACKETVER < 20130000
  655.  /// Request to buy item(s) from cash shop (CZ_PC_BUY_CASH_POINT_ITEM).
  656.  /// 0288 <name id>.W <amount>.W
  657.  /// 0288 <name id>.W <amount>.W <kafra points>.L (PACKETVER >= 20070711)
  658.  /// 0288 <packet len>.W <kafra points>.L <count>.W { <amount>.W <name id>.W }.4B*count (PACKETVER >= 20100803)
  659. -void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
  660. -{
  661. +void clif_parse_cashshop_buy(int fd, struct map_session_data *sd){
  662.      int fail = 0;
  663.      nullpo_retv(sd);
  664.  
  665. @@ -14457,10 +14458,10 @@
  666.          }
  667.          fail = npc_cashshop_buylist(sd,points,count,item_list);
  668.  #endif
  669. -    }
  670.  
  671. -    clif_cashshop_ack(sd,fail);
  672. +       clif_cashshop_ack(sd,fail);
  673.  }
  674. +#endif
  675.  
  676.  
  677.  /// Adoption System
  678. @@ -16372,6 +16373,72 @@
  679.  #endif
  680.  }
  681.  
  682. +void clif_cashshop_open( struct map_session_data* sd ){
  683. +   WFIFOHEAD( sd->fd, 10 );
  684. +   WFIFOW( sd->fd, 0 ) = 0x845;
  685. +   WFIFOL( sd->fd, 2 ) = sd->cashPoints;
  686. +   WFIFOL( sd->fd, 6 ) = 0; // TODO: Kafra cash?
  687. +   WFIFOSET( sd->fd, 10 );
  688. +}
  689. +
  690. +void clif_parse_cashshop_open_request( int fd, struct map_session_data* sd ){
  691. +   clif_cashshop_open( sd );
  692. +}
  693. +
  694. +void clif_parse_cashshop_close( int fd, struct map_session_data* sd ){
  695. +
  696. +}
  697. +
  698. +void clif_cashshop_list( int fd ){
  699. +   int tab;
  700. +
  701. +   for( tab = CASHSHOP_TAB_NEW; tab < CASHSHOP_TAB_SEARCH; tab++ ){
  702. +       int length = 8 + cash_shop_items->count * 6;
  703. +       int i, offset;
  704. +
  705. +       WFIFOHEAD( fd, length );
  706. +       WFIFOW( fd, 0 ) = 0x8ca;
  707. +       WFIFOW( fd, 2 ) = length;
  708. +       WFIFOW( fd, 4 ) = cash_shop_items[tab].count;
  709. +       WFIFOW( fd, 6 ) = tab;
  710. +
  711. +       for( i = 0, offset = 8; i < cash_shop_items[tab].count; i++, offset += 6 ){
  712. +           WFIFOW( fd, offset ) = cash_shop_items[tab].item[i]->nameid;
  713. +           WFIFOL( fd, offset + 2 ) = cash_shop_items[tab].item[i]->price;
  714. +       }
  715. +
  716. +       WFIFOSET( fd, length );
  717. +   }
  718. +}
  719. +
  720. +void clif_parse_cashshop_list_request( int fd, struct map_session_data* sd ){
  721. +   clif_cashshop_list( fd );
  722. +}
  723. +
  724. +// TODO: change this
  725. +#if PACKETVER > 20121231
  726. +void clif_parse_cashshop_buy( int fd, struct map_session_data *sd ){
  727. +   uint16 length = RFIFOW( fd, 2 );
  728. +   uint32 count = RFIFOL( fd, 4 );
  729. +
  730. +   if( length < 8 || length < ( 8 + count * 6 ) ){
  731. +       return;
  732. +   }
  733. +
  734. +   cashshop_buylist( sd, count, (uint16 *)RFIFOP( fd, 10 ) );
  735. +}
  736. +#endif
  737. +
  738. +void clif_cashshop_result( struct map_session_data *sd, uint16 item_id, uint16 result ){
  739. +   WFIFOHEAD( sd->fd, 16 );
  740. +   WFIFOW( sd->fd, 0 ) = 0x849;
  741. +   WFIFOL( sd->fd, 2 ) = item_id;
  742. +   WFIFOW( sd->fd, 6 ) = result;
  743. +   WFIFOL( sd->fd, 8 ) = sd->cashPoints;
  744. +   WFIFOL( sd->fd, 12 ) = 0; // TODO: kafra points
  745. +   WFIFOSET( sd->fd, 16 );
  746. +}
  747. +
  748.  /*==========================================
  749.   * Main client packet processing function
  750.   *------------------------------------------*/
  751. @@ -16948,7 +17015,6 @@
  752.         {clif_parse_Auction_bid,"auctionbid"},
  753.         // Quest Log System
  754.         {clif_parse_questStateAck,"queststate"},
  755. -       {clif_parse_cashshop_buy,"cashshopbuy"},
  756.         {clif_parse_ViewPlayerEquip,"viewplayerequip"},
  757.         {clif_parse_EquipTick,"equiptickbox"},
  758.         {clif_parse_BattleChat,"battlechat"},
  759. @@ -16974,6 +17040,11 @@
  760.         {clif_parse_SearchStoreInfoNextPage,"searchstoreinfonextpage"},
  761.         {clif_parse_CloseSearchStoreInfo,"closesearchstoreinfo"},
  762.         {clif_parse_SearchStoreInfoListItemClick,"searchstoreinfolistitemclick"},
  763. +       // Cashshop
  764. +       { clif_parse_cashshop_open_request, "cashshopopen" },
  765. +       { clif_parse_cashshop_close, "cashshopclose" },
  766. +       { clif_parse_cashshop_list_request, "cashshopitemlist" },
  767. +       { clif_parse_cashshop_buy, "cashshopbuy" },
  768.         /* */
  769.         { clif_parse_MoveItem , "moveitem" },
  770.         {NULL,NULL}
  771. Index: src/map/clif.h
  772. ===================================================================
  773. --- src/map/clif.h  (revision 17227)
  774. +++ src/map/clif.h  (working copy)
  775. @@ -725,6 +725,11 @@
  776.  void clif_search_store_info_failed(struct map_session_data* sd, unsigned char reason);
  777.  void clif_open_search_store_info(struct map_session_data* sd);
  778.  void clif_search_store_info_click_ack(struct map_session_data* sd, short x, short y);
  779. +
  780. +/// Cash Shop
  781. +void clif_cashshop_result( struct map_session_data* sd, uint16 item_id, uint16 result );
  782. +void clif_cashshop_open( struct map_session_data* sd );
  783. +
  784.  /**
  785.   * 3CeAM
  786.   **/
  787. Index: src/map/itemdb.h
  788. ===================================================================
  789. --- src/map/itemdb.h    (revision 17227)
  790. +++ src/map/itemdb.h    (working copy)
  791. @@ -130,6 +130,7 @@
  792.         unsigned trade_restriction : 9; //Item restrictions mask [Skotlex]
  793.         unsigned autoequip: 1;
  794.         unsigned buyingstore : 1;
  795. +       unsigned cash : 1;
  796.     } flag;
  797.     struct {// item stacking limitation
  798.         unsigned short amount;
  799. Index: src/map/log.c
  800. ===================================================================
  801. --- src/map/log.c   (revision 17227)
  802. +++ src/map/log.c   (working copy)
  803. @@ -74,6 +74,7 @@
  804.         case LOG_TYPE_BUYING_STORE:     return 'B';  // (B)uying Store
  805.         case LOG_TYPE_LOOT:             return 'L';  // (L)oot (consumed monster pick/drop)
  806.         case LOG_TYPE_OTHER:            return 'X';  // Other
  807. +       case LOG_TYPE_CASH:             return '$';  // Cash
  808.     }
  809.  
  810.     // should not get here, fallback
  811. @@ -456,7 +457,42 @@
  812.     }
  813.  }
  814.  
  815. +/// logs cash transactions
  816. +void log_cash( struct map_session_data* sd, e_log_pick_type type, struct map_session_data* src_sd, int amount ){
  817. +   nullpo_retv( sd );
  818.  
  819. +   if( !log_config.cash )
  820. +       return;
  821. +
  822. +   if( log_config.sql_logs ){
  823. +#ifdef BETA_THREAD_TEST
  824. +       char entry[512];
  825. +       int e_length = 0;
  826. +       e_length = sprintf( entry,  LOG_QUERY " INTO `%s` ( `time`, `char_id`, `src_id`, `type`, `amount`, `map` ) VALUES ( NOW(), '%d', '%d', '%c', '%d', '%s' )",
  827. +               log_config.log_cash, sd->status.char_id, src_sd->status.char_id, log_picktype2char( type ), amount, mapindex_id2name( sd->mapindex ) );
  828. +       queryThread_log( entry, e_length );
  829. +#else
  830. +       if( SQL_ERROR == Sql_Query( logmysql_handle, LOG_QUERY " INTO `%s` ( `time`, `char_id`, `src_id`, `type`, `amount`, `map` ) VALUES ( NOW(), '%d', '%d', '%c', '%d', '%s' )",
  831. +           log_config.log_cash, sd->status.char_id, src_sd->status.char_id, log_picktype2char( type ), amount, mapindex_id2name( sd->mapindex ) ) )
  832. +       {
  833. +           Sql_ShowDebug( logmysql_handle );
  834. +           return;
  835. +       }
  836. +#endif
  837. +   }else{
  838. +       char timestring[255];
  839. +       time_t curtime;
  840. +       FILE* logfp;
  841. +
  842. +       if( ( logfp = fopen( log_config.log_cash, "a" ) ) == NULL )
  843. +           return;
  844. +       time( &curtime );
  845. +       strftime( timestring, sizeof( timestring ), "%m/%d/%Y %H:%M:%S", localtime( &curtime ) );
  846. +       fprintf( logfp, "%s - %s[%d]\t%s[%d]\t%d\t\n", timestring, src_sd->status.name, src_sd->status.account_id, sd->status.name, sd->status.account_id, amount );
  847. +       fclose( logfp );
  848. +   }
  849. +}
  850. +
  851.  void log_set_defaults(void)
  852.  {
  853.     memset(&log_config, 0, sizeof(log_config));
  854. @@ -511,6 +547,8 @@
  855.                 log_config.filter = config_switch(w2);
  856.             else if( strcmpi(w1, "log_zeny") == 0 )
  857.                 log_config.zeny = config_switch(w2);
  858. +           else if( strcmpi( w1, "log_cash" ) == 0 )
  859. +               log_config.cash = config_switch( w2 );
  860.             else if( strcmpi(w1, "log_commands") == 0 )
  861.                 log_config.commands = config_switch(w2);
  862.             else if( strcmpi(w1, "log_npc") == 0 )
  863. @@ -535,6 +573,8 @@
  864.                 safestrncpy(log_config.log_npc, w2, sizeof(log_config.log_npc));
  865.             else if( strcmpi(w1, "log_chat_db") == 0 )
  866.                 safestrncpy(log_config.log_chat, w2, sizeof(log_config.log_chat));
  867. +           else if( strcmpi( w1, "log_cash_db" ) == 0 )
  868. +               safestrncpy( log_config.log_cash, w2, sizeof( log_config.log_cash ) );
  869.             //support the import command, just like any other config
  870.             else if( strcmpi(w1,"import") == 0 )
  871.                 log_config_read(w2);
  872. @@ -577,6 +617,9 @@
  873.         {
  874.             ShowInfo("Logging Zeny transactions to %s '%s'.\n", target, log_config.log_zeny);
  875.         }
  876. +       if( log_config.cash ){
  877. +           ShowInfo( "Logging Cash transactions to %s '%s'.\n", target, log_config.log_cash );
  878. +       }
  879.     }
  880.  
  881.     return 0;
  882. Index: src/map/log.h
  883. ===================================================================
  884. --- src/map/log.h   (revision 17227)
  885. +++ src/map/log.h   (working copy)
  886. @@ -44,6 +44,7 @@
  887.     LOG_TYPE_AUCTION          = 0x04000,
  888.     LOG_TYPE_BUYING_STORE     = 0x08000,
  889.     LOG_TYPE_OTHER            = 0x10000,
  890. +   LOG_TYPE_CASH             = 0x20000,
  891.     // combinations
  892.     LOG_TYPE_LOOT             = LOG_TYPE_PICKDROP_MONSTER|LOG_TYPE_CONSUME,
  893.     // all
  894. @@ -51,12 +52,11 @@
  895.  }
  896.  e_log_pick_type;
  897.  
  898. -
  899.  /// new logs
  900.  void log_pick_pc(struct map_session_data* sd, e_log_pick_type type, int amount, struct item* itm);
  901.  void log_pick_mob(struct mob_data* md, e_log_pick_type type, int amount, struct item* itm);
  902.  void log_zeny(struct map_session_data* sd, e_log_pick_type type, struct map_session_data* src_sd, int amount);
  903. -
  904. +void log_cash( struct map_session_data* sd, e_log_pick_type type, struct map_session_data* src_sd, int amount );
  905.  void log_npc(struct map_session_data* sd, const char *message);
  906.  void log_chat(e_log_chat_type type, int type_id, int src_charid, int src_accid, const char* map, int x, int y, const char* dst_charname, const char* message);
  907.  void log_atcommand(struct map_session_data* sd, const char* message);
  908. @@ -73,9 +73,10 @@
  909.     int filter;
  910.     bool sql_logs;
  911.     bool log_chat_woe_disable;
  912. +   bool cash;
  913.     int rare_items_log,refine_items_log,price_items_log,amount_items_log; //for filter
  914.     int branch, mvpdrop, zeny, commands, npc, chat;
  915. -   char log_branch[64], log_pick[64], log_zeny[64], log_mvpdrop[64], log_gm[64], log_npc[64], log_chat[64];
  916. +   char log_branch[64], log_pick[64], log_zeny[64], log_mvpdrop[64], log_gm[64], log_npc[64], log_chat[64], log_cash[64];
  917.  }
  918.  log_config;
  919.  
  920. Index: src/map/map.c
  921. ===================================================================
  922. --- src/map/map.c   (revision 17227)
  923. +++ src/map/map.c   (working copy)
  924. @@ -46,6 +46,7 @@
  925.  #include "atcommand.h"
  926.  #include "log.h"
  927.  #include "mail.h"
  928. +#include "cashshop.h"
  929.  #include <stdio.h>
  930.  #include <stdlib.h>
  931.  #include <string.h>
  932. @@ -3596,6 +3597,7 @@
  933.     do_final_battleground();
  934.     do_final_duel();
  935.     do_final_elemental();
  936. +   do_final_cashshop();
  937.  
  938.     map_db->destroy(map_db, map_db_final);
  939.  
  940. @@ -3795,6 +3797,7 @@
  941.     do_init_clif();
  942.     do_init_script();
  943.     do_init_itemdb();
  944. +   do_init_cashshop();
  945.     do_init_skill();
  946.     do_init_mob();
  947.     do_init_pc();
  948. Index: src/map/pc.c
  949. ===================================================================
  950. --- src/map/pc.c    (revision 17227)
  951. +++ src/map/pc.c    (working copy)
  952. @@ -3690,7 +3690,9 @@
  953.     }
  954.  
  955.     pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash);
  956. +   log_cash( sd, LOG_TYPE_CASH, sd, -cash );
  957.     pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints-points);
  958. +   log_cash( sd, LOG_TYPE_NPC, sd, -points );
  959.  
  960.     if( battle_config.cashshop_show_points )
  961.     {
  962. @@ -3717,6 +3719,7 @@
  963.         }
  964.  
  965.         pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints+cash);
  966. +       log_cash( sd, LOG_TYPE_CASH, sd, cash );
  967.  
  968.         if( battle_config.cashshop_show_points )
  969.         {
  970. @@ -3740,6 +3743,7 @@
  971.         }
  972.  
  973.         pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints+points);
  974. +       log_cash( sd, LOG_TYPE_NPC, sd, points );
  975.  
  976.         if( battle_config.cashshop_show_points )
  977.         {
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement