1
0

Merge remote-tracking branch 'origin/master' into Ranks

This commit is contained in:
Mattes D 2014-08-22 15:18:39 +02:00
commit e034b64a5b
84 changed files with 1044 additions and 875 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

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

@ -16,6 +16,7 @@
#include "../../../lua/src/lauxlib.h" #include "../../../lua/src/lauxlib.h"
#include <stdlib.h> #include <stdlib.h>
#include <assert.h>
TOLUA_API void tolua_pushvalue (lua_State* L, int lo) TOLUA_API void tolua_pushvalue (lua_State* L, int lo)
{ {
@ -55,12 +56,14 @@ TOLUA_API void tolua_pushusertype (lua_State* L, void* value, const char* type)
else else
{ {
luaL_getmetatable(L, type); luaL_getmetatable(L, type);
assert(!lua_isnil(L, -1)); /* Failure here means that the usertype is unknown to ToLua. Check what type you're pushing. */
lua_pushstring(L,"tolua_ubox"); lua_pushstring(L,"tolua_ubox");
lua_rawget(L,-2); /* stack: mt ubox */ lua_rawget(L,-2); /* stack: mt ubox */
if (lua_isnil(L, -1)) { if (lua_isnil(L, -1))
lua_pop(L, 1); {
lua_pushstring(L, "tolua_ubox"); lua_pop(L, 1);
lua_rawget(L, LUA_REGISTRYINDEX); lua_pushstring(L, "tolua_ubox");
lua_rawget(L, LUA_REGISTRYINDEX);
}; };
lua_pushlightuserdata(L,value); lua_pushlightuserdata(L,value);
lua_rawget(L,-2); /* stack: mt ubox ubox[u] */ lua_rawget(L,-2); /* stack: mt ubox ubox[u] */

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

@ -460,7 +460,43 @@ void cLuaState::Push(const Vector3d & a_Vector)
{ {
ASSERT(IsValid()); ASSERT(IsValid());
tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3d"); tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3<double>");
m_NumCurrentFunctionArgs += 1;
}
void cLuaState::Push(const Vector3d * a_Vector)
{
ASSERT(IsValid());
tolua_pushusertype(m_LuaState, (void *)a_Vector, "Vector3<double>");
m_NumCurrentFunctionArgs += 1;
}
void cLuaState::Push(const Vector3i & a_Vector)
{
ASSERT(IsValid());
tolua_pushusertype(m_LuaState, (void *)&a_Vector, "Vector3<int>");
m_NumCurrentFunctionArgs += 1;
}
void cLuaState::Push(const Vector3i * a_Vector)
{
ASSERT(IsValid());
tolua_pushusertype(m_LuaState, (void *)a_Vector, "Vector3<int>");
m_NumCurrentFunctionArgs += 1; m_NumCurrentFunctionArgs += 1;
} }
@ -708,11 +744,11 @@ void cLuaState::Push(TakeDamageInfo * a_TDI)
void cLuaState::Push(Vector3i * a_Vector) void cLuaState::Push(Vector3d * a_Vector)
{ {
ASSERT(IsValid()); ASSERT(IsValid());
tolua_pushusertype(m_LuaState, a_Vector, "Vector3i"); tolua_pushusertype(m_LuaState, a_Vector, "Vector3<double>");
m_NumCurrentFunctionArgs += 1; m_NumCurrentFunctionArgs += 1;
} }
@ -720,11 +756,11 @@ void cLuaState::Push(Vector3i * a_Vector)
void cLuaState::Push(Vector3d * a_Vector) void cLuaState::Push(Vector3i * a_Vector)
{ {
ASSERT(IsValid()); ASSERT(IsValid());
tolua_pushusertype(m_LuaState, a_Vector, "Vector3d"); tolua_pushusertype(m_LuaState, a_Vector, "Vector3<int>");
m_NumCurrentFunctionArgs += 1; m_NumCurrentFunctionArgs += 1;
} }

View File

@ -186,6 +186,9 @@ public:
void Push(const HTTPRequest * a_Request); void Push(const HTTPRequest * a_Request);
void Push(const HTTPTemplateRequest * a_Request); void Push(const HTTPTemplateRequest * a_Request);
void Push(const Vector3d & a_Vector); void Push(const Vector3d & a_Vector);
void Push(const Vector3d * a_Vector);
void Push(const Vector3i & a_Vector);
void Push(const Vector3i * a_Vector);
// Push a value onto the stack (keep alpha-sorted): // Push a value onto the stack (keep alpha-sorted):
void Push(bool a_Value); void Push(bool a_Value);

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;
@ -91,6 +91,7 @@ public:
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) = 0;
virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) = 0;
virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) = 0;
virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) = 0;
virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) = 0;
virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) = 0;
virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 0; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) = 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;
@ -1193,6 +1193,26 @@ bool cPluginLua::OnProjectileHitEntity(cProjectileEntity & a_Projectile, cEntity
bool cPluginLua::OnServerPing(cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon)
{
cCSLock Lock(m_CriticalSection);
bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_SERVER_PING];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
m_LuaState.Call((int)(**itr), &a_ClientHandle, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon, cLuaState::Return, res, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon);
if (res)
{
return true;
}
}
return false;
}
bool cPluginLua::OnSpawnedEntity(cWorld & a_World, cEntity & a_Entity) bool cPluginLua::OnSpawnedEntity(cWorld & a_World, cEntity & a_Entity)
{ {
cCSLock Lock(m_CriticalSection); cCSLock Lock(m_CriticalSection);
@ -1570,6 +1590,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
case cPluginManager::HOOK_PLUGINS_LOADED: return "OnPluginsLoaded"; case cPluginManager::HOOK_PLUGINS_LOADED: return "OnPluginsLoaded";
case cPluginManager::HOOK_POST_CRAFTING: return "OnPostCrafting"; case cPluginManager::HOOK_POST_CRAFTING: return "OnPostCrafting";
case cPluginManager::HOOK_PRE_CRAFTING: return "OnPreCrafting"; case cPluginManager::HOOK_PRE_CRAFTING: return "OnPreCrafting";
case cPluginManager::HOOK_SERVER_PING: return "OnServerPing";
case cPluginManager::HOOK_SPAWNED_ENTITY: return "OnSpawnedEntity"; case cPluginManager::HOOK_SPAWNED_ENTITY: return "OnSpawnedEntity";
case cPluginManager::HOOK_SPAWNED_MONSTER: return "OnSpawnedMonster"; case cPluginManager::HOOK_SPAWNED_MONSTER: return "OnSpawnedMonster";
case cPluginManager::HOOK_SPAWNING_ENTITY: return "OnSpawningEntity"; case cPluginManager::HOOK_SPAWNING_ENTITY: return "OnSpawningEntity";

View File

@ -98,8 +98,8 @@ 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 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 OnPlayerMoving (cPlayer & a_Player, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) 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;
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) override; 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) override;
@ -117,6 +117,7 @@ public:
virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override; virtual bool OnPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe) override;
virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override; virtual bool OnProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos) override;
virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override; virtual bool OnProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity) override;
virtual bool OnServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon) override;
virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawnedEntity (cWorld & a_World, cEntity & a_Entity) override;
virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override; virtual bool OnSpawnedMonster (cWorld & a_World, cMonster & a_Monster) override;
virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) override; virtual bool OnSpawningEntity (cWorld & a_World, cEntity & a_Entity) 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;
} }
@ -1189,6 +1189,25 @@ bool cPluginManager::CallHookProjectileHitEntity(cProjectileEntity & a_Projectil
bool cPluginManager::CallHookServerPing(cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon)
{
FIND_HOOK(HOOK_SERVER_PING);
VERIFY_HOOK;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnServerPing(a_ClientHandle, a_ServerDescription, a_OnlinePlayersCount, a_MaxPlayersCount, a_Favicon))
{
return true;
}
}
return false;
}
bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity) bool cPluginManager::CallHookSpawnedEntity(cWorld & a_World, cEntity & a_Entity)
{ {
FIND_HOOK(HOOK_SPAWNED_ENTITY); FIND_HOOK(HOOK_SPAWNED_ENTITY);

View File

@ -120,6 +120,7 @@ public:
HOOK_PRE_CRAFTING, HOOK_PRE_CRAFTING,
HOOK_PROJECTILE_HIT_BLOCK, HOOK_PROJECTILE_HIT_BLOCK,
HOOK_PROJECTILE_HIT_ENTITY, HOOK_PROJECTILE_HIT_ENTITY,
HOOK_SERVER_PING,
HOOK_SPAWNED_ENTITY, HOOK_SPAWNED_ENTITY,
HOOK_SPAWNED_MONSTER, HOOK_SPAWNED_MONSTER,
HOOK_SPAWNING_ENTITY, HOOK_SPAWNING_ENTITY,
@ -206,7 +207,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);
@ -225,6 +226,7 @@ public:
bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe); bool CallHookPreCrafting (const cPlayer * a_Player, const cCraftingGrid * a_Grid, cCraftingRecipe * a_Recipe);
bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos); bool CallHookProjectileHitBlock (cProjectileEntity & a_Projectile, int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_Face, const Vector3d & a_BlockHitPos);
bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity); bool CallHookProjectileHitEntity (cProjectileEntity & a_Projectile, cEntity & a_HitEntity);
bool CallHookServerPing (cClientHandle & a_ClientHandle, AString & a_ServerDescription, int & a_OnlinePlayersCount, int & a_MaxPlayersCount, AString & a_Favicon);
bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawnedEntity (cWorld & a_World, cEntity & a_Entity);
bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster); bool CallHookSpawnedMonster (cWorld & a_World, cMonster & a_Monster);
bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity); bool CallHookSpawningEntity (cWorld & a_World, cEntity & a_Entity);

