1
0

Merge branch 'master' into Fire

This commit is contained in:
Howaner 2014-08-20 22:25:05 +02:00
commit f7774ec336
78 changed files with 859 additions and 862 deletions

View File

@ -11,9 +11,11 @@ return
Params = Params =
{ {
{ Name = "Player", Type = "{{cPlayer}}", Notes = "The player who has moved. The object already has the new position stored in it." }, { 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 = [[ 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> <p>
If the function returns false or no value, other plugins' callbacks are called and finally the new 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> position is permanently stored in the cPlayer object.</p>

View File

@ -185,4 +185,10 @@ AttackDamage=6.0
SightDistance=25.0 SightDistance=25.0
MaxHealth=100 MaxHealth=100
[Bat]
AttackRange=2.0
AttackRate=1
AttackDamage=0.0
SightDistance=25.0
MaxHealth=6

View File

@ -1,3 +1,5 @@
macro (add_flags_lnk FLAGS) macro (add_flags_lnk FLAGS)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}") set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${FLAGS}")

View File

@ -39,14 +39,12 @@ set_exe_flags()
set(SHARED_SRC set(SHARED_SRC
../../src/StringCompression.cpp ../../src/StringCompression.cpp
../../src/StringUtils.cpp ../../src/StringUtils.cpp
../../src/Log.cpp ../../src/LoggerListeners.cpp
../../src/MCLogger.cpp ../../src/Logger.cpp
) )
set(SHARED_HDR set(SHARED_HDR
../../src/ByteBuffer.h ../../src/ByteBuffer.h
../../src/StringUtils.h ../../src/StringUtils.h
../../src/Log.h
../../src/MCLogger.h
) )
flatten_files(SHARED_SRC) flatten_files(SHARED_SRC)
flatten_files(SHARED_HDR) flatten_files(SHARED_HDR)

View File

@ -5,7 +5,8 @@
#include "Globals.h" #include "Globals.h"
#include "MCADefrag.h" #include "MCADefrag.h"
#include "MCLogger.h" #include "Logger.h"
#include "LoggerListeners.h"
#include "zlib/zlib.h" #include "zlib/zlib.h"
@ -21,7 +22,13 @@ static const Byte g_Zeroes[4096] = {0};
int main(int argc, char ** argv) 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; cMCADefrag Defrag;
if (!Defrag.Init(argc, argv)) if (!Defrag.Init(argc, argv))
{ {
@ -30,6 +37,11 @@ int main(int argc, char ** argv)
Defrag.Run(); Defrag.Run();
cLogger::GetInstance().DetachListener(consoleLogListener);
delete consoleLogListener;
cLogger::GetInstance().DetachListener(fileLogListener);
delete fileLogListener;
return 0; return 0;
} }

View File

@ -34,20 +34,18 @@ set_exe_flags()
set(SHARED_SRC set(SHARED_SRC
../../src/ByteBuffer.cpp ../../src/ByteBuffer.cpp
../../src/StringUtils.cpp ../../src/StringUtils.cpp
../../src/Log.cpp
../../src/MCLogger.cpp
../../src/PolarSSL++/AesCfb128Decryptor.cpp ../../src/PolarSSL++/AesCfb128Decryptor.cpp
../../src/PolarSSL++/AesCfb128Encryptor.cpp ../../src/PolarSSL++/AesCfb128Encryptor.cpp
../../src/PolarSSL++/CryptoKey.cpp ../../src/PolarSSL++/CryptoKey.cpp
../../src/PolarSSL++/CtrDrbgContext.cpp ../../src/PolarSSL++/CtrDrbgContext.cpp
../../src/PolarSSL++/EntropyContext.cpp ../../src/PolarSSL++/EntropyContext.cpp
../../src/PolarSSL++/RsaPrivateKey.cpp ../../src/PolarSSL++/RsaPrivateKey.cpp
../../src/LoggerListeners.cpp
../../src/Logger.cpp
) )
set(SHARED_HDR set(SHARED_HDR
../../src/ByteBuffer.h ../../src/ByteBuffer.h
../../src/StringUtils.h ../../src/StringUtils.h
../../src/Log.h
../../src/MCLogger.h
../../src/PolarSSL++/AesCfb128Decryptor.h ../../src/PolarSSL++/AesCfb128Decryptor.h
../../src/PolarSSL++/AesCfb128Encryptor.h ../../src/PolarSSL++/AesCfb128Encryptor.h
../../src/PolarSSL++/CryptoKey.h ../../src/PolarSSL++/CryptoKey.h

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "../MCLogger.h" #include "Logger.h"
#include <time.h> #include <time.h>
// tolua_begin // tolua_begin

View File

@ -168,7 +168,7 @@ static AString GetLogMessage(lua_State * tolua_S)
static int tolua_LOG(lua_State * tolua_S) static int tolua_LOG(lua_State * tolua_S)
{ {
// If the param is a cCompositeChat, read the log level from it: // 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; tolua_Error err;
if (tolua_isusertype(tolua_S, 1, "cCompositeChat", false, &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: // Log the message:
cMCLogger::GetInstance()->LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel); cLogger::GetInstance().LogSimple(GetLogMessage(tolua_S).c_str(), LogLevel);
return 0; return 0;
} }
@ -186,7 +186,7 @@ static int tolua_LOG(lua_State * tolua_S)
static int tolua_LOGINFO(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; return 0;
} }
@ -196,7 +196,7 @@ static int tolua_LOGINFO(lua_State * tolua_S)
static int tolua_LOGWARN(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; return 0;
} }
@ -206,7 +206,7 @@ static int tolua_LOGWARN(lua_State * tolua_S)
static int tolua_LOGERROR(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; return 0;
} }

View File

@ -73,7 +73,7 @@ public:
virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0; virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) = 0;
virtual bool OnPlayerJoined (cPlayer & a_Player) = 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 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 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 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; 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;

View File

@ -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); cCSLock Lock(m_CriticalSection);
bool res = false; bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_MOVING]; cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_PLAYER_MOVING];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr) 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) if (res)
{ {
return true; return true;

View File

@ -98,7 +98,7 @@ public:
virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override; virtual bool OnPlayerFishing (cPlayer & a_Player, cItems & a_Reward) override;
virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override; virtual bool OnPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel) override;
virtual bool OnPlayerJoined (cPlayer & a_Player) 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 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 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; 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;

View File

@ -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); FIND_HOOK(HOOK_PLAYER_MOVING);
VERIFY_HOOK; VERIFY_HOOK;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr) 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; return true;
} }

