Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Logging] Implement Player Event Logging system #2833

Merged
merged 117 commits into from
Feb 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
117 commits
Select commit Hold shift + click to select a range
4984b02
Plumbing
Akkadius Dec 13, 2022
ea0f029
Batch processing in world
Akkadius Dec 13, 2022
c46a6b8
Cleanup
Akkadius Dec 13, 2022
77403f9
Cleanup
Akkadius Dec 13, 2022
16e38f2
Update player_event_logs.cpp
Akkadius Dec 13, 2022
4f4c921
Add player zoning event
Akkadius Dec 13, 2022
e23f08a
Use generics
Akkadius Dec 14, 2022
61c39df
Comments
Akkadius Dec 14, 2022
86b2fee
Add events
Akkadius Dec 14, 2022
bd8a1ac
Add more events
Akkadius Dec 14, 2022
fb3dcab
AA_GAIN, AA_PURCHASE, FORAGE_SUCCESS, FORAGE_FAILURE
Akkadius Dec 14, 2022
ff89091
FISH_SUCCESS, FISH_FAILURE, ITEM_DESTROY
Akkadius Dec 14, 2022
ee462ba
Add charges to ITEM_DESTROY
Akkadius Dec 14, 2022
b2bc221
WENT_ONLINE, WENT_OFFLINE
Akkadius Dec 14, 2022
20a113e
LEVEL_GAIN, LEVEL_LOSS
Akkadius Dec 14, 2022
f251631
LOOT_ITEM
Akkadius Dec 14, 2022
a56542c
MERCHANT_PURCHASE
Akkadius Dec 14, 2022
ee2217c
MERCHANT_SELL
Akkadius Dec 14, 2022
cb71e2d
SKILL_UP
Akkadius Dec 14, 2022
f2d9e13
Add events
Akkadius Dec 14, 2022
002d9d7
Add more events
Akkadius Dec 14, 2022
72a0bfd
TASK_ACCEPT, TASK_COMPLETE, and TASK_UPDATE
Kinglykrab Dec 14, 2022
368ac0c
GROUNDSPAWN_PICKUP
Kinglykrab Dec 14, 2022
d7d040f
SAY
Kinglykrab Dec 14, 2022
b6bf6af
REZ_ACCEPTED
Kinglykrab Dec 15, 2022
fa74bc7
COMBINE_FAILURE and COMBINE_SUCCESS
Kinglykrab Dec 15, 2022
0b6c6db
DROPPED_ITEM
Kinglykrab Dec 15, 2022
781a88e
DEATH
Kinglykrab Dec 15, 2022
9020bfb
SPLIT_MONEY
Kinglykrab Dec 15, 2022
e9470b5
TRADER_PURCHASE and TRADER_SELL
Kinglykrab Dec 15, 2022
dc3b808
DISCOVER_ITEM
Kinglykrab Dec 15, 2022
dd9c20f
Convert GM_COMMAND to use new macro
Akkadius Dec 15, 2022
7cba575
Convert ZONING event to use macro
Akkadius Dec 15, 2022
06d7cce
Revert some code changes
Akkadius Dec 15, 2022
0fe97ad
Revert "Revert some code changes"
Akkadius Dec 15, 2022
90ba3f7
Add cereal generation support to repositories
Akkadius Dec 15, 2022
feb84ed
TRADE
Akkadius Dec 15, 2022
ec4cd85
Formatting
Akkadius Dec 15, 2022
96c3f23
Cleanup
Akkadius Dec 15, 2022
3619a0c
Relocate discord_manager to discord folder
Akkadius Dec 16, 2022
0ffd442
Discord sending plumbing
Akkadius Dec 16, 2022
075de48
Rename UCS's Database class to UCSDatabase to be more specific and no…
Akkadius Dec 16, 2022
281c75e
More discord sending plumbing
Akkadius Dec 16, 2022
036a29e
More discord message formatting work
Akkadius Dec 16, 2022
9b495b2
More discord formatting work
Akkadius Dec 16, 2022
ca25124
Discord formatting of events
Akkadius Dec 16, 2022
c6227df
Format WENT_ONLINE, WENT_OFFLINE
Akkadius Dec 16, 2022
51b7762
Add merchant purchase event
Akkadius Dec 16, 2022
8ded7af
Handle Discord MERCHANT_SELL formatter
Akkadius Dec 16, 2022
5a2ad85
Update player_event_discord_formatter.cpp
Akkadius Dec 16, 2022
f5caee3
Tweaks
Akkadius Dec 17, 2022
9de92e2
Implement retention truncation
Akkadius Dec 17, 2022
3551e42
Put mutex locking on batch queue, put processor on its own thread
Akkadius Dec 17, 2022
3c41f5c
Process on initial bootup
Akkadius Dec 17, 2022
8407da4
Implement optional QS processing, implement keepalive from world to QS
Akkadius Dec 17, 2022
467a2e5
Reload player event settings when logs are reloaded in game
Akkadius Dec 17, 2022
6fdada6
Set settings defaults
Akkadius Dec 17, 2022
6481fbd
Update player_event_logs.cpp
Akkadius Dec 17, 2022
9ca6e2f
Update player_event_logs.cpp
Akkadius Dec 17, 2022
f88c98b
Set retention days on boot
Akkadius Dec 17, 2022
d9bf712
Update player_event_logs.cpp
Akkadius Dec 17, 2022
dcd9db0
Player Handin Event Testing.
Kinglykrab Dec 18, 2022
49cbc04
Cleanup.
Kinglykrab Dec 18, 2022
dd2c75b
Finish NPC Handin.
Kinglykrab Dec 19, 2022
c570415
set a reference to the client inside of the trade object as well for …
Akkadius Dec 19, 2022
0dfbbcc
Fix for windows _inline
Akkadius Dec 19, 2022
fcd1931
Bump to cpp20 default, ignore excessive warnings on windows
Akkadius Dec 19, 2022
b952346
Bump FMT to 6.1.2 for cpp20 compat and swap fmt::join for Strings::Join
Akkadius Dec 19, 2022
e725fa7
Windows compile fixes
Akkadius Dec 19, 2022
9aa7f7b
Update CMakeLists.txt
Akkadius Dec 19, 2022
1dd0425
Update CMakeLists.txt
Akkadius Dec 19, 2022
307ffd0
Update CMakeLists.txt
Akkadius Dec 19, 2022
0db441a
Create 2022_12_19_player_events_tables.sql
Akkadius Dec 19, 2022
d08c357
[Formatters] Work on Discord Formatters
Aeadoin Dec 19, 2022
0db8732
Handin money.
Kinglykrab Dec 19, 2022
b299aed
Format header
Akkadius Dec 20, 2022
6b25752
[Formatters] Work on Discord Formatters
Aeadoin Dec 20, 2022
d3df251
Format
Akkadius Dec 20, 2022
818039d
Format
Akkadius Dec 20, 2022
2ac8a72
[Formatters] More Formatter work, need to test further.
Aeadoin Dec 20, 2022
c95afac
[Formatters] More Work on Formatters.
Aeadoin Dec 21, 2022
eec506f
Add missing #endif
Akkadius Dec 21, 2022
9521d6d
[Formatters] Work on Formatters, fix Bot formatting in ^create help
Aeadoin Dec 21, 2022
171d0b9
NPC Handin Discord Formatter
Kinglykrab Dec 22, 2022
6f4bd6c
Update player_event_logs.cpp
Kinglykrab Dec 22, 2022
0df58f4
Discover Item Discord Formatter
Kinglykrab Dec 22, 2022
2ad5fc2
Dropped Item Discord Formatter
Kinglykrab Dec 22, 2022
c2c0286
Split Money Discord Formatter
Kinglykrab Dec 22, 2022
a2425ba
Trader Discord Formatters
Kinglykrab Dec 22, 2022
3d5bf28
Cleanup.
Kinglykrab Dec 22, 2022
db7c268
Trade Event Discord Formatter Groundwork
Kinglykrab Dec 22, 2022
2644468
SAY don't record GM commands
Akkadius Jan 4, 2023
d7c4d88
GM_Command don't record #help
Akkadius Jan 4, 2023
666b853
Update player_event_logs.cpp
Akkadius Jan 4, 2023
44723a7
Fill in more event data
Akkadius Jan 4, 2023
47b821d
Post rebase fixes
Akkadius Jan 12, 2023
3da1679
Post rebase fix
Akkadius Jan 12, 2023
9a90ba3
Discord formatting adjustments
Akkadius Jan 12, 2023
4eae10d
Add event deprecation or unimplemented tag support
Akkadius Jan 12, 2023
0cd7b5a
Trade events
Akkadius Jan 12, 2023
d71478c
Add return money and sanity checks.
Kinglykrab Jan 13, 2023
c124b57
Update schema
Akkadius Jan 13, 2023
7160da4
Update ucs.cpp
Akkadius Jan 15, 2023
7c35bff
Update client.cpp
Akkadius Jan 18, 2023
097211d
Update 2022_12_19_player_events_tables.sql
Akkadius Feb 1, 2023
08ea4a5
Implement archive single line
Akkadius Feb 1, 2023
f2ae719
Replace hackers table and functions with PossibleHack player event
Akkadius Feb 1, 2023
7efd8bd
Replace very old eventlog table since the same events are covered by …
Akkadius Feb 1, 2023
5ad10d5
Update bot_command.cpp
Akkadius Feb 1, 2023
1fd011f
Record NPC kill events ALL / Named / Raid
Akkadius Feb 1, 2023
2ad8f00
Add BatchEventProcessIntervalSeconds rule
Akkadius Feb 5, 2023
611e56b
Naming
Akkadius Feb 5, 2023
fb322e9
Update CMakeLists.txt
Akkadius Feb 5, 2023
0e0bbf2
Update database_schema.h
Akkadius Feb 5, 2023
1f0f07b
Remove logging function and methods
Akkadius Feb 5, 2023
dba02b2
DB version
Akkadius Feb 5, 2023
c9ba95f
Cleanup SendPlayerHandinEvent
Akkadius Feb 5, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ SET(common_sources
eq_stream_proxy.cpp
eqtime.cpp
event_sub.cpp
events/player_event_logs.cpp
events/player_event_discord_formatter.cpp
expedition_lockout_timer.cpp
extprofile.cpp
discord_manager.cpp
discord/discord_manager.cpp
faction.cpp
file.cpp
guild_base.cpp
Expand Down Expand Up @@ -198,7 +200,6 @@ SET(repositories
repositories/base/base_dynamic_zones_repository.h
repositories/base/base_dynamic_zone_members_repository.h
repositories/base/base_dynamic_zone_templates_repository.h
repositories/base/base_eventlog_repository.h
repositories/base/base_expeditions_repository.h
repositories/base/base_expedition_lockouts_repository.h
repositories/base/base_faction_association_repository.h
Expand All @@ -218,7 +219,6 @@ SET(repositories
repositories/base/base_guilds_repository.h
repositories/base/base_guild_ranks_repository.h
repositories/base/base_guild_relations_repository.h
repositories/base/base_hackers_repository.h
repositories/base/base_horses_repository.h
repositories/base/base_instance_list_repository.h
repositories/base/base_instance_list_player_repository.h
Expand Down Expand Up @@ -264,6 +264,8 @@ SET(repositories
repositories/base/base_pets_equipmentset_repository.h
repositories/base/base_pets_equipmentset_entries_repository.h
repositories/base/base_player_titlesets_repository.h
repositories/base/base_player_event_log_settings_repository.h
repositories/base/base_player_event_logs_repository.h
repositories/base/base_quest_globals_repository.h
repositories/base/base_raid_details_repository.h
repositories/base/base_raid_members_repository.h
Expand Down Expand Up @@ -376,7 +378,6 @@ SET(repositories
repositories/dynamic_zones_repository.h
repositories/dynamic_zone_members_repository.h
repositories/dynamic_zone_templates_repository.h
repositories/eventlog_repository.h
repositories/expeditions_repository.h
repositories/expedition_lockouts_repository.h
repositories/faction_association_repository.h
Expand All @@ -396,7 +397,6 @@ SET(repositories
repositories/guilds_repository.h
repositories/guild_ranks_repository.h
repositories/guild_relations_repository.h
repositories/hackers_repository.h
repositories/horses_repository.h
repositories/instance_list_repository.h
repositories/instance_list_player_repository.h
Expand Down Expand Up @@ -442,6 +442,8 @@ SET(repositories
repositories/pets_equipmentset_repository.h
repositories/pets_equipmentset_entries_repository.h
repositories/player_titlesets_repository.h
repositories/player_event_log_settings_repository.h
repositories/player_event_logs_repository.h
repositories/quest_globals_repository.h
repositories/raid_details_repository.h
repositories/raid_members_repository.h
Expand Down Expand Up @@ -507,7 +509,7 @@ SET(common_headers
dbcore.h
deity.h
discord/discord.h
discord_manager.h
discord/discord_manager.h
dynamic_zone_base.h
emu_constants.h
emu_limits.h
Expand All @@ -530,6 +532,9 @@ SET(common_headers
eq_stream_locator.h
eq_stream_proxy.h
eqtime.h
events/player_event_logs.h
events/player_event_discord_formatter.h
events/player_events.h
errmsg.h
event_sub.h
expedition_lockout_timer.h
Expand Down Expand Up @@ -608,6 +613,7 @@ SET(common_headers
event/event_loop.h
event/task.h
event/timer.h
json/json_archive_single_line.h
json/json.h
json/json-forwards.h
net/console_server.h
Expand Down Expand Up @@ -661,8 +667,7 @@ SET(common_headers
StackWalker/StackWalker.h
util/memory_stream.h
util/directory.h
util/uuid.h
)
util/uuid.h)

SOURCE_GROUP(Event FILES
event/event_loop.h
Expand Down
38 changes: 0 additions & 38 deletions common/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1281,44 +1281,6 @@ bool Database::MoveCharacterToZone(const char *charname, uint32 zone_id)
return results.RowsAffected() != 0;
}

bool Database::SetHackerFlag(const char* accountname, const char* charactername, const char* hacked) {
std::string query = StringFormat("INSERT INTO `hackers` (account, name, hacked) values('%s','%s','%s')", accountname, charactername, hacked);
auto results = QueryDatabase(query);

if (!results.Success()) {
return false;
}

return results.RowsAffected() != 0;
}

bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const char* hacked, const char* zone) {
//Utilize the "hacker" table, but also give zone information.
std::string query = StringFormat("INSERT INTO hackers(account,name,hacked,zone) values('%s','%s','%s','%s')", accountname, charactername, hacked, zone);
auto results = QueryDatabase(query);

if (!results.Success())
{
return false;
}

return results.RowsAffected() != 0;
}

bool Database::SetMQDetectionFlag(const char* accountname, const char* charactername, const std::string &hacked, const char* zone) {
//Utilize the "hacker" table, but also give zone information.
auto query = fmt::format("INSERT INTO hackers(account, name, hacked, zone) values('{}', '{}', '{}', '{}')",
accountname, charactername, hacked, zone);
auto results = QueryDatabase(query);

if (!results.Success())
{
return false;
}

return results.RowsAffected() != 0;
}

uint8 Database::GetRaceSkill(uint8 skillid, uint8 in_race)
{
uint16 race_cap = 0;
Expand Down
3 changes: 0 additions & 3 deletions common/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@ class Database : public DBcore {
bool MoveCharacterToZone(uint32 character_id, uint32 zone_id);
bool ReserveName(uint32 account_id, char *name);
bool SaveCharacterCreate(uint32 character_id, uint32 account_id, PlayerProfile_Struct *pp);
bool SetHackerFlag(const char *accountname, const char *charactername, const char *hacked);
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const char *hacked, const char *zone);
bool SetMQDetectionFlag(const char *accountname, const char *charactername, const std::string &hacked, const char *zone);
bool UpdateName(const char *oldname, const char *newname);
bool CopyCharacter(
const std::string& source_character_name,
Expand Down
4 changes: 2 additions & 2 deletions common/database_schema.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,13 +321,11 @@ namespace DatabaseSchema {
"discord_webhooks",
"dynamic_zone_members",
"dynamic_zones",
"eventlog",
"expedition_lockouts",
"expeditions",
"gm_ips",
"group_id",
"group_leaders",
"hackers",
"instance_list",
"ip_exemptions",
"item_tick",
Expand All @@ -343,6 +341,8 @@ namespace DatabaseSchema {
"respawn_times",
"saylink",
"server_scheduled_events",
"player_event_log_settings",
"player_event_logs"
"shared_task_activity_state",
"shared_task_dynamic_zones",
"shared_task_members",
Expand Down
104 changes: 92 additions & 12 deletions common/discord/discord.cpp
Original file line number Diff line number Diff line change
@@ -1,22 +1,17 @@
#include <cereal/archives/json.hpp>
#include <cereal/archives/binary.hpp>
#include "discord.h"
#include "../http/httplib.h"
#include "../json/json.h"
#include "../strings.h"
#include "../eqemu_logsys.h"
#include "../events/player_event_logs.h"

constexpr int MAX_RETRIES = 10;

void Discord::SendWebhookMessage(const std::string &message, const std::string &webhook_url)
{
// validate
if (webhook_url.empty()) {
LogDiscord("[webhook_url] is empty");
return;
}

// validate
if (webhook_url.find("http://") == std::string::npos && webhook_url.find("https://") == std::string::npos) {
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
if (!ValidateWebhookUrl(webhook_url)) {
return;
}

Expand All @@ -28,7 +23,7 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
std::string endpoint = Strings::Replace(webhook_url, base_url, "");

// client
httplib::Client cli(base_url.c_str());
httplib::Client cli(base_url);
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
Expand All @@ -46,9 +41,9 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
int retries = 0;
int retry_timer = 1000;
while (retry) {
if (auto res = cli.Post(endpoint.c_str(), payload.str(), "application/json")) {
if (auto res = cli.Post(endpoint, payload.str(), "application/json")) {
if (res->status != 200 && res->status != 204) {
LogError("Code [{}] Error [{}]", res->status, res->body);
LogError("[Discord Client] Code [{}] Error [{}]", res->status, res->body);
}
if (res->status == 429) {
if (!res->body.empty()) {
Expand Down Expand Up @@ -81,6 +76,74 @@ void Discord::SendWebhookMessage(const std::string &message, const std::string &
}
}

void Discord::SendPlayerEventMessage(
const PlayerEvent::PlayerEventContainer &e,
const std::string &webhook_url
)
{
if (!ValidateWebhookUrl(webhook_url)) {
return;
}

auto s = Strings::Split(webhook_url, '/');

// url
std::string base_url = fmt::format("{}//{}", s[0], s[2]);
std::string endpoint = Strings::Replace(webhook_url, base_url, "");

// client
httplib::Client cli(base_url);
cli.set_connection_timeout(0, 15000000); // 15 sec
cli.set_read_timeout(15, 0); // 15 seconds
cli.set_write_timeout(15, 0); // 15 seconds
httplib::Headers headers = {
{"Content-Type", "application/json"}
};

std::string payload = PlayerEventLogs::GetDiscordPayloadFromEvent(e);
if (payload.empty()) {
return;
}

bool retry = true;
int retries = 0;
int retry_timer = 1000;
while (retry) {
if (auto res = cli.Post(endpoint, payload, "application/json")) {
if (res->status != 200 && res->status != 204) {
LogError("Code [{}] Error [{}]", res->status, res->body);
}
if (res->status == 429) {
if (!res->body.empty()) {
std::stringstream ss(res->body);
Json::Value response;

try {
ss >> response;
}
catch (std::exception const &ex) {
LogDiscord("JSON serialization failure [{}] via [{}]", ex.what(), res->body);
}

retry_timer = std::stoi(response["retry_after"].asString()) + 500;
}

LogDiscord("Rate limited... retrying message in [{}ms]", retry_timer);
std::this_thread::sleep_for(std::chrono::milliseconds(retry_timer + 500));
}
if (res->status == 204) {
retry = false;
}
if (retries > MAX_RETRIES) {
LogDiscord("Retries exceeded for player event message");
retry = false;
}

retries++;
}
}
}

std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string &message)
{
if (category_id == Logs::LogCategory::MySQLQuery) {
Expand All @@ -89,3 +152,20 @@ std::string Discord::FormatDiscordMessage(uint16 category_id, const std::string

return message + "\n";
}

bool Discord::ValidateWebhookUrl(const std::string &webhook_url)
{
// validate
if (webhook_url.empty()) {
LogDiscord("[webhook_url] is empty");
return false;
}

// validate
if (!Strings::Contains(webhook_url, "http://") && !Strings::Contains(webhook_url, "https://")) {
LogDiscord("[webhook_url] [{}] does not contain a valid http/s prefix.", webhook_url);
return false;
}

return true;
}
5 changes: 5 additions & 0 deletions common/discord/discord.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@

#include <string>
#include "../types.h"
#include "../http/httplib.h"
#include "../repositories/player_event_logs_repository.h"
#include "../events/player_events.h"

class Discord {
public:
static void SendWebhookMessage(const std::string& message, const std::string& webhook_url);
static std::string FormatDiscordMessage(uint16 category_id, const std::string& message);
static void SendPlayerEventMessage(const PlayerEvent::PlayerEventContainer& e, const std::string &webhook_url);
static bool ValidateWebhookUrl(const std::string &webhook_url);
};


Expand Down
14 changes: 10 additions & 4 deletions common/discord_manager.cpp → common/discord/discord_manager.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#include "discord_manager.h"
#include "../common/discord/discord.h"
#include "../common/eqemu_logsys.h"
#include "../common/strings.h"
#include "../../common/discord/discord.h"
#include "../events/player_event_logs.h"

void DiscordManager::QueueWebhookMessage(uint32 webhook_id, const std::string &message)
{
Expand Down Expand Up @@ -55,7 +54,6 @@ void DiscordManager::ProcessMessageQueue()
message = "";
}
}

// final flush
if (!message.empty()) {
Discord::SendWebhookMessage(
Expand All @@ -67,3 +65,11 @@ void DiscordManager::ProcessMessageQueue()
webhook_message_queue.clear();
webhook_queue_lock.unlock();
}

void DiscordManager::QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e)
{
auto w = player_event_logs.GetDiscordWebhookUrlFromEventType(e.player_event_log.event_type_id);
if (!w.empty()) {
Discord::SendPlayerEventMessage(e, w);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,15 @@
#include <mutex>
#include <map>
#include <vector>
#include "../common/types.h"
#include "../../common/types.h"
#include "../repositories/player_event_logs_repository.h"
#include "../events/player_events.h"

class DiscordManager {
public:
void QueueWebhookMessage(uint32 webhook_id, const std::string& message);
void ProcessMessageQueue();
void QueuePlayerEventMessage(const PlayerEvent::PlayerEventContainer& e);
private:
std::mutex webhook_queue_lock{};
std::map<uint32, std::vector<std::string>> webhook_message_queue{};
Expand Down
Loading