diff --git a/code/ryzom/common/readme_database_xslt.txt b/code/ryzom/common/readme_database_xslt.txt new file mode 100644 index 000000000..4aaf46991 --- /dev/null +++ b/code/ryzom/common/readme_database_xslt.txt @@ -0,0 +1,2 @@ +F:\tools\xsltproc\xsltproc.exe -o R:\code\ryzom\server\src\entities_game_service\database_plr.h --stringparam output header --stringparam filename DATABASE --stringparam side server --stringparam bank PLR R:\code\ryzom\common\src\game_share\generate_client_db.xslt R:\code\ryzom\common\data_common\database.xml +F:\tools\xsltproc\xsltproc.exe -o R:\code\ryzom\server\src\entities_game_service\database_plr.cpp --stringparam output cpp --stringparam filename database_plr --stringparam side server --stringparam bank PLR R:\code\ryzom\common\src\game_share\generate_client_db.xslt R:\code\ryzom\common\data_common\database.xml diff --git a/nel/include/nel/misc/cdb.h b/nel/include/nel/misc/cdb.h index a01c641c3..2861822b2 100644 --- a/nel/include/nel/misc/cdb.h +++ b/nel/include/nel/misc/cdb.h @@ -67,7 +67,7 @@ public: S17, S18, S19, S20, S21, S22, S23, S24, S25, S26, S27, S28, S29, S30, S31, S32, S33, S34, S35, S36, S37, S38, S39, S40, S41, S42, S43, S44, S45, S46, S47, S48, S49, S50, S51, S52, S53, S54, S55, S56, S57, S58, S59, S60, S61, S62, S63, S64, - TEXT, Nb_Prop_Type + TEXT, PACKED, Nb_Prop_Type }; diff --git a/nel/include/nel/misc/cdb_leaf.h b/nel/include/nel/misc/cdb_leaf.h index dc734c434..3a19713b6 100644 --- a/nel/include/nel/misc/cdb_leaf.h +++ b/nel/include/nel/misc/cdb_leaf.h @@ -96,6 +96,7 @@ public: _Property = 0; _oldProperty = 0; _Type = UNKNOWN; + _Nullable = false; _Changed = false; _LastChangeGC = 0; } @@ -235,6 +236,9 @@ private: /// property type EPropType _Type; + /// nullable + bool _Nullable; + /// true if this value has changed bool _Changed; diff --git a/nel/src/misc/cdb_leaf.cpp b/nel/src/misc/cdb_leaf.cpp index f5bc50ac3..3b7e86d70 100644 --- a/nel/src/misc/cdb_leaf.cpp +++ b/nel/src/misc/cdb_leaf.cpp @@ -51,6 +51,18 @@ namespace NLMISC{ //----------------------------------------------- void CCDBNodeLeaf::init( xmlNodePtr node, IProgressCallback &/* progressCallBack */, bool /* mapBanks */, CCDBBankHandler * /* bankHandler */ ) { + // Read nullable + CXMLAutoPtr nullable((const char*)xmlGetProp (node, (xmlChar*)"nullable")); + if ((const char *) nullable != NULL) + { + _Nullable = (nullable.getDatas()[0] == '1'); + } + else + { + _Nullable = false; + } + + // Read type CXMLAutoPtr type((const char*)xmlGetProp (node, (xmlChar*)"type")); nlassert((const char *) type != NULL); @@ -87,6 +99,9 @@ void CCDBNodeLeaf::init( xmlNodePtr node, IProgressCallback &/* progressCallBac // IF it is a TEXT. if(!strcmp(type, "TEXT")) _Type = ICDBNode::TEXT; + // IF it is a PACKED. + else if (!strcmp(type, "PACKED")) + _Type = ICDBNode::PACKED; // ELSE type unknown. else { @@ -131,6 +146,15 @@ void CCDBNodeLeaf::write( CTextId& id, FILE * f) fprintf(f,"%" NL_I64 "d\t%s\n",_Property,id.toString().c_str()); } // write // +inline uint readPackedBitCount(CBitMemStream & f) +{ + uint64 nibbleCount; + f.serial(nibbleCount, 4); + uint bits = (nibbleCount << 2); + // nlinfo("PACKED: %u bits", (uint32)(bits)); + return bits; +} + //----------------------------------------------- // readDelta //----------------------------------------------- @@ -141,15 +165,26 @@ void CCDBNodeLeaf::readDelta(TGameCycle gc, CBitMemStream & f ) { // Read the Property Value according to the Property Type. uint64 recvd = 0; - uint bits; - if (_Type == TEXT) - bits = 32; - else if (_Type <= I64) - bits = _Type; - else - bits = _Type - 64; - f.serial(recvd, bits); + uint64 isNull = 0; + if (_Nullable) + { + f.serial(isNull, 1); + } + + uint bits; + if (!isNull) + { + if (_Type == TEXT) + bits = 32; + else if (_Type == PACKED) + bits = readPackedBitCount(f); + else if (_Type <= I64) + bits = _Type; + else + bits = _Type - 64; + f.serial(recvd, bits); + } // if the DB update is older than last DB update, abort (but after the read!!) if(gc<_LastChangeGC) @@ -162,18 +197,24 @@ void CCDBNodeLeaf::readDelta(TGameCycle gc, CBitMemStream & f ) _Property = (sint64)recvd; // if signed - if (! ((_Type == TEXT) || (_Type <= I64))) + if (! ((_Type == TEXT) || (_Type == PACKED) || (_Type <= I64))) { - // extend bit sign - sint64 mask = (((sint64)1)<> (bits-1))==1 ) + if (!isNull) { - _Property |= ~mask; + // extend bit sign + sint64 mask = (((sint64)1)<> (bits-1))==1 ) + { + _Property |= ~mask; + } } } if ( verboseDatabase ) { - nlinfo( "CDB: Read value (%u bits) %" NL_I64 "d", bits, _Property ); + if (!isNull) + nlinfo( "CDB: Read value (%u bits) %" NL_I64 "d", bits, _Property ); + else + nlinfo( "CDB: Read null value %" NL_I64 "d", _Property ); } // bkup the date of change diff --git a/ryzom/common/data_common/database.xml b/ryzom/common/data_common/database.xml index 6ab490f60..5ebd5e36e 100644 --- a/ryzom/common/data_common/database.xml +++ b/ryzom/common/data_common/database.xml @@ -1,4 +1,8 @@ + @@ -61,7 +65,7 @@ - + @@ -87,7 +91,7 @@ - + @@ -113,11 +117,11 @@ - + - + @@ -126,18 +130,18 @@ - + - + - + - + - + @@ -167,27 +171,27 @@ - + - - + + - + - + - - + + - - - + + + @@ -198,14 +202,14 @@ - + - + @@ -246,7 +250,7 @@ - + @@ -260,7 +264,7 @@ - + @@ -268,7 +272,7 @@ - + @@ -350,7 +354,7 @@ - + @@ -358,7 +362,7 @@ - + @@ -378,7 +382,7 @@ - + @@ -386,7 +390,7 @@ - + @@ -444,37 +448,37 @@ - + - + - + - + - + - + - + - + - + - + @@ -483,15 +487,15 @@ - + - + - + - + @@ -507,8 +511,8 @@ if high order bit == 0 : guild icon : 58 low order bits - back:3 bits, symbol:6 bits, Invert:1 bit, color1&2:24 bits each if high order bit == 1 : low order bits = entry in the LIFT_ICONS::TLiftIcon enum --> - - + + @@ -518,10 +522,10 @@ - + - - + + @@ -549,7 +553,7 @@ - + @@ -557,7 +561,7 @@ - + @@ -571,7 +575,7 @@ - + @@ -582,7 +586,7 @@ - + @@ -596,7 +600,7 @@ - + - + - - + + - + - + - - + + - - - + + + @@ -641,7 +645,7 @@ - + @@ -650,7 +654,7 @@ - + @@ -665,7 +669,7 @@ - + @@ -712,13 +716,13 @@ - + - + @@ -810,7 +814,7 @@ - + @@ -820,11 +824,11 @@ --> - + - + @@ -835,7 +839,7 @@ - + @@ -984,7 +988,7 @@ - + @@ -1056,9 +1060,9 @@ - + - + diff --git a/ryzom/common/src/game_share/generate_client_db.xslt b/ryzom/common/src/game_share/generate_client_db.xslt index 1eaa9b5a0..f6d63425c 100644 --- a/ryzom/common/src/game_share/generate_client_db.xslt +++ b/ryzom/common/src/game_share/generate_client_db.xslt @@ -722,7 +722,8 @@ void ::init(ICDBStructNode *parent< sint64 sint64 - ucstring + ucstring + uint64 Unsupported leaf type diff --git a/ryzom/server/src/entities_game_service/database_plr.cpp b/ryzom/server/src/entities_game_service/database_plr.cpp index 5174a43bb..5bd93c07d 100644 --- a/ryzom/server/src/entities_game_service/database_plr.cpp +++ b/ryzom/server/src/entities_game_service/database_plr.cpp @@ -43,7 +43,6 @@ CBankAccessor_PLR::TASCENSOR CBankAccessor_PLR::_ASCENSOR; CBankAccessor_PLR::TCHOOSE_MISSIONS CBankAccessor_PLR::_CHOOSE_MISSIONS; CBankAccessor_PLR::TTRADING CBankAccessor_PLR::_TRADING; CBankAccessor_PLR::TBRICK_FAMILY CBankAccessor_PLR::_BRICK_FAMILY; -CBankAccessor_PLR::TFABER_PLANS CBankAccessor_PLR::_FABER_PLANS; CBankAccessor_PLR::TMISSIONS CBankAccessor_PLR::_MISSIONS; CBankAccessor_PLR::TEXECUTE_PHRASE CBankAccessor_PLR::_EXECUTE_PHRASE; CBankAccessor_PLR::TCHARACTER_INFO CBankAccessor_PLR::_CHARACTER_INFO; @@ -155,11 +154,6 @@ void CBankAccessor_PLR::init() // call sub branch init _BRICK_FAMILY.init(node); - node = bank->getICDBStructNodeFromName( BankTag, "FABER_PLANS" ); - nlassert(node != NULL); - // call sub branch init - _FABER_PLANS.init(node); - node = bank->getICDBStructNodeFromName( BankTag, "MISSIONS" ); nlassert(node != NULL); // call sub branch init @@ -2285,45 +2279,6 @@ void CBankAccessor_PLR::TBRICK_FAMILY::TArray::init(ICDBStructNode *parent, uint } -void CBankAccessor_PLR::TFABER_PLANS::init(ICDBStructNode *parent) -{ - ICDBStructNode *node = parent; - - _BranchNode = node; - - // leaf init - - - // branch init - - for (uint i=0; i<64; ++i) - { - node = parent->getNode( ICDBStructNode::CTextId(NLMISC::toString("%u", i)), false ); - nlassert(node != NULL); - _Array[i].init(node, i); - } - -} - - -void CBankAccessor_PLR::TFABER_PLANS::TArray::init(ICDBStructNode *parent, uint index) -{ - ICDBStructNode *node = parent; - - _BranchNode = node; - - // leaf init - - node = parent->getNode( ICDBStructNode::CTextId("KNOWN"), false ); - nlassert(node != NULL); - _KNOWN = node; - - - // branch init - -} - - void CBankAccessor_PLR::TMISSIONS::init(ICDBStructNode *parent) { ICDBStructNode *node = parent; diff --git a/ryzom/server/src/entities_game_service/database_plr.h b/ryzom/server/src/entities_game_service/database_plr.h index 2861112c1..837ffae6d 100644 --- a/ryzom/server/src/entities_game_service/database_plr.h +++ b/ryzom/server/src/entities_game_service/database_plr.h @@ -6723,77 +6723,6 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C }; - class TFABER_PLANS - { - public: - - class TArray - { - public: - - - private: - ICDBStructNode *_BranchNode; - - ICDBStructNode *_KNOWN; - - - public: - void init(ICDBStructNode *parent, uint index); - - // accessor to branch node - ICDBStructNode *getCDBNode() - { - return _BranchNode; - } - - - void setKNOWN(CCDBSynchronised &dbGroup, uint64 value, bool forceSending = false) - { - - - _setProp(dbGroup, _KNOWN, value, forceSending); - } - - uint64 getKNOWN(const CCDBSynchronised &dbGroup) - { - uint64 value; - _getProp(dbGroup, _KNOWN, value); - - return value; - } - - ICDBStructNode *getKNOWNCDBNode() - { - return _KNOWN; - } - - }; - - - private: - ICDBStructNode *_BranchNode; - - TArray _Array[64]; - - - public: - void init(ICDBStructNode *parent); - - // accessor to branch node - ICDBStructNode *getCDBNode() - { - return _BranchNode; - } - - TArray &getArray(uint32 index) - { - nlassert(index < 64); - return _Array[index]; - } - - }; - class TMISSIONS { public: @@ -10507,8 +10436,6 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C static TBRICK_FAMILY _BRICK_FAMILY; - static TFABER_PLANS _FABER_PLANS; - static TMISSIONS _MISSIONS; static TEXECUTE_PHRASE _EXECUTE_PHRASE; @@ -10617,10 +10544,6 @@ inline void _getProp(const CCDBSynchronised &db, ICDBStructNode *node, NLMISC::C { return _BRICK_FAMILY; } - static TFABER_PLANS &getFABER_PLANS() - { - return _FABER_PLANS; - } static TMISSIONS &getMISSIONS() { return _MISSIONS; diff --git a/ryzom/server/src/entities_game_service/player_manager/cdb.h b/ryzom/server/src/entities_game_service/player_manager/cdb.h index a75e66189..9eb0ec37c 100644 --- a/ryzom/server/src/entities_game_service/player_manager/cdb.h +++ b/ryzom/server/src/entities_game_service/player_manager/cdb.h @@ -55,7 +55,7 @@ public: I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47, I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63, I64, - TEXT, Nb_Prop_Type + TEXT, PACKED, Nb_Prop_Type }; diff --git a/ryzom/server/src/entities_game_service/player_manager/cdb_leaf.cpp b/ryzom/server/src/entities_game_service/player_manager/cdb_leaf.cpp index 45db31bc6..34542d376 100644 --- a/ryzom/server/src/entities_game_service/player_manager/cdb_leaf.cpp +++ b/ryzom/server/src/entities_game_service/player_manager/cdb_leaf.cpp @@ -45,6 +45,18 @@ using namespace std; //----------------------------------------------- void CCDBStructNodeLeaf::init( xmlNodePtr node, NLMISC::IProgressCallback &progressCallBack ) { + // Read nullable + CXMLAutoPtr nullable((const char*)xmlGetProp (node, (xmlChar*)"nullable")); + if ((const char *) nullable != NULL) + { + _Nullable = (nullable.getDatas()[0] == '1'); + } + else + { + _Nullable = false; + } + + // Read type CXMLAutoPtr type((const char*)xmlGetProp (node, (xmlChar*)"type")); nlassert((const char *) type != NULL); @@ -79,6 +91,9 @@ void CCDBStructNodeLeaf::init( xmlNodePtr node, NLMISC::IProgressCallback &progr // IF it is a TEXT. if(!strcmp(type, "TEXT")) _Type = ICDBStructNode::TEXT; + // IF it is a PACKED. + else if(!strcmp(type, "PACKED")) + _Type = ICDBStructNode::PACKED; // ELSE type unknown. else { diff --git a/ryzom/server/src/entities_game_service/player_manager/cdb_leaf.h b/ryzom/server/src/entities_game_service/player_manager/cdb_leaf.h index 97fabde04..f7205f766 100644 --- a/ryzom/server/src/entities_game_service/player_manager/cdb_leaf.h +++ b/ryzom/server/src/entities_game_service/player_manager/cdb_leaf.h @@ -36,6 +36,9 @@ public: /// Return the type of the property. inline const EPropType & type() const {return _Type;} + /// Return the type of the property. + inline bool nullable() const {return _Nullable;} + /// The overridden version that is usable from ICDBStructNode virtual EPropType getType() const {return _Type;} @@ -46,7 +49,7 @@ public: /** * Default constructor */ - CCDBStructNodeLeaf() : ICDBStructNode(), _Parent( NULL ), _Type( UNKNOWN ) {} + CCDBStructNodeLeaf() : ICDBStructNode(), _Parent( NULL ), _Type( UNKNOWN ), _Nullable( false ) {} /** * Build the structure of the database from a file @@ -178,6 +181,9 @@ private: /// property type EPropType _Type; + /// nullable + bool _Nullable; + /// Binary property id of the leaf (precalculated & stored to avoid having to get back in the tree to build it) CBinId _LeafId; }; diff --git a/ryzom/server/src/entities_game_service/player_manager/cdb_synchronised.cpp b/ryzom/server/src/entities_game_service/player_manager/cdb_synchronised.cpp index e2a35b7af..65912d2f7 100644 --- a/ryzom/server/src/entities_game_service/player_manager/cdb_synchronised.cpp +++ b/ryzom/server/src/entities_game_service/player_manager/cdb_synchronised.cpp @@ -516,6 +516,55 @@ bool CCDBSynchronised::writePermanentDelta( NLMISC::CBitMemStream& s ) return true; } +inline void pushPackedValue( CBitMemStream& s, uint64 value, uint32& bitsize, uint &bits ) +{ + // fast count of max bit + uint32 next = (uint32)(value >> 32); + uint32 test; + bits = 0; + if (next) // 64bit + { + bits += 32; + test = next; // 32 msb + } + else + { + test = (uint32)(value & 0xFFFFFFFF); // 32 lsb + } + next = (test >> 16); + if (next) + { + bits += 16; + test = next; // 16 msb + } + else + { + test = (test & 0xFFFF); // 16 lsb + } + next = (test >> 8); + if (next) + { + bits += 8; + test = next; // 8 msb + } + else + { + test = (test & 0xFF); // 8 lsb + } + next = (test >> 4); + if (next) + { + bits += 8; + } + else if (test & 0xF) + { + bits += 4; + } + uint64 nibbleCount = (bits >> 2); + s.serialAndLog2( nibbleCount, 4 ); + s.serialAndLog2( value, bits ); + bitsize += (4 + bits); +} /* * Push one change to the stream @@ -532,19 +581,42 @@ void CCDBSynchronised::pushDelta( CBitMemStream& s, CCDBStructNodeLeaf *node, ui value = (uint64)_DataContainer.getValue64( index ); //_DataContainer.archiveCurrentValue( index ); - if ( node->type() == ICDBStructNode::TEXT ) + if ( node->nullable() && value == 0 ) { - s.serialAndLog2( value, 32 ); - bitsize += 32; - if ( VerboseDatabase ) - nldebug( "CDB: Pushing value %" NL_I64 "d (TEXT-32) for index %d prop %s", (sint64)value, index, node->buildTextId().toString().c_str() ); + uint64 isNull = 1; + s.serialAndLog2( isNull, 1 ); + bitsize += 1; } else { - s.serialAndLog2( value, (uint)node->type() ); - bitsize += (uint32)node->type(); - if ( VerboseDatabase ) - nldebug( "CDB: Pushing value %" NL_I64 "d (%u bits) for index %d prop %s", (sint64)value, (uint32)node->type(), index, node->buildTextId().toString().c_str() ); + if ( node->nullable() ) + { + uint64 isNull = 0; + s.serialAndLog2( isNull, 1 ); + bitsize += 1; + } + + if ( node->type() == ICDBStructNode::TEXT ) + { + s.serialAndLog2( value, 32 ); + bitsize += 32; + if ( VerboseDatabase ) + nldebug( "CDB: Pushing value %" NL_I64 "d (TEXT-32) for index %d prop %s", (sint64)value, index, node->buildTextId().toString().c_str() ); + } + else if ( node->type() == ICDBStructNode::PACKED ) + { + uint bits; + pushPackedValue( s, value, bitsize, bits ); + if ( VerboseDatabase ) + nldebug( "CDB: Pushing value %" NL_I64 "d (PACKED %u bits) for index %d prop %s", (sint64)value, bits, index, node->buildTextId().toString().c_str() ); + } + else + { + s.serialAndLog2( value, (uint)node->type() ); + bitsize += (uint32)node->type(); + if ( VerboseDatabase ) + nldebug( "CDB: Pushing value %" NL_I64 "d (%u bits) for index %d prop %s", (sint64)value, (uint32)node->type(), index, node->buildTextId().toString().c_str() ); + } } } else @@ -573,6 +645,13 @@ void CCDBSynchronised::pushDeltaPermanent( NLMISC::CBitMemStream& s, CCDBStructN if ( VerboseDatabase ) nldebug( "CDB: Pushing permanent value %" NL_I64 "d (TEXT-32) for index %d prop %s", (sint64)value, index, node->buildTextId().toString().c_str() ); } + else if ( node->type() == ICDBStructNode::PACKED ) + { + uint bits; + pushPackedValue( s, value, bitsize, bits ); + if ( VerboseDatabase ) + nldebug( "CDB: Pushing permanent value %"NL_I64"d (PACKED %u bits) for index %d prop %s", (sint64)value, bits, index, node->buildTextId().toString().c_str() ); + } else { s.serialAndLog2( value, (uint)node->type() );