refactor: type the IGameServices payload as a variant instead of void*

This commit is contained in:
MatthewBeshay 2026-04-08 19:40:20 +10:00
parent 8084ec7857
commit 52b4ccaea2
17 changed files with 141 additions and 92 deletions

View file

@ -178,8 +178,8 @@ void AppGameServices::setAction(int iPad, eXuiAction action, void* param) {
} }
void AppGameServices::setXuiServerAction(int iPad, eXuiServerAction action, void AppGameServices::setXuiServerAction(int iPad, eXuiServerAction action,
void* param) { XuiActionPayload param) {
game_.SetXuiServerAction(iPad, action, param); game_.SetXuiServerAction(iPad, action, std::move(param));
} }
eXuiAction AppGameServices::getXuiAction(int iPad) { eXuiAction AppGameServices::getXuiAction(int iPad) {
@ -190,7 +190,7 @@ eXuiServerAction AppGameServices::getXuiServerAction(int iPad) {
return game_.GetXuiServerAction(iPad); return game_.GetXuiServerAction(iPad);
} }
void* AppGameServices::getXuiServerActionParam(int iPad) { const XuiActionPayload& AppGameServices::getXuiServerActionParam(int iPad) {
return game_.GetXuiServerActionParam(iPad); return game_.GetXuiServerActionParam(iPad);
} }

View file

@ -77,10 +77,10 @@ public:
// -- UI dispatch -- // -- UI dispatch --
void setAction(int iPad, eXuiAction action, void* param) override; void setAction(int iPad, eXuiAction action, void* param) override;
void setXuiServerAction(int iPad, eXuiServerAction action, void setXuiServerAction(int iPad, eXuiServerAction action,
void* param) override; XuiActionPayload param) override;
eXuiAction getXuiAction(int iPad) override; eXuiAction getXuiAction(int iPad) override;
eXuiServerAction getXuiServerAction(int iPad) override; eXuiServerAction getXuiServerAction(int iPad) override;
void* getXuiServerActionParam(int iPad) override; const XuiActionPayload& getXuiServerActionParam(int iPad) override;
void setGlobalXuiAction(eXuiAction action) override; void setGlobalXuiAction(eXuiAction action) override;
void handleButtonPresses() override; void handleButtonPresses() override;
void setTMSAction(int iPad, eTMSAction action) override; void setTMSAction(int iPad, eTMSAction action) override;

View file

@ -260,12 +260,12 @@ public:
eXuiServerAction GetXuiServerAction(int iPad) { eXuiServerAction GetXuiServerAction(int iPad) {
return m_menuController.getXuiServerAction(iPad); return m_menuController.getXuiServerAction(iPad);
} }
void* GetXuiServerActionParam(int iPad) { const XuiActionPayload& GetXuiServerActionParam(int iPad) {
return m_menuController.getXuiServerActionParam(iPad); return m_menuController.getXuiServerActionParam(iPad);
} }
void SetXuiServerAction(int iPad, eXuiServerAction action, void SetXuiServerAction(int iPad, eXuiServerAction action,
void* param = nullptr) { XuiActionPayload param = {}) {
m_menuController.setXuiServerAction(iPad, action, param); m_menuController.setXuiServerAction(iPad, action, std::move(param));
} }
eXuiServerAction GetGlobalXuiServerAction() { eXuiServerAction GetGlobalXuiServerAction() {
return m_menuController.getGlobalXuiServerAction(); return m_menuController.getGlobalXuiServerAction();

View file

@ -13,6 +13,8 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "minecraft/XuiActionPayload.h"
#include "app/linux/Stubs/winapi_stubs.h" #include "app/linux/Stubs/winapi_stubs.h"
#include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h" #include "minecraft/world/level/storage/ConsoleSaveFileIO/compression.h"
#include "minecraft/world/phys/Vec3.h" #include "minecraft/world/phys/Vec3.h"
@ -43,7 +45,7 @@ public:
void decrementRefCount() { --m_refCount; } void decrementRefCount() { --m_refCount; }
bool shouldDelete() { return m_refCount <= 0; } bool shouldDelete() { return m_refCount <= 0; }
typedef struct _XboxSchematicInitParam { struct XboxSchematicInitParam : minecraft::XuiActionOwnedPayload {
char name[64]; char name[64];
int startX; int startX;
int startY; int startY;
@ -55,13 +57,13 @@ public:
Compression::ECompressionTypes compressionType; Compression::ECompressionTypes compressionType;
_XboxSchematicInitParam() { XboxSchematicInitParam() {
memset(name, 0, 64 * (sizeof(char))); memset(name, 0, 64 * (sizeof(char)));
startX = startY = startZ = endX = endY = endZ = 0; startX = startY = startZ = endX = endY = endZ = 0;
bSaveMobs = false; bSaveMobs = false;
compressionType = Compression::eCompressionType_None; compressionType = Compression::eCompressionType_None;
} }
} XboxSchematicInitParam; };
private: private:
int m_xSize, m_ySize, m_zSize; int m_xSize, m_ySize, m_zSize;

View file

@ -5,6 +5,7 @@
#include <string> #include <string>
#include "app/common/App_structs.h" #include "app/common/App_structs.h"
#include "minecraft/XuiActionPayload.h"
#include "platform/storage/storage.h" #include "platform/storage/storage.h"
#include "platform/XboxStubs.h" #include "platform/XboxStubs.h"
@ -70,14 +71,14 @@ public:
void setAction(int iPad, eXuiAction action, void* param = nullptr); void setAction(int iPad, eXuiAction action, void* param = nullptr);
eXuiAction getXuiAction(int iPad) { return m_eXuiAction[iPad]; } eXuiAction getXuiAction(int iPad) { return m_eXuiAction[iPad]; }
void setXuiServerAction(int iPad, eXuiServerAction action, void setXuiServerAction(int iPad, eXuiServerAction action,
void* param = nullptr) { XuiActionPayload param = {}) {
m_eXuiServerAction[iPad] = action; m_eXuiServerAction[iPad] = action;
m_eXuiServerActionParam[iPad] = param; m_eXuiServerActionParam[iPad] = std::move(param);
} }
eXuiServerAction getXuiServerAction(int iPad) { eXuiServerAction getXuiServerAction(int iPad) {
return m_eXuiServerAction[iPad]; return m_eXuiServerAction[iPad];
} }
void* getXuiServerActionParam(int iPad) { const XuiActionPayload& getXuiServerActionParam(int iPad) {
return m_eXuiServerActionParam[iPad]; return m_eXuiServerActionParam[iPad];
} }
eXuiAction getGlobalXuiAction() { return m_eGlobalXuiAction; } eXuiAction getGlobalXuiAction() { return m_eGlobalXuiAction; }
@ -141,7 +142,7 @@ private:
void* m_eXuiActionParam[XUSER_MAX_COUNT]; void* m_eXuiActionParam[XUSER_MAX_COUNT];
eXuiAction m_eGlobalXuiAction; eXuiAction m_eGlobalXuiAction;
eXuiServerAction m_eXuiServerAction[XUSER_MAX_COUNT]; eXuiServerAction m_eXuiServerAction[XUSER_MAX_COUNT];
void* m_eXuiServerActionParam[XUSER_MAX_COUNT]; XuiActionPayload m_eXuiServerActionParam[XUSER_MAX_COUNT];
eXuiServerAction m_eGlobalXuiServerAction; eXuiServerAction m_eGlobalXuiServerAction;
unsigned int m_uiOpacityCountDown[XUSER_MAX_COUNT]; unsigned int m_uiOpacityCountDown[XUSER_MAX_COUNT];

View file

@ -881,7 +881,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) {
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
} }
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_PauseServer, (void*)true); eXuiServerAction_PauseServer, true);
// wait for the server to be in a non-ticking state // wait for the server to be in a non-ticking state
pServer->m_serverPausedEvent->waitForSignal(C4JThread::kInfiniteTimeout); pServer->m_serverPausedEvent->waitForSignal(C4JThread::kInfiniteTimeout);
@ -1009,7 +1009,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc(void* lpParam) {
// Start the game again // Start the game again
app.SetGameStarted(true); app.SetGameStarted(true);
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_PauseServer, (void*)false); eXuiServerAction_PauseServer, false);
app.SetChangingSessionType(false); app.SetChangingSessionType(false);
app.SetReallyChangingSessionType(false); app.SetReallyChangingSessionType(false);

