1
0

Merge branch 'master' into PreventNewWarnings

This commit is contained in:
tycho 2015-05-23 11:31:03 +01:00
commit 1577a080ee
21 changed files with 143 additions and 61 deletions

View File

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

View File

@ -7,7 +7,7 @@ return
Desc = [[ Desc = [[
This hook is called after the server has moved the {{cEntity|entity}} to the given world. This is an information-only 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> 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. entity is moved to the new world.
]], ]],
Params = Params =

View File

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

View File

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

View File

@ -56,7 +56,7 @@ public:
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) = 0; 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 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 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 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 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; 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); cCSLock Lock(m_CriticalSection);
if (!m_LuaState.IsValid()) if (!m_LuaState.IsValid())
@ -542,7 +542,7 @@ bool cPluginLua::OnEntityChangeWorld(cEntity & a_Entity, cWorld & a_World)
return false; return false;
} }
bool res = 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) for (cLuaRefs::iterator itr = Refs.begin(), end = Refs.end(); itr != end; ++itr)
{ {
m_LuaState.Call((int)(**itr), &a_Entity, &a_World, cLuaState::Return, res); m_LuaState.Call((int)(**itr), &a_Entity, &a_World, cLuaState::Return, res);
@ -1922,7 +1922,7 @@ const char * cPluginLua::GetHookFnName(int a_HookType)
case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect"; case cPluginManager::HOOK_DISCONNECT: return "OnDisconnect";
case cPluginManager::HOOK_PLAYER_ANIMATION: return "OnPlayerAnimation"; case cPluginManager::HOOK_PLAYER_ANIMATION: return "OnPlayerAnimation";
case cPluginManager::HOOK_ENTITY_ADD_EFFECT: return "OnEntityAddEffect"; 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_CHANGED_WORLD: return "OnEntityChangedWorld";
case cPluginManager::HOOK_ENTITY_TELEPORT: return "OnEntityTeleport"; case cPluginManager::HOOK_ENTITY_TELEPORT: return "OnEntityTeleport";
case cPluginManager::HOOK_EXECUTE_COMMAND: return "OnExecuteCommand"; 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 OnCraftingNoRecipe (cPlayer & a_Player, cCraftingGrid & a_Grid, cCraftingRecipe & a_Recipe) override;
virtual bool OnDisconnect (cClientHandle & a_Client, const AString & a_Reason) 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 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 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 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; 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;

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; 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)->OnEntityChangeWorld(a_Entity, a_World)) if ((*itr)->OnEntityChangingWorld(a_Entity, a_World))
{ {
return true; return true;
} }

View File

@ -86,7 +86,7 @@ public:
HOOK_DISCONNECT, HOOK_DISCONNECT,
HOOK_PLAYER_ANIMATION, HOOK_PLAYER_ANIMATION,
HOOK_ENTITY_ADD_EFFECT, HOOK_ENTITY_ADD_EFFECT,
HOOK_ENTITY_CHANGE_WORLD, HOOK_ENTITY_CHANGING_WORLD,
HOOK_ENTITY_CHANGED_WORLD, HOOK_ENTITY_CHANGED_WORLD,
HOOK_EXECUTE_COMMAND, HOOK_EXECUTE_COMMAND,
HOOK_EXPLODED, HOOK_EXPLODED,
@ -203,7 +203,7 @@ public:
bool CallHookDisconnect (cClientHandle & a_Client, const AString & a_Reason); 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 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 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 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 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); 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

