diff --git a/CONTRIBUTORS b/CONTRIBUTORS index 21654428f..9cc7f19fc 100644 --- a/CONTRIBUTORS +++ b/CONTRIBUTORS @@ -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 diff --git a/MCServer/Plugins/APIDump/Hooks/OnEntityChangedWorld.lua b/MCServer/Plugins/APIDump/Hooks/OnEntityChangedWorld.lua index 00645c152..6675fdbe0 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnEntityChangedWorld.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnEntityChangedWorld.lua @@ -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.

- 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 = diff --git a/MCServer/Plugins/APIDump/Hooks/OnEntityChangeWorld.lua b/MCServer/Plugins/APIDump/Hooks/OnEntityChangingWorld.lua similarity index 86% rename from MCServer/Plugins/APIDump/Hooks/OnEntityChangeWorld.lua rename to MCServer/Plugins/APIDump/Hooks/OnEntityChangingWorld.lua index 25072ca5c..521f829c7 100644 --- a/MCServer/Plugins/APIDump/Hooks/OnEntityChangeWorld.lua +++ b/MCServer/Plugins/APIDump/Hooks/OnEntityChangingWorld.lua @@ -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.

@@ -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 } diff --git a/src/Bindings/ManualBindings_World.cpp b/src/Bindings/ManualBindings_World.cpp index cda1518d2..8d0288556 100644 --- a/src/Bindings/ManualBindings_World.cpp +++ b/src/Bindings/ManualBindings_World.cpp @@ -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); diff --git a/src/Bindings/Plugin.h b/src/Bindings/Plugin.h index b4bbfd802..1330bca0d 100644 --- a/src/Bindings/Plugin.h +++ b/src/Bindings/Plugin.h @@ -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; diff --git a/src/Bindings/PluginLua.cpp b/src/Bindings/PluginLua.cpp index 83466ab84..d3ffcd0f4 100644 --- a/src/Bindings/PluginLua.cpp +++ b/src/Bindings/PluginLua.cpp @@ -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); @@ -1922,7 +1922,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"; diff --git a/src/Bindings/PluginLua.h b/src/Bindings/PluginLua.h index 533dc0331..29f0319ab 100644 --- a/src/Bindings/PluginLua.h +++ b/src/Bindings/PluginLua.h @@ -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; diff --git a/src/Bindings/PluginManager.cpp b/src/Bindings/PluginManager.cpp index 6fb6ef4fa..4dc3e20d3 100644 --- a/src/Bindings/PluginManager.cpp +++ b/src/Bindings/PluginManager.cpp @@ -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; } diff --git a/src/Bindings/PluginManager.h b/src/Bindings/PluginManager.h index e528c049f..6bcef87bf 100644 --- a/src/Bindings/PluginManager.h +++ b/src/Bindings/PluginManager.h @@ -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); diff --git a/src/Blocks/BlockDoor.cpp b/src/Blocks/BlockDoor.cpp index d13c8d657..a4e375cf0 100644 --- a/src/Blocks/BlockDoor.cpp +++ b/src/Blocks/BlockDoor.cpp @@ -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; + } } } diff --git a/src/Blocks/BlockTorch.h b/src/Blocks/BlockTorch.h index aaf50d23d..36d2fec67 100644 --- a/src/Blocks/BlockTorch.h +++ b/src/Blocks/BlockTorch.h @@ -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 diff --git a/src/Entities/Entity.cpp b/src/Entities/Entity.cpp index 941c4196c..91eb0744a 100644 --- a/src/Entities/Entity.cpp +++ b/src/Entities/Entity.cpp @@ -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; } diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index 01ad26297..4ed5ef8a3 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -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); } @@ -1606,9 +1613,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; } diff --git a/src/Mobs/AggressiveMonster.cpp b/src/Mobs/AggressiveMonster.cpp index 055ff47d2..648599999 100644 --- a/src/Mobs/AggressiveMonster.cpp +++ b/src/Mobs/AggressiveMonster.cpp @@ -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(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); diff --git a/src/Mobs/Monster.cpp b/src/Mobs/Monster.cpp index 619e20855..153baf7ea 100644 --- a/src/Mobs/Monster.cpp +++ b/src/Mobs/Monster.cpp @@ -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: diff --git a/src/Mobs/Path.cpp b/src/Mobs/Path.cpp index ba8046a2b..eba29be7e 100644 --- a/src/Mobs/Path.cpp +++ b/src/Mobs/Path.cpp @@ -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(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]; } } diff --git a/src/Mobs/Path.h b/src/Mobs/Path.h index 31002fe7f..71b42edc0 100644 --- a/src/Mobs/Path.h +++ b/src/Mobs/Path.h @@ -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, compareHeuristics> m_OpenList; - std::unordered_map, VectorHasher> m_Map; + std::unordered_map m_Map; Vector3i m_Destination; Vector3i m_Source; int m_StepsLeft; cPathCell * m_NearestPointToTarget; + cFastRandom m_Rand; /* Control fields */ ePathFinderStatus m_Status; diff --git a/src/PolarSSL++/BlockingSslClientSocket.h b/src/PolarSSL++/BlockingSslClientSocket.h index 319e82bf2..462ee95a7 100644 --- a/src/PolarSSL++/BlockingSslClientSocket.h +++ b/src/PolarSSL++/BlockingSslClientSocket.h @@ -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. */ diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp index 294b6e9be..bfbe5028d 100644 --- a/src/Protocol/Authenticator.cpp +++ b/src/Protocol/Authenticator.cpp @@ -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; } */ + + + + diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp index 51b8e90e7..110590359 100644 --- a/src/Protocol/MojangAPI.cpp +++ b/src/Protocol/MojangAPI.cpp @@ -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; } diff --git a/src/World.cpp b/src/World.cpp index 5f9eb2569..7bf2b2a6e 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -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); }