View File

@ -206,7 +206,7 @@ public:
bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward); bool CallHookPlayerFishing (cPlayer & a_Player, cItems a_Reward);
bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel); bool CallHookPlayerFoodLevelChange (cPlayer & a_Player, int a_NewFoodLevel);
bool CallHookPlayerJoined (cPlayer & a_Player); 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 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 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); 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);

View File

@ -37,7 +37,7 @@ public:
{ {
NIBBLETYPE Meta = a_BlockMeta & 0x7; 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; return;
} }
@ -63,11 +63,11 @@ public:
if (r1.randInt(10) == 5) if (r1.randInt(10) == 5)
{ {
cItems Pickups; cItems Pickups;
if (FlowerMeta == 2) if (FlowerMeta == E_META_BIG_FLOWER_DOUBLE_TALL_GRASS)
{ {
Pickups.Add(E_BLOCK_TALL_GRASS, 2, 1); 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); Pickups.Add(E_BLOCK_TALL_GRASS, 2, 2);
} }

View File

@ -19,7 +19,7 @@ public:
{ {
NIBBLETYPE Meta = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); 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; return;
} }

View File

@ -81,7 +81,7 @@ public:
Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta); Chunk->GetBlockTypeMeta(BlockX, BlockY + 1, BlockZ, AboveDest, AboveMeta);
if (cBlockInfo::GetHandler(AboveDest)->CanDirtGrowGrass(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); Chunk->FastSetBlock(BlockX, BlockY, BlockZ, E_BLOCK_GRASS, 0);
} }

View File

@ -54,10 +54,7 @@ public:
BLOCKTYPE * BlockTypes = Area.GetBlockTypes(); BLOCKTYPE * BlockTypes = Area.GetBlockTypes();
for (size_t i = 0; i < NumBlocks; i++) for (size_t i = 0; i < NumBlocks; i++)
{ {
if ( if (IsBlockWater(BlockTypes[i]))
(BlockTypes[i] == E_BLOCK_WATER) ||
(BlockTypes[i] == E_BLOCK_STATIONARY_WATER)
)
{ {
Found = true; Found = true;
break; break;

View File

@ -35,6 +35,7 @@ public:
NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ); NIBBLETYPE OldMetaData = a_ChunkInterface.GetBlockMeta(a_BlockX, a_BlockY, a_BlockZ);
NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetYaw()); NIBBLETYPE NewMetaData = PlayerYawToMetaData(a_Player->GetYaw());
OldMetaData ^= 4; // Toggle the gate OldMetaData ^= 4; // Toggle the gate
if ((OldMetaData & 1) == (NewMetaData & 1)) if ((OldMetaData & 1) == (NewMetaData & 1))
{ {
// Standing in front of the gate - apply new direction // Standing in front of the gate - apply new direction

View File

@ -55,8 +55,8 @@ public:
return "step.wood"; return "step.wood";
} }
/// Traces along YP until it finds an obsidian block, returns Y difference or 0 if no portal, and -1 for border /** 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 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) int FindObsidianCeiling(int X, int Y, int Z, cChunkInterface & a_ChunkInterface, int MaxY = 0)
{ {
if (a_ChunkInterface.GetBlock(X, Y, Z) != E_BLOCK_OBSIDIAN) if (a_ChunkInterface.GetBlock(X, Y, Z) != E_BLOCK_OBSIDIAN)
@ -86,13 +86,12 @@ public:
return newY; return newY;
} }
} }
else { return 0; }
} }
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) 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 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
@ -144,8 +143,8 @@ public:
return; return;
} }
/// Evaluates if coordinates are a portal going XP/XM; returns true if so, and writes boundaries to variable /** 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 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) 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) Dir = 1; // Set assumed direction (will change if portal turns out to be facing the other direction)
@ -163,7 +162,8 @@ public:
{ {
return false; // Not valid slice, no portal can be formed 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) 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); int Value = FindObsidianCeiling(X2, Y, Z, a_ChunkInterface, MaxY);
@ -177,7 +177,9 @@ public:
{ {
return false; return false;
} }
} XZM = X2 + 1; // Set boundary, see previous }
XZM = X2 + 1; // Set boundary, see previous
return (FoundFrameXP && FoundFrameXM); return (FoundFrameXP && FoundFrameXM);
} }
@ -199,7 +201,8 @@ public:
{ {
return false; 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--) 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); int Value = FindObsidianCeiling(X, Y, Z2, a_ChunkInterface, MaxY);
@ -213,7 +216,9 @@ public:
{ {
return false; return false;
} }
} XZM = Z2 + 1; }
XZM = Z2 + 1;
return (FoundFrameZP && FoundFrameZM); return (FoundFrameZP && FoundFrameZM);
} }
}; };

View File

@ -19,7 +19,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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)); a_Pickups.push_back(cItem(m_BlockType, 1, 0));
} }

View File

@ -15,13 +15,13 @@ public:
: cBlockHandler(a_BlockType) : cBlockHandler(a_BlockType)
{ {
} }
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
// Reset meta to 0 // Reset meta to 0
MTRand r1; cFastRandom Random;
a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, (char)(2 + r1.randInt(2)), 0)); a_Pickups.push_back(cItem(E_ITEM_GLOWSTONE_DUST, (char)(2 + Random.NextInt(3)), 0));
} }
} ; } ;

View File

@ -45,13 +45,11 @@
#include "BlockLadder.h" #include "BlockLadder.h"
#include "BlockLeaves.h" #include "BlockLeaves.h"
#include "BlockLilypad.h" #include "BlockLilypad.h"
#include "BlockNewLeaves.h"
#include "BlockLever.h" #include "BlockLever.h"
#include "BlockMelon.h" #include "BlockMelon.h"
#include "BlockMushroom.h" #include "BlockMushroom.h"
#include "BlockMycelium.h" #include "BlockMycelium.h"
#include "BlockNetherWart.h" #include "BlockNetherWart.h"
#include "BlockNote.h"
#include "BlockOre.h" #include "BlockOre.h"
#include "BlockPiston.h" #include "BlockPiston.h"
#include "BlockPlanks.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_PORTAL: return new cBlockPortalHandler (a_BlockType);
case E_BLOCK_NETHER_WART: return new cBlockNetherWartHandler (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_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_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: return new cBlockPistonHandler (a_BlockType);
case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler; case E_BLOCK_PISTON_EXTENSION: return new cBlockPistonHeadHandler;
case E_BLOCK_PLANKS: return new cBlockPlanksHandler (a_BlockType); case E_BLOCK_PLANKS: return new cBlockPlanksHandler (a_BlockType);

View File

@ -19,8 +19,8 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
MTRand r1; cFastRandom Random;
a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + r1.randInt(4)), 0)); a_Pickups.push_back(cItem(E_ITEM_MELON_SLICE, (char)(3 + Random.NextInt(5)), 0));
} }

