feat(Core/Chat): new argument parsing and unify chat hyperlink parsing (#6243)

This commit is contained in:
Kargatum
2021-10-23 15:15:42 +07:00
committed by GitHub
parent 1101f9dd2a
commit bc9473482e
90 changed files with 4280 additions and 2508 deletions

View File

@@ -16,7 +16,7 @@
*/
#include "PacketUtilities.h"
//#include "Hyperlinks.h"
#include "Hyperlinks.h"
#include "Errors.h"
#include <utf8.h>
#include <sstream>
@@ -41,13 +41,13 @@ bool WorldPackets::Strings::Utf8::Validate(std::string const& value)
return true;
}
//bool WorldPackets::Strings::Hyperlinks::Validate(std::string const& value)
//{
// if (!Acore::Hyperlinks::CheckAllLinks(value))
// throw InvalidHyperlinkException(value);
//
// return true;
//}
bool WorldPackets::Strings::Hyperlinks::Validate(std::string const& value)
{
if (!Acore::Hyperlinks::CheckAllLinks(value))
throw InvalidHyperlinkException(value);
return true;
}
bool WorldPackets::Strings::NoHyperlinks::Validate(std::string const& value)
{

View File

@@ -59,7 +59,7 @@ namespace WorldPackets
template<std::size_t MaxBytesWithoutNullTerminator>
struct ByteSize { static bool Validate(std::string const& value) { return value.size() <= MaxBytesWithoutNullTerminator; } };
struct Utf8 { static bool Validate(std::string const& value); };
//struct Hyperlinks { static bool Validate(std::string const& value); };
struct Hyperlinks { static bool Validate(std::string const& value); };
struct NoHyperlinks { static bool Validate(std::string const& value); };
}

View File

@@ -27,6 +27,7 @@
#include "Group.h"
#include "Guild.h"
#include "GuildMgr.h"
#include "Hyperlinks.h"
#include "Log.h"
#include "MapMgr.h"
#include "ObjectAccessor.h"
@@ -389,6 +390,26 @@ bool WorldSession::Update(uint32 diff, PacketFilter& updater)
break;
}
}
catch (WorldPackets::InvalidHyperlinkException const& ihe)
{
LOG_ERROR("network", "%s sent %s with an invalid link:\n%s", GetPlayerInfo().c_str(),
GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())).c_str(), ihe.GetInvalidValue().c_str());
if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
{
KickPlayer("WorldSession::Update Invalid chat link");
}
}
catch (WorldPackets::IllegalHyperlinkException const& ihe)
{
LOG_ERROR("network", "%s sent %s which illegally contained a hyperlink:\n%s", GetPlayerInfo().c_str(),
GetOpcodeNameForLogging(static_cast<OpcodeClient>(packet->GetOpcode())).c_str(), ihe.GetInvalidValue().c_str());
if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
{
KickPlayer("WorldSession::Update Illegal chat link");
}
}
catch (WorldPackets::PacketArrayMaxCapacityException const& pamce)
{
LOG_ERROR("network", "PacketArrayMaxCapacityException: %s while parsing %s from %s.",
@@ -698,6 +719,34 @@ void WorldSession::KickPlayer(std::string const& reason, bool setKicked)
SetKicked(true); // pussywizard: the session won't be left ingame for 60 seconds and to also kick offline session
}
bool WorldSession::ValidateHyperlinksAndMaybeKick(std::string_view str)
{
if (Acore::Hyperlinks::CheckAllLinks(str))
return true;
LOG_ERROR("network", "Player %s%s sent a message with an invalid link:\n%.*s", GetPlayer()->GetName().c_str(),
GetPlayer()->GetGUID().ToString().c_str(), STRING_VIEW_FMT_ARG(str));
if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
KickPlayer("WorldSession::ValidateHyperlinksAndMaybeKick Invalid chat link");
return false;
}
bool WorldSession::DisallowHyperlinksAndMaybeKick(std::string_view str)
{
if (str.find('|') == std::string_view::npos)
return true;
LOG_ERROR("network", "Player %s %s sent a message which illegally contained a hyperlink:\n%.*s", GetPlayer()->GetName().c_str(),
GetPlayer()->GetGUID().ToString().c_str(), STRING_VIEW_FMT_ARG(str));
if (sWorld->getIntConfig(CONFIG_CHAT_STRICT_LINK_CHECKING_KICK))
KickPlayer("WorldSession::DisallowHyperlinksAndMaybeKick Illegal chat link");
return false;
}
void WorldSession::SendNotification(const char* format, ...)
{
if (format)

View File

@@ -309,6 +309,13 @@ public:
void KickPlayer(bool setKicked = true) { return this->KickPlayer("Unknown reason", setKicked); }
void KickPlayer(std::string const& reason, bool setKicked = true);
// Returns true if all contained hyperlinks are valid
// May kick player on false depending on world config (handler should abort)
bool ValidateHyperlinksAndMaybeKick(std::string_view str);
// Returns true if the message contains no hyperlinks
// May kick player on false depending on world config (handler should abort)
bool DisallowHyperlinksAndMaybeKick(std::string_view str);
void QueuePacket(WorldPacket* new_packet);
bool Update(uint32 diff, PacketFilter& updater);