View file

@ -36,8 +36,7 @@ void SaveManager::lock() {
if (g_NetworkManager.IsLocalGame() && if (g_NetworkManager.IsLocalGame() &&
g_NetworkManager.GetPlayerCount() == 1) { g_NetworkManager.GetPlayerCount() == 1) {
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_PauseServer, eXuiServerAction_PauseServer, true);
(void*)true);
} }
} }
} }
@ -55,8 +54,7 @@ void SaveManager::unlock() {
if (g_NetworkManager.IsLocalGame() && if (g_NetworkManager.IsLocalGame() &&
g_NetworkManager.GetPlayerCount() == 1) { g_NetworkManager.GetPlayerCount() == 1) {
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_PauseServer, eXuiServerAction_PauseServer, false);
(void*)false);
} }
} }
} }

View file

@ -6,10 +6,11 @@
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include "platform/storage/storage.h"
#include "minecraft/GameHostOptions.h" #include "minecraft/GameHostOptions.h"
#include "UIEnums.h" #include "minecraft/XuiActionPayload.h"
#include "platform/C4JThread.h" #include "platform/C4JThread.h"
#include "platform/storage/storage.h"
#include "UIEnums.h"
class Container; class Container;
class Inventory; class Inventory;
@ -417,10 +418,10 @@ typedef struct _InGamePlayerOptionsInitData {
unsigned int playerPrivileges; unsigned int playerPrivileges;
} InGamePlayerOptionsInitData; } InGamePlayerOptionsInitData;
typedef struct _DebugSetCameraPosition { struct DebugSetCameraPosition : minecraft::XuiActionOwnedPayload {
int player; int player;
double m_camX, m_camY, m_camZ, m_yRot, m_elev; double m_camX, m_camY, m_camZ, m_yRot, m_elev;
} DebugSetCameraPosition; };
typedef struct _TeleportMenuInitData { typedef struct _TeleportMenuInitData {
int iPad; int iPad;

View file

@ -115,9 +115,11 @@ void UIScene_DebugCreateSchematic::handlePress(F64 controlId, F64 childId) {
else if (m_data->endZ < 0 && m_data->endZ % 2 == 0) else if (m_data->endZ < 0 && m_data->endZ % 2 == 0)
m_data->endZ += 1; m_data->endZ += 1;
std::unique_ptr<minecraft::XuiActionOwnedPayload> payload(m_data);
m_data = nullptr; // ownership transferred to the action
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_ExportSchematic, eXuiServerAction_ExportSchematic,
(void*)m_data); std::move(payload));
navigateBack(); navigateBack();
} break; } break;

