aboutsummaryrefslogtreecommitdiff
path: root/src/server/scripts
diff options
context:
space:
mode:
authorAokromes <Aokromes@users.noreply.github.com>2014-06-23 22:48:35 +0200
committerAokromes <Aokromes@users.noreply.github.com>2014-06-23 22:48:35 +0200
commit84e6af26e62eab87f94d2889943590d088f2ab65 (patch)
tree12238630eaccd03a9c64219f9ce650b0cb04e51e /src/server/scripts
parent7b832135218d58322c7fa93defb3dbc0a68b3fbd (diff)
parent6949735098144e478451e73179ca2d9c6e7344f7 (diff)
Merge pull request #11976 from Ascathor/master
Core/Misc: New ability to log account IP access history
Diffstat (limited to 'src/server/scripts')
-rw-r--r--src/server/scripts/Commands/cs_account.cpp11
-rw-r--r--src/server/scripts/Custom/CMakeLists.txt3
-rw-r--r--src/server/scripts/Events/CMakeLists.txt4
-rw-r--r--src/server/scripts/World/CMakeLists.txt15
-rw-r--r--src/server/scripts/World/action_ip_logger.cpp315
5 files changed, 335 insertions, 13 deletions
diff --git a/src/server/scripts/Commands/cs_account.cpp b/src/server/scripts/Commands/cs_account.cpp
index 3c9714ca55a..1121e4d0a2f 100644
--- a/src/server/scripts/Commands/cs_account.cpp
+++ b/src/server/scripts/Commands/cs_account.cpp
@@ -377,6 +377,7 @@ public:
if (!AccountMgr::CheckEmail(handler->GetSession()->GetAccountId(), std::string(oldEmail)))
{
handler->SendSysMessage(LANG_COMMAND_WRONGEMAIL);
+ sScriptMgr->OnFailedEmailChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change email, but the provided email [%s] is not equal to registration email [%s].",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
@@ -388,6 +389,7 @@ public:
if (!AccountMgr::CheckPassword(handler->GetSession()->GetAccountId(), std::string(password)))
{
handler->SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD);
+ sScriptMgr->OnFailedEmailChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change email, but the provided password is wrong.",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
@@ -398,6 +400,7 @@ public:
if (strcmp(email, oldEmail) == 0)
{
handler->SendSysMessage(LANG_OLD_EMAIL_IS_NEW_EMAIL);
+ sScriptMgr->OnFailedEmailChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
return false;
}
@@ -405,6 +408,7 @@ public:
if (strcmp(email, emailConfirmation) != 0)
{
handler->SendSysMessage(LANG_NEW_EMAILS_NOT_MATCH);
+ sScriptMgr->OnFailedEmailChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change email, but the provided password is wrong.",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
@@ -418,6 +422,7 @@ public:
{
case AOR_OK:
handler->SendSysMessage(LANG_COMMAND_EMAIL);
+ sScriptMgr->OnEmailChange(handler->GetSession()->GetAccountId());
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Email from [%s] to [%s].",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow(),
@@ -425,6 +430,7 @@ public:
break;
case AOR_EMAIL_TOO_LONG:
handler->SendSysMessage(LANG_EMAIL_TOO_LONG);
+ sScriptMgr->OnFailedEmailChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
return false;
default:
@@ -469,6 +475,7 @@ public:
if (!AccountMgr::CheckPassword(handler->GetSession()->GetAccountId(), std::string(oldPassword)))
{
handler->SendSysMessage(LANG_COMMAND_WRONGOLDPASSWORD);
+ sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change password, but the provided old password is wrong.",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
@@ -481,6 +488,7 @@ public:
&& !AccountMgr::CheckEmail(handler->GetSession()->GetAccountId(), std::string(emailConfirmation))) // ... and returns false if the comparison fails.
{
handler->SendSysMessage(LANG_COMMAND_WRONGEMAIL);
+ sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Tried to change password, but the entered email [%s] is wrong.",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
@@ -493,6 +501,7 @@ public:
if (strcmp(newPassword, passwordConfirmation) != 0)
{
handler->SendSysMessage(LANG_NEW_PASSWORDS_NOT_MATCH);
+ sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
return false;
}
@@ -503,12 +512,14 @@ public:
{
case AOR_OK:
handler->SendSysMessage(LANG_COMMAND_PASSWORD);
+ sScriptMgr->OnPasswordChange(handler->GetSession()->GetAccountId());
TC_LOG_INFO("entities.player.character", "Account: %u (IP: %s) Character:[%s] (GUID: %u) Changed Password.",
handler->GetSession()->GetAccountId(), handler->GetSession()->GetRemoteAddress().c_str(),
handler->GetSession()->GetPlayer()->GetName().c_str(), handler->GetSession()->GetPlayer()->GetGUIDLow());
break;
case AOR_PASS_TOO_LONG:
handler->SendSysMessage(LANG_PASSWORD_TOO_LONG);
+ sScriptMgr->OnFailedPasswordChange(handler->GetSession()->GetAccountId());
handler->SetSentErrorMessage(true);
return false;
default:
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
index 78db719ae6e..80ebe36b555 100644
--- a/src/server/scripts/Custom/CMakeLists.txt
+++ b/src/server/scripts/Custom/CMakeLists.txt
@@ -8,8 +8,11 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# file(GLOB_RECURSE sources_Custom Custom/*.cpp Custom/*.h)
+
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
+# ${sources_Custom}
)
message(" -> Prepared: Custom")
diff --git a/src/server/scripts/Events/CMakeLists.txt b/src/server/scripts/Events/CMakeLists.txt
index e45bc585007..3bdb6e6eac2 100644
--- a/src/server/scripts/Events/CMakeLists.txt
+++ b/src/server/scripts/Events/CMakeLists.txt
@@ -8,9 +8,11 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+file(GLOB_RECURSE sources_Events Events/*.cpp Events/*.h)
+
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
- Events/childrens_week.cpp
+ ${sources_Events}
)
message(" -> Prepared: Events")
diff --git a/src/server/scripts/World/CMakeLists.txt b/src/server/scripts/World/CMakeLists.txt
index 7d1b46732cf..56a0a1eb4c7 100644
--- a/src/server/scripts/World/CMakeLists.txt
+++ b/src/server/scripts/World/CMakeLists.txt
@@ -8,20 +8,11 @@
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+file(GLOB_RECURSE sources_World World/*.cpp World/*.h)
+
set(scripts_STAT_SRCS
${scripts_STAT_SRCS}
- World/achievement_scripts.cpp
- World/areatrigger_scripts.cpp
- World/boss_emerald_dragons.cpp
- World/chat_log.cpp
- World/go_scripts.cpp
- World/guards.cpp
- World/item_scripts.cpp
- World/mob_generic_creature.cpp
- World/npc_innkeeper.cpp
- World/npc_professions.cpp
- World/npc_taxi.cpp
- World/npcs_special.cpp
+ ${sources_World}
)
message(" -> Prepared: World")
diff --git a/src/server/scripts/World/action_ip_logger.cpp b/src/server/scripts/World/action_ip_logger.cpp
new file mode 100644
index 00000000000..d4f48ab19be
--- /dev/null
+++ b/src/server/scripts/World/action_ip_logger.cpp
@@ -0,0 +1,315 @@
+/*
+ * Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#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)
+ {
+ 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)
+ {
+ AccountIPLogAction(accountId, ACCOUNT_FAIL_LOGIN);
+ }
+
+ // ACCOUNT_CHANGE_PW = 2
+ void OnPasswordChange(uint32 accountId)
+ {
+ AccountIPLogAction(accountId, ACCOUNT_CHANGE_PW);
+ }
+
+ // ACCOUNT_CHANGE_PW_FAIL = 3
+ void OnFailedPasswordChange(uint32 accountId)
+ {
+ 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)
+ {
+ AccountIPLogAction(accountId, ACCOUNT_CHANGE_EMAIL); // ... they get logged by gm command logger anyway
+ }
+
+ // ACCOUNT_CHANGE_EMAIL_FAIL = 5
+ void OnFailedEmailChange(uint32 accountId)
+ {
+ 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)
+ {
+ // 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)
+ {
+ CharacterIPLogAction(player, CHARACTER_CREATE);
+ }
+
+ // CHARACTER_LOGIN = 8
+ void OnLogin(Player* player)
+ {
+ CharacterIPLogAction(player, CHARACTER_LOGIN);
+ }
+
+ // CHARACTER_LOGOUT = 9
+ void OnLogout(Player* player)
+ {
+ 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)
+ {
+ // 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)
+ {
+ DeleteIPLogAction(guid, accountId, CHARACTER_DELETE);
+ }
+
+ // CHARACTER_FAILED_DELETE = 11
+ void OnFailedDelete(uint64 guid, uint32 accountId)
+ {
+ DeleteIPLogAction(guid, accountId, CHARACTER_FAILED_DELETE);
+ }
+
+ void DeleteIPLogAction(uint64 guid, uint32 playerGuid, IPLoggingTypes aType)
+ {
+ // 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();
+}