Add infos into target window
[ryzomcore.git] / ryzom / server / src / general_utilities_service / gus_chat.cpp
blob8b9d84e5c25b9b5cffb32b3ec7e69d26da2ea7e1
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
17 //-----------------------------------------------------------------------------
18 // includes
19 //-----------------------------------------------------------------------------
21 #include "gus_chat.h"
22 #include "nel/misc/command.h"
23 #include "nel/net/message.h"
24 #include "nel/net/unified_network.h"
25 #include "nel/net/service.h"
27 #include "game_share/singleton_registry.h"
28 #include "game_share/dyn_chat.h"
29 #include "game_share/ryzom_entity_id.h"
30 #include "game_share/synchronised_message.h"
31 #include "game_share/ios_interface.h"
33 #include "gus_mirror.h"
34 #include "gus_client_manager.h"
37 //-----------------------------------------------------------------------------
38 // namespaces
39 //-----------------------------------------------------------------------------
41 using namespace std;
42 using namespace NLMISC;
43 using namespace NLNET;
46 //-----------------------------------------------------------------------------
47 // GUS namespace
48 //-----------------------------------------------------------------------------
50 namespace GUS
52 //-----------------------------------------------------------------------------
53 // class CChatChannelImplementation
54 //-----------------------------------------------------------------------------
56 class CChatChannelImplementation: public CChatChannel
58 friend class CChatManagerImplementation;
59 public:
60 CChatChannelImplementation(const NLMISC::CSString &channelName);
62 void openChannel(const NLMISC::CSString& channelTitle, uint32 historySize, bool noBroadcast, bool forwardInput, bool autoInsertPlayer);
63 void closeChannel();
65 void addClient(GUS::TClientId clientId);
66 void removeClient(GUS::TClientId clientId);
68 void broadcastMessage(const ucstring& speakerName, const ucstring& txt);
69 void broadcastMessage(const std::string& speakerNameUtf8, const std::string& txtUtf8);
70 void sendMessage(GUS::TClientId clientId, const ucstring& speakerName,const ucstring& txt);
71 void sendMessage(GUS::TClientId clientId, const std::string& speakerNameUtf8, const std::string& txtUtf8);
73 void setChatCallback(IChatCallback *callback);
74 const NLMISC::CSString& getChannelName() const;
75 const NLMISC::CSString& getChannelTitle() const;
76 void setChannelTitle(const NLMISC::CSString& title);
78 private:
80 IChatCallback* _ChatCallback;
82 NLMISC::CSString _ChannelName;
83 bool _ChannelOpen;
84 TChanID _ChannelID;
85 NLMISC::CSString _ChannelTitle;
86 uint32 _HistorySize;
87 bool _NoBroadcast;
88 bool _ForwardInput;
89 bool _AutoInsertPlayer;
91 struct TClientValidation
93 GUS::TClientId ClientId;
94 TGameCycle EntryDate;
96 // List of client waiting 'validation' in the chat
97 list<TClientValidation> _ClientToValidate;
99 NLMISC_COMMAND_FRIEND(chatDisplayChannel);
100 NLMISC_COMMAND_FRIEND(chatPlayerInput);
104 //-----------------------------------------------------------------------------
105 // class CChatManagerImplementation
106 //-----------------------------------------------------------------------------
108 class CChatManagerImplementation
109 : public CChatManager,
110 public CGusMirror::IMirrorModuleCallback,
111 public CClientManager::IConnectionHandler,
112 public IServiceSingleton
114 private:
115 // prohibit instantiation with private ctor
116 CChatManagerImplementation();
118 //-----------------------------------------------------------------------------
119 // specialisation of CGusMirror::IMirrorModuleCallback
121 void mirrorIsReady(CGusMirror *mirrorModule) {};
122 void serviceMirrorUp(CGusMirror *mirrorModule, const std::string &serviceName, NLNET::TServiceId serviceId);
123 void serviceMirrorDown(CGusMirror *mirrorModule, const std::string &serviceName, NLNET::TServiceId serviceId) {};
124 void mirrorTickUpdate(CGusMirror *mirrorModule);
125 void entityAdded(CGusMirror *mirrorModule, CMirroredDataSet *dataSet, const TDataSetRow &entityIndex) {};
126 void entityRemoved(CGusMirror *mirrorModule, CMirroredDataSet *dataSet, const TDataSetRow &entityIndex, const NLMISC::CEntityId *entityId) {};
127 void propertyChanged(CGusMirror *mirrorModule, CMirroredDataSet *dataSet, const TDataSetRow &entityIndex, TPropertyIndex propIndex) {};
130 //-----------------------------------------------------------------------------
131 // specialisation of CClientManager::IConnectionHandler
133 void connect(TClientId);
134 void disconnect(TClientId);
137 //-----------------------------------------------------------------------------
138 // specialisation of IServiceSingleton
140 void init();
143 public:
144 //-----------------------------------------------------------------------------
145 // specialisation of CChatManager
147 TChatChannelPtr createChatChannel(const NLMISC::CSString &channelName);
148 void removeChannel(CChatChannel *channel);
149 TChatChannelPtr getChatChannel(const NLMISC::CSString& channelName);
150 bool setChatChannelTitle(CChatChannel *channel,const NLMISC::CSString& channelTitle);
153 //-----------------------------------------------------------------------------
154 // propriatory public interface
156 // get singleton instance
157 static CChatManagerImplementation* getInstance();
159 uint32 generateChannelNumber();
161 static void cbDynChatForward( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId );
163 private:
164 //-----------------------------------------------------------------------------
165 // private data
167 typedef map<CSString, CSmartPtr<CChatChannelImplementation> > TChannels;
168 TChannels _Channels;
170 /// Channel numbering (incremented for each channel created)
171 uint32 _CurrentChannelNumber;
174 //-----------------------------------------------------------------------------
175 // friendship for associated NLMISC_COMMANDs
177 NLMISC_COMMAND_FRIEND(chatCreateChannel);
178 NLMISC_COMMAND_FRIEND(chatRemoveChannel);
179 NLMISC_COMMAND_FRIEND(chatSendMessage);
180 NLMISC_COMMAND_FRIEND(chatDisplayChannel);
181 NLMISC_COMMAND_FRIEND(chatPlayerInput);
184 //-----------------------------------------------------------------------------
185 // NeL service callbacks
186 //-----------------------------------------------------------------------------
187 TUnifiedCallbackItem ChatCbArray[]=
189 { "DYN_CHAT:FORWARD", CChatManagerImplementation::cbDynChatForward},
192 //-----------------------------------------------------------------------------
193 // methods CChatManagerImplementation
194 //-----------------------------------------------------------------------------
196 CChatManagerImplementation::CChatManagerImplementation()
197 : _CurrentChannelNumber(0)
201 void CChatManagerImplementation::serviceMirrorUp(CGusMirror *mirrorModule, const std::string &serviceName, NLNET::TServiceId serviceId)
203 if (serviceName == "EGS")
205 // open all channel on the EGS server
206 TChannels::iterator it(_Channels.begin()), last(_Channels.end());
207 for(; it != last; ++it)
209 CChatChannelImplementation *cci = it->second;
211 cci->openChannel(cci->_ChannelTitle, cci->_HistorySize, cci->_NoBroadcast, cci->_ForwardInput, cci->_AutoInsertPlayer);
216 void CChatManagerImplementation::mirrorTickUpdate(CGusMirror *mirrorModule)
218 // for each channel, update waiting clients
220 TGameCycle now = CTickEventHandler::getGameCycle();
222 TChannels::iterator it(_Channels.begin()), last(_Channels.end());
223 for (; it != last; ++it)
225 CChatChannelImplementation *cci = it->second;
227 while( !cci->_ClientToValidate.empty()
228 && (cci->_ClientToValidate.front().EntryDate < (now - 50)))
230 if (cci->_ChatCallback != NULL)
231 cci->_ChatCallback->clientReadyInChannel(cci, cci->_ClientToValidate.front().ClientId);
233 cci->_ClientToValidate.pop_front();
239 void CChatManagerImplementation::connect(TClientId client)
241 // For now, we consider connecting all client in all chat channel
242 TChannels::iterator it(_Channels.begin()), last(_Channels.end());
243 for (; it != last; ++it)
245 CChatChannelImplementation *cci = it->second;
247 if (cci->_AutoInsertPlayer ||
248 (cci->_ChatCallback != NULL && cci->_ChatCallback->isClientAllowedInChatChannel(client, cci)))
250 cci->addClient(client);
251 // // add the client into the chat
252 // TChanID chan = cci->_ChannelID;
253 // bool writeRight = true;
255 // CMessage msgout("DYN_CHAT:ADD_SESSION");
256 // msgout.serial(chan);
257 // msgout.serial(client);
258 // msgout.serial(writeRight);
260 // sendMessageViaMirror( "EGS", msgout);
262 // CChatChannelImplementation::TClientValidation cv;
263 // cv.ClientId = client;
264 // cv.EntryDate = CTickEventHandler::getGameCycle();
266 // cci->_ClientToValidate.push_back(cv);
271 void CChatManagerImplementation::disconnect(TClientId)
273 // Nothing special to do
276 void CChatManagerImplementation::init()
278 NLNET::CUnifiedNetwork::getInstance()->addCallbackArray(ChatCbArray, sizeof(ChatCbArray) / sizeof(TUnifiedCallbackItem));
280 // Register a callback in client manager
281 CClientManager::getInstance()->setConnectionCallback(this);
283 // Register a callback in the gus mirror
284 CGusMirror::getInstance()->registerModuleCallback(this);
287 CChatManagerImplementation* CChatManagerImplementation::getInstance()
289 static CChatManagerImplementation* ptr=NULL;
290 if (ptr==NULL)
291 ptr= new CChatManagerImplementation;
292 return ptr;
295 TChatChannelPtr CChatManagerImplementation::createChatChannel(const NLMISC::CSString &channelName)
297 if (_Channels.find(channelName) != _Channels.end())
299 nlwarning("A channel with name '%s' already exist, creation failed", channelName.c_str());
300 return NULL;
302 CChatChannelImplementation *cc = new CChatChannelImplementation(channelName);
303 _Channels[channelName] = cc;
305 return cc;
308 void CChatManagerImplementation::removeChannel(CChatChannel *channel)
310 TChannels::iterator it(_Channels.begin()), last(_Channels.end());
312 for (; it != last; ++it)
314 if (it->second == (CChatChannelImplementation*)channel)
316 _Channels.erase(it);
317 break;
322 TChatChannelPtr CChatManagerImplementation::getChatChannel(const NLMISC::CSString& channelName)
324 if (_Channels.find(channelName) == _Channels.end())
326 nlwarning("Chat Channel '%s' is unknown", channelName.c_str());
327 return TChatChannelPtr();
330 return &*_Channels[channelName];
333 bool CChatManagerImplementation::setChatChannelTitle(CChatChannel *channel,const NLMISC::CSString& channelTitle)
335 bool ok= true;
336 CSString title= channelTitle;
338 TChannels::iterator it(_Channels.begin()), last(_Channels.end());
339 for (; it != last; ++it)
341 if (it->second!=NULL && it->second!= (CChatChannelImplementation*)channel &&
342 (it->second->getChannelTitle()==title || it->second->getChannelName()==title) )
344 // the channel title is already assigned to another channel
345 ok= false;
346 title= channel->getChannelName();
347 break;
350 channel->setChannelTitle(title);
351 return ok;
354 uint32 CChatManagerImplementation::generateChannelNumber()
356 return _CurrentChannelNumber++;
360 void CChatManagerImplementation::cbDynChatForward( CMessage& msgin, const string &serviceName, NLNET::TServiceId serviceId )
362 CChatManagerImplementation *cmi = CChatManagerImplementation::getInstance();
364 // serial the player inputs
365 TPlayerInputForward pif;
366 msgin.serial(pif);
368 CEntityId eid = CGusMirror::getInstance()->getDataSet("fe_temp")->getEntityId(pif.Sender);
370 nldebug("Receiving input '%s' from player %s %s",
371 pif.Content.toString().c_str(),
372 eid.toString().c_str(),
373 pif.Sender.toString().c_str());
375 // find the channel to callback the creator
376 TChannels::iterator it(cmi->_Channels.begin()), last(cmi->_Channels.end());
377 for (; it != last; ++it)
379 CChatChannelImplementation *cc = it->second;
381 if (cc->_ChannelID == pif.ChanID)
383 nldebug("Forwarding player %s input into channel '%s'",
384 eid.toString().c_str(),
385 cc->_ChannelName.c_str());
387 // ok, we find it !
388 if (cc->_ChatCallback != NULL)
390 cc->_ChatCallback->receiveMessage(pif.Sender, pif.Content);
391 break;
398 //-----------------------------------------------------------------------------
399 // methods CChatManager
400 //-----------------------------------------------------------------------------
402 CChatManager* CChatManager::getInstance()
404 return CChatManagerImplementation::getInstance();
407 //-----------------------------------------------------------------------------
408 // methods CChatChannelImplementation
409 //-----------------------------------------------------------------------------
411 CChatChannelImplementation::CChatChannelImplementation(const CSString &channelName)
412 :_ChannelOpen(false),
413 _ChannelName(channelName)
417 void CChatChannelImplementation::openChannel(const NLMISC::CSString& channelTitle, uint32 historySize, bool noBroadcast, bool forwardInput, bool autoInsertPlayer)
419 if (_ChannelOpen)
420 return;
422 // create the channel id
423 uint32 number = CChatManagerImplementation::getInstance()->generateChannelNumber();
424 _ChannelID = CEntityId(RYZOMID::dynChatGroup, uint64(number));
425 _ChannelTitle = channelTitle;
426 _HistorySize = historySize;
427 _NoBroadcast = noBroadcast;
428 _ForwardInput = forwardInput;
429 _AutoInsertPlayer = autoInsertPlayer;
431 CMessage msgout("DYN_CHAT:ADD_SERVICE_CHAN");
432 msgout.serial(_ChannelID);
433 msgout.serial(_ChannelTitle);
434 msgout.serial(_NoBroadcast);
435 msgout.serial(_ForwardInput);
437 sendMessageViaMirror( "EGS", msgout);
439 if (_HistorySize != 0)
441 CMessage msgout("DYN_CHAT:SET_CHAN_HISTORY");
442 msgout.serial(_ChannelID);
443 msgout.serial(_HistorySize);
445 sendMessageViaMirror("EGS", msgout);
448 _ChannelOpen = true;
450 // put all existing client into this new channel
451 CMirroredDataSet *ds = CGusMirror::getInstance()->getDataSet("fe_temp");
453 TEntityIdToEntityIndexMap::const_iterator it(ds->entityBegin()), last(ds->entityEnd());
454 for (; it != last; ++it)
456 if (it->first.getType() == RYZOMID::player)
458 TDataSetRow clientID = ds->getDataSetRow(it->first);
460 if (_AutoInsertPlayer
461 || (_ChatCallback && _ChatCallback->isClientAllowedInChatChannel(clientID, this)))
463 addClient(clientID);
464 // // We have a player here, open a session
466 // TChanID chan = _ChannelID;
467 // bool writeRight = true;
469 // CMessage msgout("DYN_CHAT:ADD_SESSION");
470 // msgout.serial(chan);
471 // msgout.serial(clientID);
472 // msgout.serial(writeRight);
474 // sendMessageViaMirror( "EGS", msgout);
476 // TClientValidation cv;
477 // cv.ClientId = clientID;
478 // cv.EntryDate = CTickEventHandler::getGameCycle();
480 // _ClientToValidate.push_back(cv);
486 void CChatChannelImplementation::closeChannel()
488 if (!_ChannelOpen)
489 return;
491 CMessage msgout("DYN_CHAT:REMOVE_SERVICE_CHAN");
492 msgout.serial(_ChannelID);
494 sendMessageViaMirror( "EGS", msgout);
496 _ChannelOpen = false;
499 void CChatChannelImplementation::addClient(GUS::TClientId clientId)
501 TChanID chan = _ChannelID;
502 bool writeRight = true;
504 CMessage msgout("DYN_CHAT:ADD_SESSION");
505 msgout.serial(chan);
506 msgout.serial(clientId);
507 msgout.serial(writeRight);
509 sendMessageViaMirror( "EGS", msgout);
511 TClientValidation cv;
512 cv.ClientId = clientId;
513 cv.EntryDate = CTickEventHandler::getGameCycle();
515 _ClientToValidate.push_back(cv);
518 void CChatChannelImplementation::removeClient(GUS::TClientId clientId)
520 TChanID chan = _ChannelID;
522 CMessage msgout("DYN_CHAT:REMOVE_SESSION");
523 msgout.serial(chan);
524 msgout.serial(clientId);
526 sendMessageViaMirror( "EGS", msgout);
529 void CChatChannelImplementation::broadcastMessage(const ucstring& speakerName, const ucstring& txt)
531 nldebug("Channel %s : broadcasting \"'%s' says '%s'\"",
532 _ChannelTitle.c_str(),
533 speakerName.toString().c_str(),
534 txt.toString().c_str());
536 CMessage msgout("DYN_CHAT:SERVICE_CHAT");
537 msgout.serial(_ChannelID);
538 msgout.serial(const_cast<ucstring&>(speakerName));
539 msgout.serial(const_cast<ucstring&>(txt));
541 sendMessageViaMirror( "IOS", msgout);
544 void CChatChannelImplementation::broadcastMessage(const std::string& speakerNameUtf8, const std::string& txtUtf8)
546 ucstring speakerName, txt;
547 speakerName.fromUtf8(speakerNameUtf8);
548 txt.fromUtf8(txtUtf8);
550 broadcastMessage(speakerName, txt);
553 void CChatChannelImplementation::sendMessage(GUS::TClientId clientId, const ucstring& speakerName,const ucstring& txt)
555 CEntityId eid = CGusMirror::getInstance()->getDataSet("fe_temp")->getEntityId(clientId);
556 nldebug("Channel %s : sending \"'%s' says '%s'\" to client %s",
557 _ChannelTitle.c_str(),
558 speakerName.toString().c_str(),
559 txt.toString().c_str(),
560 eid.toString().c_str());
562 CMessage msgout("DYN_CHAT:SERVICE_TELL");
563 msgout.serial(_ChannelID);
564 msgout.serial(const_cast<ucstring&>(speakerName));
565 msgout.serial(clientId);
566 msgout.serial(const_cast<ucstring&>(txt));
568 sendMessageViaMirror( "IOS", msgout);
571 void CChatChannelImplementation::sendMessage(GUS::TClientId clientId, const std::string& speakerNameUtf8, const std::string& txtUtf8)
573 ucstring speakerName, txt;
574 speakerName.fromUtf8(speakerNameUtf8);
575 txt.fromUtf8(txtUtf8);
577 sendMessage(clientId, speakerName, txt);
580 void CChatChannelImplementation::setChatCallback(IChatCallback* callback)
582 _ChatCallback = callback;
585 const NLMISC::CSString& CChatChannelImplementation::getChannelName() const
587 return _ChannelName;
590 const NLMISC::CSString& CChatChannelImplementation::getChannelTitle() const
592 return _ChannelTitle;
595 void CChatChannelImplementation::setChannelTitle(const NLMISC::CSString& title)
597 _ChannelTitle= title;
598 CIOSMsgSetPhrase(_ChannelName,_ChannelTitle).send();
602 //-----------------------------------------------------------------------------
603 // CChat instantiator
604 //-----------------------------------------------------------------------------
606 class CChatManagerImplementationInstantiator
608 public:
609 CChatManagerImplementationInstantiator()
611 CChatManagerImplementation::getInstance();
614 static CChatManagerImplementationInstantiator ChatManagerInstantiator;
617 //-----------------------------------------------------------------------------
618 // NLMISC_COMMAND commands
619 //-----------------------------------------------------------------------------
621 NLMISC_COMMAND(chatCreateChannel, "create a new chat channel", "<channelName> <channelTitle>")
623 if (args.size() != 2)
624 return false;
626 CChatManagerImplementation *cmi = CChatManagerImplementation::getInstance();
628 TChatChannelPtr channel = cmi->createChatChannel(args[0]);
630 if (channel != NULL)
632 channel->openChannel(args[1], 0, true, true, true);
634 else
636 nlwarning("Failed to create channel '%s'", args[1].c_str());
639 return true;
642 NLMISC_COMMAND(chatRemoveChannel, "remove an existing chat channel", "<channelName>")
644 if (args.size() != 1)
645 return false;
647 CChatManagerImplementation *cmi = CChatManagerImplementation::getInstance();
649 TChatChannelPtr channel = cmi->getChatChannel(args[0]);
651 if (channel == NULL)
653 nlwarning ("The channel '%s' is unknow", args[0].c_str());
655 else
657 channel->closeChannel();
658 cmi->removeChannel(channel);
661 return true;
664 NLMISC_COMMAND(chatSendMessage, "send a chat message in a channel", "<channelName> <senderName> <text>")
666 if (args.size() < 3)
667 return false;
669 CChatManagerImplementation *cmi = CChatManagerImplementation::getInstance();
671 TChatChannelPtr channel = cmi->getChatChannel(args[0]);
672 if (channel == NULL)
674 nlwarning ("The channel '%s' is unknow", args[0].c_str());
676 else
678 ucstring text;
679 for (uint i=2; i<args.size(); ++i)
680 text += args[i] + " ";
681 channel->broadcastMessage(args[1], text);
684 return true;
687 NLMISC_COMMAND(chatDisplayChannel, "list all the chat channel and their states", "")
689 if (!args.empty())
690 return false;
692 CChatManagerImplementation *cmi = CChatManagerImplementation::getInstance();
694 log.displayNL("Listing %u chat channel :", cmi->_Channels.size());
695 CChatManagerImplementation::TChannels::iterator it(cmi->_Channels.begin()), last(cmi->_Channels.end());
696 for (;it != last; ++it)
698 CChatChannelImplementation *cmi = it->second;
700 log.displayNL(" Name '%s', Title '%s', ChanId %s, State '%s'",
701 cmi->_ChannelName.c_str(),
702 cmi->_ChannelTitle.c_str(),
703 cmi->_ChannelID.toString().c_str(),
704 cmi->_ChannelOpen ? "OPEN" : "CLOSED");
707 return true;
710 NLMISC_COMMAND(chatPlayerInput, "simulate a player input in a channel", "<player_eid> <channelName> <message>+")
712 if (args.size() < 3)
713 return false;
715 CEntityId eid(args[0]);
716 TDataSetRow index = CGusMirror::getInstance()->getDataSet("fe_temp")->getDataSetRow(eid);
717 if (index == INVALID_DATASET_ROW)
719 log.displayNL("Unknow player '%s'", eid.toString().c_str());
720 return true;
723 // Retreive the channel
724 TChatChannelPtr channel = CChatManager::getInstance()->getChatChannel(args[1]);
725 if (channel == NULL)
727 log.displayNL("Unknown channel '%s'", args[1].c_str());
728 return true;
730 CChatChannelImplementation *cmi = static_cast<CChatChannelImplementation*>(static_cast<CChatChannel*>(channel));
732 // concatenate the message
733 ucstring txt;
734 for (uint i=2; i<args.size(); ++i)
736 txt += args[i];
737 if (i < args.size() -1)
738 txt += " ";
741 TPlayerInputForward pif;
742 pif.ChanID = cmi->_ChannelID;
743 pif.Content = txt;
744 pif.Sender = index;
746 CMessage msg("DYN_CHAT:FORWARD");
747 msg.serial(pif);
748 msg.invert();
750 CChatManagerImplementation::getInstance()->cbDynChatForward(msg, IService::getInstance()->getServiceAliasName(), IService::getInstance()->getServiceId());
752 return true;
755 //-----------------------------------------------------------------------------
756 // methods CChatBroadcastDisplayer
757 //-----------------------------------------------------------------------------
759 CChatBroadcastDisplayer::CChatBroadcastDisplayer(CChatChannel* channel): IDisplayer("gusChatBroadcast")
761 _Channel= channel;
764 void CChatBroadcastDisplayer::doDisplay(const NLMISC::CLog::TDisplayInfo& args,const char *message)
766 _Channel->broadcastMessage("*",message);
770 //-----------------------------------------------------------------------------
771 // methods CChatDisplayer
772 //-----------------------------------------------------------------------------
774 CChatDisplayer::CChatDisplayer(CChatChannel* channel,TClientId clientId): IDisplayer("gusChat")
776 _Channel= channel;
777 _ClientId= clientId;
780 void CChatDisplayer::doDisplay(const NLMISC::CLog::TDisplayInfo& args,const char *message)
782 _Channel->sendMessage(_ClientId,"*",message);
785 //-----------------------------------------------------------------------------