View File

@ -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);
}
} ;

View File

@ -1,13 +0,0 @@
#pragma once
#include "BlockHandler.h"
#include "BlockEntity.h"
class cBlockNoteHandler : public cBlockEntityHandler
{
public:
cBlockNoteHandler(BLOCKTYPE a_BlockType)
: cBlockEntityHandler(a_BlockType)
{
}
};

View File

@ -2,7 +2,6 @@
#pragma once #pragma once
#include "BlockHandler.h" #include "BlockHandler.h"
#include "../MersenneTwister.h"
#include "../World.h" #include "../World.h"
@ -20,58 +19,41 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
short ItemType = m_BlockType; cFastRandom Random;
char Count = 1;
short Meta = 0;
MTRand r1;
switch (m_BlockType) switch (m_BlockType)
{ {
case E_BLOCK_LAPIS_ORE: case E_BLOCK_LAPIS_ORE:
{ {
ItemType = E_ITEM_DYE; a_Pickups.push_back(cItem(E_ITEM_DYE, (char)(4 + Random.NextInt(5)), 4));
Count = 4 + (char)r1.randInt(4);
Meta = 4;
break; break;
} }
case E_BLOCK_REDSTONE_ORE: case E_BLOCK_REDSTONE_ORE:
case E_BLOCK_REDSTONE_ORE_GLOWING: case E_BLOCK_REDSTONE_ORE_GLOWING:
{ {
Count = 4 + (char)r1.randInt(1); a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, (char)(4 + Random.NextInt(2)), 0));
break; break;
} }
default:
{
Count = 1;
break;
}
}
switch (m_BlockType)
{
case E_BLOCK_DIAMOND_ORE: case E_BLOCK_DIAMOND_ORE:
{ {
ItemType = E_ITEM_DIAMOND; a_Pickups.push_back(cItem(E_ITEM_DIAMOND));
break;
}
case E_BLOCK_REDSTONE_ORE:
case E_BLOCK_REDSTONE_ORE_GLOWING:
{
ItemType = E_ITEM_REDSTONE_DUST;
break; break;
} }
case E_BLOCK_EMERALD_ORE: case E_BLOCK_EMERALD_ORE:
{ {
ItemType = E_ITEM_EMERALD; a_Pickups.push_back(cItem(E_ITEM_EMERALD));
break; break;
} }
case E_BLOCK_COAL_ORE: case E_BLOCK_COAL_ORE:
{ {
ItemType = E_ITEM_COAL; a_Pickups.push_back(cItem(E_ITEM_COAL));
break; break;
} }
default:
{
ASSERT(!"Unhandled ore!");
}
} }
a_Pickups.push_back(cItem(ItemType, Count, Meta));
} }
} ; } ;

View File

@ -24,8 +24,7 @@ public:
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); a_BlockMeta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage);
a_BlockMeta = Meta;
return true; return true;
} }

View File

@ -36,7 +36,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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 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; return;
} }
int PosX = a_Chunk.GetPosX() * 16 + a_RelX; int PosX = a_Chunk.GetPosX() * cChunkDef::Width + a_RelX;
int PosZ = a_Chunk.GetPosZ() * 16 + a_RelZ; int PosZ = a_Chunk.GetPosZ() * cChunkDef::Width + a_RelZ;
a_WorldInterface.SpawnMob(PosX, a_RelY, PosZ, cMonster::mtZombiePigman); 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 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 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
} }

View File

@ -17,7 +17,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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)); 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); 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));
} }
} ; } ;

View File

@ -25,6 +25,7 @@ public:
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage); NIBBLETYPE Meta = (NIBBLETYPE)(a_Player->GetEquippedItem().m_ItemDamage);
if (Meta != E_META_QUARTZ_PILLAR) // Check if the block is a pillar block. if (Meta != E_META_QUARTZ_PILLAR) // Check if the block is a pillar block.
{ {
a_BlockMeta = Meta; a_BlockMeta = Meta;

View File

@ -26,8 +26,8 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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_DUST, 1)); a_Pickups.push_back(cItem(E_ITEM_REDSTONE_DUST, 1, 0));
} }
} ; } ;

View File

@ -23,7 +23,7 @@ public:
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ, int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetYaw()); a_BlockMeta = RepeaterRotationToMetaData(a_Player->GetYaw());
@ -46,7 +46,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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)); 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 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)));
} }

View File

@ -16,8 +16,8 @@ public:
{ {
} }
virtual bool GetPlacementBlockTypeMeta( virtual bool GetPlacementBlockTypeMeta(
cChunkInterface & a_ChunkInterface, cPlayer * a_Player, cChunkInterface & a_ChunkInterface, cPlayer * a_Player,
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
@ -53,8 +53,8 @@ public:
} }
return true; return true;
} }
virtual const char * GetStepSound(void) override virtual const char * GetStepSound(void) override
{ {
if ( if (
@ -64,7 +64,7 @@ public:
(m_BlockType == E_BLOCK_ACACIA_WOOD_STAIRS) || (m_BlockType == E_BLOCK_ACACIA_WOOD_STAIRS) ||
(m_BlockType == E_BLOCK_BIRCH_WOOD_STAIRS) || (m_BlockType == E_BLOCK_BIRCH_WOOD_STAIRS) ||
(m_BlockType == E_BLOCK_DARK_OAK_WOOD_STAIRS) (m_BlockType == E_BLOCK_DARK_OAK_WOOD_STAIRS)
) )
{ {
return "step.wood"; return "step.wood";
} }
@ -72,17 +72,20 @@ public:
return "step.stone"; return "step.stone";
} }
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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)); a_Pickups.push_back(cItem(m_BlockType, 1, 0));
} }
virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override virtual bool CanDirtGrowGrass(NIBBLETYPE a_Meta) override
{ {
return true; return true;
} }
static NIBBLETYPE RotationToMetaData(double a_Rotation) static NIBBLETYPE RotationToMetaData(double a_Rotation)
{ {
a_Rotation += 90 + 45; // So its not aligned with axis a_Rotation += 90 + 45; // So its not aligned with axis
@ -108,14 +111,11 @@ public:
} }
} }
virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override virtual NIBBLETYPE MetaMirrorXZ(NIBBLETYPE a_Meta) override
{ {
// Toggle bit 3: // Toggle bit 3:
return (a_Meta & 0x0b) | ((~a_Meta) & 0x04); return (a_Meta & 0x0b) | ((~a_Meta) & 0x04);
} }
} ; } ;