View file

@ -208,9 +208,9 @@ void UIScene_DebugOverlay::handlePress(F64 controlId, F64 childId) {
case eControl_Mobs: { case eControl_Mobs: {
int id = childId; int id = childId;
if (id < m_mobFactories.size()) { if (id < m_mobFactories.size()) {
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(
eXuiServerAction_SpawnMob, PlatformProfile.GetPrimaryPad(), eXuiServerAction_SpawnMob,
(void*)m_mobFactories[id]); static_cast<std::int64_t>(m_mobFactories[id]));
} }
} break; } break;
case eControl_Enchantments: { case eControl_Enchantments: {

View file

@ -107,11 +107,14 @@ void UIScene_DebugSetCamera::handleInput(int iPad, int key, bool repeat,
void UIScene_DebugSetCamera::handlePress(F64 controlId, F64 childId) { void UIScene_DebugSetCamera::handlePress(F64 controlId, F64 childId) {
switch ((int)controlId) { switch ((int)controlId) {
case eControl_Teleport: case eControl_Teleport: {
std::unique_ptr<minecraft::XuiActionOwnedPayload> payload(
currentPosition);
currentPosition = nullptr; // ownership transferred
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_SetCameraLocation, eXuiServerAction_SetCameraLocation,
(void*)currentPosition); std::move(payload));
break; } break;
case eControl_CamX: case eControl_CamX:
case eControl_CamY: case eControl_CamY:
case eControl_CamZ: case eControl_CamZ:

View file

@ -65,7 +65,7 @@ UIScene_PauseMenu::UIScene_PauseMenu(int iPad, void* initData,
if (/*g_NetworkManager.IsLocalGame() &&*/ g_NetworkManager if (/*g_NetworkManager.IsLocalGame() &&*/ g_NetworkManager
.GetPlayerCount() == 1) { .GetPlayerCount() == 1) {
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_PauseServer, (void*)true); eXuiServerAction_PauseServer, true);
} }
Minecraft* pMinecraft = Minecraft::GetInstance(); Minecraft* pMinecraft = Minecraft::GetInstance();
@ -195,8 +195,7 @@ void UIScene_PauseMenu::handleInput(int iPad, int key, bool repeat,
/*g_NetworkManager.IsLocalGame()*/ g_NetworkManager /*g_NetworkManager.IsLocalGame()*/ g_NetworkManager
.GetPlayerCount() == 1) { .GetPlayerCount() == 1) {
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_PauseServer, eXuiServerAction_PauseServer, false);
(void*)false);
} }
ui.PlayUISFX(eSFX_Back); ui.PlayUISFX(eSFX_Back);
@ -264,8 +263,7 @@ void UIScene_PauseMenu::handlePress(F64 controlId, F64 childId) {
/*g_NetworkManager.IsLocalGame()*/ g_NetworkManager /*g_NetworkManager.IsLocalGame()*/ g_NetworkManager
.GetPlayerCount() == 1) { .GetPlayerCount() == 1) {
app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(), app.SetXuiServerAction(PlatformProfile.GetPrimaryPad(),
eXuiServerAction_PauseServer, eXuiServerAction_PauseServer, false);
(void*)false);
} }
navigateBack(); navigateBack();
break; break;

