Cashshop support
Since our neighbors were a little earlier with releasing the cash shop system, here is our version of it. It supports TXT and SQL databases and even features kafra point support. Don't forget to run your SQL updates, since this feature needs another log table for your own security. ;) Follow up to r17240 finalizing pincode feature. Should be stable now - no beta anymore. Fixes bugreport:7505 Fixed guild creation bug bugreport:7502 Implemented the new NPC range tid:81303 git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@17242 54d463be-8e91-2dee-dedb-b68131a5f0ec
This commit is contained in:
parent
5fdada6013
commit
386f0ae36e
@ -107,6 +107,8 @@ ragsrvinfo_db: ragsrvinfo
|
||||
item_db_db: item_db
|
||||
item_db_re_db: item_db_re
|
||||
item_db2_db: item_db2
|
||||
item_cash_db_db: item_cash_db
|
||||
item_cash_db2_db: item_cash_db2
|
||||
mob_db_db: mob_db
|
||||
mob_db2_db: mob_db2
|
||||
mob_skill_db_db: mob_skill_db
|
||||
|
@ -27,6 +27,7 @@
|
||||
// 0x08000 - (B) Log buying store transactions
|
||||
// 0x10000 - (X) Log all other transcations (rentals expiring/inserting cards/items removed by item_check/
|
||||
// rings deleted by divorce/pet egg (un)hatching/pet armor (un)equipping/Weapon Refine skill/Remove Trap skill)
|
||||
// 0x20000 - ($) Log cash transactions
|
||||
// Example: Log trades+vending+script items+created items: 1+2+32+1024 = 1059
|
||||
// Please note that moving items from inventory to cart and back is not logged by design.
|
||||
enable_logs: 0xFFFFF
|
||||
@ -80,6 +81,11 @@ log_branch: no
|
||||
// 0 - don't log; 1 - log any zeny changes; 2.....1000000 - minimal absolut logging zeny value
|
||||
log_zeny: 0
|
||||
|
||||
// Track Cash Changes
|
||||
// 0 - don't log
|
||||
// 1 - log any changes
|
||||
log_cash: 1
|
||||
|
||||
// Log MVP Monster Drops (Note 1)
|
||||
// Outdated. Use Pick_Log instead. But this log could be useful to keep track slayed MVPs
|
||||
log_mvpdrop: no
|
||||
@ -121,6 +127,7 @@ log_chat_woe_disable: no
|
||||
// log_npc_db: log/npclog.log
|
||||
// log_pick_db: log/picklog.log
|
||||
// log_zeny_db: log/zenylog.log
|
||||
// log_cash_db: log/cashlog.log
|
||||
|
||||
log_gm_db: atcommandlog
|
||||
log_branch_db: branchlog
|
||||
@ -129,5 +136,6 @@ log_mvpdrop_db: mvplog
|
||||
log_npc_db: npclog
|
||||
log_pick_db: picklog
|
||||
log_zeny_db: zenylog
|
||||
log_cash_db: cashlog
|
||||
|
||||
import: conf/import/log_conf.txt
|
||||
|
17
db/item_cash_db2.txt
Normal file
17
db/item_cash_db2.txt
Normal file
@ -0,0 +1,17 @@
|
||||
// This file contains the items sold in the ingame cash shop
|
||||
//
|
||||
// The structure of the file is
|
||||
// type, item ID, price
|
||||
//
|
||||
// type:
|
||||
// 0: New
|
||||
// 1: Hot
|
||||
// 2: Limited
|
||||
// 3: Rental
|
||||
// 4: Gear
|
||||
// 5: Buff
|
||||
// 6: Heal
|
||||
// 7: Other
|
||||
//
|
||||
// price:
|
||||
// price of the defined item in cash points
|
@ -1803,10 +1803,8 @@ packet_ver: 34
|
||||
0x086D,26,friendslistadd,2
|
||||
0x0897,5,hommenu,2:4
|
||||
0x0947,36,storagepassword,0
|
||||
//0x0288,-1,cashshopbuy,4:8
|
||||
0x086F,26,partyinvite2,2
|
||||
0x0888,19,wanttoconnection,2:6:10:14:18
|
||||
0x08c9,4
|
||||
0x088E,7,actionrequest,2:6
|
||||
0x089B,10,useskilltoid,2:4:6
|
||||
0x0881,5,walktoxy,2
|
||||
@ -1835,5 +1833,11 @@ packet_ver: 34
|
||||
//0x0835,2,searchstoreinfonextpage,0
|
||||
//0x0838,12,searchstoreinfolistitemclick,2:6:10
|
||||
|
||||
// New cashshop
|
||||
0x0844,2,cashshopopen,0
|
||||
0x084a,2,cashshopclose,0
|
||||
0x08c9,4,cashshopitemlist,0
|
||||
0x0848,-1,cashshopbuy,0
|
||||
|
||||
//Add new packets here
|
||||
//packet_ver: 35
|
||||
|
17
db/pre-re/item_cash_db.txt
Normal file
17
db/pre-re/item_cash_db.txt
Normal file
@ -0,0 +1,17 @@
|
||||
// This file contains the items sold in the ingame cash shop
|
||||
//
|
||||
// The structure of the file is
|
||||
// type, item ID, price
|
||||
//
|
||||
// type:
|
||||
// 0: New
|
||||
// 1: Hot
|
||||
// 2: Limited
|
||||
// 3: Rental
|
||||
// 4: Gear
|
||||
// 5: Buff
|
||||
// 6: Heal
|
||||
// 7: Other
|
||||
//
|
||||
// price:
|
||||
// price of the defined item in cash points
|
17
db/re/item_cash_db.txt
Normal file
17
db/re/item_cash_db.txt
Normal file
@ -0,0 +1,17 @@
|
||||
// This file contains the items sold in the ingame cash shop
|
||||
//
|
||||
// The structure of the file is
|
||||
// type, item ID, price
|
||||
//
|
||||
// type:
|
||||
// 0: New
|
||||
// 1: Hot
|
||||
// 2: Limited
|
||||
// 3: Rental
|
||||
// 4: Gear
|
||||
// 5: Buff
|
||||
// 6: Heal
|
||||
// 7: Other
|
||||
//
|
||||
// price:
|
||||
// price of the defined item in cash points
|
7
sql-files/item_cash_db.sql
Normal file
7
sql-files/item_cash_db.sql
Normal file
@ -0,0 +1,7 @@
|
||||
DROP TABLE IF EXISTS `item_cash_db`;
|
||||
CREATE TABLE `item_cash_db` (
|
||||
`tab` smallint(6) NOT NULL,
|
||||
`item_id` smallint(5) unsigned NOT NULL,
|
||||
`price` mediumint(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`tab`,`item_id`)
|
||||
) ENGINE=MyISAM;
|
7
sql-files/item_cash_db2.sql
Normal file
7
sql-files/item_cash_db2.sql
Normal file
@ -0,0 +1,7 @@
|
||||
DROP TABLE IF EXISTS `item_cash_db2`;
|
||||
CREATE TABLE `item_cash_db2` (
|
||||
`tab` smallint(6) NOT NULL,
|
||||
`item_id` smallint(5) unsigned NOT NULL,
|
||||
`price` mediumint(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`tab`,`item_id`)
|
||||
) ENGINE=MyISAM;
|
@ -126,3 +126,17 @@ CREATE TABLE IF NOT EXISTS `loginlog` (
|
||||
`log` varchar(255) NOT NULL default '',
|
||||
INDEX (`ip`)
|
||||
) ENGINE=MyISAM ;
|
||||
|
||||
#Database: ragnarok
|
||||
#Table: cashlog
|
||||
CREATE TABLE IF NOT EXISTS `cashlog` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`char_id` int(11) NOT NULL DEFAULT '0',
|
||||
`type` enum('T','V','P','M','S','N','D','C','A','E','I','B','$') NOT NULL DEFAULT 'S',
|
||||
`cash_type` enum('O','K','C') NOT NULL DEFAULT 'O',
|
||||
`amount` int(11) NOT NULL DEFAULT '0',
|
||||
`map` varchar(11) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `type` (`type`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1;
|
29
sql-files/upgrades/upgrade_svn17242.sql
Normal file
29
sql-files/upgrades/upgrade_svn17242.sql
Normal file
@ -0,0 +1,29 @@
|
||||
DROP TABLE IF EXISTS `cashlog`;
|
||||
|
||||
CREATE TABLE `cashlog` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
|
||||
`char_id` int(11) NOT NULL DEFAULT '0',
|
||||
`type` enum('T','V','P','M','S','N','D','C','A','E','I','B','$') NOT NULL DEFAULT 'S',
|
||||
`cash_type` enum('O','K','C') NOT NULL DEFAULT 'O',
|
||||
`amount` int(11) NOT NULL DEFAULT '0',
|
||||
`map` varchar(11) NOT NULL DEFAULT '',
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `type` (`type`)
|
||||
) ENGINE=MyISAM AUTO_INCREMENT=1;
|
||||
|
||||
DROP TABLE IF EXISTS `item_cash_db`;
|
||||
CREATE TABLE `item_cash_db` (
|
||||
`tab` smallint(6) NOT NULL,
|
||||
`item_id` smallint(5) unsigned NOT NULL,
|
||||
`price` mediumint(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`tab`,`item_id`)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
DROP TABLE IF EXISTS `item_cash_db2`;
|
||||
CREATE TABLE `item_cash_db2` (
|
||||
`tab` smallint(6) NOT NULL,
|
||||
`item_id` smallint(5) unsigned NOT NULL,
|
||||
`price` mediumint(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`tab`,`item_id`)
|
||||
) ENGINE=MyISAM;
|
@ -1053,6 +1053,10 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
|
||||
}
|
||||
memset(&p, 0, sizeof(p));
|
||||
|
||||
for( i = 0; i < MAX_CHARS; i++ ){
|
||||
sd->found_char[i] = -1;
|
||||
}
|
||||
|
||||
// read char data
|
||||
if( SQL_ERROR == SqlStmt_Prepare(stmt, "SELECT "
|
||||
"`char_id`,`char_num`,`name`,`class`,`base_level`,`job_level`,`base_exp`,`job_exp`,`zeny`,"
|
||||
@ -1106,11 +1110,6 @@ int mmo_chars_fromsql(struct char_session_data* sd, uint8* buf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 0; i < MAX_CHARS; i++ ){
|
||||
sd->found_char[i] = -1;
|
||||
sd->char_moves[i] = 0;
|
||||
}
|
||||
|
||||
for( i = 0; i < MAX_CHARS && SQL_SUCCESS == SqlStmt_NextRow(stmt); i++ )
|
||||
{
|
||||
p.last_point.map = mapindex_name2id(last_map);
|
||||
@ -4614,13 +4613,13 @@ void pincode_notifyLoginPinError( int account_id ){
|
||||
|
||||
void pincode_decrypt( uint32 userSeed, char* pin ){
|
||||
int i, pos;
|
||||
char tab[10] = {0,1,2,3,4,5,6,7,8,9};
|
||||
char tab[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
char *buf;
|
||||
uint32 multiplier = 0x3498, baseSeed = 0x881234;
|
||||
|
||||
for( i = 1; i < 10; i++ ){
|
||||
userSeed = baseSeed + userSeed * multiplier;
|
||||
pos = userSeed % (i + 1);
|
||||
pos = userSeed % ( i + 1 );
|
||||
if( i != pos ){
|
||||
tab[i] ^= tab[pos];
|
||||
tab[pos] ^= tab[i];
|
||||
@ -4628,13 +4627,13 @@ void pincode_decrypt( uint32 userSeed, char* pin ){
|
||||
}
|
||||
}
|
||||
|
||||
buf = (char *)malloc(sizeof(pin));
|
||||
memset(buf,0,PINCODE_LENGTH+1);
|
||||
buf = (char *)malloc( sizeof(char) * ( PINCODE_LENGTH + 1 ) );
|
||||
memset( buf, 0, PINCODE_LENGTH + 1 );
|
||||
for( i = 0; i < PINCODE_LENGTH; i++ ){
|
||||
sprintf(buf+i,"%d",tab[pin[i] - '0']);
|
||||
sprintf( buf + i, "%d", tab[pin[i] - '0'] );
|
||||
}
|
||||
strcpy(pin,buf);
|
||||
free(buf);
|
||||
strcpy( pin, buf );
|
||||
free( buf );
|
||||
}
|
||||
|
||||
//------------------------------------------------
|
||||
|
@ -17,7 +17,7 @@ MAP_OBJ = map.o chrif.o clif.o pc.o status.o npc.o \
|
||||
storage.o skill.o atcommand.o battle.o battleground.o \
|
||||
intif.o trade.o party.o vending.o guild.o pet.o \
|
||||
log.o mail.o date.o unit.o homunculus.o mercenary.o quest.o instance.o \
|
||||
buyingstore.o searchstore.o duel.o pc_groups.o elemental.o
|
||||
buyingstore.o searchstore.o duel.o pc_groups.o elemental.o cashshop.o
|
||||
MAP_SQL_OBJ = $(MAP_OBJ:%=obj_sql/%) \
|
||||
obj_sql/mapreg_sql.o
|
||||
MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \
|
||||
@ -25,9 +25,9 @@ MAP_H = map.h chrif.h clif.h pc.h status.h npc.h \
|
||||
storage.h skill.h atcommand.h battle.h battleground.h \
|
||||
intif.h trade.h party.h vending.h guild.h pet.h \
|
||||
log.h mail.h date.h unit.h homunculus.h mercenary.h quest.h instance.h mapreg.h \
|
||||
buyingstore.h searchstore.h duel.h pc_groups.h \
|
||||
buyingstore.h searchstore.h duel.h pc_groups.h elemental.h cashshop.h \
|
||||
../config/core.h ../config/renewal.h ../config/secure.h ../config/const.h \
|
||||
../config/classes/general.h elemental.h
|
||||
../config/classes/general.h
|
||||
|
||||
HAVE_MYSQL=@HAVE_MYSQL@
|
||||
ifeq ($(HAVE_MYSQL),yes)
|
||||
|
@ -7888,7 +7888,7 @@ ACMD_FUNC(cash)
|
||||
if( !strcmpi(command+1,"cash") )
|
||||
{
|
||||
if( value > 0 ) {
|
||||
if( (ret=pc_getcash(sd, value, 0)) >= 0){
|
||||
if( (ret=pc_getcash(sd, value, 0, LOG_TYPE_COMMAND)) >= 0){
|
||||
// If this option is set, the message is already sent by pc function
|
||||
if( !battle_config.cashshop_show_points ){
|
||||
sprintf(output, msg_txt(505), ret, sd->cashPoints);
|
||||
@ -7897,7 +7897,7 @@ ACMD_FUNC(cash)
|
||||
}
|
||||
else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value.
|
||||
} else {
|
||||
if( (ret=pc_paycash(sd, -value, 0)) >= 0){
|
||||
if( (ret=pc_paycash(sd, -value, 0, LOG_TYPE_COMMAND)) >= 0){
|
||||
// If this option is set, the message is already sent by pc function
|
||||
if( !battle_config.cashshop_show_points ){
|
||||
sprintf(output, msg_txt(410), ret, sd->cashPoints);
|
||||
@ -7910,13 +7910,13 @@ ACMD_FUNC(cash)
|
||||
else
|
||||
{ // @points
|
||||
if( value > 0 ) {
|
||||
if( (ret=pc_getcash(sd, 0, value)) >= 0){
|
||||
if( (ret=pc_getcash(sd, 0, value, LOG_TYPE_COMMAND)) >= 0){
|
||||
sprintf(output, msg_txt(506), ret, sd->kafraPoints);
|
||||
clif_disp_onlyself(sd, output, strlen(output));
|
||||
}
|
||||
else clif_displaymessage(fd, msg_txt(149)); // Unable to decrease the number/value.
|
||||
} else {
|
||||
if( (ret=pc_paycash(sd, -value, -value)) >= 0){
|
||||
if( (ret=pc_paycash(sd, -value, -value, LOG_TYPE_COMMAND)) >= 0){
|
||||
sprintf(output, msg_txt(411), ret, sd->kafraPoints);
|
||||
clif_disp_onlyself(sd, output, strlen(output));
|
||||
}
|
||||
|
301
src/map/cashshop.c
Normal file
301
src/map/cashshop.c
Normal file
@ -0,0 +1,301 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#include "../common/cbasetypes.h" // uint16, uint32
|
||||
#include "../common/malloc.h" // CREATE, RECREATE, aFree
|
||||
#include "../common/nullpo.h" // nullpo_retv
|
||||
#include "../common/showmsg.h" // ShowWarning, ShowStatus
|
||||
|
||||
#include "cashshop.h"
|
||||
#include "clif.h" // clif_cashshop_result
|
||||
#include "itemdb.h" // itemdb_exists, itemdb_isstackable, itemdb_weight, itemdb_type
|
||||
#include "pc.h" // struct map_session_data, pc_checkadditem, pc_paycash, pc_additem
|
||||
#include "pet.h" // pet_create_egg
|
||||
|
||||
#include <string.h> // memset
|
||||
#include <stdlib.h> // atoi
|
||||
|
||||
static int cashshop_parse_dbrow( char** str, const char* source, int line );
|
||||
|
||||
struct cash_item_db cash_shop_items[CASHSHOP_TAB_SEARCH];
|
||||
|
||||
extern char item_cash_db_db[32];
|
||||
extern char item_cash_db2_db[32];
|
||||
|
||||
static void cashshop_read_db_txt( void ){
|
||||
const char* filename[] = { DBPATH"item_cash_db.txt", "item_cash_db2.txt" };
|
||||
int fi;
|
||||
|
||||
for( fi = 0; fi < ARRAYLENGTH( filename ); ++fi ){
|
||||
uint32 lines = 0, count = 0;
|
||||
char line[1024];
|
||||
|
||||
char path[256];
|
||||
FILE* fp;
|
||||
|
||||
sprintf( path, "%s/%s", db_path, filename[fi] );
|
||||
fp = fopen( path, "r" );
|
||||
if( fp == NULL ) {
|
||||
ShowWarning( "itemdb_readdb: File not found \"%s\", skipping.\n", path );
|
||||
continue;
|
||||
}
|
||||
|
||||
while( fgets( line, sizeof( line ), fp ) ){
|
||||
char *str[3], *p;
|
||||
int i;
|
||||
lines++;
|
||||
|
||||
if( line[0] == '/' && line[1] == '/' )
|
||||
continue;
|
||||
|
||||
memset( str, 0, sizeof( str ) );
|
||||
|
||||
p = line;
|
||||
while( ISSPACE( *p ) )
|
||||
++p;
|
||||
if( *p == '\0' )
|
||||
continue;
|
||||
|
||||
for( i = 0; i < 2; ++i ){
|
||||
str[i] = p;
|
||||
p = strchr( p, ',' );
|
||||
|
||||
if( p == NULL )
|
||||
break;
|
||||
|
||||
*p = '\0';
|
||||
++p;
|
||||
}
|
||||
|
||||
str[2] = p;
|
||||
while( !ISSPACE( *p ) && *p != '\0' && *p != '/' )
|
||||
++p;
|
||||
|
||||
if( p == NULL ){
|
||||
ShowError("cashshop_read_db_txt: Insufficient columns in line %d of \"%s\" (item with id %d), skipping.\n", lines, path, atoi( str[0] ) );
|
||||
continue;
|
||||
}
|
||||
|
||||
if( !cashshop_parse_dbrow( str, path, lines ) )
|
||||
continue;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
ShowStatus( "Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, filename[fi] );
|
||||
}
|
||||
}
|
||||
|
||||
static int cashshop_read_db_sql( void ){
|
||||
const char* cash_db_name[] = { item_cash_db_db, item_cash_db2_db };
|
||||
int fi;
|
||||
|
||||
for( fi = 0; fi < ARRAYLENGTH( cash_db_name ); ++fi ){
|
||||
uint32 lines = 0, count = 0;
|
||||
|
||||
if( SQL_ERROR == Sql_Query( mmysql_handle, "SELECT `tab`, `item_id`, `price` FROM `%s`", cash_db_name[fi] ) ){
|
||||
Sql_ShowDebug( mmysql_handle );
|
||||
continue;
|
||||
}
|
||||
|
||||
while( SQL_SUCCESS == Sql_NextRow( mmysql_handle ) ){
|
||||
char* str[3];
|
||||
int i;
|
||||
|
||||
++lines;
|
||||
|
||||
for( i = 0; i < 3; ++i ){
|
||||
Sql_GetData( mmysql_handle, i, &str[i], NULL );
|
||||
|
||||
if( str[i] == NULL ){
|
||||
str[i] = "";
|
||||
}
|
||||
}
|
||||
|
||||
if( !cashshop_parse_dbrow( str, cash_db_name[fi], lines ) )
|
||||
continue;
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
Sql_FreeResult( mmysql_handle );
|
||||
|
||||
ShowStatus( "Done reading '"CL_WHITE"%lu"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", count, cash_db_name[fi] );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cashshop_read_db( void ){
|
||||
if( db_use_sqldbs ){
|
||||
cashshop_read_db_sql();
|
||||
}else{
|
||||
cashshop_read_db_txt();
|
||||
}
|
||||
}
|
||||
|
||||
static int cashshop_parse_dbrow( char** str, const char* source, int line ){
|
||||
uint32 nameid = atoi( str[1] );
|
||||
|
||||
if( itemdb_exists( nameid ) ){
|
||||
uint16 tab = atoi( str[0] );
|
||||
uint32 price = atoi( str[2] );
|
||||
struct cash_item_data* cid;
|
||||
int j;
|
||||
|
||||
if( tab > CASHSHOP_TAB_SEARCH ){
|
||||
ShowWarning( "cashshop_parse_dbrow: Invalid tab %d in line %d of \"%s\", skipping.\n", tab, line, source );
|
||||
return 0;
|
||||
}else if( price < 1 ){
|
||||
ShowWarning( "cashshop_parse_dbrow: Invalid price %d in line %d of \"%s\", skipping.\n", price, line, source );
|
||||
return 0;
|
||||
}
|
||||
|
||||
ARR_FIND( 0, cash_shop_items[tab].count, j, nameid == cash_shop_items[tab].item[j]->nameid );
|
||||
|
||||
if( j == cash_shop_items[tab].count ){
|
||||
RECREATE( cash_shop_items[tab].item, struct cash_item_data *, ++cash_shop_items[tab].count );
|
||||
CREATE( cash_shop_items[tab].item[ cash_shop_items[tab].count - 1], struct cash_item_data, 1 );
|
||||
cid = cash_shop_items[tab].item[ cash_shop_items[tab].count - 1];
|
||||
}else{
|
||||
cid = cash_shop_items[tab].item[j];
|
||||
}
|
||||
|
||||
cid->nameid = nameid;
|
||||
cid->price = price;
|
||||
|
||||
return 1;
|
||||
}else{
|
||||
ShowWarning( "cashshop_parse_dbrow: Invalid id %d in line %d of \"%s\", skipping.\n", nameid, line, source );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list ){
|
||||
uint32 totalcash = 0;
|
||||
uint32 totalweight = 0;
|
||||
int i,new_;
|
||||
|
||||
if( sd == NULL || item_list == NULL ){
|
||||
return;
|
||||
}else if( sd->state.trading ){
|
||||
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_PC_STATE );
|
||||
return;
|
||||
}
|
||||
|
||||
new_ = 0;
|
||||
|
||||
for( i = 0; i < n; ++i ){
|
||||
uint32 nameid = *( item_list + i * 5 );
|
||||
uint32 quantity = *( item_list + i * 5 + 2 );
|
||||
uint16 tab = *( item_list + i * 5 + 4 );
|
||||
int j;
|
||||
|
||||
if( tab > CASHSHOP_TAB_SEARCH ){
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_UNKNOWN );
|
||||
return;
|
||||
}
|
||||
|
||||
ARR_FIND( 0, cash_shop_items[tab].count, j, nameid == cash_shop_items[tab].item[j]->nameid );
|
||||
|
||||
if( j == cash_shop_items[tab].count || !itemdb_exists( nameid ) ){
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_UNKNOWN );
|
||||
return;
|
||||
}else if( !itemdb_isstackable( nameid ) && quantity > 1 ){
|
||||
uint32* quantity_ptr = (uint32*)item_list + i * 5 + 2;
|
||||
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 );
|
||||
*quantity_ptr = 1;
|
||||
}
|
||||
|
||||
switch( pc_checkadditem( sd, nameid, quantity ) ){
|
||||
case ADDITEM_EXIST:
|
||||
break;
|
||||
|
||||
case ADDITEM_NEW:
|
||||
new_++;
|
||||
break;
|
||||
|
||||
case ADDITEM_OVERAMOUNT:
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_OVER_PRODUCT_TOTAL_CNT );
|
||||
return;
|
||||
}
|
||||
|
||||
totalcash += cash_shop_items[tab].item[j]->price * quantity;
|
||||
totalweight += itemdb_weight( nameid ) * quantity;
|
||||
}
|
||||
|
||||
if( ( totalcash - kafrapoints ) > sd->cashPoints || kafrapoints > sd->kafraPoints ){
|
||||
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_SHORTTAGE_CASH );
|
||||
return;
|
||||
}else if( ( totalweight + sd->weight ) > sd->max_weight ){
|
||||
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT );
|
||||
return;
|
||||
}else if( pc_inventoryblank( sd ) < new_ ){
|
||||
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_ERROR_INVENTORY_ITEMCNT );
|
||||
return;
|
||||
}
|
||||
|
||||
pc_paycash( sd, totalcash, kafrapoints, LOG_TYPE_CASH );
|
||||
|
||||
for( i = 0; i < n; ++i ){
|
||||
uint32 nameid = *( item_list + i * 5 );
|
||||
uint32 quantity = *( item_list + i * 5 + 2 );
|
||||
|
||||
if( itemdb_type( nameid ) == IT_PETEGG ){
|
||||
pet_create_egg( sd, nameid );
|
||||
}else{
|
||||
struct item item_tmp;
|
||||
memset( &item_tmp, 0, sizeof( item_tmp ) );
|
||||
|
||||
item_tmp.nameid = nameid;
|
||||
item_tmp.identify = 1;
|
||||
|
||||
switch( pc_additem( sd, &item_tmp, quantity, LOG_TYPE_CASH ) ){
|
||||
case 2:
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT );
|
||||
return;
|
||||
case 4:
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_INVENTORY_ITEMCNT );
|
||||
return;
|
||||
case 5:
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_OVER_PRODUCT_TOTAL_CNT );
|
||||
return;
|
||||
case 7:
|
||||
clif_cashshop_result( sd, nameid, CASHSHOP_RESULT_ERROR_RUNE_OVERCOUNT );
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clif_cashshop_result( sd, 0, CASHSHOP_RESULT_SUCCESS );
|
||||
}
|
||||
|
||||
void cashshop_reloaddb( void ){
|
||||
do_final_cashshop();
|
||||
do_init_cashshop();
|
||||
}
|
||||
|
||||
int do_final_cashshop( void ){
|
||||
int tab, i;
|
||||
|
||||
for( tab = CASHSHOP_TAB_NEW; tab < CASHSHOP_TAB_SEARCH; tab++ ){
|
||||
for( i = 0; i < cash_shop_items[tab].count; i++ ){
|
||||
aFree( cash_shop_items[tab].item[i] );
|
||||
}
|
||||
|
||||
aFree( cash_shop_items[tab].item );
|
||||
}
|
||||
|
||||
memset( cash_shop_items, 0, sizeof( cash_shop_items ) );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_init_cashshop( void ){
|
||||
cashshop_read_db();
|
||||
|
||||
return 0;
|
||||
}
|
58
src/map/cashshop.h
Normal file
58
src/map/cashshop.h
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
|
||||
// For more information, see LICENCE in the main folder
|
||||
|
||||
#ifndef _CASHSHOP_H_
|
||||
#define _CASHSHOP_H_
|
||||
|
||||
#include "../common/cbasetypes.h" // uint16, uint32
|
||||
#include "pc.h" // struct map_session_data
|
||||
|
||||
int do_init_cashshop( void );
|
||||
int do_final_cashshop( void );
|
||||
void cashshop_reloaddb( void );
|
||||
void cashshop_buylist( struct map_session_data* sd, uint32 kafrapoints, int n, uint16* item_list );
|
||||
|
||||
// Taken from AEGIS
|
||||
enum CASH_SHOP_TAB_CODE{
|
||||
CASHSHOP_TAB_NEW = 0x0,
|
||||
CASHSHOP_TAB_POPULAR = 0x1,
|
||||
CASHSHOP_TAB_LIMITED = 0x2,
|
||||
CASHSHOP_TAB_RENTAL = 0x3,
|
||||
CASHSHOP_TAB_PERPETUITY = 0x4,
|
||||
CASHSHOP_TAB_BUFF = 0x5,
|
||||
CASHSHOP_TAB_RECOVERY = 0x6,
|
||||
CASHSHOP_TAB_ETC = 0x7,
|
||||
CASHSHOP_TAB_SEARCH = 0x8
|
||||
};
|
||||
|
||||
// PACKET_ZC_SE_PC_BUY_CASHITEM_RESULT
|
||||
enum CASHSHOP_BUY_RESULT{
|
||||
CASHSHOP_RESULT_SUCCESS = 0x0,
|
||||
CASHSHOP_RESULT_ERROR_SYSTEM = 0x1,
|
||||
CASHSHOP_RESULT_ERROR_SHORTTAGE_CASH = 0x2,
|
||||
CASHSHOP_RESULT_ERROR_UNKONWN_ITEM = 0x3,
|
||||
CASHSHOP_RESULT_ERROR_INVENTORY_WEIGHT = 0x4,
|
||||
CASHSHOP_RESULT_ERROR_INVENTORY_ITEMCNT = 0x5,
|
||||
CASHSHOP_RESULT_ERROR_PC_STATE = 0x6,
|
||||
CASHSHOP_RESULT_ERROR_OVER_PRODUCT_TOTAL_CNT = 0x7,
|
||||
CASHSHOP_RESULT_ERROR_SOME_BUY_FAILURE = 0x8,
|
||||
CASHSHOP_RESULT_ERROR_RUNE_OVERCOUNT = 0x9,
|
||||
CASHSHOP_RESULT_ERROR_EACHITEM_OVERCOUNT = 0xa,
|
||||
CASHSHOP_RESULT_ERROR_UNKNOWN = 0xb,
|
||||
CASHSHOP_RESULT_ERROR_BUSY = 0xc,
|
||||
};
|
||||
|
||||
|
||||
struct cash_item_data{
|
||||
uint32 nameid;
|
||||
uint32 price;
|
||||
};
|
||||
|
||||
struct cash_item_db{
|
||||
struct cash_item_data** item;
|
||||
uint32 count;
|
||||
};
|
||||
|
||||
extern struct cash_item_db cash_shop_items[CASHSHOP_TAB_SEARCH];
|
||||
|
||||
#endif /* _CASHSHOP_H_ */
|
@ -43,6 +43,7 @@
|
||||
#include "clif.h"
|
||||
#include "mail.h"
|
||||
#include "quest.h"
|
||||
#include "cashshop.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -14593,13 +14594,13 @@ void clif_cashshop_ack(struct map_session_data* sd, int error)
|
||||
WFIFOSET(fd, packet_len(0x289));
|
||||
}
|
||||
|
||||
|
||||
// TODO: find a more accurate date for this
|
||||
#if PACKETVER < 20130320
|
||||
/// Request to buy item(s) from cash shop (CZ_PC_BUY_CASH_POINT_ITEM).
|
||||
/// 0288 <name id>.W <amount>.W
|
||||
/// 0288 <name id>.W <amount>.W <kafra points>.L (PACKETVER >= 20070711)
|
||||
/// 0288 <packet len>.W <kafra points>.L <count>.W { <amount>.W <name id>.W }.4B*count (PACKETVER >= 20100803)
|
||||
void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
|
||||
{
|
||||
void clif_parse_cashshop_buy(int fd, struct map_session_data *sd){
|
||||
int fail = 0;
|
||||
nullpo_retv(sd);
|
||||
|
||||
@ -14625,10 +14626,10 @@ void clif_parse_cashshop_buy(int fd, struct map_session_data *sd)
|
||||
}
|
||||
fail = npc_cashshop_buylist(sd,points,count,item_list);
|
||||
#endif
|
||||
}
|
||||
|
||||
clif_cashshop_ack(sd,fail);
|
||||
clif_cashshop_ack(sd,fail);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/// Adoption System
|
||||
@ -16519,6 +16520,72 @@ void clif_monster_hp_bar( struct mob_data* md, int fd ) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void clif_cashshop_open( struct map_session_data* sd ){
|
||||
WFIFOHEAD( sd->fd, 10 );
|
||||
WFIFOW( sd->fd, 0 ) = 0x845;
|
||||
WFIFOL( sd->fd, 2 ) = sd->cashPoints;
|
||||
WFIFOL( sd->fd, 6 ) = sd->kafraPoints;
|
||||
WFIFOSET( sd->fd, 10 );
|
||||
}
|
||||
|
||||
void clif_parse_cashshop_open_request( int fd, struct map_session_data* sd ){
|
||||
clif_cashshop_open( sd );
|
||||
}
|
||||
|
||||
void clif_parse_cashshop_close( int fd, struct map_session_data* sd ){
|
||||
// No need to do anything here
|
||||
}
|
||||
|
||||
void clif_cashshop_list( int fd ){
|
||||
int tab;
|
||||
|
||||
for( tab = CASHSHOP_TAB_NEW; tab < CASHSHOP_TAB_SEARCH; tab++ ){
|
||||
int length = 8 + cash_shop_items->count * 6;
|
||||
int i, offset;
|
||||
|
||||
WFIFOHEAD( fd, length );
|
||||
WFIFOW( fd, 0 ) = 0x8ca;
|
||||
WFIFOW( fd, 2 ) = length;
|
||||
WFIFOW( fd, 4 ) = cash_shop_items[tab].count;
|
||||
WFIFOW( fd, 6 ) = tab;
|
||||
|
||||
for( i = 0, offset = 8; i < cash_shop_items[tab].count; i++, offset += 6 ){
|
||||
WFIFOW( fd, offset ) = cash_shop_items[tab].item[i]->nameid;
|
||||
WFIFOL( fd, offset + 2 ) = cash_shop_items[tab].item[i]->price;
|
||||
}
|
||||
|
||||
WFIFOSET( fd, length );
|
||||
}
|
||||
}
|
||||
|
||||
void clif_parse_cashshop_list_request( int fd, struct map_session_data* sd ){
|
||||
clif_cashshop_list( fd );
|
||||
}
|
||||
|
||||
// TODO: find a more accurate date for this
|
||||
#if PACKETVER >= 20130320
|
||||
void clif_parse_cashshop_buy( int fd, struct map_session_data *sd ){
|
||||
uint16 length = RFIFOW( fd, 2 );
|
||||
uint16 count = RFIFOL( fd, 4 );
|
||||
|
||||
if( length < 10 || length < ( 10 + count * 6 ) ){
|
||||
return;
|
||||
}
|
||||
|
||||
cashshop_buylist( sd, RFIFOL( fd, 6 ), count, (uint16 *)RFIFOP( fd, 10 ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
void clif_cashshop_result( struct map_session_data *sd, uint16 item_id, uint16 result ){
|
||||
WFIFOHEAD( sd->fd, 16 );
|
||||
WFIFOW( sd->fd, 0 ) = 0x849;
|
||||
WFIFOL( sd->fd, 2 ) = item_id;
|
||||
WFIFOW( sd->fd, 6 ) = result;
|
||||
WFIFOL( sd->fd, 8 ) = sd->cashPoints;
|
||||
WFIFOL( sd->fd, 12 ) = sd->kafraPoints;
|
||||
WFIFOSET( sd->fd, 16 );
|
||||
}
|
||||
|
||||
/*==========================================
|
||||
* Main client packet processing function
|
||||
*------------------------------------------*/
|
||||
@ -17097,7 +17164,6 @@ static int packetdb_readdb(void)
|
||||
{clif_parse_Auction_bid,"auctionbid"},
|
||||
// Quest Log System
|
||||
{clif_parse_questStateAck,"queststate"},
|
||||
{clif_parse_cashshop_buy,"cashshopbuy"},
|
||||
{clif_parse_ViewPlayerEquip,"viewplayerequip"},
|
||||
{clif_parse_EquipTick,"equiptickbox"},
|
||||
{clif_parse_BattleChat,"battlechat"},
|
||||
@ -17123,6 +17189,11 @@ static int packetdb_readdb(void)
|
||||
{clif_parse_SearchStoreInfoNextPage,"searchstoreinfonextpage"},
|
||||
{clif_parse_CloseSearchStoreInfo,"closesearchstoreinfo"},
|
||||
{clif_parse_SearchStoreInfoListItemClick,"searchstoreinfolistitemclick"},
|
||||
// Cashshop
|
||||
{ clif_parse_cashshop_open_request, "cashshopopen" },
|
||||
{ clif_parse_cashshop_close, "cashshopclose" },
|
||||
{ clif_parse_cashshop_list_request, "cashshopitemlist" },
|
||||
{ clif_parse_cashshop_buy, "cashshopbuy" },
|
||||
/* */
|
||||
{ clif_parse_MoveItem , "moveitem" },
|
||||
{NULL,NULL}
|
||||
|
@ -728,6 +728,11 @@ void clif_search_store_info_ack(struct map_session_data* sd);
|
||||
void clif_search_store_info_failed(struct map_session_data* sd, unsigned char reason);
|
||||
void clif_open_search_store_info(struct map_session_data* sd);
|
||||
void clif_search_store_info_click_ack(struct map_session_data* sd, short x, short y);
|
||||
|
||||
/// Cash Shop
|
||||
void clif_cashshop_result( struct map_session_data* sd, uint16 item_id, uint16 result );
|
||||
void clif_cashshop_open( struct map_session_data* sd );
|
||||
|
||||
/**
|
||||
* 3CeAM
|
||||
**/
|
||||
|
@ -401,6 +401,7 @@ int guild_create(struct map_session_data *sd, const char *name)
|
||||
int guild_created(int account_id,int guild_id)
|
||||
{
|
||||
struct map_session_data *sd=map_id2sd(account_id);
|
||||
struct guild *guild;
|
||||
|
||||
if(sd==NULL)
|
||||
return 0;
|
||||
@ -408,8 +409,14 @@ int guild_created(int account_id,int guild_id)
|
||||
clif_guild_created(sd, 2); // Creation failure (presence of the same name Guild)
|
||||
return 0;
|
||||
}
|
||||
//struct guild *g;
|
||||
sd->status.guild_id=guild_id;
|
||||
|
||||
guild = guild_search( guild_id );
|
||||
if( !guild ){ //guild not found
|
||||
return -1;
|
||||
}
|
||||
|
||||
sd->status.guild_id = guild_id;
|
||||
sd->guild = guild;
|
||||
clif_guild_created(sd,0);
|
||||
if(battle_config.guild_emperium_check)
|
||||
pc_delitem(sd,pc_search_inventory(sd,ITEMID_EMPERIUM),1,0,0,LOG_TYPE_CONSUME); //emperium consumption
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "itemdb.h"
|
||||
#include "map.h"
|
||||
#include "battle.h" // struct battle_config
|
||||
#include "cashshop.h"
|
||||
#include "script.h" // item script processing
|
||||
#include "pc.h" // W_MUSICAL, W_WHIP
|
||||
|
||||
@ -1386,6 +1387,7 @@ void itemdb_reload(void)
|
||||
|
||||
// read new data
|
||||
itemdb_read();
|
||||
cashshop_reloaddb();
|
||||
|
||||
//Epoque's awesome @reloaditemdb fix - thanks! [Ind]
|
||||
//- Fixes the need of a @reloadmobdb after a @reloaditemdb to re-link monster drop data
|
||||
|
@ -74,6 +74,7 @@ static char log_picktype2char(e_log_pick_type type)
|
||||
case LOG_TYPE_BUYING_STORE: return 'B'; // (B)uying Store
|
||||
case LOG_TYPE_LOOT: return 'L'; // (L)oot (consumed monster pick/drop)
|
||||
case LOG_TYPE_OTHER: return 'X'; // Other
|
||||
case LOG_TYPE_CASH: return '$'; // Cash
|
||||
}
|
||||
|
||||
// should not get here, fallback
|
||||
@ -99,6 +100,17 @@ static char log_chattype2char(e_log_chat_type type)
|
||||
return 'O';
|
||||
}
|
||||
|
||||
static char log_cashtype2char( e_log_cash_type type ){
|
||||
switch( type ){
|
||||
case LOG_CASH_TYPE_CASH:
|
||||
return 'C';
|
||||
case LOG_CASH_TYPE_KAFRA:
|
||||
return 'K';
|
||||
}
|
||||
|
||||
ShowDebug("log_chattype2char: Unknown chat type %d.\n", type);
|
||||
return 'O';
|
||||
}
|
||||
|
||||
/// check if this item should be logged according the settings
|
||||
static bool should_log_item(int nameid, int amount, int refine)
|
||||
@ -456,6 +468,41 @@ void log_chat(e_log_chat_type type, int type_id, int src_charid, int src_accid,
|
||||
}
|
||||
}
|
||||
|
||||
/// logs cash transactions
|
||||
void log_cash( struct map_session_data* sd, e_log_pick_type type, e_log_cash_type cash_type, int amount ){
|
||||
nullpo_retv( sd );
|
||||
|
||||
if( !log_config.cash )
|
||||
return;
|
||||
|
||||
if( log_config.sql_logs ){
|
||||
#ifdef BETA_THREAD_TEST
|
||||
char entry[512];
|
||||
int e_length = 0;
|
||||
e_length = sprintf( entry, LOG_QUERY " INTO `%s` ( `time`, `char_id`, `type`, `cash_type`, `amount`, `map` ) VALUES ( NOW(), '%d', '%c', '%c', '%d', '%s' )",
|
||||
log_config.log_cash, sd->status.char_id, log_picktype2char( type ), log_cashtype2char( cash_type ), amount, mapindex_id2name( sd->mapindex ) );
|
||||
queryThread_log( entry, e_length );
|
||||
#else
|
||||
if( SQL_ERROR == Sql_Query( logmysql_handle, LOG_QUERY " INTO `%s` ( `time`, `char_id`, `type`, `cash_type`, `amount`, `map` ) VALUES ( NOW(), '%d', '%c', '%c', '%d', '%s' )",
|
||||
log_config.log_cash, sd->status.char_id, log_picktype2char( type ), log_cashtype2char( cash_type ), amount, mapindex_id2name( sd->mapindex ) ) )
|
||||
{
|
||||
Sql_ShowDebug( logmysql_handle );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
}else{
|
||||
char timestring[255];
|
||||
time_t curtime;
|
||||
FILE* logfp;
|
||||
|
||||
if( ( logfp = fopen( log_config.log_cash, "a" ) ) == NULL )
|
||||
return;
|
||||
time( &curtime );
|
||||
strftime( timestring, sizeof( timestring ), "%m/%d/%Y %H:%M:%S", localtime( &curtime ) );
|
||||
fprintf( logfp, "%s - %s[%d]\t%d(%c)\t\n", timestring, sd->status.name, sd->status.account_id, amount, log_cashtype2char( cash_type ) );
|
||||
fclose( logfp );
|
||||
}
|
||||
}
|
||||
|
||||
void log_set_defaults(void)
|
||||
{
|
||||
@ -511,6 +558,8 @@ int log_config_read(const char* cfgName)
|
||||
log_config.filter = config_switch(w2);
|
||||
else if( strcmpi(w1, "log_zeny") == 0 )
|
||||
log_config.zeny = config_switch(w2);
|
||||
else if( strcmpi( w1, "log_cash" ) == 0 )
|
||||
log_config.cash = config_switch( w2 );
|
||||
else if( strcmpi(w1, "log_commands") == 0 )
|
||||
log_config.commands = config_switch(w2);
|
||||
else if( strcmpi(w1, "log_npc") == 0 )
|
||||
@ -535,6 +584,8 @@ int log_config_read(const char* cfgName)
|
||||
safestrncpy(log_config.log_npc, w2, sizeof(log_config.log_npc));
|
||||
else if( strcmpi(w1, "log_chat_db") == 0 )
|
||||
safestrncpy(log_config.log_chat, w2, sizeof(log_config.log_chat));
|
||||
else if( strcmpi( w1, "log_cash_db" ) == 0 )
|
||||
safestrncpy( log_config.log_cash, w2, sizeof( log_config.log_cash ) );
|
||||
//support the import command, just like any other config
|
||||
else if( strcmpi(w1,"import") == 0 )
|
||||
log_config_read(w2);
|
||||
@ -577,6 +628,9 @@ int log_config_read(const char* cfgName)
|
||||
{
|
||||
ShowInfo("Logging Zeny transactions to %s '%s'.\n", target, log_config.log_zeny);
|
||||
}
|
||||
if( log_config.cash ){
|
||||
ShowInfo( "Logging Cash transactions to %s '%s'.\n", target, log_config.log_cash );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -44,6 +44,7 @@ typedef enum e_log_pick_type
|
||||
LOG_TYPE_AUCTION = 0x04000,
|
||||
LOG_TYPE_BUYING_STORE = 0x08000,
|
||||
LOG_TYPE_OTHER = 0x10000,
|
||||
LOG_TYPE_CASH = 0x20000,
|
||||
// combinations
|
||||
LOG_TYPE_LOOT = LOG_TYPE_PICKDROP_MONSTER|LOG_TYPE_CONSUME,
|
||||
// all
|
||||
@ -51,12 +52,16 @@ typedef enum e_log_pick_type
|
||||
}
|
||||
e_log_pick_type;
|
||||
|
||||
typedef enum e_log_cash_type{
|
||||
LOG_CASH_TYPE_CASH = 0x1,
|
||||
LOG_CASH_TYPE_KAFRA = 0x2
|
||||
}e_log_cash_type;
|
||||
|
||||
/// new logs
|
||||
void log_pick_pc(struct map_session_data* sd, e_log_pick_type type, int amount, struct item* itm);
|
||||
void log_pick_mob(struct mob_data* md, e_log_pick_type type, int amount, struct item* itm);
|
||||
void log_zeny(struct map_session_data* sd, e_log_pick_type type, struct map_session_data* src_sd, int amount);
|
||||
|
||||
void log_cash( struct map_session_data* sd, e_log_pick_type type, e_log_cash_type cash_type, int amount );
|
||||
void log_npc(struct map_session_data* sd, const char *message);
|
||||
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);
|
||||
void log_atcommand(struct map_session_data* sd, const char* message);
|
||||
@ -73,9 +78,10 @@ extern struct Log_Config
|
||||
int filter;
|
||||
bool sql_logs;
|
||||
bool log_chat_woe_disable;
|
||||
bool cash;
|
||||
int rare_items_log,refine_items_log,price_items_log,amount_items_log; //for filter
|
||||
int branch, mvpdrop, zeny, commands, npc, chat;
|
||||
char log_branch[64], log_pick[64], log_zeny[64], log_mvpdrop[64], log_gm[64], log_npc[64], log_chat[64];
|
||||
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];
|
||||
}
|
||||
log_config;
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "atcommand.h"
|
||||
#include "log.h"
|
||||
#include "mail.h"
|
||||
#include "cashshop.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -69,6 +70,8 @@ int db_use_sqldbs = 0;
|
||||
char item_db_db[32] = "item_db";
|
||||
char item_db2_db[32] = "item_db2";
|
||||
char item_db_re_db[32] = "item_db_re";
|
||||
char item_cash_db_db[32] = "item_cash_db";
|
||||
char item_cash_db2_db[32] = "item_cash_db2";
|
||||
char mob_db_db[32] = "mob_db";
|
||||
char mob_db2_db[32] = "mob_db2";
|
||||
char mob_skill_db_db[32] = "mob_skill_db";
|
||||
@ -3390,6 +3393,10 @@ int inter_config_read(char *cfgName)
|
||||
else
|
||||
if(strcmpi(w1,"mob_db2_db")==0)
|
||||
strcpy(mob_db2_db,w2);
|
||||
else if( strcmpi( w1, "item_cash_db_db" ) == 0 )
|
||||
strcpy( item_cash_db_db, w2 );
|
||||
else if( strcmpi( w1, "item_cash_db2_db" ) == 0 )
|
||||
strcpy( item_cash_db2_db, w2 );
|
||||
else
|
||||
//Map Server SQL DB
|
||||
if(strcmpi(w1,"map_server_ip")==0)
|
||||
@ -3616,6 +3623,7 @@ void do_final(void)
|
||||
do_final_battleground();
|
||||
do_final_duel();
|
||||
do_final_elemental();
|
||||
do_final_cashshop();
|
||||
|
||||
map_db->destroy(map_db, map_db_final);
|
||||
|
||||
@ -3814,6 +3822,7 @@ int do_init(int argc, char *argv[])
|
||||
do_init_clif();
|
||||
do_init_script();
|
||||
do_init_itemdb();
|
||||
do_init_cashshop();
|
||||
do_init_skill();
|
||||
do_init_mob();
|
||||
do_init_pc();
|
||||
|
@ -1349,7 +1349,7 @@ int npc_cashshop_buylist(struct map_session_data *sd, int points, int count, uns
|
||||
// Payment Process ----------------------------------------------------
|
||||
if( sd->kafraPoints < points || sd->cashPoints < (vt - points) )
|
||||
return 6;
|
||||
pc_paycash(sd,vt,points);
|
||||
pc_paycash(sd,vt,points, LOG_TYPE_NPC);
|
||||
|
||||
// Delivery Process ----------------------------------------------------
|
||||
for( i = 0; i < count; i++ )
|
||||
@ -1464,7 +1464,7 @@ int npc_cashshop_buy(struct map_session_data *sd, int nameid, int amount, int po
|
||||
if( (sd->kafraPoints < points) || (sd->cashPoints < price - points) )
|
||||
return 6;
|
||||
|
||||
pc_paycash(sd, price, points);
|
||||
pc_paycash(sd, price, points, LOG_TYPE_NPC);
|
||||
|
||||
if( !pet_create_egg(sd, nameid) )
|
||||
{
|
||||
|
@ -91,7 +91,7 @@ enum actor_classes
|
||||
#define MAX_NPC_CLASS 1000
|
||||
//Checks if a given id is a valid npc id. [Skotlex]
|
||||
//Since new npcs are added all the time, the max valid value is the one before the first mob (Scorpion = 1001)
|
||||
#define npcdb_checkid(id) ( ( (id) >= 46 && (id) <= 125) || (id) == HIDDEN_WARP_CLASS || ( (id) > 400 && (id) < MAX_NPC_CLASS ) || (id) == INVISIBLE_CLASS )
|
||||
#define npcdb_checkid(id) ( ( (id) >= 46 && (id) <= 125) || (id) == HIDDEN_WARP_CLASS || ( (id) > 400 && (id) < MAX_NPC_CLASS ) || (id) == INVISIBLE_CLASS || ( id > 10000 && id < 10049 ) )
|
||||
|
||||
#ifdef PCRE_SUPPORT
|
||||
void npc_chat_finalize(struct npc_data* nd);
|
||||
|
18
src/map/pc.c
18
src/map/pc.c
@ -3660,8 +3660,7 @@ int pc_payzeny(struct map_session_data *sd,int zeny, enum e_log_pick_type type,
|
||||
* Cash Shop
|
||||
*------------------------------------------*/
|
||||
|
||||
int pc_paycash(struct map_session_data *sd, int price, int points)
|
||||
{
|
||||
int pc_paycash(struct map_session_data *sd, int price, int points, e_log_pick_type type ){
|
||||
int cash;
|
||||
nullpo_retr(-1,sd);
|
||||
|
||||
@ -3687,7 +3686,13 @@ int pc_paycash(struct map_session_data *sd, int price, int points)
|
||||
}
|
||||
|
||||
pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints-cash);
|
||||
if( cash ){
|
||||
log_cash( sd, type, LOG_CASH_TYPE_CASH, -cash );
|
||||
}
|
||||
pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints-points);
|
||||
if( points ){
|
||||
log_cash( sd, type, LOG_CASH_TYPE_KAFRA, -points );
|
||||
}
|
||||
|
||||
if( battle_config.cashshop_show_points )
|
||||
{
|
||||
@ -3698,8 +3703,7 @@ int pc_paycash(struct map_session_data *sd, int price, int points)
|
||||
return cash+points;
|
||||
}
|
||||
|
||||
int pc_getcash(struct map_session_data *sd, int cash, int points)
|
||||
{
|
||||
int pc_getcash( struct map_session_data *sd, int cash, int points, e_log_pick_type type ){
|
||||
char output[128];
|
||||
nullpo_retr(-1,sd);
|
||||
|
||||
@ -3714,6 +3718,9 @@ int pc_getcash(struct map_session_data *sd, int cash, int points)
|
||||
}
|
||||
|
||||
pc_setaccountreg(sd, "#CASHPOINTS", sd->cashPoints+cash);
|
||||
if( cash ){
|
||||
log_cash( sd, type, LOG_CASH_TYPE_CASH, cash );
|
||||
}
|
||||
|
||||
if( battle_config.cashshop_show_points )
|
||||
{
|
||||
@ -3737,6 +3744,9 @@ int pc_getcash(struct map_session_data *sd, int cash, int points)
|
||||
}
|
||||
|
||||
pc_setaccountreg(sd, "#KAFRAPOINTS", sd->kafraPoints+points);
|
||||
if( points ){
|
||||
log_cash( sd, type, LOG_CASH_TYPE_KAFRA, points );
|
||||
}
|
||||
|
||||
if( battle_config.cashshop_show_points )
|
||||
{
|
||||
|
@ -740,8 +740,8 @@ int pc_getzeny(struct map_session_data*,int, enum e_log_pick_type, struct map_se
|
||||
int pc_delitem(struct map_session_data*,int,int,int,short,e_log_pick_type);
|
||||
|
||||
// Special Shop System
|
||||
int pc_paycash(struct map_session_data *sd, int price, int points);
|
||||
int pc_getcash(struct map_session_data *sd, int cash, int points);
|
||||
int pc_paycash( struct map_session_data *sd, int price, int points, e_log_pick_type type );
|
||||
int pc_getcash( struct map_session_data *sd, int cash, int points, e_log_pick_type type );
|
||||
|
||||
int pc_cart_additem(struct map_session_data *sd,struct item *item_data,int amount,e_log_pick_type log_type);
|
||||
int pc_cart_delitem(struct map_session_data *sd,int n,int amount,int type,e_log_pick_type log_type);
|
||||
|
@ -164,6 +164,7 @@
|
||||
<ClInclude Include="..\src\map\battle.h" />
|
||||
<ClInclude Include="..\src\map\battleground.h" />
|
||||
<ClInclude Include="..\src\map\buyingstore.h" />
|
||||
<ClInclude Include="..\src\map\cashshop.h" />
|
||||
<ClInclude Include="..\src\map\chat.h" />
|
||||
<ClInclude Include="..\src\map\chrif.h" />
|
||||
<ClInclude Include="..\src\map\clif.h" />
|
||||
@ -236,6 +237,7 @@
|
||||
<ClCompile Include="..\src\map\battle.c" />
|
||||
<ClCompile Include="..\src\map\battleground.c" />
|
||||
<ClCompile Include="..\src\map\buyingstore.c" />
|
||||
<ClCompile Include="..\src\map\cashshop.c" />
|
||||
<ClCompile Include="..\src\map\chat.c" />
|
||||
<ClCompile Include="..\src\map\chrif.c" />
|
||||
<ClCompile Include="..\src\map\clif.c" />
|
||||
|
@ -13,6 +13,9 @@
|
||||
<ClCompile Include="..\src\map\buyingstore.c">
|
||||
<Filter>map_sql</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\map\cashshop.c">
|
||||
<Filter>map_sql</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\map\chat.c">
|
||||
<Filter>map_sql</Filter>
|
||||
</ClCompile>
|
||||
@ -207,6 +210,9 @@
|
||||
<ClInclude Include="..\src\map\buyingstore.h">
|
||||
<Filter>map_sql</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\map\cashshop.h">
|
||||
<Filter>map_sql</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\map\chat.h">
|
||||
<Filter>map_sql</Filter>
|
||||
</ClInclude>
|
||||
|
@ -163,11 +163,12 @@
|
||||
<ClInclude Include="..\src\common\utils.h" />
|
||||
<ClInclude Include="..\src\common\winapi.h" />
|
||||
<ClInclude Include="..\src\common\cli.h" />
|
||||
<ClInclude Include="..\src\common\msg_conf.h" />
|
||||
<ClInclude Include="..\src\common\msg_conf.h" />
|
||||
<ClInclude Include="..\src\map\atcommand.h" />
|
||||
<ClInclude Include="..\src\map\battle.h" />
|
||||
<ClInclude Include="..\src\map\battleground.h" />
|
||||
<ClInclude Include="..\src\map\buyingstore.h" />
|
||||
<ClInclude Include="..\src\map\cashshop.h" />
|
||||
<ClInclude Include="..\src\map\chat.h" />
|
||||
<ClInclude Include="..\src\map\chrif.h" />
|
||||
<ClInclude Include="..\src\map\clif.h" />
|
||||
@ -235,11 +236,12 @@
|
||||
<ClCompile Include="..\src\common\timer.c" />
|
||||
<ClCompile Include="..\src\common\utils.c" />
|
||||
<ClCompile Include="..\src\common\cli.c" />
|
||||
<ClCompile Include="..\src\common\msg_conf.c" />
|
||||
<ClCompile Include="..\src\common\msg_conf.c" />
|
||||
<ClCompile Include="..\src\map\atcommand.c" />
|
||||
<ClCompile Include="..\src\map\battle.c" />
|
||||
<ClCompile Include="..\src\map\battleground.c" />
|
||||
<ClCompile Include="..\src\map\buyingstore.c" />
|
||||
<ClCompile Include="..\src\map\cashshop.c" />
|
||||
<ClCompile Include="..\src\map\chat.c" />
|
||||
<ClCompile Include="..\src\map\chrif.c" />
|
||||
<ClCompile Include="..\src\map\clif.c" />
|
||||
@ -288,4 +290,4 @@
|
||||
<Copy SourceFiles="..\conf\import-tmpl\packet_conf.txt" DestinationFolder="..\conf\import\" ContinueOnError="true" Condition="!Exists('..\conf\import\packet_conf.txt')" />
|
||||
<Copy SourceFiles="..\conf\import-tmpl\script_conf.txt" DestinationFolder="..\conf\import\" ContinueOnError="true" Condition="!Exists('..\conf\import\script_conf.txt')" />
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
@ -193,6 +193,11 @@
|
||||
<ClCompile Include="..\src\common\raconf.c">
|
||||
<Filter>common</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\common\cli.c" />
|
||||
<ClCompile Include="..\src\common\msg_conf.c" />
|
||||
<ClCompile Include="..\src\map\cashshop.c">
|
||||
<Filter>map_sql</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\map\atcommand.h">
|
||||
@ -404,6 +409,11 @@
|
||||
<ClInclude Include="..\src\common\raconf.h">
|
||||
<Filter>common</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\common\cli.h" />
|
||||
<ClInclude Include="..\src\common\msg_conf.h" />
|
||||
<ClInclude Include="..\src\map\cashshop.h">
|
||||
<Filter>map_sql</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="common">
|
||||
|
@ -504,6 +504,14 @@
|
||||
RelativePath="..\src\map\buyingstore.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\map\cashshop.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\map\cashshop.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\map\chat.c"
|
||||
>
|
||||
|
Loading…
x
Reference in New Issue
Block a user