diff --git a/conf/log_athena.conf b/conf/log_athena.conf index 39b0169838..26666a78e0 100644 --- a/conf/log_athena.conf +++ b/conf/log_athena.conf @@ -121,6 +121,12 @@ log_chat: 0 // Disable chat logging when WoE is running? (Note 1) log_chat_woe_disable: no +// Log item used for feeding to its own table? (Bitmask) +// 0: Disabled +// 1: Pet +// 2: Homunculus +log_feeding: 3 + //Time-stamp format which will be printed for log file. //Can at most be 20 characters long. //Common formats: @@ -142,6 +148,7 @@ log_timestamp_format: %m/%d/%Y %H:%M:%S // log_pick_db: log/picklog.log // log_zeny_db: log/zenylog.log // log_cash_db: log/cashlog.log +// log_feeding_db: log/feedinglog.log log_gm_db: atcommandlog log_branch_db: branchlog @@ -151,5 +158,6 @@ log_npc_db: npclog log_pick_db: picklog log_zeny_db: zenylog log_cash_db: cashlog +log_feeding_db: feedinglog import: conf/import/log_conf.txt diff --git a/sql-files/logs.sql b/sql-files/logs.sql index 035e8f017f..1b9c82b061 100644 --- a/sql-files/logs.sql +++ b/sql-files/logs.sql @@ -70,6 +70,25 @@ CREATE TABLE IF NOT EXISTS `chatlog` ( INDEX (`src_charid`) ) ENGINE=MyISAM AUTO_INCREMENT=1; +-- +-- Table structure for table `feedinglog` +-- + +CREATE TABLE IF NOT EXISTS `feedinglog` ( + `id` INT(11) NOT NULL AUTO_INCREMENT, + `time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00', + `char_id` INT(11) NOT NULL, + `target_id` INT(11) NOT NULL, + `target_class` SMALLINT(11) NOT NULL, + `type` ENUM('P','H','O') NOT NULL, -- P: Pet, H: Homunculus, O: Other + `intimacy` INT(11) UNSIGNED NOT NULL, + `item_id` SMALLINT(5) UNSIGNED NOT NULL, + `map` VARCHAR(11) NOT NULL, + `x` SMALLINT(5) UNSIGNED NOT NULL, + `y` SMALLINT(5) UNSIGNED NOT NULL, + PRIMARY KEY (`id`) +) ENGINE = MyISAM AUTO_INCREMENT = 1; + -- -- Table structure for table `loginlog` -- diff --git a/src/map/homunculus.c b/src/map/homunculus.c index f5024a8734..6fbbbf387e 100644 --- a/src/map/homunculus.c +++ b/src/map/homunculus.c @@ -845,6 +845,8 @@ int hom_food(struct map_session_data *sd, struct homun_data *hd) if(hd->homunculus.hunger > 100) hd->homunculus.hunger = 100; + log_feeding(sd, LOG_FEED_HOMUNCULUS, foodID); + clif_emotion(&hd->bl,emotion); clif_send_homdata(sd,SP_HUNGRY,hd->homunculus.hunger); clif_send_homdata(sd,SP_INTIMATE,hd->homunculus.intimacy / 100); diff --git a/src/map/log.c b/src/map/log.c index c51b2c14cb..45cdd543ad 100644 --- a/src/map/log.c +++ b/src/map/log.c @@ -9,8 +9,10 @@ #include "map.h" #include "battle.h" #include "itemdb.h" +#include "homunculus.h" #include "log.h" #include "mob.h" +#include "pet.h" #include "pc.h" #include @@ -116,6 +118,18 @@ static char log_cashtype2char( e_log_cash_type type ){ return 'O'; } +static char log_feedingtype2char(e_log_feeding_type type) { + switch(type) { + case LOG_FEED_HOMUNCULUS: + return 'H'; + case LOG_FEED_PET: + return 'P'; + } + + ShowDebug("log_feedingtype2char: Unknown feeding type %d.\n", type); + return 'O'; +} + /// check if this item should be logged according the settings static bool should_log_item(unsigned short nameid, int amount, int refine) { @@ -508,6 +522,67 @@ void log_cash( struct map_session_data* sd, e_log_pick_type type, e_log_cash_typ } } +/** + * Log feeding activity + * @param sd Player, feeder + * @param type Log type, @see e_log_feeding_type + * @param nameid Item used as food + **/ +void log_feeding(struct map_session_data *sd, e_log_feeding_type type, unsigned short nameid) { + unsigned int target_id = 0, intimacy = 0; + unsigned short target_class = 0; + + nullpo_retv( sd ); + + if (!(log_config.feeding&type)) + return; + + switch (type) { + case LOG_FEED_HOMUNCULUS: + if (sd->hd) { + target_id = sd->hd->homunculus.hom_id; + target_class = sd->hd->homunculus.class_; + intimacy = sd->hd->homunculus.intimacy; + } + break; + case LOG_FEED_PET: + if (sd->pd) { + target_id = sd->pd->pet.pet_id; + target_class = sd->pd->pet.class_; + intimacy = sd->pd->pet.intimate; + } + break; + } + + 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`, `target_id`, `target_class`, `type`, `intimacy`, `item_id`, `map`, `x`, `y`) VALUES ( NOW(), '%"PRIu32"', '%"PRIu32"', '%hu', '%c', '%"PRIu32"', '%hu', '%s', '%hu', '%hu' )", + log_config.log_feeding, sd->status.char_id, target_id, target_class, log_feedingtype2char(type), intimacy, nameid, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y); + queryThread_log(entry, e_length); +#else + if (SQL_ERROR == Sql_Query(logmysql_handle, LOG_QUERY " INTO `%s` (`time`, `char_id`, `target_id`, `target_class`, `type`, `intimacy`, `item_id`, `map`, `x`, `y`) VALUES ( NOW(), '%"PRIu32"', '%"PRIu32"', '%hu', '%c', '%"PRIu32"', '%hu', '%s', '%hu', '%hu' )", + log_config.log_feeding, sd->status.char_id, target_id, target_class, log_feedingtype2char(type), intimacy, nameid, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y)) + { + Sql_ShowDebug(logmysql_handle); + return; + } +#endif + } else { + char timestring[255]; + time_t curtime; + FILE* logfp; + + if ((logfp = fopen(log_config.log_feeding, "a")) == NULL) + return; + time(&curtime); + strftime(timestring, sizeof(timestring), log_timestamp_format, localtime(&curtime)); + fprintf(logfp, "%s - %s[%d]\t%d\t%d(%c)\t%d\t%hu\t%s\t%hu,%hu\n", timestring, sd->status.name, sd->status.char_id, target_id, target_class, log_feedingtype2char(type), intimacy, nameid, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y); + fclose(logfp); + } +} + void log_set_defaults(void) { memset(&log_config, 0, sizeof(log_config)); @@ -574,6 +649,8 @@ int log_config_read(const char* cfgName) log_config.chat = config_switch(w2); else if( strcmpi(w1, "log_mvpdrop") == 0 ) log_config.mvpdrop = config_switch(w2); + else if( strcmpi(w1, "log_feeding") == 0 ) + log_config.feeding = config_switch(w2); else if( strcmpi(w1, "log_chat_woe_disable") == 0 ) log_config.log_chat_woe_disable = (bool)config_switch(w2); else if( strcmpi(w1, "log_branch_db") == 0 ) @@ -592,6 +669,8 @@ int log_config_read(const char* cfgName) 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 ) ); + else if( strcmpi( w1, "log_feeding_db" ) == 0 ) + safestrncpy( log_config.log_feeding, w2, sizeof( log_config.log_feeding ) ); // log file timestamp format else if( strcmpi( w1, "log_timestamp_format" ) == 0 ) safestrncpy(log_timestamp_format, w2, sizeof(log_timestamp_format)); @@ -640,6 +719,9 @@ int log_config_read(const char* cfgName) if( log_config.cash ){ ShowInfo( "Logging Cash transactions to %s '%s'.\n", target, log_config.log_cash ); } + if( log_config.feeding ){ + ShowInfo( "Logging Feeding items to %s '%s'.\n", target, log_config.log_feeding ); + } } return 0; diff --git a/src/map/log.h b/src/map/log.h index bba93d7a15..73463b05d2 100644 --- a/src/map/log.h +++ b/src/map/log.h @@ -59,6 +59,11 @@ typedef enum e_log_cash_type LOG_CASH_TYPE_KAFRA = 0x2 } e_log_cash_type; +typedef enum e_log_feeding_type { + LOG_FEED_HOMUNCULUS = 0x1, + LOG_FEED_PET = 0x2, +} e_log_feeding_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); @@ -67,6 +72,7 @@ void log_cash( struct map_session_data* sd, e_log_pick_type type, e_log_cash_typ 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); +void log_feeding(struct map_session_data *sd, e_log_feeding_type type, unsigned short nameid); /// old, but useful logs void log_branch(struct map_session_data* sd); @@ -83,7 +89,9 @@ extern struct Log_Config bool cash; int rare_items_log,refine_items_log,price_items_log,amount_items_log; //for filter int branch, mvpdrop, zeny, commands, npc, chat; + unsigned feeding : 2; 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]; + char log_feeding[64]; } log_config; #ifdef BETA_THREAD_TEST diff --git a/src/map/pet.c b/src/map/pet.c index a0ccf268e7..9a45b8bfa4 100644 --- a/src/map/pet.c +++ b/src/map/pet.c @@ -995,6 +995,8 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd) if( pd->pet.hungry > 100 ) pd->pet.hungry = 100; + log_feeding(sd, LOG_FEED_PET, pd->petDB->FoodID); + clif_send_petdata(sd,pd,2,pd->pet.hungry); clif_send_petdata(sd,pd,1,pd->pet.intimate); clif_pet_food(sd,pd->petDB->FoodID,1);