View File

@ -29,6 +29,7 @@ public:
{ {
return false; return false;
} }
switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ)) switch (a_Chunk.GetBlock(a_RelX, a_RelY - 1, a_RelZ))
{ {
case E_BLOCK_DIRT: case E_BLOCK_DIRT:

View File

@ -126,7 +126,7 @@ public:
(BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) ||
(BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)) && (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)) &&
(Face == BLOCK_FACE_TOP) (Face == BLOCK_FACE_TOP)
) )
{ {
return Face; return Face;
} }
@ -162,7 +162,7 @@ public:
(BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour (BlockInQuestion == E_BLOCK_END_PORTAL_FRAME) || // Actual vanilla behaviour
(BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) || (BlockInQuestion == E_BLOCK_NETHER_BRICK_FENCE) ||
(BlockInQuestion == E_BLOCK_COBBLESTONE_WALL) (BlockInQuestion == E_BLOCK_COBBLESTONE_WALL)
) )
{ {
// Torches can be placed on tops of glass and fences, despite them being 'untorcheable' // 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 // No need to check for upright orientation, it was done when the torch was placed

View File

@ -23,7 +23,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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)); 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_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ, int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = BlockFaceToMetaData(a_BlockFace); a_BlockMeta = BlockFaceToMetaData(a_BlockFace);
@ -103,9 +103,10 @@ public:
a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta); a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
AddFaceDirection(a_RelX, a_RelY, a_RelZ, BlockMetaDataToBlockFace(Meta), true); 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));
} }
}; };

View File

@ -21,10 +21,9 @@ public:
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ, int a_CursorX, int a_CursorY, int a_CursorZ,
BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta BLOCKTYPE & a_BlockType, NIBBLETYPE & a_BlockMeta
) override ) override
{ {
a_BlockType = m_BlockType; a_BlockType = m_BlockType;
a_BlockMeta = DirectionToMetadata(a_BlockFace); a_BlockMeta = DirectionToMetadata(a_BlockFace);
return true; return true;
@ -56,7 +55,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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)); 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); a_Chunk.UnboundedRelGetBlockMeta(a_RelX, a_RelY, a_RelZ, Meta);
AddFaceDirection(a_RelX, a_RelY, a_RelZ, MetadataToDirection(Meta), true); 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 virtual const char * GetStepSound(void) override

View File

@ -46,7 +46,7 @@ public:
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override 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)); 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 /// Returns true if the specified block type is good for vines to attach to
static bool IsBlockAttachable(BLOCKTYPE a_BlockType) 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); a_Chunk.UnboundedRelGetBlockType(a_RelX, a_RelY - 1, a_RelZ, Block);
if (Block == E_BLOCK_AIR) 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)); a_Chunk.UnboundedRelSetBlock(a_RelX, a_RelY - 1, a_RelZ, E_BLOCK_VINES, a_Chunk.GetMeta(a_RelX, a_RelY, a_RelZ));
} }

View File

@ -57,8 +57,6 @@ SET (HDRS
BlockMushroom.h BlockMushroom.h
BlockMycelium.h BlockMycelium.h
BlockNetherWart.h BlockNetherWart.h
BlockNewLeaves.h
BlockNote.h
BlockOre.h BlockOre.h
BlockPiston.h BlockPiston.h
BlockPlanks.h BlockPlanks.h

View File

@ -1,6 +1,7 @@
cmake_minimum_required (VERSION 2.8.2) cmake_minimum_required (VERSION 2.8.2)
project (MCServer) project (MCServer)
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/") 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/jsoncpp/include")
include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include") include_directories (SYSTEM "${CMAKE_CURRENT_SOURCE_DIR}/../lib/polarssl/include")
@ -41,8 +42,8 @@ SET (SRCS
LightingThread.cpp LightingThread.cpp
LineBlockTracer.cpp LineBlockTracer.cpp
LinearInterpolation.cpp LinearInterpolation.cpp
Log.cpp LoggerListeners.cpp
MCLogger.cpp Logger.cpp
Map.cpp Map.cpp
MapManager.cpp MapManager.cpp
MobCensus.cpp MobCensus.cpp
@ -107,8 +108,8 @@ SET (HDRS
LineBlockTracer.h LineBlockTracer.h
LinearInterpolation.h LinearInterpolation.h
LinearUpscale.h LinearUpscale.h
Log.h Logger.h
MCLogger.h LoggerListeners.h
Map.h Map.h
MapManager.h MapManager.h
Matrix4.h Matrix4.h
@ -234,7 +235,7 @@ endif()
# Generate a list of all source files: # Generate a list of all source files:
set(ALLFILES "") set(ALLFILES "${SRCS}" "${HDRS}")
foreach(folder ${FOLDERS}) foreach(folder ${FOLDERS})
get_directory_property(FOLDER_SRCS DIRECTORY ${folder} DEFINITION SRCS) get_directory_property(FOLDER_SRCS DIRECTORY ${folder} DEFINITION SRCS)
foreach (src ${FOLDER_SRCS}) foreach (src ${FOLDER_SRCS})

View File

@ -1,3 +1,4 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#ifndef _WIN32 #ifndef _WIN32
@ -579,7 +580,7 @@ void cChunk::Tick(float a_Dt)
} }
for (cEntityList::iterator itr = m_Entities.begin(); itr != m_Entities.end();) 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) 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): // Tick all entities in this chunk (except mobs):
@ -594,17 +595,19 @@ void cChunk::Tick(float a_Dt)
itr = m_Entities.erase(itr); itr = m_Entities.erase(itr);
delete ToDelete; 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(); MarkDirty();
(*itr)->SetWorldTravellingFrom(NULL); (*itr)->SetWorldTravellingFrom(NULL);
itr = m_Entities.erase(itr); 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)->GetChunkX() != m_PosX) ||
((*itr)->GetChunkZ() != m_PosZ) ((*itr)->GetChunkZ() != m_PosZ)
) )
{ {
// The entity moved out of the chunk, move it to the neighbor
MarkDirty(); MarkDirty();
MoveEntityToNewChunk(*itr); MoveEntityToNewChunk(*itr);
itr = m_Entities.erase(itr); itr = m_Entities.erase(itr);
@ -885,14 +888,14 @@ void cChunk::ApplyWeatherToTop()
SetBlock(X, Height, Z, E_BLOCK_ICE, 0); SetBlock(X, Height, Z, E_BLOCK_ICE, 0);
} }
else if ( else if (
(m_World->IsDeepSnowEnabled()) && (m_World->IsDeepSnowEnabled()) &&
( (
(TopBlock == E_BLOCK_RED_ROSE) || (TopBlock == E_BLOCK_RED_ROSE) ||
(TopBlock == E_BLOCK_YELLOW_FLOWER) || (TopBlock == E_BLOCK_YELLOW_FLOWER) ||
(TopBlock == E_BLOCK_RED_MUSHROOM) || (TopBlock == E_BLOCK_RED_MUSHROOM) ||
(TopBlock == E_BLOCK_BROWN_MUSHROOM) (TopBlock == E_BLOCK_BROWN_MUSHROOM)
)
) )
)
{ {
SetBlock(X, Height, Z, E_BLOCK_SNOW, 0); 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_DROPPER:
case E_BLOCK_DISPENSER: case E_BLOCK_DISPENSER:
case E_BLOCK_NOTE_BLOCK: case E_BLOCK_NOTE_BLOCK:
{
break; break;
}
default: default:
{
// There is a block entity here, but of different type. No other block entity can be here, so we can safely bail out // 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; return false;
}
} }
if (a_Callback.Item((cRedstonePoweredEntity *)*itr)) if (a_Callback.Item((cRedstonePoweredEntity *)*itr))

