mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-05-24 08:42:53 +00:00
Modernise portable file and timing utilities
This commit is contained in:
parent
ca48a01a81
commit
e1a66b0ad0
|
|
@ -1,6 +1,7 @@
|
|||
#include "../Platform/stdafx.h"
|
||||
|
||||
#include "../../Minecraft.World/Util/StringHelpers.h"
|
||||
#include "../../Minecraft.World/Util/PortableFileIO.h"
|
||||
#include "../../Minecraft.World/IO/Streams/Compression.h"
|
||||
|
||||
#include "ArchiveFile.h"
|
||||
|
|
@ -120,66 +121,18 @@ byteArray ArchiveFile::getFile(const std::wstring &filename)
|
|||
|
||||
memcpy( out.data, m_cachedData + data->ptr, data->filesize );
|
||||
#else
|
||||
const unsigned int fileSize = static_cast<unsigned int>(data->filesize);
|
||||
PBYTE pbData = new BYTE[fileSize == 0 ? 1 : fileSize];
|
||||
out = byteArray(pbData, fileSize);
|
||||
const PortableFileIO::BinaryReadResult readResult = PortableFileIO::ReadBinaryFileSegment(
|
||||
m_sourcefile.getPath(),
|
||||
static_cast<std::size_t>(data->ptr),
|
||||
out.data,
|
||||
static_cast<std::size_t>(data->filesize));
|
||||
|
||||
#if defined(_UNICODE) && !defined(__linux__)
|
||||
HANDLE hfile = CreateFile( m_sourcefile.getPath().c_str(),
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
#else
|
||||
app.DebugPrintf("Createfile archive\n");
|
||||
HANDLE hfile = CreateFile( wstringtofilename(m_sourcefile.getPath()),
|
||||
GENERIC_READ,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL
|
||||
);
|
||||
#endif
|
||||
|
||||
if (hfile != INVALID_HANDLE_VALUE)
|
||||
if (readResult.status != PortableFileIO::BinaryReadStatus::ok)
|
||||
{
|
||||
app.DebugPrintf("hfile ok\n");
|
||||
DWORD ok = SetFilePointer( hfile,
|
||||
data->ptr,
|
||||
NULL,
|
||||
FILE_BEGIN
|
||||
);
|
||||
|
||||
if (ok != INVALID_SET_FILE_POINTER)
|
||||
{
|
||||
PBYTE pbData = new BYTE[ data->filesize ];
|
||||
|
||||
DWORD bytesRead = -1;
|
||||
BOOL bSuccess = ReadFile( hfile,
|
||||
(LPVOID) pbData,
|
||||
data->filesize,
|
||||
&bytesRead,
|
||||
NULL
|
||||
);
|
||||
|
||||
if(bSuccess==FALSE)
|
||||
{
|
||||
app.FatalLoadError();
|
||||
}
|
||||
assert(bytesRead == data->filesize);
|
||||
out = byteArray(pbData, data->filesize);
|
||||
}
|
||||
else
|
||||
{
|
||||
app.FatalLoadError();
|
||||
}
|
||||
|
||||
CloseHandle(hfile);
|
||||
}
|
||||
else
|
||||
{
|
||||
app.DebugPrintf("bad hfile\n");
|
||||
app.DebugPrintf("Failed to read archive file segment\n");
|
||||
app.FatalLoadError();
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@
|
|||
#include "../../Level/Storage/McRegionLevelStorageSource.h"
|
||||
#include "File.h"
|
||||
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#endif
|
||||
|
||||
#ifdef __PS3__
|
||||
#include <cell/cell_fs.h>
|
||||
#endif
|
||||
|
|
@ -17,6 +22,34 @@ const std::wstring File::pathRoot = L"GAME:"; // Path root after pathSeparator h
|
|||
const std::wstring File::pathRoot = L""; // Path root after pathSeparator has been removed
|
||||
#endif
|
||||
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
namespace
|
||||
{
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
fs::path ToFilesystemPath(const std::wstring& path)
|
||||
{
|
||||
const std::string nativePath = wstringtofilename(path);
|
||||
return fs::u8path(nativePath);
|
||||
}
|
||||
|
||||
std::wstring ToFilename(const fs::path& path)
|
||||
{
|
||||
const std::string filename = path.filename().u8string();
|
||||
return filenametowstring(filename.c_str());
|
||||
}
|
||||
|
||||
__int64 ToEpochMilliseconds(const fs::file_time_type& fileTime)
|
||||
{
|
||||
using namespace std::chrono;
|
||||
|
||||
const auto systemTime = time_point_cast<milliseconds>(
|
||||
fileTime - fs::file_time_type::clock::now() + system_clock::now());
|
||||
return static_cast<__int64>(systemTime.time_since_epoch().count());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//Creates a new File instance from a parent abstract pathname and a child pathname string.
|
||||
File::File( const File &parent, const std::wstring& child )
|
||||
{
|
||||
|
|
@ -97,7 +130,36 @@ this->parent = NULL;
|
|||
//true if and only if the file or directory is successfully deleted; false otherwise
|
||||
bool File::_delete()
|
||||
{
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
const bool result = fs::remove(ToFilesystemPath(getPath()), error);
|
||||
#if defined _UNICODE
|
||||
if( !result || error )
|
||||
{
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
printf( "File::_delete - Error code %d (%#0.8X)\n", error.value(), error.value() );
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#elif defined(__linux__)
|
||||
if( !result || error )
|
||||
{
|
||||
printf("Unable to delete file :(");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
if( !result || error )
|
||||
{
|
||||
#ifndef _CONTENT_PACKAGE
|
||||
printf( "File::_delete - Error code %d (%#0.8X)\n", error.value(), error.value() );
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#endif
|
||||
#elif defined _UNICODE
|
||||
BOOL result = DeleteFile( getPath().c_str() );
|
||||
#elif defined(__linux__)
|
||||
// FIXME
|
||||
|
|
@ -126,7 +188,10 @@ bool File::_delete()
|
|||
//true if and only if the directory was created; false otherwise
|
||||
bool File::mkdir() const
|
||||
{
|
||||
#if defined (_UNICODE)
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
return fs::create_directory(ToFilesystemPath(getPath()), error);
|
||||
#elif defined (_UNICODE)
|
||||
return CreateDirectory( getPath().c_str(), NULL) != 0;
|
||||
#elif defined(__linux__)
|
||||
return ::mkdir(wstringtofilename(getPath()), 0777) == 0;
|
||||
|
|
@ -157,6 +222,22 @@ bool File::mkdir() const
|
|||
//
|
||||
bool File::mkdirs() const
|
||||
{
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
const fs::path path = ToFilesystemPath(getPath());
|
||||
|
||||
if( fs::exists(path, error) )
|
||||
{
|
||||
return fs::is_directory(path, error);
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return fs::create_directories(path, error);
|
||||
#else
|
||||
std::vector<std::wstring> path = stringSplit( m_abstractPathName, pathSeparator );
|
||||
|
||||
std::wstring pathToHere = L"";
|
||||
|
|
@ -208,6 +289,7 @@ bool File::mkdirs() const
|
|||
assert( exists() );
|
||||
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -223,7 +305,10 @@ return (File *) parent;
|
|||
bool File::exists() const
|
||||
{
|
||||
// TODO 4J Stu - Possible we could get an error result from something other than the file not existing?
|
||||
#if defined(_UNICODE)
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
return fs::exists(ToFilesystemPath(getPath()), error);
|
||||
#elif defined(_UNICODE)
|
||||
return GetFileAttributes( getPath().c_str() ) != -1;
|
||||
#elif defined(__linux__)
|
||||
// BAD DOBBY BAD DOBBY
|
||||
|
|
@ -252,6 +337,16 @@ bool File::isFile() const
|
|||
//true if and only if the renaming succeeded; false otherwise
|
||||
bool File::renameTo(File dest)
|
||||
{
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
fs::rename(ToFilesystemPath(getPath()), ToFilesystemPath(dest.getPath()), error);
|
||||
if(error)
|
||||
{
|
||||
perror("File::renameTo - Error renaming file");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
#else
|
||||
std::string sourcePath = wstringtofilename(getPath());
|
||||
std::string destPath = wstringtofilename(dest.getPath());
|
||||
|
||||
|
|
@ -266,37 +361,9 @@ bool File::renameTo(File dest)
|
|||
{
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__linux__)
|
||||
// DecalOverdose: Stolen from my other project
|
||||
void listFiles(const char *directory) {
|
||||
DIR *dp;
|
||||
struct dirent *entry;
|
||||
struct stat fileStat;
|
||||
|
||||
dp = opendir(directory);
|
||||
if (dp == NULL) {
|
||||
perror("opendir");
|
||||
return;
|
||||
}
|
||||
|
||||
while ((entry = readdir(dp)) != NULL) {
|
||||
char fullPath[1024];
|
||||
snprintf(fullPath, sizeof(fullPath), "%s/%s", directory, entry->d_name);
|
||||
|
||||
if (stat(fullPath, &fileStat) == 0) {
|
||||
if (S_ISREG(fileStat.st_mode)) {
|
||||
printf("File: %s\n", entry->d_name);
|
||||
}
|
||||
} else {
|
||||
perror("stat");
|
||||
}
|
||||
}
|
||||
closedir(dp);
|
||||
}
|
||||
#endif // __linux__
|
||||
|
||||
//Returns an array of abstract pathnames denoting the files in the directory denoted by this abstract pathname.
|
||||
//If this abstract pathname does not denote a directory, then this method returns null. Otherwise an array of File objects is returned,
|
||||
//one for each file or directory in the directory. Pathnames denoting the directory itself and the directory's parent directory
|
||||
|
|
@ -319,6 +386,13 @@ std::vector<File *> *File::listFiles() const
|
|||
if( !isDirectory() )
|
||||
return vOutput;
|
||||
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
for( fs::directory_iterator it(ToFilesystemPath(getPath()), error); !error && it != fs::directory_iterator(); it.increment(error) )
|
||||
{
|
||||
vOutput->push_back( new File( *this, ToFilename(it->path()) ) );
|
||||
}
|
||||
#else
|
||||
#ifdef __PS3__
|
||||
const char *lpFileName=wstringtofilename(getPath());
|
||||
char filePath[256];
|
||||
|
|
@ -447,6 +521,7 @@ std::vector<File *> *File::listFiles() const
|
|||
FindClose( hFind);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
return vOutput;
|
||||
}
|
||||
|
|
@ -469,6 +544,17 @@ std::vector<File *> *File::listFiles(FileFilter *filter) const
|
|||
|
||||
std::vector<File *> *vOutput = new std::vector<File *>();
|
||||
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
for( fs::directory_iterator it(ToFilesystemPath(getPath()), error); !error && it != fs::directory_iterator(); it.increment(error) )
|
||||
{
|
||||
File thisFile = File( *this, ToFilename(it->path()) );
|
||||
if( filter->accept( &thisFile ) )
|
||||
{
|
||||
vOutput->push_back( new File( thisFile ) );
|
||||
}
|
||||
}
|
||||
#else
|
||||
#ifdef __PS3__
|
||||
const char *lpFileName=wstringtofilename(getPath());
|
||||
char filePath[256];
|
||||
|
|
@ -551,6 +637,7 @@ std::vector<File *> *File::listFiles(FileFilter *filter) const
|
|||
FindClose( hFind);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
return vOutput;
|
||||
}
|
||||
|
|
@ -560,7 +647,10 @@ std::vector<File *> *File::listFiles(FileFilter *filter) const
|
|||
//true if and only if the file denoted by this abstract pathname exists and is a directory; false otherwise
|
||||
bool File::isDirectory() const
|
||||
{
|
||||
#if defined(_UNICODE)
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
return fs::is_directory(ToFilesystemPath(getPath()), error);
|
||||
#elif defined(_UNICODE)
|
||||
return exists() && ( GetFileAttributes( getPath().c_str() ) & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY;
|
||||
#elif defined(__linux__)
|
||||
const char *dirpath = wstringtofilename(getPath());
|
||||
|
|
@ -639,17 +729,20 @@ __int64 File::length()
|
|||
return 0;
|
||||
}
|
||||
return statData.fileSize;
|
||||
#elif defined(__linux__)
|
||||
struct stat fileInfoBuffer;
|
||||
const char *path = wstringtofilename(getPath());
|
||||
#elif !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
const fs::path path = ToFilesystemPath(getPath());
|
||||
|
||||
int result = stat(path, &fileInfoBuffer);
|
||||
|
||||
if(result == 0) {
|
||||
return fileInfoBuffer.st_size;
|
||||
} else {
|
||||
return 0;
|
||||
if( fs::is_regular_file(path, error) )
|
||||
{
|
||||
const auto size = fs::file_size(path, error);
|
||||
if( !error )
|
||||
{
|
||||
return static_cast<__int64>(size);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
WIN32_FILE_ATTRIBUTE_DATA fileInfoBuffer;
|
||||
#ifdef _UNICODE
|
||||
|
|
@ -689,7 +782,21 @@ __int64 File::length()
|
|||
//or 0L if the file does not exist or if an I/O error occurs
|
||||
__int64 File::lastModified()
|
||||
{
|
||||
#if !defined(__linux__)
|
||||
#if !defined(__PS3__) && !defined(__ORBIS__) && !defined(__PSVITA__)
|
||||
std::error_code error;
|
||||
const fs::path path = ToFilesystemPath(getPath());
|
||||
|
||||
if( fs::is_regular_file(path, error) )
|
||||
{
|
||||
const fs::file_time_type lastWriteTime = fs::last_write_time(path, error);
|
||||
if( !error )
|
||||
{
|
||||
return ToEpochMilliseconds(lastWriteTime);
|
||||
}
|
||||
}
|
||||
|
||||
return 0l;
|
||||
#elif !defined(__linux__)
|
||||
WIN32_FILE_ATTRIBUTE_DATA fileInfoBuffer;
|
||||
#ifdef _UNICODE
|
||||
BOOL result = GetFileAttributesEx(
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "../Platform/stdafx.h"
|
||||
#include "../Util/PortableFileIO.h"
|
||||
#include "../Headers/net.minecraft.world.level.h"
|
||||
#include "../Headers/net.minecraft.world.level.biome.h"
|
||||
#include "../Headers/net.minecraft.world.level.levelgen.h"
|
||||
|
|
@ -19,86 +20,47 @@ CustomLevelSource::CustomLevelSource(Level *level, __int64 seed, bool generateSt
|
|||
|
||||
m_heightmapOverride = byteArray( (m_XZSize*16) * (m_XZSize*16) );
|
||||
|
||||
#ifdef _UNICODE
|
||||
std::wstring path = L"GAME:\\GameRules\\heightmap.bin";
|
||||
|
||||
#else
|
||||
#ifdef _WINDOWS64
|
||||
std::string path = "GameRules\\heightmap.bin";
|
||||
const std::wstring path = L"GameRules\\heightmap.bin";
|
||||
#else
|
||||
std::string path = "GAME:\\GameRules\\heightmap.bin";
|
||||
const std::wstring path = L"GAME:\\GameRules\\heightmap.bin";
|
||||
#endif
|
||||
#endif
|
||||
HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if( file == INVALID_HANDLE_VALUE )
|
||||
const PortableFileIO::BinaryReadResult heightmapReadResult = PortableFileIO::ReadBinaryFile(path, m_heightmapOverride.data, m_heightmapOverride.length);
|
||||
if(heightmapReadResult.status == PortableFileIO::BinaryReadStatus::not_found)
|
||||
{
|
||||
app.FatalLoadError();
|
||||
DWORD error = GetLastError();
|
||||
assert(false);
|
||||
}
|
||||
else
|
||||
else if(heightmapReadResult.status == PortableFileIO::BinaryReadStatus::too_large)
|
||||
{
|
||||
|
||||
#ifdef _DURANGO
|
||||
__debugbreak(); // TODO
|
||||
DWORD bytesRead,dwFileSize = 0;
|
||||
#else
|
||||
DWORD bytesRead,dwFileSize = GetFileSize(file,NULL);
|
||||
#endif
|
||||
if(dwFileSize > m_heightmapOverride.length)
|
||||
{
|
||||
app.DebugPrintf("Heightmap binary is too large!!\n");
|
||||
__debugbreak();
|
||||
}
|
||||
BOOL bSuccess = ReadFile(file,m_heightmapOverride.data,dwFileSize,&bytesRead,NULL);
|
||||
|
||||
if(bSuccess==FALSE)
|
||||
{
|
||||
app.FatalLoadError();
|
||||
}
|
||||
CloseHandle(file);
|
||||
app.DebugPrintf("Heightmap binary is too large!!\n");
|
||||
__debugbreak();
|
||||
}
|
||||
else if(heightmapReadResult.status != PortableFileIO::BinaryReadStatus::ok)
|
||||
{
|
||||
app.FatalLoadError();
|
||||
}
|
||||
|
||||
m_waterheightOverride = byteArray( (m_XZSize*16) * (m_XZSize*16) );
|
||||
|
||||
#ifdef _UNICODE
|
||||
std::wstring waterHeightPath = L"GAME:\\GameRules\\waterheight.bin";
|
||||
|
||||
#else
|
||||
#ifdef _WINDOWS64
|
||||
std::string waterHeightPath = "GameRules\\waterheight.bin";
|
||||
const std::wstring waterHeightPath = L"GameRules\\waterheight.bin";
|
||||
#else
|
||||
std::string waterHeightPath = "GAME:\\GameRules\\waterheight.bin";
|
||||
const std::wstring waterHeightPath = L"GAME:\\GameRules\\waterheight.bin";
|
||||
#endif
|
||||
#endif
|
||||
file = CreateFile(waterHeightPath.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if( file == INVALID_HANDLE_VALUE )
|
||||
const PortableFileIO::BinaryReadResult waterHeightReadResult = PortableFileIO::ReadBinaryFile(waterHeightPath, m_waterheightOverride.data, m_waterheightOverride.length);
|
||||
if(waterHeightReadResult.status == PortableFileIO::BinaryReadStatus::not_found)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
//assert(false);
|
||||
memset(m_waterheightOverride.data, level->seaLevel, m_waterheightOverride.length);
|
||||
}
|
||||
else
|
||||
else if(waterHeightReadResult.status == PortableFileIO::BinaryReadStatus::too_large)
|
||||
{
|
||||
|
||||
#ifdef _DURANGO
|
||||
__debugbreak(); // TODO
|
||||
DWORD bytesRead,dwFileSize = 0;
|
||||
#else
|
||||
DWORD bytesRead,dwFileSize = GetFileSize(file,NULL);
|
||||
#endif
|
||||
if(dwFileSize > m_waterheightOverride.length)
|
||||
{
|
||||
app.DebugPrintf("waterheight binary is too large!!\n");
|
||||
__debugbreak();
|
||||
}
|
||||
BOOL bSuccess = ReadFile(file,m_waterheightOverride.data,dwFileSize,&bytesRead,NULL);
|
||||
|
||||
if(bSuccess==FALSE)
|
||||
{
|
||||
app.FatalLoadError();
|
||||
}
|
||||
CloseHandle(file);
|
||||
app.DebugPrintf("waterheight binary is too large!!\n");
|
||||
__debugbreak();
|
||||
}
|
||||
else if(waterHeightReadResult.status != PortableFileIO::BinaryReadStatus::ok)
|
||||
{
|
||||
app.FatalLoadError();
|
||||
}
|
||||
|
||||
caveFeature = new LargeCaveFeature();
|
||||
|
|
|
|||
|
|
@ -3,33 +3,17 @@
|
|||
|
||||
PerformanceTimer::PerformanceTimer()
|
||||
{
|
||||
#if !defined (__linux__)
|
||||
// Get the frequency of the timer
|
||||
LARGE_INTEGER qwTicksPerSec;
|
||||
QueryPerformanceFrequency( &qwTicksPerSec );
|
||||
m_fSecsPerTick = 1.0f / (float)qwTicksPerSec.QuadPart;
|
||||
|
||||
Reset();
|
||||
#endif
|
||||
}
|
||||
|
||||
void PerformanceTimer::Reset()
|
||||
{
|
||||
#if !defined (__linux__)
|
||||
QueryPerformanceCounter( &m_qwStartTime );
|
||||
#endif
|
||||
m_startTime = std::chrono::steady_clock::now();
|
||||
}
|
||||
|
||||
void PerformanceTimer::PrintElapsedTime(const std::wstring &description)
|
||||
{
|
||||
#if !defined (__linux__)
|
||||
LARGE_INTEGER qwNewTime, qwDeltaTime;
|
||||
const std::chrono::duration<float> elapsedTime = std::chrono::steady_clock::now() - m_startTime;
|
||||
|
||||
QueryPerformanceCounter( &qwNewTime );
|
||||
|
||||
qwDeltaTime.QuadPart = qwNewTime.QuadPart - m_qwStartTime.QuadPart;
|
||||
float fElapsedTime = m_fSecsPerTick * ((FLOAT)(qwDeltaTime.QuadPart));
|
||||
|
||||
app.DebugPrintf("TIMER: %ls: Elapsed time %f\n", description.c_str(), fElapsedTime);
|
||||
#endif
|
||||
app.DebugPrintf("TIMER: %ls: Elapsed time %f\n", description.c_str(), elapsedTime.count());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,24 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __valid
|
||||
#pragma push_macro("__valid")
|
||||
#undef __valid
|
||||
#define PERFORMANCE_TIMER_RESTORE_VALID_MACRO
|
||||
#endif
|
||||
#include <chrono>
|
||||
#ifdef PERFORMANCE_TIMER_RESTORE_VALID_MACRO
|
||||
#pragma pop_macro("__valid")
|
||||
#undef PERFORMANCE_TIMER_RESTORE_VALID_MACRO
|
||||
#endif
|
||||
#include <string>
|
||||
|
||||
class PerformanceTimer
|
||||
{
|
||||
private:
|
||||
LARGE_INTEGER m_qwStartTime;
|
||||
float m_fSecsPerTick;
|
||||
std::chrono::steady_clock::time_point m_startTime;
|
||||
|
||||
public:
|
||||
PerformanceTimer();
|
||||
void Reset();
|
||||
void PrintElapsedTime(const std::wstring &description);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
90
Minecraft.World/Util/PortableFileIO.h
Normal file
90
Minecraft.World/Util/PortableFileIO.h
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include <fstream>
|
||||
#include <ios>
|
||||
#include <string>
|
||||
|
||||
#include "StringHelpers.h"
|
||||
|
||||
namespace PortableFileIO
|
||||
{
|
||||
enum class BinaryReadStatus
|
||||
{
|
||||
ok,
|
||||
not_found,
|
||||
too_large,
|
||||
read_error,
|
||||
};
|
||||
|
||||
struct BinaryReadResult
|
||||
{
|
||||
BinaryReadStatus status;
|
||||
std::size_t bytesRead;
|
||||
std::size_t fileSize;
|
||||
};
|
||||
|
||||
inline BinaryReadResult ReadBinaryFile(const std::wstring &path, void *buffer, std::size_t capacity)
|
||||
{
|
||||
const std::string nativePath = wstringtofilename(path);
|
||||
std::ifstream stream(nativePath.c_str(), std::ios::binary | std::ios::ate);
|
||||
if (!stream.is_open())
|
||||
{
|
||||
return { BinaryReadStatus::not_found, 0, 0 };
|
||||
}
|
||||
|
||||
const std::streamoff endPosition = stream.tellg();
|
||||
if (endPosition < 0)
|
||||
{
|
||||
return { BinaryReadStatus::read_error, 0, 0 };
|
||||
}
|
||||
|
||||
const std::size_t fileSize = static_cast<std::size_t>(endPosition);
|
||||
if (fileSize > capacity)
|
||||
{
|
||||
return { BinaryReadStatus::too_large, 0, fileSize };
|
||||
}
|
||||
|
||||
stream.seekg(0, std::ios::beg);
|
||||
stream.read(reinterpret_cast<char *>(buffer), static_cast<std::streamsize>(fileSize));
|
||||
const std::size_t bytesRead = static_cast<std::size_t>(stream.gcount());
|
||||
if ((!stream && !stream.eof()) || bytesRead != fileSize)
|
||||
{
|
||||
return { BinaryReadStatus::read_error, bytesRead, fileSize };
|
||||
}
|
||||
|
||||
return { BinaryReadStatus::ok, bytesRead, fileSize };
|
||||
}
|
||||
|
||||
inline BinaryReadResult ReadBinaryFileSegment(const std::wstring &path, std::size_t offset, void *buffer, std::size_t bytesToRead)
|
||||
{
|
||||
const std::string nativePath = wstringtofilename(path);
|
||||
std::ifstream stream(nativePath.c_str(), std::ios::binary | std::ios::ate);
|
||||
if (!stream.is_open())
|
||||
{
|
||||
return { BinaryReadStatus::not_found, 0, 0 };
|
||||
}
|
||||
|
||||
const std::streamoff endPosition = stream.tellg();
|
||||
if (endPosition < 0)
|
||||
{
|
||||
return { BinaryReadStatus::read_error, 0, 0 };
|
||||
}
|
||||
|
||||
const std::size_t fileSize = static_cast<std::size_t>(endPosition);
|
||||
if ((offset > fileSize) || (bytesToRead > (fileSize - offset)))
|
||||
{
|
||||
return { BinaryReadStatus::too_large, 0, fileSize };
|
||||
}
|
||||
|
||||
stream.seekg(static_cast<std::streamoff>(offset), std::ios::beg);
|
||||
stream.read(reinterpret_cast<char *>(buffer), static_cast<std::streamsize>(bytesToRead));
|
||||
const std::size_t bytesRead = static_cast<std::size_t>(stream.gcount());
|
||||
if ((!stream && !stream.eof()) || bytesRead != bytesToRead)
|
||||
{
|
||||
return { BinaryReadStatus::read_error, bytesRead, fileSize };
|
||||
}
|
||||
|
||||
return { BinaryReadStatus::ok, bytesRead, fileSize };
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include "../../Platform/stdafx.h"
|
||||
#include "../../Util/PortableFileIO.h"
|
||||
#include "../../Headers/net.minecraft.world.level.biome.h"
|
||||
#include "../../Headers/net.minecraft.world.level.newbiome.layer.h"
|
||||
#include "../../Headers/net.minecraft.world.level.h"
|
||||
|
|
@ -9,47 +10,25 @@ BiomeOverrideLayer::BiomeOverrideLayer(int seedMixup) : Layer(seedMixup)
|
|||
{
|
||||
m_biomeOverride = byteArray( width * height );
|
||||
|
||||
#ifdef _UNICODE
|
||||
std::wstring path = L"GAME:\\GameRules\\biomemap.bin";
|
||||
HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#else
|
||||
#ifdef _WINDOWS64
|
||||
std::string path = "GameRules\\biomemap.bin";
|
||||
const std::wstring path = L"GameRules\\biomemap.bin";
|
||||
#else
|
||||
std::string path = "GAME:\\GameRules\\biomemap.bin";
|
||||
const std::wstring path = L"GAME:\\GameRules\\biomemap.bin";
|
||||
#endif
|
||||
HANDLE file = CreateFile(path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
#endif
|
||||
if( file == INVALID_HANDLE_VALUE )
|
||||
const PortableFileIO::BinaryReadResult readResult = PortableFileIO::ReadBinaryFile(path, m_biomeOverride.data, m_biomeOverride.length);
|
||||
if(readResult.status == PortableFileIO::BinaryReadStatus::not_found)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
//assert(false);
|
||||
app.DebugPrintf("Biome override not found, using plains as default\n");
|
||||
|
||||
memset(m_biomeOverride.data,Biome::plains->id,m_biomeOverride.length);
|
||||
}
|
||||
else
|
||||
else if(readResult.status == PortableFileIO::BinaryReadStatus::too_large)
|
||||
{
|
||||
|
||||
#ifdef _DURANGO
|
||||
__debugbreak(); // TODO
|
||||
DWORD bytesRead,dwFileSize = 0;
|
||||
#else
|
||||
DWORD bytesRead,dwFileSize = GetFileSize(file,NULL);
|
||||
#endif
|
||||
if(dwFileSize > m_biomeOverride.length)
|
||||
{
|
||||
app.DebugPrintf("Biomemap binary is too large!!\n");
|
||||
__debugbreak();
|
||||
}
|
||||
BOOL bSuccess = ReadFile(file,m_biomeOverride.data,dwFileSize,&bytesRead,NULL);
|
||||
|
||||
if(bSuccess==FALSE)
|
||||
{
|
||||
app.FatalLoadError();
|
||||
}
|
||||
|
||||
CloseHandle(file);
|
||||
app.DebugPrintf("Biomemap binary is too large!!\n");
|
||||
__debugbreak();
|
||||
}
|
||||
else if(readResult.status != PortableFileIO::BinaryReadStatus::ok)
|
||||
{
|
||||
app.FatalLoadError();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,4 +57,4 @@ intArray BiomeOverrideLayer::getArea(int xo, int yo, int w, int h)
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue