1
0

Merge remote-tracking branch 'upstream/master'

This commit is contained in:
HaoTNN 2015-05-23 14:06:37 -07:00
commit 2578afb244
43 changed files with 229 additions and 135 deletions

View File

@ -52,6 +52,9 @@ if(MSVC OR MSVC_IDE)
endif()
endif()
set(BUILD_TOOLS OFF CACHE BOOL "")
set(SELF_TEST OFF CACHE BOOL "")
# This has to be done before any flags have been set up.
if(${BUILD_TOOLS})
message("Building tools")

View File

@ -2,6 +2,7 @@ Many people have contributed to MCServer, and this list attempts to broadcast at
BasedDoge (Donated AlchemistVillage prefabs)
bearbin (Alexander Harkness)
beeduck
derouinw
Diusrex
Duralex

View File

@ -7,7 +7,7 @@ return
Desc = [[
This hook is called after the server has moved the {{cEntity|entity}} to the given world. This is an information-only
callback, the entity is already in the new world.<p>
See also the {{OnEntityChangeWorld|HOOK_ENTITY_CHANGE_WORLD}} hook for a similar hook called before the
See also the {{OnEntityChangingWorld|HOOK_ENTITY_CHANGING_WORLD}} hook for a similar hook called before the
entity is moved to the new world.
]],
Params =

View File

@ -1,9 +1,9 @@
return
{
HOOK_ENTITY_CHANGE_WORLD =
HOOK_ENTITY_CHANGING_WORLD =
{
CalledWhen = "Before a entity is changing the world.",
DefaultFnName = "OnEntityChangeWorld", -- also used as pagename
DefaultFnName = "OnEntityChangingWorld", -- also used as pagename
Desc = [[
This hook is called before the server moves the {{cEntity|entity}} to the given world. Plugins may
refuse the changing of the entity to the new world.<p>
@ -20,7 +20,7 @@ return
returns true, no other callback is called for this event and the change of the entity to the world is
cancelled.
]],
}, -- HOOK_ENTITY_CHANGE_WORLD
}, -- HOOK_ENTITY_CHANGING_WORLD
}

View File

@ -263,6 +263,10 @@ macro(set_exe_flags)
# flags introduced in 3.2
add_flags_cxx("-Wno-documentation")
endif()
if ("${CLANG_VERSION}" VERSION_GREATER 3.5)
# Use this flag to ignore error for a reserved macro problem in sqlite 3
add_flags_cxx("-Wno-reserved-id-macro")
endif()
endif()
endif()

View File

@ -530,7 +530,7 @@ static int tolua_cWorld_TryGetHeight(lua_State * tolua_S)
// Call the implementation:
int Height = 0;
bool res = self->TryGetHeight(BlockX, BlockZ, Height);
L.Push(res ? 1 : 0);
L.Push(res);
if (res)
{
L.Push(Height);

View File

@ -56,7 +56,7 @@ public:
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0;
virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) = 0;
virtual bool OnEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition) = 0;
virtual bool OnEntityChangeWorld (cEntity & a_Entity, cWorld & a_World) = 0;
virtual bool OnEntityChangingWorld (cEntity & a_Entity, cWorld & a_World) = 0;
virtual bool OnEntityChangedWorld (cEntity & a_Entity, cWorld & a_World) = 0;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) = 0;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) = 0;

View File

