mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-05-11 19:53:52 +00:00
Initial commit
This commit is contained in:
parent
def8cb4153
commit
b691c43c44
19437 changed files with 4363922 additions and 0 deletions
365
Minecraft.World/McRegionLevelStorageSource.cpp
Normal file
365
Minecraft.World/McRegionLevelStorageSource.cpp
Normal file
|
|
@ -0,0 +1,365 @@
|
|||
#include "stdafx.h"
|
||||
#include "JavaMath.h"
|
||||
#include "BasicTypeContainers.h"
|
||||
#if 0
|
||||
// 4J - not required anymore
|
||||
#include "Matcher.h"
|
||||
#endif
|
||||
#include "ProgressListener.h"
|
||||
#include "net.minecraft.world.level.chunk.storage.h"
|
||||
#include "net.minecraft.world.level.chunk.h"
|
||||
#include "LevelSummary.h"
|
||||
#include "McRegionLevelStorage.h"
|
||||
#include "File.h"
|
||||
#include "LevelData.h"
|
||||
#include "McRegionLevelStorageSource.h"
|
||||
|
||||
#include "ConsoleSaveFileIO.h"
|
||||
|
||||
#if 0
|
||||
// 4J - not required anymore
|
||||
// These were Pattern class objects, using the c++0x regex class instead
|
||||
const std::tr1::wregex McRegionLevelStorageSource::FolderFilter::chunkFolderPattern = std::tr1::wregex(L"[0-9a-z]|([0-9a-z][0-9a-z])");
|
||||
const std::tr1::wregex McRegionLevelStorageSource::ChunkFilter::chunkFilePattern = std::tr1::wregex(L"c\\.(-?[0-9a-z]+)\\.(-?[0-9a-z]+)\\.dat");
|
||||
#endif
|
||||
|
||||
McRegionLevelStorageSource::McRegionLevelStorageSource(File dir) : DirectoryLevelStorageSource(dir)
|
||||
{
|
||||
}
|
||||
|
||||
wstring McRegionLevelStorageSource::getName()
|
||||
{
|
||||
return L"Scaevolus' McRegion";
|
||||
}
|
||||
|
||||
vector<LevelSummary *> *McRegionLevelStorageSource::getLevelList()
|
||||
{
|
||||
// 4J Stu - We don't need to do directory lookups with the xbox save files
|
||||
vector<LevelSummary *> *levels = new vector<LevelSummary *>;
|
||||
#if 0
|
||||
vector<File *> *subFolders = baseDir.listFiles();
|
||||
File *file;
|
||||
AUTO_VAR(itEnd, subFolders->end());
|
||||
for (AUTO_VAR(it, subFolders->begin()); it != itEnd; it++)
|
||||
{
|
||||
file = *it; //subFolders->at(i);
|
||||
|
||||
if (file->isDirectory())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
wstring levelId = file->getName();
|
||||
|
||||
LevelData *levelData = getDataTagFor(levelId);
|
||||
if (levelData != NULL)
|
||||
{
|
||||
bool requiresConversion = levelData->getVersion() != McRegionLevelStorage::MCREGION_VERSION_ID;
|
||||
wstring levelName = levelData->getLevelName();
|
||||
|
||||
if (levelName.empty()) // 4J Jev TODO: levelName can't be NULL? if (levelName == NULL || isEmpty(levelName))
|
||||
{
|
||||
levelName = levelId;
|
||||
}
|
||||
// long size = getLevelSize(folder);
|
||||
long size = 0;
|
||||
levels->push_back(new LevelSummary(levelId, levelName, levelData->getLastPlayed(), size, requiresConversion, levelData->isHardcore()));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return levels;
|
||||
}
|
||||
|
||||
void McRegionLevelStorageSource::clearAll()
|
||||
{
|
||||
}
|
||||
|
||||
shared_ptr<LevelStorage> McRegionLevelStorageSource::selectLevel(ConsoleSaveFile *saveFile, const wstring& levelId, bool createPlayerDir)
|
||||
{
|
||||
// return new LevelStorageProfilerDecorator(new McRegionLevelStorage(baseDir, levelId, createPlayerDir));
|
||||
return shared_ptr<LevelStorage>(new McRegionLevelStorage(saveFile, baseDir, levelId, createPlayerDir));
|
||||
}
|
||||
|
||||
bool McRegionLevelStorageSource::isConvertible(ConsoleSaveFile *saveFile, const wstring& levelId)
|
||||
{
|
||||
// check if there is old file format level data
|
||||
LevelData *levelData = getDataTagFor(saveFile, levelId);
|
||||
if (levelData == NULL || levelData->getVersion() != 0)
|
||||
{
|
||||
delete levelData;
|
||||
return false;
|
||||
}
|
||||
delete levelData;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool McRegionLevelStorageSource::requiresConversion(ConsoleSaveFile *saveFile, const wstring& levelId)
|
||||
{
|
||||
LevelData *levelData = getDataTagFor(saveFile, levelId);
|
||||
if (levelData == NULL || levelData->getVersion() != 0)
|
||||
{
|
||||
delete levelData;
|
||||
return false;
|
||||
}
|
||||
delete levelData;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool McRegionLevelStorageSource::convertLevel(ConsoleSaveFile *saveFile, const wstring& levelId, ProgressListener *progress)
|
||||
{
|
||||
assert(false);
|
||||
// I removed this while updating the saves to use the single save file
|
||||
// Will we ever use this convertLevel function anyway? The main issue is the check
|
||||
// for the hellFolder.exists() which would require a slight change to the way our
|
||||
// save files are structured
|
||||
#if 0
|
||||
progress->progressStagePercentage(0);
|
||||
|
||||
vector<ChunkFile *> *normalRegions = new vector<ChunkFile *>;
|
||||
vector<File *> *normalBaseFolders = new vector<File *>;
|
||||
vector<ChunkFile *> *netherRegions = new vector<ChunkFile *>;
|
||||
vector<File *> *netherBaseFolders = new vector<File *>;
|
||||
ArrayList<ChunkFile> enderRegions = new ArrayList<ChunkFile>();
|
||||
ArrayList<File> enderBaseFolders = new ArrayList<File>();
|
||||
|
||||
//File baseFolder = File(baseDir, levelId);
|
||||
//File netherFolder = File(baseFolder, LevelStorage::HELL_FOLDER);
|
||||
//File enderFolder = new File(baseFolder, LevelStorage.ENDER_FOLDER);
|
||||
ConsoleSaveFile saveFile = ConsoleSaveFile( levelId );
|
||||
|
||||
// System.out.println("Scanning folders..."); 4J Jev, TODO how do we println ?
|
||||
|
||||
// find normal world
|
||||
addRegions(baseFolder, normalRegions, normalBaseFolders);
|
||||
|
||||
// find hell world
|
||||
if (netherFolder.exists())
|
||||
{
|
||||
addRegions(netherFolder, netherRegions, netherBaseFolders);
|
||||
}
|
||||
if (enderFolder.exists())
|
||||
{
|
||||
addRegions(enderFolder, enderRegions, enderBaseFolders);
|
||||
}
|
||||
|
||||
int totalCount = normalRegions->size() + netherRegions->size() + enderRegions.size() + normalBaseFolders->size() + netherBaseFolders->size() + enderBaseFolders.size();
|
||||
|
||||
// System.out.println("Total conversion count is " + totalCount); 4J Jev, TODO
|
||||
|
||||
// convert normal world
|
||||
convertRegions(baseFolder, normalRegions, 0, totalCount, progress);
|
||||
// convert hell world
|
||||
convertRegions(netherFolder, netherRegions, normalRegions->size(), totalCount, progress);
|
||||
// convert hell world
|
||||
convertRegions(enderFolder, enderRegions, normalRegions.size() + netherRegions.size(), totalCount, progress);
|
||||
|
||||
LevelData *levelData = getDataTagFor(levelId);
|
||||
levelData->setVersion(McRegionLevelStorage::MCREGION_VERSION_ID);
|
||||
|
||||
LevelStorage *levelStorage = selectLevel(levelId, false);
|
||||
levelStorage->saveLevelData(levelData);
|
||||
|
||||
// erase old files
|
||||
eraseFolders(normalBaseFolders, normalRegions->size() + netherRegions->size(), totalCount, progress);
|
||||
if (netherFolder.exists())
|
||||
{
|
||||
eraseFolders(netherBaseFolders, normalRegions->size() + netherRegions->size() + normalBaseFolders->size(), totalCount, progress);
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// 4J - not required anymore
|
||||
void McRegionLevelStorageSource::addRegions(File &baseFolder, vector<ChunkFile *> *dest, vector<File *> *firstLevelFolders)
|
||||
{
|
||||
FolderFilter folderFilter;
|
||||
ChunkFilter chunkFilter;
|
||||
|
||||
File *folder1;
|
||||
vector<File *> *folderLevel1 = baseFolder.listFiles((FileFilter *) &folderFilter);
|
||||
AUTO_VAR(itEnd, folderLevel1->end());
|
||||
for (AUTO_VAR(it, folderLevel1->begin()); it != itEnd; it++)
|
||||
{
|
||||
folder1 = *it; //folderLevel1->at(i1);
|
||||
|
||||
// keep this for the clean-up process later on
|
||||
firstLevelFolders->push_back(folder1);
|
||||
|
||||
File *folder2;
|
||||
vector<File *> *folderLevel2 = folder1->listFiles(&folderFilter);
|
||||
AUTO_VAR(itEnd2, folderLevel2->end());
|
||||
for (AUTO_VAR(it2, folderLevel2->begin()); it2 != itEnd; it2++)
|
||||
{
|
||||
folder2 = *it2; //folderLevel2->at(i2);
|
||||
|
||||
vector<File *> *chunkFiles = folder2->listFiles((FileFilter *) &chunkFilter);
|
||||
|
||||
File *chunk;
|
||||
AUTO_VAR(itEndFile, chunkFiles->end());
|
||||
for (AUTO_VAR(itFile, chunkFiles->begin()); itFile != itEndFile; itFile++)
|
||||
{
|
||||
chunk = *itFile; //chunkFiles->at(i3);
|
||||
|
||||
dest->push_back(new ChunkFile(chunk));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void McRegionLevelStorageSource::convertRegions(File &baseFolder, vector<ChunkFile *> *chunkFiles, int currentCount, int totalCount, ProgressListener *progress)
|
||||
{
|
||||
assert( false );
|
||||
|
||||
// 4J Stu - Removed, see comment in convertLevel above
|
||||
#if 0
|
||||
//Collections::sort(chunkFiles);
|
||||
std::sort( chunkFiles->begin(), chunkFiles->end() );
|
||||
|
||||
byteArray buffer = byteArray(4096);
|
||||
|
||||
ChunkFile *chunkFile;
|
||||
AUTO_VAR(itEnd, chunkFiles->end());
|
||||
for (AUTO_VAR(it, chunkFiles->begin()); it != itEnd; it++)
|
||||
{
|
||||
chunkFile = *it; //chunkFiles->at(i1);
|
||||
|
||||
// Matcher matcher = ChunkFilter.chunkFilePattern.matcher(chunkFile.getName());
|
||||
// if (!matcher.matches()) {
|
||||
// continue;
|
||||
// }
|
||||
// int x = Integer.parseInt(matcher.group(1), 36);
|
||||
// int z = Integer.parseInt(matcher.group(2), 36);
|
||||
|
||||
int x = chunkFile->getX();
|
||||
int z = chunkFile->getZ();
|
||||
|
||||
RegionFile *region = RegionFileCache::getRegionFile(baseFolder, x, z);
|
||||
if (!region->hasChunk(x & 31, z & 31))
|
||||
{
|
||||
FileInputStream fis = new BufferedInputStream(FileInputStream(*chunkFile->getFile()));
|
||||
DataInputStream istream = DataInputStream(&fis); // 4J - was new GZIPInputStream as well
|
||||
|
||||
DataOutputStream *out = region->getChunkDataOutputStream(x & 31, z & 31);
|
||||
|
||||
int length = 0;
|
||||
while ( (length = istream.read(buffer)) != -1 )
|
||||
{
|
||||
out->write(buffer, 0, length);
|
||||
}
|
||||
|
||||
out->close();
|
||||
istream.close();
|
||||
|
||||
// 4J Stu - getChunkDataOutputStream makes a new DataOutputStream that points to a new ChunkBuffer( ByteArrayOutputStream )
|
||||
// We should clean these up when we are done
|
||||
out->deleteChildStream();
|
||||
delete out;
|
||||
}
|
||||
|
||||
currentCount++;
|
||||
int percent = (int) Math::round(100.0 * (double) currentCount / (double) totalCount);
|
||||
progress->progressStagePercentage(percent);
|
||||
}
|
||||
RegionFileCache::clear();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void McRegionLevelStorageSource::eraseFolders(vector<File *> *folders, int currentCount, int totalCount, ProgressListener *progress)
|
||||
{
|
||||
File *folder;
|
||||
AUTO_VAR(itEnd, folders->end());
|
||||
for (AUTO_VAR(it, folders->begin()); it != itEnd; it++)
|
||||
{
|
||||
folder = *it; //folders->at(i);
|
||||
|
||||
vector<File *> *files = folder->listFiles();
|
||||
deleteRecursive(files);
|
||||
folder->_delete();
|
||||
|
||||
currentCount++;
|
||||
int percent = (int) Math::round(100.0 * (double) currentCount / (double) totalCount);
|
||||
progress->progressStagePercentage(percent);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// 4J - not required anymore
|
||||
bool McRegionLevelStorageSource::FolderFilter::accept(File *file)
|
||||
{
|
||||
if (file->isDirectory())
|
||||
{
|
||||
Matcher matcher( chunkFolderPattern, file->getName() );
|
||||
return matcher.matches();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool McRegionLevelStorageSource::ChunkFilter::accept(File *dir, const wstring& name)
|
||||
{
|
||||
Matcher matcher( chunkFilePattern, name );
|
||||
return matcher.matches();
|
||||
}
|
||||
|
||||
|
||||
McRegionLevelStorageSource::ChunkFile::ChunkFile(File *file)
|
||||
{
|
||||
this->file = file;
|
||||
|
||||
Matcher matcher( ChunkFilter::chunkFilePattern, file->getName() );
|
||||
if (matcher.matches())
|
||||
{
|
||||
x = Integer::parseInt(matcher.group(1), 36);
|
||||
z = Integer::parseInt(matcher.group(2), 36);
|
||||
}
|
||||
else
|
||||
{
|
||||
x = 0;
|
||||
z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
|
||||
int McRegionLevelStorageSource::ChunkFile::compareTo(ChunkFile *rhs)
|
||||
{
|
||||
// sort chunk files so that they are placed according to their
|
||||
// region position
|
||||
int rx = x >> 5;
|
||||
int rhsrx = rhs->x >> 5;
|
||||
if (rx == rhsrx)
|
||||
{
|
||||
int rz = z >> 5;
|
||||
int rhsrz = rhs->z >> 5;
|
||||
return rz - rhsrz;
|
||||
}
|
||||
|
||||
return rx - rhsrx;
|
||||
}
|
||||
|
||||
// 4J Stu Added so we can use std::sort instead of the java Collections::sort
|
||||
// a < b
|
||||
bool McRegionLevelStorageSource::ChunkFile::operator<( ChunkFile *b )
|
||||
{
|
||||
return compareTo( b ) < 0;
|
||||
}
|
||||
|
||||
File *McRegionLevelStorageSource::ChunkFile::getFile()
|
||||
{
|
||||
return (File *) file;
|
||||
}
|
||||
|
||||
int McRegionLevelStorageSource::ChunkFile::getX()
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
int McRegionLevelStorageSource::ChunkFile::getZ()
|
||||
{
|
||||
return z;
|
||||
}
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue