2016-01-28 14:52:40 +01:00
|
|
|
/** @file
|
|
|
|
|
*
|
|
|
|
|
* @par History
|
|
|
|
|
* - 2005/11/26 Shinigami: changed "strcmp" into "stricmp" to suppress Script Errors
|
|
|
|
|
* - 2006/09/26 Shinigami: GCC 3.4.x fix - added "template<>" to TmplExecutorModule
|
|
|
|
|
* - 2007/06/17 Shinigami: added config.world_data_path
|
|
|
|
|
* - 2009/12/21 Turley: ._method() call fix
|
|
|
|
|
*/
|
2014-08-30 12:25:08 +02:00
|
|
|
|
|
|
|
|
|
2014-11-01 22:25:33 +01:00
|
|
|
#include "datastore.h"
|
2018-01-29 21:55:48 +01:00
|
|
|
#include <exception>
|
|
|
|
|
#include <fstream>
|
|
|
|
|
#include <stddef.h>
|
2014-08-30 12:25:08 +02:00
|
|
|
|
|
|
|
|
#include "../../bscript/berror.h"
|
2018-01-29 21:55:48 +01:00
|
|
|
#include "../../bscript/bobject.h"
|
|
|
|
|
#include "../../bscript/bstruct.h"
|
|
|
|
|
#include "../../bscript/executor.h"
|
2014-08-30 12:25:08 +02:00
|
|
|
#include "../../bscript/impstr.h"
|
|
|
|
|
#include "../../bscript/objmethods.h"
|
|
|
|
|
#include "../../clib/cfgelem.h"
|
|
|
|
|
#include "../../clib/cfgfile.h"
|
|
|
|
|
#include "../../clib/fileutil.h"
|
2018-01-29 21:55:48 +01:00
|
|
|
#include "../../clib/rawtypes.h"
|
2014-11-01 22:25:33 +01:00
|
|
|
#include "../../clib/streamsaver.h"
|
2014-08-30 12:25:08 +02:00
|
|
|
#include "../../plib/pkg.h"
|
2014-12-30 14:14:41 +01:00
|
|
|
#include "../../plib/systemstate.h"
|
2014-12-31 13:18:08 +01:00
|
|
|
#include "../globals/ucfg.h"
|
2018-01-29 21:55:48 +01:00
|
|
|
#include "../proplist.h"
|
|
|
|
|
#include "datastoreimp.h"
|
2014-11-01 22:25:33 +01:00
|
|
|
|
2019-11-10 22:04:08 +01:00
|
|
|
#include <module_defs/datafile.h>
|
|
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
namespace Pol
|
|
|
|
|
{
|
|
|
|
|
namespace Module
|
|
|
|
|
{
|
|
|
|
|
///
|
|
|
|
|
/// Datastore
|
|
|
|
|
///
|
|
|
|
|
/// datastore files are stored in
|
2018-04-03 04:13:03 +02:00
|
|
|
/// config.world_data_path + ds/fname.txt
|
|
|
|
|
/// config.world_data_path + ds/{pkgname}/fname.txt
|
2016-02-19 19:26:35 +01:00
|
|
|
///
|
|
|
|
|
|
|
|
|
|
Bscript::BApplicObjType datafileref_type;
|
|
|
|
|
Bscript::BApplicObjType datafileelem_type;
|
|
|
|
|
|
2018-01-29 21:55:48 +01:00
|
|
|
DataFileContents::DataFileContents( DataStoreFile* dsf ) : dsf( dsf ), dirty( false ) {}
|
2016-02-19 19:26:35 +01:00
|
|
|
|
|
|
|
|
DataFileContents::~DataFileContents()
|
|
|
|
|
{
|
|
|
|
|
elements_by_integer.clear();
|
|
|
|
|
elements_by_string.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t DataFileContents::estimateSize() const
|
|
|
|
|
{
|
|
|
|
|
size_t size = sizeof( DataStoreFile* ) /*dsf*/
|
|
|
|
|
+ sizeof( bool ); /*dirty*/
|
|
|
|
|
|
|
|
|
|
for ( const auto& ele : elements_by_string )
|
|
|
|
|
{
|
|
|
|
|
size += ele.first.capacity() + sizeof( DataFileElementRef ) + ( sizeof( void* ) * 3 + 1 ) / 2;
|
|
|
|
|
if ( ele.second.get() != nullptr )
|
|
|
|
|
size += ele.second->proplist.estimatedSize();
|
|
|
|
|
}
|
|
|
|
|
size += ( sizeof( int ) + sizeof( DataFileElementRef ) + ( sizeof( void* ) * 3 + 1 ) / 2 ) *
|
|
|
|
|
elements_by_integer.size();
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFileContents::load( Clib::ConfigFile& cf )
|
|
|
|
|
{
|
|
|
|
|
Clib::ConfigElem elem;
|
|
|
|
|
|
|
|
|
|
while ( cf.read( elem ) )
|
|
|
|
|
{
|
|
|
|
|
DataFileElement* delem = new DataFileElement( elem );
|
|
|
|
|
|
|
|
|
|
if ( dsf->flags & DF_KEYTYPE_INTEGER )
|
2015-01-19 18:18:21 +01:00
|
|
|
{
|
2016-02-19 19:26:35 +01:00
|
|
|
elements_by_integer[atol( elem.rest() )].set( delem );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
elements_by_string[elem.rest()].set( delem );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFileContents::save( Clib::StreamWriter& sw )
|
|
|
|
|
{
|
|
|
|
|
for ( const auto& element : elements_by_string )
|
|
|
|
|
{
|
Savefile rewrite (#601)
* rewrite of saving, replaced operator way with a generic add method, thus
not everywhere the formating of the savefiles is hardcoded.
since its the last spot which uses the old formating lib, remobed the
lib
* removed cmake of old format lib
* testscripts for load/save of UObject,Item,Armor,Weapon
* fixed: member faster_cast_recovery and faster_cast_recovery_mod getter returned
a wrong value
* wrong/missing docs
* test containers, lockable, map, spellbooks
fixed save bug in map and spellbook
removed ancient savestrategy experiments
* added corpse test
splitted testfiles
* fixed loading (ancient bug) and saving (PR bug) of Reportables
added tests for houses, boats, accounts and chars
* fixed include
* fix shutdown leak
* added npc tests
upload complete coretest folder also on failure
* do not write and load RegisteredHouse for NPCs two times
readded extra newline between accounts
* tests for guild, party, realm
added resource cfgs, but a test is not really possible since nothing of
interest is stored
* added datafile, storage test
* activated resource loading, 25year old bug, but since the stored values
are senseless it makes no real difference.
added a few wtf comments
catch all exceptions during formatting of log lines
* replaced .write with explixit .begin, .end and .comment.
for leftovers.txt the StreamSaver was also used, since the format is
different use directly ofstream
* added corechanges
2024-01-24 18:49:06 +01:00
|
|
|
sw.begin( "Element", element.first );
|
2016-02-19 19:26:35 +01:00
|
|
|
element.second->printOn( sw );
|
Savefile rewrite (#601)
* rewrite of saving, replaced operator way with a generic add method, thus
not everywhere the formating of the savefiles is hardcoded.
since its the last spot which uses the old formating lib, remobed the
lib
* removed cmake of old format lib
* testscripts for load/save of UObject,Item,Armor,Weapon
* fixed: member faster_cast_recovery and faster_cast_recovery_mod getter returned
a wrong value
* wrong/missing docs
* test containers, lockable, map, spellbooks
fixed save bug in map and spellbook
removed ancient savestrategy experiments
* added corpse test
splitted testfiles
* fixed loading (ancient bug) and saving (PR bug) of Reportables
added tests for houses, boats, accounts and chars
* fixed include
* fix shutdown leak
* added npc tests
upload complete coretest folder also on failure
* do not write and load RegisteredHouse for NPCs two times
readded extra newline between accounts
* tests for guild, party, realm
added resource cfgs, but a test is not really possible since nothing of
interest is stored
* added datafile, storage test
* activated resource loading, 25year old bug, but since the stored values
are senseless it makes no real difference.
added a few wtf comments
catch all exceptions during formatting of log lines
* replaced .write with explixit .begin, .end and .comment.
for leftovers.txt the StreamSaver was also used, since the format is
different use directly ofstream
* added corechanges
2024-01-24 18:49:06 +01:00
|
|
|
sw.end();
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for ( const auto& element : elements_by_integer )
|
|
|
|
|
{
|
Savefile rewrite (#601)
* rewrite of saving, replaced operator way with a generic add method, thus
not everywhere the formating of the savefiles is hardcoded.
since its the last spot which uses the old formating lib, remobed the
lib
* removed cmake of old format lib
* testscripts for load/save of UObject,Item,Armor,Weapon
* fixed: member faster_cast_recovery and faster_cast_recovery_mod getter returned
a wrong value
* wrong/missing docs
* test containers, lockable, map, spellbooks
fixed save bug in map and spellbook
removed ancient savestrategy experiments
* added corpse test
splitted testfiles
* fixed loading (ancient bug) and saving (PR bug) of Reportables
added tests for houses, boats, accounts and chars
* fixed include
* fix shutdown leak
* added npc tests
upload complete coretest folder also on failure
* do not write and load RegisteredHouse for NPCs two times
readded extra newline between accounts
* tests for guild, party, realm
added resource cfgs, but a test is not really possible since nothing of
interest is stored
* added datafile, storage test
* activated resource loading, 25year old bug, but since the stored values
are senseless it makes no real difference.
added a few wtf comments
catch all exceptions during formatting of log lines
* replaced .write with explixit .begin, .end and .comment.
for leftovers.txt the StreamSaver was also used, since the format is
different use directly ofstream
* added corechanges
2024-01-24 18:49:06 +01:00
|
|
|
sw.begin( "Element", element.first );
|
2016-02-19 19:26:35 +01:00
|
|
|
element.second->printOn( sw );
|
Savefile rewrite (#601)
* rewrite of saving, replaced operator way with a generic add method, thus
not everywhere the formating of the savefiles is hardcoded.
since its the last spot which uses the old formating lib, remobed the
lib
* removed cmake of old format lib
* testscripts for load/save of UObject,Item,Armor,Weapon
* fixed: member faster_cast_recovery and faster_cast_recovery_mod getter returned
a wrong value
* wrong/missing docs
* test containers, lockable, map, spellbooks
fixed save bug in map and spellbook
removed ancient savestrategy experiments
* added corpse test
splitted testfiles
* fixed loading (ancient bug) and saving (PR bug) of Reportables
added tests for houses, boats, accounts and chars
* fixed include
* fix shutdown leak
* added npc tests
upload complete coretest folder also on failure
* do not write and load RegisteredHouse for NPCs two times
readded extra newline between accounts
* tests for guild, party, realm
added resource cfgs, but a test is not really possible since nothing of
interest is stored
* added datafile, storage test
* activated resource loading, 25year old bug, but since the stored values
are senseless it makes no real difference.
added a few wtf comments
catch all exceptions during formatting of log lines
* replaced .write with explixit .begin, .end and .comment.
for leftovers.txt the StreamSaver was also used, since the format is
different use directly ofstream
* added corechanges
2024-01-24 18:49:06 +01:00
|
|
|
sw.end();
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileContents::methodCreateElement( int key )
|
|
|
|
|
{
|
|
|
|
|
ElementsByInteger::iterator itr = elements_by_integer.find( key );
|
|
|
|
|
DataFileElementRef dfelem;
|
|
|
|
|
if ( itr == elements_by_integer.end() )
|
|
|
|
|
{
|
|
|
|
|
dfelem.set( new DataFileElement );
|
|
|
|
|
elements_by_integer[key] = dfelem;
|
|
|
|
|
dirty = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dfelem = ( *itr ).second;
|
|
|
|
|
}
|
|
|
|
|
return new DataElemRefObjImp( DataFileContentsRef( this ), dfelem );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileContents::methodCreateElement( const std::string& key )
|
|
|
|
|
{
|
|
|
|
|
ElementsByString::iterator itr = elements_by_string.find( key );
|
|
|
|
|
DataFileElementRef dfelem;
|
|
|
|
|
if ( itr == elements_by_string.end() )
|
|
|
|
|
{
|
|
|
|
|
dfelem.set( new DataFileElement );
|
|
|
|
|
elements_by_string[key] = dfelem;
|
|
|
|
|
dirty = true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
dfelem = ( *itr ).second;
|
|
|
|
|
}
|
|
|
|
|
return new DataElemRefObjImp( DataFileContentsRef( this ), dfelem );
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-19 18:18:21 +01:00
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
Bscript::BObjectImp* DataFileContents::methodFindElement( int key )
|
|
|
|
|
{
|
|
|
|
|
ElementsByInteger::iterator itr = elements_by_integer.find( key );
|
|
|
|
|
if ( itr != elements_by_integer.end() )
|
|
|
|
|
{
|
|
|
|
|
DataFileElementRef dfelem = ( *itr ).second;
|
|
|
|
|
return new DataElemRefObjImp( DataFileContentsRef( this ), dfelem );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "Element not found" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileContents::methodFindElement( const std::string& key )
|
|
|
|
|
{
|
|
|
|
|
ElementsByString::iterator itr = elements_by_string.find( key );
|
|
|
|
|
if ( itr != elements_by_string.end() )
|
|
|
|
|
{
|
|
|
|
|
DataFileElementRef dfelem = ( *itr ).second;
|
|
|
|
|
return new DataElemRefObjImp( DataFileContentsRef( this ), dfelem );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "Element not found" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileContents::methodDeleteElement( int key )
|
|
|
|
|
{
|
|
|
|
|
if ( elements_by_integer.erase( key ) )
|
|
|
|
|
{
|
|
|
|
|
dirty = true;
|
|
|
|
|
return new Bscript::BLong( 1 );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return new Bscript::BError( "Element not found" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileContents::methodDeleteElement( const std::string& key )
|
|
|
|
|
{
|
|
|
|
|
if ( elements_by_string.erase( key ) )
|
|
|
|
|
{
|
|
|
|
|
dirty = true;
|
|
|
|
|
return new Bscript::BLong( 1 );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
return new Bscript::BError( "Element not found" );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileContents::methodKeys() const
|
|
|
|
|
{
|
|
|
|
|
std::unique_ptr<Bscript::ObjArray> arr( new Bscript::ObjArray );
|
|
|
|
|
|
|
|
|
|
for ( ElementsByString::const_iterator citr = elements_by_string.begin();
|
|
|
|
|
citr != elements_by_string.end(); ++citr )
|
|
|
|
|
{
|
|
|
|
|
arr->addElement( new Bscript::String( ( *citr ).first ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for ( ElementsByInteger::const_iterator citr = elements_by_integer.begin();
|
|
|
|
|
citr != elements_by_integer.end(); ++citr )
|
|
|
|
|
{
|
|
|
|
|
arr->addElement( new Bscript::BLong( ( *citr ).first ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return arr.release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DataFileRefObjImp::DataFileRefObjImp( DataFileContentsRef dfcontents )
|
|
|
|
|
: DataFileRefObjImpBase( &datafileref_type, dfcontents )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* DataFileRefObjImp::typeOf() const
|
|
|
|
|
{
|
|
|
|
|
return "DataFileRef";
|
|
|
|
|
}
|
|
|
|
|
u8 DataFileRefObjImp::typeOfInt() const
|
|
|
|
|
{
|
|
|
|
|
return OTDataFileRef;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileRefObjImp::copy() const
|
|
|
|
|
{
|
|
|
|
|
return new DataFileRefObjImp( obj_ );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileRefObjImp::call_method_id( const int id, Bscript::Executor& ex,
|
|
|
|
|
bool /*forcebuiltin*/ )
|
|
|
|
|
{
|
|
|
|
|
switch ( id )
|
|
|
|
|
{
|
|
|
|
|
case Bscript::MTH_CREATEELEMENT:
|
|
|
|
|
if ( !ex.hasParams( 1 ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "not enough parameters to datafile.createelement(key)" );
|
|
|
|
|
}
|
|
|
|
|
if ( obj_->dsf->flags & DF_KEYTYPE_INTEGER )
|
|
|
|
|
{
|
|
|
|
|
int key;
|
|
|
|
|
if ( !ex.getParam( 0, key ) )
|
2015-01-19 18:18:21 +01:00
|
|
|
{
|
2016-02-19 19:26:35 +01:00
|
|
|
return new Bscript::BError( "datafile.createelement(key): key must be an Integer" );
|
2015-01-19 18:18:21 +01:00
|
|
|
}
|
2016-02-19 19:26:35 +01:00
|
|
|
return obj_->methodCreateElement( key );
|
2015-01-19 18:18:21 +01:00
|
|
|
}
|
2016-02-19 19:26:35 +01:00
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const Bscript::String* key;
|
|
|
|
|
if ( !ex.getStringParam( 0, key ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "datafile.createelement(key): key must be a String" );
|
|
|
|
|
}
|
|
|
|
|
return obj_->methodCreateElement( key->value() );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Bscript::MTH_FINDELEMENT:
|
|
|
|
|
if ( !ex.hasParams( 1 ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "not enough parameters to datafile.findelement(key)" );
|
|
|
|
|
}
|
|
|
|
|
if ( obj_->dsf->flags & DF_KEYTYPE_INTEGER )
|
|
|
|
|
{
|
|
|
|
|
int key;
|
|
|
|
|
if ( !ex.getParam( 0, key ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "datafile.findelement(key): key must be an Integer" );
|
|
|
|
|
}
|
|
|
|
|
return obj_->methodFindElement( key );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const Bscript::String* key;
|
|
|
|
|
if ( !ex.getStringParam( 0, key ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "datafile.findelement(key): key must be a String" );
|
|
|
|
|
}
|
|
|
|
|
return obj_->methodFindElement( key->value() );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Bscript::MTH_DELETEELEMENT:
|
|
|
|
|
if ( !ex.hasParams( 1 ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "not enough parameters to datafile.deleteelement(key)" );
|
|
|
|
|
}
|
|
|
|
|
if ( obj_->dsf->flags & DF_KEYTYPE_INTEGER )
|
|
|
|
|
{
|
|
|
|
|
int key;
|
|
|
|
|
if ( !ex.getParam( 0, key ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "datafile.deleteelement(key): key must be an Integer" );
|
|
|
|
|
}
|
|
|
|
|
return obj_->methodDeleteElement( key );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const Bscript::String* key;
|
|
|
|
|
if ( !ex.getStringParam( 0, key ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "datafile.deleteelement(key): key must be a String" );
|
|
|
|
|
}
|
|
|
|
|
return obj_->methodDeleteElement( key->value() );
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case Bscript::MTH_KEYS:
|
|
|
|
|
return obj_->methodKeys();
|
|
|
|
|
default:
|
2018-07-31 14:30:29 +02:00
|
|
|
return nullptr;
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileRefObjImp::call_method( const char* methodname, Bscript::Executor& ex )
|
|
|
|
|
{
|
|
|
|
|
Bscript::ObjMethod* objmethod = Bscript::getKnownObjMethod( methodname );
|
2018-07-31 14:30:29 +02:00
|
|
|
if ( objmethod != nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
return this->call_method_id( objmethod->id, ex );
|
|
|
|
|
else
|
2018-07-31 14:30:29 +02:00
|
|
|
return nullptr;
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DataElemRefObjImp::DataElemRefObjImp( DataFileContentsRef dfcontents, DataFileElementRef dfelem )
|
|
|
|
|
: DataElemRefObjImpBase( &datafileelem_type, DataFileElemObj( dfcontents, dfelem ) )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
const char* DataElemRefObjImp::typeOf() const
|
|
|
|
|
{
|
|
|
|
|
return "DataElemRef";
|
|
|
|
|
}
|
|
|
|
|
u8 DataElemRefObjImp::typeOfInt() const
|
|
|
|
|
{
|
|
|
|
|
return OTDataElemRef;
|
|
|
|
|
}
|
|
|
|
|
Bscript::BObjectImp* DataElemRefObjImp::copy() const
|
|
|
|
|
{
|
|
|
|
|
return new DataElemRefObjImp( obj_.dfcontents, obj_.dfelem );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataElemRefObjImp::call_method_id( const int id, Bscript::Executor& ex,
|
|
|
|
|
bool /*forcebuiltin*/ )
|
|
|
|
|
{
|
|
|
|
|
bool changed = false;
|
|
|
|
|
Bscript::BObjectImp* res = CallPropertyListMethod_id( obj_.dfelem->proplist, id, ex, changed );
|
|
|
|
|
if ( changed )
|
|
|
|
|
obj_.dfcontents->dirty = true;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataElemRefObjImp::call_method( const char* methodname, Bscript::Executor& ex )
|
|
|
|
|
{
|
|
|
|
|
bool changed = false;
|
|
|
|
|
Bscript::BObjectImp* res =
|
|
|
|
|
CallPropertyListMethod( obj_.dfelem->proplist, methodname, ex, changed );
|
|
|
|
|
if ( changed )
|
|
|
|
|
obj_.dfcontents->dirty = true;
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2016-12-14 21:50:23 +01:00
|
|
|
DataFileExecutorModule::DataFileExecutorModule( Bscript::Executor& exec )
|
2020-02-08 09:21:35 +01:00
|
|
|
: Bscript::TmplExecutorModule<DataFileExecutorModule, Bscript::ExecutorModule>( exec )
|
2016-12-14 21:50:23 +01:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
DataStoreFile* DataFileExecutorModule::GetDataStoreFile( const std::string& inspec )
|
|
|
|
|
{
|
|
|
|
|
std::string descriptor;
|
|
|
|
|
|
2018-07-31 14:30:29 +02:00
|
|
|
const Plib::Package* spec_pkg = nullptr;
|
2016-02-19 19:26:35 +01:00
|
|
|
std::string spec_filename;
|
|
|
|
|
if ( !Plib::pkgdef_split( inspec, exec.prog()->pkg, &spec_pkg, &spec_filename ) )
|
|
|
|
|
{
|
2018-07-31 14:30:29 +02:00
|
|
|
return nullptr; // new BError( "Error in descriptor" );
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
2018-07-31 14:30:29 +02:00
|
|
|
if ( spec_pkg == nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
{
|
|
|
|
|
// ::filename
|
|
|
|
|
descriptor = "::" + spec_filename;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// :somepkg:filename
|
|
|
|
|
descriptor = ":" + spec_pkg->name() + ":" + spec_filename;
|
|
|
|
|
}
|
2015-01-19 18:18:21 +01:00
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
Core::DataStore::iterator itr = Core::configurationbuffer.datastore.find( descriptor );
|
|
|
|
|
if ( itr != Core::configurationbuffer.datastore.end() )
|
|
|
|
|
{
|
|
|
|
|
DataStoreFile* dsf = ( *itr ).second;
|
|
|
|
|
return dsf;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2018-07-31 14:30:29 +02:00
|
|
|
return nullptr;
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileExecutorModule::mf_ListDataFiles()
|
|
|
|
|
{
|
|
|
|
|
std::unique_ptr<Bscript::ObjArray> file_list( new Bscript::ObjArray );
|
|
|
|
|
for ( Core::DataStore::iterator itr = Core::configurationbuffer.datastore.begin();
|
|
|
|
|
itr != Core::configurationbuffer.datastore.end(); ++itr )
|
|
|
|
|
{
|
|
|
|
|
DataStoreFile* dsf = ( *itr ).second;
|
|
|
|
|
std::unique_ptr<Bscript::BStruct> file_name( new Bscript::BStruct );
|
|
|
|
|
file_name->addMember( "pkg", new Bscript::String( dsf->pkgname ) );
|
|
|
|
|
file_name->addMember( "name", new Bscript::String( dsf->name ) );
|
|
|
|
|
file_name->addMember( "descriptor", new Bscript::String( dsf->descriptor ) );
|
|
|
|
|
|
|
|
|
|
file_list->addElement( file_name.release() );
|
|
|
|
|
}
|
|
|
|
|
return file_list.release();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileExecutorModule::mf_CreateDataFile()
|
|
|
|
|
{
|
|
|
|
|
const Bscript::String* strob;
|
|
|
|
|
int flags;
|
|
|
|
|
if ( getStringParam( 0, strob ) && getParam( 1, flags ) )
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2014-11-01 22:25:33 +01:00
|
|
|
std::string descriptor;
|
2016-02-19 19:26:35 +01:00
|
|
|
std::string directory;
|
|
|
|
|
std::string d_ds;
|
|
|
|
|
const std::string& inspec = strob->value();
|
2014-08-30 12:25:08 +02:00
|
|
|
|
2018-07-31 14:30:29 +02:00
|
|
|
const Plib::Package* spec_pkg = nullptr;
|
2014-11-01 22:25:33 +01:00
|
|
|
std::string spec_filename;
|
2016-02-19 19:26:35 +01:00
|
|
|
if ( !Plib::pkgdef_split( inspec, exec.prog()->pkg, &spec_pkg, &spec_filename ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "Error in descriptor" );
|
|
|
|
|
}
|
2018-07-31 14:30:29 +02:00
|
|
|
if ( spec_pkg == nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
{
|
|
|
|
|
// ::filename
|
|
|
|
|
descriptor = "::" + spec_filename;
|
|
|
|
|
directory = Plib::systemstate.config.world_data_path + "ds/";
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// :somepkg:filename
|
|
|
|
|
descriptor = ":" + spec_pkg->name() + ":" + spec_filename;
|
|
|
|
|
d_ds = Plib::systemstate.config.world_data_path + "ds/";
|
|
|
|
|
directory = Plib::systemstate.config.world_data_path + "ds/" + spec_pkg->name() + "/";
|
|
|
|
|
}
|
|
|
|
|
if ( !Clib::FileExists( directory.c_str() ) )
|
|
|
|
|
{
|
|
|
|
|
if ( !d_ds.empty() )
|
|
|
|
|
Clib::MakeDirectory( d_ds.c_str() );
|
|
|
|
|
Clib::MakeDirectory( directory.c_str() );
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-31 14:30:29 +02:00
|
|
|
DataStoreFile* dsf = nullptr;
|
2016-02-19 19:26:35 +01:00
|
|
|
|
|
|
|
|
Core::DataStore::iterator itr = Core::configurationbuffer.datastore.find( descriptor );
|
|
|
|
|
if ( itr != Core::configurationbuffer.datastore.end() )
|
|
|
|
|
{
|
|
|
|
|
dsf = ( *itr ).second;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// create a new one
|
|
|
|
|
dsf = new DataStoreFile( descriptor, spec_pkg, spec_filename, flags );
|
|
|
|
|
Core::configurationbuffer.datastore[descriptor] = dsf;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// didn't find it, time to go open or create.
|
|
|
|
|
if ( !dsf->loaded() )
|
|
|
|
|
dsf->load();
|
|
|
|
|
|
|
|
|
|
return new DataFileRefObjImp( dsf->dfcontents );
|
|
|
|
|
}
|
|
|
|
|
catch ( std::exception& ex )
|
2015-01-19 18:18:21 +01:00
|
|
|
{
|
2016-02-19 19:26:35 +01:00
|
|
|
std::string message = std::string( "An exception occurred: " ) + ex.what();
|
|
|
|
|
return new Bscript::BError( message );
|
2015-01-19 18:18:21 +01:00
|
|
|
}
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "Invalid parameter type" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileExecutorModule::mf_OpenDataFile()
|
|
|
|
|
{
|
|
|
|
|
const Bscript::String* strob;
|
|
|
|
|
if ( getStringParam( 0, strob ) )
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
std::string descriptor;
|
2018-04-03 04:13:03 +02:00
|
|
|
// string directory;
|
2016-02-19 19:26:35 +01:00
|
|
|
const std::string& inspec = strob->value();
|
2015-01-19 18:18:21 +01:00
|
|
|
|
2018-07-31 14:30:29 +02:00
|
|
|
const Plib::Package* spec_pkg = nullptr;
|
2016-02-19 19:26:35 +01:00
|
|
|
std::string spec_filename;
|
|
|
|
|
if ( !Plib::pkgdef_split( inspec, exec.prog()->pkg, &spec_pkg, &spec_filename ) )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "Error in descriptor" );
|
|
|
|
|
}
|
2018-07-31 14:30:29 +02:00
|
|
|
if ( spec_pkg == nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
{
|
|
|
|
|
// ::filename
|
|
|
|
|
descriptor = "::" + spec_filename;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// :somepkg:filename
|
|
|
|
|
descriptor = ":" + spec_pkg->name() + ":" + spec_filename;
|
|
|
|
|
}
|
2015-01-19 18:18:21 +01:00
|
|
|
|
2016-02-19 19:26:35 +01:00
|
|
|
Core::DataStore::iterator itr = Core::configurationbuffer.datastore.find( descriptor );
|
|
|
|
|
if ( itr != Core::configurationbuffer.datastore.end() )
|
|
|
|
|
{
|
|
|
|
|
DataStoreFile* dsf = ( *itr ).second;
|
|
|
|
|
// didn't find it, time to go open or create.
|
|
|
|
|
if ( !dsf->loaded() )
|
|
|
|
|
dsf->load();
|
|
|
|
|
return new DataFileRefObjImp( dsf->dfcontents );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "Datafile does not exist" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch ( std::exception& ex )
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( std::string( "An exception occurred" ) + ex.what() );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "Invalid parameter type" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Bscript::BObjectImp* DataFileExecutorModule::mf_UnloadDataFile()
|
|
|
|
|
{
|
|
|
|
|
const Bscript::String* strob;
|
|
|
|
|
if ( getStringParam( 0, strob ) )
|
|
|
|
|
{
|
|
|
|
|
DataStoreFile* dsf = GetDataStoreFile( strob->value() );
|
|
|
|
|
if ( !dsf )
|
|
|
|
|
return new Bscript::BError( "Unable to find data store file" );
|
|
|
|
|
|
|
|
|
|
dsf->unload = true;
|
|
|
|
|
return new Bscript::BLong( 1 );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return new Bscript::BError( "Invalid parameter type" );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DataStoreFile::DataStoreFile( Clib::ConfigElem& elem )
|
|
|
|
|
: descriptor( elem.remove_string( "Descriptor" ) ),
|
|
|
|
|
name( elem.remove_string( "name" ) ),
|
|
|
|
|
pkgname( elem.remove_string( "package", "" ) ),
|
|
|
|
|
pkg( Plib::find_package( pkgname ) ),
|
|
|
|
|
version( elem.remove_ushort( "Version" ) ),
|
|
|
|
|
oldversion( elem.remove_ushort( "OldVersion" ) ),
|
|
|
|
|
flags( elem.remove_ulong( "Flags" ) ),
|
|
|
|
|
unload( false ),
|
|
|
|
|
delversion( 0 )
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DataStoreFile::DataStoreFile( const std::string& descriptor, const Plib::Package* pkg,
|
|
|
|
|
const std::string& name, int flags )
|
|
|
|
|
: descriptor( descriptor ),
|
|
|
|
|
name( name ),
|
|
|
|
|
pkgname( "" ),
|
|
|
|
|
pkg( pkg ),
|
|
|
|
|
version( 0 ),
|
|
|
|
|
oldversion( 0 ),
|
|
|
|
|
flags( flags ),
|
|
|
|
|
unload( false ),
|
|
|
|
|
delversion( 0 )
|
|
|
|
|
{
|
2018-07-31 14:30:29 +02:00
|
|
|
if ( pkg != nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
pkgname = pkg->name();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool DataStoreFile::loaded() const
|
|
|
|
|
{
|
2018-07-31 14:30:29 +02:00
|
|
|
return dfcontents.get() != nullptr;
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataStoreFile::load()
|
|
|
|
|
{
|
|
|
|
|
if ( loaded() )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
dfcontents.set( new DataFileContents( this ) );
|
|
|
|
|
|
|
|
|
|
std::string fn = filename();
|
|
|
|
|
if ( Clib::FileExists( fn.c_str() ) )
|
|
|
|
|
{
|
|
|
|
|
Clib::ConfigFile cf( filename().c_str(), "Element" );
|
|
|
|
|
dfcontents->load( cf );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// just force an empty file to be written
|
|
|
|
|
dfcontents->dirty = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DataStoreFile::~DataStoreFile()
|
|
|
|
|
{
|
|
|
|
|
dfcontents.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataStoreFile::printOn( Clib::StreamWriter& sw ) const
|
|
|
|
|
{
|
Savefile rewrite (#601)
* rewrite of saving, replaced operator way with a generic add method, thus
not everywhere the formating of the savefiles is hardcoded.
since its the last spot which uses the old formating lib, remobed the
lib
* removed cmake of old format lib
* testscripts for load/save of UObject,Item,Armor,Weapon
* fixed: member faster_cast_recovery and faster_cast_recovery_mod getter returned
a wrong value
* wrong/missing docs
* test containers, lockable, map, spellbooks
fixed save bug in map and spellbook
removed ancient savestrategy experiments
* added corpse test
splitted testfiles
* fixed loading (ancient bug) and saving (PR bug) of Reportables
added tests for houses, boats, accounts and chars
* fixed include
* fix shutdown leak
* added npc tests
upload complete coretest folder also on failure
* do not write and load RegisteredHouse for NPCs two times
readded extra newline between accounts
* tests for guild, party, realm
added resource cfgs, but a test is not really possible since nothing of
interest is stored
* added datafile, storage test
* activated resource loading, 25year old bug, but since the stored values
are senseless it makes no real difference.
added a few wtf comments
catch all exceptions during formatting of log lines
* replaced .write with explixit .begin, .end and .comment.
for leftovers.txt the StreamSaver was also used, since the format is
different use directly ofstream
* added corechanges
2024-01-24 18:49:06 +01:00
|
|
|
sw.begin( "DataFile" );
|
|
|
|
|
sw.add( "Descriptor", descriptor );
|
|
|
|
|
sw.add( "Name", name );
|
2016-02-19 19:26:35 +01:00
|
|
|
|
|
|
|
|
if ( !pkgname.empty() )
|
Savefile rewrite (#601)
* rewrite of saving, replaced operator way with a generic add method, thus
not everywhere the formating of the savefiles is hardcoded.
since its the last spot which uses the old formating lib, remobed the
lib
* removed cmake of old format lib
* testscripts for load/save of UObject,Item,Armor,Weapon
* fixed: member faster_cast_recovery and faster_cast_recovery_mod getter returned
a wrong value
* wrong/missing docs
* test containers, lockable, map, spellbooks
fixed save bug in map and spellbook
removed ancient savestrategy experiments
* added corpse test
splitted testfiles
* fixed loading (ancient bug) and saving (PR bug) of Reportables
added tests for houses, boats, accounts and chars
* fixed include
* fix shutdown leak
* added npc tests
upload complete coretest folder also on failure
* do not write and load RegisteredHouse for NPCs two times
readded extra newline between accounts
* tests for guild, party, realm
added resource cfgs, but a test is not really possible since nothing of
interest is stored
* added datafile, storage test
* activated resource loading, 25year old bug, but since the stored values
are senseless it makes no real difference.
added a few wtf comments
catch all exceptions during formatting of log lines
* replaced .write with explixit .begin, .end and .comment.
for leftovers.txt the StreamSaver was also used, since the format is
different use directly ofstream
* added corechanges
2024-01-24 18:49:06 +01:00
|
|
|
sw.add( "Package", pkgname );
|
2016-02-19 19:26:35 +01:00
|
|
|
|
Savefile rewrite (#601)
* rewrite of saving, replaced operator way with a generic add method, thus
not everywhere the formating of the savefiles is hardcoded.
since its the last spot which uses the old formating lib, remobed the
lib
* removed cmake of old format lib
* testscripts for load/save of UObject,Item,Armor,Weapon
* fixed: member faster_cast_recovery and faster_cast_recovery_mod getter returned
a wrong value
* wrong/missing docs
* test containers, lockable, map, spellbooks
fixed save bug in map and spellbook
removed ancient savestrategy experiments
* added corpse test
splitted testfiles
* fixed loading (ancient bug) and saving (PR bug) of Reportables
added tests for houses, boats, accounts and chars
* fixed include
* fix shutdown leak
* added npc tests
upload complete coretest folder also on failure
* do not write and load RegisteredHouse for NPCs two times
readded extra newline between accounts
* tests for guild, party, realm
added resource cfgs, but a test is not really possible since nothing of
interest is stored
* added datafile, storage test
* activated resource loading, 25year old bug, but since the stored values
are senseless it makes no real difference.
added a few wtf comments
catch all exceptions during formatting of log lines
* replaced .write with explixit .begin, .end and .comment.
for leftovers.txt the StreamSaver was also used, since the format is
different use directly ofstream
* added corechanges
2024-01-24 18:49:06 +01:00
|
|
|
sw.add( "Flags", flags );
|
|
|
|
|
sw.add( "Version", version );
|
|
|
|
|
sw.add( "OldVersion", oldversion );
|
|
|
|
|
sw.end();
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string DataStoreFile::filename( unsigned ver ) const
|
|
|
|
|
{
|
|
|
|
|
std::string tmp = Plib::systemstate.config.world_data_path + "ds/";
|
2018-07-31 14:30:29 +02:00
|
|
|
if ( pkg != nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
tmp += pkg->name() + "/";
|
|
|
|
|
tmp += name + "." + Clib::tostring( ver % 10 ) + ".txt";
|
|
|
|
|
return tmp;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string DataStoreFile::filename() const
|
|
|
|
|
{
|
|
|
|
|
return filename( version );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataStoreFile::save() const
|
|
|
|
|
{
|
|
|
|
|
std::string fname = filename();
|
|
|
|
|
std::ofstream ofs( fname.c_str(), std::ios::out );
|
Savefile rewrite (#601)
* rewrite of saving, replaced operator way with a generic add method, thus
not everywhere the formating of the savefiles is hardcoded.
since its the last spot which uses the old formating lib, remobed the
lib
* removed cmake of old format lib
* testscripts for load/save of UObject,Item,Armor,Weapon
* fixed: member faster_cast_recovery and faster_cast_recovery_mod getter returned
a wrong value
* wrong/missing docs
* test containers, lockable, map, spellbooks
fixed save bug in map and spellbook
removed ancient savestrategy experiments
* added corpse test
splitted testfiles
* fixed loading (ancient bug) and saving (PR bug) of Reportables
added tests for houses, boats, accounts and chars
* fixed include
* fix shutdown leak
* added npc tests
upload complete coretest folder also on failure
* do not write and load RegisteredHouse for NPCs two times
readded extra newline between accounts
* tests for guild, party, realm
added resource cfgs, but a test is not really possible since nothing of
interest is stored
* added datafile, storage test
* activated resource loading, 25year old bug, but since the stored values
are senseless it makes no real difference.
added a few wtf comments
catch all exceptions during formatting of log lines
* replaced .write with explixit .begin, .end and .comment.
for leftovers.txt the StreamSaver was also used, since the format is
different use directly ofstream
* added corechanges
2024-01-24 18:49:06 +01:00
|
|
|
Clib::StreamWriter sw( &ofs );
|
2016-02-19 19:26:35 +01:00
|
|
|
dfcontents->save( sw );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t DataStoreFile::estimateSize() const
|
|
|
|
|
{
|
|
|
|
|
size_t size = descriptor.capacity() + name.capacity() + pkgname.capacity() +
|
|
|
|
|
sizeof( Plib::Package* ) /*pkg*/
|
|
|
|
|
+ 3 * sizeof( unsigned ) /*version oldversion delversion*/
|
|
|
|
|
+ sizeof( int ) /*flags*/
|
|
|
|
|
+ sizeof( bool ) /*unload*/
|
|
|
|
|
+ sizeof( DataFileContentsRef );
|
|
|
|
|
if ( dfcontents.get() )
|
|
|
|
|
size += dfcontents->estimateSize();
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2018-01-29 21:55:48 +01:00
|
|
|
DataFileElement::DataFileElement() : proplist( Core::CPropProfiler::Type::DATAFILEELEMENT ) {}
|
2016-02-19 19:26:35 +01:00
|
|
|
|
|
|
|
|
DataFileElement::DataFileElement( Clib::ConfigElem& elem )
|
|
|
|
|
: proplist( Core::CPropProfiler::Type::DATAFILEELEMENT )
|
|
|
|
|
{
|
|
|
|
|
proplist.readRemainingPropertiesAsStrings( elem );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void DataFileElement::printOn( Clib::StreamWriter& sw ) const
|
|
|
|
|
{
|
|
|
|
|
proplist.printPropertiesAsStrings( sw );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void read_datastore_dat()
|
|
|
|
|
{
|
|
|
|
|
std::string datastorefile = Plib::systemstate.config.world_data_path + "datastore.txt";
|
|
|
|
|
|
|
|
|
|
if ( !Clib::FileExists( datastorefile ) )
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
Clib::ConfigFile cf( datastorefile, "DataFile" );
|
|
|
|
|
Clib::ConfigElem elem;
|
|
|
|
|
|
|
|
|
|
while ( cf.read( elem ) )
|
|
|
|
|
{
|
|
|
|
|
DataStoreFile* dsf = new DataStoreFile( elem );
|
|
|
|
|
Core::configurationbuffer.datastore[dsf->descriptor] = dsf;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void write_datastore( Clib::StreamWriter& sw )
|
|
|
|
|
{
|
|
|
|
|
for ( Core::DataStore::iterator itr = Core::configurationbuffer.datastore.begin();
|
|
|
|
|
itr != Core::configurationbuffer.datastore.end(); ++itr )
|
|
|
|
|
{
|
|
|
|
|
DataStoreFile* dsf = ( *itr ).second;
|
|
|
|
|
|
|
|
|
|
dsf->delversion = dsf->oldversion;
|
|
|
|
|
dsf->oldversion = dsf->version;
|
|
|
|
|
|
|
|
|
|
if ( dsf->dfcontents.get() && dsf->dfcontents->dirty )
|
|
|
|
|
{
|
|
|
|
|
// make a new generation of file and write it.
|
|
|
|
|
++dsf->version;
|
|
|
|
|
|
|
|
|
|
dsf->save();
|
|
|
|
|
|
|
|
|
|
dsf->dfcontents->dirty = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
dsf->printOn( sw );
|
|
|
|
|
// sw.flush();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void commit_datastore()
|
|
|
|
|
{
|
|
|
|
|
for ( Core::DataStore::iterator itr = Core::configurationbuffer.datastore.begin();
|
|
|
|
|
itr != Core::configurationbuffer.datastore.end(); ++itr )
|
|
|
|
|
{
|
|
|
|
|
DataStoreFile* dsf = ( *itr ).second;
|
|
|
|
|
|
|
|
|
|
if ( dsf->delversion != dsf->version && dsf->delversion != dsf->oldversion )
|
|
|
|
|
{
|
|
|
|
|
Clib::RemoveFile( dsf->filename( dsf->delversion ) );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( dsf->unload )
|
|
|
|
|
{
|
2018-07-31 14:30:29 +02:00
|
|
|
if ( dsf->dfcontents.get() != nullptr )
|
2016-02-19 19:26:35 +01:00
|
|
|
{
|
|
|
|
|
if ( dsf->dfcontents->count() == 1 )
|
|
|
|
|
{
|
|
|
|
|
dsf->dfcontents.clear();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
dsf->unload = false;
|
|
|
|
|
}
|
2014-08-30 12:25:08 +02:00
|
|
|
}
|
2016-02-19 19:26:35 +01:00
|
|
|
}
|
2019-11-10 22:04:08 +01:00
|
|
|
} // namespace Module
|
|
|
|
|
} // namespace Pol
|