@ -534,7 +534,7 @@ bool cPluginLua::OnEntityAddEffect(cEntity & a_Entity, int a_EffectType, int a_E
bool cPluginLua::OnEntityChangeWorld(cEntity & a_Entity, cWorld & a_World)
bool cPluginLua::OnEntityChangingWorld(cEntity & a_Entity, cWorld & a_World)
{
cCSLock Lock(m_CriticalSection);
if (!m_LuaState.IsValid())
@ -542,7 +542,7 @@ bool cPluginLua::OnEntityChangeWorld(cEntity & a_Entity, cWorld & a_World)
return false;
}
bool res = false;
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_CHANGE_WORLD];
cLuaRefs & Refs = m_HookMap[cPluginManager::HOOK_ENTITY_CHANGING_WORLD];
for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{
m_LuaState.Call((int)(**itr), &a_Entity, &a_World, cLuaState::Return, res);
@ -1932,7 +1932,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect";
case cPluginManager::HOOK_PLAYER_ANIMATION: return "OnPlayerAnimation";
case cPluginManager::HOOK_ENTITY_ADD_EFFECT: return "OnEntityAddEffect";
case cPluginManager::HOOK_ENTITY_CHANGE_WORLD: return "OnEntityChangeWorld";
case cPluginManager::HOOK_ENTITY_CHANGING_WORLD: return "OnEntityChangingWorld";
case cPluginManager::HOOK_ENTITY_CHANGED_WORLD: return "OnEntityChangedWorld";
case cPluginManager::HOOK_ENTITY_TELEPORT: return "OnEntityTeleport";
case cPluginManager::HOOK_EXECUTE_COMMAND: return "OnExecuteCommand";

View File

@ -115,7 +115,7 @@ public:
virtual bool OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override;
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) override;
virtual bool OnEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier) override;
virtual bool OnEntityChangeWorld (cEntity & a_Entity, cWorld & a_World) override;
virtual bool OnEntityChangingWorld (cEntity & a_Entity, cWorld & a_World) override;
virtual bool OnEntityChangedWorld (cEntity & a_Entity, cWorld & a_World) override;
virtual bool OnExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, cPluginManager::CommandResult & a_Result) override;
virtual bool OnExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData) override;
@ -179,7 +179,7 @@ public:
bool CanAddOldStyleHook(int a_HookType);
// cWebPlugin overrides
virtual const AString GetWebTitle(void) const {return GetName(); }
virtual const AString GetWebTitle(void) const override {return GetName(); }
virtual AString HandleWebRequest(const HTTPRequest & a_Request) override;
/** Adds a new web tab to webadmin.

View File

@ -525,14 +525,14 @@ bool cPluginManager::CallHookEntityTeleport(cEntity & a_Entity, const Vector3d &
bool cPluginManager::CallHookEntityChangeWorld(cEntity & a_Entity, cWorld & a_World)
bool cPluginManager::CallHookEntityChangingWorld(cEntity & a_Entity, cWorld & a_World)
{
FIND_HOOK(HOOK_ENTITY_CHANGE_WORLD);
FIND_HOOK(HOOK_ENTITY_CHANGING_WORLD);
VERIFY_HOOK;
for (PluginList::iterator itr = Plugins->second.begin(); itr != Plugins->second.end(); ++itr)
{
if ((*itr)->OnEntityChangeWorld(a_Entity, a_World))
if ((*itr)->OnEntityChangingWorld(a_Entity, a_World))
{
return true;
}

View File

@ -86,7 +86,7 @@ public:
HOOK_DISCONNECT,
HOOK_PLAYER_ANIMATION,
HOOK_ENTITY_ADD_EFFECT,
HOOK_ENTITY_CHANGE_WORLD,
HOOK_ENTITY_CHANGING_WORLD,
HOOK_ENTITY_CHANGED_WORLD,
HOOK_EXECUTE_COMMAND,
HOOK_EXPLODED,
@ -203,7 +203,7 @@ public:
bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason);
bool CallHookEntityAddEffect (cEntity & a_Entity, int a_EffectType, int a_EffectDurationTicks, int a_EffectIntensity, double a_DistanceModifier);
bool CallHookEntityTeleport (cEntity & a_Entity, const Vector3d & a_OldPosition, const Vector3d & a_NewPosition);
bool CallHookEntityChangeWorld (cEntity & a_Entity, cWorld & a_World);
bool CallHookEntityChangingWorld (cEntity & a_Entity, cWorld & a_World);
bool CallHookEntityChangedWorld (cEntity & a_Entity, cWorld & a_World);
bool CallHookExecuteCommand (cPlayer * a_Player, const AStringVector & a_Split, const AString & a_EntireCommand, CommandResult & a_Result); // If a_Player == nullptr, it is a console cmd
bool CallHookExploded (cWorld & a_World, double a_ExplosionSize, bool a_CanCauseFire, double a_X, double a_Y, double a_Z, eExplosionSource a_Source, void * a_SourceData);

View File

@ -76,7 +76,7 @@ protected:
cItemGrid m_Contents;
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum)
virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override
{
UNUSED(a_SlotNum);
ASSERT(a_Grid == &m_Contents);

View File

@ -52,7 +52,7 @@ public:
virtual void UsedBy(cPlayer * a_Player) override;
virtual void SendTo(cClientHandle &) override {}
virtual void SetRedstonePower(bool a_Value)
virtual void SetRedstonePower(bool a_Value) override
{
if (a_Value)
{

View File

@ -50,10 +50,24 @@ void cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterfac
UNUSED(a_CursorY);
UNUSED(a_CursorZ);
if (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ) == E_BLOCK_WOODEN_DOOR)
switch (a_ChunkInterface.GetBlock(a_BlockX, a_BlockY, a_BlockZ))
{
ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
default:
{
ASSERT(!"Unhandled door block type");
}
case E_BLOCK_ACACIA_DOOR:
case E_BLOCK_BIRCH_DOOR:
case E_BLOCK_DARK_OAK_DOOR:
case E_BLOCK_JUNGLE_DOOR:
case E_BLOCK_SPRUCE_DOOR:
case E_BLOCK_IRON_DOOR:
case E_BLOCK_WOODEN_DOOR:
{
ChangeDoor(a_ChunkInterface, a_BlockX, a_BlockY, a_BlockZ);
a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle());
break;
}
}
}

View File

@ -103,6 +103,11 @@ public:
case E_BLOCK_STAINED_GLASS:
case E_BLOCK_FENCE:
case E_BLOCK_NETHER_BRICK_FENCE:
case E_BLOCK_SPRUCE_FENCE:
case E_BLOCK_BIRCH_FENCE:
case E_BLOCK_JUNGLE_FENCE:
case E_BLOCK_DARK_OAK_FENCE:
case E_BLOCK_ACACIA_FENCE:
case E_BLOCK_COBBLESTONE_WALL:
{
// Torches can only be placed on top of these blocks

View File

@ -177,7 +177,7 @@ public:
}
virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ)
virtual void OnUpdate(cChunkInterface & a_ChunkInterface, cWorldInterface & a_WorldInterface, cBlockPluginInterface & a_BlockPluginInterface, cChunk & a_Chunk, int a_RelX, int a_RelY, int a_RelZ) override
{
UNUSED(a_ChunkInterface);
UNUSED(a_WorldInterface);

View File

@ -1403,10 +1403,10 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
return false;
}
// Ask the plugins if the entity is allowed to change the world
if (cRoot::Get()->GetPluginManager()->CallHookEntityChangeWorld(*this, *a_World))
// Ask the plugins if the entity is allowed to changing the world
if (cRoot::Get()->GetPluginManager()->CallHookEntityChangingWorld(*this, *a_World))
{
// A Plugin doesn't allow the entity to change the world
// A Plugin doesn't allow the entity to changing the world
return false;
}

View File

@ -135,7 +135,7 @@ protected:
virtual void Destroyed() override;
// cItemGrid::cListener overrides:
virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum)
virtual void OnSlotChanged(cItemGrid * a_Grid, int a_SlotNum) override
{
UNUSED(a_SlotNum);
ASSERT(a_Grid == &m_Contents);

View File

@ -128,6 +128,13 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) :
m_IsFlying = true;
}
}
if (m_GameMode == gmSpectator) // If player is reconnecting to the server in spectator mode
{
m_CanFly = true;
m_IsFlying = true;
m_bVisible = false;
}
cRoot::Get()->GetServer()->PlayerCreated(this);
}
@ -1205,6 +1212,15 @@ void cPlayer::SetGameMode(eGameMode a_GameMode)
SetCanFly(false);
}
if (IsGameModeSpectator() && IsVisible())
{
SetVisible(false);
}
else if (!IsVisible())
{
SetVisible(true);
}
m_World->BroadcastPlayerListUpdateGameMode(*this);
}
@ -1606,9 +1622,10 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
return false;
}
if (cRoot::Get()->GetPluginManager()->CallHookEntityChangeWorld(*this, *a_World))
// Ask the plugins if the player is allowed to changing the world
if (cRoot::Get()->GetPluginManager()->CallHookEntityChangingWorld(*this, *a_World))
{
// A Plugin doesn't allow the player to change the world
// A Plugin doesn't allow the player to changing the world
return false;
}

View File

@ -483,11 +483,11 @@ public:
bool PlaceBlocks(const sSetBlockVector & a_Blocks);
// cEntity overrides:
virtual bool IsCrouched (void) const { return m_IsCrouched; }
virtual bool IsSprinting(void) const { return m_IsSprinting; }
virtual bool IsRclking (void) const { return IsEating() || IsChargingBow(); }
virtual bool IsCrouched (void) const override { return m_IsCrouched; }
virtual bool IsSprinting(void) const override { return m_IsSprinting; }
virtual bool IsRclking (void) const override { return IsEating() || IsChargingBow(); }
virtual void Detach(void);
virtual void Detach(void) override;
/** Called by cClientHandle when the client is being destroyed.
The player removes its m_ClientHandle ownership so that the ClientHandle gets deleted. */
@ -642,7 +642,7 @@ protected:
void ResolvePermissions(void);
void ResolveGroups(void);
virtual void Destroyed(void);
virtual void Destroyed(void) override;
/** Filters out damage for creative mode / friendly fire */
virtual bool DoTakeDamage(TakeDamageInfo & TDI) override;