View File

@ -54,6 +54,7 @@ local Combinations =
{9, 2}, {9, 2},
-- Special combinations: -- Special combinations:
{5, 5},
{7, 3}, {7, 3},
{8, 3}, {8, 3},
{9, 5}, {9, 5},

View File

@ -1764,7 +1764,9 @@ NIBBLETYPE cBlockArea::GetNibble(int a_BlockX, int a_BlockY, int a_BlockZ, NIBBL
cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) : cBlockArea::cChunkReader::cChunkReader(cBlockArea & a_Area) :
m_Area(a_Area), m_Area(a_Area),
m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z) m_Origin(a_Area.m_Origin.x, a_Area.m_Origin.y, a_Area.m_Origin.z),
m_CurrentChunkX(0),
m_CurrentChunkZ(0)
{ {
} }

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

@ -40,11 +40,6 @@ public:
FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface); FindAndSetPortalFrame(a_BlockX, a_BlockY - 1, a_BlockZ, a_ChunkInterface, a_WorldInterface);
} }
virtual void OnDigging(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cPlayer * a_Player, int a_BlockX, int a_BlockY, int a_BlockZ) override
{
a_ChunkInterface.DigBlock(a_WorldInterface, a_BlockX, a_BlockY, a_BlockZ);
}
virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override
{ {
// No pickups from this block // No pickups from this block
@ -60,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)
@ -91,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
@ -149,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)
@ -168,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);
@ -182,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);
} }
@ -204,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);
@ -218,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")
@ -39,8 +40,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
@ -104,8 +105,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

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