View file

@ -17,6 +17,7 @@ class DLCPack;
#include "minecraft/client/model/SkinBox.h" #include "minecraft/client/model/SkinBox.h"
#include "minecraft/GameTypes.h" #include "minecraft/GameTypes.h"
#include "minecraft/GameEnums.h" #include "minecraft/GameEnums.h"
#include "minecraft/XuiActionPayload.h"
#include "platform/PlatformTypes.h" #include "platform/PlatformTypes.h"
#include "minecraft/network/packet/DisconnectPacket.h" #include "minecraft/network/packet/DisconnectPacket.h"
#include "minecraft/client/IMenuService.h" #include "minecraft/client/IMenuService.h"
@ -109,10 +110,11 @@ public:
virtual void setAction(int iPad, eXuiAction action, virtual void setAction(int iPad, eXuiAction action,
void* param = nullptr) = 0; void* param = nullptr) = 0;
virtual void setXuiServerAction(int iPad, eXuiServerAction action, virtual void setXuiServerAction(int iPad, eXuiServerAction action,
void* param = nullptr) = 0; XuiActionPayload param = {}) = 0;
[[nodiscard]] virtual eXuiAction getXuiAction(int iPad) = 0; [[nodiscard]] virtual eXuiAction getXuiAction(int iPad) = 0;
[[nodiscard]] virtual eXuiServerAction getXuiServerAction(int iPad) = 0; [[nodiscard]] virtual eXuiServerAction getXuiServerAction(int iPad) = 0;
[[nodiscard]] virtual void* getXuiServerActionParam(int iPad) = 0; [[nodiscard]] virtual const XuiActionPayload& getXuiServerActionParam(
int iPad) = 0;
virtual void setGlobalXuiAction(eXuiAction action) = 0; virtual void setGlobalXuiAction(eXuiAction action) = 0;
virtual void handleButtonPresses() = 0; virtual void handleButtonPresses() = 0;
virtual void setTMSAction(int iPad, eTMSAction action) = 0; virtual void setTMSAction(int iPad, eTMSAction action) = 0;

View file

@ -0,0 +1,27 @@
#pragma once
#include <cstdint>
#include <memory>
#include <variant>
// Type-safe payload carried by IGameServices::setAction /
// setXuiServerAction. Replaces the old `void* param` which mixed
// integers, booleans, and heap-allocated pointers without ownership
// tracking. Concrete heap-allocated payload types (e.g.
// _DebugSetCameraPosition, _XboxSchematicInitParam) inherit from
// XuiActionOwnedPayload so they can be destroyed polymorphically through
// the unique_ptr alternative inside the variant.
namespace minecraft {
struct XuiActionOwnedPayload {
virtual ~XuiActionOwnedPayload() = default;
};
} // namespace minecraft
using XuiActionPayload = std::variant<
std::monostate,
bool,
std::int64_t,
std::unique_ptr<minecraft::XuiActionOwnedPayload>>;

View file

