Add infos into target window
[ryzomcore.git] / ryzom / server / src / entities_game_service / cdb_group.cpp
blobc28ec16836c48f42e5fb2d45f355b6165d664c68
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 #include "stdpch.h"
18 #include "cdb_group.h"
19 #include "game_share/generic_xml_msg_mngr.h"
20 #include "nel/net/unified_network.h"
21 #include "game_item_manager/guild_inv.h"
23 using namespace NLMISC;
24 using namespace NLNET;
25 using namespace std;
27 extern CGenericXmlMsgHeaderManager GenericMsgManager;
30 CBitMemStream DBOutput( false, 2048 ); // global to avoid reallocation
34 * Handy logging macros & variables
37 CVariable<bool> VerboseCDBGroup("egs", "VerboseCDBGroup", "Flag to enable or dissable verbose logging in cdb_group.cpp", true,0,true);
38 #define LOG if (VerboseCDBGroup==false) {} else nldebug
42 * Add a recipient (recipient must not move in memory after calling addRecipient! Beware vectors
44 void CCDBGroup::addRecipient( const CCDBRecipient& recipient )
46 // Add to list of new recipients (will be moved to normal list in sendDelta()
47 // because if doing it here, the new recipient will receive twice the changes
48 // done since the latest sendDeltas(), one of which is from the 'permanent
49 // changes')
50 _NewRecipients.push_back( recipient );
52 LOG( "CDB: %s added into group", recipient.toString().c_str() );
57 * Remove a recipient
59 void CCDBGroup::removeRecipient( const CCDBRecipient& recipient )
61 // Remove from list
62 if ( _Recipients.erase( recipient ) == 0 )
64 // Not found in normal list, search in the list of new recipients
65 std::vector<CCDBRecipient>::iterator inr = std::find( _NewRecipients.begin(), _NewRecipients.end(), recipient );
66 if ( inr != _NewRecipients.end() )
68 _NewRecipients.erase( inr );
69 // The group database was not sent to recipient yet => return (don't send reset bank)
71 else
73 nlwarning( "Recipient %s not found when removing from CDBGroup", recipient.toString().c_str() );
75 return;
78 // Send message for the client to clear its properties corresponding to the bank
79 // If it did that when receving a new INIT_BANK, he would lose any database update
80 // that occur after addRecipient() but arrive before INIT_BANK (because the impulsion
81 // arriving order is not guaranteed).
82 DBOutput.resetBufPos();
83 GenericMsgManager.pushNameToStream( "DB_GROUP:RESET_BANK", DBOutput );
84 // write the server tick, to ensure old DB update are not applied after newer
85 TGameCycle serverTick= CTickEventHandler::getGameCycle();
86 DBOutput.serial(serverTick);
87 // encode the bank
88 uint32 bank = (uint32)Database.bank();
89 uint nbits;
90 FILL_nbits_WITH_NB_BITS_FOR_CDBBANK
91 DBOutput.serial( bank, nbits );
92 CMessage msgout( "CDB_IMPULSION" );
93 msgout.serial( const_cast<CEntityId&>(recipient) );
94 msgout.serialBufferWithSize( (uint8*)DBOutput.buffer(), DBOutput.length() );
95 CUnifiedNetwork::getInstance()->send( NLNET::TServiceId(recipient.getDynamicId()), msgout );
97 LOG( "CDB: %s removed from group", recipient.toString().c_str() );
105 void CCDBGroup::sendDeltas( uint32 maxBitSize, IDataProvider& dataProvider, uint8 sendFlags )
107 // Check if there are changes
108 if ( (Database.getChangedPropertyCount() != 0) ||
109 dataProvider.nonEmpty() )
111 // Send a message to all frontends, for multiple delivery to recipients (except new ones)
112 DBOutput.resetBufPos();
113 GenericMsgManager.pushNameToStream( "DB_GROUP:UPDATE_BANK", DBOutput );
114 // Write the server tick, to ensure old DB update are not applied after newer
115 TGameCycle serverTick = CTickEventHandler::getGameCycle();
116 DBOutput.serial( serverTick );
117 // Encode the bank
118 uint32 bank = (uint32)Database.bank();
119 uint nbits;
120 FILL_nbits_WITH_NB_BITS_FOR_CDBBANK
121 DBOutput.serial( bank, nbits );
122 // Write the shared database delta
123 if ( Database.getChangedPropertyCount() != 0 )
125 Database.writeDelta( DBOutput, maxBitSize );
127 else
129 uint32 noChange = 0;
130 DBOutput.serial( noChange, CDBChangedPropertyCountBitSize );
132 // Write additional provided data (for guild inventory)
133 dataProvider.provideUpdate( DBOutput );
134 // Send
135 CMessage msgout( "CDB_MULTI_IMPULSION" );
136 msgout.serial (sendFlags);
137 if (sendFlags & SendDeltasToAll ) // Broadcasting event; no need to include recipient list
139 // All users; bypass recipient list
141 else
143 msgout.serialCont( _Recipients ); // Explicit multi-recipients
146 msgout.serialBufferWithSize( (uint8*)DBOutput.buffer(), DBOutput.length() );
147 CUnifiedNetwork::getInstance()->send( "FS", msgout, false ); // viaMirror not needed because sending entity ids instead of datasetrows
148 LOG( "Sent CDB_MULTI_IMPULSION to all FS (%u bytes)", msgout.length() );
150 // Send a message to each new recipient, with the history (including the latest changes)
151 // and move them to the normal recipient list
152 for ( std::vector<CCDBRecipient>::const_iterator inr=_NewRecipients.begin(); inr!=_NewRecipients.end(); ++inr )
154 const CCDBRecipient& recipient = (*inr);
156 // Sent history of what was modified before its arrival in the group
157 // As this is a specific message, the client can react differently from an update
158 DBOutput.resetBufPos();
159 GenericMsgManager.pushNameToStream( "DB_GROUP:INIT_BANK", DBOutput );
160 // Write the server tick, to ensure old DB update are not applied after newer
161 TGameCycle serverTick = CTickEventHandler::getGameCycle();
162 DBOutput.serial( serverTick );
163 // Encode the bank
164 uint32 bank = (uint32)Database.bank();
165 uint nbits;
166 FILL_nbits_WITH_NB_BITS_FOR_CDBBANK
167 DBOutput.serial( bank, nbits );
168 // Write the shared database delta (from the beginning)
169 if ( ! Database.writePermanentDelta( DBOutput ) )
171 uint32 noInitialDelta = 0;
172 DBOutput.serial( noInitialDelta, 16 );
174 // Write additional provided data (for guild inventory)
175 dataProvider.provideContents( DBOutput ); // provideUpdate() must have been called before, otherwise would not be empty()
176 // Send
177 CMessage msgout( "CDB_IMPULSION" );
178 msgout.serial( const_cast<CEntityId&>(recipient) );
179 msgout.serialBufferWithSize( (uint8*)DBOutput.buffer(), DBOutput.length() );
180 CUnifiedNetwork::getInstance()->send( NLNET::TServiceId(recipient.getDynamicId()), msgout );
182 // Add to normal recipient list
183 if ( ! _Recipients.insert( recipient ).second )
184 nlwarning( "Recipient %s added twice into CDBGroup", recipient.toString().c_str() );
186 _NewRecipients.clear();