1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
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.
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/>.
21 #include "nel/misc/entity_id.h"
22 #include "nel/misc/historic.h"
23 #include "base_types.h"
25 // forward declarations
30 // identifier of a dynchat channel
31 //typedef uint32 TChanID;
32 typedef NLMISC::CEntityId TChanID
;
34 // tag for invalid channel
35 const TChanID DYN_CHAT_INVALID_CHAN
= NLMISC::CEntityId::Unknown
;
36 const std::string DYN_CHAT_INVALID_NAME
;
39 /// Message payload for player input forward to channel service owner
40 struct TPlayerInputForward
46 void serial(NLMISC::IStream
&f
)
54 //===================================================================================================================
55 /** This class represents an interaction between a client and a channel in a dynamic chat
56 * A session is initiated from a CDynChat instance.
60 NL_INSTANCE_COUNTER_DECL(CDynChatSession
);
62 uint32 StringID
; // string ID for EGS (to fill client DB)
63 bool WriteRight
; // in read-only mode client can't talk in the channel
65 // Get next session for client
66 CDynChatSession
*getNextClientSession() { return _NextClientSession
; }
67 // Get next session for channel
68 CDynChatSession
*getNextChannelSession() { return _NextChannelSession
; }
69 // Get the client taking part to this session
70 CDynChatClient
*getClient() { return _Client
; }
71 // Get the channel hosting that session
72 CDynChatChan
*getChan() { return _Channel
; }
74 CDynChatClient
*_Client
;
75 CDynChatChan
*_Channel
;
76 CDynChatSession
*_NextClientSession
;
77 CDynChatSession
**_PrevClientSession
; // Pointer on 'next' field in previous client session, or start of linked list
78 CDynChatSession
*_NextChannelSession
;
79 CDynChatSession
**_PrevChannelSession
; // Pointer on 'next' field in previous channel session, or start of linked list
83 CDynChatSession(CDynChatClient
*client
, CDynChatChan
*channel
);
85 friend class CDynChat
;
86 friend class CDynChatClient
;
87 friend class CDynChatChan
;
88 static uint _NumSessions
;
92 //===================================================================================================================
93 /** A client in a dyn chat system. Should be created from a CDynChat instance.
99 CDynChatClient(const TDataSetRow
&client
= TDataSetRow());
101 // Head of linked list of sessions for this channel. List must be followed by calling CDynChatSession::getNextClientSession.
102 CDynChatSession
*getFirstSession() { return _FirstSession
; }
103 const TDataSetRow
&getID() const { return _ID
; }
104 // Return session for this client in channel 'chan', or NULL if no such session exists
105 CDynChatSession
*getSession(TChanID chan
) const;
107 CDynChatSession
*_FirstSession
;
109 friend class CDynChatSession
;
110 friend class CDynChat
;
117 //===================================================================================================================
118 /** A channel in a dyn chat system. Should be created from a CDynChat instance.
123 struct CHistoricEntry
126 // TDataSetRow Sender;
127 ucstring SenderString
;
129 NLMISC::CHistoric
<CHistoricEntry
> Historic
; // historic of messages for IOS
130 uint HistoricSize
; // Historic size for EGS
131 bool Localized
; // for EGS only
132 ucstring Title
; // gives the title of the channel when it is not translated (e.g Localized == false)
133 bool HideBubble
; // hide the display of bubble
134 bool UniversalChannel
; // treat like universe channel
137 // CDynChatChan(TChanID id = NLMISC::CEntityId::Unknown, NLNET::TServiceId ownerServiceId, bool noBroadcast, bool forwadInput);
138 CDynChatChan(TChanID id
, bool noBroadcast
, bool forwardInput
, bool unified
);
140 // Get ID for that channel
141 TChanID
getID() const { return _ID
; }
142 // Head of linked list of sessions for this channel. List must be followed by calling CDynChatSession::getNextChannelSession.
143 CDynChatSession
*getFirstSession() { return _FirstSession
; }
144 // Count number of session in that channel (in O(n))
145 uint
getSessionCount() const;
147 bool getDontBroadcastPlayerInputs() { return _DontBroadcastPlayerInputs
; }
148 bool getForwardPlayerIntputToOwnerService() { return _ForwardPlayerIntputToOwnerService
;}
149 bool getUnifiedChannel() { return _UnifyChannel
;}
152 CDynChatSession
*_FirstSession
;
155 /// Flag to disable client broadcasting
156 bool _DontBroadcastPlayerInputs
;
157 /// Flag to activate player input forwarding to owner service.
158 bool _ForwardPlayerIntputToOwnerService
;
159 /// Flag to activate unification (domain wide) of this channel
162 friend class CDynChatSession
;
163 friend class CDynChat
;
170 //===================================================================================================================
171 /** Data structure to store clients / channels / sessions
172 * To be used by both IOS & EGS
174 * \TODO : Would be good to generalize the pattern used as something like NLMISC::CBinaryRelation<CompoundA, CompoundB, Relation>
175 * This would avoid to have fields for one service that aren't used by another (like the historic...)
177 * \author Nicolas Vizerie
178 * \author Nevrax France
184 typedef std::map
<TChanID
, CDynChatChan
> TChanMap
;
185 typedef std::map
<TDataSetRow
, CDynChatClient
> TClientMap
;
191 /** Create a new channel with the given ID. A warning is issued if channel already exists.
192 * \return true if creation succeeded
194 bool addChan(TChanID chan
, bool noBroadcast
, bool forwardInput
, bool unify
);
195 // Remove channel with the given ID. Return true if success
196 bool removeChan(TChanID chan
);
197 // Add a client with the given ID. Return true if success
198 bool addClient(const TDataSetRow
&client
);
199 // Remove client from its ID. Return true if success
200 bool removeClient(const TDataSetRow
&client
);
201 /** Create a new session in channel 'chan' for the client 'client'. No-op if session already exists
202 * \return pointer on created session
204 CDynChatSession
*addSession(TChanID chan
, const TDataSetRow
&client
);
205 // Stop session in channel 'chan' for the client 'client'.
206 bool removeSession(TChanID chan
, const TDataSetRow
&client
);
207 // Get channel object from its ID or NULL if not found.
208 CDynChatChan
*getChan(TChanID chan
);
209 // Get client object from its ID or NULL if not found.
210 CDynChatClient
*getClient(const TDataSetRow
&client
);
211 // Get a session or NULL if not found
212 CDynChatSession
*getSession(TChanID chan
, const TDataSetRow
&client
);
214 typedef std::vector
<CDynChatChan
*> TChanPtrVector
;
215 void getChans(TChanPtrVector
&channels
);
216 // Remove all channels
217 void removeAllChannels() { _Chans
.clear(); }