@ -34,7 +34,7 @@ void PauseScreen::init() {
if (g_NetworkManager.IsLocalGame() && if (g_NetworkManager.IsLocalGame() &&
g_NetworkManager.GetPlayerCount() == 1) g_NetworkManager.GetPlayerCount() == 1)
gameServices().setXuiServerAction(PlatformInput.GetPrimaryPad(), gameServices().setXuiServerAction(PlatformInput.GetPrimaryPad(),
eXuiServerAction_PauseServer, (void*)true); eXuiServerAction_PauseServer, true);
buttons.push_back(new Button(1, width / 2 - 100, height / 4 + 24 * 5 + yo, buttons.push_back(new Button(1, width / 2 - 100, height / 4 + 24 * 5 + yo,
I18n::get("menu.returnToMenu"))); I18n::get("menu.returnToMenu")));
if (!g_NetworkManager.IsHost()) { if (!g_NetworkManager.IsHost()) {
@ -92,7 +92,7 @@ void PauseScreen::buttonClicked(Button* button) {
} }
if (button->id == 4) { if (button->id == 4) {
gameServices().setXuiServerAction(PlatformInput.GetPrimaryPad(), gameServices().setXuiServerAction(PlatformInput.GetPrimaryPad(),
eXuiServerAction_PauseServer, (void*)false); eXuiServerAction_PauseServer, false);
minecraft->setScreen(nullptr); minecraft->setScreen(nullptr);
// minecraft->grabMouse(); // 4J - removed // minecraft->grabMouse(); // 4J - removed
} }

View file

@ -44,7 +44,7 @@ void Screen::keyPressed(char eventCharacter, int eventKey) {
if (g_NetworkManager.IsLocalGame() && if (g_NetworkManager.IsLocalGame() &&
g_NetworkManager.GetPlayerCount() == 1) g_NetworkManager.GetPlayerCount() == 1)
gameServices().setXuiServerAction(PlatformInput.GetPrimaryPad(), gameServices().setXuiServerAction(PlatformInput.GetPrimaryPad(),
eXuiServerAction_PauseServer, (void*)false); eXuiServerAction_PauseServer, false);
} }
} }

View file