View File

@ -419,7 +419,7 @@ public:
X Data; X Data;
cCoordWithData(int a_X, int a_Y, int a_Z) : cCoordWithData(int a_X, int a_Y, int a_Z) :
x(a_X), y(a_Y), z(a_Z) x(a_X), y(a_Y), z(a_Z), Data()
{ {
} }

View File

@ -75,11 +75,21 @@ cClientHandle::cClientHandle(const cSocket * a_Socket, int a_ViewDistance) :
m_TimeSinceLastPacket(0), m_TimeSinceLastPacket(0),
m_Ping(1000), m_Ping(1000),
m_PingID(1), m_PingID(1),
m_PingStartTime(0),
m_LastPingTime(1000),
m_BlockDigAnimStage(-1), m_BlockDigAnimStage(-1),
m_BlockDigAnimSpeed(0),
m_BlockDigAnimX(0),
m_BlockDigAnimY(256), // Invalid Y, so that the coords don't get picked up
m_BlockDigAnimZ(0),
m_HasStartedDigging(false), m_HasStartedDigging(false),
m_LastDigBlockX(0),
m_LastDigBlockY(256), // Invalid Y, so that the coords don't get picked up
m_LastDigBlockZ(0),
m_State(csConnected), m_State(csConnected),
m_ShouldCheckDownloaded(false), m_ShouldCheckDownloaded(false),
m_NumExplosionsThisTick(0), m_NumExplosionsThisTick(0),
m_NumBlockChangeInteractionsThisTick(0),
m_UniqueID(0), m_UniqueID(0),
m_HasSentPlayerChunk(false), m_HasSentPlayerChunk(false),
m_Locale("en_GB") m_Locale("en_GB")
@ -912,6 +922,23 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
return; return;
} }
// Check for clickthrough-blocks:
/* When the user breaks a fire block, the client send the wrong block location.
We must find the right block with the face direction. */
if (a_BlockFace != BLOCK_FACE_NONE)
{
int BlockX = a_BlockX;
int BlockY = a_BlockY;
int BlockZ = a_BlockZ;
AddFaceDirection(BlockX, BlockY, BlockZ, a_BlockFace);
if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(BlockX, BlockY, BlockZ))->IsClickedThrough())
{
a_BlockX = BlockX;
a_BlockY = BlockY;
a_BlockZ = BlockZ;
}
}
if ( if (
((a_Status == DIG_STATUS_STARTED) || (a_Status == DIG_STATUS_FINISHED)) && // Only do a radius check for block destruction - things like pickup tossing send coordinates that are to be ignored ((a_Status == DIG_STATUS_STARTED) || (a_Status == DIG_STATUS_FINISHED)) && // Only do a radius check for block destruction - things like pickup tossing send coordinates that are to be ignored
((Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) || ((Diff(m_Player->GetPosX(), (double)a_BlockX) > 6) ||
@ -920,10 +947,6 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
) )
{ {
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))->IsClickedThrough())
{
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player);
}
return; return;
} }
@ -932,10 +955,6 @@ void cClientHandle::HandleLeftClick(int a_BlockX, int a_BlockY, int a_BlockZ, eB
{ {
// A plugin doesn't agree with the action, replace the block on the client and quit: // A plugin doesn't agree with the action, replace the block on the client and quit:
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player);
if (cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(a_BlockX, a_BlockY + 1, a_BlockZ))->IsClickedThrough())
{
m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player);
}
return; return;
} }
@ -1059,26 +1078,6 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc
m_LastDigBlockY = a_BlockY; m_LastDigBlockY = a_BlockY;
m_LastDigBlockZ = a_BlockZ; m_LastDigBlockZ = a_BlockZ;
// Check for clickthrough-blocks:
/* When the user breaks a fire block, the client send the wrong block location.
We must find the right block with the face direction. */
if (a_BlockFace != BLOCK_FACE_NONE)
{
int pX = a_BlockX;
int pY = a_BlockY;
int pZ = a_BlockZ;
AddFaceDirection(pX, pY, pZ, a_BlockFace); // Get the block in front of the clicked coordinates (m_bInverse defaulted to false)
cBlockHandler * Handler = cBlockInfo::GetHandler(m_Player->GetWorld()->GetBlock(pX, pY, pZ));
if (Handler->IsClickedThrough())
{
cChunkInterface ChunkInterface(m_Player->GetWorld()->GetChunkMap());
Handler->OnDigging(ChunkInterface, *m_Player->GetWorld(), m_Player, pX, pY, pZ);
return;
}
}
if ( if (
(m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately (m_Player->IsGameModeCreative()) || // In creative mode, digging is done immediately
cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too cBlockInfo::IsOneHitDig(a_OldBlock) // One-hit blocks get destroyed immediately, too

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

@ -21,7 +21,8 @@ const int CYCLE_MILLISECONDS = 100;
cDeadlockDetect::cDeadlockDetect(void) : cDeadlockDetect::cDeadlockDetect(void) :
super("DeadlockDetect") super("DeadlockDetect"),
m_IntervalSec(1000)
{ {
} }
@ -136,6 +137,7 @@ void cDeadlockDetect::CheckWorldAge(const AString & a_WorldName, Int64 a_Age)
void cDeadlockDetect::DeadlockDetected(void) void cDeadlockDetect::DeadlockDetected(void)
{ {
LOGERROR("Deadlock detected, aborting the server");
ASSERT(!"Deadlock detected"); ASSERT(!"Deadlock detected");
abort(); abort();
} }

View File

@ -222,16 +222,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
{ {
@ -881,7 +889,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 !
@ -1500,7 +1508,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);
@ -1685,6 +1693,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

@ -45,7 +45,7 @@ public:
float NextFloat(float a_Range, int a_Salt); float NextFloat(float a_Range, int a_Salt);
/** Returns a random float between 0 and 1. */ /** Returns a random float between 0 and 1. */
float NextFloat(void) { return NextFloat(1); }; float NextFloat(void) { return NextFloat(1); }
/** Returns a random int in the range [a_Begin .. a_End] */ /** Returns a random int in the range [a_Begin .. a_End] */
int GenerateRandomInteger(int a_Begin, int a_End); int GenerateRandomInteger(int a_Begin, int a_End);

View File

@ -166,6 +166,9 @@ cCaveTunnel::cCaveTunnel(
if ((a_BlockStartY <= 0) && (a_BlockEndY <= 0)) if ((a_BlockStartY <= 0) && (a_BlockEndY <= 0))
{ {
// Don't bother detailing this cave, it's under the world anyway // Don't bother detailing this cave, it's under the world anyway
m_MinBlockX = m_MaxBlockX = 0;
m_MinBlockY = m_MaxBlockY = -1;
m_MinBlockZ = m_MaxBlockZ = 0;
return; return;
} }

View File

@ -27,6 +27,7 @@ const unsigned int QUEUE_SKIP_LIMIT = 500;
cChunkGenerator::cChunkGenerator(void) : cChunkGenerator::cChunkGenerator(void) :
super("cChunkGenerator"), super("cChunkGenerator"),
m_Seed(0), // Will be overwritten by the actual generator
m_Generator(NULL), m_Generator(NULL),
m_PluginInterface(NULL), m_PluginInterface(NULL),
m_ChunkSink(NULL) m_ChunkSink(NULL)

View File

@ -239,7 +239,13 @@ bool cHeiGenCache::GetHeightAt(int a_ChunkX, int a_ChunkZ, int a_RelX, int a_Rel
cHeiGenClassic::cHeiGenClassic(int a_Seed) : cHeiGenClassic::cHeiGenClassic(int a_Seed) :
m_Seed(a_Seed), m_Seed(a_Seed),
m_Noise(a_Seed) m_Noise(a_Seed),
m_HeightFreq1(1.0f),
m_HeightAmp1(1.0f),
m_HeightFreq2(0.5f),
m_HeightAmp2(0.5f),
m_HeightFreq3(0.1f),
m_HeightAmp3(0.1f)
{ {
} }
@ -432,7 +438,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

@ -15,7 +15,8 @@
cHTTPConnection::cHTTPConnection(cHTTPServer & a_HTTPServer) : cHTTPConnection::cHTTPConnection(cHTTPServer & a_HTTPServer) :
m_HTTPServer(a_HTTPServer), m_HTTPServer(a_HTTPServer),
m_State(wcsRecvHeaders), m_State(wcsRecvHeaders),
m_CurrentRequest(NULL) m_CurrentRequest(NULL),
m_CurrentRequestBodyRemaining(0)
{ {
// LOGD("HTTP: New connection at %p", this); // LOGD("HTTP: New connection at %p", this);
} }

View File

@ -15,7 +15,9 @@
cHTTPFormParser::cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callbacks) : cHTTPFormParser::cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callbacks) :
m_Callbacks(a_Callbacks), m_Callbacks(a_Callbacks),
m_IsValid(true) m_IsValid(true),
m_IsCurrentPartFile(false),
m_FileHasBeenAnnounced(false)
{ {
if (a_Request.GetMethod() == "GET") if (a_Request.GetMethod() == "GET")
{ {
@ -55,7 +57,9 @@ cHTTPFormParser::cHTTPFormParser(cHTTPRequest & a_Request, cCallbacks & a_Callba
cHTTPFormParser::cHTTPFormParser(eKind a_Kind, const char * a_Data, size_t a_Size, cCallbacks & a_Callbacks) : cHTTPFormParser::cHTTPFormParser(eKind a_Kind, const char * a_Data, size_t a_Size, cCallbacks & a_Callbacks) :
m_Callbacks(a_Callbacks), m_Callbacks(a_Callbacks),
m_Kind(a_Kind), m_Kind(a_Kind),
m_IsValid(true) m_IsValid(true),
m_IsCurrentPartFile(false),
m_FileHasBeenAnnounced(false)
{ {
Parse(a_Data, a_Size); Parse(a_Data, a_Size);
} }

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

@ -73,6 +73,8 @@ public:
HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs) HEIGHTTYPE * m_HeightMap; // 3x3 chunks of height map, organized as a single XZY blob of data (instead of 3x3 XZY blobs)
cReader(BLOCKTYPE * a_BlockTypes, HEIGHTTYPE * a_HeightMap) : cReader(BLOCKTYPE * a_BlockTypes, HEIGHTTYPE * a_HeightMap) :
m_ReadingChunkX(0),
m_ReadingChunkZ(0),
m_MaxHeight(0), m_MaxHeight(0),
m_BlockTypes(a_BlockTypes), m_BlockTypes(a_BlockTypes),
m_HeightMap(a_HeightMap) m_HeightMap(a_HeightMap)
@ -89,7 +91,9 @@ public:
cLightingThread::cLightingThread(void) : cLightingThread::cLightingThread(void) :
super("cLightingThread"), super("cLightingThread"),
m_World(NULL) m_World(NULL),
m_MaxHeight(0),
m_NumSeeds(0)
{ {
} }

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

@ -146,6 +146,8 @@ cCubicCell2D::cCubicCell2D(
) : ) :
m_Noise(a_Noise), m_Noise(a_Noise),
m_WorkRnds(&m_Workspace1), m_WorkRnds(&m_Workspace1),
m_CurFloorX(0),
m_CurFloorY(0),
m_Array(a_Array), m_Array(a_Array),
m_SizeX(a_SizeX), m_SizeX(a_SizeX),
m_SizeY(a_SizeY), m_SizeY(a_SizeY),
@ -300,6 +302,9 @@ cCubicCell3D::cCubicCell3D(
) : ) :
m_Noise(a_Noise), m_Noise(a_Noise),
m_WorkRnds(&m_Workspace1), m_WorkRnds(&m_Workspace1),
m_CurFloorX(0),
m_CurFloorY(0),
m_CurFloorZ(0),
m_Array(a_Array), m_Array(a_Array),
m_SizeX(a_SizeX), m_SizeX(a_SizeX),
m_SizeY(a_SizeY), m_SizeY(a_SizeY),

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

@ -16,6 +16,7 @@ cSslContext::cSslContext(void) :
m_IsValid(false), m_IsValid(false),
m_HasHandshaken(false) m_HasHandshaken(false)
{ {
memset(&m_Ssl, 0, sizeof(m_Ssl));
} }

View File

@ -41,6 +41,7 @@ Implements the 1.7.x protocol classes:
#include "../BlockEntities/CommandBlockEntity.h" #include "../BlockEntities/CommandBlockEntity.h"
#include "../BlockEntities/MobHeadEntity.h" #include "../BlockEntities/MobHeadEntity.h"
#include "../BlockEntities/FlowerPotEntity.h" #include "../BlockEntities/FlowerPotEntity.h"
#include "Bindings/PluginManager.h"
@ -1720,21 +1721,41 @@ void cProtocol172::HandlePacketStatusPing(cByteBuffer & a_ByteBuffer)
void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
{ {
// Send the response:
AString Response = "{\"version\":{\"name\":\"1.7.2\", \"protocol\":4}, \"players\":{";
cServer * Server = cRoot::Get()->GetServer(); cServer * Server = cRoot::Get()->GetServer();
AppendPrintf(Response, "\"max\":%u, \"online\":%u, \"sample\":[]},", AString ServerDescription = Server->GetDescription();
Server->GetMaxPlayers(), int NumPlayers = Server->GetNumPlayers();
Server->GetNumPlayers() int MaxPlayers = Server->GetMaxPlayers();
); AString Favicon = Server->GetFaviconData();
AppendPrintf(Response, "\"description\":{\"text\":\"%s\"},", cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon);
Server->GetDescription().c_str()
); // Version:
AppendPrintf(Response, "\"favicon\": \"data:image/png;base64,%s\"", Json::Value Version;
Server->GetFaviconData().c_str() Version["name"] = "1.7.2";
); Version["protocol"] = 4;
Response.append("}");
// Players:
Json::Value Players;
Players["online"] = NumPlayers;
Players["max"] = MaxPlayers;
// TODO: Add "sample"
// Description:
Json::Value Description;
Description["text"] = ServerDescription.c_str();
// Create the response:
Json::Value ResponseValue;
ResponseValue["version"] = Version;
ResponseValue["players"] = Players;
ResponseValue["description"] = Description;
if (!Favicon.empty())
{
ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str());
}
Json::StyledWriter Writer;
AString Response = Writer.write(ResponseValue);
cPacketizer Pkt(*this, 0x00); // Response packet cPacketizer Pkt(*this, 0x00); // Response packet
Pkt.WriteString(Response); Pkt.WriteString(Response);
} }
@ -1803,7 +1824,11 @@ void cProtocol172::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffe
void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) void cProtocol172::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
{ {
AString Username; AString Username;
a_ByteBuffer.ReadVarUTF8String(Username); if (!a_ByteBuffer.ReadVarUTF8String(Username))
{
m_Client->Kick("Bad username");
return;
}
if (!m_Client->HandleHandshake(Username)) if (!m_Client->HandleHandshake(Username))
{ {
@ -3070,20 +3095,41 @@ void cProtocol176::SendPlayerSpawn(const cPlayer & a_Player)
void cProtocol176::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) void cProtocol176::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
{ {
// Send the response: cServer * Server = cRoot::Get()->GetServer();
AString Response = "{\"version\": {\"name\": \"1.7.6\", \"protocol\":5}, \"players\": {"; AString Motd = Server->GetDescription();
AppendPrintf(Response, "\"max\": %u, \"online\": %u, \"sample\": []},", int NumPlayers = Server->GetNumPlayers();
cRoot::Get()->GetServer()->GetMaxPlayers(), int MaxPlayers = Server->GetMaxPlayers();
cRoot::Get()->GetServer()->GetNumPlayers() AString Favicon = Server->GetFaviconData();
); cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, Motd, NumPlayers, MaxPlayers, Favicon);
AppendPrintf(Response, "\"description\": {\"text\": \"%s\"},",
cRoot::Get()->GetServer()->GetDescription().c_str() // Version:
); Json::Value Version;
AppendPrintf(Response, "\"favicon\": \"data:image/png;base64,%s\"", Version["name"] = "1.7.6";
cRoot::Get()->GetServer()->GetFaviconData().c_str() Version["protocol"] = 5;
);
Response.append("}"); // Players:
Json::Value Players;
Players["online"] = NumPlayers;
Players["max"] = MaxPlayers;
// TODO: Add "sample"
// Description:
Json::Value Description;
Description["text"] = Motd.c_str();
// Create the response:
Json::Value ResponseValue;
ResponseValue["version"] = Version;
ResponseValue["players"] = Players;
ResponseValue["description"] = Description;
if (!Favicon.empty())
{
ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str());
}
Json::StyledWriter Writer;
AString Response = Writer.write(ResponseValue);
cPacketizer Pkt(*this, 0x00); // Response packet cPacketizer Pkt(*this, 0x00); // Response packet
Pkt.WriteString(Response); Pkt.WriteString(Response);
} }

View File

@ -18,6 +18,7 @@
#include "../Server.h" #include "../Server.h"
#include "../World.h" #include "../World.h"
#include "../ChatColor.h" #include "../ChatColor.h"
#include "Bindings/PluginManager.h"
@ -1013,6 +1014,13 @@ void cProtocolRecognizer::SendLengthlessServerPing(void)
{ {
AString Reply; AString Reply;
cServer * Server = cRoot::Get()->GetServer(); cServer * Server = cRoot::Get()->GetServer();
AString ServerDescription = Server->GetDescription();
int NumPlayers = Server->GetNumPlayers();
int MaxPlayers = Server->GetMaxPlayers();
AString Favicon = Server->GetFaviconData();
cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon);
switch (cRoot::Get()->GetPrimaryServerVersion()) switch (cRoot::Get()->GetPrimaryServerVersion())
{ {
case PROTO_VERSION_1_2_5: case PROTO_VERSION_1_2_5:
@ -1020,11 +1028,11 @@ void cProtocolRecognizer::SendLengthlessServerPing(void)
{ {
// http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29 // http://wiki.vg/wiki/index.php?title=Protocol&oldid=3099#Server_List_Ping_.280xFE.29
Printf(Reply, "%s%s%i%s%i", Printf(Reply, "%s%s%i%s%i",
Server->GetDescription().c_str(), ServerDescription.c_str(),
cChatColor::Delimiter, cChatColor::Delimiter,
Server->GetNumPlayers(), NumPlayers,
cChatColor::Delimiter, cChatColor::Delimiter,
Server->GetMaxPlayers() MaxPlayers
); );
break; break;
} }
@ -1051,13 +1059,7 @@ void cProtocolRecognizer::SendLengthlessServerPing(void)
m_Buffer.ReadByte(val); // 0x01 magic value m_Buffer.ReadByte(val); // 0x01 magic value
ASSERT(val == 0x01); ASSERT(val == 0x01);
} }
// http://wiki.vg/wiki/index.php?title=Server_List_Ping&oldid=3100
AString NumPlayers;
Printf(NumPlayers, "%d", Server->GetNumPlayers());
AString MaxPlayers;
Printf(MaxPlayers, "%d", Server->GetMaxPlayers());
AString ProtocolVersionNum; AString ProtocolVersionNum;
Printf(ProtocolVersionNum, "%d", cRoot::Get()->GetPrimaryServerVersion()); Printf(ProtocolVersionNum, "%d", cRoot::Get()->GetPrimaryServerVersion());
AString ProtocolVersionTxt(GetVersionTextFromInt(cRoot::Get()->GetPrimaryServerVersion())); AString ProtocolVersionTxt(GetVersionTextFromInt(cRoot::Get()->GetPrimaryServerVersion()));
@ -1070,11 +1072,11 @@ void cProtocolRecognizer::SendLengthlessServerPing(void)
Reply.push_back(0); Reply.push_back(0);
Reply.append(ProtocolVersionTxt); Reply.append(ProtocolVersionTxt);
Reply.push_back(0); Reply.push_back(0);
Reply.append(Server->GetDescription()); Reply.append(ServerDescription);
Reply.push_back(0); Reply.push_back(0);
Reply.append(NumPlayers); Reply.append(Printf("%d", NumPlayers));
Reply.push_back(0); Reply.push_back(0);
Reply.append(MaxPlayers); Reply.append(Printf("%d", MaxPlayers));
break; break;
} }
} // switch (m_PrimaryServerVersion) } // switch (m_PrimaryServerVersion)

View File

@ -18,7 +18,7 @@
// Adjust these if a new protocol is added or an old one is removed: // Adjust these if a new protocol is added or an old one is removed:
#define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.5, 1.5.1, 1.5.2, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.7.2, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9" #define MCS_CLIENT_VERSIONS "1.2.4, 1.2.5, 1.3.1, 1.3.2, 1.4.2, 1.4.4, 1.4.5, 1.4.6, 1.4.7, 1.5, 1.5.1, 1.5.2, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.7.2, 1.7.4, 1.7.5, 1.7.6, 1.7.7, 1.7.8, 1.7.9, 1.7.10"
#define MCS_PROTOCOL_VERSIONS "29, 39, 47, 49, 51, 60, 61, 73, 74, 77, 78, 4, 5" #define MCS_PROTOCOL_VERSIONS "29, 39, 47, 49, 51, 60, 61, 73, 74, 77, 78, 4, 5"

View File

@ -17,6 +17,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"
@ -49,7 +50,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)
{ {
@ -103,10 +103,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)
@ -245,8 +250,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;
} }
@ -270,15 +280,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

