aboutsummaryrefslogtreecommitdiff
path: root/src/server/game/Chat/ChatCommands
diff options
context:
space:
mode:
authorTreeston <treeston.mmoc@gmail.com>2020-09-06 23:36:23 +0200
committerGitHub <noreply@github.com>2020-09-06 23:36:23 +0200
commitb63d655e20a0facf14fc77798c52ea67d8551fa7 (patch)
tree296a3fa0db1abecf9646785b8ee128eab65263fd /src/server/game/Chat/ChatCommands
parent67b112f8a4862a521daf96b2f738db81a649e79d (diff)
[3.3.5] Scripts/Commands: .arena command conversion (PR #25407)
Diffstat (limited to 'src/server/game/Chat/ChatCommands')
-rw-r--r--src/server/game/Chat/ChatCommands/ChatCommandTags.cpp93
-rw-r--r--src/server/game/Chat/ChatCommands/ChatCommandTags.h99
2 files changed, 166 insertions, 26 deletions
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp b/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp
new file mode 100644
index 00000000000..0f11f1cd66f
--- /dev/null
+++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.cpp
@@ -0,0 +1,93 @@
+/*
+ * This file is part of the TrinityCore Project. See AUTHORS file for Copyright information
+ *
+ * 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 "ChatCommandTags.h"
+
+#include "CharacterCache.h"
+#include "Chat.h"
+#include "ChatCommandArgs.h"
+#include "ObjectAccessor.h"
+#include "ObjectMgr.h"
+#include "Player.h"
+
+Optional<std::string_view> Trinity::ChatCommands::QuotedString::TryConsume(std::string_view args)
+{
+ if (args.empty())
+ return std::nullopt;
+ if ((args[0] != '"') && (args[0] != '\''))
+ return Trinity::Impl::ChatCommands::ArgInfo<std::string>::TryConsume(*this, args);
+
+ char const QUOTE = args[0];
+ for (size_t i = 1; i < args.length(); ++i)
+ {
+ if (args[i] == QUOTE)
+ {
+ auto [remainingToken, tail] = Trinity::Impl::ChatCommands::tokenize(args.substr(i + 1));
+ if (remainingToken.empty()) // if this is not empty, then we did not consume the full token
+ return tail;
+ else
+ return std::nullopt;
+ }
+
+ if (args[i] == '\\')
+ {
+ ++i;
+ if (!(i < args.length()))
+ break;
+ }
+ std::string::push_back(args[i]);
+ }
+ // if we reach this, we did not find a closing quote
+ return std::nullopt;
+}
+
+Optional<std::string_view> Trinity::ChatCommands::PlayerIdentifier::TryConsume(std::string_view args)
+{
+ Variant<Hyperlink<player>, std::string_view> name;
+ Optional<std::string_view> next = Trinity::Impl::ChatCommands::ArgInfo<decltype(name)>::TryConsume(name, args);
+ if (!next)
+ return std::nullopt;
+
+ _name = static_cast<std::string_view>(name);
+ normalizePlayerName(_name);
+
+ if ((_player = ObjectAccessor::FindPlayerByName(_name)))
+ _guid = _player->GetGUID();
+ else if (!(_guid = sCharacterCache->GetCharacterGuidByName(_name)))
+ return std::nullopt;
+
+ return next;
+}
+
+Trinity::ChatCommands::PlayerIdentifier::PlayerIdentifier(Player& player)
+ : _name(player.GetName()), _guid(player.GetGUID()), _player(&player) {}
+
+/*static*/ Optional<Trinity::ChatCommands::PlayerIdentifier> Trinity::ChatCommands::PlayerIdentifier::FromTarget(ChatHandler* handler)
+{
+ if (Player* player = handler->GetPlayer())
+ if (Player* target = player->GetSelectedPlayer())
+ return { *target };
+ return std::nullopt;
+
+}
+
+/*static*/ Optional<Trinity::ChatCommands::PlayerIdentifier> Trinity::ChatCommands::PlayerIdentifier::FromSelf(ChatHandler* handler)
+{
+ if (Player* player = handler->GetPlayer())
+ return { *player };
+ return std::nullopt;
+}
diff --git a/src/server/game/Chat/ChatCommands/ChatCommandTags.h b/src/server/game/Chat/ChatCommands/ChatCommandTags.h
index 1ef1a9d1b97..f2bda962f51 100644
--- a/src/server/game/Chat/ChatCommands/ChatCommandTags.h
+++ b/src/server/game/Chat/ChatCommands/ChatCommandTags.h
@@ -21,6 +21,7 @@
#include "advstd.h"
#include "ChatCommandHelpers.h"
#include "Hyperlinks.h"
+#include "ObjectGuid.h"
#include "Optional.h"
#include "Util.h"
#include <cmath>
@@ -33,6 +34,9 @@
#include <utility>
#include <variant>
+class ChatHandler;
+class Player;
+
namespace Trinity::Impl::ChatCommands
{
struct ContainerTag {};
@@ -109,39 +113,82 @@ namespace Trinity::ChatCommands
}
};
+ struct QuotedString : std::string, Trinity::Impl::ChatCommands::ContainerTag
+ {
+ using value_type = std::string;
+
+ TC_GAME_API Optional<std::string_view> TryConsume(std::string_view args);
+ };
+
+ struct TC_GAME_API PlayerIdentifier : Trinity::Impl::ChatCommands::ContainerTag
+ {
+ using value_type = Player*;
+
+ PlayerIdentifier() : _name(), _guid(), _player(nullptr) {}
+ PlayerIdentifier(Player& player);
+
+ template <typename T>
+ operator std::enable_if_t<std::is_base_of_v<T, Player>, T*>() const { return static_cast<T*>(_player); }
+ operator value_type() const { return _player; }
+ operator ObjectGuid() { return _guid; }
+ Player* operator->() const { return _player; }
+ explicit operator bool() const { return (_player != nullptr); }
+ bool operator!() const { return (_player == nullptr); }
+
+ std::string const& GetName() { return _name; }
+ ObjectGuid GetGUID() const { return _guid; }
+ Player* GetPlayer() const { return _player; }
+
+ Optional<std::string_view> TryConsume(std::string_view args);
+
+ static Optional<PlayerIdentifier> FromTarget(ChatHandler* handler);
+ static Optional<PlayerIdentifier> FromSelf(ChatHandler* handler);
+ static Optional<PlayerIdentifier> FromTargetOrSelf(ChatHandler* handler)
+ {
+ if (Optional<PlayerIdentifier> fromTarget = FromTarget(handler))
+ return fromTarget;
+ else
+ return FromSelf(handler);
+ }
+
+ private:
+ std::string _name;
+ ObjectGuid _guid;
+ Player* _player;
+ };
+
template <typename linktag>
struct Hyperlink : Trinity::Impl::ChatCommands::ContainerTag
{
using value_type = typename linktag::value_type;
using storage_type = advstd::remove_cvref_t<value_type>;
- public:
- operator value_type() const { return val; }
- value_type operator*() const { return val; }
- storage_type const* operator->() const { return &val; }
+ operator value_type() const { return val; }
+ value_type operator*() const { return val; }
+ storage_type const* operator->() const { return &val; }
- Optional<std::string_view> TryConsume(std::string_view args)
- {
- Trinity::Hyperlinks::HyperlinkInfo info = Trinity::Hyperlinks::ParseSingleHyperlink(args);
- // invalid hyperlinks cannot be consumed
- if (!info)
- return std::nullopt;
-
- // check if we got the right tag
- if (info.tag != linktag::tag())
- return std::nullopt;
-
- // store value
- if (!linktag::StoreTo(val, info.data))
- return std::nullopt;
-
- // finally, skip any potential delimiters
- auto [token, next] = Trinity::Impl::ChatCommands::tokenize(info.tail);
- if (token.empty()) /* empty token = first character is delimiter, skip past it */
- return next;
- else
- return info.tail;
- }
+ Optional<std::string_view> TryConsume(std::string_view args)
+ {
+ Trinity::Hyperlinks::HyperlinkInfo info = Trinity::Hyperlinks::ParseSingleHyperlink(args);
+ // invalid hyperlinks cannot be consumed
+ if (!info)
+ return std::nullopt;
+
+ // check if we got the right tag
+ if (info.tag != linktag::tag())
+ return std::nullopt;
+
+ // store value
+ if (!linktag::StoreTo(val, info.data))
+ return std::nullopt;
+
+ // finally, skip any potential delimiters
+ auto [token, next] = Trinity::Impl::ChatCommands::tokenize(info.tail);
+ if (token.empty()) /* empty token = first character is delimiter, skip past it */
+ return next;
+ else
+ return info.tail;
+ }
private:
storage_type val;