feat: Added logs_ip_action + more (#1157)

This commit is contained in:
Nefertumm
2019-02-08 19:52:22 -03:00
committed by Francesco Borzì
parent 6750fd5a73
commit 2a71b2a666
19 changed files with 564 additions and 45 deletions

View File

@@ -347,6 +347,7 @@ public:
if (!AccountMgr::CheckPassword(handler->GetSession()->GetAccountId(), std::string(oldPassword)))
{
handler->SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD);
sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
return false;
}
@@ -354,6 +355,7 @@ public:
if (strcmp(newPassword, passwordConfirmation) != 0)
{
handler->SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH);
sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
return false;
}
@@ -363,9 +365,11 @@ public:
{
case AOR_OK:
handler->SendSysMessage(LANG_COMMAND_PASSWORD);
sScriptMgr->OnPasswordChange(handler->GetSession()->GetAccountId());
break;
case AOR_PASS_TOO_LONG:
handler->SendSysMessage(LANG_PASSWORD_TOO_LONG);
sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
return false;
default:

View File

@@ -6,6 +6,7 @@
#include "ScriptLoader.h"
#include "ScriptMgr.h"
#include "World.h"
// spells
void AddSC_deathknight_spell_scripts();
@@ -73,6 +74,7 @@ void AddSC_npc_innkeeper();
void AddSC_npcs_special();
void AddSC_npc_taxi();
void AddSC_achievement_scripts();
void AddSC_action_ip_logger();
//events
void AddSC_event_brewfest_scripts();
@@ -577,6 +579,7 @@ void AddSC_outdoorpvp_gh();
// player
void AddSC_chat_log();
void AddSC_character_creation();
void AddSC_action_ip_logger();
#endif
@@ -650,8 +653,9 @@ void AddWorldScripts()
AddSC_npcs_special();
AddSC_npc_taxi();
AddSC_achievement_scripts();
AddSC_chat_log();
AddSC_chat_log(); // location: scripts\World\chat_log.cpp
AddSC_character_creation();
AddSC_action_ip_logger(); // location: scripts\World\action_ip_logger.cpp
#endif
}

View File

@@ -23,6 +23,7 @@ set(scripts_STAT_SRCS
${AC_SCRIPTS_DIR}/World/npc_taxi.cpp
${AC_SCRIPTS_DIR}/World/npcs_special.cpp
${AC_SCRIPTS_DIR}/World/character_creation.cpp
${AC_SCRIPTS_DIR}/World/action_ip_logger.cpp
)
AC_ADD_SCRIPT_LOADER("World" "ScriptLoader.h")

View File