@ -50,10 +50,24 @@ void cBlockDoorHandler::OnUse(cChunkInterface & a_ChunkInterface, cWorldInterfac
UNUSED(a_CursorY); UNUSED(a_CursorY);
UNUSED(a_CursorZ); 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); default:
a_Player->GetWorld()->BroadcastSoundParticleEffect(1003, a_BlockX, a_BlockY, a_BlockZ, 0, a_Player->GetClientHandle()); {
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_STAINED_GLASS:
case E_BLOCK_FENCE: case E_BLOCK_FENCE:
case E_BLOCK_NETHER_BRICK_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: case E_BLOCK_COBBLESTONE_WALL:
{ {
// Torches can only be placed on top of these blocks // Torches can only be placed on top of these blocks

View File

@ -1403,10 +1403,10 @@ bool cEntity::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
return false; return false;
} }
// Ask the plugins if the entity is allowed to change the world // Ask the plugins if the entity is allowed to changing the world
if (cRoot::Get()->GetPluginManager()->CallHookEntityChangeWorld(*this, *a_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; return false;
} }

View File

@ -129,6 +129,13 @@ cPlayer::cPlayer(cClientHandlePtr a_Client, const AString & a_PlayerName) :
} }
} }
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); cRoot::Get()->GetServer()->PlayerCreated(this);
} }
@ -1606,9 +1613,10 @@ bool cPlayer::DoMoveToWorld(cWorld * a_World, bool a_ShouldSendRespawn)
return false; 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; return false;
} }

View File

@ -76,9 +76,11 @@ void cAggressiveMonster::Tick(std::chrono::milliseconds a_Dt, cChunk & a_Chunk)
} }
cTracer LineOfSight(GetWorld()); 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 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); Attack(a_Dt);

View File

@ -177,13 +177,14 @@ bool cMonster::TickPathFinding(cChunk & a_Chunk)
case ePathFinderStatus::NEARBY_FOUND: case ePathFinderStatus::NEARBY_FOUND:
{ {
m_NoPathToTarget = true; m_NoPathToTarget = true;
m_Path->AcceptNearbyPath(); m_PathFinderDestination = m_Path->AcceptNearbyPath();
break; break;
} }
case ePathFinderStatus::PATH_NOT_FOUND: 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; break;
} }
case ePathFinderStatus::CALCULATING: case ePathFinderStatus::CALCULATING:

View File

@ -6,20 +6,14 @@
#include "Path.h" #include "Path.h"
#include "../Chunk.h" #include "../Chunk.h"
#define DISTANCE_MANHATTAN 0 // 1: More speed, a bit less accuracy 0: Max accuracy, less speed. #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 HEURISTICS_ONLY 0 // 1: Much more speed, much less accurate.
#define CALCULATIONS_PER_STEP 10 // Higher means more CPU load but faster path calculations. #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. // 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. // Calculation not finished yet.
// Check if we have a new NearestPoint. // 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; m_NearestPointToTarget = CurrentCell;
} }
// process a currentCell by inspecting all neighbors. // process a currentCell by inspecting all neighbors.
// Check North, South, East, West on all 3 different heights. // 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) cPathCell * cPath::GetCell(const Vector3i & a_Location)
{ {
// Create the cell in the hash table if it's not already there. // 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. 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(); m_Map[a_Location].m_Location = a_Location;
Cell->m_Location = a_Location; m_Map[a_Location].m_IsSolid = IsSolid(a_Location);
m_Map[a_Location] = UniquePtr<cPathCell>(Cell); m_Map[a_Location].m_Status = eCellStatus::NOLIST;
Cell->m_IsSolid = IsSolid(a_Location);
Cell->m_Status = eCellStatus::NOLIST;
#ifdef COMPILING_PATHFIND_DEBUGGER #ifdef COMPILING_PATHFIND_DEBUGGER
#ifdef COMPILING_PATHFIND_DEBUGGER_MARK_UNCHECKED #ifdef COMPILING_PATHFIND_DEBUGGER_MARK_UNCHECKED
si::setBlock(a_Location.x, a_Location.y, a_Location.z, debug_unchecked, Cell->m_IsSolid ? NORMAL : MINI); si::setBlock(a_Location.x, a_Location.y, a_Location.z, debug_unchecked, Cell->m_IsSolid ? NORMAL : MINI);
#endif #endif
#endif #endif
return Cell; return &m_Map[a_Location];
} }
else else
{ {
return m_Map[a_Location].get(); return &m_Map[a_Location];
} }
} }

View File