View File

@ -241,7 +241,7 @@ public:
bool DoWithBlockEntityAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBlockEntityCallback & a_Callback); // Lua-acessible 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 */ /** 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 */ /** 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 bool DoWithBeaconAt(int a_BlockX, int a_BlockY, int a_BlockZ, cBeaconCallback & a_Callback); // Lua-acessible

View File

@ -341,8 +341,8 @@ void cClientHandle::Authenticate(const AString & a_Name, const AString & a_UUID,
m_Protocol->SendWeather(World->GetWeather()); m_Protocol->SendWeather(World->GetWeather());
} }
// Send time // Send time:
m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay()); m_Protocol->SendTimeUpdate(World->GetWorldAge(), World->GetTimeOfDay(), World->IsDaylightCycleEnabled());
// Send contents of the inventory window // Send contents of the inventory window
m_Protocol->SendWholeInventory(*m_Player->GetWindow()); m_Protocol->SendWholeInventory(*m_Player->GetWindow());
@ -2578,9 +2578,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);
} }

View File

@ -179,7 +179,7 @@ public:
void SendTabCompletionResults(const AStringVector & a_Results); void SendTabCompletionResults(const AStringVector & a_Results);
void SendTeleportEntity (const cEntity & a_Entity); void SendTeleportEntity (const cEntity & a_Entity);
void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); 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 SendUnloadChunk (int a_ChunkX, int a_ChunkZ);
void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); 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); 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);

View File

@ -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) switch (a_MessageType)
{ {
case mtCustom: return cMCLogger::llRegular; case mtCustom: return cLogger::llRegular;
case mtFailure: return cMCLogger::llWarning; case mtFailure: return cLogger::llWarning;
case mtInformation: return cMCLogger::llInfo; case mtInformation: return cLogger::llInfo;
case mtSuccess: return cMCLogger::llRegular; case mtSuccess: return cLogger::llRegular;
case mtWarning: return cMCLogger::llWarning; case mtWarning: return cLogger::llWarning;
case mtFatal: return cMCLogger::llError; case mtFatal: return cLogger::llError;
case mtDeath: return cMCLogger::llRegular; case mtDeath: return cLogger::llRegular;
case mtPrivateMessage: return cMCLogger::llRegular; case mtPrivateMessage: return cLogger::llRegular;
case mtJoin: return cMCLogger::llRegular; case mtJoin: return cLogger::llRegular;
case mtLeave: return cMCLogger::llRegular; case mtLeave: return cLogger::llRegular;
} }
ASSERT(!"Unhandled MessageType"); ASSERT(!"Unhandled MessageType");
return cMCLogger::llError; return cLogger::llError;
} }

View File

@ -196,7 +196,7 @@ public:
/** Converts the MessageType to a LogLevel value. /** Converts the MessageType to a LogLevel value.
Used by the logging bindings when logging a cCompositeChat object. */ 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: protected:
/** All the parts that */ /** All the parts that */

View File

@ -225,16 +225,24 @@ void cPlayer::Tick(float a_Dt, cChunk & a_Chunk)
SendExperience(); SendExperience();
} }
bool CanMove = true;
if (!GetPosition().EqualsEps(m_LastPos, 0.01)) // Non negligible change in position from last tick? if (!GetPosition().EqualsEps(m_LastPos, 0.01)) // Non negligible change in position from last tick?
{ {
// Apply food exhaustion from movement: // Apply food exhaustion from movement:
ApplyFoodExhaustionFromMovement(); 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(); m_ClientHandle->StreamChunks();
} }
BroadcastMovementUpdate(m_ClientHandle); if (CanMove)
{
BroadcastMovementUpdate(m_ClientHandle);
}
if (m_Health > 0) // make sure player is alive 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)); 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); m_World->SpawnItemPickups(Pickups, GetPosX(), GetPosY(), GetPosZ(), 10);
SaveToDisk(); // Save it, yeah the world is a tough place ! 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) 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; double vX = 0, vY = 0, vZ = 0;
EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY); EulerToVector(-GetYaw(), GetPitch(), vZ, vX, vY);
@ -1834,6 +1842,7 @@ bool cPlayer::LoadFromFile(const AString & a_FileName, cWorldPtr & a_World)
bool cPlayer::SaveToDisk() 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)); cFile::CreateFolder(FILE_IO_PREFIX + AString("players/") + m_UUID.substr(0, 2));
// create the JSON data // create the JSON data