@ -1180,10 +1180,10 @@ void MinecraftServer::run(int64_t seed, void* lpParameter) {
// Process delayed actions // Process delayed actions
eXuiServerAction eAction; eXuiServerAction eAction;
void* param;
for (int i = 0; i < XUSER_MAX_COUNT; i++) { for (int i = 0; i < XUSER_MAX_COUNT; i++) {
eAction = gameServices().getXuiServerAction(i); eAction = gameServices().getXuiServerAction(i);
param = gameServices().getXuiServerActionParam(i); const XuiActionPayload& param =
gameServices().getXuiServerActionParam(i);
switch (eAction) { switch (eAction) {
case eXuiServerAction_AutoSaveGame: case eXuiServerAction_AutoSaveGame:
@ -1227,18 +1227,20 @@ void MinecraftServer::run(int64_t seed, void* lpParameter) {
break; break;
case eXuiServerAction_DropItem: case eXuiServerAction_DropItem:
// Find the player, and drop the id at their feet // Find the player, and drop the id at their feet
{ if (auto* id = std::get_if<std::int64_t>(&param)) {
std::shared_ptr<ServerPlayer> player = std::shared_ptr<ServerPlayer> player =
players->players.at(0); players->players.at(0);
size_t id = (size_t)param;
player->drop(std::shared_ptr<ItemInstance>( player->drop(std::shared_ptr<ItemInstance>(
new ItemInstance(id, 1, 0))); new ItemInstance(static_cast<int>(*id), 1, 0)));
} }
break; break;
case eXuiServerAction_SpawnMob: { case eXuiServerAction_SpawnMob: {
auto* id = std::get_if<std::int64_t>(&param);
if (!id) break;
std::shared_ptr<ServerPlayer> player = std::shared_ptr<ServerPlayer> player =
players->players.at(0); players->players.at(0);
eINSTANCEOF factory = (eINSTANCEOF)((size_t)param); eINSTANCEOF factory =
static_cast<eINSTANCEOF>(*id);
std::shared_ptr<Mob> mob = std::shared_ptr<Mob> mob =
std::dynamic_pointer_cast<Mob>( std::dynamic_pointer_cast<Mob>(
EntityIO::newByEnumType(factory, EntityIO::newByEnumType(factory,
@ -1254,9 +1256,11 @@ void MinecraftServer::run(int64_t seed, void* lpParameter) {
player->level->addEntity(mob); player->level->addEntity(mob);
} break; } break;
case eXuiServerAction_PauseServer: case eXuiServerAction_PauseServer:
m_isServerPaused = ((size_t)param == true); if (auto* val = std::get_if<bool>(&param)) {
if (m_isServerPaused) { m_isServerPaused = *val;
m_serverPausedEvent->set(); if (m_isServerPaused) {
m_serverPausedEvent->set();
}
} }
break; break;
case eXuiServerAction_ToggleRain: { case eXuiServerAction_ToggleRain: {
@ -1311,32 +1315,42 @@ void MinecraftServer::run(int64_t seed, void* lpParameter) {
// UpdateProgressPacket(20) ) ); // UpdateProgressPacket(20) ) );
if (!s_bServerHalted) { if (!s_bServerHalted) {
auto* owned = std::get_if<
std::unique_ptr<minecraft::XuiActionOwnedPayload>>(
&param);
ConsoleSchematicFile::XboxSchematicInitParam* ConsoleSchematicFile::XboxSchematicInitParam*
initData = (ConsoleSchematicFile:: initData = owned ? dynamic_cast<
XboxSchematicInitParam*)param; ConsoleSchematicFile::XboxSchematicInitParam*>(
File targetFileDir("Schematics"); owned->get())
if (!targetFileDir.exists()) targetFileDir.mkdir(); : nullptr;
if (initData) {
File targetFileDir("Schematics");
if (!targetFileDir.exists())
targetFileDir.mkdir();
char filename[128]; char filename[128];
snprintf(filename, 128, "%s%dx%dx%d.sch", snprintf(
initData->name, filename, 128, "%s%dx%dx%d.sch",
(initData->endX - initData->startX + 1), initData->name,
(initData->endY - initData->startY + 1), (initData->endX - initData->startX + 1),
(initData->endZ - initData->startZ + 1)); (initData->endY - initData->startY + 1),
(initData->endZ - initData->startZ + 1));
File dataFile = File dataFile =
File(targetFileDir, std::string(filename)); File(targetFileDir, std::string(filename));
if (dataFile.exists()) dataFile._delete(); if (dataFile.exists()) dataFile._delete();
FileOutputStream fos = FileOutputStream(dataFile); FileOutputStream fos = FileOutputStream(dataFile);
DataOutputStream dos = DataOutputStream(&fos); DataOutputStream dos = DataOutputStream(&fos);
ConsoleSchematicFile::generateSchematicFile( ConsoleSchematicFile::generateSchematicFile(
&dos, levels[0], initData->startX, &dos, levels[0], initData->startX,
initData->startY, initData->startZ, initData->startY, initData->startZ,
initData->endX, initData->endY, initData->endZ, initData->endX, initData->endY,
initData->bSaveMobs, initData->compressionType); initData->endZ, initData->bSaveMobs,
dos.close(); initData->compressionType);
dos.close();
delete initData; // owned unique_ptr is destroyed when the
// payload is overwritten on the next setXuiServerAction
}
} }
gameServices().unlockSaveNotification(); gameServices().unlockSaveNotification();
#endif #endif
@ -1344,26 +1358,27 @@ void MinecraftServer::run(int64_t seed, void* lpParameter) {
case eXuiServerAction_SetCameraLocation: case eXuiServerAction_SetCameraLocation:
#if !defined(_CONTENT_PACKAGE) #if !defined(_CONTENT_PACKAGE)
{ {
auto* owned = std::get_if<
std::unique_ptr<minecraft::XuiActionOwnedPayload>>(
&param);
DebugSetCameraPosition* pos = DebugSetCameraPosition* pos =
(DebugSetCameraPosition*)param; owned ? dynamic_cast<DebugSetCameraPosition*>(
owned->get())
: nullptr;
if (pos) {
Log::info("DEBUG: Player=%i\n", pos->player);
Log::info(
"DEBUG: Teleporting to pos=(%f.2, %f.2, %f.2), "
"looking at=(%f.2,%f.2)\n",
pos->m_camX, pos->m_camY, pos->m_camZ,
pos->m_yRot, pos->m_elev);
Log::info("DEBUG: Player=%i\n", pos->player); std::shared_ptr<ServerPlayer> player =
Log::info( players->players.at(pos->player);
"DEBUG: Teleporting to pos=(%f.2, %f.2, %f.2), " player->debug_setPosition(pos->m_camX, pos->m_camY,
"looking at=(%f.2,%f.2)\n", pos->m_camZ, pos->m_yRot,
pos->m_camX, pos->m_camY, pos->m_camZ, pos->m_yRot, pos->m_elev);
pos->m_elev); }
std::shared_ptr<ServerPlayer> player =
players->players.at(pos->player);
player->debug_setPosition(pos->m_camX, pos->m_camY,
pos->m_camZ, pos->m_yRot,
pos->m_elev);
// Doesn't work
// player->setYHeadRot(pos->m_yRot);
// player->absMoveTo(pos->m_camX, pos->m_camY,
// pos->m_camZ, pos->m_yRot, pos->m_elev);
} }
#endif #endif
break; break;