@ -193,8 +193,6 @@ private:
cRankManager m_RankManager; cRankManager m_RankManager;
cHTTPServer m_HTTPServer; cHTTPServer m_HTTPServer;
cMCLogger * m_Log;
bool m_bStop; bool m_bStop;
bool m_bRestart; bool m_bRestart;

View File

@ -116,7 +116,9 @@ cServer::cServer(void) :
m_MaxPlayers(0), m_MaxPlayers(0),
m_bIsHardcore(false), m_bIsHardcore(false),
m_TickThread(*this), m_TickThread(*this),
m_ShouldAuthenticate(false) m_ShouldAuthenticate(false),
m_ShouldLoadOfflinePlayerData(false),
m_ShouldLoadNamedPlayerData(true)
{ {
} }

View File

@ -13,6 +13,9 @@
cSetChunkData::cSetChunkData(int a_ChunkX, int a_ChunkZ, bool a_ShouldMarkDirty) : cSetChunkData::cSetChunkData(int a_ChunkX, int a_ChunkZ, bool a_ShouldMarkDirty) :
m_ChunkX(a_ChunkX), m_ChunkX(a_ChunkX),
m_ChunkZ(a_ChunkZ), m_ChunkZ(a_ChunkZ),
m_IsLightValid(false),
m_IsHeightMapValid(false),
m_AreBiomesValid(false),
m_ShouldMarkDirty(a_ShouldMarkDirty) m_ShouldMarkDirty(a_ShouldMarkDirty)
{ {
} }

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

