summaryrefslogtreecommitdiff
path: root/src/server/game/Chat/Chat.h
blob: 7753670ed656bf501538a6c5f9d2036400b0fcb5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*
 * Copyright (C) 2016+     AzerothCore <www.azerothcore.org>, released under GNU GPL v2 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-GPL2
 * Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
 * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
 */

#ifndef AZEROTHCORE_CHAT_H
#define AZEROTHCORE_CHAT_H

#include "SharedDefines.h"
#include "WorldSession.h"
#include <vector>

class ChatHandler;
class Creature;
class Group;
class Player;
class Unit;
class WorldSession;
class WorldObject;

struct GameTele;

class ChatCommand
{
    typedef bool(*pHandler)(ChatHandler*, char const*);

public:
    ChatCommand(char const* name, uint32 securityLevel, bool allowConsole, pHandler handler, std::string help, std::vector<ChatCommand> childCommands = std::vector<ChatCommand>())
        : Name(ASSERT_NOTNULL(name)), SecurityLevel(securityLevel), AllowConsole(allowConsole), Handler(handler), Help(std::move(help)), ChildCommands(std::move(childCommands)) { }

    char const* Name;
    uint32 SecurityLevel;
    bool AllowConsole;
    pHandler Handler;
    std::string Help;
    std::vector<ChatCommand> ChildCommands;
};

class ChatHandler
{
public:
    WorldSession* GetSession() { return m_session; }
    explicit ChatHandler(WorldSession* session) : m_session(session), sentErrorMessage(false) {}
    virtual ~ChatHandler() { }

    // Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders
    static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, uint64 senderGUID, uint64 receiverGUID, std::string const& message, uint8 chatTag,
                                  std::string const& senderName = "", std::string const& receiverName = "",
                                  uint32 achievementId = 0, bool gmMessage = false, std::string const& channelName = "");

    // Builds chat packet and returns receiver guid position in the packet to substitute in whisper builders
    static size_t BuildChatPacket(WorldPacket& data, ChatMsg chatType, Language language, WorldObject const* sender, WorldObject const* receiver, std::string const& message, uint32 achievementId = 0, std::string const& channelName = "", LocaleConstant locale = DEFAULT_LOCALE);

    static char* LineFromMessage(char*& pos) { char* start = strtok(pos, "\n"); pos = nullptr; return start; }

    // function with different implementation for chat/console
    virtual char const* GetAcoreString(uint32 entry) const;
    virtual void SendSysMessage(char const* str);

    void SendSysMessage(uint32 entry);
    void PSendSysMessage(char const* format, ...) ATTR_PRINTF(2, 3);
    void PSendSysMessage(uint32 entry, ...);
    std::string PGetParseString(uint32 entry, ...) const;

    bool ParseCommands(const char* text);

    static std::vector<ChatCommand> const& getCommandTable();

    bool isValidChatMessage(const char* msg);
    void SendGlobalSysMessage(const char* str);

    bool hasStringAbbr(const char* name, const char* part);

    // function with different implementation for chat/console
    virtual bool isAvailable(ChatCommand const& cmd) const;
    virtual std::string GetNameLink() const { return GetNameLink(m_session->GetPlayer()); }
    virtual bool needReportToTarget(Player* chr) const;
    virtual LocaleConstant GetSessionDbcLocale() const;
    virtual int GetSessionDbLocaleIndex() const;

    bool HasLowerSecurity(Player* target, uint64 guid, bool strong = false);
    bool HasLowerSecurityAccount(WorldSession* target, uint32 account, bool strong = false);

    void SendGlobalGMSysMessage(const char* str);
    Player*   getSelectedPlayer();
    Creature* getSelectedCreature();
    Unit*     getSelectedUnit();
    WorldObject* getSelectedObject();
    // Returns either the selected player or self if there is no selected player
    Player*   getSelectedPlayerOrSelf();

    char*     extractKeyFromLink(char* text, char const* linkType, char** something1 = nullptr);
    char*     extractKeyFromLink(char* text, char const* const* linkTypes, int* found_idx, char** something1 = nullptr);

    // if args have single value then it return in arg2 and arg1 == NULL
    void      extractOptFirstArg(char* args, char** arg1, char** arg2);
    char*     extractQuotedArg(char* args);

    uint32    extractSpellIdFromLink(char* text);
    uint64    extractGuidFromLink(char* text);
    GameTele const* extractGameTeleFromLink(char* text);
    bool GetPlayerGroupAndGUIDByName(const char* cname, Player*& player, Group*& group, uint64& guid, bool offline = false);
    std::string extractPlayerNameFromLink(char* text);
    // select by arg (name/link) or in-game selection online/offline player
    bool extractPlayerTarget(char* args, Player** player, uint64* player_guid = NULL, std::string* player_name = nullptr);

    std::string playerLink(std::string const& name) const { return m_session ? "|cffffffff|Hplayer:" + name + "|h[" + name + "]|h|r" : name; }
    std::string GetNameLink(Player* chr) const;

    GameObject* GetNearbyGameObject();
    GameObject* GetObjectGlobalyWithGuidOrNearWithDbGuid(uint32 lowguid, uint32 entry);
    bool HasSentErrorMessage() const { return sentErrorMessage; }
    void SetSentErrorMessage(bool val) { sentErrorMessage = val; }
    static bool LoadCommandTable() { return load_command_table; }
    static void SetLoadCommandTable(bool val) { load_command_table = val; }

    bool ShowHelpForCommand(std::vector<ChatCommand> const& table, const char* cmd);
protected:
    explicit ChatHandler() : m_session(nullptr), sentErrorMessage(false) {}      // for CLI subclass
    static bool SetDataForCommandInTable(std::vector<ChatCommand>& table, const char* text, uint32 securityLevel, std::string const& help, std::string const& fullcommand);
    bool ExecuteCommandInTable(std::vector<ChatCommand> const& table, const char* text, std::string const& fullcmd);
    bool ShowHelpForSubCommands(std::vector<ChatCommand> const& table, char const* cmd, char const* subcmd);

private:
    WorldSession* m_session;                           // != NULL for chat command call and NULL for CLI command

    // common global flag
    static bool load_command_table;
    bool sentErrorMessage;
};

class CliHandler : public ChatHandler
{
public:
    typedef void Print(void*, char const*);
    explicit CliHandler(void* callbackArg, Print* zprint) : m_callbackArg(callbackArg), m_print(zprint) {}

    // overwrite functions
    char const* GetAcoreString(uint32 entry) const override;
    bool isAvailable(ChatCommand const& cmd) const override;
    void SendSysMessage(const char* str) override;
    std::string GetNameLink() const override;
    bool needReportToTarget(Player* chr) const override;
    LocaleConstant GetSessionDbcLocale() const override;
    int GetSessionDbLocaleIndex() const override;

private:
    void* m_callbackArg;
    Print* m_print;
};

#endif