205 lines
6.9 KiB
C++
205 lines
6.9 KiB
C++
/**
|
|
* MaNGOS is a full featured server for World of Warcraft, supporting
|
|
* the following clients: 1.12.x, 2.4.3, 3.3.5a, 4.3.4a and 5.4.8
|
|
*
|
|
* Copyright (C) 2005-2020 MaNGOS <https://getmangos.eu>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* World of Warcraft, and all World of Warcraft or Warcraft art, images,
|
|
* and lore are copyrighted by Blizzard Entertainment, Inc.
|
|
*/
|
|
|
|
#ifndef MANGOS_H_PLAYERLOGGER
|
|
#define MANGOS_H_PLAYERLOGGER
|
|
|
|
#include "Platform/Define.h"
|
|
#include <vector>
|
|
|
|
class Player;
|
|
class ObjectGuid;
|
|
|
|
enum PlayerLogEntity
|
|
{
|
|
PLAYER_LOG_DAMAGE_GET = 0,
|
|
PLAYER_LOG_DAMAGE_DONE = 1,
|
|
PLAYER_LOG_LOOTING = 2,
|
|
PLAYER_LOG_TRADE = 3,
|
|
PLAYER_LOG_KILL = 4,
|
|
PLAYER_LOG_POSITION = 5,
|
|
PLAYER_LOG_PROGRESS = 6,
|
|
};
|
|
#define MAX_PLAYER_LOG_ENTITIES 7
|
|
|
|
enum PlayerLogMask
|
|
{
|
|
PLAYER_LOGMASK_DAMAGE_GET = 1,
|
|
PLAYER_LOGMASK_DAMAGE_DONE = 2,
|
|
PLAYER_LOGMASK_LOOTING = 4,
|
|
PLAYER_LOGMASK_TRADE = 8,
|
|
PLAYER_LOGMASK_KILL = 0x10,
|
|
PLAYER_LOGMASK_POSITION = 0x20,
|
|
PLAYER_LOGMASK_PROGRESS = 0x40,
|
|
};
|
|
#define PLAYER_LOGMASK_ANYTHING PlayerLogMask((1 << MAX_PLAYER_LOG_ENTITIES)-1)
|
|
|
|
enum ProgressType
|
|
{
|
|
PROGRESS_LEVEL = 0,
|
|
PROGRESS_REPUTATION = 1,
|
|
PROGRESS_BOSS_KILL = 3,
|
|
PROGRESS_PET_LEVEL = 2,
|
|
};
|
|
|
|
struct PlayerLogBase
|
|
{
|
|
uint32 timestamp;
|
|
|
|
PlayerLogBase(uint32 _time) : timestamp(_time) {}
|
|
};
|
|
typedef std::vector<PlayerLogBase> PlayerLogBaseType;
|
|
|
|
struct PlayerLogDamage : public PlayerLogBase // 10 bytes
|
|
{
|
|
uint16 dmgUnit; // guid for player, entry with highest bit set for mob incl. pet/guardian
|
|
int16 damage; // if negative then it's heal
|
|
uint16 spell; // 0 for melee autoattack
|
|
|
|
void SetCreature(bool on) { if (on) dmgUnit |= 0x8000; else dmgUnit &= 0x7FFF; }
|
|
bool IsPlayer() const { return (dmgUnit & 0x8000) == 0; }
|
|
bool IsAutoAttack() const { return spell == 0; }
|
|
bool GetHeal() const { return -damage; }
|
|
uint16 GetId() const { return dmgUnit & 0x7FFF; }
|
|
|
|
PlayerLogDamage(uint32 _time) : PlayerLogBase(_time) {}
|
|
};
|
|
|
|
enum LootSourceType
|
|
{
|
|
LOOTSOURCE_CREATURE = 0,
|
|
LOOTSOURCE_GAMEOBJECT = 1,
|
|
LOOTSOURCE_SPELL = 2,
|
|
LOOTSOURCE_VENDOR = 3,
|
|
LOOTSOURCE_LETTER = 4,
|
|
};
|
|
|
|
struct PlayerLogLooting : public PlayerLogBase // 16 bytes
|
|
{
|
|
uint32 droppedBy; // entry of object, depends on sourceType
|
|
uint32 itemGuid; // item GUIDlow
|
|
uint32 itemEntry; // item entry, packet with LootSourceType
|
|
|
|
LootSourceType GetLootSourceType() const { return LootSourceType((itemEntry >> 24) & 0xFF); }
|
|
void SetLootSourceType(LootSourceType ltype) { itemEntry &= 0x00FFFFFF; itemEntry |= ltype << 24; }
|
|
uint32 GetItemEntry() const { return itemEntry & 0x00FFFFFF; }
|
|
|
|
PlayerLogLooting(uint32 _time) : PlayerLogBase(_time) {}
|
|
};
|
|
|
|
struct PlayerLogTrading : public PlayerLogBase // 14 bytes
|
|
{
|
|
uint32 itemGuid; // item GUIDlow
|
|
uint32 itemEntry; // item entry, with highest bit: =1 item lost, =0 item aquired
|
|
uint16 partner; // GUID of the player - trade partner; 0 if no partner (item sold/destroyed)
|
|
|
|
bool IsItemAquired() const { return (itemEntry & 0x80000000) == 0; }
|
|
void SetItemAquired(bool aquired) { if (aquired) itemEntry &= 0x7FFFFFFF; else itemEntry |= 0x80000000; }
|
|
uint32 GetItemEntry() const { return itemEntry & 0x7FFFFFFF; }
|
|
|
|
PlayerLogTrading(uint32 _time) : PlayerLogBase(_time) {}
|
|
};
|
|
|
|
struct PlayerLogKilling : public PlayerLogBase // 12 bytes
|
|
{
|
|
uint32 unitGuid; // GUID of unit
|
|
uint32 unitEntry; // entry of the unit (highest bit: 1 unit is killer, 0 unit is victim)
|
|
|
|
bool IsKill() const { return (unitEntry & 0x80000000) == 0; }
|
|
void SetKill(bool on) { if (on) unitEntry &= 0x7FFFFFFF; else unitEntry |= 0x80000000; }
|
|
uint32 GetUnitEntry() const { return unitEntry & 0x7FFFFFFF; }
|
|
|
|
PlayerLogKilling(uint32 _time) : PlayerLogBase(_time) {}
|
|
};
|
|
|
|
struct PlayerLogPosition : public PlayerLogBase // 18 bytes
|
|
{
|
|
float x, y, z;
|
|
uint16 map;
|
|
|
|
PlayerLogPosition(uint32 _time) : PlayerLogBase(_time) {}
|
|
};
|
|
|
|
struct PlayerLogProgress : public PlayerLogPosition // 18+4=22 bytes
|
|
{
|
|
uint8 progressType; // enum ProgressType
|
|
uint8 level; // level achieved
|
|
uint16 data; // misc data, depends on ProgressType (like faction ID for reputation)
|
|
|
|
PlayerLogProgress(uint32 _time) : PlayerLogPosition(_time) {}
|
|
};
|
|
|
|
class PlayerLogger
|
|
{
|
|
public:
|
|
PlayerLogger(ObjectGuid const & guid);
|
|
~PlayerLogger();
|
|
|
|
static inline PlayerLogMask CalcLogMask(PlayerLogEntity entity) { return PlayerLogMask(1 << entity); }
|
|
|
|
// active logs check
|
|
bool IsLoggingActive(PlayerLogMask mask) const { return (mask & logActiveMask) != 0; }
|
|
bool IsLoggingActive(PlayerLogEntity entity) const { return IsLoggingActive(CalcLogMask(entity)); }
|
|
|
|
// check active loggers and init missing ones
|
|
void Initialize(PlayerLogEntity, uint32 maxLength = 0);
|
|
|
|
// remove entries of type PlayerLogEntity
|
|
void Clean(PlayerLogMask);
|
|
|
|
// save to DB entries
|
|
bool SaveToDB(PlayerLogMask, bool removeSaved = true, bool insideTransaction = false);
|
|
|
|
// start logging for PLAYER_LOG_DAMAGE
|
|
void StartCombatLogging();
|
|
|
|
// start logging for strictly timed logs
|
|
void StartLogging(PlayerLogEntity);
|
|
|
|
// stop logging - returns number of entries logged currently
|
|
uint32 Stop(PlayerLogEntity);
|
|
|
|
// check and limit the total size of the log dropping older entries
|
|
void CheckAndTruncate(PlayerLogMask, uint32 maxRecords);
|
|
|
|
// logging itself
|
|
void LogDamage(bool done, uint16 damage, uint16 heal, ObjectGuid const & unitGuid, uint16 spell);
|
|
void LogLooting(LootSourceType type, ObjectGuid const & droppedBy, ObjectGuid const & itemGuid, uint32 id);
|
|
void LogTrading(bool aquire, ObjectGuid const & partner, ObjectGuid const & itemGuid);
|
|
void LogKilling(bool killedEnemy, ObjectGuid const & unitGuid);
|
|
void LogPosition();
|
|
void LogProgress(ProgressType type, uint8 achieve, uint16 misc = 0);
|
|
|
|
private:
|
|
inline void SetLogActiveMask(PlayerLogEntity entity, bool on);
|
|
Player* GetPlayer() const;
|
|
void FillPosition(PlayerLogPosition* log, Player* me);
|
|
|
|
uint32 playerGuid;
|
|
|
|
std::vector<PlayerLogBase>* data[MAX_PLAYER_LOG_ENTITIES];
|
|
uint8 logActiveMask;
|
|
};
|
|
|
|
#endif |