@ -1,16 +1,13 @@
#pragma once #pragma once
/* Wanna use the pathfinder? Put this in your header file: /*
// Needed Fwds: cPath
// Fwd: cPath
enum class ePathFinderStatus; enum class ePathFinderStatus;
class cPath; class cPath;
Put this in your .cpp:
#include "...Path.h"
*/ */
#include "../FastRandom.h"
#ifdef COMPILING_PATHFIND_DEBUGGER #ifdef COMPILING_PATHFIND_DEBUGGER
/* Note: the COMPILING_PATHFIND_DEBUGGER flag is used by Native / WiseOldMan95 to debug /* 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. */ 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 */ /* Various little structs and classes */
enum class ePathFinderStatus {CALCULATING, PATH_FOUND, PATH_NOT_FOUND, NEARBY_FOUND}; 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 class compareHeuristics
{ {
public: public:
bool operator()(cPathCell * & a_V1, cPathCell * & a_V2); bool operator()(cPathCell * & a_V1, cPathCell * & a_V2);
}; };
class cPath class cPath
{ {
public: public:
@ -144,11 +158,12 @@ private:
/* Pathfinding fields */ /* Pathfinding fields */
std::priority_queue<cPathCell *, std::vector<cPathCell *>, compareHeuristics> m_OpenList; 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_Destination;
Vector3i m_Source; Vector3i m_Source;
int m_StepsLeft; int m_StepsLeft;
cPathCell * m_NearestPointToTarget; cPathCell * m_NearestPointToTarget;
cFastRandom m_Rand;
/* Control fields */ /* Control fields */
ePathFinderStatus m_Status; ePathFinderStatus m_Status;

View File

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

View File

@ -19,6 +19,10 @@
#define DEFAULT_AUTH_SERVER "sessionserver.mojang.com" #define DEFAULT_AUTH_SERVER "sessionserver.mojang.com"
#define DEFAULT_AUTH_ADDRESS "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%" #define DEFAULT_AUTH_ADDRESS "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%"
cAuthenticator::cAuthenticator(void) : cAuthenticator::cAuthenticator(void) :
super("cAuthenticator"), super("cAuthenticator"),
m_Server(DEFAULT_AUTH_SERVER), m_Server(DEFAULT_AUTH_SERVER),
@ -267,3 +271,7 @@ bool cAuthenticator::GetPlayerProperties(const AString & a_UUID, Json::Value & a
return true; 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: /** Returns the CA certificates that should be trusted for Mojang-related connections. */
Downloaded from http://certs.starfieldtech.com/repository/ */ static const AString & GetCACerts(void)
static const AString & StarfieldCACert(void)
{ {
static const AString Cert( 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" "-----BEGIN CERTIFICATE-----\n"
"MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n" "MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n"
"EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n" "EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n"
@ -67,7 +91,8 @@ static const AString & StarfieldCACert(void)
"pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\n" "pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\n"
"mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n" "mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n"
"-----END CERTIFICATE-----\n\n" "-----END CERTIFICATE-----\n\n"
// Original (G1) cert:
// Starfield original (G1) cert:
"-----BEGIN CERTIFICATE-----\n" "-----BEGIN CERTIFICATE-----\n"
"MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n" "MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n"
"MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n" "MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n"
@ -390,7 +415,7 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
{ {
// Connect the socket: // Connect the socket:
cBlockingSslClientSocket Socket; cBlockingSslClientSocket Socket;
Socket.SetTrustedRootCertsFromString(StarfieldCACert(), a_ServerName); Socket.SetTrustedRootCertsFromString(GetCACerts(), a_ServerName);
if (!Socket.Connect(a_ServerName, 443)) if (!Socket.Connect(a_ServerName, 443))
{ {
LOGWARNING("%s: Can't connect to %s: %s", __FUNCTION__, a_ServerName.c_str(), Socket.GetLastErrorText().c_str()); 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); a_Response.append((const char *)buf, (size_t)ret);
} }
Socket.Disconnect();
return true; return true;
} }

View File

@ -362,6 +362,7 @@ cWorld::~cWorld()
void cWorld::CastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) void cWorld::CastThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ)
{ {
BroadcastThunderbolt(a_BlockX, a_BlockY, a_BlockZ); BroadcastThunderbolt(a_BlockX, a_BlockY, a_BlockZ);
BroadcastSoundEffect("ambient.weather.thunder", a_BlockX, a_BlockY, a_BlockZ, 50, 1);
} }