View File

@ -1259,7 +1259,7 @@ bool cFinishGenPassiveMobs::TrySpawnAnimals(cChunkDesc & a_ChunkDesc, int a_RelX
}
if (
(BlockUnderFeet != E_BLOCK_GRASS) &&
((AnimalToSpawn == mtSheep) || (AnimalToSpawn == mtChicken) || (AnimalToSpawn == mtPig))
((AnimalToSpawn == mtRabbit) || (AnimalToSpawn == mtCow) || (AnimalToSpawn == mtSheep) || (AnimalToSpawn == mtChicken) || (AnimalToSpawn == mtPig))
)
{
return false;

View File

@ -69,7 +69,7 @@ public:
}
virtual void InitializeShapeGen(cIniFile & a_IniFile)
virtual void InitializeShapeGen(cIniFile & a_IniFile) override
{
m_FrequencyX = static_cast<NOISE_DATATYPE>(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyX", 40));
m_FrequencyY = static_cast<NOISE_DATATYPE>(a_IniFile.GetValueSetF("Generator", "TwoHeightsFrequencyY", 40));

View File

@ -259,13 +259,13 @@ protected:
// cPiecePool overrides:
virtual cPieces GetPiecesWithConnector(int a_ConnectorType)
virtual cPieces GetPiecesWithConnector(int a_ConnectorType) override
{
return m_Prefabs.GetPiecesWithConnector(a_ConnectorType);
}
virtual cPieces GetStartingPieces(void)
virtual cPieces GetStartingPieces(void) override
{
return m_Prefabs.GetStartingPieces();
}

View File

@ -89,7 +89,7 @@ public:
void Clear(void);
/** Returns true iff the specified value exists. */
bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const;
bool HasValue(const AString & a_KeyName, const AString & a_ValueName) const override;
/// Returns index of specified key, or noID if not found
int FindKey(const AString & keyname) const;
@ -101,7 +101,7 @@ public:
int GetNumKeys(void) const { return (int)keys.size(); }
/// Add a key name
int AddKeyName(const AString & keyname);
int AddKeyName(const AString & keyname) override;
// Returns key names by index.
AString GetKeyName(const int keyID) const;
@ -117,7 +117,7 @@ public:
// Gets value of [keyname] valuename =.
// Overloaded to return string, int, and double.
// Returns defValue if key / value not found.
AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const;
AString GetValue (const AString & keyname, const AString & valuename, const AString & defValue = "") const override;
AString GetValue (const int keyID, const int valueID, const AString & defValue = "") const;
double GetValueF(const AString & keyname, const AString & valuename, const double defValue = 0) const;
int GetValueI(const AString & keyname, const AString & valuename, const int defValue = 0) const;
@ -127,18 +127,18 @@ public:
}
// Gets the value; if not found, write the default to the INI file
AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "");
AString GetValueSet (const AString & keyname, const AString & valuename, const AString & defValue = "") override;
double GetValueSetF(const AString & keyname, const AString & valuename, const double defValue = 0.0);
int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0);
Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0);
bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false)
int GetValueSetI(const AString & keyname, const AString & valuename, const int defValue = 0) override;
Int64 GetValueSetI(const AString & keyname, const AString & valuename, const Int64 defValue = 0) override;
bool GetValueSetB(const AString & keyname, const AString & valuename, const bool defValue = false) override
{
return (GetValueSetI(keyname, valuename, defValue ? 1 : 0) != 0);
}
// Adds a new value to the specified key.
// If a value of the same name already exists, creates another one (non-standard INI file)
void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value);
void AddValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value) override;
void AddValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value);
void AddValueB(const AString & a_KeyName, const AString & a_ValueName, const bool a_Value)
{
@ -151,8 +151,8 @@ public:
// Returns true if value set, false otherwise.
// Overloaded to accept string, int, and double.
bool SetValue (const int keyID, const int valueID, const AString & value);
bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true);
bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true);
bool SetValue (const AString & a_KeyName, const AString & a_ValueName, const AString & a_Value, const bool a_CreateIfNotExists = true) override;
bool SetValueI(const AString & a_KeyName, const AString & a_ValueName, const int a_Value, const bool a_CreateIfNotExists = true) override;
bool SetValueI(const AString & a_Keyname, const AString & a_ValueName, const Int64 a_Value, const bool a_CreateIfNotExists = true);
bool SetValueB(const AString & a_KeyName, const AString & a_ValueName, const bool a_Value, const bool a_CreateIfNotExists = true)
{
@ -163,7 +163,7 @@ public:
// Deletes specified value.
// Returns true if value existed and deleted, false otherwise.
bool DeleteValueByID(const int keyID, const int valueID);
bool DeleteValue(const AString & keyname, const AString & valuename);
bool DeleteValue(const AString & keyname, const AString & valuename) override;
// Deletes specified key and all values contained within.
// Returns true if key existed and deleted, false otherwise.
@ -204,15 +204,15 @@ public:
bool AddKeyComment(const int keyID, const AString & comment);
/// Add a key comment
bool AddKeyComment(const AString & keyname, const AString & comment);
bool AddKeyComment(const AString & keyname, const AString & comment) override;
/// Return a key comment
AString GetKeyComment(const int keyID, const int commentID) const;
AString GetKeyComment(const AString & keyname, const int commentID) const;
AString GetKeyComment(const AString & keyname, const int commentID) const override;
// Delete a key comment.
bool DeleteKeyComment(const int keyID, const int commentID);
bool DeleteKeyComment(const AString & keyname, const int commentID);
bool DeleteKeyComment(const AString & keyname, const int commentID) override;
// Delete all comments for a key.
bool DeleteKeyComments(const int keyID);

View File

@ -25,7 +25,7 @@ public:
cWorld & a_World, cPlayer & a_Player, const cItem & a_EquippedItem,
int a_BlockX, int a_BlockY, int a_BlockZ, eBlockFace a_BlockFace,
int a_CursorX, int a_CursorY, int a_CursorZ
)
) override
{
// If the regular placement doesn't work, do no further processing:
if (!super::OnPlayerPlace(a_World, a_Player, a_EquippedItem, a_BlockX, a_BlockY, a_BlockZ, a_BlockFace, a_CursorX, a_CursorY, a_CursorZ))

View File

@ -76,9 +76,11 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
}
cTracer LineOfSight(GetWorld());
Vector3d AttackDirection(m_Target->GetPosition() - GetPosition());
Vector3d MyHeadPosition = GetPosition() + Vector3d(0, GetHeight(), 0);
Vector3d AttackDirection(m_Target->GetPosition() + Vector3d(0, m_Target->GetHeight(), 0) - MyHeadPosition);
if (ReachedFinalDestination() && !LineOfSight.Trace(GetPosition(), AttackDirection, (int)AttackDirection.Length()))
if (ReachedFinalDestination() && !LineOfSight.Trace(MyHeadPosition, AttackDirection, static_cast<int>(AttackDirection.Length())))
{
// Attack if reached destination, target isn't null, and have a clear line of sight to target (so won't attack through walls)
Attack(a_Dt);

View File

@ -26,7 +26,7 @@ public:
bool IsEating (void) const {return m_bIsEating; }
bool IsRearing (void) const {return m_bIsRearing; }
bool IsMthOpen (void) const {return m_bIsMouthOpen; }
bool IsTame (void) const {return m_bIsTame; }
bool IsTame (void) const override {return m_bIsTame; }
int GetHorseType (void) const {return m_Type; }
int GetHorseColor (void) const {return m_Color; }
int GetHorseStyle (void) const {return m_Style; }

View File

@ -177,13 +177,14 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk)
case ePathFinderStatus::NEARBY_FOUND:
{
m_NoPathToTarget = true;
m_Path->AcceptNearbyPath();
m_PathFinderDestination = m_Path->AcceptNearbyPath();
break;
}
case ePathFinderStatus::PATH_NOT_FOUND:
{
StopMovingToPosition(); // Give up pathfinding to that destination.
ResetPathFinding(); // Try to calculate a path again.
// Note that the next time may succeed, e.g. if a player breaks a barrier.
break;
}
case ePathFinderStatus::CALCULATING:

View File

@ -6,20 +6,14 @@
#include "Path.h"
#include "../Chunk.h"
#define DISTANCE_MANHATTAN 0 // 1: More speed, a bit less accuracy 0: Max accuracy, less speed.
#define HEURISTICS_ONLY 0 // 1: Much more speed, much less accurate.
#define CALCULATIONS_PER_STEP 10 // Higher means more CPU load but faster path calculations.
// The only version which guarantees the shortest path is 0, 0.
enum class eCellStatus {OPENLIST, CLOSEDLIST, NOLIST};
struct cPathCell
{
Vector3i m_Location; // Location of the cell in the world.
int m_F, m_G, m_H; // F, G, H as defined in regular A*.
eCellStatus m_Status; // Which list is the cell in? Either non, open, or closed.
cPathCell * m_Parent; // Cell's parent, as defined in regular A*.
bool m_IsSolid; // Is the cell an air or a solid? Partial solids are currently considered solids.
};
@ -185,11 +179,18 @@ bool cPath::Step_Internal()
// Calculation not finished yet.
// Check if we have a new NearestPoint.
if (CurrentCell->m_H < m_NearestPointToTarget->m_H)
if ((m_Destination - CurrentCell->m_Location).Length() < 5)
{
if (m_Rand.NextInt(4) == 0)
{
m_NearestPointToTarget = CurrentCell;
}
}
else if (CurrentCell->m_H < m_NearestPointToTarget->m_H)
{
m_NearestPointToTarget = CurrentCell;
}
// process a currentCell by inspecting all neighbors.
// Check North, South, East, West on all 3 different heights.
@ -388,23 +389,20 @@ void cPath::ProcessCell(cPathCell * a_Cell, cPathCell * a_Caller, int a_GDelta)
cPathCell * cPath::GetCell(const Vector3i & a_Location)
{
// Create the cell in the hash table if it's not already there.
cPathCell * Cell;
if (m_Map.count(a_Location) == 0) // Case 1: Cell is not on any list. We've never checked this cell before.
{
Cell = new cPathCell();
Cell->m_Location = a_Location;
m_Map[a_Location] = UniquePtr<cPathCell>(Cell);
Cell->m_IsSolid = IsSolid(a_Location);
Cell->m_Status = eCellStatus::NOLIST;
m_Map[a_Location].m_Location = a_Location;
m_Map[a_Location].m_IsSolid = IsSolid(a_Location);
m_Map[a_Location].m_Status = eCellStatus::NOLIST;
#ifdef COMPILING_PATHFIND_DEBUGGER
#ifdef COMPILING_PATHFIND_DEBUGGER_MARK_UNCHECKED
si::setBlock(a_Location.x, a_Location.y, a_Location.z, debug_unchecked, Cell->m_IsSolid ? NORMAL : MINI);
#endif
#endif
return Cell;
return &m_Map[a_Location];
}
else
{
return m_Map[a_Location].get();
return &m_Map[a_Location];
}
}

