// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This source file has been modified by the following contributors: // Copyright (C) 2013 Laszlo KIS-ADAM (dfighter) // Copyright (C) 2020 Jan BOON (Kaetemi) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 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 Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #ifndef CLIENT_CHAT_MANAGER_H #define CLIENT_CHAT_MANAGER_H // misc #include "nel/misc/types_nl.h" // game share //#include "game_share/chat_static_database.h" #include "game_share/chat_group.h" #include "game_share/dyn_chat.h" // std #include #include namespace NLMISC{ class CCDBNodeLeaf; } //#define OLD_STRING_SYSTEM /** * CDynamicStringInfos * \author Stephane Coutelas * \author Nevrax France * \date 2002 */ #ifdef OLD_STRING_SYSTEM struct CDynamicStringInfos { /// string ucstring Str; // OLD /// index in the infos buffer, same as the index in the client dynamic string known buffer uint32 Index; /// true if the string has a Huffman code bool IsHuffman; /// true if we received the association bool Associated; /// Constructor CDynamicStringInfos() : Associated(false), Index(0xffffffff), IsHuffman(true), Str("???") { } }; #endif /** * CChatDynamicDatabase * \author Stephane Coutelas * \author Nevrax France * \date 2002 */ #ifdef OLD_STRING_SYSTEM class CChatDynamicDatabase { public : /// Add a string to dynamic base( used by client, add the string with its code ) /// \param index the index of the string /// \param str the string /// \param huffCode the Huffman code(may be empty) /// \return the index of the string uint32 add( uint32 index, ucstring& str, std::vector& huffCode ); // OLD /// Get the string from its Huffman code /// \param str will be filled with the string /// \param bms contains the Huffman code void decodeString( ucstring& str, NLMISC::CBitMemStream& bms ); // OLD /// Get infos on the dynamic string CDynamicStringInfos * getDynamicStringInfos( uint32 index ); /// Destructor ~CChatDynamicDatabase(); private : /// Provides a Huffman tree to get huffman code of a string / CHuffman _Huffman; /// Dynamic base std::map< uint32, CDynamicStringInfos *> _Data; /// Map to find index from the string (only for uncoded strings) std::map< ucstring, uint32> _StringToIndex; // OLD }; #endif // *************************************************************************** /** * CClientChatManager * \author Stephane Coutelas * \author Nevrax France * \date 2002 */ class CClientChatManager { public: class IChatDisplayer { public: /** * \param mode in which channel should this message goes * \param dynChatId is valid only if mode==dyn_chat. This the Id of channel (not the index in DB!) */ virtual void displayChat(TDataSetIndex compressedSenderIndex, const std::string &ucstr, const std::string &rawMessage, CChatGroup::TGroupType mode, NLMISC::CEntityId dynChatId, std::string &senderName, uint bubbleTimer=0) =0; /** * display a player tell message */ virtual void displayTell(/*TDataSetIndex senderIndex, */const std::string &ucstr, const std::string &senderName) =0; /** * Clear a channel. * \param dynChatDbIndex is valid only if mode==dyn_chat. Contrary to displayChat, this is the Db Index (0..MaxDynChanPerPlayer) */ virtual void clearChannel(CChatGroup::TGroupType mode, uint32 dynChatDbIndex) =0; }; public : CClientChatManager(); /** * Init the manager. Init the static database */ void init( const std::string& staticDBFileName ); // InGame init/release. call init after init of database void initInGame(); void releaseInGame(); /** * Return a reference on the static database */ // CChatStaticDatabase& getStaticDB() { return _StaticDB; } /** * Return a reference on the dynamic database */ // #ifdef OLD_STRING_SYSTEM // CChatDynamicDatabase& getDynamicDB() { return _DynamicDB; } // #endif /** * Transmit a chat message to the last target group (see setChatMode) * \param str is the chat content (truncated to 255 char max) * \param isChatTeam special case for Chat TEAM */ void chat( const std::string& str, bool isChatTeam = false ); /** * Transmit a chat message to the receiver * \param receiver is the name of the listening char (truncated to 255 char max) * \param str is the chat content (truncated to 255 char max) */ void tell( const std::string& receiver, const std::string& str ); /** Get the last name of the people with which a 'tell' has been done, then move that name at the start of the list */ const std::string *cycleLastTell(); /** Set the max number of name in the tell list */ void setTellListSize(uint numPeople); /** * Add or remove a character from the ignore list * \param filter is the filter id */ void filter( uint8 filter ); /** * Change the chat mode * \param mode is the chat mode( say/shout/group/clade ) * \param dynChannelId the dynamic channel id (if group==dyn_chat). * Not the db index! Use getDynamicChannelIdFromDbIndex() if you got a dbIndex */ void setChatMode(CChatGroup::TGroupType group, TChanID dynamicChannelId=NLMISC::CEntityId::Unknown); /// Reset the chat mode to force the client to resend it. Used during far TP. void resetChatMode(); /** * update chat mode button */ void updateChatModeAndButton(uint mode, uint32 dynamicChannelDbIndex = 0); /** * Get the string for a tell. display now if ready or delay in flushBuffer() */ void processTellString(NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer); /** * Get the string for a far tell. display now if ready or delay in flushBuffer() */ void processFarTellString(NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer); /** * Extract and decode the chat string from the stream. display now if ready or delay in flushBuffer() */ void processChatString( NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer); /** * Extract and decode the chat string from the stream. display now if ready or delay in flushBuffer() * Difference with processTellString() is that processTellString2() receive a DynamicString for the message */ void processTellString2(NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer); /** * Extract and decode the chat string from the stream. display now if ready or delay in flushBuffer() * Difference with processChatString() is that processChatString2() receive a DynamicString for the message */ void processChatString2(NLMISC::CBitMemStream& bms, IChatDisplayer &chatDisplayer); /** * Extract and decode the chat string from the stream. * the stream here is only a iunt32 for the id of the dynamic string * \param type where do you want this string to go (dyn_chat is not allowed) */ void processChatStringWithNoSender( NLMISC::CBitMemStream& bms, CChatGroup::TGroupType type, IChatDisplayer &chatDisplayer); /** * Process any waiting string */ void flushBuffer(IChatDisplayer &chatDisplayer); /** * Extract and decode the chat string from a vector a uint64 * \param args vector of argument * \param str string with parameter values at end * \param result decoded string * \return true if the string is finalize, false if some param are missing from network */ bool getString( std::string &result, std::vector& args, const std::string& strbase ); // build a sentence to be displayed in the chat (e.g add "you say", "you shout", "[user name] says" or "[user name] shout") static void buildChatSentence(TDataSetIndex compressedSenderIndex, const std::string &sender, const std::string &msg, CChatGroup::TGroupType type, std::string &result); // build a sentence to be displayed in the tell static void buildTellSentence(const std::string &sender, const std::string &msg, std::string &result); /// \name Dynamic Chat channel mgt // @{ // Use info from DB SERVER:DYN_CHAT. return 0 if fails TChanID getDynamicChannelIdFromDbIndex(uint32 dbIndex); // Use info from DB SERVER:DYN_CHAT. return -1 if fails sint32 getDynamicChannelDbIndexFromId(TChanID channelId); // return true if channel exist (getDynamicChannelDbIndexFromId>=0 && _ChatBuffer; // peoples std::list _TellPeople; // the last people on which tells ha been done uint _NumTellPeople; uint _MaxNumTellPeople; /// \name Dynamic Chat channel mgt // @{ TChanID _ChatDynamicChannelId; NLMISC::CCDBNodeLeaf *_DynamicChannelNameLeaf[CChatGroup::MaxDynChanPerPlayer]; NLMISC::CCDBNodeLeaf *_DynamicChannelIdLeaf[CChatGroup::MaxDynChanPerPlayer]; // Id cached. If different from precedent, then the channel must be flushed enum {DynamicChannelEmptyId=-1}; uint32 _DynamicChannelIdCache[CChatGroup::MaxDynChanPerPlayer]; void updateDynamicChatChannels(IChatDisplayer &chatDisplayer); // @} private : /** * Extract and decode the chat string from the stream * \param bms the bit mem stream * \param str string with parameter values at end (str will change after) * \return decoded string (str) */ std::string getString( NLMISC::CBitMemStream& bms, std::string& str ); }; /** This class enable you to store a static string + arg and evaluate it every frame. All args could perhaps not be translated because all dynamic string are not received right now. So you can call getString() every time to */ #ifdef OLD_STRING_SYSTEM class CNetworkString { ucstring StaticString; // OLD public: std::vector Args; bool getString (ucstring &result, CClientChatManager *mng); // OLD void setString (const ucstring &staticStringId, CClientChatManager *mng); // OLD }; #endif #endif // CLIENT_CHAT_MANAGER_H /* End of client_chat_manager.h */