Something went wrong. Try again.
the game where you go into mines and start crafting! but for consoles (forked directly from smartcmd's github)
Something went wrong. Try again.
24 kB · 821 lines
C++
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822#include "stdafx.h"#include "System.h"#include "net.minecraft.world.entity.player.h"#include "net.minecraft.world.level.h"#include "net.minecraft.world.level.chunk.storage.h"#include "net.minecraft.world.level.dimension.h"#include "com.mojang.nbt.h"#include "File.h"#include "DataInputStream.h"#include "FileInputStream.h"#include "LevelData.h"#include "DirectoryLevelStorage.h"#include "ConsoleSaveFileIO.h"
const wstring DirectoryLevelStorage::sc_szPlayerDir(L"players/");
_MapDataMappings::_MapDataMappings(){#ifndef _DURANGO ZeroMemory(xuids,sizeof(PlayerUID)*MAXIMUM_MAP_SAVE_DATA);#endif ZeroMemory(dimensions,sizeof(byte)*(MAXIMUM_MAP_SAVE_DATA/4));}
int _MapDataMappings::getDimension(int id){ int offset = (2*(id%4)); int val = (dimensions[id>>2] & (3 << offset))>>offset;
int returnVal=0;
switch(val) { case 0: returnVal = 0; // Overworld break; case 1: returnVal = -1; // Nether break; case 2: returnVal = 1; // End break; default:#ifndef _CONTENT_PACKAGE printf("Read invalid dimension from MapDataMapping\n"); __debugbreak();#endif break; } return returnVal;}
void _MapDataMappings::setMapping(int id, PlayerUID xuid, int dimension){ xuids[id] = xuid;
int offset = (2*(id%4));
// Reset it first dimensions[id>>2] &= ~( 2 << offset ); switch(dimension) { case 0: // Overworld //dimensions[id>>2] &= ~( 2 << offset ); break; case -1: // Nether dimensions[id>>2] |= ( 1 << offset ); break; case 1: // End dimensions[id>>2] |= ( 2 << offset ); break; default:#ifndef _CONTENT_PACKAGE printf("Trinyg to set a MapDataMapping for an invalid dimension.\n"); __debugbreak();#endif break; }}
// Old version the only used 1 bit for dimension indexing_MapDataMappings_old::_MapDataMappings_old(){#ifndef _DURANGO ZeroMemory(xuids,sizeof(PlayerUID)*MAXIMUM_MAP_SAVE_DATA);#endif ZeroMemory(dimensions,sizeof(byte)*(MAXIMUM_MAP_SAVE_DATA/8));}
int _MapDataMappings_old::getDimension(int id){ return dimensions[id>>3] & (128 >> (id%8) ) ? -1 : 0;}
void _MapDataMappings_old::setMapping(int id, PlayerUID xuid, int dimension){ xuids[id] = xuid; if( dimension == 0 ) { dimensions[id>>3] &= ~( 128 >> (id%8) ); } else { dimensions[id>>3] |= ( 128 >> (id%8) ); }}
#ifdef _LARGE_WORLDSvoid DirectoryLevelStorage::PlayerMappings::addMapping(int id, int centreX, int centreZ, int dimension, int scale){ __int64 index = ( ((__int64)(centreZ & 0x1FFFFFFF)) << 34) | ( ((__int64)(centreX & 0x1FFFFFFF)) << 5) | ( (scale & 0x7) << 2) | (dimension & 0x3); m_mappings[index] = id; //app.DebugPrintf("Adding mapping: %d - (%d,%d)/%d/%d [%I64d - 0x%016llx]\n", id, centreX, centreZ, dimension, scale, index, index);}
bool DirectoryLevelStorage::PlayerMappings::getMapping(int &id, int centreX, int centreZ, int dimension, int scale){ //__int64 zMasked = centreZ & 0x1FFFFFFF; //__int64 xMasked = centreX & 0x1FFFFFFF; //__int64 zShifted = zMasked << 34; //__int64 xShifted = xMasked << 5; //app.DebugPrintf("xShifted = %d (0x%016x), zShifted = %I64d (0x%016llx)\n", xShifted, xShifted, zShifted, zShifted); __int64 index = ( ((__int64)(centreZ & 0x1FFFFFFF)) << 34) | ( ((__int64)(centreX & 0x1FFFFFFF)) << 5) | ( (scale & 0x7) << 2) | (dimension & 0x3); AUTO_VAR(it,m_mappings.find(index)); if(it != m_mappings.end()) { id = it->second; //app.DebugPrintf("Found mapping: %d - (%d,%d)/%d/%d [%I64d - 0x%016llx]\n", id, centreX, centreZ, dimension, scale, index, index); return true; } else { //app.DebugPrintf("Failed to find mapping: (%d,%d)/%d/%d [%I64d - 0x%016llx]\n", centreX, centreZ, dimension, scale, index, index); return false; }}
void DirectoryLevelStorage::PlayerMappings::writeMappings(DataOutputStream *dos){ dos->writeInt(m_mappings.size()); for(AUTO_VAR(it, m_mappings.begin()); it != m_mappings.end(); ++it) { app.DebugPrintf(" -- %lld (0x%016llx) = %d\n", it->first, it->first, it->second); dos->writeLong(it->first); dos->writeInt(it->second); }}
void DirectoryLevelStorage::PlayerMappings::readMappings(DataInputStream *dis){ int count = dis->readInt(); for(unsigned int i = 0; i < count; ++i) { __int64 index = dis->readLong(); int id = dis->readInt(); m_mappings[index] = id; app.DebugPrintf(" -- %lld (0x%016llx) = %d\n", index, index, id); }}#endif
DirectoryLevelStorage::DirectoryLevelStorage(ConsoleSaveFile *saveFile, const File dir, const wstring& levelId, bool createPlayerDir) : sessionId( System::currentTimeMillis() ), dir( L"" ), playerDir( sc_szPlayerDir ), dataDir( wstring(L"data/") ), levelId(levelId){ m_saveFile = saveFile; m_bHasLoadedMapDataMappings = false;
#ifdef _LARGE_WORLDS m_usedMappings = byteArray(MAXIMUM_MAP_SAVE_DATA/8);#endif}
DirectoryLevelStorage::~DirectoryLevelStorage(){ delete m_saveFile;
for(AUTO_VAR(it,m_cachedSaveData.begin()); it != m_cachedSaveData.end(); ++it) { delete it->second; }
#ifdef _LARGE_WORLDS delete m_usedMappings.data;#endif}
void DirectoryLevelStorage::initiateSession(){ // 4J Jev, removed try/catch.
File dataFile = File( dir, wstring(L"session.lock") ); FileOutputStream fos = FileOutputStream(dataFile); DataOutputStream dos = DataOutputStream(&fos); dos.writeLong(sessionId); dos.close();
}
File DirectoryLevelStorage::getFolder(){ return dir;}
void DirectoryLevelStorage::checkSession(){ // 4J-PB - Not in the Xbox game
/* File dataFile = File( dir, wstring(L"session.lock")); FileInputStream fis = FileInputStream(dataFile); DataInputStream dis = DataInputStream(&fis); dis.close(); */}
ChunkStorage *DirectoryLevelStorage::createChunkStorage(Dimension *dimension){ // 4J Jev, removed try/catch.
if (dynamic_cast<HellDimension *>(dimension) != NULL) { File dir2 = File(dir, LevelStorage::NETHER_FOLDER); //dir2.mkdirs(); // 4J Removed return new OldChunkStorage(dir2, true); } if (dynamic_cast<TheEndDimension *>(dimension) != NULL) { File dir2 = File(dir, LevelStorage::ENDER_FOLDER); //dir2.mkdirs(); // 4J Removed return new OldChunkStorage(dir2, true); }
return new OldChunkStorage(dir, true);}
LevelData *DirectoryLevelStorage::prepareLevel() { // 4J Stu Added#ifdef _LARGE_WORLDS ConsoleSavePath mapFile = getDataFile(L"largeMapDataMappings");#else ConsoleSavePath mapFile = getDataFile(L"mapDataMappings");#endif if (!m_bHasLoadedMapDataMappings && !mapFile.getName().empty() && getSaveFile()->doesFileExist( mapFile )) { DWORD NumberOfBytesRead; FileEntry *fileEntry = getSaveFile()->createFile(mapFile);
#ifdef __PS3__ // 4J Stu - This version changed happened before initial release if(getSaveFile()->getSaveVersion() < SAVE_FILE_VERSION_CHANGE_MAP_DATA_MAPPING_SIZE) { // Delete the old file if(fileEntry) getSaveFile()->deleteFile( fileEntry );
// Save a new, blank version saveMapIdLookup(); } else#elif defined(_DURANGO) // 4J Stu - This version changed happened before initial release if(getSaveFile()->getSaveVersion() < SAVE_FILE_VERSION_DURANGO_CHANGE_MAP_DATA_MAPPING_SIZE) { // Delete the old file if(fileEntry) getSaveFile()->deleteFile( fileEntry );
// Save a new, blank version saveMapIdLookup(); } else#endif { getSaveFile()->setFilePointer(fileEntry,0,NULL, FILE_BEGIN);
#ifdef _LARGE_WORLDS byteArray data(fileEntry->getFileSize()); getSaveFile()->readFile( fileEntry, data.data, fileEntry->getFileSize(), &NumberOfBytesRead); assert( NumberOfBytesRead == fileEntry->getFileSize() );
ByteArrayInputStream bais(data); DataInputStream dis(&bais); int count = dis.readInt(); app.DebugPrintf("Loading %d mappings\n", count); for(unsigned int i = 0; i < count; ++i) { PlayerUID playerUid = dis.readPlayerUID();#ifdef _WINDOWS64 app.DebugPrintf(" -- %d\n", playerUid);#else app.DebugPrintf(" -- %ls\n", playerUid.toString().c_str());#endif m_playerMappings[playerUid].readMappings(&dis); } dis.readFully(m_usedMappings);#else
if(getSaveFile()->getSaveVersion() < END_DIMENSION_MAP_MAPPINGS_SAVE_VERSION) { MapDataMappings_old oldMapDataMappings; getSaveFile()->readFile( fileEntry, &oldMapDataMappings, // data buffer sizeof(MapDataMappings_old), // number of bytes to read &NumberOfBytesRead // number of bytes read ); assert( NumberOfBytesRead == sizeof(MapDataMappings_old) );
for(unsigned int i = 0; i < MAXIMUM_MAP_SAVE_DATA; ++i) { m_saveableMapDataMappings.setMapping(i,oldMapDataMappings.xuids[i],oldMapDataMappings.getDimension(i)); } } else { getSaveFile()->readFile( fileEntry, &m_saveableMapDataMappings, // data buffer sizeof(MapDataMappings), // number of bytes to read &NumberOfBytesRead // number of bytes read ); assert( NumberOfBytesRead == sizeof(MapDataMappings) ); }
memcpy(&m_mapDataMappings,&m_saveableMapDataMappings,sizeof(MapDataMappings));#endif
// Write out our changes now if(getSaveFile()->getSaveVersion() < END_DIMENSION_MAP_MAPPINGS_SAVE_VERSION) saveMapIdLookup(); }
m_bHasLoadedMapDataMappings = true; }
// 4J Jev, removed try/catch
ConsoleSavePath dataFile = ConsoleSavePath( wstring( L"level.dat" ) );
if ( m_saveFile->doesFileExist( dataFile ) ) { ConsoleSaveFileInputStream fis = ConsoleSaveFileInputStream(m_saveFile, dataFile); CompoundTag *root = NbtIo::readCompressed(&fis); CompoundTag *tag = root->getCompound(L"Data"); LevelData *ret = new LevelData(tag); delete root; return ret; }
return NULL;}
void DirectoryLevelStorage::saveLevelData(LevelData *levelData, vector<shared_ptr<Player> > *players){ // 4J Jev, removed try/catch
CompoundTag *dataTag = levelData->createTag(players);
CompoundTag *root = new CompoundTag(); root->put(L"Data", dataTag);
ConsoleSavePath currentFile = ConsoleSavePath( wstring( L"level.dat" ) );
ConsoleSaveFileOutputStream fos = ConsoleSaveFileOutputStream( m_saveFile, currentFile ); NbtIo::writeCompressed(root, &fos);
delete root;}
void DirectoryLevelStorage::saveLevelData(LevelData *levelData){ // 4J Jev, removed try/catch
CompoundTag *dataTag = levelData->createTag();
CompoundTag *root = new CompoundTag(); root->put(L"Data", dataTag);
ConsoleSavePath currentFile = ConsoleSavePath( wstring( L"level.dat" ) );
ConsoleSaveFileOutputStream fos = ConsoleSaveFileOutputStream( m_saveFile, currentFile ); NbtIo::writeCompressed(root, &fos);
delete root;}
void DirectoryLevelStorage::save(shared_ptr<Player> player){ // 4J Jev, removed try/catch. PlayerUID playerXuid = player->getXuid();#if defined(__PS3__) || defined(__ORBIS__) if( playerXuid != INVALID_XUID )#else if( playerXuid != INVALID_XUID && !player->isGuest() )#endif { CompoundTag *tag = new CompoundTag(); player->saveWithoutId(tag);#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) ConsoleSavePath realFile = ConsoleSavePath( m_saveFile->getPlayerDataFilenameForSave(playerXuid).c_str() );#elif defined(_DURANGO) ConsoleSavePath realFile = ConsoleSavePath( playerDir.getName() + player->getXuid().toString() + L".dat" );#else ConsoleSavePath realFile = ConsoleSavePath( playerDir.getName() + _toString( player->getXuid() ) + L".dat" );#endif // If saves are disabled (e.g. because we are writing the save buffer to disk) then cache this player data if(StorageManager.GetSaveDisabled()) { ByteArrayOutputStream *bos = new ByteArrayOutputStream(); NbtIo::writeCompressed(tag,bos);
AUTO_VAR(it, m_cachedSaveData.find(realFile.getName())); if(it != m_cachedSaveData.end() ) { delete it->second; } m_cachedSaveData[realFile.getName()] = bos; app.DebugPrintf("Cached saving of file %ls due to saves being disabled\n", realFile.getName().c_str() ); } else { ConsoleSaveFileOutputStream fos = ConsoleSaveFileOutputStream( m_saveFile, realFile ); NbtIo::writeCompressed(tag, &fos); } delete tag; } else if( playerXuid != INVALID_XUID ) { app.DebugPrintf("Not saving player as their XUID is a guest\n"); dontSaveMapMappingForPlayer(playerXuid); }}
// 4J Changed return val to bool to check if new player or loaded playerCompoundTag *DirectoryLevelStorage::load(shared_ptr<Player> player) { CompoundTag *tag = loadPlayerDataTag( player->getXuid() ); if (tag != NULL) { player->load(tag); } return tag;}
CompoundTag *DirectoryLevelStorage::loadPlayerDataTag(PlayerUID xuid){ // 4J Jev, removed try/catch.#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) ConsoleSavePath realFile = ConsoleSavePath( m_saveFile->getPlayerDataFilenameForLoad(xuid).c_str() );#elif defined(_DURANGO) ConsoleSavePath realFile = ConsoleSavePath( playerDir.getName() + xuid.toString() + L".dat" );#else ConsoleSavePath realFile = ConsoleSavePath( playerDir.getName() + _toString( xuid ) + L".dat" );#endif AUTO_VAR(it, m_cachedSaveData.find(realFile.getName())); if(it != m_cachedSaveData.end() ) { ByteArrayOutputStream *bos = it->second; ByteArrayInputStream bis(bos->buf, 0, bos->size()); CompoundTag *tag = NbtIo::readCompressed(&bis); bis.reset(); app.DebugPrintf("Loaded player data from cached file %ls\n", realFile.getName().c_str() ); return tag; } else if ( m_saveFile->doesFileExist( realFile ) ) { ConsoleSaveFileInputStream fis = ConsoleSaveFileInputStream(m_saveFile, realFile); return NbtIo::readCompressed(&fis); } return NULL;}
// 4J Added functionvoid DirectoryLevelStorage::clearOldPlayerFiles(){ if(StorageManager.GetSaveDisabled() ) return;
#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) vector<FileEntry *> *playerFiles = m_saveFile->getValidPlayerDatFiles();#else vector<FileEntry *> *playerFiles = m_saveFile->getFilesWithPrefix( playerDir.getName() );#endif
if( playerFiles != NULL ) {#ifndef _FINAL_BUILD if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_DistributableSave)) { for(unsigned int i = 0; i < playerFiles->size(); ++i ) { FileEntry *file = playerFiles->at(i); wstring xuidStr = replaceAll( replaceAll(file->data.filename,playerDir.getName(),L""),L".dat",L"");#if defined(__PS3__) || defined(__ORBIS__) || defined(_DURANGO) PlayerUID xuid(xuidStr);#else PlayerUID xuid = _fromString<PlayerUID>(xuidStr);#endif deleteMapFilesForPlayer(xuid); m_saveFile->deleteFile( playerFiles->at(i) ); } } else #endif if( playerFiles->size() > MAX_PLAYER_DATA_SAVES ) { sort(playerFiles->begin(), playerFiles->end(), FileEntry::newestFirst );
for(unsigned int i = MAX_PLAYER_DATA_SAVES; i < playerFiles->size(); ++i ) { FileEntry *file = playerFiles->at(i); wstring xuidStr = replaceAll( replaceAll(file->data.filename,playerDir.getName(),L""),L".dat",L"");#if defined(__PS3__) || defined(__ORBIS__) || defined(_DURANGO) PlayerUID xuid(xuidStr);#else PlayerUID xuid = _fromString<PlayerUID>(xuidStr);#endif deleteMapFilesForPlayer(xuid); m_saveFile->deleteFile( playerFiles->at(i) ); } }
delete playerFiles; }}
PlayerIO *DirectoryLevelStorage::getPlayerIO() { return this;}
void DirectoryLevelStorage::closeAll() {}
ConsoleSavePath DirectoryLevelStorage::getDataFile(const wstring& id){ return ConsoleSavePath( dataDir.getName() + id + L".dat" );}
wstring DirectoryLevelStorage::getLevelId(){ return levelId;}
void DirectoryLevelStorage::flushSaveFile(bool autosave){#ifndef _CONTENT_PACKAGE if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_DistributableSave)) { // Delete gamerules files if it exists ConsoleSavePath gameRulesFiles(GAME_RULE_SAVENAME); if(m_saveFile->doesFileExist(gameRulesFiles)) { FileEntry *fe = m_saveFile->createFile(gameRulesFiles); m_saveFile->deleteFile( fe ); } }#endif m_saveFile->Flush(autosave);}
// 4J Addedvoid DirectoryLevelStorage::resetNetherPlayerPositions(){ if(app.GetResetNether()) {#if defined(__PS3__) || defined(__ORBIS__) || defined(__PSVITA__) vector<FileEntry *> *playerFiles = m_saveFile->getValidPlayerDatFiles();#else vector<FileEntry *> *playerFiles = m_saveFile->getFilesWithPrefix( playerDir.getName() );#endif
if( playerFiles != NULL ) { for( AUTO_VAR(it, playerFiles->begin()); it != playerFiles->end(); ++it) { FileEntry * realFile = *it; ConsoleSaveFileInputStream fis = ConsoleSaveFileInputStream(m_saveFile, realFile); CompoundTag *tag = NbtIo::readCompressed(&fis); if (tag != NULL) { // If the player is in the nether, set their y position above the top of the nether // This will force the player to be spawned in a valid position in the overworld when they are loaded if(tag->contains(L"Dimension") && tag->getInt(L"Dimension") == LevelData::DIMENSION_NETHER && tag->contains(L"Pos")) { ListTag<DoubleTag> *pos = (ListTag<DoubleTag> *) tag->getList(L"Pos"); pos->get(1)->data = DBL_MAX;
ConsoleSaveFileOutputStream fos = ConsoleSaveFileOutputStream( m_saveFile, realFile ); NbtIo::writeCompressed(tag, &fos); } delete tag; } } delete playerFiles; } }}
int DirectoryLevelStorage::getAuxValueForMap(PlayerUID xuid, int dimension, int centreXC, int centreZC, int scale){ int mapId = -1; bool foundMapping = false;
#ifdef _LARGE_WORLDS AUTO_VAR(it, m_playerMappings.find(xuid) ); if(it != m_playerMappings.end()) { foundMapping = it->second.getMapping(mapId, centreXC, centreZC, dimension, scale); }
if(!foundMapping) { for(unsigned int i = 0; i < m_usedMappings.length; ++i) { if(m_usedMappings[i] < 0xFF) { unsigned int offset = 0; for(; offset < 8; ++offset) { if( !(m_usedMappings[i] & (1<<offset)) ) { break; } } mapId = (i*8) + offset; m_playerMappings[xuid].addMapping(mapId, centreXC, centreZC, dimension, scale); m_usedMappings[i] |= (1<<offset); break; } } }#else for(unsigned int i = 0; i < MAXIMUM_MAP_SAVE_DATA; ++i) { if(m_mapDataMappings.xuids[i] == xuid && m_mapDataMappings.getDimension(i) == dimension) { foundMapping = true; mapId = i; break; } if( mapId < 0 && m_mapDataMappings.xuids[i] == INVALID_XUID ) { mapId = i; } } if( !foundMapping && mapId >= 0 && mapId < MAXIMUM_MAP_SAVE_DATA ) { m_mapDataMappings.setMapping(mapId, xuid, dimension); m_saveableMapDataMappings.setMapping(mapId, xuid, dimension);
// If we had an old map file for a mapping that is no longer valid, delete it std::wstring id = wstring( L"map_" ) + _toString(mapId); ConsoleSavePath file = getDataFile(id);
if(m_saveFile->doesFileExist(file) ) { AUTO_VAR(it, find(m_mapFilesToDelete.begin(), m_mapFilesToDelete.end(), mapId)); if(it != m_mapFilesToDelete.end()) m_mapFilesToDelete.erase(it);
m_saveFile->deleteFile( m_saveFile->createFile(file) ); } }#endif return mapId;}
void DirectoryLevelStorage::saveMapIdLookup(){ if(StorageManager.GetSaveDisabled() ) return;
#ifdef _LARGE_WORLDS ConsoleSavePath file = getDataFile(L"largeMapDataMappings");#else ConsoleSavePath file = getDataFile(L"mapDataMappings");#endif
if (!file.getName().empty()) { DWORD NumberOfBytesWritten; FileEntry *fileEntry = m_saveFile->createFile(file); m_saveFile->setFilePointer(fileEntry,0,NULL, FILE_BEGIN);
#ifdef _LARGE_WORLDS ByteArrayOutputStream baos; DataOutputStream dos(&baos); dos.writeInt(m_playerMappings.size()); app.DebugPrintf("Saving %d mappings\n", m_playerMappings.size()); for(AUTO_VAR(it,m_playerMappings.begin()); it != m_playerMappings.end(); ++it) {#ifdef _WINDOWS64 app.DebugPrintf(" -- %d\n", it->first);#else app.DebugPrintf(" -- %ls\n", it->first.toString().c_str());#endif dos.writePlayerUID(it->first); it->second.writeMappings(&dos); } dos.write(m_usedMappings); m_saveFile->writeFile( fileEntry, baos.buf.data, // data buffer baos.size(), // number of bytes to write &NumberOfBytesWritten // number of bytes written );#else m_saveFile->writeFile( fileEntry, &m_saveableMapDataMappings, // data buffer sizeof(MapDataMappings), // number of bytes to write &NumberOfBytesWritten // number of bytes written ); assert( NumberOfBytesWritten == sizeof(MapDataMappings) );#endif }}
void DirectoryLevelStorage::dontSaveMapMappingForPlayer(PlayerUID xuid){#ifdef _LARGE_WORLDS AUTO_VAR(it, m_playerMappings.find(xuid) ); if(it != m_playerMappings.end()) { for(AUTO_VAR(itMap, it->second.m_mappings.begin()); itMap != it->second.m_mappings.end(); ++itMap) { int index = itMap->second / 8; int offset = itMap->second % 8; m_usedMappings[index] &= ~(1<<offset); } m_playerMappings.erase(it); }#else for(unsigned int i = 0; i < MAXIMUM_MAP_SAVE_DATA; ++i) { if(m_saveableMapDataMappings.xuids[i] == xuid) { m_saveableMapDataMappings.setMapping(i,INVALID_XUID,0); } }#endif}
void DirectoryLevelStorage::deleteMapFilesForPlayer(shared_ptr<Player> player){ PlayerUID playerXuid = player->getXuid(); if(playerXuid != INVALID_XUID) deleteMapFilesForPlayer(playerXuid);}
void DirectoryLevelStorage::deleteMapFilesForPlayer(PlayerUID xuid){#ifdef _LARGE_WORLDS AUTO_VAR(it, m_playerMappings.find(xuid) ); if(it != m_playerMappings.end()) { for(AUTO_VAR(itMap, it->second.m_mappings.begin()); itMap != it->second.m_mappings.end(); ++itMap) { std::wstring id = wstring( L"map_" ) + _toString(itMap->second); ConsoleSavePath file = getDataFile(id);
if(m_saveFile->doesFileExist(file) ) { // If we can't actually delete this file, store the name so we can delete it later if(StorageManager.GetSaveDisabled()) m_mapFilesToDelete.push_back(itMap->second); else m_saveFile->deleteFile( m_saveFile->createFile(file) ); }
int index = itMap->second / 8; int offset = itMap->second % 8; m_usedMappings[index] &= ~(1<<offset); } m_playerMappings.erase(it); }#else bool changed = false; for(unsigned int i = 0; i < MAXIMUM_MAP_SAVE_DATA; ++i) { if(m_mapDataMappings.xuids[i] == xuid) { changed = true;
std::wstring id = wstring( L"map_" ) + _toString(i); ConsoleSavePath file = getDataFile(id);
if(m_saveFile->doesFileExist(file) ) { // If we can't actually delete this file, store the name so we can delete it later if(StorageManager.GetSaveDisabled()) m_mapFilesToDelete.push_back(i); else m_saveFile->deleteFile( m_saveFile->createFile(file) ); } m_mapDataMappings.setMapping(i,INVALID_XUID,0); m_saveableMapDataMappings.setMapping(i,INVALID_XUID,0); break; } }#endif}
void DirectoryLevelStorage::saveAllCachedData(){ if(StorageManager.GetSaveDisabled() ) return;
// Save any files that were saved while saving was disabled for(AUTO_VAR(it, m_cachedSaveData.begin()); it != m_cachedSaveData.end(); ++it) { ByteArrayOutputStream *bos = it->second;
ConsoleSavePath realFile = ConsoleSavePath( it->first ); ConsoleSaveFileOutputStream fos = ConsoleSaveFileOutputStream( m_saveFile, realFile );
app.DebugPrintf("Actually writing cached file %ls\n",it->first.c_str() ); fos.write(bos->buf, 0, bos->size() ); delete bos; } m_cachedSaveData.clear();
for(AUTO_VAR(it, m_mapFilesToDelete.begin()); it != m_mapFilesToDelete.end(); ++it) { std::wstring id = wstring( L"map_" ) + _toString(*it); ConsoleSavePath file = getDataFile(id); if(m_saveFile->doesFileExist(file) ) { m_saveFile->deleteFile( m_saveFile->createFile(file) ); } } m_mapFilesToDelete.clear();}