View File

@ -1,16 +1,13 @@
#pragma once
/* Wanna use the pathfinder? Put this in your header file:
// Fwd: cPath
/*
// Needed Fwds: cPath
enum class ePathFinderStatus;
class cPath;
Put this in your .cpp:
#include "...Path.h"
*/
#include "../FastRandom.h"
#ifdef COMPILING_PATHFIND_DEBUGGER
/* Note: the COMPILING_PATHFIND_DEBUGGER flag is used by Native / WiseOldMan95 to debug
this class outside of MCServer. This preprocessor flag is never set when compiling MCServer. */
@ -24,13 +21,30 @@ class cChunk;
/* Various little structs and classes */
enum class ePathFinderStatus {CALCULATING, PATH_FOUND, PATH_NOT_FOUND, NEARBY_FOUND};
struct cPathCell; // Defined inside Path.cpp
enum class eCellStatus {OPENLIST, CLOSEDLIST, NOLIST};
struct cPathCell
{
Vector3i m_Location; // Location of the cell in the world.
int m_F, m_G, m_H; // F, G, H as defined in regular A*.
eCellStatus m_Status; // Which list is the cell in? Either non, open, or closed.
cPathCell * m_Parent; // Cell's parent, as defined in regular A*.
bool m_IsSolid; // Is the cell an air or a solid? Partial solids are currently considered solids.
};
class compareHeuristics
{
public:
bool operator()(cPathCell * & a_V1, cPathCell * & a_V2);
};
class cPath
{
public:
@ -144,11 +158,12 @@ private:
/* Pathfinding fields */
std::priority_queue<cPathCell *, std::vector<cPathCell *>, compareHeuristics> m_OpenList;
std::unordered_map<Vector3i, UniquePtr<cPathCell>, VectorHasher> m_Map;
std::unordered_map<Vector3i, cPathCell, VectorHasher> m_Map;
Vector3i m_Destination;
Vector3i m_Source;
int m_StepsLeft;
cPathCell * m_NearestPointToTarget;
cFastRandom m_Rand;
/* Control fields */
ePathFinderStatus m_Status;

View File

@ -25,8 +25,8 @@ public:
virtual void Attack(std::chrono::milliseconds a_Dt) override;
// Get functions
bool IsSitting (void) const { return m_IsSitting; }
bool IsTame (void) const { return m_IsTame; }
bool IsSitting (void) const override { return m_IsSitting; }
bool IsTame (void) const override { return m_IsTame; }
bool IsBegging (void) const { return m_IsBegging; }
bool IsAngry (void) const { return m_IsAngry; }
AString GetOwnerName (void) const { return m_OwnerName; }

View File

@ -260,7 +260,7 @@ bool cOverridesSettingsRepository::DeleteValue(const AString & a_KeyName, const
}
else
{
return m_Overrides->DeleteValue(a_KeyName, a_ValueName);
return m_Main->DeleteValue(a_KeyName, a_ValueName);
}
}