View File

@ -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 /* 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 /* 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 /* 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: // Biomes 135 .. 139 unused, 5 empty placeholders here:
{}, {}, {}, {}, {}, // 135 .. 139 {}, {}, {}, {}, {}, // 135 .. 139

View File

@ -249,7 +249,7 @@ template class SizeChecker<UInt16, 2>;
#include "OSSupport/Event.h" #include "OSSupport/Event.h"
#include "OSSupport/Thread.h" #include "OSSupport/Thread.h"
#include "OSSupport/File.h" #include "OSSupport/File.h"
#include "MCLogger.h" #include "Logger.h"
#else #else
// Logging functions // Logging functions
void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2); void inline LOGERROR(const char* a_Format, ...) FORMATSTRING(1, 2);

View File

@ -29,7 +29,7 @@ public:
a_Player->AddEntityEffect(cEntityEffect::effRegeneration, 100, 1); a_Player->AddEntityEffect(cEntityEffect::effRegeneration, 100, 1);
// When the apple is a 'notch apple', give extra effects: // 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::effRegeneration, 600, 4);
a_Player->AddEntityEffect(cEntityEffect::effResistance, 6000, 0); a_Player->AddEntityEffect(cEntityEffect::effResistance, 6000, 0);

View File

@ -19,7 +19,6 @@ public:
cItemShovelHandler(int a_ItemType) cItemShovelHandler(int a_ItemType)
: cItemHandler(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 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

View File

@ -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);
}

View File

@ -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();
};

145
src/Logger.cpp Normal file
View File

@ -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);
}

73
src/Logger.h Normal file
View File

@ -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

322
src/LoggerListeners.cpp Normal file
View File

@ -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());
}

31
src/LoggerListeners.h Normal file
View File

@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -70,6 +70,7 @@ bool cFile::Open(const AString & iFileName, eMode iMode)
case fmRead: Mode = "rb"; break; case fmRead: Mode = "rb"; break;
case fmWrite: Mode = "wb"; break; case fmWrite: Mode = "wb"; break;
case fmReadWrite: Mode = "rb+"; break; case fmReadWrite: Mode = "rb+"; break;
case fmAppend: Mode = "a+"; break;
} }
if (Mode == NULL) if (Mode == NULL)
{ {
@ -255,10 +256,10 @@ int cFile::ReadRestOfFile(AString & a_Contents)
return -1; 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 // 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); return Read((void *)a_Contents.data(), DataSize);
} }
@ -459,7 +460,7 @@ int cFile::Printf(const char * a_Fmt, ...)
va_start(args, a_Fmt); va_start(args, a_Fmt);
AppendVPrintf(buf, a_Fmt, args); AppendVPrintf(buf, a_Fmt, args);
va_end(args); va_end(args);
return Write(buf.c_str(), (int)buf.length()); return Write(buf.c_str(), buf.length());
} }

View File

@ -60,9 +60,10 @@ public:
/** The mode in which to open the file */ /** The mode in which to open the file */
enum eMode enum eMode
{ {
fmRead, // Read-only. If the file doesn't exist, object will not be valid 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 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 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 */ /** Simple constructor - creates an unopened file object, use Open() to open / create a real file */

View File

@ -116,7 +116,7 @@ public:
virtual void SendTabCompletionResults(const AStringVector & a_Results) = 0; virtual void SendTabCompletionResults(const AStringVector & a_Results) = 0;
virtual void SendTeleportEntity (const cEntity & a_Entity) = 0; virtual void SendTeleportEntity (const cEntity & a_Entity) = 0;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 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 SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 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; 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;

View File

@ -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); cCSLock Lock(m_CSPacket);
WriteByte (PACKET_UPDATE_TIME); WriteByte (PACKET_UPDATE_TIME);
// Use a_WorldAge for daycount, and a_TimeOfDay for the proper time of day: // Use a_WorldAge for daycount, and a_TimeOfDay for the proper time of day:

View File

@ -88,7 +88,7 @@ public:
virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTabCompletionResults(const AStringVector & a_Results) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) 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 SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) 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; 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;

View File

@ -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); cCSLock Lock(m_CSPacket);
WriteByte (PACKET_UPDATE_TIME); WriteByte (PACKET_UPDATE_TIME);
WriteInt64(a_WorldAge); WriteInt64(a_WorldAge);

View File

@ -34,7 +34,7 @@ public:
// Sending commands (alphabetically sorted): // Sending commands (alphabetically sorted):
virtual void SendPickupSpawn (const cPickup & a_Pickup) override; 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 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: // Specific packet parsers:
virtual int ParseLocaleViewDistance(void) override; virtual int ParseLocaleViewDistance(void) override;

View File

@ -48,7 +48,10 @@ Implements the 1.7.x protocol classes:
#define HANDLE_READ(ByteBuf, Proc, Type, Var) \ #define HANDLE_READ(ByteBuf, Proc, Type, Var) \
Type Var; \ Type Var; \
ByteBuf.Proc(Var); if (!ByteBuf.Proc(Var))\
{\
return;\
}
@ -1286,9 +1289,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? 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); cPacketizer Pkt(*this, 0x03);
Pkt.WriteInt64(a_WorldAge); Pkt.WriteInt64(a_WorldAge);
@ -1700,8 +1708,7 @@ bool cProtocol172::HandlePacket(cByteBuffer & a_ByteBuffer, UInt32 a_PacketType)
void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer) void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer)
{ {
Int64 Timestamp; HANDLE_READ(a_ByteBuffer, ReadBEInt64, Int64, Timestamp);
a_ByteBuffer.ReadBEInt64(Timestamp);
cPacketizer Pkt(*this, 0x01); // Ping packet cPacketizer Pkt(*this, 0x01); // Ping packet
Pkt.WriteInt64(Timestamp); Pkt.WriteInt64(Timestamp);
@ -2054,7 +2061,10 @@ void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel); HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
HANDLE_READ(a_ByteBuffer, ReadBEShort, short, Length); HANDLE_READ(a_ByteBuffer, ReadBEShort, short, Length);
AString Data; AString Data;
a_ByteBuffer.ReadString(Data, Length); if (!a_ByteBuffer.ReadString(Data, Length))
{
return;
}
m_Client->HandlePluginMessage(Channel, Data); m_Client->HandlePluginMessage(Channel, Data);
} }