@ -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"
@ -250,8 +251,38 @@ cWorld::cWorld(const AString & a_WorldName, eDimension a_Dimension, const AStrin
m_TimeOfDay(0), m_TimeOfDay(0),
m_LastTimeUpdate(0), m_LastTimeUpdate(0),
m_SkyDarkness(0), m_SkyDarkness(0),
m_GameMode(gmNotSet),
m_bEnabledPVP(false),
m_IsDeepSnowEnabled(false),
m_ShouldLavaSpawnFire(true),
m_VillagersShouldHarvestCrops(true),
m_SimulatorManager(NULL),
m_SandSimulator(NULL),
m_WaterSimulator(NULL),
m_LavaSimulator(NULL),
m_FireSimulator(NULL),
m_RedstoneSimulator(NULL),
m_MaxPlayers(10),
m_ChunkMap(NULL),
m_bAnimals(true),
m_Weather(eWeather_Sunny), m_Weather(eWeather_Sunny),
m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :) m_WeatherInterval(24000), // Guaranteed 1 day of sunshine at server start :)
m_MaxCactusHeight(3),
m_MaxSugarcaneHeight(4),
m_IsCactusBonemealable(false),
m_IsCarrotsBonemealable(true),
m_IsCropsBonemealable(true),
m_IsGrassBonemealable(true),
m_IsMelonStemBonemealable(true),
m_IsMelonBonemealable(true),
m_IsPotatoesBonemealable(true),
m_IsPumpkinStemBonemealable(true),
m_IsPumpkinBonemealable(true),
m_IsSaplingBonemealable(true),
m_IsSugarcaneBonemealable(false),
m_bCommandBlocksEnabled(true),
m_bUseChatPrefixes(false),
m_TNTShrapnelLevel(slNone),
m_Scoreboard(this), m_Scoreboard(this),
m_MapManager(this), m_MapManager(this),
m_GeneratorCallbacks(*this), m_GeneratorCallbacks(*this),
@ -406,7 +437,7 @@ void cWorld::InitializeSpawn(void)
int ViewDist = IniFile.GetValueSetI("SpawnPosition", "PregenerateDistance", DefaultViewDist); int ViewDist = IniFile.GetValueSetI("SpawnPosition", "PregenerateDistance", DefaultViewDist);
IniFile.WriteFile(m_IniFileName); IniFile.WriteFile(m_IniFileName);
LOG("Preparing spawn area in world \"%s\"...", m_WorldName.c_str()); LOG("Preparing spawn area in world \"%s\", %d x %d chunks, total %d chunks...", m_WorldName.c_str(), ViewDist, ViewDist, ViewDist * ViewDist);
for (int x = 0; x < ViewDist; x++) for (int x = 0; x < ViewDist; x++)
{ {
for (int z = 0; z < ViewDist; z++) for (int z = 0; z < ViewDist; z++)

View File

@ -76,7 +76,9 @@ public:
cFastNBTTag(eTagType a_Type, int a_Parent) : cFastNBTTag(eTagType a_Type, int a_Parent) :
m_Type(a_Type), m_Type(a_Type),
m_NameStart(0),
m_NameLength(0), m_NameLength(0),
m_DataStart(0),
m_DataLength(0), m_DataLength(0),
m_Parent(a_Parent), m_Parent(a_Parent),
m_PrevSibling(-1), m_PrevSibling(-1),
@ -88,7 +90,9 @@ public:
cFastNBTTag(eTagType a_Type, int a_Parent, int a_PrevSibling) : cFastNBTTag(eTagType a_Type, int a_Parent, int a_PrevSibling) :
m_Type(a_Type), m_Type(a_Type),
m_NameStart(0),
m_NameLength(0), m_NameLength(0),
m_DataStart(0),
m_DataLength(0), m_DataLength(0),
m_Parent(a_Parent), m_Parent(a_Parent),
m_PrevSibling(a_PrevSibling), m_PrevSibling(a_PrevSibling),

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