diff options
77 files changed, 842 insertions, 856 deletions
diff --git a/MCServer/Plugins/APIDump/Hooks/OnPlayerMoving.lua b/MCServer/Plugins/APIDump/Hooks/OnPlayerMoving.lua index 2756529ef..4385bf94d 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnPlayerMoving.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnPlayerMoving.lua @@ -11,9 +11,11 @@ return Params = { { Name = "Player", Type = "{{cPlayer}}", Notes = "The player who has moved. The object already has the new position stored in it." }, + { Name = "OldPosition", Type = "{{Vector3d}}", Notes = "The old position." }, + { Name = "NewPosition", Type = "{{Vector3d}}", Notes = "The new position." }, }, Returns = [[ - If the function returns true, movement is prohibited. FIXME: The player's client is not informed.</p> + If the function returns true, movement is prohibited.</p> <p> If the function returns false or no value, other plugins' callbacks are called and finally the new position is permanently stored in the cPlayer object.</p> diff --git a/SetFlags.cmake b/SetFlags.cmake index a5a61eaa4..0e2e0c277 100644 --- a/SetFlags.cmake +++ b/SetFlags.cmake @@ -1,3 +1,5 @@ + + macro (add_flags_lnk FLAGS) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}") set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}") diff --git a/Tools/MCADefrag/CMakeLists.txt b/Tools/MCADefrag/CMakeLists.txt index 2a021049f..42b42018b 100644 --- a/Tools/MCADefrag/CMakeLists.txt +++ b/Tools/MCADefrag/CMakeLists.txt @@ -39,14 +39,12 @@ set_exe_flags() set(SHARED_SRC ../../src/StringCompression.cpp ../../src/StringUtils.cpp - ../../src/Log.cpp - ../../src/MCLogger.cpp + ../../src/LoggerListeners.cpp + ../../src/Logger.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h ../../src/StringUtils.h - ../../src/Log.h - ../../src/MCLogger.h ) flatten_files(SHARED_SRC) flatten_files(SHARED_HDR) diff --git a/Tools/MCADefrag/MCADefrag.cpp b/Tools/MCADefrag/MCADefrag.cpp index a2de7f957..d5d233fd2 100644 --- a/Tools/MCADefrag/MCADefrag.cpp +++ b/Tools/MCADefrag/MCADefrag.cpp @@ -5,7 +5,8 @@ #include "Globals.h" #include "MCADefrag.h" -#include "MCLogger.h" +#include "Logger.h" +#include "LoggerListeners.h" #include "zlib/zlib.h" @@ -21,7 +22,13 @@ static const Byte g_Zeroes[4096] = {0}; int main(int argc, char ** argv) { - new cMCLogger(Printf("Defrag_%08x.log", time(NULL))); + cLogger::cListener * consoleLogListener = MakeConsoleListener(); + cLogger::cListener * fileLogListener = new cFileListener(); + cLogger::GetInstance().AttachListener(consoleLogListener); + cLogger::GetInstance().AttachListener(fileLogListener); + + cLogger::InitiateMultithreading(); + cMCADefrag Defrag; if (!Defrag.Init(argc, argv)) { @@ -30,6 +37,11 @@ int main(int argc, char ** argv) Defrag.Run(); + cLogger::GetInstance().DetachListener(consoleLogListener); + delete consoleLogListener; + cLogger::GetInstance().DetachListener(fileLogListener); + delete fileLogListener; + return 0; } diff --git a/Tools/ProtoProxy/CMakeLists.txt b/Tools/ProtoProxy/CMakeLists.txt index f0796363c..bc3923d90 100644 --- a/Tools/ProtoProxy/CMakeLists.txt +++ b/Tools/ProtoProxy/CMakeLists.txt @@ -34,20 +34,18 @@ set_exe_flags() set(SHARED_SRC ../../src/ByteBuffer.cpp ../../src/StringUtils.cpp - ../../src/Log.cpp - ../../src/MCLogger.cpp ../../src/PolarSSL++/AesCfb128Decryptor.cpp ../../src/PolarSSL++/AesCfb128Encryptor.cpp ../../src/PolarSSL++/CryptoKey.cpp ../../src/PolarSSL++/CtrDrbgContext.cpp ../../src/PolarSSL++/EntropyContext.cpp ../../src/PolarSSL++/RsaPrivateKey.cpp + ../../src/LoggerListeners.cpp + ../../src/Logger.cpp ) set(SHARED_HDR ../../src/ByteBuffer.h ../../src/StringUtils.h - ../../src/Log.h - ../../src/MCLogger.h ../../src/PolarSSL++/AesCfb128Decryptor.h ../../src/PolarSSL++/AesCfb128Encryptor.h ../../src/PolarSSL++/CryptoKey.h diff --git a/src/Bindings/LuaFunctions.h b/src/Bindings/LuaFunctions.h index 2ea37d7a4..be1d9aaa9 100644 --- a/src/Bindings/LuaFunctions.h +++ b/src/Bindings/LuaFunctions.h @@ -1,6 +1,6 @@ #pragma once -#include "../MCLogger.h" +#include "Logger.h" #include <time.h> // tolua_begin diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp index 6b40cece8..5aa76eee3 100644 --- a/src/Bindings/ManualBindings.cpp +++ b/src/Bindings/ManualBindings.cpp @@ -168,7 +168,7 @@ static AString GetLogMessage(lua_State * tolua_S) static int tolua_LOG(lua_State * tolua_S) { // If the param is a cCompositeChat, read the log level from it: - cMCLogger::eLogLevel LogLevel = cMCLogger::llRegular; + cLogger::eLogLevel LogLevel = cLogger::llRegular; tolua_Error err; if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &err)) { @@ -176,7 +176,7 @@ static int tolua_LOG(lua_State * tolua_S) } // Log the message: - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); return 0; } @@ -186,7 +186,7 @@ static int tolua_LOG(lua_State * tolua_S) static int tolua_LOGINFO(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llInfo); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llInfo); return 0; } @@ -196,7 +196,7 @@ static int tolua_LOGINFO(lua_State * tolua_S) static int tolua_LOGWARN(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llWarning); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llWarning); return 0; } @@ -206,7 +206,7 @@ static int tolua_LOGWARN(lua_State * tolua_S) static int tolua_LOGERROR(lua_State * tolua_S) { - cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), cMCLogger::llError); + cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), cLogger::llError); return 0; } diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index b4dfeb8cf..53d4be29d 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -73,7 +73,7 @@ public: virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0; virtual bool OnPlayerJoined (cPlayer & a_Player) = 0; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) = 0; - virtual bool OnPlayerMoved (cPlayer & a_Player) = 0; + virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) = 0; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) = 0; virtual bool OnPlayerRightClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ) = 0; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 462dda629..d0b4fa617 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -835,14 +835,14 @@ bool cPluginLua::OnPlayerLeftClick(cPlayer & a_Player, int a_BlockX, int a_Block -bool cPluginLua::OnPlayerMoved(cPlayer & a_Player) +bool cPluginLua::OnPlayerMoving(cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) { cCSLock Lock(m_CriticalSection); bool res = false; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_MOVING]; for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) { - m_LuaState.Call((int)(**itr), &a_Player, cLuaState::Return, res); + m_LuaState.Call((int)(**itr), &a_Player, &a_OldPosition, &a_NewPosition, cLuaState::Return, res); if (res) { return true; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index d3b0d2723..2b7358043 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -98,7 +98,7 @@ public: virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override; virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override; virtual bool OnPlayerJoined (cPlayer & a_Player) override; - virtual bool OnPlayerMoved (cPlayer & a_Player) override; + virtual bool OnPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) override; virtual bool OnPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status) override; virtual bool OnPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; virtual bool OnPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index f708c2d85..f62e6ae02 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -849,14 +849,14 @@ bool cPluginManager::CallHookPlayerLeftClick(cPlayer & a_Player, int a_BlockX, i -bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player) +bool cPluginManager::CallHookPlayerMoving(cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition) { FIND_HOOK(HOOK_PLAYER_MOVING); VERIFY_HOOK; for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) { - if ((*itr)->OnPlayerMoved(a_Player)) + if ((*itr)->OnPlayerMoving(a_Player, a_OldPosition, a_NewPosition)) { return true; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index a60a0cdda..cef6619d7 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -207,7 +207,7 @@ public: bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward); bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel); bool CallHookPlayerJoined (cPlayer & a_Player); - bool CallHookPlayerMoving (cPlayer & a_Player); + bool CallHookPlayerMoving (cPlayer & a_Player, const Vector3d a_OldPosition, const Vector3d a_NewPosition); bool CallHookPlayerLeftClick (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, char a_Status); bool CallHookPlayerPlacedBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); bool CallHookPlayerPlacingBlock (cPlayer & a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, char a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta); diff --git a/src/Blocks/BlockBigFlower.h b/src/Blocks/BlockBigFlower.h index 0b6ac9d8a..72e552dee 100644 --- a/src/Blocks/BlockBigFlower.h +++ b/src/Blocks/BlockBigFlower.h @@ -37,7 +37,7 @@ public: { NIBBLETYPE Meta = a_BlockMeta & 0x7; - if ((Meta == 2) || (Meta == 3)) + if ((Meta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS) || (Meta == E_META_BIG_FLOWER_LARGE_FERN)) { return; } @@ -63,11 +63,11 @@ public: if (r1.randInt(10) == 5) { cItems Pickups; - if (FlowerMeta == 2) + if (FlowerMeta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS) { Pickups.Add(E_BLOCK_TALL_GRASS, 2, 1); } - else if (FlowerMeta == 3) + else if (FlowerMeta == E_META_BIG_FLOWER_LARGE_FERN) { Pickups.Add(E_BLOCK_TALL_GRASS, 2, 2); } diff --git a/src/Blocks/BlockCake.h b/src/Blocks/BlockCake.h index 36e133388..f05f468e5 100644 --- a/src/Blocks/BlockCake.h +++ b/src/Blocks/BlockCake.h @@ -19,7 +19,7 @@ public: { NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); - if (!a_Player->Feed(2, 0.1)) + if (!a_Player->Feed(2, 0.4)) { return; } diff --git a/src/Blocks/BlockDirt.h b/src/Blocks/BlockDirt.h index 2d4fccbac..d458c6062 100644 --- a/src/Blocks/BlockDirt.h +++ b/src/Blocks/BlockDirt.h @@ -81,7 +81,7 @@ public: Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(AboveMeta)) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, BlockX * cChunkDef::Width, BlockY, BlockZ * cChunkDef::Width, ssGrassSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread(Chunk->GetWorld(), Chunk->GetPosX() * cChunkDef::Width + BlockX, BlockY, Chunk->GetPosZ() * cChunkDef::Width + BlockZ, ssGrassSpread)) { Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0); } diff --git a/src/Blocks/BlockFarmland.h b/src/Blocks/BlockFarmland.h index ed0592acd..bb624e54f 100644 --- a/src/Blocks/BlockFarmland.h +++ b/src/Blocks/BlockFarmland.h @@ -54,10 +54,7 @@ public: BLOCKTYPE * BlockTypes = Area.GetBlockTypes(); for (size_t i = 0; i < NumBlocks; i++) { - if ( - (BlockTypes[i] == E_BLOCK_WATER) || - (BlockTypes[i] == E_BLOCK_STATIONARY_WATER) - ) + if (IsBlockWater(BlockTypes[i])) { Found = true; break; diff --git a/src/Blocks/BlockFenceGate.h b/src/Blocks/BlockFenceGate.h index 433531275..ae99a4f94 100644 --- a/src/Blocks/BlockFenceGate.h +++ b/src/Blocks/BlockFenceGate.h @@ -35,6 +35,7 @@ public: NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetYaw()); OldMetaData ^= 4; // Toggle the gate + if ((OldMetaData & 1) == (NewMetaData & 1)) { // Standing in front of the gate - apply new direction diff --git a/src/Blocks/BlockFire.h b/src/Blocks/BlockFire.h index f52825362..c6a3e62cf 100644 --- a/src/Blocks/BlockFire.h +++ b/src/Blocks/BlockFire.h @@ -60,8 +60,8 @@ public: return "step.wood"; } - /// Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border - /// Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding + /** Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border + Takes the X, Y, and Z of the base block; with an optional MaxY for portal border finding */ int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0) { if (a_ChunkInterface.GetBlock(X, Y, Z) != E_BLOCK_OBSIDIAN) @@ -91,13 +91,12 @@ public: return newY; } } - else { return 0; } } return 0; } - /// Evaluates if coords have a valid border on top, based on MaxY + /** Evaluates if coords have a valid border on top, based on MaxY */ bool EvaluatePortalBorder(int X, int FoundObsidianY, int Z, int MaxY, cChunkInterface & a_ChunkInterface) { for (int checkBorder = FoundObsidianY + 1; checkBorder <= MaxY - 1; checkBorder++) // FoundObsidianY + 1: FoundObsidianY has already been checked in FindObsidianCeiling; MaxY - 1: portal doesn't need corners @@ -149,8 +148,8 @@ public: return; } - /// Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable - /// Takes coordinates of base block and Y coord of target obsidian ceiling + /** Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable + Takes coordinates of base block and Y coord of target obsidian ceiling */ bool FindPortalSliceX(int X1, int X2, int Y, int Z, int MaxY, cChunkInterface & a_ChunkInterface) { Dir = 1; // Set assumed direction (will change if portal turns out to be facing the other direction) @@ -168,7 +167,8 @@ public: { return false; // Not valid slice, no portal can be formed } - } XZP = X1 - 1; // Set boundary of frame interior + } + XZP = X1 - 1; // Set boundary of frame interior for (; ((a_ChunkInterface.GetBlock(X2, Y, Z) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X2, Y + 1, Z) == E_BLOCK_OBSIDIAN)); X2--) // Go the other direction (XM) { int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY); @@ -182,7 +182,9 @@ public: { return false; } - } XZM = X2 + 1; // Set boundary, see previous + } + XZM = X2 + 1; // Set boundary, see previous + return (FoundFrameXP && FoundFrameXM); } @@ -204,7 +206,8 @@ public: { return false; } - } XZP = Z1 - 1; + } + XZP = Z1 - 1; for (; ((a_ChunkInterface.GetBlock(X, Y, Z2) == E_BLOCK_OBSIDIAN) || (a_ChunkInterface.GetBlock(X, Y + 1, Z2) == E_BLOCK_OBSIDIAN)); Z2--) { int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY); @@ -218,7 +221,9 @@ public: { return false; } - } XZM = Z2 + 1; + } + XZM = Z2 + 1; + return (FoundFrameZP && FoundFrameZM); } }; diff --git a/src/Blocks/BlockFlower.h b/src/Blocks/BlockFlower.h index e8fd4c7f6..6f64c062b 100644 --- a/src/Blocks/BlockFlower.h +++ b/src/Blocks/BlockFlower.h @@ -19,7 +19,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } diff --git a/src/Blocks/BlockGlowstone.h b/src/Blocks/BlockGlowstone.h index 6c198efc4..d1353e29a 100644 --- a/src/Blocks/BlockGlowstone.h +++ b/src/Blocks/BlockGlowstone.h @@ -15,13 +15,13 @@ public: : cBlockHandler(a_BlockType) { } - + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { // Reset meta to 0 - MTRand r1; - a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, (char)(2 + r1.randInt(2)), 0)); + cFastRandom Random; + a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, (char)(2 + Random.NextInt(3)), 0)); } } ; diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index 52f7dd608..028277e4c 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -45,13 +45,11 @@ #include "BlockLadder.h" #include "BlockLeaves.h" #include "BlockLilypad.h" -#include "BlockNewLeaves.h" #include "BlockLever.h" #include "BlockMelon.h" #include "BlockMushroom.h" #include "BlockMycelium.h" #include "BlockNetherWart.h" -#include "BlockNote.h" #include "BlockOre.h" #include "BlockPiston.h" #include "BlockPlanks.h" @@ -251,9 +249,9 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_NETHER_PORTAL: return new cBlockPortalHandler (a_BlockType); case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (a_BlockType); case E_BLOCK_NETHER_QUARTZ_ORE: return new cBlockOreHandler (a_BlockType); - case E_BLOCK_NEW_LEAVES: return new cBlockNewLeavesHandler (a_BlockType); + case E_BLOCK_NEW_LEAVES: return new cBlockLeavesHandler (a_BlockType); case E_BLOCK_NEW_LOG: return new cBlockSidewaysHandler (a_BlockType); - case E_BLOCK_NOTE_BLOCK: return new cBlockNoteHandler (a_BlockType); + case E_BLOCK_NOTE_BLOCK: return new cBlockEntityHandler (a_BlockType); case E_BLOCK_PISTON: return new cBlockPistonHandler (a_BlockType); case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler; case E_BLOCK_PLANKS: return new cBlockPlanksHandler (a_BlockType); diff --git a/src/Blocks/BlockMelon.h b/src/Blocks/BlockMelon.h index 2f7d9a461..60202d66e 100644 --- a/src/Blocks/BlockMelon.h +++ b/src/Blocks/BlockMelon.h @@ -19,8 +19,8 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - MTRand r1; - a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + r1.randInt(4)), 0)); + cFastRandom Random; + a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + Random.NextInt(5)), 0)); } diff --git a/src/Blocks/BlockNewLeaves.h b/src/Blocks/BlockNewLeaves.h deleted file mode 100644 index 5a267e8c6..000000000 --- a/src/Blocks/BlockNewLeaves.h +++ /dev/null @@ -1,42 +0,0 @@ -#pragma once -#include "BlockHandler.h" -#include "BlockLeaves.h" -#include "../World.h" - - - - - - -class cBlockNewLeavesHandler : - public cBlockLeavesHandler -{ -public: - cBlockNewLeavesHandler(BLOCKTYPE a_BlockType) - : cBlockLeavesHandler(a_BlockType) - { - } - - - virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override - { - MTRand rand; - - // Only the first 2 bits contain the display information, the others are for growing - if (rand.randInt(5) == 0) - { - a_Pickups.push_back(cItem(E_BLOCK_SAPLING, 1, (a_BlockMeta & 3) + 4)); - } - } - - - void OnDestroyed(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, int a_BlockX, int a_BlockY, int a_BlockZ) override - { - cBlockHandler::OnDestroyed(a_ChunkInterface, a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ); - } -} ; - - - - - diff --git a/src/Blocks/BlockNote.h b/src/Blocks/BlockNote.h deleted file mode 100644 index fef38d845..000000000 --- a/src/Blocks/BlockNote.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once -#include "BlockHandler.h" -#include "BlockEntity.h" - -class cBlockNoteHandler : public cBlockEntityHandler -{ -public: - cBlockNoteHandler(BLOCKTYPE a_BlockType) - : cBlockEntityHandler(a_BlockType) - { - } - -}; diff --git a/src/Blocks/BlockOre.h b/src/Blocks/BlockOre.h index 9684dbb19..0067d475f 100644 --- a/src/Blocks/BlockOre.h +++ b/src/Blocks/BlockOre.h @@ -2,7 +2,6 @@ #pragma once #include "BlockHandler.h" -#include "../MersenneTwister.h" #include "../World.h" @@ -20,58 +19,41 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - short ItemType = m_BlockType; - char Count = 1; - short Meta = 0; - - MTRand r1; + cFastRandom Random; + switch (m_BlockType) { case E_BLOCK_LAPIS_ORE: { - ItemType = E_ITEM_DYE; - Count = 4 + (char)r1.randInt(4); - Meta = 4; + a_Pickups.push_back(cItem(E_ITEM_DYE, (char)(4 + Random.NextInt(5)), 4)); break; } case E_BLOCK_REDSTONE_ORE: case E_BLOCK_REDSTONE_ORE_GLOWING: { - Count = 4 + (char)r1.randInt(1); - break; - } - default: - { - Count = 1; + a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, (char)(4 + Random.NextInt(2)), 0)); break; } - } - - switch (m_BlockType) - { case E_BLOCK_DIAMOND_ORE: { - ItemType = E_ITEM_DIAMOND; - break; - } - case E_BLOCK_REDSTONE_ORE: - case E_BLOCK_REDSTONE_ORE_GLOWING: - { - ItemType = E_ITEM_REDSTONE_DUST; + a_Pickups.push_back(cItem(E_ITEM_DIAMOND)); break; } case E_BLOCK_EMERALD_ORE: { - ItemType = E_ITEM_EMERALD; + a_Pickups.push_back(cItem(E_ITEM_EMERALD)); break; } case E_BLOCK_COAL_ORE: { - ItemType = E_ITEM_COAL; + a_Pickups.push_back(cItem(E_ITEM_COAL)); break; } + default: + { + ASSERT(!"Unhandled ore!"); + } } - a_Pickups.push_back(cItem(ItemType, Count, Meta)); } } ; diff --git a/src/Blocks/BlockPlanks.h b/src/Blocks/BlockPlanks.h index de84ed319..4c5bb4860 100644 --- a/src/Blocks/BlockPlanks.h +++ b/src/Blocks/BlockPlanks.h @@ -24,8 +24,7 @@ public: ) override { a_BlockType = m_BlockType; - NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); - a_BlockMeta = Meta; + a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); return true; } diff --git a/src/Blocks/BlockPortal.h b/src/Blocks/BlockPortal.h index fc74e89d0..8fac2a126 100644 --- a/src/Blocks/BlockPortal.h +++ b/src/Blocks/BlockPortal.h @@ -36,7 +36,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - return; // No pickups + // No pickups } virtual void OnUpdate(cChunkInterface & cChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_PluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override @@ -47,15 +47,15 @@ public: return; } - int PosX = a_Chunk.GetPosX() * 16 + a_RelX; - int PosZ = a_Chunk.GetPosZ() * 16 + a_RelZ; + int PosX = a_Chunk.GetPosX() * cChunkDef::Width + a_RelX; + int PosZ = a_Chunk.GetPosZ() * cChunkDef::Width + a_RelZ; a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, cMonster::mtZombiePigman); } virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - if ((a_RelY - 1 < 0) || (a_RelY + 1 > cChunkDef::Height)) + if ((a_RelY <= 0) || (a_RelY >= cChunkDef::Height)) { return false; // In case someone places a portal with meta 1 or 2 at boundaries, and server tries to get invalid coords at Y - 1 or Y + 1 } diff --git a/src/Blocks/BlockPressurePlate.h b/src/Blocks/BlockPressurePlate.h index adec36eb6..a5c34a776 100644 --- a/src/Blocks/BlockPressurePlate.h +++ b/src/Blocks/BlockPressurePlate.h @@ -17,7 +17,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } @@ -29,7 +29,7 @@ public: } BLOCKTYPE BlockBelow = a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ); - return ((BlockBelow == E_BLOCK_FENCE_GATE) || (BlockBelow == E_BLOCK_FENCE) || cBlockInfo::IsSolid(BlockBelow)); + return (cBlockInfo::IsSolid(BlockBelow)); } } ; diff --git a/src/Blocks/BlockQuartz.h b/src/Blocks/BlockQuartz.h index 2ce7e71e4..edc4fb9c5 100644 --- a/src/Blocks/BlockQuartz.h +++ b/src/Blocks/BlockQuartz.h @@ -25,6 +25,7 @@ public: { a_BlockType = m_BlockType; NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); + if (Meta != E_META_QUARTZ_PILLAR) // Check if the block is a pillar block. { a_BlockMeta = Meta; diff --git a/src/Blocks/BlockRedstone.h b/src/Blocks/BlockRedstone.h index a898c9acb..37d61ed73 100644 --- a/src/Blocks/BlockRedstone.h +++ b/src/Blocks/BlockRedstone.h @@ -26,8 +26,8 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 - a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1)); + // Reset meta to zero + a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1, 0)); } } ; diff --git a/src/Blocks/BlockRedstoneRepeater.h b/src/Blocks/BlockRedstoneRepeater.h index 4c8a6a087..4b18add12 100644 --- a/src/Blocks/BlockRedstoneRepeater.h +++ b/src/Blocks/BlockRedstoneRepeater.h @@ -23,7 +23,7 @@ public: int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + ) override { a_BlockType = m_BlockType; a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetYaw()); @@ -46,7 +46,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(E_ITEM_REDSTONE_REPEATER, 1, 0)); } @@ -59,7 +59,7 @@ public: virtual bool CanBeAt(cChunkInterface & a_ChunkInterface, int a_RelX, int a_RelY, int a_RelZ, const cChunk & a_Chunk) override { - return ((a_RelY > 0) && (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ) != E_BLOCK_AIR)); + return ((a_RelY > 0) && cBlockInfo::IsSolid(a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))); } diff --git a/src/Blocks/BlockStairs.h b/src/Blocks/BlockStairs.h index a7ccf1714..417969a82 100644 --- a/src/Blocks/BlockStairs.h +++ b/src/Blocks/BlockStairs.h @@ -16,8 +16,8 @@ public: { } - - + + virtual bool GetPlacementBlockTypeMeta( cChunkInterface & a_ChunkInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, @@ -53,8 +53,8 @@ public: } return true; } - - + + virtual const char * GetStepSound(void) override { if ( @@ -64,7 +64,7 @@ public: (m_BlockType == E_BLOCK_ACACIA_WOOD_STAIRS) || (m_BlockType == E_BLOCK_BIRCH_WOOD_STAIRS) || (m_BlockType == E_BLOCK_DARK_OAK_WOOD_STAIRS) - ) + ) { return "step.wood"; } @@ -72,17 +72,20 @@ public: return "step.stone"; } + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } + virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override { return true; } - + + static NIBBLETYPE RotationToMetaData(double a_Rotation) { a_Rotation += 90 + 45; // So its not aligned with axis @@ -108,14 +111,11 @@ public: } } - virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override { // Toggle bit 3: return (a_Meta & 0x0b) | ((~a_Meta) & 0x04); } - - } ; diff --git a/src/Blocks/BlockSugarcane.h b/src/Blocks/BlockSugarcane.h index 84d3b2e7d..5902c791b 100644 --- a/src/Blocks/BlockSugarcane.h +++ b/src/Blocks/BlockSugarcane.h @@ -29,6 +29,7 @@ public: { return false; } + switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) { case E_BLOCK_DIRT: diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index c73118870..df5574d5d 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -126,7 +126,7 @@ public: (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)) && (Face == BLOCK_FACE_TOP) - ) + ) { return Face; } @@ -162,7 +162,7 @@ public: (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) - ) + ) { // Torches can be placed on tops of glass and fences, despite them being 'untorcheable' // No need to check for upright orientation, it was done when the torch was placed diff --git a/src/Blocks/BlockTrapdoor.h b/src/Blocks/BlockTrapdoor.h index 6a36ab874..a6327b5c2 100644 --- a/src/Blocks/BlockTrapdoor.h +++ b/src/Blocks/BlockTrapdoor.h @@ -23,7 +23,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(m_BlockType, 1, 0)); } @@ -53,7 +53,7 @@ public: int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + ) override { a_BlockType = m_BlockType; a_BlockMeta = BlockFaceToMetaData(a_BlockFace); @@ -103,9 +103,10 @@ public: a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); - BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + BLOCKTYPE BlockIsOn; + a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn); + return ((a_RelY > 0) && cBlockInfo::IsSolid(BlockIsOn)); } }; diff --git a/src/Blocks/BlockTripwireHook.h b/src/Blocks/BlockTripwireHook.h index f849fb8ad..4f9d79483 100644 --- a/src/Blocks/BlockTripwireHook.h +++ b/src/Blocks/BlockTripwireHook.h @@ -21,10 +21,9 @@ public: int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_CursorX, int a_CursorY, int a_CursorZ, BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta - ) override + ) override { a_BlockType = m_BlockType; - a_BlockMeta = DirectionToMetadata(a_BlockFace); return true; @@ -56,7 +55,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(E_BLOCK_TRIPWIRE_HOOK, 1, 0)); } @@ -66,9 +65,10 @@ public: a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); AddFaceDirection(a_RelX, a_RelY, a_RelZ, MetadataToDirection(Meta), true); - BLOCKTYPE BlockIsOn; a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); + BLOCKTYPE BlockIsOn; + a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY, a_RelZ, BlockIsOn); - return (a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn); + return ((a_RelY > 0) && cBlockInfo::FullyOccupiesVoxel(BlockIsOn)); } virtual const char * GetStepSound(void) override diff --git a/src/Blocks/BlockVine.h b/src/Blocks/BlockVine.h index 1e1f6d8d2..578224c61 100644 --- a/src/Blocks/BlockVine.h +++ b/src/Blocks/BlockVine.h @@ -46,7 +46,7 @@ public: virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override { - // Reset meta to 0 + // Reset meta to zero a_Pickups.push_back(cItem(E_BLOCK_VINES, 1, 0)); } @@ -80,7 +80,7 @@ public: /// Returns true if the specified block type is good for vines to attach to static bool IsBlockAttachable(BLOCKTYPE a_BlockType) { - return (a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType); + return ((a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES) || cBlockInfo::IsSolid(a_BlockType)); } @@ -182,7 +182,7 @@ public: a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block); if (Block == E_BLOCK_AIR) { - if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX * cChunkDef::Width, a_RelY - 1, a_RelZ * cChunkDef::Width, ssVineSpread)) + if (!cRoot::Get()->GetPluginManager()->CallHookBlockSpread((cWorld*) &a_WorldInterface, a_RelX + a_Chunk.GetPosX() * cChunkDef::Width, a_RelY - 1, a_RelZ + a_Chunk.GetPosZ() * cChunkDef::Width, ssVineSpread)) { a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ)); } diff --git a/src/Blocks/CMakeLists.txt b/src/Blocks/CMakeLists.txt index 05b7bfab4..9f971a8bd 100644 --- a/src/Blocks/CMakeLists.txt +++ b/src/Blocks/CMakeLists.txt @@ -57,8 +57,6 @@ SET (HDRS BlockMushroom.h BlockMycelium.h BlockNetherWart.h - BlockNewLeaves.h - BlockNote.h BlockOre.h BlockPiston.h BlockPlanks.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index db9c61082..6b5efbd1f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ cmake_minimum_required (VERSION 2.8.2) project (MCServer) + include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/") include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/jsoncpp/include") include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include") @@ -41,8 +42,8 @@ SET (SRCS LightingThread.cpp LineBlockTracer.cpp LinearInterpolation.cpp - Log.cpp - MCLogger.cpp + LoggerListeners.cpp + Logger.cpp Map.cpp MapManager.cpp MobCensus.cpp @@ -107,8 +108,8 @@ SET (HDRS LineBlockTracer.h LinearInterpolation.h LinearUpscale.h - Log.h - MCLogger.h + Logger.h + LoggerListeners.h Map.h MapManager.h Matrix4.h @@ -234,7 +235,7 @@ endif() # Generate a list of all source files: -set(ALLFILES "") +set(ALLFILES "${SRCS}" "${HDRS}") foreach(folder ${FOLDERS}) get_directory_property(FOLDER_SRCS DIRECTORY ${folder} DEFINITION SRCS) foreach (src ${FOLDER_SRCS}) diff --git a/src/Chunk.cpp b/src/Chunk.cpp index a79a485a6..116c0f3a0 100644 --- a/src/Chunk.cpp +++ b/src/Chunk.cpp @@ -1,3 +1,4 @@ + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #ifndef _WIN32 @@ -579,7 +580,7 @@ void cChunk::Tick(float a_Dt) } for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();) - { + { if (!((*itr)->IsMob())) // Mobs are ticked inside cWorld::TickMobs() (as we don't have to tick them if they are far away from players) { // Tick all entities in this chunk (except mobs): @@ -594,17 +595,19 @@ void cChunk::Tick(float a_Dt) itr = m_Entities.erase(itr); delete ToDelete; } - else if ((*itr)->IsWorldTravellingFrom(m_World)) // Remove all entities that are travelling to another world: + else if ((*itr)->IsWorldTravellingFrom(m_World)) { + // Remove all entities that are travelling to another world MarkDirty(); (*itr)->SetWorldTravellingFrom(NULL); itr = m_Entities.erase(itr); } - else if ( // If any entity moved out of the chunk, move it to the neighbor: + else if ( ((*itr)->GetChunkX() != m_PosX) || ((*itr)->GetChunkZ() != m_PosZ) ) { + // The entity moved out of the chunk, move it to the neighbor MarkDirty(); MoveEntityToNewChunk(*itr); itr = m_Entities.erase(itr); @@ -885,14 +888,14 @@ void cChunk::ApplyWeatherToTop() SetBlock(X, Height, Z, E_BLOCK_ICE, 0); } else if ( - (m_World->IsDeepSnowEnabled()) && - ( - (TopBlock == E_BLOCK_RED_ROSE) || - (TopBlock == E_BLOCK_YELLOW_FLOWER) || - (TopBlock == E_BLOCK_RED_MUSHROOM) || - (TopBlock == E_BLOCK_BROWN_MUSHROOM) - ) + (m_World->IsDeepSnowEnabled()) && + ( + (TopBlock == E_BLOCK_RED_ROSE) || + (TopBlock == E_BLOCK_YELLOW_FLOWER) || + (TopBlock == E_BLOCK_RED_MUSHROOM) || + (TopBlock == E_BLOCK_BROWN_MUSHROOM) ) + ) { SetBlock(X, Height, Z, E_BLOCK_SNOW, 0); } @@ -2142,10 +2145,14 @@ bool cChunk::DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_Blo case E_BLOCK_DROPPER: case E_BLOCK_DISPENSER: case E_BLOCK_NOTE_BLOCK: + { break; + } default: + { // There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out return false; + } } if (a_Callback.Item((cRedstonePoweredEntity *)*itr)) diff --git a/src/Chunk.h b/src/Chunk.h index 813a8b13f..72a1f6c95 100644 --- a/src/Chunk.h +++ b/src/Chunk.h @@ -241,7 +241,7 @@ public: bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible /** Calls the callback for the redstone powered entity at the specified coords; returns false if there's no redstone powered entity at those coords, true if found */ - bool DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback); + bool DoWithRedstonePoweredEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cRedstonePoweredCallback & a_Callback); /** Calls the callback for the beacon at the specified coords; returns false if there's no beacon at those coords, true if found */ bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 3e046f38d..d386f3576 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -341,8 +341,8 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID, m_Protocol->SendWeather(World->GetWeather()); } - // Send time - m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay()); + // Send time: + m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay(), World->IsDaylightCycleEnabled()); // Send contents of the inventory window m_Protocol->SendWholeInventory(*m_Player->GetWindow()); @@ -2589,9 +2589,9 @@ void cClientHandle::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) -void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cClientHandle::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { - m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay); + m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index ee1db3155..7ae70a07f 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -179,7 +179,7 @@ public: void SendTabCompletionResults(const AStringVector & a_Results); void SendTeleportEntity (const cEntity & a_Entity); void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); - void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay); + void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle); // tolua_export void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); diff --git a/src/CompositeChat.cpp b/src/CompositeChat.cpp index f1a797897..0d339021e 100644 --- a/src/CompositeChat.cpp +++ b/src/CompositeChat.cpp @@ -353,23 +353,23 @@ AString cCompositeChat::ExtractText(void) const -cMCLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) +cLogger::eLogLevel cCompositeChat::MessageTypeToLogLevel(eMessageType a_MessageType) { switch (a_MessageType) { - case mtCustom: return cMCLogger::llRegular; - case mtFailure: return cMCLogger::llWarning; - case mtInformation: return cMCLogger::llInfo; - case mtSuccess: return cMCLogger::llRegular; - case mtWarning: return cMCLogger::llWarning; - case mtFatal: return cMCLogger::llError; - case mtDeath: return cMCLogger::llRegular; - case mtPrivateMessage: return cMCLogger::llRegular; - case mtJoin: return cMCLogger::llRegular; - case mtLeave: return cMCLogger::llRegular; + case mtCustom: return cLogger::llRegular; + case mtFailure: return cLogger::llWarning; + case mtInformation: return cLogger::llInfo; + case mtSuccess: return cLogger::llRegular; + case mtWarning: return cLogger::llWarning; + case mtFatal: return cLogger::llError; + case mtDeath: return cLogger::llRegular; + case mtPrivateMessage: return cLogger::llRegular; + case mtJoin: return cLogger::llRegular; + case mtLeave: return cLogger::llRegular; } ASSERT(!"Unhandled MessageType"); - return cMCLogger::llError; + return cLogger::llError; } diff --git a/src/CompositeChat.h b/src/CompositeChat.h index 1ad196f1d..2dc21b98f 100644 --- a/src/CompositeChat.h +++ b/src/CompositeChat.h @@ -196,7 +196,7 @@ public: /** Converts the MessageType to a LogLevel value. Used by the logging bindings when logging a cCompositeChat object. */ - static cMCLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); + static cLogger::eLogLevel MessageTypeToLogLevel(eMessageType a_MessageType); protected: /** All the parts that */ diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 4398a5bf3..32290885d 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -225,16 +225,24 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk) SendExperience(); } + bool CanMove = true; if (!GetPosition().EqualsEps(m_LastPos, 0.01)) // Non negligible change in position from last tick? { // Apply food exhaustion from movement: ApplyFoodExhaustionFromMovement(); - cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this); + if (cRoot::Get()->GetPluginManager()->CallHookPlayerMoving(*this, m_LastPos, GetPosition())) + { + CanMove = false; + TeleportToCoords(m_LastPos.x, m_LastPos.y, m_LastPos.z); + } m_ClientHandle->StreamChunks(); } - BroadcastMovementUpdate(m_ClientHandle); + if (CanMove) + { + BroadcastMovementUpdate(m_ClientHandle); + } if (m_Health > 0) // make sure player is alive { @@ -884,7 +892,7 @@ void cPlayer::KilledBy(TakeDamageInfo & a_TDI) Pickups.Add(cItem(E_ITEM_RED_APPLE)); } - m_Stats.AddValue(statItemsDropped, Pickups.Size()); + m_Stats.AddValue(statItemsDropped, (StatValue)Pickups.Size()); m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10); SaveToDisk(); // Save it, yeah the world is a tough place ! @@ -1610,7 +1618,7 @@ void cPlayer::TossPickup(const cItem & a_Item) void cPlayer::TossItems(const cItems & a_Items) { - m_Stats.AddValue(statItemsDropped, a_Items.Size()); + m_Stats.AddValue(statItemsDropped, (StatValue)a_Items.Size()); double vX = 0, vY = 0, vZ = 0; EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); @@ -1834,6 +1842,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World) bool cPlayer::SaveToDisk() { + cFile::CreateFolder(FILE_IO_PREFIX + AString("players/")); // Create the "players" folder, if it doesn't exist yet (#1268) cFile::CreateFolder(FILE_IO_PREFIX + AString("players/") + m_UUID.substr(0, 2)); // create the JSON data diff --git a/src/Generating/HeiGen.cpp b/src/Generating/HeiGen.cpp index ba11b31b4..c3f3b38a9 100644 --- a/src/Generating/HeiGen.cpp +++ b/src/Generating/HeiGen.cpp @@ -432,7 +432,7 @@ const cHeiGenBiomal::sGenParam cHeiGenBiomal::m_GenParam[256] = /* biExtremeHillsM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 131 /* biFlowerForest */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 132 /* biTaigaM */ { 0.1f, 2.0f, 0.05f, 12.0f, 0.01f, 10.0f, 40}, // 133 - /* biSwamplandM */ { 1.0f, 2.0f, 1.10f, 5.0f, 0.01f, 8.0f, 60}, // 134 + /* biSwamplandM */ { 1.0f, 3.0f, 1.10f, 7.0f, 0.01f, 0.01f, 60}, // 134 // Biomes 135 .. 139 unused, 5 empty placeholders here: {}, {}, {}, {}, {}, // 135 .. 139 diff --git a/src/Globals.h b/src/Globals.h index 60ee456c9..de1024010 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -249,7 +249,7 @@ template class SizeChecker<UInt16, 2>; #include "OSSupport/Event.h" #include "OSSupport/Thread.h" #include "OSSupport/File.h" - #include "MCLogger.h" + #include "Logger.h" #else // Logging functions void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); diff --git a/src/Items/ItemGoldenApple.h b/src/Items/ItemGoldenApple.h index 4e1096e65..02ac0202c 100644 --- a/src/Items/ItemGoldenApple.h +++ b/src/Items/ItemGoldenApple.h @@ -29,7 +29,7 @@ public: a_Player->AddEntityEffect(cEntityEffect::effRegeneration, 100, 1); // When the apple is a 'notch apple', give extra effects: - if (a_Item->m_ItemDamage > 0) + if (a_Item->m_ItemDamage >= E_META_GOLDEN_APPLE_ENCHANTED) { a_Player->AddEntityEffect(cEntityEffect::effRegeneration, 600, 4); a_Player->AddEntityEffect(cEntityEffect::effResistance, 6000, 0); diff --git a/src/Items/ItemShovel.h b/src/Items/ItemShovel.h index 7d5760fa9..cd235678d 100644 --- a/src/Items/ItemShovel.h +++ b/src/Items/ItemShovel.h @@ -19,7 +19,6 @@ public: cItemShovelHandler(int a_ItemType) : cItemHandler(a_ItemType) { - } virtual bool OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, const cItem & a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Dir) override diff --git a/src/Log.cpp b/src/Log.cpp deleted file mode 100644 index 7686a0fb4..000000000 --- a/src/Log.cpp +++ /dev/null @@ -1,169 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include "Log.h" - -#include <fstream> -#include <ctime> -#include "OSSupport/IsThread.h" - -#if defined(ANDROID_NDK) - #include <android/log.h> - #include "ToJava.h" -#endif - - - - -cLog* cLog::s_Log = NULL; - -cLog::cLog(const AString & a_FileName) - : m_File(NULL) -{ - s_Log = this; - - // create logs directory - cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); - - OpenLog((FILE_IO_PREFIX + AString("logs/") + a_FileName).c_str()); -} - - - - - -cLog::~cLog() -{ - CloseLog(); - s_Log = NULL; -} - - - - - -cLog * cLog::GetInstance() -{ - if (s_Log != NULL) - { - return s_Log; - } - - new cLog("log.txt"); - return s_Log; -} - - - - - -void cLog::CloseLog() -{ - if (m_File) - fclose (m_File); - m_File = 0; -} - - - - - -void cLog::OpenLog( const char* a_FileName) -{ - if (m_File) fclose (m_File); - #ifdef _MSC_VER - fopen_s( &m_File, a_FileName, "a+"); - #else - m_File = fopen(a_FileName, "a+"); - #endif -} - - - - - -void cLog::ClearLog() -{ - #ifdef _MSC_VER - if (fopen_s( &m_File, "log.txt", "w") == 0) - fclose (m_File); - #else - m_File = fopen("log.txt", "w"); - if (m_File) - fclose (m_File); - #endif - m_File = NULL; -} - - - - - -void cLog::Log(const char * a_Format, va_list argList) -{ - AString Message; - AppendVPrintf(Message, a_Format, argList); - - time_t rawtime; - time ( &rawtime); - - struct tm* timeinfo; -#ifdef _MSC_VER - struct tm timeinforeal; - timeinfo = &timeinforeal; - localtime_s(timeinfo, &rawtime); -#else - timeinfo = localtime( &rawtime); -#endif - - AString Line; - #ifdef _DEBUG - Printf(Line, "[%04lx|%02d:%02d:%02d] %s", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); - #else - Printf(Line, "[%02d:%02d:%02d] %s", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, Message.c_str()); - #endif - if (m_File) - { - fprintf(m_File, "%s\n", Line.c_str()); - fflush(m_File); - } - - // Print to console: -#if defined(ANDROID_NDK) - // __android_log_vprint(ANDROID_LOG_ERROR, "MCServer", a_Format, argList); - __android_log_print(ANDROID_LOG_ERROR, "MCServer", "%s", Line.c_str()); - // CallJavaFunction_Void_String(g_JavaThread, "AddToLog", Line); -#else - printf("%s", Line.c_str()); -#endif - - #if defined (_WIN32) && defined(_DEBUG) - // In a Windows Debug build, output the log to debug console as well: - OutputDebugStringA((Line + "\n").c_str()); - #endif // _WIN32 -} - - - - - -void cLog::Log(const char * a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - Log(a_Format, argList); - va_end(argList); -} - - - - - -void cLog::SimpleLog(const char * a_String) -{ - Log("%s", a_String); -} - - - - diff --git a/src/Log.h b/src/Log.h deleted file mode 100644 index dc88aa92f..000000000 --- a/src/Log.h +++ /dev/null @@ -1,30 +0,0 @@ - -#pragma once - - - - - -class cLog -{ -private: - FILE * m_File; - static cLog * s_Log; - -public: - cLog(const AString & a_FileName); - ~cLog(); - void Log(const char * a_Format, va_list argList) FORMATSTRING(2, 0); - void Log(const char * a_Format, ...) FORMATSTRING(2, 3); - // tolua_begin - void SimpleLog(const char * a_String); - void OpenLog(const char * a_FileName); - void CloseLog(); - void ClearLog(); - static cLog* GetInstance(); -}; - - - - - diff --git a/src/Logger.cpp b/src/Logger.cpp new file mode 100644 index 000000000..cb528e8ab --- /dev/null +++ b/src/Logger.cpp @@ -0,0 +1,145 @@ + +#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules + +#include "OSSupport/IsThread.h" +#ifdef _WIN32 + #include <time.h> +#endif + + + + + +cLogger & cLogger::GetInstance(void) +{ + static cLogger Instance; + return Instance; +} + + + + + +void cLogger::InitiateMultithreading() +{ + GetInstance(); +} + + + + + +void cLogger::LogSimple(AString a_Message, eLogLevel a_LogLevel) +{ + time_t rawtime; + time(&rawtime); + + struct tm * timeinfo; + #ifdef _MSC_VER + struct tm timeinforeal; + timeinfo = &timeinforeal; + localtime_s(timeinfo, &rawtime); + #else + timeinfo = localtime(&rawtime); + #endif + + AString Line; + #ifdef _DEBUG + Printf(Line, "[%04lx|%02d:%02d:%02d] %s\n", cIsThread::GetCurrentID(), timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + #else + Printf(Line, "[%02d:%02d:%02d] %s\n", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, a_Message.c_str()); + #endif + + + cCSLock Lock(m_CriticalSection); + for (size_t i = 0; i < m_LogListeners.size(); i++) + { + m_LogListeners[i]->Log(Line, a_LogLevel); + } +} + + + + + +void cLogger::Log(const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) +{ + AString Message; + AppendVPrintf(Message, a_Format, a_ArgList); + LogSimple(Message, a_LogLevel); +} + + + + + +void cLogger::AttachListener(cListener * a_Listener) +{ + cCSLock Lock(m_CriticalSection); + m_LogListeners.push_back(a_Listener); +} + + + + + +void cLogger::DetachListener(cListener * a_Listener) +{ + cCSLock Lock(m_CriticalSection); + m_LogListeners.erase(std::remove(m_LogListeners.begin(), m_LogListeners.end(), a_Listener)); +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// Global functions + +void LOG(const char * a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log(a_Format, cLogger::llRegular, argList); + va_end(argList); +} + + + + + +void LOGINFO(const char * a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llInfo, argList); + va_end(argList); +} + + + + + +void LOGWARN(const char * a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llWarning, argList); + va_end(argList); +} + + + + + +void LOGERROR(const char * a_Format, ...) +{ + va_list argList; + va_start(argList, a_Format); + cLogger::GetInstance().Log( a_Format, cLogger::llError, argList); + va_end(argList); +} + + + + diff --git a/src/Logger.h b/src/Logger.h new file mode 100644 index 000000000..5e65de8a8 --- /dev/null +++ b/src/Logger.h @@ -0,0 +1,73 @@ + +#pragma once + + +class cLogger +{ +public: + + enum eLogLevel + { + llRegular, + llInfo, + llWarning, + llError, + }; + + + class cListener + { + public: + virtual void Log(AString a_Message, eLogLevel a_LogLevel) = 0; + + virtual ~cListener(){} + }; + + void Log (const char * a_Format, eLogLevel a_LogLevel, va_list a_ArgList) FORMATSTRING(2, 0); + + /** Logs the simple text message at the specified log level. */ + void LogSimple(AString a_Message, eLogLevel a_LogLevel = llRegular); + + void AttachListener(cListener * a_Listener); + void DetachListener(cListener * a_Listener); + + static cLogger & GetInstance(void); + // Must be called before calling GetInstance in a multithreaded context + static void InitiateMultithreading(); +private: + + cCriticalSection m_CriticalSection; + std::vector<cListener *> m_LogListeners; + +}; + + + + + + +extern void LOG(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1, 2); +extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); + + + + + +// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: +#ifdef _DEBUG + #define LOGD LOG +#else + #define LOGD(...) +#endif // _DEBUG + + + + + +#define LOGWARNING LOGWARN + + + + diff --git a/src/LoggerListeners.cpp b/src/LoggerListeners.cpp new file mode 100644 index 000000000..836536cbd --- /dev/null +++ b/src/LoggerListeners.cpp @@ -0,0 +1,322 @@ + +#include "Globals.h" + +#include "LoggerListeners.h" + +#if defined(_WIN32) + #include <io.h> // Needed for _isatty(), not available on Linux + #include <time.h> +#elif defined(__linux) && !defined(ANDROID_NDK) + #include <unistd.h> // Needed for isatty() on Linux +#elif defined(ANDROID_NDK) + #include <android/log.h> +#endif + + +#if defined(_WIN32) || (defined (__linux) && !defined(ANDROID_NDK)) + class cColouredConsoleListener + : public cLogger::cListener + { + protected: + + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) = 0; + virtual void SetDefaultLogColour() = 0; + + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + SetLogColour(a_LogLevel); + fputs(a_Message.c_str(), stdout); + SetDefaultLogColour(); + } + }; +#endif + + + + + +#ifdef _WIN32 + class cWindowsConsoleListener + : public cColouredConsoleListener + { + typedef cColouredConsoleListener super; + public: + cWindowsConsoleListener(HANDLE a_Console, WORD a_DefaultConsoleAttrib) : + m_Console(a_Console), + m_DefaultConsoleAttrib(a_DefaultConsoleAttrib) + { + } + + #ifdef _DEBUG + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + super::Log(a_Message, a_LogLevel); + // In a Windows Debug build, output the log to debug console as well: + OutputDebugStringA(a_Message.c_str()); + } + #endif + + + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) override + { + // by default, gray on black + WORD Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + switch (a_LogLevel) + { + case cLogger::llRegular: + { + // Gray on black + Attrib = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED; + break; + } + case cLogger::llInfo: + { + // Yellow on black + Attrib = FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + } + case cLogger::llWarning: + { + // Red on black + Attrib = FOREGROUND_RED | FOREGROUND_INTENSITY; + break; + } + case cLogger::llError: + { + // Black on red + Attrib = BACKGROUND_RED | BACKGROUND_INTENSITY; + break; + } + } + SetConsoleTextAttribute(m_Console, Attrib); + } + + + virtual void SetDefaultLogColour() override + { + SetConsoleTextAttribute(m_Console, m_DefaultConsoleAttrib); + } + + private: + + HANDLE m_Console; + WORD m_DefaultConsoleAttrib; + }; + + + +#elif defined (__linux) && !defined(ANDROID_NDK) + + + + class cLinuxConsoleListener + : public cColouredConsoleListener + { + public: + virtual void SetLogColour(cLogger::eLogLevel a_LogLevel) override + { + switch (a_LogLevel) + { + case cLogger::llRegular: + { + // Whatever the console default is + printf("\x1b[0m"); + break; + } + case cLogger::llInfo: + { + // Yellow on black + printf("\x1b[33;1m"); + break; + } + case cLogger::llWarning: + { + // Red on black + printf("\x1b[31;1m"); + break; + } + case cLogger::llError: + { + // Yellow on red + printf("\x1b[1;33;41;1m"); + break; + } + } + } + + + virtual void SetDefaultLogColour() override + { + // Whatever the console default is + printf("\x1b[0m"); + } + }; + + + +#elif defined(ANDROID_NDK) + + + + class cAndroidConsoleListener + : public cLogger::cListener + { + public: + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + android_LogPriority AndroidLogLevel; + switch (a_LogLevel) + { + case cLogger::llRegular: + { + AndroidLogLevel = ANDROID_LOG_VERBOSE; + break; + } + case cLogger::llInfo: + { + AndroidLogLevel = ANDROID_LOG_INFO; + break; + } + case cLogger::llWarning: + { + AndroidLogLevel = ANDROID_LOG_WARNING; + break; + } + case cLogger::llError: + { + AndroidLogLevel = ANDROID_LOG_ERROR; + break; + } + } + __android_log_print(AndroidLogLevel, "MCServer", "%s", a_Message.c_str()); + } + }; + +#endif + + + + + +class cVanillaCPPConsoleListener + : public cLogger::cListener +{ +public: + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override + { + AString LogLevelString; + switch (a_LogLevel) + { + case cLogger::llRegular: + { + LogLevelString = "Log"; + break; + } + case cLogger::llInfo: + { + LogLevelString = "Info"; + break; + } + case cLogger::llWarning: + { + LogLevelString = "Warning"; + break; + } + case cLogger::llError: + { + LogLevelString = "Error"; + break; + } + } + printf("%s: %s", LogLevelString.c_str(), a_Message.c_str()); + } +}; + + + + + +cLogger::cListener * MakeConsoleListener(void) +{ + #ifdef _WIN32 + // See whether we are writing to a console the default console attrib: + bool ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); + if (ShouldColorOutput) + { + CONSOLE_SCREEN_BUFFER_INFO sbi; + HANDLE Console = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(Console, &sbi); + WORD DefaultConsoleAttrib = sbi.wAttributes; + return new cWindowsConsoleListener(Console, DefaultConsoleAttrib); + } + else + { + return new cVanillaCPPConsoleListener; + } + + #elif defined (__linux) && !defined(ANDROID_NDK) + // TODO: lookup terminal in terminfo + if (isatty(fileno(stdout))) + { + return new cLinuxConsoleListener(); + } + else + { + return new cVanillaCPPConsoleListener(); + } + #else + return new cVanillaCPPConsoleListener(); + #endif +} + + + + + +//////////////////////////////////////////////////////////////////////////////// +// cFileListener: + +cFileListener::cFileListener(void) +{ + cFile::CreateFolder(FILE_IO_PREFIX + AString("logs")); + AString FileName; + FileName = Printf("%s%sLOG_%d.txt", FILE_IO_PREFIX, "logs/", (int)time(NULL)); + m_File.Open(FileName, cFile::fmAppend); +} + + + + + +void cFileListener::Log(AString a_Message, cLogger::eLogLevel a_LogLevel) +{ + const char * LogLevelPrefix = "Unkn "; + switch (a_LogLevel) + { + case cLogger::llRegular: + { + LogLevelPrefix = " "; + break; + } + case cLogger::llInfo: + { + LogLevelPrefix = "info "; + break; + } + case cLogger::llWarning: + { + LogLevelPrefix = "Warn "; + break; + } + case cLogger::llError: + { + LogLevelPrefix = "Err "; + break; + } + } + m_File.Printf("%s%s", LogLevelPrefix, a_Message.c_str()); +} + + + + diff --git a/src/LoggerListeners.h b/src/LoggerListeners.h new file mode 100644 index 000000000..d300184b1 --- /dev/null +++ b/src/LoggerListeners.h @@ -0,0 +1,31 @@ + +#include "Logger.h" + + + + + +class cFileListener + : public cLogger::cListener +{ +public: + + cFileListener(); + cFileListener(AString a_Filename); + + virtual void Log(AString a_Message, cLogger::eLogLevel a_LogLevel) override; + +private: + + cFile m_File; +}; + + + + + +cLogger::cListener * MakeConsoleListener(); + + + + diff --git a/src/MCLogger.cpp b/src/MCLogger.cpp deleted file mode 100644 index 044e83937..000000000 --- a/src/MCLogger.cpp +++ /dev/null @@ -1,267 +0,0 @@ - -#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules - -#include <time.h> -#include "Log.h" - - - - - -cMCLogger * cMCLogger::s_MCLogger = NULL; - -#ifdef _WIN32 - #include <io.h> // Needed for _isatty(), not available on Linux - - HANDLE g_Console = GetStdHandle(STD_OUTPUT_HANDLE); - WORD g_DefaultConsoleAttrib = 0x07; -#elif defined (__linux) && !defined(ANDROID_NDK) - #include <unistd.h> // Needed for isatty() on Linux -#endif - - - - - -cMCLogger * cMCLogger::GetInstance(void) -{ - return s_MCLogger; -} - - - - - -cMCLogger::cMCLogger(void): - m_ShouldColorOutput(false) -{ - AString FileName; - Printf(FileName, "LOG_%d.txt", (int)time(NULL)); - InitLog(FileName); -} - - - - - -cMCLogger::cMCLogger(const AString & a_FileName) -{ - InitLog(a_FileName); -} - - - - - -cMCLogger::~cMCLogger() -{ - m_Log->Log("--- Stopped Log ---\n"); - delete m_Log; - m_Log = NULL; - if (this == s_MCLogger) - { - s_MCLogger = NULL; - } -} - - - - - -void cMCLogger::InitLog(const AString & a_FileName) -{ - m_Log = new cLog(a_FileName); - m_Log->Log("--- Started Log ---\n"); - - s_MCLogger = this; - - #ifdef _WIN32 - // See whether we are writing to a console the default console attrib: - m_ShouldColorOutput = (_isatty(_fileno(stdin)) != 0); - if (m_ShouldColorOutput) - { - CONSOLE_SCREEN_BUFFER_INFO sbi; - GetConsoleScreenBufferInfo(g_Console, &sbi); - g_DefaultConsoleAttrib = sbi.wAttributes; - } - #elif defined (__linux) && !defined(ANDROID_NDK) - m_ShouldColorOutput = isatty(fileno(stdout)); - // TODO: Check if the terminal supports colors, somehow? - #endif -} - - - - - -void cMCLogger::LogSimple(const char * a_Text, eLogLevel a_LogLevel) -{ - switch (a_LogLevel) - { - case llRegular: - { - LOG("%s", a_Text); - break; - } - case llInfo: - { - LOGINFO("%s", a_Text); - break; - } - case llWarning: - { - LOGWARN("%s", a_Text); - break; - } - case llError: - { - LOGERROR("%s", a_Text); - break; - } - } -} - - - - - -void cMCLogger::Log(const char * a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor(csRegular); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); -} - - - - - -void cMCLogger::Info(const char * a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor(csInfo); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); -} - - - - - -void cMCLogger::Warn(const char * a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor(csWarning); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); -} - - - - - -void cMCLogger::Error(const char * a_Format, va_list a_ArgList) -{ - cCSLock Lock(m_CriticalSection); - SetColor(csError); - m_Log->Log(a_Format, a_ArgList); - ResetColor(); - puts(""); -} - - - - - -void cMCLogger::SetColor(eColorScheme a_Scheme) -{ - if (!m_ShouldColorOutput) - { - return; - } - #ifdef _WIN32 - WORD Attrib = 0x07; // by default, gray on black - switch (a_Scheme) - { - case csRegular: Attrib = 0x07; break; // Gray on black - case csInfo: Attrib = 0x0e; break; // Yellow on black - case csWarning: Attrib = 0x0c; break; // Read on black - case csError: Attrib = 0xc0; break; // Black on red - default: ASSERT(!"Unhandled color scheme"); - } - SetConsoleTextAttribute(g_Console, Attrib); - #elif defined(__linux) && !defined(ANDROID_NDK) - switch (a_Scheme) - { - case csRegular: printf("\x1b[0m"); break; // Whatever the console default is - case csInfo: printf("\x1b[33;1m"); break; // Yellow on black - case csWarning: printf("\x1b[31;1m"); break; // Red on black - case csError: printf("\x1b[1;33;41;1m"); break; // Yellow on red - default: ASSERT(!"Unhandled color scheme"); - } - #endif -} - - - - - -void cMCLogger::ResetColor(void) -{ - if (!m_ShouldColorOutput) - { - return; - } - #ifdef _WIN32 - SetConsoleTextAttribute(g_Console, g_DefaultConsoleAttrib); - #elif defined(__linux) && !defined(ANDROID_NDK) - printf("\x1b[0m"); - #endif -} - - - - - -//////////////////////////////////////////////////////////////////////////////// -// Global functions - -void LOG(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Log( a_Format, argList); - va_end(argList); -} - -void LOGINFO(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Info( a_Format, argList); - va_end(argList); -} - -void LOGWARN(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Warn( a_Format, argList); - va_end(argList); -} - -void LOGERROR(const char* a_Format, ...) -{ - va_list argList; - va_start(argList, a_Format); - cMCLogger::GetInstance()->Error( a_Format, argList); - va_end(argList); -} - - - - diff --git a/src/MCLogger.h b/src/MCLogger.h deleted file mode 100644 index aa3a52d02..000000000 --- a/src/MCLogger.h +++ /dev/null @@ -1,95 +0,0 @@ - -#pragma once - - - - -class cLog; - - - - - -class cMCLogger -{ -public: - enum eLogLevel - { - llRegular, - llInfo, - llWarning, - llError, - }; - // tolua_end - - /** Creates a logger with the default filename, "logs/LOG_<timestamp>.log" */ - cMCLogger(void); - - /** Creates a logger with the specified filename inside "logs" folder */ - cMCLogger(const AString & a_FileName); - - ~cMCLogger(); - - void Log (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Info (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Warn (const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - void Error(const char * a_Format, va_list a_ArgList) FORMATSTRING(2, 0); - - /** Logs the simple text message at the specified log level. */ - void LogSimple(const char * a_Text, eLogLevel a_LogLevel = llRegular); - - static cMCLogger * GetInstance(); -private: - enum eColorScheme - { - csRegular, - csInfo, - csWarning, - csError, - } ; - - cCriticalSection m_CriticalSection; - cLog * m_Log; - static cMCLogger * s_MCLogger; - bool m_ShouldColorOutput; - - - /// Sets the specified color scheme in the terminal (TODO: if coloring available) - void SetColor(eColorScheme a_Scheme); - - /// Resets the color back to whatever is the default in the terminal - void ResetColor(void); - - /// Common initialization for all constructors, creates a logfile with the specified name and assigns s_MCLogger to this - void InitLog(const AString & a_FileName); -}; - - - - - -extern void LOG(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGINFO(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGWARN(const char* a_Format, ...) FORMATSTRING(1, 2); -extern void LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); - - - - - -// In debug builds, translate LOGD to LOG, otherwise leave it out altogether: -#ifdef _DEBUG - #define LOGD LOG -#else - #define LOGD(...) -#endif // _DEBUG - - - - - -#define LOGWARNING LOGWARN - - - - diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index ff6fb5898..2194c46ee 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -70,6 +70,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode) case fmRead: Mode = "rb"; break; case fmWrite: Mode = "wb"; break; case fmReadWrite: Mode = "rb+"; break; + case fmAppend: Mode = "a+"; break; } if (Mode == NULL) { @@ -255,10 +256,10 @@ int cFile::ReadRestOfFile(AString & a_Contents) return -1; } - int DataSize = GetSize() - Tell(); + size_t DataSize = GetSize() - Tell(); // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly - a_Contents.assign((size_t)DataSize, '\0'); + a_Contents.assign(DataSize, '\0'); return Read((void *)a_Contents.data(), DataSize); } @@ -459,7 +460,7 @@ int cFile::Printf(const char * a_Fmt, ...) va_start(args, a_Fmt); AppendVPrintf(buf, a_Fmt, args); va_end(args); - return Write(buf.c_str(), (int)buf.length()); + return Write(buf.c_str(), buf.length()); } diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index 2a7ecf0ed..dfb38e839 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -60,9 +60,10 @@ public: /** The mode in which to open the file */ enum eMode { - fmRead, // Read-only. If the file doesn't exist, object will not be valid - fmWrite, // Write-only. If the file already exists, it will be overwritten - fmReadWrite // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning + fmRead, // Read-only. If the file doesn't exist, object will not be valid + fmWrite, // Write-only. If the file already exists, it will be overwritten + fmReadWrite, // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning + fmAppend // Write-only. If the file already exists cursor will be moved to the end of the file } ; /** Simple constructor - creates an unopened file object, use Open() to open / create a real file */ diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index d110f2af9..8e1842ec1 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -116,7 +116,7 @@ public: virtual void SendTabCompletionResults(const AStringVector & a_Results) = 0; virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) = 0; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) = 0; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0; diff --git a/src/Protocol/Protocol125.cpp b/src/Protocol/Protocol125.cpp index 538d31642..a66c64309 100644 --- a/src/Protocol/Protocol125.cpp +++ b/src/Protocol/Protocol125.cpp @@ -1072,8 +1072,11 @@ void cProtocol125::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) -void cProtocol125::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cProtocol125::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { + // This protocol doesn't support a_DoDaylightCycle on false. + UNUSED(a_DoDaylightCycle); + cCSLock Lock(m_CSPacket); WriteByte (PACKET_UPDATE_TIME); // Use a_WorldAge for daycount, and a_TimeOfDay for the proper time of day: diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 3adac3055..1063777a2 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -88,7 +88,7 @@ public: virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override {} virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; diff --git a/src/Protocol/Protocol14x.cpp b/src/Protocol/Protocol14x.cpp index 8b177ea48..3b6b6a42a 100644 --- a/src/Protocol/Protocol14x.cpp +++ b/src/Protocol/Protocol14x.cpp @@ -130,8 +130,14 @@ void cProtocol142::SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_Src -void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cProtocol142::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { + if (!a_DoDaylightCycle) + { + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); + } + cCSLock Lock(m_CSPacket); WriteByte (PACKET_UPDATE_TIME); WriteInt64(a_WorldAge); diff --git a/src/Protocol/Protocol14x.h b/src/Protocol/Protocol14x.h index ca497bbc1..227cc8cc7 100644 --- a/src/Protocol/Protocol14x.h +++ b/src/Protocol/Protocol14x.h @@ -34,7 +34,7 @@ public: // Sending commands (alphabetically sorted): virtual void SendPickupSpawn (const cPickup & a_Pickup) override; virtual void SendSoundParticleEffect(int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; // Specific packet parsers: virtual int ParseLocaleViewDistance(void) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 59db0b7d8..a8df948cd 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -1290,9 +1290,14 @@ void cProtocol172::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ) -void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { ASSERT(m_State == 3); // In game mode? + if (!a_DoDaylightCycle) + { + // When writing a "-" before the number the client ignores it but it will stop the client-side time expiration. + a_TimeOfDay = std::min(-a_TimeOfDay, -1LL); + } cPacketizer Pkt(*this, 0x03); Pkt.WriteInt64(a_WorldAge); diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 9c9f563e0..ccfa19eb6 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -120,7 +120,7 @@ public: virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 6e6cb3caf..c831da251 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -717,10 +717,10 @@ void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_Bloc -void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay) +void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) { ASSERT(m_Protocol != NULL); - m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay); + m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 796464202..a05aeda70 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -123,7 +123,7 @@ public: virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; - virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; + virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; diff --git a/src/Root.cpp b/src/Root.cpp index c20cf0d21..ee0d9b835 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -18,6 +18,7 @@ #include "CommandOutput.h" #include "DeadlockDetect.h" #include "OSSupport/Timer.h" +#include "LoggerListeners.h" #include "inifile/iniFile.h" @@ -51,7 +52,6 @@ cRoot::cRoot(void) : m_FurnaceRecipe(NULL), m_WebAdmin(NULL), m_PluginManager(NULL), - m_Log(NULL), m_bStop(false), m_bRestart(false) { @@ -105,10 +105,15 @@ void cRoot::Start(void) HMENU hmenu = GetSystemMenu(hwnd, FALSE); EnableMenuItem(hmenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling #endif + + cLogger::cListener * consoleLogListener = MakeConsoleListener(); + cLogger::cListener * fileLogListener = new cFileListener(); + cLogger::GetInstance().AttachListener(consoleLogListener); + cLogger::GetInstance().AttachListener(fileLogListener); + + LOG("--- Started Log ---\n"); cDeadlockDetect dd; - delete m_Log; - m_Log = new cMCLogger(); m_bStop = false; while (!m_bStop) @@ -249,8 +254,13 @@ void cRoot::Start(void) delete m_Server; m_Server = NULL; LOG("Shutdown successful!"); } - - delete m_Log; m_Log = NULL; + + LOG("--- Stopped Log ---"); + + cLogger::GetInstance().DetachListener(consoleLogListener); + delete consoleLogListener; + cLogger::GetInstance().DetachListener(fileLogListener); + delete fileLogListener; } @@ -274,15 +284,15 @@ void cRoot::LoadWorlds(cIniFile & IniFile) m_WorldsByName[ DefaultWorldName ] = m_pDefaultWorld; // Then load the other worlds - unsigned int KeyNum = IniFile.FindKey("Worlds"); - unsigned int NumWorlds = IniFile.GetNumValues(KeyNum); + int KeyNum = IniFile.FindKey("Worlds"); + int NumWorlds = IniFile.GetNumValues(KeyNum); if (NumWorlds <= 0) { return; } bool FoundAdditionalWorlds = false; - for (unsigned int i = 0; i < NumWorlds; i++) + for (int i = 0; i < NumWorlds; i++) { AString ValueName = IniFile.GetValueName(KeyNum, i); if (ValueName.compare("World") != 0) diff --git a/src/Root.h b/src/Root.h index 1cd175ab4..6840efcbe 100644 --- a/src/Root.h +++ b/src/Root.h @@ -196,8 +196,6 @@ private: cMojangAPI m_MojangAPI; cHTTPServer m_HTTPServer; - cMCLogger * m_Log; - bool m_bStop; bool m_bRestart; diff --git a/src/StringUtils.h b/src/StringUtils.h index 142aaf59b..3d4379352 100644 --- a/src/StringUtils.h +++ b/src/StringUtils.h @@ -12,7 +12,6 @@ - typedef std::string AString; typedef std::vector<AString> AStringVector; typedef std::list<AString> AStringList; diff --git a/src/WebAdmin.cpp b/src/WebAdmin.cpp index ab6925e55..23eedbd14 100644 --- a/src/WebAdmin.cpp +++ b/src/WebAdmin.cpp @@ -159,28 +159,6 @@ void cWebAdmin::Stop(void) -AString cWebAdmin::GetTemplate() -{ - AString retVal = ""; - - char SourceFile[] = "webadmin/template.html"; - - cFile f; - if (!f.Open(SourceFile, cFile::fmRead)) - { - return ""; - } - - // copy the file into the buffer: - f.ReadRestOfFile(retVal); - - return retVal; -} - - - - - void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request) { if (!a_Request.HasAuth()) @@ -198,9 +176,9 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque } // Check if the contents should be wrapped in the template: - AString URL = a_Request.GetBareURL(); - ASSERT(URL.length() > 0); - bool ShouldWrapInTemplate = ((URL.length() > 1) && (URL[1] != '~')); + AString BareURL = a_Request.GetBareURL(); + ASSERT(BareURL.length() > 0); + bool ShouldWrapInTemplate = ((BareURL.length() > 1) && (BareURL[1] != '~')); // Retrieve the request data: cWebadminRequestData * Data = (cWebadminRequestData *)(a_Request.GetUserData()); @@ -215,7 +193,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque HTTPTemplateRequest TemplateRequest; TemplateRequest.Request.Username = a_Request.GetAuthUsername(); TemplateRequest.Request.Method = a_Request.GetMethod(); - TemplateRequest.Request.Path = URL.substr(1); + TemplateRequest.Request.Path = BareURL.substr(1); if (Data->m_Form.Finish()) { @@ -258,7 +236,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque return; } - AString BaseURL = GetBaseURL(URL); + AString BaseURL = GetBaseURL(BareURL); AString Menu; Template = "{CONTENT}"; AString FoundPlugin; diff --git a/src/WebAdmin.h b/src/WebAdmin.h index f48e8ce9e..aefc1d145 100644 --- a/src/WebAdmin.h +++ b/src/WebAdmin.h @@ -208,9 +208,6 @@ protected: /** The HTTP server which provides the underlying HTTP parsing, serialization and events */ cHTTPServer m_HTTPServer; - - AString GetTemplate(void); - /** Handles requests coming to the "/webadmin" or "/~webadmin" URLs */ void HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); diff --git a/src/World.cpp b/src/World.cpp index d2213d1e5..2027e215a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -1,3 +1,4 @@ + #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "BlockID.h" @@ -243,6 +244,7 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin #endif m_Dimension(a_Dimension), m_IsSpawnExplicitlySet(false), + m_IsDaylightCycleEnabled(true), m_WorldAgeSecs(0), m_TimeOfDaySecs(0), m_WorldAge(0), @@ -576,6 +578,7 @@ void cWorld::Start(void) m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", true); + m_IsDaylightCycleEnabled = IniFile.GetValueSetB("General", "IsDaylightCycleEnabled", true); int GameMode = IniFile.GetValueSetI("General", "Gamemode", (int)m_GameMode); int Weather = IniFile.GetValueSetI("General", "Weather", (int)m_Weather); @@ -797,6 +800,7 @@ void cWorld::Stop(void) IniFile.SetValueI("Physics", "TNTShrapnelLevel", (int)m_TNTShrapnelLevel); IniFile.SetValueB("Mechanics", "CommandBlocksEnabled", m_bCommandBlocksEnabled); IniFile.SetValueB("Mechanics", "UseChatPrefixes", m_bUseChatPrefixes); + IniFile.SetValueB("General", "IsDaylightCycleEnabled", m_IsDaylightCycleEnabled); IniFile.SetValueI("General", "Weather", (int)m_Weather); IniFile.SetValueI("General", "TimeInTicks", m_TimeOfDay); IniFile.WriteFile(m_IniFileName); @@ -827,28 +831,32 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec) { SetChunkData(**itr); } // for itr - SetChunkDataQueue[] - - // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it + m_WorldAgeSecs += (double)a_Dt / 1000.0; - m_TimeOfDaySecs += (double)a_Dt / 1000.0; + m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); - // Wrap time of day each 20 minutes (1200 seconds) - if (m_TimeOfDaySecs > 1200.0) + if (m_IsDaylightCycleEnabled) { - m_TimeOfDaySecs -= 1200.0; - } + // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it + m_TimeOfDaySecs += (double)a_Dt / 1000.0; - m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); - m_TimeOfDay = (Int64)(m_TimeOfDaySecs * 20.0); + // Wrap time of day each 20 minutes (1200 seconds) + if (m_TimeOfDaySecs > 1200.0) + { + m_TimeOfDaySecs -= 1200.0; + } - // Updates the sky darkness based on current time of day - UpdateSkyDarkness(); + m_TimeOfDay = (Int64)(m_TimeOfDaySecs * 20.0); - // Broadcast time update every 40 ticks (2 seconds) - if (m_LastTimeUpdate < m_WorldAge - 40) - { - BroadcastTimeUpdate(); - m_LastTimeUpdate = m_WorldAge; + // Updates the sky darkness based on current time of day + UpdateSkyDarkness(); + + // Broadcast time update every 40 ticks (2 seconds) + if (m_LastTimeUpdate < m_WorldAge - 40) + { + BroadcastTimeUpdate(); + m_LastTimeUpdate = m_WorldAge; + } } // Add entities waiting in the queue to be added: @@ -2251,7 +2259,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude) { continue; } - ch->SendTimeUpdate(m_WorldAge, m_TimeOfDay); + ch->SendTimeUpdate(m_WorldAge, m_TimeOfDay, m_IsDaylightCycleEnabled); } } @@ -3320,7 +3328,7 @@ void cWorld::AddQueuedPlayers(void) cCSLock Lock(m_CSPlayers); for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr) { - ASSERT(std::find(m_Players.begin(), m_Players.end(), *itr) == m_Players.end()); // Is it already in the list? HOW? + ASSERT(std::find(m_Players.begin(), m_Players.end(), *itr) == m_Players.end()); // Is it already in the list? HOW? LOGD("Adding player %s to world \"%s\".", (*itr)->GetName().c_str(), m_WorldName.c_str()); m_Players.push_back(*itr); diff --git a/src/World.h b/src/World.h index 90b798e8e..578c9682b 100644 --- a/src/World.h +++ b/src/World.h @@ -145,7 +145,17 @@ public: // tolua_begin int GetTicksUntilWeatherChange(void) const { return m_WeatherInterval; } - + + /** Is the daylight cyclus enabled? */ + virtual bool IsDaylightCycleEnabled(void) const { return m_IsDaylightCycleEnabled; } + + /** Sets the daylight cyclus to true/false. */ + virtual void SetDaylightCycleEnabled(bool a_IsDaylightCycleEnabled) + { + m_IsDaylightCycleEnabled = a_IsDaylightCycleEnabled; + BroadcastTimeUpdate(); + } + virtual Int64 GetWorldAge (void) const override { return m_WorldAge; } virtual Int64 GetTimeOfDay(void) const override { return m_TimeOfDay; } @@ -158,6 +168,7 @@ public: { m_TimeOfDay = a_TimeOfDay; m_TimeOfDaySecs = (double)a_TimeOfDay / 20.0; + UpdateSkyDarkness(); BroadcastTimeUpdate(); } @@ -224,7 +235,7 @@ public: void BroadcastEntityRelMoveLook (const cEntity & a_Entity, char a_RelX, char a_RelY, char a_RelZ, const cClientHandle * a_Exclude = NULL); void BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL); void BroadcastEntityVelocity (const cEntity & a_Entity, const cClientHandle * a_Exclude = NULL); - virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export + virtual void BroadcastEntityAnimation(const cEntity & a_Entity, char a_Animation, const cClientHandle * a_Exclude = NULL) override; // tolua_export void BroadcastParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmmount, cClientHandle * a_Exclude = NULL); // tolua_export void BroadcastPlayerListItem (const cPlayer & a_Player, bool a_IsOnline, const cClientHandle * a_Exclude = NULL); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL); @@ -868,6 +879,7 @@ private: bool m_BroadcastDeathMessages; bool m_BroadcastAchievementMessages; + bool m_IsDaylightCycleEnabled; double m_WorldAgeSecs; // World age, in seconds. Is only incremented, cannot be set by plugins. double m_TimeOfDaySecs; // Time of day in seconds. Can be adjusted. Is wrapped to zero each day. Int64 m_WorldAge; // World age in ticks, calculated off of m_WorldAgeSecs diff --git a/src/main.cpp b/src/main.cpp index 106233342..86ecd4000 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -273,6 +273,8 @@ int main( int argc, char **argv) } } // for i - argv[] + cLogger::InitiateMultithreading(); + #if !defined(ANDROID_NDK) try #endif |