mirror of
https://github.com/smartcmd/MinecraftConsoles.git
synced 2026-07-28 20:12:24 +00:00
Merge remote-tracking branch 'smartcmd/main' into feature/plugin-api
This commit is contained in:
commit
7251a8419f
|
|
@ -89,6 +89,11 @@ void EnderDragonRenderer::render(shared_ptr<Entity> _mob, double x, double y, do
|
||||||
// 4J - dynamic cast required because we aren't using templates/generics in our version
|
// 4J - dynamic cast required because we aren't using templates/generics in our version
|
||||||
shared_ptr<EnderDragon> mob = dynamic_pointer_cast<EnderDragon>(_mob);
|
shared_ptr<EnderDragon> mob = dynamic_pointer_cast<EnderDragon>(_mob);
|
||||||
BossMobGuiInfo::setBossHealth(mob, false);
|
BossMobGuiInfo::setBossHealth(mob, false);
|
||||||
|
if (!mob->getCustomName().empty())
|
||||||
|
{
|
||||||
|
BossMobGuiInfo::name = mob->getCustomName();
|
||||||
|
}
|
||||||
|
|
||||||
MobRenderer::render(mob, x, y, z, rot, a);
|
MobRenderer::render(mob, x, y, z, rot, a);
|
||||||
if (mob->nearestCrystal != nullptr)
|
if (mob->nearestCrystal != nullptr)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1795,7 +1795,6 @@ void MinecraftServer::run(int64_t seed, void *lpParameter)
|
||||||
|
|
||||||
chunkPacketManagement_PostTick();
|
chunkPacketManagement_PostTick();
|
||||||
}
|
}
|
||||||
//lastTime = getCurrentTimeMillis();
|
|
||||||
// int64_t afterall = System::currentTimeMillis();
|
// int64_t afterall = System::currentTimeMillis();
|
||||||
// PIXReportCounter(L"Server time all",(float)(afterall-beforeall));
|
// PIXReportCounter(L"Server time all",(float)(afterall-beforeall));
|
||||||
// PIXReportCounter(L"Server ticks",(float)tickcount);
|
// PIXReportCounter(L"Server ticks",(float)tickcount);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,10 @@ void WitherBossRenderer::render(shared_ptr<Entity> entity, double x, double y, d
|
||||||
shared_ptr<WitherBoss> mob = dynamic_pointer_cast<WitherBoss>(entity);
|
shared_ptr<WitherBoss> mob = dynamic_pointer_cast<WitherBoss>(entity);
|
||||||
|
|
||||||
BossMobGuiInfo::setBossHealth(mob, true);
|
BossMobGuiInfo::setBossHealth(mob, true);
|
||||||
|
if (!mob->getCustomName().empty())
|
||||||
|
{
|
||||||
|
BossMobGuiInfo::name = mob->getCustomName();
|
||||||
|
}
|
||||||
|
|
||||||
int modelVersion = dynamic_cast<WitherBossModel*>(model)->modelVersion();
|
int modelVersion = dynamic_cast<WitherBossModel*>(model)->modelVersion();
|
||||||
if (modelVersion != this->modelVersion)
|
if (modelVersion != this->modelVersion)
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
#include "../../Minecraft.World/TilePos.h"
|
#include "../../Minecraft.World/TilePos.h"
|
||||||
#include "../../Minecraft.World/compression.h"
|
#include "../../Minecraft.World/compression.h"
|
||||||
#include "../../Minecraft.World/OldChunkStorage.h"
|
#include "../../Minecraft.World/OldChunkStorage.h"
|
||||||
|
#include "../../Minecraft.World/ConsoleSaveFileOriginal.h"
|
||||||
#include "../../Minecraft.World/net.minecraft.world.level.tile.h"
|
#include "../../Minecraft.World/net.minecraft.world.level.tile.h"
|
||||||
#include "../../Minecraft.World/Random.h"
|
#include "../../Minecraft.World/Random.h"
|
||||||
|
|
||||||
|
|
@ -326,6 +327,7 @@ static void TickCoreSystems()
|
||||||
g_NetworkManager.DoWork();
|
g_NetworkManager.DoWork();
|
||||||
ProfileManager.Tick();
|
ProfileManager.Tick();
|
||||||
StorageManager.Tick();
|
StorageManager.Tick();
|
||||||
|
ConsoleSaveFileOriginal::flushPendingBackgroundSave();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -704,9 +706,20 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
C4JThread waitThread(&WaitForServerStoppedThreadProc, NULL, "WaitServerStopped");
|
C4JThread waitThread(&WaitForServerStoppedThreadProc, NULL, "WaitServerStopped");
|
||||||
waitThread.Run();
|
waitThread.Run();
|
||||||
|
while (waitThread.isRunning())
|
||||||
|
{
|
||||||
|
TickCoreSystems();
|
||||||
|
Sleep(10);
|
||||||
|
}
|
||||||
waitThread.WaitForCompletion(INFINITE);
|
waitThread.WaitForCompletion(INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while (ConsoleSaveFileOriginal::hasPendingBackgroundSave())
|
||||||
|
{
|
||||||
|
TickCoreSystems();
|
||||||
|
Sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
LogInfof("shutdown", "Cleaning up and exiting.");
|
LogInfof("shutdown", "Cleaning up and exiting.");
|
||||||
FourKitBridge::Shutdown();
|
FourKitBridge::Shutdown();
|
||||||
WinsockNetLayer::Shutdown();
|
WinsockNetLayer::Shutdown();
|
||||||
|
|
|
||||||
|
|
@ -510,6 +510,8 @@ set(_MINECRAFT_SERVER_COMMON_ROOT
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/Mushroom.h"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/Mushroom.h"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/Sapling.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/Sapling.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/Sapling.h"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/Sapling.h"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/ConsoleSaveFileOriginal.cpp"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../Minecraft.World/ConsoleSaveFileOriginal.h"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../include/lce_filesystem/lce_filesystem.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../include/lce_filesystem/lce_filesystem.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/Console/ServerCliInput.cpp"
|
"${CMAKE_CURRENT_SOURCE_DIR}/Console/ServerCliInput.cpp"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/Console/ServerCliInput.h"
|
"${CMAKE_CURRENT_SOURCE_DIR}/Console/ServerCliInput.h"
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,26 @@
|
||||||
#include "..\Minecraft.Client\Common\GameRules\LevelGenerationOptions.h"
|
#include "..\Minecraft.Client\Common\GameRules\LevelGenerationOptions.h"
|
||||||
#include "..\Minecraft.World\net.minecraft.world.level.chunk.storage.h"
|
#include "..\Minecraft.World\net.minecraft.world.level.chunk.storage.h"
|
||||||
|
|
||||||
|
#ifdef MINECRAFT_SERVER_BUILD
|
||||||
|
#include <thread>
|
||||||
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
static std::atomic<bool> s_bgSaveActive{false};
|
||||||
|
static std::mutex s_bgSaveMutex;
|
||||||
|
|
||||||
|
struct BackgroundSaveResult
|
||||||
|
{
|
||||||
|
ConsoleSaveFile *owner = nullptr;
|
||||||
|
PBYTE thumbData = nullptr;
|
||||||
|
DWORD thumbSize = 0;
|
||||||
|
BYTE textMeta[88] = {};
|
||||||
|
int textMetaBytes = 0;
|
||||||
|
bool pending = false;
|
||||||
|
};
|
||||||
|
static BackgroundSaveResult s_bgResult;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef _XBOX
|
#ifdef _XBOX
|
||||||
#define RESERVE_ALLOCATION MEM_RESERVE | MEM_LARGE_PAGES
|
#define RESERVE_ALLOCATION MEM_RESERVE | MEM_LARGE_PAGES
|
||||||
|
|
@ -673,6 +693,83 @@ void ConsoleSaveFileOriginal::Flush(bool autosave, bool updateThumbnail )
|
||||||
|
|
||||||
unsigned int fileSize = header.GetFileSize();
|
unsigned int fileSize = header.GetFileSize();
|
||||||
|
|
||||||
|
#ifdef MINECRAFT_SERVER_BUILD
|
||||||
|
// on the server we dont want to block the tick thread doing compression!!!
|
||||||
|
// sna[pshot pvSaveMem while we still hold the lock then hand it off to a background thread
|
||||||
|
byte *snap = new (std::nothrow) byte[fileSize];
|
||||||
|
if (snap)
|
||||||
|
{
|
||||||
|
// copy the save buffer while we still own the lock so nothing can write to it mid-copy
|
||||||
|
QueryPerformanceCounter(&qwTime);
|
||||||
|
memcpy(snap, pvSaveMem, fileSize);
|
||||||
|
QueryPerformanceCounter(&qwNewTime);
|
||||||
|
app.DebugPrintf("snapshot %u bytes in %.3f sec\n", fileSize,
|
||||||
|
(qwNewTime.QuadPart - qwTime.QuadPart) * fSecsPerTick);
|
||||||
|
|
||||||
|
PBYTE thumb = nullptr;
|
||||||
|
DWORD thumbSz = 0;
|
||||||
|
app.GetSaveThumbnail(&thumb, &thumbSz);
|
||||||
|
|
||||||
|
BYTE meta[88];
|
||||||
|
ZeroMemory(meta, 88);
|
||||||
|
int64_t seed = 0;
|
||||||
|
bool hasSeed = false;
|
||||||
|
if (MinecraftServer *sv = MinecraftServer::getInstance(); sv && sv->levels[0])
|
||||||
|
{
|
||||||
|
seed = sv->levels[0]->getLevelData()->getSeed();
|
||||||
|
hasSeed = true;
|
||||||
|
}
|
||||||
|
int metaLen = app.CreateImageTextData(meta, seed, hasSeed,
|
||||||
|
app.GetGameHostOption(eGameHostOption_All), Minecraft::GetInstance()->getCurrentTexturePackId());
|
||||||
|
|
||||||
|
// telemetry
|
||||||
|
INT uid = 0;
|
||||||
|
StorageManager.GetSaveUniqueNumber(&uid);
|
||||||
|
TelemetryManager->RecordLevelSaveOrCheckpoint(ProfileManager.GetPrimaryPad(), uid, fileSize);
|
||||||
|
|
||||||
|
ReleaseSaveAccess();
|
||||||
|
s_bgSaveActive.store(true, std::memory_order_release);
|
||||||
|
|
||||||
|
std::thread([snap, fileSize, thumb, thumbSz, meta, metaLen, this]() {
|
||||||
|
unsigned int compLen = fileSize + 8;
|
||||||
|
byte *buf = static_cast<byte *>(StorageManager.AllocateSaveData(compLen));
|
||||||
|
if (!buf)
|
||||||
|
{
|
||||||
|
// FAIL!! attempt precalc
|
||||||
|
compLen = 0;
|
||||||
|
Compression::getCompression()->Compress(nullptr, &compLen, snap, fileSize);
|
||||||
|
compLen += 8;
|
||||||
|
buf = static_cast<byte *>(StorageManager.AllocateSaveData(compLen));
|
||||||
|
}
|
||||||
|
if (buf)
|
||||||
|
{
|
||||||
|
// COM,PRESS
|
||||||
|
Compression::getCompression()->Compress(buf + 8, &compLen, snap, fileSize);
|
||||||
|
ZeroMemory(buf, 8);
|
||||||
|
memcpy(buf + 4, &fileSize, sizeof(fileSize));
|
||||||
|
|
||||||
|
// store the result so flushPendingBackgroundSave() can pick it up on the main thread next tick
|
||||||
|
// StorageManager isnt thread safe so we cant call SetSaveImages or SaveSaveData from here. Bwoomp
|
||||||
|
std::lock_guard<std::mutex> lk(s_bgSaveMutex);
|
||||||
|
s_bgResult.owner = this;
|
||||||
|
s_bgResult.thumbData = thumb;
|
||||||
|
s_bgResult.thumbSize = thumbSz;
|
||||||
|
memcpy(s_bgResult.textMeta, meta, sizeof(meta));
|
||||||
|
s_bgResult.textMetaBytes = metaLen;
|
||||||
|
s_bgResult.pending = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
app.DebugPrintf("save buf alloc failed\n");
|
||||||
|
s_bgSaveActive.store(false, std::memory_order_release);
|
||||||
|
}
|
||||||
|
delete[] snap;
|
||||||
|
}).detach();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
app.DebugPrintf("snapshot alloc failed (%u bytes)\n", fileSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Assume that the compression will make it smaller so initially attempt to allocate the current file size
|
// Assume that the compression will make it smaller so initially attempt to allocate the current file size
|
||||||
// We add 4 bytes to the start so that we can signal compressed data
|
// We add 4 bytes to the start so that we can signal compressed data
|
||||||
// And another 4 bytes to store the decompressed data size
|
// And another 4 bytes to store the decompressed data size
|
||||||
|
|
@ -838,6 +935,10 @@ int ConsoleSaveFileOriginal::SaveSaveDataCallback(LPVOID lpParam,bool bRes)
|
||||||
{
|
{
|
||||||
ConsoleSaveFile *pClass=static_cast<ConsoleSaveFile *>(lpParam);
|
ConsoleSaveFile *pClass=static_cast<ConsoleSaveFile *>(lpParam);
|
||||||
|
|
||||||
|
#ifdef MINECRAFT_SERVER_BUILD
|
||||||
|
s_bgSaveActive.store(false, std::memory_order_release);
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1085,3 +1186,25 @@ void *ConsoleSaveFileOriginal::getWritePointer(FileEntry *file)
|
||||||
{
|
{
|
||||||
return static_cast<char *>(pvSaveMem) + file->currentFilePointer;;
|
return static_cast<char *>(pvSaveMem) + file->currentFilePointer;;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MINECRAFT_SERVER_BUILD
|
||||||
|
void ConsoleSaveFileOriginal::flushPendingBackgroundSave()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lk(s_bgSaveMutex);
|
||||||
|
if (!s_bgResult.pending)
|
||||||
|
return;
|
||||||
|
|
||||||
|
StorageManager.SetSaveImages(
|
||||||
|
s_bgResult.thumbData, s_bgResult.thumbSize,
|
||||||
|
nullptr, 0, s_bgResult.textMeta, s_bgResult.textMetaBytes);
|
||||||
|
StorageManager.SaveSaveData(&ConsoleSaveFileOriginal::SaveSaveDataCallback, s_bgResult.owner);
|
||||||
|
|
||||||
|
s_bgResult.pending = false;
|
||||||
|
// the actual write isnt done until SaveSaveDataCallback fires
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConsoleSaveFileOriginal::hasPendingBackgroundSave()
|
||||||
|
{
|
||||||
|
return s_bgSaveActive.load(std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,11 @@ public:
|
||||||
virtual void LockSaveAccess();
|
virtual void LockSaveAccess();
|
||||||
virtual void ReleaseSaveAccess();
|
virtual void ReleaseSaveAccess();
|
||||||
|
|
||||||
|
#ifdef MINECRAFT_SERVER_BUILD
|
||||||
|
static void flushPendingBackgroundSave();
|
||||||
|
static bool hasPendingBackgroundSave();
|
||||||
|
#endif
|
||||||
|
|
||||||
virtual ESavePlatform getSavePlatform();
|
virtual ESavePlatform getSavePlatform();
|
||||||
virtual bool isSaveEndianDifferent();
|
virtual bool isSaveEndianDifferent();
|
||||||
virtual void setLocalPlatform();
|
virtual void setLocalPlatform();
|
||||||
|
|
|
||||||
|
|
@ -183,7 +183,7 @@ public:
|
||||||
double getHeadPartYRotDiff(int partIndex, doubleArray bodyPos, doubleArray partPos);
|
double getHeadPartYRotDiff(int partIndex, doubleArray bodyPos, doubleArray partPos);
|
||||||
Vec3 *getHeadLookVector(float a);
|
Vec3 *getHeadLookVector(float a);
|
||||||
|
|
||||||
virtual wstring getAName() { return app.GetString(IDS_ENDERDRAGON); };
|
virtual wstring getAName() { if (hasCustomName()) return getCustomName(); return app.GetString(IDS_ENDERDRAGON); };
|
||||||
virtual float getHealth() { return LivingEntity::getHealth(); };
|
virtual float getHealth() { return LivingEntity::getHealth(); };
|
||||||
virtual float getMaxHealth() { return LivingEntity::getMaxHealth(); };
|
virtual float getMaxHealth() { return LivingEntity::getMaxHealth(); };
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -105,5 +105,5 @@ public:
|
||||||
// 4J Stu - These are required for the BossMob interface
|
// 4J Stu - These are required for the BossMob interface
|
||||||
virtual float getMaxHealth() { return Monster::getMaxHealth(); };
|
virtual float getMaxHealth() { return Monster::getMaxHealth(); };
|
||||||
virtual float getHealth() { return Monster::getHealth(); };
|
virtual float getHealth() { return Monster::getHealth(); };
|
||||||
virtual wstring getAName() { return app.GetString(IDS_WITHER); };
|
virtual wstring getAName() { if (hasCustomName()) return getCustomName(); return app.GetString(IDS_WITHER); };
|
||||||
};
|
};
|
||||||
Loading…
Reference in a new issue