View File

@ -120,7 +120,7 @@ public:
virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTabCompletionResults(const AStringVector & a_Results) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) 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 SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) 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; 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;

View File

@ -716,10 +716,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); ASSERT(m_Protocol != NULL);
m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay); m_Protocol->SendTimeUpdate(a_WorldAge, a_TimeOfDay, a_DoDaylightCycle);
} }

View File

@ -123,7 +123,7 @@ public:
virtual void SendTabCompletionResults(const AStringVector & a_Results) override; virtual void SendTabCompletionResults(const AStringVector & a_Results) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override; virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) 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 SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) 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; 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;

View File

@ -18,6 +18,7 @@
#include "CommandOutput.h" #include "CommandOutput.h"
#include "DeadlockDetect.h" #include "DeadlockDetect.h"
#include "OSSupport/Timer.h" #include "OSSupport/Timer.h"
#include "LoggerListeners.h"
#include "inifile/iniFile.h" #include "inifile/iniFile.h"
@ -51,7 +52,6 @@ cRoot::cRoot(void) :
m_FurnaceRecipe(NULL), m_FurnaceRecipe(NULL),
m_WebAdmin(NULL), m_WebAdmin(NULL),
m_PluginManager(NULL), m_PluginManager(NULL),
m_Log(NULL),
m_bStop(false), m_bStop(false),
m_bRestart(false) m_bRestart(false)
{ {
@ -105,10 +105,15 @@ void cRoot::Start(void)
HMENU hmenu = GetSystemMenu(hwnd, FALSE); 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 EnableMenuItem(hmenu, SC_CLOSE, MF_GRAYED); // Disable close button when starting up; it causes problems with our CTRL-CLOSE handling
#endif #endif
cLogger::cListener * consoleLogListener = MakeConsoleListener();
cLogger::cListener * fileLogListener = new cFileListener();
cLogger::GetInstance().AttachListener(consoleLogListener);
cLogger::GetInstance().AttachListener(fileLogListener);
LOG("--- Started Log ---\n");
cDeadlockDetect dd; cDeadlockDetect dd;
delete m_Log;
m_Log = new cMCLogger();
m_bStop = false; m_bStop = false;
while (!m_bStop) while (!m_bStop)
@ -249,8 +254,13 @@ void cRoot::Start(void)
delete m_Server; m_Server = NULL; delete m_Server; m_Server = NULL;
LOG("Shutdown successful!"); 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; m_WorldsByName[ DefaultWorldName ] = m_pDefaultWorld;
// Then load the other worlds // Then load the other worlds
unsigned int KeyNum = IniFile.FindKey("Worlds"); int KeyNum = IniFile.FindKey("Worlds");
unsigned int NumWorlds = IniFile.GetNumValues(KeyNum); int NumWorlds = IniFile.GetNumValues(KeyNum);
if (NumWorlds <= 0) if (NumWorlds <= 0)
{ {
return; return;
} }
bool FoundAdditionalWorlds = false; bool FoundAdditionalWorlds = false;
for (unsigned int i = 0; i < NumWorlds; i++) for (int i = 0; i < NumWorlds; i++)
{ {
AString ValueName = IniFile.GetValueName(KeyNum, i); AString ValueName = IniFile.GetValueName(KeyNum, i);
if (ValueName.compare("World") != 0) if (ValueName.compare("World") != 0)

View File

@ -196,8 +196,6 @@ private:
cMojangAPI m_MojangAPI; cMojangAPI m_MojangAPI;
cHTTPServer m_HTTPServer; cHTTPServer m_HTTPServer;
cMCLogger * m_Log;
bool m_bStop; bool m_bStop;
bool m_bRestart; bool m_bRestart;

View File

@ -12,7 +12,6 @@
typedef std::string AString; typedef std::string AString;
typedef std::vector<AString> AStringVector; typedef std::vector<AString> AStringVector;
typedef std::list<AString> AStringList; typedef std::list<AString> AStringList;

View File

@ -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) void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request)
{ {
if (!a_Request.HasAuth()) 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: // Check if the contents should be wrapped in the template:
AString URL = a_Request.GetBareURL(); AString BareURL = a_Request.GetBareURL();
ASSERT(URL.length() > 0); ASSERT(BareURL.length() > 0);
bool ShouldWrapInTemplate = ((URL.length() > 1) && (URL[1] != '~')); bool ShouldWrapInTemplate = ((BareURL.length() > 1) && (BareURL[1] != '~'));
// Retrieve the request data: // Retrieve the request data:
cWebadminRequestData * Data = (cWebadminRequestData *)(a_Request.GetUserData()); cWebadminRequestData * Data = (cWebadminRequestData *)(a_Request.GetUserData());
@ -215,7 +193,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque
HTTPTemplateRequest TemplateRequest; HTTPTemplateRequest TemplateRequest;
TemplateRequest.Request.Username = a_Request.GetAuthUsername(); TemplateRequest.Request.Username = a_Request.GetAuthUsername();
TemplateRequest.Request.Method = a_Request.GetMethod(); TemplateRequest.Request.Method = a_Request.GetMethod();
TemplateRequest.Request.Path = URL.substr(1); TemplateRequest.Request.Path = BareURL.substr(1);
if (Data->m_Form.Finish()) if (Data->m_Form.Finish())
{ {
@ -258,7 +236,7 @@ void cWebAdmin::HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPReque
return; return;
} }
AString BaseURL = GetBaseURL(URL); AString BaseURL = GetBaseURL(BareURL);
AString Menu; AString Menu;
Template = "{CONTENT}"; Template = "{CONTENT}";
AString FoundPlugin; AString FoundPlugin;

View File

@ -208,9 +208,6 @@ protected:
/** The HTTP server which provides the underlying HTTP parsing, serialization and events */ /** The HTTP server which provides the underlying HTTP parsing, serialization and events */
cHTTPServer m_HTTPServer; cHTTPServer m_HTTPServer;
AString GetTemplate(void);
/** Handles requests coming to the "/webadmin" or "/~webadmin" URLs */ /** Handles requests coming to the "/webadmin" or "/~webadmin" URLs */
void HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request); void HandleWebadminRequest(cHTTPConnection & a_Connection, cHTTPRequest & a_Request);

View File

@ -1,3 +1,4 @@
#include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules
#include "BlockID.h" #include "BlockID.h"
@ -243,6 +244,7 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin
#endif #endif
m_Dimension(a_Dimension), m_Dimension(a_Dimension),
m_IsSpawnExplicitlySet(false), m_IsSpawnExplicitlySet(false),
m_IsDaylightCycleEnabled(true),
m_WorldAgeSecs(0), m_WorldAgeSecs(0),
m_TimeOfDaySecs(0), m_TimeOfDaySecs(0),
m_WorldAge(0), m_WorldAge(0),
@ -576,6 +578,7 @@ void cWorld::Start(void)
m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true); m_bEnabledPVP = IniFile.GetValueSetB("Mechanics", "PVPEnabled", true);
m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true); m_bUseChatPrefixes = IniFile.GetValueSetB("Mechanics", "UseChatPrefixes", true);
m_VillagersShouldHarvestCrops = IniFile.GetValueSetB("Monsters", "VillagersShouldHarvestCrops", 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 GameMode = IniFile.GetValueSetI("General", "Gamemode", (int)m_GameMode);
int Weather = IniFile.GetValueSetI("General", "Weather", (int)m_Weather); 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.SetValueI("Physics", "TNTShrapnelLevel", (int)m_TNTShrapnelLevel);
IniFile.SetValueB("Mechanics", "CommandBlocksEnabled", m_bCommandBlocksEnabled); IniFile.SetValueB("Mechanics", "CommandBlocksEnabled", m_bCommandBlocksEnabled);
IniFile.SetValueB("Mechanics", "UseChatPrefixes", m_bUseChatPrefixes); IniFile.SetValueB("Mechanics", "UseChatPrefixes", m_bUseChatPrefixes);
IniFile.SetValueB("General", "IsDaylightCycleEnabled", m_IsDaylightCycleEnabled);
IniFile.SetValueI("General", "Weather", (int)m_Weather); IniFile.SetValueI("General", "Weather", (int)m_Weather);
IniFile.SetValueI("General", "TimeInTicks", m_TimeOfDay); IniFile.SetValueI("General", "TimeInTicks", m_TimeOfDay);
IniFile.WriteFile(m_IniFileName); IniFile.WriteFile(m_IniFileName);
@ -827,28 +831,32 @@ void cWorld::Tick(float a_Dt, int a_LastTickDurationMSec)
{ {
SetChunkData(**itr); SetChunkData(**itr);
} // for itr - SetChunkDataQueue[] } // 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_WorldAgeSecs += (double)a_Dt / 1000.0;
m_TimeOfDaySecs += (double)a_Dt / 1000.0;
// Wrap time of day each 20 minutes (1200 seconds)
if (m_TimeOfDaySecs > 1200.0)
{
m_TimeOfDaySecs -= 1200.0;
}
m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0); m_WorldAge = (Int64)(m_WorldAgeSecs * 20.0);
m_TimeOfDay = (Int64)(m_TimeOfDaySecs * 20.0);
// Updates the sky darkness based on current time of day if (m_IsDaylightCycleEnabled)
UpdateSkyDarkness();
// Broadcast time update every 40 ticks (2 seconds)
if (m_LastTimeUpdate < m_WorldAge - 40)
{ {
BroadcastTimeUpdate(); // We need sub-tick precision here, that's why we store the time in seconds and calculate ticks off of it
m_LastTimeUpdate = m_WorldAge; m_TimeOfDaySecs += (double)a_Dt / 1000.0;
// Wrap time of day each 20 minutes (1200 seconds)
if (m_TimeOfDaySecs > 1200.0)
{
m_TimeOfDaySecs -= 1200.0;
}
m_TimeOfDay = (Int64)(m_TimeOfDaySecs * 20.0);
// 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: // Add entities waiting in the queue to be added:
@ -2251,7 +2259,7 @@ void cWorld::BroadcastTimeUpdate(const cClientHandle * a_Exclude)
{ {
continue; 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); cCSLock Lock(m_CSPlayers);
for (cPlayerList::iterator itr = PlayersToAdd.begin(), end = PlayersToAdd.end(); itr != end; ++itr) 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()); LOGD("Adding player %s to world \"%s\".", (*itr)->GetName().c_str(), m_WorldName.c_str());
m_Players.push_back(*itr); m_Players.push_back(*itr);

View File

@ -145,7 +145,17 @@ public:
// tolua_begin // tolua_begin
int GetTicksUntilWeatherChange(void) const { return m_WeatherInterval; } 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 GetWorldAge (void) const override { return m_WorldAge; }
virtual Int64 GetTimeOfDay(void) const override { return m_TimeOfDay; } virtual Int64 GetTimeOfDay(void) const override { return m_TimeOfDay; }
@ -158,6 +168,7 @@ public:
{ {
m_TimeOfDay = a_TimeOfDay; m_TimeOfDay = a_TimeOfDay;
m_TimeOfDaySecs = (double)a_TimeOfDay / 20.0; m_TimeOfDaySecs = (double)a_TimeOfDay / 20.0;
UpdateSkyDarkness();
BroadcastTimeUpdate(); 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 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 BroadcastEntityStatus (const cEntity & a_Entity, char a_Status, const cClientHandle * a_Exclude = NULL);
void BroadcastEntityVelocity (const cEntity & a_Entity, 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 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 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); void BroadcastRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID, const cClientHandle * a_Exclude = NULL);
@ -868,6 +879,7 @@ private:
bool m_BroadcastDeathMessages; bool m_BroadcastDeathMessages;
bool m_BroadcastAchievementMessages; bool m_BroadcastAchievementMessages;
bool m_IsDaylightCycleEnabled;
double m_WorldAgeSecs; // World age, in seconds. Is only incremented, cannot be set by plugins. 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. 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 Int64 m_WorldAge; // World age in ticks, calculated off of m_WorldAgeSecs

View File

@ -273,6 +273,8 @@ int main( int argc, char **argv)
} }
} // for i - argv[] } // for i - argv[]
cLogger::InitiateMultithreading();
#if !defined(ANDROID_NDK) #if !defined(ANDROID_NDK)
try try
#endif #endif