View File

@ -54,19 +54,19 @@ class cBlockingSslClientSocketLinkCallbacks:
}
virtual void OnReceivedData(const char * a_Data, size_t a_Length)
virtual void OnReceivedData(const char * a_Data, size_t a_Length) override
{
m_Socket.OnReceivedData(a_Data, a_Length);
}
virtual void OnRemoteClosed(void)
virtual void OnRemoteClosed(void) override
{
m_Socket.OnDisconnected();
}
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg)
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override
{
m_Socket.OnDisconnected();
}

View File

@ -21,6 +21,11 @@ class cBlockingSslClientSocket :
{
public:
cBlockingSslClientSocket(void);
~cBlockingSslClientSocket(void)
{
Disconnect();
}
/** Connects to the specified server and performs SSL handshake.
Returns true if successful, false on failure. Sets internal error text on failure. */

View File

@ -152,7 +152,7 @@ void cSslContext::SetCACerts(const cX509CertPtr & a_CACert, const AString & a_Ex
m_CACerts = a_CACert;
// Set the trusted CA root cert store:
ssl_set_authmode(&m_Ssl, SSL_VERIFY_OPTIONAL);
ssl_set_authmode(&m_Ssl, SSL_VERIFY_REQUIRED);
ssl_set_ca_chain(&m_Ssl, m_CACerts->GetInternal(), nullptr, m_ExpectedPeerName.empty() ? nullptr : m_ExpectedPeerName.c_str());
}

View File

@ -19,6 +19,10 @@
#define DEFAULT_AUTH_SERVER "sessionserver.mojang.com"
#define DEFAULT_AUTH_ADDRESS "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%"
cAuthenticator::cAuthenticator(void) :
super("cAuthenticator"),
m_Server(DEFAULT_AUTH_SERVER),
@ -267,3 +271,7 @@ bool cAuthenticator::GetPlayerProperties(const AString & a_UUID, Json::Value & a
return true;
}
*/

View File

@ -38,12 +38,36 @@ const int MAX_PER_QUERY = 100;
/** This is the data of the root certs for Starfield Technologies, the CA that signed sessionserver.mojang.com's cert:
Downloaded from http://certs.starfieldtech.com/repository/ */
static const AString & StarfieldCACert(void)
/** Returns the CA certificates that should be trusted for Mojang-related connections. */
static const AString & GetCACerts(void)
{
static const AString Cert(
// G2 cert
// Equifax root CA cert
// Currently used for signing *.mojang.com's cert
// Exported from Mozilla Firefox's built-in CA repository
"-----BEGIN CERTIFICATE-----\n"
"MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV\n"
"UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy\n"
"dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1\n"
"MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx\n"
"dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B\n"
"AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f\n"
"BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A\n"
"cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC\n"
"AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ\n"
"MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm\n"
"aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw\n"
"ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj\n"
"IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF\n"
"MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA\n"
"A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y\n"
"7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh\n"
"1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4\n"
"-----END CERTIFICATE-----\n\n"
// Starfield G2 cert
// This is the data of the root certs for Starfield Technologies, the CA that used to sign sessionserver.mojang.com's cert
// Downloaded from http://certs.starfieldtech.com/repository/
"-----BEGIN CERTIFICATE-----\n"
"MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n"
"EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n"
@ -67,7 +91,8 @@ static const AString & StarfieldCACert(void)
"pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\n"
"mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n"
"-----END CERTIFICATE-----\n\n"
// Original (G1) cert:
// Starfield original (G1) cert:
"-----BEGIN CERTIFICATE-----\n"
"MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n"
"MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n"
@ -390,7 +415,7 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
{
// Connect the socket:
cBlockingSslClientSocket Socket;
Socket.SetTrustedRootCertsFromString(StarfieldCACert(), a_ServerName);
Socket.SetTrustedRootCertsFromString(GetCACerts(), a_ServerName);
if (!Socket.Connect(a_ServerName, 443))
{
LOGWARNING("%s: Can't connect to %s: %s", __FUNCTION__, a_ServerName.c_str(), Socket.GetLastErrorText().c_str());
@ -434,7 +459,6 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
a_Response.append((const char *)buf, (size_t)ret);
}
Socket.Disconnect();
return true;
}

View File

@ -61,7 +61,7 @@ protected:
// cTCPLink::cCallbacks overrides:
virtual void OnLinkCreated(cTCPLinkPtr a_Link);
virtual void OnLinkCreated(cTCPLinkPtr a_Link) override;
virtual void OnReceivedData(const char * a_Data, size_t a_Length) override;
virtual void OnRemoteClosed(void) override;
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override;

View File

@ -72,7 +72,7 @@ class cServerListenCallbacks:
virtual void OnAccepted(cTCPLink & a_Link) override {}
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg)
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override
{
LOGWARNING("Cannot listen on port %d: %d (%s).", m_Port, a_ErrorCode, a_ErrorMsg.c_str());
}

View File

@ -239,7 +239,7 @@ public:
// cSlotAreaTemporary overrides:
virtual void Clicked (cPlayer & a_Player, int a_SlotNum, eClickAction a_ClickAction, const cItem & a_ClickedItem) override;
virtual void DblClicked (cPlayer & a_Player, int a_SlotNum);
virtual void DblClicked (cPlayer & a_Player, int a_SlotNum) override;
virtual void OnPlayerRemoved(cPlayer & a_Player) override;
virtual void SetSlot (int a_SlotNum, cPlayer & a_Player, const cItem & a_Item) override;

View File

@ -150,7 +150,7 @@ protected:
int m_LastReportChunkCount;
// cChunkCoordCallback override:
virtual void Call(int a_ChunkX, int a_ChunkZ)
virtual void Call(int a_ChunkX, int a_ChunkZ) override
{
// Check if this was the last chunk:
m_NumPrepared += 1;
@ -362,6 +362,7 @@ cWorld::~cWorld()
void cWorld::CastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ)
{
BroadcastThunderbolt(a_BlockX, a_BlockY, a_BlockZ);
BroadcastSoundEffect("ambient.weather.thunder", a_BlockX, a_BlockY, a_BlockZ, 50, 1);
}

View File

@ -203,10 +203,10 @@ public:
bool VillagersShouldHarvestCrops(void) const { return m_VillagersShouldHarvestCrops; }
virtual eDimension GetDimension(void) const { return m_Dimension; }
virtual eDimension GetDimension(void) const override { return m_Dimension; }
/** Returns the world height at the specified coords; waits for the chunk to get loaded / generated */
virtual int GetHeight(int a_BlockX, int a_BlockZ);
virtual int GetHeight(int a_BlockX, int a_BlockZ) override;
// tolua_end
@ -253,7 +253,7 @@ public:
void BroadcastScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode);
void BroadcastScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode);
void BroadcastDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display);
void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr); // tolua_export
void BroadcastSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch, const cClientHandle * a_Exclude = nullptr) override; // tolua_export
void BroadcastSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data, const cClientHandle * a_Exclude = nullptr); // tolua_export
void BroadcastSpawnEntity (cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
void BroadcastTeleportEntity (const cEntity & a_Entity, const cClientHandle * a_Exclude = nullptr);
@ -788,7 +788,7 @@ public:
bool IsWeatherWet(void) const { return !IsWeatherSunny(); }
/** Returns true if it is raining, stormy or snowing at the specified location. This takes into account biomes. */
virtual bool IsWeatherWetAt(int a_BlockX, int a_BlockZ)
virtual bool IsWeatherWetAt(int a_BlockX, int a_BlockZ) override
{
return (IsWeatherWet() && !IsBiomeNoDownfall(GetBiomeAt(a_BlockX, a_BlockZ)));
}

View File

@ -374,6 +374,14 @@ std::unique_ptr<cMemorySettingsRepository> parseArguments(int argc, char **argv)
TCLAP::MultiArg<int> portsArg("p", "port", "The port number the server should listen to", false, "port", cmd);
TCLAP::SwitchArg commLogArg("", "log-comm", "Log server client communications to file", cmd);
TCLAP::SwitchArg commLogInArg("", "log-comm-in", "Log inbound server client communications to file", cmd);
TCLAP::SwitchArg commLogOutArg("", "log-comm-out", "Log outbound server client communications to file", cmd);
TCLAP::SwitchArg noBufArg("", "no-output-buffering", "Disable output buffering", cmd);
cmd.parse(argc, argv);
auto repo = cpp14::make_unique<cMemorySettingsRepository>();
@ -396,6 +404,22 @@ std::unique_ptr<cMemorySettingsRepository> parseArguments(int argc, char **argv)
}
}
if (commLogArg.getValue())
{
g_ShouldLogCommIn = true;
g_ShouldLogCommOut = true;
}
else
{
g_ShouldLogCommIn = commLogInArg.getValue();
g_ShouldLogCommOut = commLogOutArg.getValue();
}
if (noBufArg.getValue())
{
setvbuf(stdout, nullptr, _IONBF, 0);
}
repo->SetReadOnly();
return repo;
@ -473,35 +497,7 @@ int main(int argc, char **argv)
for (int i = 0; i < argc; i++)
{
AString Arg(argv[i]);
if (
(NoCaseCompare(Arg, "/commlog") == 0) ||
(NoCaseCompare(Arg, "/logcomm") == 0)
)
{
g_ShouldLogCommIn = true;
g_ShouldLogCommOut = true;
}
else if (
(NoCaseCompare(Arg, "/commlogin") == 0) ||
(NoCaseCompare(Arg, "/comminlog") == 0) ||
(NoCaseCompare(Arg, "/logcommin") == 0)
)
{
g_ShouldLogCommIn = true;
}
else if (
(NoCaseCompare(Arg, "/commlogout") == 0) ||
(NoCaseCompare(Arg, "/commoutlog") == 0) ||
(NoCaseCompare(Arg, "/logcommout") == 0)
)
{
g_ShouldLogCommOut = true;
}
else if (NoCaseCompare(Arg, "nooutbuf") == 0)
{
setvbuf(stdout, nullptr, _IONBF, 0);
}
else if (NoCaseCompare(Arg, "/service") == 0)
if (NoCaseCompare(Arg, "/service") == 0)
{
cRoot::m_RunAsService = true;
}