@@ -0,0 +1,312 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
*/
#include "ScriptMgr.h"
#include "Channel.h"
#include "Guild.h"
#include "Group.h"
enum IPLoggingTypes
{
// AccountActionIpLogger();
ACCOUNT_LOGIN = 0,
ACCOUNT_FAIL_LOGIN = 1,
ACCOUNT_CHANGE_PW = 2,
ACCOUNT_CHANGE_PW_FAIL = 3, // Only two types of account changes exist...
ACCOUNT_CHANGE_EMAIL = 4,
ACCOUNT_CHANGE_EMAIL_FAIL = 5, // ...so we log them individually
// OBSOLETE - ACCOUNT_LOGOUT = 6, /* Can not be logged. We still keep the type however */
// CharacterActionIpLogger();
CHARACTER_CREATE = 7,
CHARACTER_LOGIN = 8,
CHARACTER_LOGOUT = 9,
// CharacterDeleteActionIpLogger();
CHARACTER_DELETE = 10,
CHARACTER_FAILED_DELETE = 11,
// AccountActionIpLogger(), CharacterActionIpLogger(), CharacterActionIpLogger();
UNKNOWN_ACTION = 12
};
class AccountActionIpLogger : public AccountScript
{
public:
AccountActionIpLogger() : AccountScript("AccountActionIpLogger") { }
// We log last_ip instead of last_attempt_ip, as login was successful
// ACCOUNT_LOGIN = 0
void OnAccountLogin(uint32 accountId) override
{
AccountIPLogAction(accountId, ACCOUNT_LOGIN);
}
// We log last_attempt_ip instead of last_ip, as failed login doesn't necessarily mean approperiate user
// ACCOUNT_FAIL_LOGIN = 1
void OnFailedAccountLogin(uint32 accountId) override
{
AccountIPLogAction(accountId, ACCOUNT_FAIL_LOGIN);
}
// ACCOUNT_CHANGE_PW = 2
void OnPasswordChange(uint32 accountId) override
{
AccountIPLogAction(accountId, ACCOUNT_CHANGE_PW);
}
// ACCOUNT_CHANGE_PW_FAIL = 3
void OnFailedPasswordChange(uint32 accountId) override
{
AccountIPLogAction(accountId, ACCOUNT_CHANGE_PW_FAIL);
}
// Registration Email can NOT be changed apart from GM level users. Thus, we do not require to log them...
// ACCOUNT_CHANGE_EMAIL = 4
void OnEmailChange(uint32 accountId) override
{
AccountIPLogAction(accountId, ACCOUNT_CHANGE_EMAIL); // ... they get logged by gm command logger anyway
}
// ACCOUNT_CHANGE_EMAIL_FAIL = 5
void OnFailedEmailChange(uint32 accountId) override
{
AccountIPLogAction(accountId, ACCOUNT_CHANGE_EMAIL_FAIL);
}
/* It's impossible to log the account logout process out of character selection - shouldn't matter anyway,
* as ip doesn't change through playing (obviously).*/
// ACCOUNT_LOGOUT = 6
void AccountIPLogAction(uint32 accountId, IPLoggingTypes aType)
{
if (!sWorld->getBoolConfig(CONFIG_IP_BASED_ACTION_LOGGING))
return;
// Action IP Logger is only intialized if config is set up
// Else, this script isn't loaded in the first place: We require no config check.
// We declare all the required variables
uint32 playerGuid = accountId;
uint32 characterGuid = 0;
std::string systemNote = "ERROR"; // "ERROR" is a placeholder here. We change it later.
// With this switch, we change systemNote so that we have a more accurate phrasing of what type it is.
// Avoids Magicnumbers in SQL table
switch (aType)
{
case ACCOUNT_LOGIN:
systemNote = "Logged on Successful AccountLogin";
break;
case ACCOUNT_FAIL_LOGIN:
systemNote = "Logged on Failed AccountLogin";
break;
case ACCOUNT_CHANGE_PW:
systemNote = "Logged on Successful Account Password Change";
break;
case ACCOUNT_CHANGE_PW_FAIL:
systemNote = "Logged on Failed Account Password Change";
break;
case ACCOUNT_CHANGE_EMAIL:
systemNote = "Logged on Successful Account Email Change";
break;
case ACCOUNT_CHANGE_EMAIL_FAIL:
systemNote = "Logged on Failed Account Email Change";
break;
/*case ACCOUNT_LOGOUT:
systemNote = "Logged on AccountLogout"; //Can not be logged
break;*/
// Neither should happen. Ever. Period. If it does, call Ghostbusters and all your local software defences to investigate.
case UNKNOWN_ACTION:
default:
systemNote = "ERROR! Unknown action!";
break;
}
// Once we have done everything, we can insert the new log.
// Seeing as the time differences should be minimal, we do not get unixtime and the timestamp right now;
// Rather, we let it be added with the SQL query.
if (aType != ACCOUNT_FAIL_LOGIN)
{
// As we can assume most account actions are NOT failed login, so this is the more accurate check.
// For those, we need last_ip...
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_ALDL_IP_LOGGING);
stmt->setUInt32(0, playerGuid);
stmt->setUInt32(1, characterGuid);
stmt->setUInt8(2, aType);
stmt->setUInt32(3, playerGuid);
stmt->setString(4, systemNote.c_str());
LoginDatabase.Execute(stmt);
}
else // ... but for failed login, we query last_attempt_ip from account table. Which we do with an unique query
{
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_FACL_IP_LOGGING);
stmt->setUInt32(0, playerGuid);
stmt->setUInt32(1, characterGuid);
stmt->setUInt8(2, aType);
stmt->setUInt32(3, playerGuid);
stmt->setString(4, systemNote.c_str());
LoginDatabase.Execute(stmt);
}
return;
}
};
class CharacterActionIpLogger : public PlayerScript
{
public:
CharacterActionIpLogger() : PlayerScript("CharacterActionIpLogger") { }
// CHARACTER_CREATE = 7
void OnCreate(Player* player) override
{
CharacterIPLogAction(player, CHARACTER_CREATE);
}
// CHARACTER_LOGIN = 8
void OnLogin(Player* player) override
{
CharacterIPLogAction(player, CHARACTER_LOGIN);
}
// CHARACTER_LOGOUT = 9
void OnLogout(Player* player) override
{
CharacterIPLogAction(player, CHARACTER_LOGOUT);
}
// CHARACTER_DELETE = 10
// CHARACTER_FAILED_DELETE = 11
// We don't log either here - they require a guid
// UNKNOWN_ACTION = 12
// There is no real hook we could use for that.
// Shouldn't happen anyway, should it ? Nothing to see here.
/// Logs a number of actions done by players with an IP
void CharacterIPLogAction(Player* player, IPLoggingTypes aType)
{
if (!sWorld->getBoolConfig(CONFIG_IP_BASED_ACTION_LOGGING))
return;
// Action IP Logger is only intialized if config is set up
// Else, this script isn't loaded in the first place: We require no config check.
// We declare all the required variables
uint32 playerGuid = player->GetSession()->GetAccountId();
uint32 characterGuid = player->GetGUIDLow();
const std::string currentIp = player->GetSession()->GetRemoteAddress();
std::string systemNote = "ERROR"; // "ERROR" is a placeholder here. We change it...
// ... with this switch, so that we have a more accurate phrasing of what type it is
switch (aType)
{
case CHARACTER_CREATE:
systemNote = "Logged on CharacterCreate";
break;
case CHARACTER_LOGIN:
systemNote = "Logged on CharacterLogin";
break;
case CHARACTER_LOGOUT:
systemNote = "Logged on CharacterLogout";
break;
case CHARACTER_DELETE:
systemNote = "Logged on CharacterDelete";
break;
case CHARACTER_FAILED_DELETE:
systemNote = "Logged on Failed CharacterDelete";
break;
// Neither should happen. Ever. Period. If it does, call Mythbusters.
case UNKNOWN_ACTION:
default:
systemNote = "ERROR! Unknown action!";
break;
}
// Once we have done everything, we can insert the new log.
PreparedStatement* stmt = LoginDatabase.GetPreparedStatement(LOGIN_INS_CHAR_IP_LOGGING);
stmt->setUInt32(0, playerGuid);
stmt->setUInt32(1, characterGuid);
stmt->setUInt8(2, aType);
stmt->setString(3, currentIp.c_str()); // We query the ip here.
stmt->setString(4, systemNote.c_str());
// Seeing as the time differences should be minimal, we do not get unixtime and the timestamp right now;
// Rather, we let it be added with the SQL query.
LoginDatabase.Execute(stmt);
return;
}
};
class CharacterDeleteActionIpLogger : public PlayerScript
{
public:
CharacterDeleteActionIpLogger() : PlayerScript("CharacterDeleteActionIpLogger") { }
// CHARACTER_DELETE = 10
void OnDelete(uint64 guid, uint32 accountId) override
{
DeleteIPLogAction(guid, accountId, CHARACTER_DELETE);
}
// CHARACTER_FAILED_DELETE = 11
void OnFailedDelete(uint64 guid, uint32 accountId) override
{
DeleteIPLogAction(guid, accountId, CHARACTER_FAILED_DELETE);
}
void DeleteIPLogAction(uint64 guid, uint32 playerGuid, IPLoggingTypes aType)
{
if (!sWorld->getBoolConfig(CONFIG_IP_BASED_ACTION_LOGGING))
return;
// Action IP Logger is only intialized if config is set up
// Else, this script isn't loaded in the first place: We require no config check.
// We declare all the required variables
uint32 characterGuid = GUID_LOPART(guid); // We have no access to any member function of Player* or WorldSession*. So use old-fashioned way.
// Query playerGuid/accountId, as we only have characterGuid
std::string systemNote = "ERROR"; // "ERROR" is a placeholder here. We change it later.
// With this switch, we change systemNote so that we have a more accurate phrasing of what type it is.
// Avoids Magicnumbers in SQL table
switch (aType)
{
case CHARACTER_DELETE:
systemNote = "Logged on CharacterDelete";
break;
case CHARACTER_FAILED_DELETE:
systemNote = "Logged on Failed CharacterDelete";
break;
// Neither should happen. Ever. Period. If it does, call to whatever god you have for mercy and guidance.
case UNKNOWN_ACTION:
default:
systemNote = "ERROR! Unknown action!";
break;
}
// Once we have done everything, we can insert the new log.
PreparedStatement* stmt2 = LoginDatabase.GetPreparedStatement(LOGIN_INS_ALDL_IP_LOGGING);
stmt2->setUInt32(0, playerGuid);
stmt2->setUInt32(1, characterGuid);
stmt2->setUInt8(2, aType);
stmt2->setUInt32(3, playerGuid);
stmt2->setString(4, systemNote.c_str());
// Seeing as the time differences should be minimal, we do not get unixtime and the timestamp right now;
// Rather, we let it be added with the SQL query.
LoginDatabase.Execute(stmt2);
return;
}
};
void AddSC_action_ip_logger()
{
new AccountActionIpLogger();
new CharacterActionIpLogger();
new CharacterDeleteActionIpLogger();
}