Merge branch 'master' into ChangeToPolarSSL.
This commit is contained in:
commit
98976de071
@ -1,24 +0,0 @@
|
|||||||
|
|
||||||
cmake_minimum_required (VERSION 2.6)
|
|
||||||
project (MCServer)
|
|
||||||
|
|
||||||
# NOTE: This CMake file is processed only for Unix builds; Windows(MSVC) builds handle all the subfolders in /src in a single file, /src/CMakeLists.txt
|
|
||||||
|
|
||||||
include_directories ("${PROJECT_SOURCE_DIR}/../")
|
|
||||||
|
|
||||||
ADD_CUSTOM_COMMAND(
|
|
||||||
# add any new generated bindings here
|
|
||||||
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings.h
|
|
||||||
|
|
||||||
# command execuded to regerate bindings
|
|
||||||
COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
|
||||||
|
|
||||||
# add any new generation dependencies here
|
|
||||||
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/virtual_method_hooks.lua ${CMAKE_CURRENT_SOURCE_DIR}/AllToLua.pkg tolua
|
|
||||||
)
|
|
||||||
|
|
||||||
#add cpp files here
|
|
||||||
add_library(Bindings PluginManager LuaState WebPlugin Bindings ManualBindings LuaWindow Plugin PluginLua WebPlugin)
|
|
||||||
|
|
||||||
target_link_libraries(Bindings lua sqlite tolualib)
|
|
@ -1740,7 +1740,7 @@ bool cPluginManager::DoWithPlugin(const AString & a_PluginName, cPluginCallback
|
|||||||
{
|
{
|
||||||
// TODO: Implement locking for plugins
|
// TODO: Implement locking for plugins
|
||||||
PluginMap::iterator itr = m_Plugins.find(a_PluginName);
|
PluginMap::iterator itr = m_Plugins.find(a_PluginName);
|
||||||
if (itr == m_Plugins.end())
|
if ((itr == m_Plugins.end()) || (itr->second == NULL))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -151,9 +151,13 @@ void cCommandBlockEntity::SendTo(cClientHandle & a_Client)
|
|||||||
|
|
||||||
bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value)
|
bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value)
|
||||||
{
|
{
|
||||||
m_Command = a_Value.get("Command", "").asString();
|
m_PosX = a_Value.get("x", 0).asInt();
|
||||||
|
m_PosY = a_Value.get("y", 0).asInt();
|
||||||
|
m_PosZ = a_Value.get("z", 0).asInt();
|
||||||
|
|
||||||
|
m_Command = a_Value.get("Command", "").asString();
|
||||||
m_LastOutput = a_Value.get("LastOutput", "").asString();
|
m_LastOutput = a_Value.get("LastOutput", "").asString();
|
||||||
|
m_Result = a_Value.get("SuccessCount", 0).asInt();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -164,9 +168,13 @@ bool cCommandBlockEntity::LoadFromJson(const Json::Value & a_Value)
|
|||||||
|
|
||||||
void cCommandBlockEntity::SaveToJson(Json::Value & a_Value)
|
void cCommandBlockEntity::SaveToJson(Json::Value & a_Value)
|
||||||
{
|
{
|
||||||
a_Value["Command"] = m_Command;
|
a_Value["x"] = m_PosX;
|
||||||
|
a_Value["y"] = m_PosY;
|
||||||
|
a_Value["z"] = m_PosZ;
|
||||||
|
|
||||||
|
a_Value["Command"] = m_Command;
|
||||||
a_Value["LastOutput"] = m_LastOutput;
|
a_Value["LastOutput"] = m_LastOutput;
|
||||||
|
a_Value["SuccessCount"] = m_Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -175,18 +183,24 @@ void cCommandBlockEntity::SaveToJson(Json::Value & a_Value)
|
|||||||
|
|
||||||
void cCommandBlockEntity::Execute()
|
void cCommandBlockEntity::Execute()
|
||||||
{
|
{
|
||||||
|
if (m_World != NULL)
|
||||||
|
{
|
||||||
|
if (!m_World->AreCommandBlocksEnabled())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class CommandBlockOutCb :
|
class CommandBlockOutCb :
|
||||||
public cCommandOutputCallback
|
public cCommandOutputCallback
|
||||||
{
|
{
|
||||||
cCommandBlockEntity* m_CmdBlock;
|
cCommandBlockEntity * m_CmdBlock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CommandBlockOutCb(cCommandBlockEntity* a_CmdBlock) : m_CmdBlock(a_CmdBlock) {}
|
CommandBlockOutCb(cCommandBlockEntity * a_CmdBlock) : m_CmdBlock(a_CmdBlock) {}
|
||||||
|
|
||||||
virtual void Out(const AString & a_Text)
|
virtual void Out(const AString & a_Text)
|
||||||
{
|
{
|
||||||
ASSERT(m_CmdBlock != NULL);
|
|
||||||
|
|
||||||
// Overwrite field
|
// Overwrite field
|
||||||
m_CmdBlock->SetLastOutput(a_Text);
|
m_CmdBlock->SetLastOutput(a_Text);
|
||||||
}
|
}
|
||||||
@ -194,7 +208,7 @@ void cCommandBlockEntity::Execute()
|
|||||||
|
|
||||||
LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str());
|
LOGD("cCommandBlockEntity: Executing command %s", m_Command.c_str());
|
||||||
|
|
||||||
cServer* Server = cRoot::Get()->GetServer();
|
cServer * Server = cRoot::Get()->GetServer();
|
||||||
|
|
||||||
Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb);
|
Server->ExecuteConsoleCommand(m_Command, CmdBlockOutCb);
|
||||||
|
|
||||||
|
@ -6,12 +6,67 @@ include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/")
|
|||||||
include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/jsoncpp/include")
|
include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/jsoncpp/include")
|
||||||
include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include")
|
include_directories (SYSTEM "${PROJECT_SOURCE_DIR}/../lib/polarssl/include")
|
||||||
|
|
||||||
set(FOLDERS OSSupport HTTPServer Bindings Items Blocks Protocol Generating)
|
set(FOLDERS OSSupport HTTPServer Items Blocks Protocol Generating)
|
||||||
set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities)
|
set(FOLDERS ${FOLDERS} WorldStorage Mobs Entities Simulator UI BlockEntities)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (NOT MSVC)
|
if (NOT MSVC)
|
||||||
|
|
||||||
|
#Bindings needs to reference other folders so are done here
|
||||||
|
|
||||||
|
#lib dependecies are not included
|
||||||
|
|
||||||
|
set(BINDING_DEPENDECIES ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/virtual_method_hooks.lua)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/AllToLua.pkg)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} ChunkDef.h BiomeDef.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} OSSupport/File.h Bindings/LuaFunctions.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Bindings/PluginManager.h Bindings/Plugin.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Bindings/PluginLua.h Bindings/WebPlugin.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Bindings/LuaWindow.h BlockID.h StringUtils.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Defines.h ChatColor.h ClientHandle.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Entities/Entity.h Entities/Floater.h )
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Entities/Pawn.h Entities/Player.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Entities/Pickup.h Entities/ProjectileEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Entities/TNTEntity.h Entities/Effects.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Server.h World.h Inventory.h Enchantments.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Item.h ItemGrid.h BlockEntities/BlockEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/BlockEntityWithItems.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/ChestEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/DropSpenserEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/DispenserEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/DropperEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/FurnaceEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/HopperEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/JukeboxEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/NoteEntity.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockEntities/SignEntity.h WebAdmin.h Root.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Vector3f.h Vector3d.h Vector3i.h Matrix4f.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} Cuboid.h BoundingBox.h Tracer.h Group.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} BlockArea.h Generating/ChunkDesc.h)
|
||||||
|
set(BINDING_DEPENDECIES ${BINDING_DEPENDECIES} CraftingRecipes.h UI/Window.h Mobs/Monster.h)
|
||||||
|
|
||||||
|
include_directories(Bindings)
|
||||||
|
include_directories(.)
|
||||||
|
|
||||||
|
ADD_CUSTOM_COMMAND(
|
||||||
|
# add any new generated bindings here
|
||||||
|
OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.cpp ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/Bindings.h
|
||||||
|
|
||||||
|
# command execuded to regerate bindings
|
||||||
|
COMMAND tolua -L virtual_method_hooks.lua -o Bindings.cpp -H Bindings.h AllToLua.pkg
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/Bindings/
|
||||||
|
|
||||||
|
# add any new generation dependencies here
|
||||||
|
DEPENDS ${BINDING_DEPENDECIES}
|
||||||
|
)
|
||||||
|
#add cpp files here
|
||||||
|
add_library(Bindings Bindings/PluginManager Bindings/LuaState Bindings/WebPlugin Bindings/Bindings Bindings/ManualBindings Bindings/LuaWindow Bindings/Plugin Bindings/PluginLua Bindings/WebPlugin)
|
||||||
|
|
||||||
|
target_link_libraries(Bindings lua sqlite tolualib)
|
||||||
|
|
||||||
|
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "Bindings.cpp Bindings.h")
|
||||||
|
|
||||||
foreach(folder ${FOLDERS})
|
foreach(folder ${FOLDERS})
|
||||||
add_subdirectory(${folder})
|
add_subdirectory(${folder})
|
||||||
endforeach(folder)
|
endforeach(folder)
|
||||||
@ -45,6 +100,7 @@ else ()
|
|||||||
|
|
||||||
# Add all subfolders as solution-folders:
|
# Add all subfolders as solution-folders:
|
||||||
list(APPEND FOLDERS "Resources")
|
list(APPEND FOLDERS "Resources")
|
||||||
|
list(APPEND FOLDERS "Bindings")
|
||||||
function(includefolder PATH)
|
function(includefolder PATH)
|
||||||
FILE(GLOB FOLDER_FILES
|
FILE(GLOB FOLDER_FILES
|
||||||
"${PATH}/*.cpp"
|
"${PATH}/*.cpp"
|
||||||
|
@ -610,25 +610,18 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class cUpdateCommandBlock :
|
|
||||||
public cCommandBlockCallback
|
|
||||||
{
|
|
||||||
AString m_Command;
|
|
||||||
public:
|
|
||||||
cUpdateCommandBlock(const AString & a_Command) : m_Command(a_Command) {}
|
|
||||||
|
|
||||||
virtual bool Item(cCommandBlockEntity * a_CommandBlock) override
|
|
||||||
{
|
|
||||||
a_CommandBlock->SetCommand(m_Command);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} CmdBlockCB (Command);
|
|
||||||
|
|
||||||
cWorld * World = m_Player->GetWorld();
|
cWorld * World = m_Player->GetWorld();
|
||||||
|
|
||||||
World->DoWithCommandBlockAt(BlockX, BlockY, BlockZ, CmdBlockCB);
|
if (World->AreCommandBlocksEnabled())
|
||||||
|
{
|
||||||
|
World->SetCommandBlockCommand(BlockX, BlockY, BlockZ, Command);
|
||||||
|
|
||||||
SendChat(Printf("%s[INFO]%s Successfully set command block command", cChatColor::Green.c_str(), cChatColor::White.c_str()));
|
SendChat(Printf("%s[INFO]%s Successfully set command block command", cChatColor::Green.c_str(), cChatColor::White.c_str()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendChat(Printf("%s[INFO]%s Command blocks are not enabled on this server", cChatColor::Green.c_str(), cChatColor::White.c_str()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,9 +37,9 @@ enum
|
|||||||
{
|
{
|
||||||
PACKET_WINDOW_OPEN = 0x64,
|
PACKET_WINDOW_OPEN = 0x64,
|
||||||
PACKET_PARTICLE_EFFECT = 0x3F,
|
PACKET_PARTICLE_EFFECT = 0x3F,
|
||||||
PACKET_SCOREBOARD_OBJECTIVE = 0x3B,
|
PACKET_SCOREBOARD_OBJECTIVE = 0xCE,
|
||||||
PACKET_SCORE_UPDATE = 0x3C,
|
PACKET_SCORE_UPDATE = 0xCF,
|
||||||
PACKET_DISPLAY_OBJECTIVE = 0x3D
|
PACKET_DISPLAY_OBJECTIVE = 0xD0
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,6 +22,8 @@
|
|||||||
#include "Entities/Player.h"
|
#include "Entities/Player.h"
|
||||||
#include "Entities/TNTEntity.h"
|
#include "Entities/TNTEntity.h"
|
||||||
|
|
||||||
|
#include "BlockEntities/CommandBlockEntity.h"
|
||||||
|
|
||||||
// Simulators:
|
// Simulators:
|
||||||
#include "Simulator/SimulatorManager.h"
|
#include "Simulator/SimulatorManager.h"
|
||||||
#include "Simulator/FloodyFluidSimulator.h"
|
#include "Simulator/FloodyFluidSimulator.h"
|
||||||
@ -523,7 +525,7 @@ void cWorld::Start(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_StorageSchema = IniFile.GetValueSet ("Storage", "Schema", m_StorageSchema);
|
m_StorageSchema = IniFile.GetValueSet ("Storage", "Schema", m_StorageSchema);
|
||||||
m_StorageCompressionFactor = IniFile.GetValueSetI ("Storage", "CompressionFactor", m_StorageCompressionFactor);
|
m_StorageCompressionFactor = IniFile.GetValueSetI("Storage", "CompressionFactor", m_StorageCompressionFactor);
|
||||||
m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3);
|
m_MaxCactusHeight = IniFile.GetValueSetI("Plants", "MaxCactusHeight", 3);
|
||||||
m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3);
|
m_MaxSugarcaneHeight = IniFile.GetValueSetI("Plants", "MaxSugarcaneHeight", 3);
|
||||||
m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false);
|
m_IsCactusBonemealable = IniFile.GetValueSetB("Plants", "IsCactusBonemealable", false);
|
||||||
@ -540,6 +542,7 @@ void cWorld::Start(void)
|
|||||||
m_bEnabledPVP = IniFile.GetValueSetB("PVP", "Enabled", true);
|
m_bEnabledPVP = IniFile.GetValueSetB("PVP", "Enabled", true);
|
||||||
m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", false);
|
m_IsDeepSnowEnabled = IniFile.GetValueSetB("Physics", "DeepSnow", false);
|
||||||
m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true);
|
m_ShouldLavaSpawnFire = IniFile.GetValueSetB("Physics", "ShouldLavaSpawnFire", true);
|
||||||
|
m_bCommandBlocksEnabled = IniFile.GetValueSetB("Mechanics", "CommandBlocksEnabled", false);
|
||||||
|
|
||||||
m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode);
|
m_GameMode = (eGameMode)IniFile.GetValueSetI("GameMode", "GameMode", m_GameMode);
|
||||||
|
|
||||||
@ -2611,6 +2614,28 @@ bool cWorld::UpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool cWorld::SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command)
|
||||||
|
{
|
||||||
|
class cUpdateCommandBlock : public cCommandBlockCallback
|
||||||
|
{
|
||||||
|
AString m_Command;
|
||||||
|
public:
|
||||||
|
cUpdateCommandBlock(const AString & a_Command) : m_Command(a_Command) {}
|
||||||
|
|
||||||
|
virtual bool Item(cCommandBlockEntity * a_CommandBlock) override
|
||||||
|
{
|
||||||
|
a_CommandBlock->SetCommand(m_Command);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} CmdBlockCB (a_Command);
|
||||||
|
|
||||||
|
return DoWithCommandBlockAt(a_BlockX, a_BlockY, a_BlockZ, CmdBlockCB);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void cWorld::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay)
|
void cWorld::ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay)
|
||||||
{
|
{
|
||||||
m_ChunkMap->ChunksStay(a_Chunks, a_Stay);
|
m_ChunkMap->ChunksStay(a_Chunks, a_Stay);
|
||||||
|
@ -296,6 +296,9 @@ public:
|
|||||||
/** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be NULL. Returns true if sign text changed. Same as SetSignLines() */
|
/** Sets the sign text, asking plugins for permission first. a_Player is the player who this change belongs to, may be NULL. Returns true if sign text changed. Same as SetSignLines() */
|
||||||
bool UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = NULL); // Exported in ManualBindings.cpp
|
bool UpdateSign(int a_X, int a_Y, int a_Z, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4, cPlayer * a_Player = NULL); // Exported in ManualBindings.cpp
|
||||||
|
|
||||||
|
/** Sets the command block command. Returns true if command changed. */
|
||||||
|
bool SetCommandBlockCommand(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Command); // tolua_export
|
||||||
|
|
||||||
/** Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable. To be used only by cChunkStay! */
|
/** Marks (a_Stay == true) or unmarks (a_Stay == false) chunks as non-unloadable. To be used only by cChunkStay! */
|
||||||
void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true);
|
void ChunksStay(const cChunkCoordsList & a_Chunks, bool a_Stay = true);
|
||||||
|
|
||||||
@ -512,6 +515,10 @@ public:
|
|||||||
/// Returns the associated scoreboard instance
|
/// Returns the associated scoreboard instance
|
||||||
cScoreboard & GetScoreBoard(void) { return m_Scoreboard; }
|
cScoreboard & GetScoreBoard(void) { return m_Scoreboard; }
|
||||||
|
|
||||||
|
bool AreCommandBlocksEnabled(void) const { return m_bCommandBlocksEnabled; }
|
||||||
|
|
||||||
|
void SetCommandBlocksEnabled(bool a_Flag) { m_bCommandBlocksEnabled = a_Flag; }
|
||||||
|
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
||||||
inline static void AbsoluteToRelative( int & a_X, int & a_Y, int & a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ )
|
inline static void AbsoluteToRelative( int & a_X, int & a_Y, int & a_Z, int & a_ChunkX, int & a_ChunkY, int & a_ChunkZ )
|
||||||
@ -775,6 +782,8 @@ private:
|
|||||||
bool m_IsSaplingBonemealable;
|
bool m_IsSaplingBonemealable;
|
||||||
bool m_IsSugarcaneBonemealable;
|
bool m_IsSugarcaneBonemealable;
|
||||||
|
|
||||||
|
bool m_bCommandBlocksEnabled;
|
||||||
|
|
||||||
cCriticalSection m_CSFastSetBlock;
|
cCriticalSection m_CSFastSetBlock;
|
||||||
sSetBlockList m_FastSetBlockQueue;
|
sSetBlockList m_FastSetBlockQueue;
|
||||||
|
|
||||||
|
@ -666,6 +666,7 @@ void cNBTChunkSerializer::BlockEntity(cBlockEntity * a_Entity)
|
|||||||
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
case E_BLOCK_NOTE_BLOCK: AddNoteEntity ((cNoteEntity *) a_Entity); break;
|
||||||
case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
|
case E_BLOCK_JUKEBOX: AddJukeboxEntity ((cJukeboxEntity *) a_Entity); break;
|
||||||
case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *) a_Entity); break;
|
case E_BLOCK_COMMAND_BLOCK: AddCommandBlockEntity((cCommandBlockEntity *) a_Entity); break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
ASSERT(!"Unhandled block entity saved into Anvil");
|
ASSERT(!"Unhandled block entity saved into Anvil");
|
||||||
|
@ -13,11 +13,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define SCOREBOARD_INFLATE_MAX 16 KiB
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cScoreboardSerializer::cScoreboardSerializer(const AString & a_WorldName, cScoreboard* a_ScoreBoard)
|
cScoreboardSerializer::cScoreboardSerializer(const AString & a_WorldName, cScoreboard* a_ScoreBoard)
|
||||||
: m_ScoreBoard(a_ScoreBoard)
|
: m_ScoreBoard(a_ScoreBoard)
|
||||||
@ -37,37 +32,25 @@ cScoreboardSerializer::cScoreboardSerializer(const AString & a_WorldName, cScore
|
|||||||
bool cScoreboardSerializer::Load(void)
|
bool cScoreboardSerializer::Load(void)
|
||||||
{
|
{
|
||||||
cFile File;
|
cFile File;
|
||||||
|
if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmRead))
|
||||||
if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmReadWrite))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AString Data;
|
AString Data;
|
||||||
|
|
||||||
File.ReadRestOfFile(Data);
|
File.ReadRestOfFile(Data);
|
||||||
|
|
||||||
File.Close();
|
File.Close();
|
||||||
|
|
||||||
char Uncompressed[SCOREBOARD_INFLATE_MAX];
|
AString Uncompressed;
|
||||||
z_stream strm;
|
int res = UncompressStringGZIP(Data.data(), Data.size(), Uncompressed);
|
||||||
strm.zalloc = (alloc_func)NULL;
|
|
||||||
strm.zfree = (free_func)NULL;
|
if (res != Z_OK)
|
||||||
strm.opaque = NULL;
|
|
||||||
inflateInit(&strm);
|
|
||||||
strm.next_out = (Bytef *)Uncompressed;
|
|
||||||
strm.avail_out = sizeof(Uncompressed);
|
|
||||||
strm.next_in = (Bytef *)Data.data();
|
|
||||||
strm.avail_in = Data.size();
|
|
||||||
int res = inflate(&strm, Z_FINISH);
|
|
||||||
inflateEnd(&strm);
|
|
||||||
if (res != Z_STREAM_END)
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parse the NBT data:
|
// Parse the NBT data:
|
||||||
cParsedNBT NBT(Uncompressed, strm.total_out);
|
cParsedNBT NBT(Uncompressed.data(), Uncompressed.size());
|
||||||
if (!NBT.IsValid())
|
if (!NBT.IsValid())
|
||||||
{
|
{
|
||||||
// NBT Parsing failed
|
// NBT Parsing failed
|
||||||
@ -85,11 +68,8 @@ bool cScoreboardSerializer::Save(void)
|
|||||||
{
|
{
|
||||||
cFastNBTWriter Writer;
|
cFastNBTWriter Writer;
|
||||||
|
|
||||||
Writer.BeginCompound("");
|
|
||||||
m_ScoreBoard->RegisterObjective("test","test",cObjective::E_TYPE_DUMMY)->AddScore("dot", 2);
|
|
||||||
SaveScoreboardToNBT(Writer);
|
SaveScoreboardToNBT(Writer);
|
||||||
|
|
||||||
Writer.EndCompound();
|
|
||||||
Writer.Finish();
|
Writer.Finish();
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
@ -97,12 +77,22 @@ bool cScoreboardSerializer::Save(void)
|
|||||||
ASSERT(TestParse.IsValid());
|
ASSERT(TestParse.IsValid());
|
||||||
#endif // _DEBUG
|
#endif // _DEBUG
|
||||||
|
|
||||||
gzFile gz = gzopen((FILE_IO_PREFIX + m_Path).c_str(), "wb");
|
cFile File;
|
||||||
if (gz != NULL)
|
if (!File.Open(FILE_IO_PREFIX + m_Path, cFile::fmWrite))
|
||||||
{
|
{
|
||||||
gzwrite(gz, Writer.GetResult().data(), Writer.GetResult().size());
|
return false;
|
||||||
}
|
}
|
||||||
gzclose(gz);
|
|
||||||
|
AString Compressed;
|
||||||
|
int res = CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed);
|
||||||
|
|
||||||
|
if (res != Z_OK)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File.Write(Compressed.data(), Compressed.size());
|
||||||
|
File.Close();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -113,7 +103,8 @@ bool cScoreboardSerializer::Save(void)
|
|||||||
|
|
||||||
void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
||||||
{
|
{
|
||||||
a_Writer.BeginCompound("Data");
|
a_Writer.BeginCompound("data");
|
||||||
|
|
||||||
a_Writer.BeginList("Objectives", TAG_Compound);
|
a_Writer.BeginList("Objectives", TAG_Compound);
|
||||||
|
|
||||||
for (cScoreboard::cObjectiveMap::const_iterator it = m_ScoreBoard->m_Objectives.begin(); it != m_ScoreBoard->m_Objectives.end(); ++it)
|
for (cScoreboard::cObjectiveMap::const_iterator it = m_ScoreBoard->m_Objectives.begin(); it != m_ScoreBoard->m_Objectives.end(); ++it)
|
||||||
@ -130,7 +121,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
|||||||
a_Writer.EndCompound();
|
a_Writer.EndCompound();
|
||||||
}
|
}
|
||||||
|
|
||||||
a_Writer.EndList();
|
a_Writer.EndList(); // Objectives
|
||||||
|
|
||||||
a_Writer.BeginList("PlayerScores", TAG_Compound);
|
a_Writer.BeginList("PlayerScores", TAG_Compound);
|
||||||
|
|
||||||
@ -151,7 +142,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a_Writer.EndList();
|
a_Writer.EndList(); // PlayerScores
|
||||||
|
|
||||||
a_Writer.BeginList("Teams", TAG_Compound);
|
a_Writer.BeginList("Teams", TAG_Compound);
|
||||||
|
|
||||||
@ -182,8 +173,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
|||||||
a_Writer.EndCompound();
|
a_Writer.EndCompound();
|
||||||
}
|
}
|
||||||
|
|
||||||
a_Writer.EndList();
|
a_Writer.EndList(); // Teams
|
||||||
a_Writer.EndCompound();
|
|
||||||
|
|
||||||
a_Writer.BeginCompound("DisplaySlots");
|
a_Writer.BeginCompound("DisplaySlots");
|
||||||
|
|
||||||
@ -196,7 +186,9 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
|||||||
Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_NAME);
|
Objective = m_ScoreBoard->GetObjectiveIn(cScoreboard::E_DISPLAY_SLOT_NAME);
|
||||||
a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName());
|
a_Writer.AddString("slot_2", (Objective == NULL) ? "" : Objective->GetName());
|
||||||
|
|
||||||
a_Writer.EndCompound();
|
a_Writer.EndCompound(); // DisplaySlots
|
||||||
|
|
||||||
|
a_Writer.EndCompound(); // Data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -205,7 +197,7 @@ void cScoreboardSerializer::SaveScoreboardToNBT(cFastNBTWriter & a_Writer)
|
|||||||
|
|
||||||
bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT)
|
bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT)
|
||||||
{
|
{
|
||||||
int Data = a_NBT.FindChildByName(0, "Data");
|
int Data = a_NBT.FindChildByName(0, "data");
|
||||||
if (Data < 0)
|
if (Data < 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -347,7 +339,7 @@ bool cScoreboardSerializer::LoadScoreboardFromNBT(const cParsedNBT & a_NBT)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int DisplaySlots = a_NBT.FindChildByName(0, "DisplaySlots");
|
int DisplaySlots = a_NBT.FindChildByName(Data, "DisplaySlots");
|
||||||
if (DisplaySlots < 0)
|
if (DisplaySlots < 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "json/json.h"
|
#include "json/json.h"
|
||||||
#include "../StringCompression.h"
|
#include "../StringCompression.h"
|
||||||
#include "../BlockEntities/ChestEntity.h"
|
#include "../BlockEntities/ChestEntity.h"
|
||||||
|
#include "../BlockEntities/CommandBlockEntity.h"
|
||||||
#include "../BlockEntities/DispenserEntity.h"
|
#include "../BlockEntities/DispenserEntity.h"
|
||||||
#include "../BlockEntities/FurnaceEntity.h"
|
#include "../BlockEntities/FurnaceEntity.h"
|
||||||
#include "../BlockEntities/JukeboxEntity.h"
|
#include "../BlockEntities/JukeboxEntity.h"
|
||||||
@ -79,6 +80,7 @@ void cJsonChunkSerializer::BlockEntity(cBlockEntity * a_BlockEntity)
|
|||||||
case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break;
|
case E_BLOCK_WALLSIGN: SaveInto = "Signs"; break;
|
||||||
case E_BLOCK_NOTE_BLOCK: SaveInto = "Notes"; break;
|
case E_BLOCK_NOTE_BLOCK: SaveInto = "Notes"; break;
|
||||||
case E_BLOCK_JUKEBOX: SaveInto = "Jukeboxes"; break;
|
case E_BLOCK_JUKEBOX: SaveInto = "Jukeboxes"; break;
|
||||||
|
case E_BLOCK_COMMAND_BLOCK: SaveInto = "CommandBlocks"; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
@ -263,126 +265,114 @@ bool cWSSCompact::EraseChunkData(const cChunkCoords & a_Chunk)
|
|||||||
|
|
||||||
void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World)
|
void cWSSCompact::LoadEntitiesFromJson(Json::Value & a_Value, cEntityList & a_Entities, cBlockEntityList & a_BlockEntities, cWorld * a_World)
|
||||||
{
|
{
|
||||||
// Load chests
|
// Load chests:
|
||||||
Json::Value AllChests = a_Value.get("Chests", Json::nullValue);
|
Json::Value AllChests = a_Value.get("Chests", Json::nullValue);
|
||||||
if (!AllChests.empty())
|
if (!AllChests.empty())
|
||||||
{
|
{
|
||||||
for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr )
|
for (Json::Value::iterator itr = AllChests.begin(); itr != AllChests.end(); ++itr )
|
||||||
{
|
{
|
||||||
Json::Value & Chest = *itr;
|
std::auto_ptr<cChestEntity> ChestEntity(new cChestEntity(0, 0, 0, a_World));
|
||||||
cChestEntity * ChestEntity = new cChestEntity(0,0,0, a_World);
|
if (!ChestEntity->LoadFromJson(*itr))
|
||||||
if (!ChestEntity->LoadFromJson( Chest ) )
|
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR READING CHEST FROM JSON!" );
|
LOGWARNING("ERROR READING CHEST FROM JSON!" );
|
||||||
delete ChestEntity;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_BlockEntities.push_back( ChestEntity );
|
a_BlockEntities.push_back(ChestEntity.release());
|
||||||
}
|
}
|
||||||
} // for itr - AllChests[]
|
} // for itr - AllChests[]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load dispensers
|
// Load dispensers:
|
||||||
Json::Value AllDispensers = a_Value.get("Dispensers", Json::nullValue);
|
Json::Value AllDispensers = a_Value.get("Dispensers", Json::nullValue);
|
||||||
if( !AllDispensers.empty() )
|
for (Json::Value::iterator itr = AllDispensers.begin(); itr != AllDispensers.end(); ++itr)
|
||||||
{
|
{
|
||||||
for( Json::Value::iterator itr = AllDispensers.begin(); itr != AllDispensers.end(); ++itr )
|
std::auto_ptr<cDispenserEntity> DispenserEntity(new cDispenserEntity(0, 0, 0, a_World));
|
||||||
|
if (!DispenserEntity->LoadFromJson(*itr))
|
||||||
{
|
{
|
||||||
Json::Value & Dispenser = *itr;
|
LOGWARNING("ERROR READING DISPENSER FROM JSON!" );
|
||||||
cDispenserEntity * DispenserEntity = new cDispenserEntity(0,0,0, a_World);
|
|
||||||
if( !DispenserEntity->LoadFromJson( Dispenser ) )
|
|
||||||
{
|
|
||||||
LOGERROR("ERROR READING DISPENSER FROM JSON!" );
|
|
||||||
delete DispenserEntity;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_BlockEntities.push_back( DispenserEntity );
|
a_BlockEntities.push_back(DispenserEntity.release());
|
||||||
}
|
}
|
||||||
} // for itr - AllDispensers[]
|
} // for itr - AllDispensers[]
|
||||||
}
|
|
||||||
|
|
||||||
// Load furnaces
|
// Load furnaces:
|
||||||
Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue);
|
Json::Value AllFurnaces = a_Value.get("Furnaces", Json::nullValue);
|
||||||
if( !AllFurnaces.empty() )
|
for (Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr)
|
||||||
{
|
{
|
||||||
for( Json::Value::iterator itr = AllFurnaces.begin(); itr != AllFurnaces.end(); ++itr )
|
|
||||||
{
|
|
||||||
Json::Value & Furnace = *itr;
|
|
||||||
// TODO: The block type and meta aren't correct, there's no way to get them here
|
// TODO: The block type and meta aren't correct, there's no way to get them here
|
||||||
cFurnaceEntity * FurnaceEntity = new cFurnaceEntity(0, 0, 0, E_BLOCK_FURNACE, 0, a_World);
|
std::auto_ptr<cFurnaceEntity> FurnaceEntity(new cFurnaceEntity(0, 0, 0, E_BLOCK_FURNACE, 0, a_World));
|
||||||
if (!FurnaceEntity->LoadFromJson(Furnace))
|
if (!FurnaceEntity->LoadFromJson(*itr))
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR READING FURNACE FROM JSON!" );
|
LOGWARNING("ERROR READING FURNACE FROM JSON!" );
|
||||||
delete FurnaceEntity;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_BlockEntities.push_back(FurnaceEntity);
|
a_BlockEntities.push_back(FurnaceEntity.release());
|
||||||
}
|
}
|
||||||
} // for itr - AllFurnaces[]
|
} // for itr - AllFurnaces[]
|
||||||
}
|
|
||||||
|
|
||||||
// Load signs
|
// Load signs:
|
||||||
Json::Value AllSigns = a_Value.get("Signs", Json::nullValue);
|
Json::Value AllSigns = a_Value.get("Signs", Json::nullValue);
|
||||||
if( !AllSigns.empty() )
|
for (Json::Value::iterator itr = AllSigns.begin(); itr != AllSigns.end(); ++itr)
|
||||||
{
|
{
|
||||||
for( Json::Value::iterator itr = AllSigns.begin(); itr != AllSigns.end(); ++itr )
|
std::auto_ptr<cSignEntity> SignEntity(new cSignEntity(E_BLOCK_SIGN_POST, 0, 0, 0, a_World));
|
||||||
|
if (!SignEntity->LoadFromJson(*itr))
|
||||||
{
|
{
|
||||||
Json::Value & Sign = *itr;
|
LOGWARNING("ERROR READING SIGN FROM JSON!");
|
||||||
cSignEntity * SignEntity = new cSignEntity( E_BLOCK_SIGN_POST, 0,0,0, a_World);
|
|
||||||
if ( !SignEntity->LoadFromJson( Sign ) )
|
|
||||||
{
|
|
||||||
LOGERROR("ERROR READING SIGN FROM JSON!" );
|
|
||||||
delete SignEntity;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_BlockEntities.push_back( SignEntity );
|
a_BlockEntities.push_back(SignEntity.release());
|
||||||
}
|
}
|
||||||
} // for itr - AllSigns[]
|
} // for itr - AllSigns[]
|
||||||
}
|
|
||||||
|
|
||||||
// Load note blocks
|
// Load note blocks:
|
||||||
Json::Value AllNotes = a_Value.get("Notes", Json::nullValue);
|
Json::Value AllNotes = a_Value.get("Notes", Json::nullValue);
|
||||||
if( !AllNotes.empty() )
|
|
||||||
{
|
|
||||||
for( Json::Value::iterator itr = AllNotes.begin(); itr != AllNotes.end(); ++itr )
|
for( Json::Value::iterator itr = AllNotes.begin(); itr != AllNotes.end(); ++itr )
|
||||||
{
|
{
|
||||||
Json::Value & Note = *itr;
|
std::auto_ptr<cNoteEntity> NoteEntity(new cNoteEntity(0, 0, 0, a_World));
|
||||||
cNoteEntity * NoteEntity = new cNoteEntity(0, 0, 0, a_World);
|
if (!NoteEntity->LoadFromJson(*itr))
|
||||||
if ( !NoteEntity->LoadFromJson( Note ) )
|
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR READING NOTE BLOCK FROM JSON!" );
|
LOGWARNING("ERROR READING NOTE BLOCK FROM JSON!" );
|
||||||
delete NoteEntity;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_BlockEntities.push_back( NoteEntity );
|
a_BlockEntities.push_back(NoteEntity.release());
|
||||||
}
|
}
|
||||||
} // for itr - AllNotes[]
|
} // for itr - AllNotes[]
|
||||||
}
|
|
||||||
|
|
||||||
// Load jukeboxes
|
// Load jukeboxes:
|
||||||
Json::Value AllJukeboxes = a_Value.get("Jukeboxes", Json::nullValue);
|
Json::Value AllJukeboxes = a_Value.get("Jukeboxes", Json::nullValue);
|
||||||
if( !AllJukeboxes.empty() )
|
|
||||||
{
|
|
||||||
for( Json::Value::iterator itr = AllJukeboxes.begin(); itr != AllJukeboxes.end(); ++itr )
|
for( Json::Value::iterator itr = AllJukeboxes.begin(); itr != AllJukeboxes.end(); ++itr )
|
||||||
{
|
{
|
||||||
Json::Value & Jukebox = *itr;
|
std::auto_ptr<cJukeboxEntity> JukeboxEntity(new cJukeboxEntity(0, 0, 0, a_World));
|
||||||
cJukeboxEntity * JukeboxEntity = new cJukeboxEntity(0, 0, 0, a_World);
|
if (!JukeboxEntity->LoadFromJson(*itr))
|
||||||
if ( !JukeboxEntity->LoadFromJson( Jukebox ) )
|
|
||||||
{
|
{
|
||||||
LOGERROR("ERROR READING JUKEBOX FROM JSON!" );
|
LOGWARNING("ERROR READING JUKEBOX FROM JSON!" );
|
||||||
delete JukeboxEntity;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_BlockEntities.push_back( JukeboxEntity );
|
a_BlockEntities.push_back(JukeboxEntity.release());
|
||||||
}
|
}
|
||||||
} // for itr - AllJukeboxes[]
|
} // for itr - AllJukeboxes[]
|
||||||
|
|
||||||
|
// Load command blocks:
|
||||||
|
Json::Value AllCommandBlocks = a_Value.get("CommandBlocks", Json::nullValue);
|
||||||
|
for( Json::Value::iterator itr = AllCommandBlocks.begin(); itr != AllCommandBlocks.end(); ++itr )
|
||||||
|
{
|
||||||
|
std::auto_ptr<cCommandBlockEntity> CommandBlockEntity(new cCommandBlockEntity(0, 0, 0, a_World));
|
||||||
|
if (!CommandBlockEntity->LoadFromJson(*itr))
|
||||||
|
{
|
||||||
|
LOGWARNING("ERROR READING COMMAND BLOCK FROM JSON!" );
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
a_BlockEntities.push_back(CommandBlockEntity.release());
|
||||||
|
}
|
||||||
|
} // for itr - AllCommandBlocks[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user