diff options
Diffstat (limited to 'src')
37 files changed, 832 insertions, 456 deletions
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp index 7b519a798..c9e7815ca 100644 --- a/src/Bindings/LuaState.cpp +++ b/src/Bindings/LuaState.cpp @@ -128,7 +128,7 @@ void cLuaState::Close(void) { LOGWARNING( "%s: Detected mis-use, calling Close() on an attached state (0x%p). Detaching instead.", - __FUNCTION__, m_LuaState + __FUNCTION__, static_cast<void *>(m_LuaState) ); Detach(); return; @@ -146,7 +146,7 @@ void cLuaState::Attach(lua_State * a_State) { if (m_LuaState != nullptr) { - LOGINFO("%s: Already contains a LuaState (0x%p), will be closed / detached.", __FUNCTION__, m_LuaState); + LOGINFO("%s: Already contains a LuaState (0x%p), will be closed / detached.", __FUNCTION__, static_cast<void *>(m_LuaState)); if (m_IsOwned) { Close(); @@ -174,7 +174,7 @@ void cLuaState::Detach(void) { LOGWARNING( "%s: Detected a mis-use, calling Detach() when the state is owned. Closing the owned state (0x%p).", - __FUNCTION__, m_LuaState + __FUNCTION__, static_cast<void *>(m_LuaState) ); Close(); return; @@ -676,6 +676,18 @@ void cLuaState::Push(int a_Value) +void cLuaState::Push(long a_Value) +{ + ASSERT(IsValid()); + + tolua_pushnumber(m_LuaState, static_cast<lua_Number>(a_Value)); + m_NumCurrentFunctionArgs += 1; +} + + + + + void cLuaState::Push(UInt32 a_Value) { ASSERT(IsValid()); diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h index 759fdc54f..269a10369 100644 --- a/src/Bindings/LuaState.h +++ b/src/Bindings/LuaState.h @@ -248,6 +248,7 @@ public: void Push(cLuaUDPEndpoint * a_UDPEndpoint); void Push(double a_Value); void Push(int a_Value); + void Push(long a_Value); void Push(const UInt32 a_Value); void Push(void * a_Ptr); void Push(std::chrono::milliseconds a_time); diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 876d4e280..7e6839fdf 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -482,8 +482,258 @@ cPluginLua * cManualBindings::GetLuaPlugin(lua_State * L) +static int tolua_cFile_ChangeFileExt(lua_State * tolua_S) +{ + // API signature: + // ChangeFileExt(string, string) -> string + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2, 3) || + !L.CheckParamEnd(4) + ) + { + return 0; + } + + // Execute: + AString FileName, NewExt; + ASSERT(L.GetStackValues(2, FileName, NewExt)); + L.Push(cFile::ChangeFileExt(FileName, NewExt)); + return 1; +} + + + + + +static int tolua_cFile_Copy(lua_State * tolua_S) +{ + // API signature: + // cFile:Copy(string, string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2, 3) || + !L.CheckParamEnd(4) + ) + { + return 0; + } + + // Execute: + AString SrcFile, DstFile; + ASSERT(L.GetStackValues(2, SrcFile, DstFile)); + L.Push(cFile::Copy(SrcFile, DstFile)); + return 1; +} + + + + + +static int tolua_cFile_CreateFolder(lua_State * tolua_S) +{ + // API signature: + // cFile:CreateFolder(string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString FolderPath; + ASSERT(L.GetStackValues(2, FolderPath)); + L.Push(cFile::CreateFolder(FolderPath)); + return 1; +} + + + + + +static int tolua_cFile_CreateFolderRecursive(lua_State * tolua_S) +{ + // API signature: + // cFile:CreateFolderRecursive(string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString FolderPath; + ASSERT(L.GetStackValues(2, FolderPath)); + L.Push(cFile::CreateFolderRecursive(FolderPath)); + return 1; +} + + + + + +static int tolua_cFile_Delete(lua_State * tolua_S) +{ + // API signature: + // cFile:Delete(string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::Delete(Path)); + return 1; +} + + + + + +static int tolua_cFile_DeleteFile(lua_State * tolua_S) +{ + // API signature: + // cFile:DeleteFile(string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::DeleteFile(Path)); + return 1; +} + + + + + +static int tolua_cFile_DeleteFolder(lua_State * tolua_S) +{ + // API signature: + // cFile:DeleteFolder(string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::DeleteFolder(Path)); + return 1; +} + + + + + +static int tolua_cFile_DeleteFolderContents(lua_State * tolua_S) +{ + // API signature: + // cFile:DeleteFolderContents(string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::DeleteFolderContents(Path)); + return 1; +} + + + + + +static int tolua_cFile_Exists(lua_State * tolua_S) +{ + // API signature: + // cFile:Exists(string) -> bool + + // Obsolete, use IsFile() or IsFolder() instead + cLuaState L(tolua_S); + LOGWARNING("cFile:Exists() is obsolete, use cFile:IsFolder() or cFile:IsFile() instead!"); + L.LogStackTrace(); + + // Check params: + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::Exists(Path)); + return 1; +} + + + + + static int tolua_cFile_GetFolderContents(lua_State * tolua_S) { + // API signature: + // cFile:GetFolderContents(string) -> {string, string, ...} + // Check params: cLuaState LuaState(tolua_S); if ( @@ -497,7 +747,7 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S) // Get params: AString Folder; - LuaState.GetStackValues(2, Folder); + ASSERT(LuaState.GetStackValues(2, Folder)); // Execute and push result: LuaState.Push(cFile::GetFolderContents(Folder)); @@ -508,8 +758,119 @@ static int tolua_cFile_GetFolderContents(lua_State * tolua_S) +static int tolua_cFile_GetLastModificationTime(lua_State * tolua_S) +{ + // API signature: + // cFile:GetLastModificationTime(string) -> number + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::GetLastModificationTime(Path)); + return 1; +} + + + + + +static int tolua_cFile_GetSize(lua_State * tolua_S) +{ + // API signature: + // cFile:GetSize(string) -> number + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::GetSize(Path)); + return 1; +} + + + + + +static int tolua_cFile_IsFile(lua_State * tolua_S) +{ + // API signature: + // cFile:IsFile(string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::IsFile(Path)); + return 1; +} + + + + + +static int tolua_cFile_IsFolder(lua_State * tolua_S) +{ + // API signature: + // cFile:IsFolder(string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2) || + !L.CheckParamEnd(3) + ) + { + return 0; + } + + // Execute: + AString Path; + ASSERT(L.GetStackValues(2, Path)); + L.Push(cFile::IsFolder(Path)); + return 1; +} + + + + + static int tolua_cFile_ReadWholeFile(lua_State * tolua_S) { + // API signature: + // cFile:ReadWholeFile(string) -> string + // Check params: cLuaState LuaState(tolua_S); if ( @@ -523,7 +884,7 @@ static int tolua_cFile_ReadWholeFile(lua_State * tolua_S) // Get params: AString FileName; - LuaState.GetStackValues(2, FileName); + ASSERT(LuaState.GetStackValues(2, FileName)); // Execute and push result: LuaState.Push(cFile::ReadWholeFile(FileName)); @@ -534,6 +895,33 @@ static int tolua_cFile_ReadWholeFile(lua_State * tolua_S) +static int tolua_cFile_Rename(lua_State * tolua_S) +{ + // API signature: + // cFile:Rename(string, string) -> bool + + // Check params: + cLuaState L(tolua_S); + if ( + !L.CheckParamUserTable(1, "cFile") || + !L.CheckParamString(2, 3) || + !L.CheckParamEnd(4) + ) + { + return 0; + } + + // Execute: + AString SrcPath, DstPath; + ASSERT(L.GetStackValues(2, SrcPath, DstPath)); + L.Push(cFile::Rename(SrcPath, DstPath)); + return 1; +} + + + + + static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S) { // API function no longer available: @@ -1151,7 +1539,7 @@ static int tolua_cPlayer_GetPermissions(lua_State * tolua_S) cPlayer * self = reinterpret_cast<cPlayer *>(tolua_tousertype(tolua_S, 1, nullptr)); if (self == nullptr) { - LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); + LOGWARNING("%s: invalid self (%p)", __FUNCTION__, static_cast<void *>(self)); return 0; } @@ -1182,7 +1570,7 @@ static int tolua_cPlayer_GetRestrictions(lua_State * tolua_S) cPlayer * self = reinterpret_cast<cPlayer *>(tolua_tousertype(tolua_S, 1, nullptr)); if (self == nullptr) { - LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); + LOGWARNING("%s: invalid self (%p)", __FUNCTION__, static_cast<void *>(self)); return 0; } @@ -1211,7 +1599,7 @@ static int tolua_cPlayer_OpenWindow(lua_State * tolua_S) cWindow * wnd = reinterpret_cast<cWindow *>(tolua_tousertype(tolua_S, 2, nullptr)); if ((self == nullptr) || (wnd == nullptr)) { - LOGWARNING("%s: invalid self (%p) or wnd (%p)", __FUNCTION__, self, wnd); + LOGWARNING("%s: invalid self (%p) or wnd (%p)", __FUNCTION__, static_cast<void *>(self), static_cast<void *>(wnd)); return 0; } @@ -1292,7 +1680,7 @@ static int tolua_SetObjectCallback(lua_State * tolua_S) OBJTYPE * self = reinterpret_cast<OBJTYPE *>(tolua_tousertype(tolua_S, 1, nullptr)); if (self == nullptr) { - LOGWARNING("%s: invalid self (%p)", __FUNCTION__, self); + LOGWARNING("%s: invalid self (%p)", __FUNCTION__, static_cast<void *>(self)); return 0; } int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX); // Store function reference for later retrieval @@ -2846,8 +3234,22 @@ void cManualBindings::Bind(lua_State * tolua_S) tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cFile"); - tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents); - tolua_function(tolua_S, "ReadWholeFile", tolua_cFile_ReadWholeFile); + tolua_function(tolua_S, "ChangeFileExt", tolua_cFile_ChangeFileExt); + tolua_function(tolua_S, "Copy", tolua_cFile_Copy); + tolua_function(tolua_S, "CreateFolder", tolua_cFile_CreateFolder); + tolua_function(tolua_S, "CreateFolderRecursive", tolua_cFile_CreateFolderRecursive); + tolua_function(tolua_S, "Delete", tolua_cFile_Delete); + tolua_function(tolua_S, "DeleteFile", tolua_cFile_DeleteFile); + tolua_function(tolua_S, "DeleteFolder", tolua_cFile_DeleteFolder); + tolua_function(tolua_S, "DeleteFolderContents", tolua_cFile_DeleteFolderContents); + tolua_function(tolua_S, "Exists", tolua_cFile_Exists); + tolua_function(tolua_S, "GetFolderContents", tolua_cFile_GetFolderContents); + tolua_function(tolua_S, "GetLastModificationTime", tolua_cFile_GetLastModificationTime); + tolua_function(tolua_S, "GetSize", tolua_cFile_GetSize); + tolua_function(tolua_S, "IsFile", tolua_cFile_IsFile); + tolua_function(tolua_S, "IsFolder", tolua_cFile_IsFolder); + tolua_function(tolua_S, "ReadWholeFile", tolua_cFile_ReadWholeFile); + tolua_function(tolua_S, "Rename", tolua_cFile_Rename); tolua_endmodule(tolua_S); tolua_beginmodule(tolua_S, "cHopperEntity"); diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h index 38f7ac5f1..e2556bafd 100644 --- a/src/Bindings/ManualBindings.h +++ b/src/Bindings/ManualBindings.h @@ -400,7 +400,7 @@ public: L.GetStackValues(1, Self, Box, FnRef); if ((Self == nullptr) || (Box == nullptr)) { - LOGWARNING("Invalid world (%p) or boundingbox (%p)", Self, Box); + LOGWARNING("Invalid world (%p) or boundingbox (%p)", static_cast<void *>(Self), static_cast<void *>(Box)); L.LogStackTrace(); return 0; } diff --git a/src/Bindings/ManualBindings_World.cpp b/src/Bindings/ManualBindings_World.cpp index e2902b81a..ba80d7130 100644 --- a/src/Bindings/ManualBindings_World.cpp +++ b/src/Bindings/ManualBindings_World.cpp @@ -110,6 +110,59 @@ static int tolua_cWorld_ChunkStay(lua_State * tolua_S) +static int tolua_cWorld_ForEachLoadedChunk(lua_State * tolua_S) +{ + // Exported manually, because tolua doesn't support converting functions to functor types. + // Function signature: ForEachLoadedChunk(callback) -> bool + + cLuaState L(tolua_S); + if ( + !L.CheckParamUserType(1, "cWorld") || + !L.CheckParamFunction(2) + ) + { + return 0; + } + + cPluginLua * Plugin = cManualBindings::GetLuaPlugin(tolua_S); + if (Plugin == nullptr) + { + return 0; + } + + // Read the params: + cWorld * World = reinterpret_cast<cWorld *>(tolua_tousertype(tolua_S, 1, nullptr)); + if (World == nullptr) + { + LOGWARNING("World:ForEachLoadedChunk(): invalid world parameter"); + L.LogStackTrace(); + return 0; + } + cLuaState::cRef FnRef; + L.GetStackValues(2, FnRef); + if (!FnRef.IsValid()) + { + return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #2"); + } + + // Call the enumeration: + bool ret = World->ForEachLoadedChunk( + [&L, &FnRef](int a_ChunkX, int a_ChunkZ) -> bool + { + bool res = false; // By default continue the enumeration + L.Call(FnRef, a_ChunkX, a_ChunkZ, cLuaState::Return, res); + return res; + } + ); + + // Push the return value: + L.Push(ret); + return 1; +} + + + + static int tolua_cWorld_GetBlockInfo(lua_State * tolua_S) { @@ -321,7 +374,6 @@ static int tolua_cWorld_PrepareChunk(lua_State * tolua_S) class cLuaWorldTask : - public cWorld::cTask, public cPluginLua::cResettable { public: @@ -331,11 +383,7 @@ public: { } -protected: - int m_FnRef; - - // cWorld::cTask overrides: - virtual void Run(cWorld & a_World) override + void Run(cWorld & a_World) { cCSLock Lock(m_CSPlugin); if (m_Plugin != nullptr) @@ -343,7 +391,10 @@ protected: m_Plugin->Call(m_FnRef, &a_World); } } -} ; + +protected: + int m_FnRef; +}; @@ -380,9 +431,9 @@ static int tolua_cWorld_QueueTask(lua_State * tolua_S) return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1"); } - auto task = std::make_shared<cLuaWorldTask>(*Plugin, FnRef); - Plugin->AddResettable(task); - self->QueueTask(task); + auto ResettableTask = std::make_shared<cLuaWorldTask>(*Plugin, FnRef); + Plugin->AddResettable(ResettableTask); + self->QueueTask(std::bind(&cLuaWorldTask::Run, ResettableTask, std::placeholders::_1)); return 0; } @@ -430,35 +481,6 @@ static int tolua_cWorld_SetSignLines(lua_State * tolua_S) -class cLuaScheduledWorldTask : - public cWorld::cTask, - public cPluginLua::cResettable -{ -public: - cLuaScheduledWorldTask(cPluginLua & a_Plugin, int a_FnRef) : - cPluginLua::cResettable(a_Plugin), - m_FnRef(a_FnRef) - { - } - -protected: - int m_FnRef; - - // cWorld::cTask overrides: - virtual void Run(cWorld & a_World) override - { - cCSLock Lock(m_CSPlugin); - if (m_Plugin != nullptr) - { - m_Plugin->Call(m_FnRef, &a_World); - } - } -}; - - - - - static int tolua_cWorld_ScheduleTask(lua_State * tolua_S) { // Binding for cWorld::ScheduleTask @@ -495,11 +517,9 @@ static int tolua_cWorld_ScheduleTask(lua_State * tolua_S) return cManualBindings::lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1"); } - int DelayTicks = static_cast<int>(tolua_tonumber(tolua_S, 2, 0)); - - auto task = std::make_shared<cLuaScheduledWorldTask>(*Plugin, FnRef); - Plugin->AddResettable(task); - World->ScheduleTask(DelayTicks, static_cast<cWorld::cTaskPtr>(task)); + auto ResettableTask = std::make_shared<cLuaWorldTask>(*Plugin, FnRef); + Plugin->AddResettable(ResettableTask); + World->ScheduleTask(static_cast<int>(tolua_tonumber(tolua_S, 2, 0)), std::bind(&cLuaWorldTask::Run, ResettableTask, std::placeholders::_1)); return 0; } @@ -580,6 +600,7 @@ void cManualBindings::BindWorld(lua_State * tolua_S) tolua_function(tolua_S, "ForEachEntityInChunk", ForEachInChunk<cWorld, cEntity, &cWorld::ForEachEntityInChunk>); tolua_function(tolua_S, "ForEachFurnaceInChunk", ForEachInChunk<cWorld, cFurnaceEntity, &cWorld::ForEachFurnaceInChunk>); tolua_function(tolua_S, "ForEachPlayer", ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>); + tolua_function(tolua_S, "ForEachLoadedChunk", tolua_cWorld_ForEachLoadedChunk); tolua_function(tolua_S, "GetBlockInfo", tolua_cWorld_GetBlockInfo); tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cWorld_GetBlockTypeMeta); tolua_function(tolua_S, "GetSignLines", tolua_cWorld_GetSignLines); diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 4344b36ac..1312103b8 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -14,8 +14,8 @@ #include "LuaState.h" // Names for the global variables through which the plugin is identified in its LuaState -#define LUA_PLUGIN_NAME_VAR_NAME "_MCServerInternal_PluginName" -#define LUA_PLUGIN_INSTANCE_VAR_NAME "_MCServerInternal_PluginInstance" +#define LUA_PLUGIN_NAME_VAR_NAME "_CuberiteInternal_PluginName" +#define LUA_PLUGIN_INSTANCE_VAR_NAME "_CuberiteInternal_PluginInstance" diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 026865f5b..72e031b33 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -1761,7 +1761,7 @@ bool cPluginManager::BindConsoleCommand(const AString & a_Command, cPlugin * a_P { if (cmd->second.m_Plugin == nullptr) { - LOGWARNING("Console command \"%s\" is already bound internally by MCServer, cannot bind in plugin \"%s\".", a_Command.c_str(), a_Plugin->GetName().c_str()); + LOGWARNING("Console command \"%s\" is already bound internally by Cuberite, cannot bind in plugin \"%s\".", a_Command.c_str(), a_Plugin->GetName().c_str()); } else { diff --git a/src/BiomeDef.h b/src/BiomeDef.h index 48726123c..0fad23100 100644 --- a/src/BiomeDef.h +++ b/src/BiomeDef.h @@ -16,7 +16,7 @@ // tolua_begin /** Biome IDs The first batch corresponds to the clientside biomes, used by MineCraft. -BiomeIDs over 255 are used by MCServer internally and are translated to MC biomes before sending them to client +BiomeIDs over 255 are used by Cuberite internally and are translated to MC biomes before sending them to client */ enum EMCSBiome { diff --git a/src/Blocks/BlockLilypad.h b/src/Blocks/BlockLilypad.h index b2fb69309..18a576017 100644 --- a/src/Blocks/BlockLilypad.h +++ b/src/Blocks/BlockLilypad.h @@ -23,6 +23,22 @@ public: UNUSED(a_Meta); return 7; } + + + virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override + { + if ((a_RelY < 1) || (a_RelY >= cChunkDef::Height)) + { + return false; + } + BLOCKTYPE UnderType; + NIBBLETYPE UnderMeta; + a_Chunk.GetBlockTypeMeta(a_RelX, a_RelY - 1, a_RelZ, UnderType, UnderMeta); + return ( + ((UnderType == E_BLOCK_STATIONARY_WATER) || (UnderType == E_BLOCK_WATER)) && // Water is below... + (UnderMeta == 0) // ... and it's a source + ); + } }; diff --git a/src/Blocks/BlockPiston.cpp b/src/Blocks/BlockPiston.cpp index 4e4814242..94782a7ed 100644 --- a/src/Blocks/BlockPiston.cpp +++ b/src/Blocks/BlockPiston.cpp @@ -27,7 +27,6 @@ } \ } -#define PISTON_TICK_DELAY 1 #define PISTON_MAX_PUSH_DISTANCE 12 @@ -156,15 +155,12 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, // Push blocks, from the furthest to the nearest: int oldx = a_BlockX, oldy = a_BlockY, oldz = a_BlockZ; NIBBLETYPE currBlockMeta; - std::vector<Vector3i> ScheduledBlocks; - ScheduledBlocks.reserve(PISTON_MAX_PUSH_DISTANCE); for (int i = dist + 1; i > 1; i--) { AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); a_World->GetBlockTypeMeta(a_BlockX, a_BlockY, a_BlockZ, currBlock, currBlockMeta); - a_World->SetBlock(oldx, oldy, oldz, currBlock, currBlockMeta, false); - ScheduledBlocks.push_back(Vector3i(oldx, oldy, oldz)); + a_World->SetBlock(oldx, oldy, oldz, currBlock, currBlockMeta); oldx = a_BlockX; oldy = a_BlockY; oldz = a_BlockZ; @@ -173,13 +169,11 @@ void cBlockPistonHandler::ExtendPiston(int a_BlockX, int a_BlockY, int a_BlockZ, int extx = a_BlockX; int exty = a_BlockY; int extz = a_BlockZ; - ScheduledBlocks.push_back(Vector3i(extx, exty, extz)); AddPistonDir(a_BlockX, a_BlockY, a_BlockZ, pistonMeta, -1); // "a_Block" now at piston body, "ext" at future extension a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, pistonBlock, pistonMeta | 0x8); - a_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0), false); - a_World->ScheduleTask(PISTON_TICK_DELAY, static_cast<cWorld::cTaskPtr>(std::make_shared<cWorld::cTaskSendBlockToAllPlayers>(ScheduledBlocks))); + a_World->SetBlock(extx, exty, extz, E_BLOCK_PISTON_EXTENSION, pistonMeta | (IsSticky(pistonBlock) ? 8 : 0)); } @@ -223,23 +217,14 @@ void cBlockPistonHandler::RetractPiston(int a_BlockX, int a_BlockY, int a_BlockZ if (CanPull(tempBlock, tempMeta)) { // Pull the block - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, tempBlock, tempMeta, false); - a_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0, false); - - std::vector<Vector3i> ScheduledBlocks; - ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); - ScheduledBlocks.push_back(Vector3i(tempx, tempy, tempz)); - a_World->ScheduleTask(PISTON_TICK_DELAY + 1, static_cast<cWorld::cTaskPtr>(std::make_shared<cWorld::cTaskSendBlockToAllPlayers>(ScheduledBlocks))); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, tempBlock, tempMeta); + a_World->SetBlock(tempx, tempy, tempz, E_BLOCK_AIR, 0); return; } } // Retract without pulling - a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0, false); - - std::vector<Vector3i> ScheduledBlocks; - ScheduledBlocks.push_back(Vector3i(a_BlockX, a_BlockY, a_BlockZ)); - a_World->ScheduleTask(PISTON_TICK_DELAY + 1, static_cast<cWorld::cTaskPtr>(std::make_shared<cWorld::cTaskSendBlockToAllPlayers>(ScheduledBlocks))); + a_World->SetBlock(a_BlockX, a_BlockY, a_BlockZ, E_BLOCK_AIR, 0); } diff --git a/src/Chunk.cpp b/src/Chunk.cpp index 7a6938b77..39a5a6053 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -490,7 +490,7 @@ void cChunk::CollectMobCensus(cMobCensus & toFill) { auto & Monster = reinterpret_cast<cMonster &>(*entity); currentPosition = Monster.GetPosition(); - for (const auto PlayerPos : PlayerPositions) + for (const auto & PlayerPos : PlayerPositions) { toFill.CollectMob(Monster, *this, (currentPosition - PlayerPos).SqrLength()); } diff --git a/src/ChunkDef.h b/src/ChunkDef.h index 7af0ef630..f6c0381db 100644 --- a/src/ChunkDef.h +++ b/src/ChunkDef.h @@ -68,8 +68,8 @@ public: /** The type used for any heightmap operations and storage; idx = x + Width * z; Height points to the highest non-air block in the column */ typedef HEIGHTTYPE HeightMap[Width * Width]; - /** The type used for any biomemap operations and storage inside MCServer, - using MCServer biomes (need not correspond to client representation!) + /** The type used for any biomemap operations and storage inside Cuberite, + using Cuberite biomes (need not correspond to client representation!) idx = x + Width * z */ typedef EMCSBiome BiomeMap[Width * Width]; diff --git a/src/ChunkMap.cpp b/src/ChunkMap.cpp index aeae8f350..a4771ce52 100644 --- a/src/ChunkMap.cpp +++ b/src/ChunkMap.cpp @@ -1723,7 +1723,7 @@ void cChunkMap::AddEntity(cEntity * a_Entity) ) { LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.", - a_Entity, a_Entity->GetClass(), a_Entity->GetUniqueID() + static_cast<void *>(a_Entity), a_Entity->GetClass(), a_Entity->GetUniqueID() ); return; } @@ -1744,7 +1744,7 @@ void cChunkMap::AddEntityIfNotPresent(cEntity * a_Entity) ) { LOGWARNING("Entity at %p (%s, ID %d) spawning in a non-existent chunk, the entity is lost.", - a_Entity, a_Entity->GetClass(), a_Entity->GetUniqueID() + static_cast<void *>(a_Entity), a_Entity->GetClass(), a_Entity->GetUniqueID() ); return; } @@ -2576,6 +2576,34 @@ bool cChunkMap::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinCh +bool cChunkMap::ForEachLoadedChunk(std::function<bool(int, int)> a_Callback) +{ + cCSLock Lock(m_CSLayers); + for (cChunkLayerList::const_iterator itr = m_Layers.begin(); itr != m_Layers.end(); ++itr) // iterate over ALL loaded layers + { + cChunkLayer * layer = *itr; + for (int x = 0; x < LAYER_SIZE; x++) + { + for (int z = 0; z < LAYER_SIZE; z++) + { + cChunkPtr p = layer->FindChunk(layer->GetX() * LAYER_SIZE + x, layer->GetZ() * LAYER_SIZE + z); + if ((p != nullptr) && p->IsValid()) // if chunk is loaded + { + if (a_Callback(p->GetPosX(), p->GetPosZ())) + { + return false; + } + } + } + } + } + return true; +} + + + + + bool cChunkMap::WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes) { // Convert block coords to chunks coords: diff --git a/src/ChunkMap.h b/src/ChunkMap.h index 4974671da..e9309dbd8 100644 --- a/src/ChunkMap.h +++ b/src/ChunkMap.h @@ -344,6 +344,9 @@ public: /** Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully */ bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback); + + /** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */ + bool ForEachLoadedChunk(std::function<bool(int, int)> a_Callback); /** Writes the block area into the specified coords. Returns true if all chunks have been processed. Prefer cBlockArea::Write() instead. */ bool WriteBlockArea(cBlockArea & a_Area, int a_MinBlockX, int a_MinBlockY, int a_MinBlockZ, int a_DataTypes); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 6c9e6a781..98005e934 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -95,7 +95,7 @@ cClientHandle::cClientHandle(const AString & a_IPString, int a_ViewDistance) : m_UniqueID = s_ClientCount; m_PingStartTime = std::chrono::steady_clock::now(); - LOGD("New ClientHandle created at %p", this); + LOGD("New ClientHandle created at %p", static_cast<void *>(this)); } @@ -106,7 +106,7 @@ cClientHandle::~cClientHandle() { ASSERT(m_State == csDestroyed); // Has Destroy() been called? - LOGD("Deleting client \"%s\" at %p", GetUsername().c_str(), this); + LOGD("Deleting client \"%s\" at %p", GetUsername().c_str(), static_cast<void *>(this)); { cCSLock Lock(m_CSChunkLists); @@ -140,7 +140,7 @@ cClientHandle::~cClientHandle() delete m_Protocol; m_Protocol = nullptr; - LOGD("ClientHandle at %p deleted", this); + LOGD("ClientHandle at %p deleted", static_cast<void *>(this)); } @@ -164,7 +164,7 @@ void cClientHandle::Destroy(void) } // DEBUG: - LOGD("%s: client %p, \"%s\"", __FUNCTION__, this, m_Username.c_str()); + LOGD("%s: client %p, \"%s\"", __FUNCTION__, static_cast<void *>(this), m_Username.c_str()); if ((m_Player != nullptr) && (m_Player->GetWorld() != nullptr)) { @@ -2935,7 +2935,7 @@ void cClientHandle::AddWantedChunk(int a_ChunkX, int a_ChunkZ) return; } - LOGD("Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ, this); + LOGD("Adding chunk [%d, %d] to wanted chunks for client %p", a_ChunkX, a_ChunkZ, static_cast<void *>(this)); cCSLock Lock(m_CSChunkLists); if (m_ChunksToSend.find(cChunkCoords(a_ChunkX, a_ChunkZ)) == m_ChunksToSend.end()) { diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 910ad4c0e..d35b92296 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -150,7 +150,7 @@ cPlayer::~cPlayer(void) LOGINFO("Player %s has left the game", GetName().c_str()); } - LOGD("Deleting cPlayer \"%s\" at %p, ID %d", GetName().c_str(), this, GetUniqueID()); + LOGD("Deleting cPlayer \"%s\" at %p, ID %d", GetName().c_str(), static_cast<void *>(this), GetUniqueID()); // Notify the server that the player is being destroyed cRoot::Get()->GetServer()->PlayerDestroying(this); @@ -162,7 +162,7 @@ cPlayer::~cPlayer(void) delete m_InventoryWindow; m_InventoryWindow = nullptr; - LOGD("Player %p deleted", this); + LOGD("Player %p deleted", static_cast<void *>(this)); } diff --git a/src/Globals.h b/src/Globals.h index a69a64452..2ee8574ba 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -225,7 +225,7 @@ template class SizeChecker<UInt8, 1>; #endif #if defined(ANDROID_NDK) - #define FILE_IO_PREFIX "/sdcard/mcserver/" + #define FILE_IO_PREFIX "/sdcard/Cuberite/" #else #define FILE_IO_PREFIX "" #endif diff --git a/src/HTTPServer/HTTPServer.cpp b/src/HTTPServer/HTTPServer.cpp index 7a6303b1f..bbff5d57a 100644 --- a/src/HTTPServer/HTTPServer.cpp +++ b/src/HTTPServer/HTTPServer.cpp @@ -83,7 +83,7 @@ class cDebugCallbacks : { if (!a_Request.HasAuth() || (a_Request.GetAuthUsername() != "a") || (a_Request.GetAuthPassword() != "b")) { - a_Connection.SendNeedAuth("MCServer WebAdmin"); + a_Connection.SendNeedAuth("Cuberite WebAdmin"); return; } } diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp index 3b6ed2147..ed10e648c 100644 --- a/src/LoggerListeners.cpp +++ b/src/LoggerListeners.cpp @@ -190,7 +190,7 @@ break; } } - __android_log_print(AndroidLogLevel, "MCServer", "%s", a_Message.c_str()); + __android_log_print(AndroidLogLevel, "Cuberite", "%s", a_Message.c_str()); } }; diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index fa86f28ae..b28e94ec1 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -912,7 +912,7 @@ eMonsterType cMonster::StringToMobType(const AString & a_Name) { AString lcName = StrToLower(a_Name); - // Search MCServer name: + // Search Cuberite name: for (size_t i = 0; i < ARRAYCOUNT(g_MobTypeNames); i++) { if (strcmp(g_MobTypeNames[i].m_lcName, lcName.c_str()) == 0) diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index d42bb77bc..69a05f651 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -10,7 +10,7 @@ class cPath; #include "../FastRandom.h" #ifdef COMPILING_PATHFIND_DEBUGGER /* Note: the COMPILING_PATHFIND_DEBUGGER flag is used by Native / WiseOldMan95 to debug - this class outside of MCServer. This preprocessor flag is never set when compiling MCServer. */ + this class outside of Cuberite. This preprocessor flag is never set when compiling Cuberite. */ #include "PathFinderIrrlicht_Head.h" #endif diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 09f6147b2..dec873ccd 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -16,11 +16,7 @@ cFile::cFile(void) : - #ifdef USE_STDIO_FILE m_File(nullptr) - #else - m_File(INVALID_HANDLE_VALUE) - #endif // USE_STDIO_FILE { // Nothing needed yet } @@ -30,11 +26,7 @@ cFile::cFile(void) : cFile::cFile(const AString & iFileName, eMode iMode) : - #ifdef USE_STDIO_FILE m_File(nullptr) - #else - m_File(INVALID_HANDLE_VALUE) - #endif // USE_STDIO_FILE { Open(iFileName, iMode); } @@ -78,11 +70,11 @@ bool cFile::Open(const AString & iFileName, eMode iMode) return false; } -#ifdef _WIN32 - m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), Mode, _SH_DENYWR); -#else - m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode); -#endif // _WIN32 + #ifdef _WIN32 + m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), Mode, _SH_DENYWR); + #else + m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode); + #endif // _WIN32 if ((m_File == nullptr) && (iMode == fmReadWrite)) { @@ -91,11 +83,11 @@ bool cFile::Open(const AString & iFileName, eMode iMode) // So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents. // Simply re-open for read-writing, erasing existing contents: -#ifdef _WIN32 - m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+", _SH_DENYWR); -#else - m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+"); -#endif // _WIN32 + #ifdef _WIN32 + m_File = _fsopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+", _SH_DENYWR); + #else + m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+"); + #endif // _WIN32 } return (m_File != nullptr); @@ -310,7 +302,77 @@ bool cFile::Exists(const AString & a_FileName) -bool cFile::Delete(const AString & a_FileName) +bool cFile::Delete(const AString & a_Path) +{ + if (IsFolder(a_Path)) + { + return DeleteFolder(a_Path); + } + else + { + return DeleteFile(a_Path); + } +} + + + + + +bool cFile::DeleteFolder(const AString & a_FolderName) +{ + #ifdef _WIN32 + return (RemoveDirectoryA(a_FolderName.c_str()) != 0); + #else // _WIN32 + return (rmdir(a_FolderName.c_str()) == 0); + #endif // else _WIN32 +} + + + + + +bool cFile::DeleteFolderContents(const AString & a_FolderName) +{ + auto Contents = cFile::GetFolderContents(a_FolderName); + for (const auto item: Contents) + { + // Skip "." and ".." altogether: + if ((item == ".") || (item == "..")) + { + continue; + } + + // Remove the item: + auto WholePath = a_FolderName + GetPathSeparator() + item; + if (IsFolder(WholePath)) + { + if (!DeleteFolderContents(WholePath)) + { + return false; + } + if (!DeleteFolder(WholePath)) + { + return false; + } + } + else + { + if (!DeleteFile(WholePath)) + { + return false; + } + } + } // for item - Contents[] + + // All deletes succeeded + return true; +} + + + + + +bool cFile::DeleteFile(const AString & a_FileName) { return (remove(a_FileName.c_str()) == 0); } @@ -331,7 +393,7 @@ bool cFile::Rename(const AString & a_OrigFileName, const AString & a_NewFileName bool cFile::Copy(const AString & a_SrcFileName, const AString & a_DstFileName) { #ifdef _WIN32 - return (CopyFileA(a_SrcFileName.c_str(), a_DstFileName.c_str(), true) != 0); + return (CopyFileA(a_SrcFileName.c_str(), a_DstFileName.c_str(), FALSE) != 0); #else // Other OSs don't have a direct CopyFile equivalent, do it the harder way: std::ifstream src(a_SrcFileName.c_str(), std::ios::binary); @@ -409,57 +471,85 @@ bool cFile::CreateFolder(const AString & a_FolderPath) +bool cFile::CreateFolderRecursive(const AString & a_FolderPath) +{ + // Special case: Fail if the path is empty + if (a_FolderPath.empty()) + { + return false; + } + + // Go through each path element and create the folder: + auto len = a_FolderPath.length(); + auto PathSep = GetPathSeparator()[0]; + for (decltype(len) i = 0; i < len; i++) + { + if (a_FolderPath[i] == PathSep) + { + CreateFolder(a_FolderPath.substr(0, i)); + } + } + CreateFolder(a_FolderPath); + + // Check the result by querying whether the final path exists: + return IsFolder(a_FolderPath); +} + + + + + AStringVector cFile::GetFolderContents(const AString & a_Folder) { AStringVector AllFiles; #ifdef _WIN32 - // If the folder name doesn't contain the terminating slash / backslash, add it: - AString FileFilter = a_Folder; - if ( - !FileFilter.empty() && - (FileFilter[FileFilter.length() - 1] != '\\') && - (FileFilter[FileFilter.length() - 1] != '/') - ) - { - FileFilter.push_back('\\'); - } + // If the folder name doesn't contain the terminating slash / backslash, add it: + AString FileFilter = a_Folder; + if ( + !FileFilter.empty() && + (FileFilter[FileFilter.length() - 1] != '\\') && + (FileFilter[FileFilter.length() - 1] != '/') + ) + { + FileFilter.push_back('\\'); + } - // Find all files / folders: - FileFilter.append("*.*"); - HANDLE hFind; - WIN32_FIND_DATAA FindFileData; - if ((hFind = FindFirstFileA(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) - { - do + // Find all files / folders: + FileFilter.append("*.*"); + HANDLE hFind; + WIN32_FIND_DATAA FindFileData; + if ((hFind = FindFirstFileA(FileFilter.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) { - AllFiles.push_back(FindFileData.cFileName); - } while (FindNextFileA(hFind, &FindFileData)); - FindClose(hFind); - } + do + { + AllFiles.push_back(FindFileData.cFileName); + } while (FindNextFileA(hFind, &FindFileData)); + FindClose(hFind); + } #else // _WIN32 - DIR * dp; - struct dirent *dirp; - AString Folder = a_Folder; - if (Folder.empty()) - { - Folder = "."; - } - if ((dp = opendir(Folder.c_str())) == nullptr) - { - LOGERROR("Error (%i) opening directory \"%s\"\n", errno, Folder.c_str()); - } - else - { - while ((dirp = readdir(dp)) != nullptr) + DIR * dp; + struct dirent *dirp; + AString Folder = a_Folder; + if (Folder.empty()) { - AllFiles.push_back(dirp->d_name); + Folder = "."; + } + if ((dp = opendir(Folder.c_str())) == nullptr) + { + LOGERROR("Error (%i) opening directory \"%s\"\n", errno, Folder.c_str()); + } + else + { + while ((dirp = readdir(dp)) != nullptr) + { + AllFiles.push_back(dirp->d_name); + } + closedir(dp); } - closedir(dp); - } #endif // else _WIN32 diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index b8381ac0e..aab86811d 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -32,17 +32,6 @@ For reading entire files into memory, just use the static cFile::ReadWholeFile() -#ifndef _WIN32 - #define USE_STDIO_FILE -#endif // _WIN32 - -// DEBUG: -#define USE_STDIO_FILE - - - - - // tolua_begin class cFile @@ -101,48 +90,64 @@ public: /** Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error */ int ReadRestOfFile(AString & a_Contents); - // tolua_begin - /** Returns true if the file specified exists */ - static bool Exists(const AString & a_FileName); + static bool Exists(const AString & a_FileName); // Exported in ManualBindings.cpp + + /** Deletes a file or a folder, returns true if successful. + Prefer to use DeleteFile or DeleteFolder, since those don't have the penalty of checking whether a_Path is a folder. */ + static bool Delete(const AString & a_Path); // Exported in ManualBindings.cpp + + /** Deletes a file, returns true if successful. + Returns false if a_FileName points to a folder. */ + static bool DeleteFile(const AString & a_FileName); // Exported in ManualBindings.cpp - /** Deletes a file, returns true if successful */ - static bool Delete(const AString & a_FileName); + /** Deletes a folder, returns true if successful. + Returns false if a_FolderName points to a file. */ + static bool DeleteFolder(const AString & a_FolderName); // Exported in ManualBindings.cpp + + /** Deletes all content from the specified folder. + The specified folder itself stays intact. + Returns true on success, false on failure. */ + static bool DeleteFolderContents(const AString & a_FolderName); // Exported in ManualBindings.cpp /** Renames a file or folder, returns true if successful. May fail if dest already exists (libc-dependant)! */ - static bool Rename(const AString & a_OrigPath, const AString & a_NewPath); + static bool Rename(const AString & a_OrigPath, const AString & a_NewPath); // Exported in ManualBindings.cpp - /** Copies a file, returns true if successful. */ - static bool Copy(const AString & a_SrcFileName, const AString & a_DstFileName); + /** Copies a file, returns true if successful. + Overwrites the dest file if it already exists. */ + static bool Copy(const AString & a_SrcFileName, const AString & a_DstFileName); // Exported in ManualBindings.cpp /** Returns true if the specified path is a folder */ - static bool IsFolder(const AString & a_Path); + static bool IsFolder(const AString & a_Path); // Exported in ManualBindings.cpp /** Returns true if the specified path is a regular file */ - static bool IsFile(const AString & a_Path); + static bool IsFile(const AString & a_Path); // Exported in ManualBindings.cpp /** Returns the size of the file, or a negative number on error */ - static long GetSize(const AString & a_FileName); + static long GetSize(const AString & a_FileName); // Exported in ManualBindings.cpp /** Creates a new folder with the specified name. Returns true if successful. Path may be relative or absolute */ - static bool CreateFolder(const AString & a_FolderPath); - - // tolua_end + static bool CreateFolder(const AString & a_FolderPath); // Exported in ManualBindings.cpp - /** Returns the entire contents of the specified file as a string. Returns empty string on error. - Exported manually in ManualBindings.cpp due to #1914 - ToLua code doesn't work well with binary files. */ - static AString ReadWholeFile(const AString & a_FileName); - - // tolua_begin + /** Creates a new folder with the specified name, creating its parents if needed. Path may be relative or absolute. + Returns true if the folder exists at the end of the operation (either created, or already existed). + Supports only paths that use the path separator used by the current platform (MSVC CRT supports slashes for file paths, too, but this function doesn't) */ + static bool CreateFolderRecursive(const AString & a_FolderPath); // Exported in ManualBindings.cpp + + /** Returns the entire contents of the specified file as a string. Returns empty string on error. */ + static AString ReadWholeFile(const AString & a_FileName); // Exported in ManualBindings.cpp /** Returns a_FileName with its extension changed to a_NewExt. a_FileName may contain path specification. */ - static AString ChangeFileExt(const AString & a_FileName, const AString & a_NewExt); + static AString ChangeFileExt(const AString & a_FileName, const AString & a_NewExt); // Exported in ManualBindings.cpp /** Returns the last modification time (in current timezone) of the specified file. The value returned is in the same units as the value returned by time() function. - If the file is not found / accessible, zero is returned. */ - static unsigned GetLastModificationTime(const AString & a_FileName); + If the file is not found / accessible, zero is returned. + Works for folders, too, when specified without the trailing path separator. */ + static unsigned GetLastModificationTime(const AString & a_FileName); // Exported in ManualBindings.cpp + + // tolua_begin /** Returns the path separator used by the current platform. Note that the platform / CRT may support additional path separators (such as slashes on Windows), these don't get reported. */ @@ -162,11 +167,7 @@ public: void Flush(void); private: - #ifdef USE_STDIO_FILE FILE * m_File; - #else - HANDLE m_File; - #endif } ; // tolua_export diff --git a/src/PolarSSL++/SslContext.cpp b/src/PolarSSL++/SslContext.cpp index 1409405bc..90e0ae0e2 100644 --- a/src/PolarSSL++/SslContext.cpp +++ b/src/PolarSSL++/SslContext.cpp @@ -50,7 +50,7 @@ int cSslContext::Initialize(bool a_IsClient, const SharedPtr<cCtrDrbgContext> & if (m_CtrDrbg.get() == nullptr) { m_CtrDrbg.reset(new cCtrDrbgContext); - m_CtrDrbg->Initialize("MCServer", 8); + m_CtrDrbg->Initialize("Cuberite", 8); } // Initialize PolarSSL's structures: diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index bfbe5028d..304486935 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -149,7 +149,7 @@ bool cAuthenticator::AuthWithYggdrasil(AString & a_UserName, const AString & a_S AString Request; Request += "GET " + ActualAddress + " HTTP/1.0\r\n"; Request += "Host: " + m_Server + "\r\n"; - Request += "User-Agent: MCServer\r\n"; + Request += "User-Agent: Cuberite\r\n"; Request += "Connection: close\r\n"; Request += "\r\n"; @@ -223,7 +223,7 @@ bool cAuthenticator::GetPlayerProperties(const AString & a_UUID, Json::Value & a AString Request; Request += "GET " + ActualAddress + " HTTP/1.0\r\n"; Request += "Host: " + m_Server + "\r\n"; - Request += "User-Agent: MCServer\r\n"; + Request += "User-Agent: Cuberite\r\n"; Request += "Connection: close\r\n"; Request += "\r\n"; diff --git a/src/Protocol/Authenticator.h b/src/Protocol/Authenticator.h index 02b349256..845277569 100644 --- a/src/Protocol/Authenticator.h +++ b/src/Protocol/Authenticator.h @@ -1,10 +1,10 @@ // cAuthenticator.h -// Interfaces to the cAuthenticator class representing the thread that authenticates users against the official MC server +// Interfaces to the cAuthenticator class representing the thread that authenticates users against the official Mojang servers // Authentication prevents "hackers" from joining with an arbitrary username (possibly impersonating the server admins) // For more info, see http://wiki.vg/Session#Server_operation -// In MCS, authentication is implemented as a single thread that receives queued auth requests and dispatches them one by one. +// In Cuberite, authentication is implemented as a single thread that receives queued auth requests and dispatches them one by one. diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index f3f9baf25..73b3bd8c0 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -688,7 +688,7 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery) AString Request; Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding Request += "Host: " + m_NameToUUIDServer + "\r\n"; - Request += "User-Agent: MCServer\r\n"; + Request += "User-Agent: Cuberite\r\n"; Request += "Connection: close\r\n"; Request += "Content-Type: application/json\r\n"; Request += Printf("Content-Length: %u\r\n", static_cast<unsigned>(RequestBody.length())); @@ -802,7 +802,7 @@ void cMojangAPI::QueryUUIDToProfile(const AString & a_UUID) AString Request; Request += "GET " + Address + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding Request += "Host: " + m_UUIDToProfileServer + "\r\n"; - Request += "User-Agent: MCServer\r\n"; + Request += "User-Agent: Cuberite\r\n"; Request += "Connection: close\r\n"; Request += "Content-Length: 0\r\n"; Request += "\r\n"; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index ad76480b3..d17537ff7 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1800,7 +1800,7 @@ void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) // Version: Json::Value Version; - Version["name"] = "MCServer 1.7.2"; + Version["name"] = "Cuberite 1.7.2"; Version["protocol"] = 4; // Players: @@ -2394,7 +2394,7 @@ void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const } // Send back our brand: - SendPluginMessage("MC|Brand", "MCServer"); + SendPluginMessage("MC|Brand", "Cuberite"); return; } else if (a_Channel == "MC|Beacon") @@ -3256,7 +3256,7 @@ void cProtocol176::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) // Version: Json::Value Version; - Version["name"] = "MCServer 1.7.6"; + Version["name"] = "Cuberite 1.7.6"; Version["protocol"] = 5; // Players: diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp index d69c631d2..ea71103f7 100644 --- a/src/Protocol/Protocol18x.cpp +++ b/src/Protocol/Protocol18x.cpp @@ -2080,7 +2080,7 @@ void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) // Version: Json::Value Version; - Version["name"] = "MCServer 1.8"; + Version["name"] = "Cuberite 1.8"; Version["protocol"] = 47; // Players: @@ -2685,7 +2685,7 @@ void cProtocol180::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Brand); m_Client->SetClientBrand(Brand); // Send back our brand, including the length: - SendPluginMessage("MC|Brand", "\x08MCServer"); + SendPluginMessage("MC|Brand", "\x08Cuberite"); return; } else if (a_Channel == "MC|Beacon") diff --git a/src/Root.cpp b/src/Root.cpp index 13166d883..57056cc1b 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -121,7 +121,7 @@ void cRoot::Start(std::unique_ptr<cSettingsRepositoryInterface> a_OverridesRepo) LOG("--- Started Log ---"); #ifdef BUILD_ID - LOG("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID); + LOG("Cuberite " BUILD_SERIES_NAME " build id: " BUILD_ID); LOG("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME); #endif diff --git a/src/Server.cpp b/src/Server.cpp index 313db90e6..a21248695 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -187,7 +187,7 @@ void cServer::PlayerDestroying(const cPlayer * a_Player) bool cServer::InitServer(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth) { - m_Description = a_Settings.GetValueSet("Server", "Description", "MCServer - in C++!"); + m_Description = a_Settings.GetValueSet("Server", "Description", "Cuberite - in C++!"); m_MaxPlayers = a_Settings.GetValueSetI("Server", "MaxPlayers", 100); m_bIsHardcore = a_Settings.GetValueSetB("Server", "HardcoreEnabled", false); m_bAllowMultiLogin = a_Settings.GetValueSetB("Server", "AllowMultiLogin", false); diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index 91fad96c6..27294f19b 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -96,7 +96,7 @@ bool cWebAdmin::Init(void) if (!m_IniFile.ReadFile("webadmin.ini")) { LOGWARN("Regenerating webadmin.ini, all settings will be reset"); - m_IniFile.AddHeaderComment(" This file controls the webadmin feature of MCServer"); + m_IniFile.AddHeaderComment(" This file controls the webadmin feature of Cuberite"); m_IniFile.AddHeaderComment(" Username format: [User:*username*]"); m_IniFile.AddHeaderComment(" Password format: Password=*password*; for example:"); m_IniFile.AddHeaderComment(" [User:admin]"); @@ -131,7 +131,7 @@ bool cWebAdmin::Init(void) // Sets the fallback template: m_LoginTemplate = \ - "<h1>MCServer WebAdmin</h1>" \ + "<h1>Cuberite WebAdmin</h1>" \ "<center>" \ "<form method='get' action='webadmin/'>" \ "<input type='submit' value='Log in'>" \ @@ -216,7 +216,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque { if (!a_Request.HasAuth()) { - a_Connection.SendNeedAuth("MCServer WebAdmin"); + a_Connection.SendNeedAuth("Cuberite WebAdmin"); return; } @@ -224,7 +224,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque AString UserPassword = m_IniFile.GetValue("User:" + a_Request.GetAuthUsername(), "Password", ""); if ((UserPassword == "") || (a_Request.GetAuthPassword() != UserPassword)) { - a_Connection.SendNeedAuth("MCServer WebAdmin - bad username or password"); + a_Connection.SendNeedAuth("Cuberite WebAdmin - bad username or password"); return; } @@ -333,7 +333,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque ReplaceString(Template, "{MENU}", Menu); ReplaceString(Template, "{PLUGIN_NAME}", FoundPlugin); ReplaceString(Template, "{CONTENT}", Content); - ReplaceString(Template, "{TITLE}", "MCServer"); + ReplaceString(Template, "{TITLE}", "Cuberite"); AString NumChunks; Printf(NumChunks, "%d", cRoot::Get()->GetTotalChunkCount()); diff --git a/src/World.cpp b/src/World.cpp index eb96eb57a..18d042382 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -839,7 +839,6 @@ void cWorld::Tick(std::chrono::milliseconds a_Dt, std::chrono::milliseconds a_La TickClients(static_cast<float>(a_Dt.count())); TickQueuedBlocks(); TickQueuedTasks(); - TickScheduledTasks(); GetSimulatorManager()->Simulate(static_cast<float>(a_Dt.count())); @@ -962,55 +961,39 @@ void cWorld::TickMobs(std::chrono::milliseconds a_Dt) void cWorld::TickQueuedTasks(void) { - // Make a copy of the tasks to avoid deadlocks on accessing m_Tasks - cTasks Tasks; - { - cCSLock Lock(m_CSTasks); - std::swap(Tasks, m_Tasks); - } - - // Execute and delete each task: - for (cTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr) - { - (*itr)->Run(*this); - } // for itr - m_Tasks[] -} - - - - - -void cWorld::TickScheduledTasks(void) -{ // Move the tasks to be executed to a seperate vector to avoid deadlocks on accessing m_Tasks - cScheduledTasks Tasks; + decltype(m_Tasks) Tasks; { - cCSLock Lock(m_CSScheduledTasks); - auto WorldAge = m_WorldAge; - - // Move all the due tasks from m_ScheduledTasks into Tasks: - for (auto itr = m_ScheduledTasks.begin(); itr != m_ScheduledTasks.end();) // Cannot use range-based for, we're modifying the container + cCSLock Lock(m_CSTasks); + if (m_Tasks.empty()) { - if ((*itr)->m_TargetTick < std::chrono::duration_cast<cTickTimeLong>(WorldAge).count()) - { - auto next = itr; - ++next; - Tasks.push_back(std::move(*itr)); - m_ScheduledTasks.erase(itr); - itr = next; - } - else + return; + } + + // Partition everything to be executed by returning false to move to end of list if time reached + auto MoveBeginIterator = std::partition(m_Tasks.begin(), m_Tasks.end(), [this](const decltype(m_Tasks)::value_type & a_Task) { - // All the eligible tasks have been moved, bail out now - break; + if (a_Task.first < std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count()) + { + return false; + } + return true; } - } + ); + + // Cut all the due tasks from m_Tasks into Tasks: + Tasks.insert( + Tasks.end(), + std::make_move_iterator(MoveBeginIterator), + std::make_move_iterator(m_Tasks.end()) + ); + m_Tasks.erase(MoveBeginIterator, m_Tasks.end()); } - // Execute and delete each task: - for (cScheduledTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr) + // Execute each task: + for (const auto & Task : Tasks) { - (*itr)->m_Task->Run(*this); + Task.second(*this); } // for itr - m_Tasks[] } @@ -2662,7 +2645,7 @@ void cWorld::UnloadUnusedChunks(void) void cWorld::QueueUnloadUnusedChunks(void) { - QueueTask(cpp14::make_unique<cWorld::cTaskUnloadUnusedChunks>()); + QueueTask([](cWorld & a_World) { a_World.UnloadUnusedChunks(); }); } @@ -3140,6 +3123,15 @@ bool cWorld::ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunk +bool cWorld::ForEachLoadedChunk(std::function<bool(int, int)> a_Callback) +{ + return m_ChunkMap->ForEachLoadedChunk(a_Callback); +} + + + + + void cWorld::SaveAllChunks(void) { m_LastSave = std::chrono::duration_cast<cTickTimeLong>(m_WorldAge); @@ -3152,42 +3144,32 @@ void cWorld::SaveAllChunks(void) void cWorld::QueueSaveAllChunks(void) { - QueueTask(std::make_shared<cWorld::cTaskSaveAllChunks>()); + QueueTask([](cWorld & a_World) { a_World.SaveAllChunks(); }); } -void cWorld::QueueTask(cTaskPtr a_Task) +void cWorld::QueueTask(std::function<void(cWorld &)> a_Task) { cCSLock Lock(m_CSTasks); - m_Tasks.push_back(std::move(a_Task)); + m_Tasks.emplace_back(0, a_Task); } -void cWorld::ScheduleTask(int a_DelayTicks, std::function<void (cWorld&)> a_Func) -{ - cTaskLambda task(a_Func); - ScheduleTask(a_DelayTicks, static_cast<cTaskPtr>(std::make_shared<cTaskLambda>(task))); -} -void cWorld::ScheduleTask(int a_DelayTicks, cTaskPtr a_Task) + +void cWorld::ScheduleTask(int a_DelayTicks, std::function<void (cWorld &)> a_Task) { Int64 TargetTick = a_DelayTicks + std::chrono::duration_cast<cTickTimeLong>(m_WorldAge).count(); - - // Insert the task into the list of scheduled tasks, ordered by its target tick - cCSLock Lock(m_CSScheduledTasks); - for (cScheduledTasks::iterator itr = m_ScheduledTasks.begin(), end = m_ScheduledTasks.end(); itr != end; ++itr) + + // Insert the task into the list of scheduled tasks { - if ((*itr)->m_TargetTick >= TargetTick) - { - m_ScheduledTasks.insert(itr, cScheduledTaskPtr(new cScheduledTask(TargetTick, a_Task))); - return; - } + cCSLock Lock(m_CSTasks); + m_Tasks.emplace_back(TargetTick, a_Task); } - m_ScheduledTasks.push_back(cScheduledTaskPtr(new cScheduledTask(TargetTick, a_Task))); } @@ -3616,75 +3598,6 @@ void cWorld::AddQueuedPlayers(void) //////////////////////////////////////////////////////////////////////////////// -// cWorld::cTaskSaveAllChunks: - -void cWorld::cTaskSaveAllChunks::Run(cWorld & a_World) -{ - a_World.SaveAllChunks(); -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cWorld::cTaskUnloadUnusedChunks - -void cWorld::cTaskUnloadUnusedChunks::Run(cWorld & a_World) -{ - a_World.UnloadUnusedChunks(); -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// cWorld::cTaskSendBlockToAllPlayers - -cWorld::cTaskSendBlockToAllPlayers::cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue) : - m_SendQueue(a_SendQueue) -{ -} - -void cWorld::cTaskSendBlockToAllPlayers::Run(cWorld & a_World) -{ - class cPlayerCallback : - public cPlayerListCallback - { - public: - cPlayerCallback(std::vector<Vector3i> & a_SendQueue, cWorld & a_CallbackWorld) : - m_SendQueue(a_SendQueue), - m_World(a_CallbackWorld) - { - } - - virtual bool Item(cPlayer * a_Player) - { - for (std::vector<Vector3i>::const_iterator itr = m_SendQueue.begin(); itr != m_SendQueue.end(); ++itr) - { - m_World.SendBlockTo(itr->x, itr->y, itr->z, a_Player); - } - return false; - } - - private: - - std::vector<Vector3i> m_SendQueue; - cWorld & m_World; - - } PlayerCallback(m_SendQueue, a_World); - - a_World.ForEachPlayer(PlayerCallback); -} - -void cWorld::cTaskLambda::Run(cWorld & a_World) -{ - m_func(a_World); -} - - -//////////////////////////////////////////////////////////////////////////////// // cWorld::cChunkGeneratorCallbacks: cWorld::cChunkGeneratorCallbacks::cChunkGeneratorCallbacks(cWorld & a_World) : diff --git a/src/World.h b/src/World.h index 1ee473970..44f18df4a 100644 --- a/src/World.h +++ b/src/World.h @@ -27,7 +27,7 @@ #include "Blocks/BroadcastInterface.h" #include "FastRandom.h" #include "ClientHandle.h" - +#include <functional> @@ -96,72 +96,8 @@ public: typedef cCSLock super; public: cLock(cWorld & a_World); - } ; - - - /** A common ancestor for all tasks queued onto the tick thread */ - class cTask - { - public: - cTask(const cTask & other) = default; - virtual ~cTask() {} - virtual void Run(cWorld & a_World) = 0; - - protected: - cTask() {} - } ; - - typedef SharedPtr<cTask> cTaskPtr; - typedef std::vector<cTaskPtr> cTasks; - - - class cTaskSaveAllChunks : - public cTask - { - protected: - // cTask overrides: - virtual void Run(cWorld & a_World) override; - } ; - - - class cTaskUnloadUnusedChunks : - public cTask - { - protected: - // cTask overrides: - virtual void Run(cWorld & a_World) override; - }; - - - class cTaskSendBlockToAllPlayers : - public cTask - { - public: - cTaskSendBlockToAllPlayers(std::vector<Vector3i> & a_SendQueue); - - protected: - // cTask overrides: - virtual void Run(cWorld & a_World) override; - - std::vector<Vector3i> m_SendQueue; }; - class cTaskLambda : - public cTask - { - - public: - cTaskLambda(std::function<void(cWorld&)> a_Func) : - m_func(a_Func) - { } - - protected: - virtual void Run(cWorld & a_World) override; - - std::function<void(cWorld&)> m_func; - }; - - static const char * GetClassStatic(void) // Needed for ManualBindings's ForEach templates { return "cWorld"; @@ -434,6 +370,9 @@ public: /** Calls the callback for each chunk in the coords specified (all cords are inclusive). Returns true if all chunks have been processed successfully */ virtual bool ForEachChunkInRect(int a_MinChunkX, int a_MaxChunkX, int a_MinChunkZ, int a_MaxChunkZ, cChunkDataCallback & a_Callback) override; + /** Calls the callback for each loaded chunk. Returns true if all chunks have been processed successfully */ + bool ForEachLoadedChunk(std::function<bool(int, int)> a_Callback); + // tolua_begin /** Sets the block at the specified coords to the specified value. @@ -736,13 +675,10 @@ public: void QueueSaveAllChunks(void); // tolua_export /** Queues a task onto the tick thread. The task object will be deleted once the task is finished */ - void QueueTask(cTaskPtr a_Task); // Exported in ManualBindings.cpp + void QueueTask(std::function<void(cWorld &)> a_Task); // Exported in ManualBindings.cpp /** Queues a lambda task onto the tick thread, with the specified delay. */ - void ScheduleTask(int a_DelayTicks, std::function<void(cWorld&)> a_Func); - - /** Queues a task onto the tick thread, with the specified delay. */ - void ScheduleTask(int a_DelayTicks, cTaskPtr a_Task); + void ScheduleTask(int a_DelayTicks, std::function<void(cWorld &)> a_Task); /** Returns the number of chunks loaded */ int GetNumChunks() const; // tolua_export @@ -909,27 +845,6 @@ private: public: cChunkGeneratorCallbacks(cWorld & a_World); } ; - - - /** A container for tasks that have been scheduled for a specific game tick */ - class cScheduledTask - { - public: - Int64 m_TargetTick; - cTaskPtr m_Task; - - /** Creates a new scheduled task; takes ownership of the task object passed to it. */ - cScheduledTask(Int64 a_TargetTick, cTaskPtr a_Task) : - m_TargetTick(a_TargetTick), - m_Task(a_Task) - { - } - - virtual ~cScheduledTask() {} - }; - - typedef std::unique_ptr<cScheduledTask> cScheduledTaskPtr; - typedef std::list<cScheduledTaskPtr> cScheduledTasks; AString m_WorldName; @@ -1059,16 +974,8 @@ private: /** Guards the m_Tasks */ cCriticalSection m_CSTasks; - /** Tasks that have been queued onto the tick thread; guarded by m_CSTasks */ - cTasks m_Tasks; - - /** Guards the m_ScheduledTasks */ - cCriticalSection m_CSScheduledTasks; - - /** Tasks that have been queued to be executed on the tick thread at target tick in the future. - Ordered by increasing m_TargetTick. - Guarded by m_CSScheduledTasks */ - cScheduledTasks m_ScheduledTasks; + /** Tasks that have been queued onto the tick thread, possibly to be executed at target tick in the future; guarded by m_CSTasks */ + std::vector<std::pair<Int64, std::function<void(cWorld &)>>> m_Tasks; /** Guards m_Clients */ cCriticalSection m_CSClients; @@ -1115,9 +1022,6 @@ private: /** Executes all tasks queued onto the tick thread */ void TickQueuedTasks(void); - /** Executes all tasks queued onto the tick thread */ - void TickScheduledTasks(void); - /** Ticks all clients that are in this world */ void TickClients(float a_Dt); diff --git a/src/WorldStorage/NBTChunkSerializer.cpp b/src/WorldStorage/NBTChunkSerializer.cpp index f204ec52b..e2ba416c6 100644 --- a/src/WorldStorage/NBTChunkSerializer.cpp +++ b/src/WorldStorage/NBTChunkSerializer.cpp @@ -415,7 +415,7 @@ void cNBTChunkSerializer::AddFallingBlockEntity(cFallingBlock * a_FallingBlock) AddBasicEntity(a_FallingBlock, "FallingSand"); m_Writer.AddInt("TileID", a_FallingBlock->GetBlockType()); m_Writer.AddByte("Data", a_FallingBlock->GetBlockMeta()); - m_Writer.AddByte("Time", 1); // Unused in MCServer, Vanilla said to need nonzero + m_Writer.AddByte("Time", 1); // Unused in Cuberite, Vanilla said to need nonzero m_Writer.AddByte("DropItem", 1); m_Writer.AddByte("HurtEntities", a_FallingBlock->GetBlockType() == E_BLOCK_ANVIL); m_Writer.EndCompound(); diff --git a/src/WorldStorage/WSSAnvil.cpp b/src/WorldStorage/WSSAnvil.cpp index dc1b7faff..f0c990037 100755 --- a/src/WorldStorage/WSSAnvil.cpp +++ b/src/WorldStorage/WSSAnvil.cpp @@ -1139,7 +1139,7 @@ cBlockEntity * cWSSAnvil::LoadMobSpawnerFromNBT(const cParsedNBT & a_NBT, int a_ std::unique_ptr<cMobSpawnerEntity> MobSpawner = cpp14::make_unique<cMobSpawnerEntity>(a_BlockX, a_BlockY, a_BlockZ, m_World); - // Load entity (MCServer worlds): + // Load entity (Cuberite worlds): int Type = a_NBT.FindChildByName(a_TagIdx, "Entity"); if ((Type >= 0) && (a_NBT.GetType(Type) == TAG_Short)) { diff --git a/src/main.cpp b/src/main.cpp index b9c3ae0bc..c26e7900f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -39,7 +39,7 @@ bool cRoot::m_RunAsService = false; #if defined(_WIN32) SERVICE_STATUS_HANDLE g_StatusHandle = nullptr; HANDLE g_ServiceThread = INVALID_HANDLE_VALUE; - #define SERVICE_NAME "MCServerService" + #define SERVICE_NAME "CuberiteService" #endif @@ -77,10 +77,10 @@ void NonCtrlHandler(int a_Signal) case SIGSEGV: { std::signal(SIGSEGV, SIG_DFL); - LOGERROR(" D: | MCServer has encountered an error and needs to close"); + LOGERROR(" D: | Cuberite has encountered an error and needs to close"); LOGERROR("Details | SIGSEGV: Segmentation fault"); #ifdef BUILD_ID - LOGERROR("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID); + LOGERROR("Cuberite " BUILD_SERIES_NAME " build id: " BUILD_ID); LOGERROR("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME); #endif PrintStackTrace(); @@ -92,10 +92,10 @@ void NonCtrlHandler(int a_Signal) #endif { std::signal(a_Signal, SIG_DFL); - LOGERROR(" D: | MCServer has encountered an error and needs to close"); + LOGERROR(" D: | Cuberite has encountered an error and needs to close"); LOGERROR("Details | SIGABRT: Server self-terminated due to an internal fault"); #ifdef BUILD_ID - LOGERROR("MCServer " BUILD_SERIES_NAME " build id: " BUILD_ID); + LOGERROR("Cuberite " BUILD_SERIES_NAME " build id: " BUILD_ID); LOGERROR("from commit id: " BUILD_COMMIT_ID " built at: " BUILD_DATETIME); #endif PrintStackTrace(); @@ -358,7 +358,7 @@ std::unique_ptr<cMemorySettingsRepository> ParseArguments(int argc, char **argv) try { // Parse the comand line args: - TCLAP::CmdLine cmd("MCServer"); + TCLAP::CmdLine cmd("Cuberite"); TCLAP::ValueArg<int> slotsArg ("s", "max-players", "Maximum number of slots for the server to use, overrides setting in setting.ini", false, -1, "number", cmd); TCLAP::MultiArg<int> portsArg ("p", "port", "The port number the server should listen to", false, "port", cmd); TCLAP::SwitchArg commLogArg ("", "log-comm", "Log server client communications to file", cmd); @@ -522,7 +522,7 @@ int main(int argc, char **argv) while (!cRoot::m_TerminateEventRaised) { - UniversalMain(std::move(ParseArguments(argc, argv))); + UniversalMain(ParseArguments(argc, argv)); } #endif } @@ -531,7 +531,7 @@ int main(int argc, char **argv) while (!cRoot::m_TerminateEventRaised) { // Not running as a service, do normal startup - UniversalMain(std::move(ParseArguments(argc, argv))); + UniversalMain(ParseArguments(argc, argv)); } } |