refactor: replace POSIX/Win32 APIs with standard C++ equivalents

Replaces platform-specific APIs across 21 files with std::chrono, std::fstream, std::filesystem, and std::this_thread. Adds PlatformTime.h utility header wrapping std::chrono::steady_clock for GetTickCount/QueryPerformanceCounter patterns.
This commit is contained in:
MatthewBeshay 2026-04-01 05:01:37 +11:00
parent 2f92b07c1f
commit ee31bfcec5
21 changed files with 196 additions and 306 deletions

View file

@ -31,6 +31,7 @@
#include "../Windows64/XML/ATGXmlParser.h"
#include "../Windows64/XML/xmlFilesCallback.h"
#endif
#include "Minecraft.World/ConsoleHelpers/PlatformTime.h"
#include "Minecraft_Macros.h"
#include "../net/minecraft/server/PlayerList.h"
#include "../net/minecraft/server/level/ServerPlayer.h"
@ -4341,15 +4342,14 @@ void CMinecraftApp::HandleDLC(DLCPack* pack) {
//-------------------------------------------------------------------------------------
void CMinecraftApp::InitTime() {
// Get the frequency of the timer
LARGE_INTEGER qwTicksPerSec;
QueryPerformanceFrequency(&qwTicksPerSec);
m_Time.fSecsPerTick = 1.0f / (float)qwTicksPerSec.QuadPart;
auto freq = PlatformTime::QueryPerformanceFrequency();
m_Time.fSecsPerTick = 1.0f / static_cast<float>(freq);
// Save the start time
QueryPerformanceCounter(&m_Time.qwTime);
m_Time.qwTime = PlatformTime::QueryPerformanceCounter();
// Zero out the elapsed and total time
m_Time.qwAppTime.QuadPart = 0;
m_Time.qwAppTime = 0;
m_Time.fAppTime = 0.0f;
m_Time.fElapsedTime = 0.0f;
}
@ -4359,19 +4359,16 @@ void CMinecraftApp::InitTime() {
// Desc: Updates the elapsed time since our last frame.
//-------------------------------------------------------------------------------------
void CMinecraftApp::UpdateTime() {
LARGE_INTEGER qwNewTime;
LARGE_INTEGER qwDeltaTime;
auto qwNewTime = PlatformTime::QueryPerformanceCounter();
auto qwDeltaTime = qwNewTime - m_Time.qwTime;
QueryPerformanceCounter(&qwNewTime);
qwDeltaTime.QuadPart = qwNewTime.QuadPart - m_Time.qwTime.QuadPart;
m_Time.qwAppTime.QuadPart += qwDeltaTime.QuadPart;
m_Time.qwTime.QuadPart = qwNewTime.QuadPart;
m_Time.qwAppTime += qwDeltaTime;
m_Time.qwTime = qwNewTime;
m_Time.fElapsedTime =
m_Time.fSecsPerTick * static_cast<float>(qwDeltaTime.QuadPart);
m_Time.fSecsPerTick * static_cast<float>(qwDeltaTime);
m_Time.fAppTime =
m_Time.fSecsPerTick * static_cast<float>(m_Time.qwAppTime.QuadPart);
m_Time.fSecsPerTick * static_cast<float>(m_Time.qwAppTime);
}
bool CMinecraftApp::isXuidNotch(PlayerUID xuid) {
@ -7143,17 +7140,17 @@ int CMinecraftApp::GetDLCInfoTexturesOffersCount() {
// AUTOSAVE
void CMinecraftApp::SetAutosaveTimerTime(void) {
m_uiAutosaveTimer =
GetTickCount() +
PlatformTime::GetTickCount() +
GetGameSettings(ProfileManager.GetPrimaryPad(), eGameSetting_Autosave) *
1000 * 60 * 15;
} // value x 15 to get mins, x60 for secs
bool CMinecraftApp::AutosaveDue(void) {
return (GetTickCount() > m_uiAutosaveTimer);
return (PlatformTime::GetTickCount() > m_uiAutosaveTimer);
}
unsigned int CMinecraftApp::SecondsToAutosave() {
return (m_uiAutosaveTimer - GetTickCount()) / 1000;
return (m_uiAutosaveTimer - PlatformTime::GetTickCount()) / 1000;
}
void CMinecraftApp::SetTrialTimerStart(void) {

View file

@ -610,8 +610,8 @@ private:
// Trial timer
float m_fTrialTimerStart, mfTrialPausedTime;
typedef struct TimeInfo {
LARGE_INTEGER qwTime;
LARGE_INTEGER qwAppTime;
std::int64_t qwTime;
std::int64_t qwAppTime;
float fAppTime;
float fElapsedTime;

View file

@ -1,5 +1,6 @@
#include "Minecraft.World/Header Files/stdafx.h"
#include "SoundEngine.h"
#include <filesystem>
#include "Minecraft.World/ConsoleHelpers/PathHelper.h"
#include "../../Consoles_App.h"
#include "../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
@ -172,7 +173,7 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume,
for (int i = 1; i <= 16; i++) {
char tryP[512];
snprintf(tryP, 512, "%s%s%d%s", fullRoot.c_str(), szId, i, ext);
if (access(tryP, F_OK) != -1)
if (std::filesystem::exists(tryP))
count = i;
else
break;
@ -185,7 +186,7 @@ void SoundEngine::play(int iSound, float x, float y, float z, float volume,
}
char tryP[512];
snprintf(tryP, 512, "%s%s%s", fullRoot.c_str(), szId, ext);
if (access(tryP, F_OK) != -1) {
if (std::filesystem::exists(tryP)) {
strncpy(finalPath, tryP, 511);
found = true;
break;
@ -240,7 +241,7 @@ void SoundEngine::playUI(int iSound, float volume, float pitch) {
char tryP[512];
snprintf(tryP, 512, "%s%s%s%s", base.c_str(), root, szIdentifier,
ext);
if (access(tryP, F_OK) != -1) {
if (std::filesystem::exists(tryP)) {
strncpy(finalPath, tryP, 511);
found = true;
break;
@ -441,14 +442,14 @@ void SoundEngine::playMusicTick() {
// try with folder prefix (music/ or cds/)
snprintf(c, 512, "%s%s%s%s%s", base.c_str(), r, folder,
track, e);
if (access(c, F_OK) != -1) {
if (std::filesystem::exists(c)) {
strncpy(m_szStreamName, c, 511);
found = true;
break;
}
// try without folder prefix
snprintf(c, 512, "%s%s%s%s", base.c_str(), r, track, e);
if (access(c, F_OK) != -1) {
if (std::filesystem::exists(c)) {
strncpy(m_szStreamName, c, 511);
found = true;
break;

View file

@ -1,5 +1,7 @@
#include "Minecraft.World/Header Files/stdafx.h"
#include <fstream>
#include <filesystem>
#include <unordered_set>
#include "Minecraft.World/ConsoleHelpers/StringHelpers.h"
@ -504,47 +506,16 @@ int LevelGenerationOptions::packMounted(void* pParam, int iPad, uint32_t dwErr,
dlcFile->getGrfPath(), true,
L"WPACK:"));
if (grf.exists()) {
#if defined(_UNICODE)
std::wstring path = grf.getPath();
const wchar_t* pchFilename = path.c_str();
void* fileHandle = CreateFile(
pchFilename, // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share
// file? Probably not but...
nullptr, // Unused
OPEN_EXISTING, // how to create // TODO 4J Stu -
// Assuming that the file already exists
// if we are opening to read from it
FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
nullptr // Unsupported
);
#else
const char* pchFilename = wstringtofilename(grf.getPath());
void* fileHandle = CreateFile(
pchFilename, // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share
// file? Probably not but...
nullptr, // Unused
OPEN_EXISTING, // how to create // TODO 4J Stu -
// Assuming that the file already exists
// if we are opening to read from it
FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
nullptr // Unsupported
);
#endif
std::filesystem::path grfPath = grf.getPath();
std::ifstream fileHandle(grfPath, std::ios::binary);
if (fileHandle != INVALID_HANDLE_VALUE) {
if (fileHandle) {
uint32_t dwFileSize = grf.length();
uint32_t bytesRead;
uint8_t* pbData = (uint8_t*)new uint8_t[dwFileSize];
bool bSuccess = ReadFile(fileHandle, pbData, dwFileSize,
&bytesRead, nullptr);
if (bSuccess == false) {
fileHandle.read(reinterpret_cast<char*>(pbData), static_cast<std::streamsize>(dwFileSize));
if (!fileHandle) {
app.FatalLoadError();
}
CloseHandle(fileHandle);
// 4J-PB - is it possible that we can get here after a
// read fail and it's not an error?
@ -562,47 +533,16 @@ int LevelGenerationOptions::packMounted(void* pParam, int iPad, uint32_t dwErr,
File save(app.getFilePath(lgo->m_parentDLCPack->GetPackID(),
lgo->getBaseSavePath(), true, L"WPACK:"));
if (save.exists()) {
#if defined(_UNICODE)
std::wstring path = save.getPath();
const wchar_t* pchFilename = path.c_str();
void* fileHandle = CreateFile(
pchFilename, // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share
// file? Probably not but...
nullptr, // Unused
OPEN_EXISTING, // how to create // TODO 4J Stu - Assuming
// that the file already exists if we are
// opening to read from it
FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
nullptr // Unsupported
);
#else
const char* pchFilename = wstringtofilename(save.getPath());
void* fileHandle = CreateFile(
pchFilename, // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need to share
// file? Probably not but...
nullptr, // Unused
OPEN_EXISTING, // how to create // TODO 4J Stu - Assuming
// that the file already exists if we are
// opening to read from it
FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
nullptr // Unsupported
);
#endif
std::filesystem::path savePath = save.getPath();
std::ifstream saveHandle(savePath, std::ios::binary);
if (fileHandle != INVALID_HANDLE_VALUE) {
uint32_t bytesRead,
dwFileSize = GetFileSize(fileHandle, nullptr);
if (saveHandle) {
auto dwFileSize = std::filesystem::file_size(savePath);
uint8_t* pbData = (uint8_t*)new uint8_t[dwFileSize];
bool bSuccess = ReadFile(fileHandle, pbData, dwFileSize,
&bytesRead, nullptr);
if (bSuccess == false) {
saveHandle.read(reinterpret_cast<char*>(pbData), static_cast<std::streamsize>(dwFileSize));
if (!saveHandle) {
app.FatalLoadError();
}
CloseHandle(fileHandle);
// 4J-PB - is it possible that we can get here after a read
// fail and it's not an error?

View file

@ -1,5 +1,7 @@
#include <thread>
#include <chrono>
#include <fstream>
#include <filesystem>
#include "Minecraft.World/Header Files/stdafx.h"
#include "Minecraft.World/ConsoleHelpers/StringHelpers.h"
@ -136,52 +138,18 @@ bool CGameNetworkManager::StartNetworkGame(Minecraft* minecraft,
#endif
File grf(fileRoot);
if (grf.exists()) {
#if defined(_UNICODE)
std::wstring path = grf.getPath();
const wchar_t* pchFilename = path.c_str();
void* fileHandle = CreateFile(
pchFilename, // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need
// to share file? Probably not but...
nullptr, // Unused
OPEN_EXISTING, // how to create // TODO 4J Stu
// - Assuming that the file
// already exists if we are
// opening to read from it
FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
nullptr // Unsupported
);
#else
const char* pchFilename =
wstringtofilename(grf.getPath());
void* fileHandle = CreateFile(
pchFilename, // file name
GENERIC_READ, // access mode
0, // share mode // TODO 4J Stu - Will we need
// to share file? Probably not but...
nullptr, // Unused
OPEN_EXISTING, // how to create // TODO 4J Stu
// - Assuming that the file
// already exists if we are
// opening to read from it
FILE_FLAG_SEQUENTIAL_SCAN, // file attributes
nullptr // Unsupported
);
#endif
std::filesystem::path grfPath = grf.getPath();
std::ifstream fileHandle(grfPath, std::ios::binary);
if (fileHandle != INVALID_HANDLE_VALUE) {
uint32_t bytesRead, dwFileSize = GetFileSize(
fileHandle, nullptr);
if (fileHandle) {
auto dwFileSize = std::filesystem::file_size(grfPath);
uint8_t* pbData =
(uint8_t*)new uint8_t[dwFileSize];
bool bSuccess =
ReadFile(fileHandle, pbData, dwFileSize,
&bytesRead, nullptr);
if (bSuccess == false) {
fileHandle.read(reinterpret_cast<char*>(pbData),
static_cast<std::streamsize>(dwFileSize));
if (!fileHandle) {
app.FatalLoadError();
}
CloseHandle(fileHandle);
// 4J-PB - is it possible that we can get here
// after a read fail and it's not an error?

View file

@ -1,4 +1,5 @@
#include "Minecraft.World/Header Files/stdafx.h"
#include "Minecraft.World/ConsoleHelpers/PlatformTime.h"
#include "Minecraft.World/net/minecraft/stats/net.minecraft.stats.h"
#include "../../../net/minecraft/client/player/LocalPlayer.h"
#include "Minecraft.World/net/minecraft/world/entity/Entity.h"
@ -2047,7 +2048,7 @@ void Tutorial::tick() {
// Don't do anything for the first 2 seconds so that the loading screen is
// gone
if (!m_bHasTickedOnce) {
int time = GetTickCount();
int time = PlatformTime::GetTickCount();
if (m_firstTickTime == 0) {
m_firstTickTime = time;
} else if (time - m_firstTickTime > 1500) {
@ -2101,7 +2102,7 @@ void Tutorial::tick() {
if (currentTask[m_CurrentState] != nullptr &&
(!currentTask[m_CurrentState]->AllowFade() ||
(lastMessageTime + m_iTutorialDisplayMessageTime) >
GetTickCount())) {
PlatformTime::GetTickCount())) {
uiTempDisabled = true;
}
ui.SetTutorialVisible(m_iPad, false);
@ -2122,7 +2123,7 @@ void Tutorial::tick() {
if (currentTask[m_CurrentState] != nullptr &&
(!currentTask[m_CurrentState]->AllowFade() ||
(lastMessageTime + m_iTutorialDisplayMessageTime) >
GetTickCount())) {
PlatformTime::GetTickCount())) {
uiTempDisabled = true;
}
ui.SetTutorialVisible(m_iPad, false);
@ -2130,7 +2131,7 @@ void Tutorial::tick() {
}
if (uiTempDisabled) {
ui.SetTutorialVisible(m_iPad, true);
lastMessageTime = GetTickCount();
lastMessageTime = PlatformTime::GetTickCount();
uiTempDisabled = false;
}
@ -2202,7 +2203,7 @@ void Tutorial::tick() {
if ((!task->ShowMinimumTime() ||
(task->hasBeenActivated() &&
(lastMessageTime + m_iTutorialMinimumDisplayMessageTime) <
GetTickCount())) &&
PlatformTime::GetTickCount())) &&
task->isCompleted()) {
eTutorial_CompletionAction compAction =
task->getCompletionAction();
@ -2293,7 +2294,7 @@ void Tutorial::tick() {
if (task != nullptr && task->ShowMinimumTime() &&
task->hasBeenActivated() &&
(lastMessageTime + m_iTutorialMinimumDisplayMessageTime) <
GetTickCount()) {
PlatformTime::GetTickCount()) {
task->setShownForMinimumTime();
if (!m_hintDisplayed) {
@ -2362,14 +2363,14 @@ void Tutorial::tick() {
}
if (m_hintDisplayed &&
(lastMessageTime + m_iTutorialDisplayMessageTime) < GetTickCount()) {
(lastMessageTime + m_iTutorialDisplayMessageTime) < PlatformTime::GetTickCount()) {
m_hintDisplayed = false;
}
if (currentFailedConstraint[m_CurrentState] == nullptr &&
currentTask[m_CurrentState] != nullptr && (m_iTaskReminders != 0) &&
(lastMessageTime + (m_iTaskReminders * m_iTutorialReminderTime)) <
GetTickCount()) {
PlatformTime::GetTickCount()) {
// Reminder
PopupMessageDetails* message = new PopupMessageDetails();
message->m_messageId = currentTask[m_CurrentState]->getDescriptionId();
@ -2397,7 +2398,7 @@ bool Tutorial::setMessage(PopupMessageDetails* message) {
m_lastMessageState == m_CurrentState &&
message->isSameContent(m_lastMessage) &&
(!message->m_isReminder ||
((lastMessageTime + m_iTutorialReminderTime) > GetTickCount() &&
((lastMessageTime + m_iTutorialReminderTime) > PlatformTime::GetTickCount() &&
message->m_isReminder))) {
delete message;
return false;
@ -2407,7 +2408,7 @@ bool Tutorial::setMessage(PopupMessageDetails* message) {
(message->m_messageId > 0 || !message->m_messageString.empty())) {
m_lastMessageState = m_CurrentState;
if (!message->m_replaceCurrent) lastMessageTime = GetTickCount();
if (!message->m_replaceCurrent) lastMessageTime = PlatformTime::GetTickCount();
std::wstring text;
if (!message->m_messageString.empty()) {
@ -2467,7 +2468,7 @@ bool Tutorial::setMessage(PopupMessageDetails* message) {
} else if ((m_lastMessage != nullptr &&
m_lastMessage->m_messageId !=
-1)) //&& (lastMessageTime + m_iTutorialReminderTime ) >
// GetTickCount() )
// PlatformTime::GetTickCount() )
{
// This should cause the popup to dissappear
TutorialPopupInfo popupInfo;
@ -2490,7 +2491,7 @@ bool Tutorial::setMessage(TutorialHint* hint, PopupMessageDetails* message) {
app.GetGameSettings(m_iPad, eGameSetting_DisplayHUD));
bool messageShown = false;
std::uint32_t time = GetTickCount();
std::uint32_t time = PlatformTime::GetTickCount();
if (message != nullptr && (message->m_forceDisplay || hintsOn) &&
(!message->m_delay ||
((m_hintDisplayed &&
@ -2526,7 +2527,7 @@ void Tutorial::showTutorialPopup(bool show) {
if (currentTask[m_CurrentState] != nullptr &&
(!currentTask[m_CurrentState]->AllowFade() ||
(lastMessageTime + m_iTutorialDisplayMessageTime) >
GetTickCount())) {
PlatformTime::GetTickCount())) {
uiTempDisabled = true;
}
ui.SetTutorialVisible(m_iPad, show);

View file

@ -1,4 +1,5 @@
#include "Minecraft.World/Header Files/stdafx.h"
#include "Minecraft.World/ConsoleHelpers/PlatformTime.h"
#include <memory>
#include "../../../net/minecraft/client/Minecraft.h"
#include "../../../net/minecraft/client/multiplayer/MultiPlayerLocalPlayer.h"
@ -59,7 +60,7 @@ void TutorialMode::tick() {
/*
if( tutorial.m_allTutorialsComplete && (tutorial.lastMessageTime +
m_iTutorialDisplayMessageTime) < GetTickCount() )
m_iTutorialDisplayMessageTime) < PlatformTime::GetTickCount() )
{
// Exit tutorial
minecraft->gameMode = new SurvivalMode( this );

View file

@ -1,4 +1,5 @@
#include "Minecraft.World/Header Files/stdafx.h"
#include "Minecraft.World/ConsoleHelpers/PlatformTime.h"
#include "UIController.h"
#include "UI.h"
#include "UIScene.h"
@ -735,13 +736,13 @@ void UIController::handleKeyPress(unsigned int iPad, unsigned int key) {
if (pressed) {
// Start repeat timer
m_actionRepeatTimer[iPad][key] =
GetTickCount() + UI_REPEAT_KEY_DELAY_MS;
PlatformTime::GetTickCount() + UI_REPEAT_KEY_DELAY_MS;
} else if (released) {
// Stop repeat timer
m_actionRepeatTimer[iPad][key] = 0;
} else if (down) {
// Check is enough time has elapsed to be a repeat key
std::uint32_t currentTime = GetTickCount();
std::uint32_t currentTime = PlatformTime::GetTickCount();
if (m_actionRepeatTimer[iPad][key] > 0 &&
currentTime > m_actionRepeatTimer[iPad][key]) {
repeat = true;
@ -1372,7 +1373,7 @@ UIScene* UIController::GetTopScene(int iPad, EUILayer layer, EUIGroup group) {
size_t UIController::RegisterForCallbackId(UIScene* scene) {
std::lock_guard<std::mutex> lock(m_registeredCallbackScenesCS);
size_t newId = GetTickCount();
size_t newId = PlatformTime::GetTickCount();
newId &= 0xFFFFFF; // Chop off the top byte, we don't need any more
// accuracy than that
newId |= (scene->getSceneType()

View file

@ -4,9 +4,7 @@
#include "Minecraft.World/ConsoleHelpers/PathHelper.h"
#include "Minecraft.World/ConsoleHelpers/ArrayWithLength.h"
#include "../Header Files/BufferedImage.h"
#if defined(__linux__)
#include <unistd.h>
#endif
#include <filesystem>
#include <vector>
#include <string>
@ -76,7 +74,7 @@ BufferedImage::BufferedImage(const std::wstring& File,
size_t p;
while ((p = attempt.find(L"//")) != std::wstring::npos)
attempt.replace(p, 2, L"/");
if (access(wstringtofilename(attempt), F_OK) != -1) {
if (std::filesystem::exists(wstringtofilename(attempt))) {
finalPath = attempt;
foundOnDisk = true;
break;

View file

@ -1,5 +1,6 @@
#include <thread>
#include <chrono>
#include <ctime>
#include "Minecraft.World/Header Files/stdafx.h"
#include "Minecraft.h"
@ -1069,14 +1070,19 @@ void Minecraft::run_middle() {
#if !defined(_CONTENT_PACKAGE)
{
// print the time
SYSTEMTIME UTCSysTime;
GetSystemTime(&UTCSysTime);
// char szTime[15];
auto now_tp = std::chrono::system_clock::now();
std::time_t now_tt = std::chrono::system_clock::to_time_t(now_tp);
std::tm utcTime{};
#if defined(_WIN32)
gmtime_s(&utcTime, &now_tt);
#else
gmtime_r(&now_tt, &utcTime);
#endif
app.DebugPrintf("%02d:%02d:%02d\n",
UTCSysTime.wHour,
UTCSysTime.wMinute,
UTCSysTime.wSecond);
utcTime.tm_hour,
utcTime.tm_min,
utcTime.tm_sec);
}
#endif
} else {

View file

@ -1,4 +1,5 @@
#include "Minecraft.World/Header Files/stdafx.h"
#include "Minecraft.World/ConsoleHelpers/PlatformTime.h"
#include "ClientConnection.h"
#include <cfloat>
#include <limits>
@ -3454,7 +3455,7 @@ void ClientConnection::checkDeferredEntityLinkPackets(int newEntityId) {
bool remove = false;
// Only consider recently deferred packets
int tickInterval = GetTickCount() - deferred->m_recievedTick;
int tickInterval = PlatformTime::GetTickCount() - deferred->m_recievedTick;
if (tickInterval < MAX_ENTITY_LINK_DEFERRAL_INTERVAL) {
// Note: we assume it's the destination entity
if (deferred->m_packet->destId == newEntityId) {
@ -3477,6 +3478,6 @@ void ClientConnection::checkDeferredEntityLinkPackets(int newEntityId) {
ClientConnection::DeferredEntityLinkPacket::DeferredEntityLinkPacket(
std::shared_ptr<SetEntityLinkPacket> packet) {
m_recievedTick = GetTickCount();
m_recievedTick = PlatformTime::GetTickCount();
m_packet = packet;
}

View file

@ -29,6 +29,7 @@
#include "Minecraft.World/net/minecraft/Pos.h"
#include "java/System.h"
#include "Minecraft.World/ConsoleHelpers/StringHelpers.h"
#include "Minecraft.World/ConsoleHelpers/PlatformTime.h"
#if defined(SPLIT_SAVES)
#include "Minecraft.World/ConsoleHelpers/ConsoleSaveFileIO/ConsoleSaveFileSplit.h"
#endif
@ -829,12 +830,9 @@ void MinecraftServer::Suspend() {
PIXBeginNamedEvent(0, "Suspending server");
m_suspending = true;
// Get the frequency of the timer
LARGE_INTEGER qwTicksPerSec, qwTime, qwNewTime, qwDeltaTime;
float fElapsedTime = 0.0f;
QueryPerformanceFrequency(&qwTicksPerSec);
float fSecsPerTick = 1.0f / (float)qwTicksPerSec.QuadPart;
// Save the start time
QueryPerformanceCounter(&qwTime);
auto qwTime = PlatformTime::QueryPerformanceCounter();
if (m_bLoaded &&
(!StorageManager.GetSaveDisabled())) {
if (players != nullptr) {
@ -854,10 +852,9 @@ void MinecraftServer::Suspend() {
levels[0]->saveToDisc(nullptr, true);
}
}
QueryPerformanceCounter(&qwNewTime);
auto qwNewTime = PlatformTime::QueryPerformanceCounter();
qwDeltaTime.QuadPart = qwNewTime.QuadPart - qwTime.QuadPart;
fElapsedTime = fSecsPerTick * static_cast<float>(qwDeltaTime.QuadPart);
fElapsedTime = static_cast<float>(PlatformTime::ElapsedSeconds(qwTime, qwNewTime));
m_suspending = false;
app.DebugPrintf("Suspend server: Elapsed time %f\n", fElapsedTime);
@ -1630,7 +1627,7 @@ void MinecraftServer::chunkPacketManagement_PostTick() {}
bool MinecraftServer::chunkPacketManagement_CanSendTo(INetworkPlayer* player) {
if (player == nullptr) return false;
int time = GetTickCount();
int time = PlatformTime::GetTickCount();
if (player->GetSessionIndex() == s_slowQueuePlayerIndex &&
(time - s_slowQueueLastTime) > MINECRAFT_SERVER_SLOW_QUEUE_DELAY) {
// app.DebugPrintf("Slow queue OK for player #%d\n",
@ -1650,7 +1647,7 @@ void MinecraftServer::chunkPacketManagement_PreTick() {}
void MinecraftServer::chunkPacketManagement_PostTick() {
// 4J Ensure that the slow queue owner keeps cycling if it's not been used
// in a while
int time = GetTickCount();
int time = PlatformTime::GetTickCount();
if ((s_slowQueuePacketSent) || ((time - s_slowQueueLastTime) >
(2 * MINECRAFT_SERVER_SLOW_QUEUE_DELAY))) {
// app.DebugPrintf("Considering cycling: (%d) %d - %d -> %d

View file

@ -28,6 +28,8 @@
#include "Minecraft.Client/Linux/Linux_App.h"
#include "Minecraft.Client/Linux/Stubs/winapi_stubs.h"
#include "compression.h"
#include "Minecraft.World/ConsoleHelpers/PlatformTime.h"
#include <ctime>
#include "java/InputOutputStream/DataInputStream.h"
#include "java/InputOutputStream/DataOutputStream.h"
#include "java/System.h"
@ -1281,10 +1283,9 @@ void ConsoleSaveFileSplit::Flush(bool autosave, bool updateThumbnail) {
if (!m_autosave) processSubfilesForWrite();
// Get the frequency of the timer
LARGE_INTEGER qwTicksPerSec, qwTime, qwNewTime, qwDeltaTime;
auto qwTime = PlatformTime::QueryPerformanceCounter();
auto qwNewTime = qwTime;
float fElapsedTime = 0.0f;
QueryPerformanceFrequency(&qwTicksPerSec);
float fSecsPerTick = 1.0f / (float)qwTicksPerSec.QuadPart;
unsigned int fileSize = header.GetFileSize();
@ -1312,13 +1313,12 @@ void ConsoleSaveFileSplit::Flush(bool autosave, bool updateThumbnail) {
// Pre-calculate the buffer size required for the compressed data
PIXBeginNamedEvent(0, "Pre-calc save compression");
// Save the start time
QueryPerformanceCounter(&qwTime);
qwTime = PlatformTime::QueryPerformanceCounter();
Compression::getCompression()->Compress(nullptr, &compLength, pvSaveMem,
fileSize);
QueryPerformanceCounter(&qwNewTime);
qwNewTime = PlatformTime::QueryPerformanceCounter();
qwDeltaTime.QuadPart = qwNewTime.QuadPart - qwTime.QuadPart;
fElapsedTime = fSecsPerTick * static_cast<float>(qwDeltaTime.QuadPart);
fElapsedTime = static_cast<float>(PlatformTime::ElapsedSeconds(qwTime, qwNewTime));
app.DebugPrintf("Check buffer size: Elapsed time %f\n", fElapsedTime);
PIXEndNamedEvent();
@ -1335,13 +1335,12 @@ void ConsoleSaveFileSplit::Flush(bool autosave, bool updateThumbnail) {
// Re-compress all save data before we save it to disk
PIXBeginNamedEvent(0, "Actual save compression");
// Save the start time
QueryPerformanceCounter(&qwTime);
qwTime = PlatformTime::QueryPerformanceCounter();
Compression::getCompression()->Compress(compData + 8, &compLength,
pvSaveMem, fileSize);
QueryPerformanceCounter(&qwNewTime);
qwNewTime = PlatformTime::QueryPerformanceCounter();
qwDeltaTime.QuadPart = qwNewTime.QuadPart - qwTime.QuadPart;
fElapsedTime = fSecsPerTick * static_cast<float>(qwDeltaTime.QuadPart);
fElapsedTime = static_cast<float>(PlatformTime::ElapsedSeconds(qwTime, qwNewTime));
app.DebugPrintf("Compress: Elapsed time %f\n", fElapsedTime);
PIXEndNamedEvent();
@ -1445,8 +1444,14 @@ void ConsoleSaveFileSplit::DebugFlushToFile(
wchar_t* fileName = new wchar_t[XCONTENT_MAX_FILENAME_LENGTH + 1];
SYSTEMTIME t;
GetSystemTime(&t);
auto now_tp = std::chrono::system_clock::now();
std::time_t now_tt = std::chrono::system_clock::to_time_t(now_tp);
std::tm t{};
#if defined(_WIN32)
gmtime_s(&t, &now_tt);
#else
gmtime_r(&now_tt, &t);
#endif
// 14 chars for the digits
// 11 chars for the separators + suffix
@ -1457,8 +1462,8 @@ void ConsoleSaveFileSplit::DebugFlushToFile(
}
swprintf(fileName, XCONTENT_MAX_FILENAME_LENGTH + 1,
L"\\v%04d-%ls%02d.%02d.%02d.%02d.%02d.mcs", VER_PRODUCTBUILD,
cutFileName.c_str(), t.wMonth, t.wDay, t.wHour, t.wMinute,
t.wSecond);
cutFileName.c_str(), t.tm_mon + 1, t.tm_mday, t.tm_hour, t.tm_min,
t.tm_sec);
const std::wstring outputPath =
targetFileDir.getPath() + std::wstring(fileName);

View file

@ -0,0 +1,38 @@
#pragma once
#include <chrono>
#include <cstdint>
// Portable replacements for Win32 time APIs.
// GetTickCount() → PlatformTime::GetTickCount()
// QueryPerformanceCounter() → PlatformTime::QueryPerformanceCounter()
// QueryPerformanceFrequency() → PlatformTime::QueryPerformanceFrequency()
namespace PlatformTime {
// Returns milliseconds since an unspecified epoch (like Win32 GetTickCount).
inline std::uint32_t GetTickCount() {
auto now = std::chrono::steady_clock::now().time_since_epoch();
return static_cast<std::uint32_t>(
std::chrono::duration_cast<std::chrono::milliseconds>(now).count());
}
// High-resolution counter value (like Win32 QueryPerformanceCounter).
// Returns a count in ticks of steady_clock.
inline std::int64_t QueryPerformanceCounter() {
return std::chrono::steady_clock::now().time_since_epoch().count();
}
// Ticks per second for the high-resolution counter.
inline std::int64_t QueryPerformanceFrequency() {
return static_cast<std::int64_t>(std::chrono::steady_clock::period::den)
/ static_cast<std::int64_t>(std::chrono::steady_clock::period::num);
}
// Elapsed seconds between two counter values.
inline double ElapsedSeconds(std::int64_t start, std::int64_t end) {
return static_cast<double>(end - start)
/ static_cast<double>(QueryPerformanceFrequency());
}
} // namespace PlatformTime

View file

@ -640,7 +640,7 @@ int Connection::runClose(void* lpParam) {
// try {
sleep(2000);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
if (con->running) {
// 4J TODO writeThread.interrupt();
con->close(DisconnectPacket::eDisconnect_Closed);
@ -662,7 +662,7 @@ int Connection::runSendAndQuit(void* lpParam) {
// try {
sleep(2000);
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
if (con->running) {
// 4J TODO writeThread.interrupt();
con->close(DisconnectPacket::eDisconnect_Closed);

View file

@ -1,10 +1,14 @@
#include <assert.h>
#include <string.h>
#include <fstream>
#include <filesystem>
#include "CustomLevelSource.h"
#include "Minecraft.Client/Common/Source Files/GameRules/LevelGeneration/LevelGenerationOptions.h"
#include "Minecraft.Client/Linux/Linux_App.h"
#if defined(__linux__)
#include "Minecraft.Client/Linux/Stubs/winapi_stubs.h"
#endif
#include "java/Random.h"
#include "Minecraft.World/net/minecraft/world/entity/MobCategory.h"
#include "Minecraft.World/net/minecraft/world/level/Level.h"
@ -36,69 +40,43 @@ CustomLevelSource::CustomLevelSource(Level* level, int64_t seed,
m_heightmapOverride = std::vector<uint8_t>((m_XZSize * 16) * (m_XZSize * 16));
#if defined(_UNICODE)
std::wstring path = L"GAME:\\GameRules\\heightmap.bin";
#else
#if defined(_WINDOWS64)
std::string path = "GameRules\\heightmap.bin";
#else
std::string path = "GAME:\\GameRules\\heightmap.bin";
#endif
#endif
void* file = CreateFile(path.c_str(), GENERIC_READ, 0, nullptr,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (file == INVALID_HANDLE_VALUE) {
std::filesystem::path path = "GameRules/heightmap.bin";
std::ifstream file(path, std::ios::binary);
if (!file) {
app.FatalLoadError();
uint32_t error = GetLastError();
assert(false);
} else {
uint32_t bytesRead, dwFileSize = GetFileSize(file, nullptr);
if (dwFileSize > m_heightmapOverride.size()) {
auto fileSize = std::filesystem::file_size(path);
if (fileSize > m_heightmapOverride.size()) {
app.DebugPrintf("Heightmap binary is too large!!\n");
__debugbreak();
}
bool bSuccess = ReadFile(file, m_heightmapOverride.data(), dwFileSize,
&bytesRead, nullptr);
file.read(reinterpret_cast<char*>(m_heightmapOverride.data()), static_cast<std::streamsize>(fileSize));
if (bSuccess == false) {
if (!file) {
app.FatalLoadError();
}
CloseHandle(file);
}
m_waterheightOverride = std::vector<uint8_t>((m_XZSize * 16) * (m_XZSize * 16));
#if defined(_UNICODE)
std::wstring waterHeightPath = L"GAME:\\GameRules\\waterheight.bin";
#else
#if defined(_WINDOWS64)
std::string waterHeightPath = "GameRules\\waterheight.bin";
#else
std::string waterHeightPath = "GAME:\\GameRules\\waterheight.bin";
#endif
#endif
file = CreateFile(waterHeightPath.c_str(), GENERIC_READ, 0, nullptr,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
if (file == INVALID_HANDLE_VALUE) {
uint32_t error = GetLastError();
std::filesystem::path waterHeightPath = "GameRules/waterheight.bin";
std::ifstream waterHeightFile(waterHeightPath, std::ios::binary);
if (!waterHeightFile) {
// assert(false);
memset(m_waterheightOverride.data(), level->seaLevel,
m_waterheightOverride.size());
} else {
uint32_t bytesRead, dwFileSize = GetFileSize(file, nullptr);
if (dwFileSize > m_waterheightOverride.size()) {
auto waterFileSize = std::filesystem::file_size(waterHeightPath);
if (waterFileSize > m_waterheightOverride.size()) {
app.DebugPrintf("waterheight binary is too large!!\n");
__debugbreak();
}
bool bSuccess = ReadFile(file, m_waterheightOverride.data(), dwFileSize,
&bytesRead, nullptr);
waterHeightFile.read(reinterpret_cast<char*>(m_waterheightOverride.data()), static_cast<std::streamsize>(waterFileSize));
if (bSuccess == false) {
if (!waterHeightFile) {
app.FatalLoadError();
}
CloseHandle(file);
}
caveFeature = new LargeCaveFeature();

View file

@ -2,6 +2,7 @@
#include "Minecraft.Client/Common/Source Files/GameRules/LevelGeneration/LevelGenerationOptions.h"
#include "Minecraft.Client/Linux/Linux_App.h"
#include "Minecraft.Client/Linux/Stubs/winapi_stubs.h"
#include "Minecraft.World/ConsoleHelpers/PlatformTime.h"
#include "java/Random.h"
#include "Minecraft.World/net/minecraft/util/Mth.h"
#include "Minecraft.World/net/minecraft/world/entity/MobCategory.h"
@ -96,8 +97,8 @@ RandomLevelSource::~RandomLevelSource() {
}
int g_numPrepareHeightCalls = 0;
LARGE_INTEGER g_totalPrepareHeightsTime = {0, 0};
LARGE_INTEGER g_averagePrepareHeightsTime = {0, 0};
std::int64_t g_totalPrepareHeightsTime = 0;
std::int64_t g_averagePrepareHeightsTime = 0;
#if defined(_LARGE_WORLDS)
@ -236,7 +237,7 @@ float RandomLevelSource::getHeightFalloff(int xxx, int zzz, int* pEMin) {
#endif
void RandomLevelSource::prepareHeights(int xOffs, int zOffs, std::vector<uint8_t>& blocks) {
LARGE_INTEGER startTime;
std::int64_t startTime;
int xChunks = 16 / CHUNK_WIDTH;
int yChunks = Level::genDepth / CHUNK_HEIGHT;
int waterHeight = level->seaLevel;
@ -257,7 +258,7 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, std::vector<uint8_t
buffer = getHeights(buffer, xOffs * xChunks, 0, zOffs * xChunks, xSize,
ySize, zSize, biomes);
QueryPerformanceCounter(&startTime);
startTime = PlatformTime::QueryPerformanceCounter();
for (int xc = 0; xc < xChunks; xc++) {
for (int zc = 0; zc < xChunks; zc++) {
for (int yc = 0; yc < yChunks; yc++) {
@ -369,14 +370,12 @@ void RandomLevelSource::prepareHeights(int xOffs, int zOffs, std::vector<uint8_t
}
}
}
LARGE_INTEGER endTime;
QueryPerformanceCounter(&endTime);
LARGE_INTEGER timeInFunc;
timeInFunc.QuadPart = endTime.QuadPart - startTime.QuadPart;
auto endTime = PlatformTime::QueryPerformanceCounter();
auto timeInFunc = endTime - startTime;
g_numPrepareHeightCalls++;
g_totalPrepareHeightsTime.QuadPart += timeInFunc.QuadPart;
g_averagePrepareHeightsTime.QuadPart =
g_totalPrepareHeightsTime.QuadPart / g_numPrepareHeightCalls;
g_totalPrepareHeightsTime += timeInFunc;
g_averagePrepareHeightsTime =
g_totalPrepareHeightsTime / g_numPrepareHeightCalls;
}

View file

@ -1,48 +1,37 @@
#include <string.h>
#include <string>
#include <fstream>
#include <filesystem>
#include "BiomeOverrideLayer.h"
#include "Minecraft.Client/Linux/Linux_App.h"
#if defined(__linux__)
#include "Minecraft.Client/Linux/Stubs/winapi_stubs.h"
#endif
#include "Minecraft.World/net/minecraft/world/level/biome/Biome.h"
#include "Minecraft.World/net/minecraft/world/level/newbiome/layer/Layer.h"
BiomeOverrideLayer::BiomeOverrideLayer(int seedMixup) : Layer(seedMixup) {
m_biomeOverride = std::vector<uint8_t>(width * height);
#if defined(_UNICODE)
std::wstring path = L"GAME:\\GameRules\\biomemap.bin";
void* file = CreateFile(path.c_str(), GENERIC_READ, 0, nullptr,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
#else
#if defined(_WINDOWS64)
std::string path = "GameRules\\biomemap.bin";
#else
std::string path = "GAME:\\GameRules\\biomemap.bin";
#endif
void* file = CreateFile(path.c_str(), GENERIC_READ, 0, nullptr,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
#endif
if (file == INVALID_HANDLE_VALUE) {
uint32_t error = GetLastError();
std::filesystem::path path = "GameRules/biomemap.bin";
std::ifstream file(path, std::ios::binary);
if (!file) {
// assert(false);
app.DebugPrintf("Biome override not found, using plains as default\n");
memset(m_biomeOverride.data(), Biome::plains->id, m_biomeOverride.size());
} else {
uint32_t bytesRead, dwFileSize = GetFileSize(file, nullptr);
if (dwFileSize > m_biomeOverride.size()) {
auto fileSize = std::filesystem::file_size(path);
if (fileSize > m_biomeOverride.size()) {
app.DebugPrintf("Biomemap binary is too large!!\n");
__debugbreak();
}
bool bSuccess = ReadFile(file, m_biomeOverride.data(), dwFileSize,
&bytesRead, nullptr);
file.read(reinterpret_cast<char*>(m_biomeOverride.data()), static_cast<std::streamsize>(fileSize));
if (bSuccess == false) {
if (!file) {
app.FatalLoadError();
}
CloseHandle(file);
}
}

View file

@ -85,11 +85,11 @@ File::File(const std::wstring& pathname) {
for (const char* base : bases) {
std::string tryFull = exeDir + base + request;
std::string tryFile = exeDir + base + fileName;
if (access(tryFull.c_str(), F_OK) != -1) {
if (std::filesystem::exists(tryFull)) {
m_abstractPathName = convStringToWstring(tryFull);
return;
}
if (access(tryFile.c_str(), F_OK) != -1) {
if (std::filesystem::exists(tryFile)) {
m_abstractPathName = convStringToWstring(tryFile);
return;
}

View file

@ -1,4 +1,4 @@
#include <ctime>
#include <chrono>
#include <cstdint> // for int64_t
#include "java/Random.h"
@ -9,10 +9,8 @@ Random::Random() {
// only millisecond accuate, so use QueryPerformanceCounter here instead
int64_t seed;
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
seed = ts.tv_sec * 1000000000LL + ts.tv_nsec;
auto now = std::chrono::steady_clock::now().time_since_epoch();
seed = std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
seed += 8682522807148012LL;

View file

@ -1,7 +1,4 @@
#if defined(__linux__)
#include <sys/time.h>
#include <time.h>
#endif
#include <chrono>
#include <assert.h>
#include <stdint.h>
@ -69,13 +66,8 @@ void System::arraycopy(const std::vector<int>& src, unsigned int srcPos,
// Returns:
// The current value of the system timer, in nanoseconds.
int64_t System::nanoTime() {
#if !defined(__linux__)
return GetTickCount() * 1000000LL;
#else
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
return static_cast<int64_t>(ts.tv_sec) * 1000000000LL + ts.tv_nsec;
#endif
auto now = std::chrono::steady_clock::now().time_since_epoch();
return std::chrono::duration_cast<std::chrono::nanoseconds>(now).count();
}
// Returns the current time in milliseconds. Note that while the unit of time of
@ -89,28 +81,8 @@ int64_t System::nanoTime() {
// the difference, measured in milliseconds, between the current time and
// midnight, January 1, 1970 UTC.
int64_t System::currentTimeMillis() {
#if defined(__linux__)
struct timeval tv;
gettimeofday(&tv, nullptr);
// Convert to milliseconds since unix epoch instead of windows file time
// time is expecting calculation to be between 10-30 ms.
return (int64_t)tv.tv_sec * 1000LL + tv.tv_usec / 1000;
#else
SYSTEMTIME UTCSysTime;
GetSystemTime(&UTCSysTime);
// Represents as a 64-bit value the number of 100-nanosecond intervals since
// January 1, 1601
FILETIME UTCFileTime;
SystemTimeToFileTime(&UTCSysTime, &UTCFileTime);
LARGE_INTEGER li;
li.HighPart = UTCFileTime.dwHighDateTime;
li.LowPart = UTCFileTime.dwLowDateTime;
return li.QuadPart / 10000;
#endif
auto now = std::chrono::system_clock::now().time_since_epoch();
return std::chrono::duration_cast<std::chrono::milliseconds>(now).count();
}
// 4J Stu - Added this so that we can use real-world timestamps in PSVita saves.