summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MCServer/Plugins/APIDump/Hooks/OnPlayerMoving.lua4
-rw-r--r--SetFlags.cmake2
-rw-r--r--Tools/MCADefrag/CMakeLists.txt6
-rw-r--r--Tools/MCADefrag/MCADefrag.cpp16
-rw-r--r--Tools/ProtoProxy/CMakeLists.txt6
-rw-r--r--src/Bindings/LuaFunctions.h2
-rw-r--r--src/Bindings/ManualBindings.cpp10
-rw-r--r--src/Bindings/Plugin.h2
-rw-r--r--src/Bindings/PluginLua.cpp4
-rw-r--r--src/Bindings/PluginLua.h2
-rw-r--r--src/Bindings/PluginManager.cpp4
-rw-r--r--src/Bindings/PluginManager.h2
-rw-r--r--src/Blocks/BlockBigFlower.h6
-rw-r--r--src/Blocks/BlockCake.h2
-rw-r--r--src/Blocks/BlockDirt.h2
-rw-r--r--src/Blocks/BlockFarmland.h5
-rw-r--r--src/Blocks/BlockFenceGate.h1
-rw-r--r--src/Blocks/BlockFire.h25
-rw-r--r--src/Blocks/BlockFlower.h2
-rw-r--r--src/Blocks/BlockGlowstone.h6
-rw-r--r--src/Blocks/BlockHandler.cpp6
-rw-r--r--src/Blocks/BlockMelon.h4
-rw-r--r--src/Blocks/BlockNewLeaves.h42
-rw-r--r--src/Blocks/BlockNote.h13
-rw-r--r--src/Blocks/BlockOre.h40
-rw-r--r--src/Blocks/BlockPlanks.h3
-rw-r--r--src/Blocks/BlockPortal.h8
-rw-r--r--src/Blocks/BlockPressurePlate.h4
-rw-r--r--src/Blocks/BlockQuartz.h1
-rw-r--r--src/Blocks/BlockRedstone.h4
-rw-r--r--src/Blocks/BlockRedstoneRepeater.h6
-rw-r--r--src/Blocks/BlockStairs.h20
-rw-r--r--src/Blocks/BlockSugarcane.h1
-rw-r--r--src/Blocks/BlockTorch.h4
-rw-r--r--src/Blocks/BlockTrapdoor.h9
-rw-r--r--src/Blocks/BlockTripwireHook.h10
-rw-r--r--src/Blocks/BlockVine.h6
-rw-r--r--src/Blocks/CMakeLists.txt2
-rw-r--r--src/CMakeLists.txt11
-rw-r--r--src/Chunk.cpp27
-rw-r--r--src/Chunk.h2
-rw-r--r--src/ClientHandle.cpp8
-rw-r--r--src/ClientHandle.h2
-rw-r--r--src/CompositeChat.cpp24
-rw-r--r--src/CompositeChat.h2
-rw-r--r--src/Entities/Player.cpp17
-rw-r--r--src/Generating/HeiGen.cpp2
-rw-r--r--src/Globals.h2
-rw-r--r--src/Items/ItemGoldenApple.h2
-rw-r--r--src/Items/ItemShovel.h1
-rw-r--r--src/Log.cpp169
-rw-r--r--src/Log.h30
-rw-r--r--src/Logger.cpp145
-rw-r--r--src/Logger.h73
-rw-r--r--src/LoggerListeners.cpp322
-rw-r--r--src/LoggerListeners.h31
-rw-r--r--src/MCLogger.cpp267
-rw-r--r--src/MCLogger.h95
-rw-r--r--src/OSSupport/File.cpp7
-rw-r--r--src/OSSupport/File.h7
-rw-r--r--src/Protocol/Protocol.h2
-rw-r--r--src/Protocol/Protocol125.cpp5
-rw-r--r--src/Protocol/Protocol125.h2
-rw-r--r--src/Protocol/Protocol14x.cpp8
-rw-r--r--src/Protocol/Protocol14x.h2
-rw-r--r--src/Protocol/Protocol17x.cpp7
-rw-r--r--src/Protocol/Protocol17x.h2
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp4
-rw-r--r--src/Protocol/ProtocolRecognizer.h2
-rw-r--r--src/Root.cpp26
-rw-r--r--src/Root.h2
-rw-r--r--src/StringUtils.h1
-rw-r--r--src/WebAdmin.cpp32
-rw-r--r--src/WebAdmin.h3
-rw-r--r--src/World.cpp44
-rw-r--r--src/World.h16
-rw-r--r--src/main.cpp2
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