diff --git a/Client/core/CVersionUpdater.Util.hpp b/Client/core/CVersionUpdater.Util.hpp index d6f7677c9a..0380f9bda4 100644 --- a/Client/core/CVersionUpdater.Util.hpp +++ b/Client/core/CVersionUpdater.Util.hpp @@ -12,8 +12,8 @@ class CVersionUpdater; // Update master info -#define UPDATER_MASTER_URL1 "http://updatesa.mtasa.com/sa/master/?v=%VERSION%&id=%ID%" -#define UPDATER_MASTER_URL2 "http://updatesa.multitheftauto.com/sa/master/?v=%VERSION%&id=%ID%" +#define UPDATER_MASTER_URL1 "https://updatesa.mtasa.com/sa/master/?v=%VERSION%&id=%ID%" +#define UPDATER_MASTER_URL2 "https://updatesa.multitheftauto.com/sa/master/?v=%VERSION%&id=%ID%" /* diff --git a/Client/game_sa/CAnimManagerSA.cpp b/Client/game_sa/CAnimManagerSA.cpp index d540fa16af..f792f54e14 100644 --- a/Client/game_sa/CAnimManagerSA.cpp +++ b/Client/game_sa/CAnimManagerSA.cpp @@ -32,18 +32,10 @@ static const char* const kGateWayAnimationName = "run_wuzi"; CAnimManagerSA::CAnimManagerSA() { - MemSetFast(m_pAnimAssocGroups, 0, sizeof(m_pAnimAssocGroups)); - MemSetFast(m_pAnimBlocks, 0, sizeof(m_pAnimBlocks)); } CAnimManagerSA::~CAnimManagerSA() { - for (unsigned int i = 0; i < MAX_ANIM_GROUPS; i++) - if (m_pAnimAssocGroups[i]) - delete m_pAnimAssocGroups[i]; - for (unsigned int i = 0; i < MAX_ANIM_BLOCKS; i++) - if (m_pAnimBlocks[i]) - delete m_pAnimBlocks[i]; } void CAnimManagerSA::Initialize() diff --git a/Client/game_sa/CAnimManagerSA.h b/Client/game_sa/CAnimManagerSA.h index bb29059fac..2268270044 100644 --- a/Client/game_sa/CAnimManagerSA.h +++ b/Client/game_sa/CAnimManagerSA.h @@ -165,7 +165,4 @@ class CAnimManagerSA : public CAnimManager bool IsValidGroup(std::uint32_t uiAnimGroup) const; bool IsValidAnim(std::uint32_t uiAnimGroup, std::uint32_t uiAnimID) const; -private: - CAnimBlendAssocGroup* m_pAnimAssocGroups[MAX_ANIM_GROUPS]; - CAnimBlock* m_pAnimBlocks[MAX_ANIM_BLOCKS]; }; diff --git a/Client/game_sa/CBuildingsPoolSA.cpp b/Client/game_sa/CBuildingsPoolSA.cpp index 3aedb72476..4509d8c70d 100644 --- a/Client/game_sa/CBuildingsPoolSA.cpp +++ b/Client/game_sa/CBuildingsPoolSA.cpp @@ -51,7 +51,7 @@ inline bool CBuildingsPoolSA::AddBuildingToPool(CClientBuilding* pClientBuilding CClientEntity* CBuildingsPoolSA::GetClientBuilding(CBuildingSAInterface* pGameInterface) const noexcept { - std::uint32_t poolIndex = (*m_ppBuildingPoolInterface)->GetObjectIndex(pGameInterface); + std::uint32_t poolIndex = (*m_ppBuildingPoolInterface)->GetObjectIndexSafe(pGameInterface); if (poolIndex == static_cast(-1)) return nullptr; diff --git a/Client/game_sa/CDynamicPool.h b/Client/game_sa/CDynamicPool.h new file mode 100644 index 0000000000..8a6d0a7433 --- /dev/null +++ b/Client/game_sa/CDynamicPool.h @@ -0,0 +1,178 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CDynamicPool.h + * PURPOSE: Custom implementation for SA pools + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include +#include +#include + +template +class CDynamicPoolPart +{ +public: + explicit CDynamicPoolPart(std::size_t size) : m_size{size} + { + m_items = std::make_unique(size); + m_unusedIndices.reserve(size); + for (std::size_t i = 0; i < size; i++) + m_unusedIndices.push_back(i); + } + + PoolObjT* AllocateItem() + { + std::size_t index = m_unusedIndices.back(); + m_unusedIndices.pop_back(); + return &m_items[index]; + } + + void RemoveItem(PoolObjT* item) + { + auto pos = item - m_items.get(); + m_unusedIndices.push_back(pos); + } + + bool OwnsItem(PoolObjT* item) const noexcept { return item >= m_items.get() && item < m_items.get() + m_size; } + bool HasFreeSize() const noexcept { return m_unusedIndices.size() != 0; } + std::size_t GetCapacity() const noexcept { return m_size; } + std::size_t GetUsedSize() const noexcept { return m_size - m_unusedIndices.size(); } + +private: + std::unique_ptr m_items; + std::vector m_unusedIndices; + const std::size_t m_size; +}; + +template +struct PoolGrowAddStrategy +{ + static constexpr std::size_t GetInitialSize() { return InitialSize; } + static constexpr std::size_t GetNextSize(std::size_t index) { return AddSize; } +}; + +template +class CDynamicPool +{ +public: + CDynamicPool() + { + constexpr size_t initialSize = GrowStrategy::GetInitialSize(); + m_poolParts.emplace_back(initialSize); + } + + PoolObjT* AllocateItem() + { + for (auto& pool : m_poolParts) + { + if (pool.HasFreeSize()) + return pool.AllocateItem(); + } + + try + { + return AllocateNewPart().AllocateItem(); + } + catch (const std::bad_alloc&) + { + assert(false && "Could not allocate a memory for CDynamicPoolPart"); + } + } + + void RemoveItem(PoolObjT* item) + { + for (auto& pool : m_poolParts) + { + if (pool.OwnsItem(item)) + { + pool.RemoveItem(item); + return; + } + } + + assert(false && "Invalid item for CDynamicPool::RemoveItem"); + } + + std::size_t GetCapacity() const noexcept + { + std::size_t size = 0; + for (auto& pool : m_poolParts) + size += pool.GetCapacity(); + + return size; + } + + std::size_t GetUsedSize() const noexcept + { + std::size_t size = 0; + for (auto& pool : m_poolParts) + size += pool.GetUsedSize(); + + return size; + } + + bool SetCapacity(std::size_t newSize) { + if (newSize == 0) + return false; + + std::size_t currentSize = GetCapacity(); + + if (currentSize == newSize) + return false; + else if (currentSize < newSize) + { + // Grow + while (currentSize < newSize) + { + try + { + auto& nextPart = AllocateNewPart(); + currentSize += nextPart.GetCapacity(); + } + catch (const std::bad_alloc&) + { + return false; + } + } + } + else + { + // Shrink + while (true) + { + auto& part = m_poolParts.back(); + if (part.GetUsedSize() != 0) + return false; + + currentSize -= part.GetCapacity(); + if (currentSize < newSize) + return false; + + m_poolParts.pop_back(); + + if (currentSize == newSize) + return true; + } + } + + return true; + } + +private: + CDynamicPoolPart& AllocateNewPart() + { + const std::size_t nextSize = GrowStrategy::GetNextSize(m_poolParts.size()); + m_poolParts.emplace_back(nextSize); + return m_poolParts.back(); + } + +private: + std::list> m_poolParts; +}; diff --git a/Client/game_sa/CGameSA.cpp b/Client/game_sa/CGameSA.cpp index 744993584e..49992830d9 100644 --- a/Client/game_sa/CGameSA.cpp +++ b/Client/game_sa/CGameSA.cpp @@ -59,6 +59,7 @@ #include "CIplStoreSA.h" #include "CBuildingRemovalSA.h" #include "CCheckpointSA.h" +#include "CPtrNodeSingleLinkPoolSA.h" extern CGameSA* pGame; @@ -245,6 +246,7 @@ CGameSA::CGameSA() CVehicleSA::StaticSetHooks(); CCheckpointSA::StaticSetHooks(); CHudSA::StaticSetHooks(); + CPtrNodeSingleLinkPoolSA::StaticSetHooks(); } catch (const std::bad_alloc& e) { diff --git a/Client/game_sa/CPoolsSA.cpp b/Client/game_sa/CPoolsSA.cpp index 6d926ecfc8..d5f86f6fea 100644 --- a/Client/game_sa/CPoolsSA.cpp +++ b/Client/game_sa/CPoolsSA.cpp @@ -900,8 +900,7 @@ int CPoolsSA::GetPoolCapacity(ePools pool) iPtr = 0x550F82; break; case POINTER_SINGLE_LINK_POOL: - iPtr = 0x550F46; - break; + return GetPtrNodeSingleLinkPool().GetCapacity(); case ENV_MAP_MATERIAL_POOL: iPtr = 0x5DA08E; break; @@ -1067,9 +1066,7 @@ int CPoolsSA::GetNumberOfUsedSpaces(ePools pool) dwThis = CLASS_CPtrNodeDoubleLinkPool; break; case POINTER_SINGLE_LINK_POOL: - dwFunc = FUNC_CPtrNodeSingleLinkPool_GetNoOfUsedSpaces; - dwThis = CLASS_CPtrNodeSingleLinkPool; - break; + return GetPtrNodeSingleLinkPool().GetUsedSize(); default: return -1; } diff --git a/Client/game_sa/CPoolsSA.h b/Client/game_sa/CPoolsSA.h index e190c2fbd6..072f893d30 100644 --- a/Client/game_sa/CPoolsSA.h +++ b/Client/game_sa/CPoolsSA.h @@ -18,6 +18,7 @@ #include "CBuildingsPoolSA.h" #include "CDummyPoolSA.h" #include "CTxdPoolSA.h" +#include "CPtrNodeSingleLinkPoolSA.h" #define INVALID_POOL_ARRAY_ID 0xFFFFFFFF @@ -97,6 +98,7 @@ class CPoolsSA : public CPools CBuildingsPool& GetBuildingsPool() noexcept override { return m_BuildingsPool; }; CDummyPool& GetDummyPool() noexcept { return m_DummyPool; }; CTxdPool& GetTxdPool() noexcept { return m_TxdPool; }; + CPtrNodeSingleLinkPool& GetPtrNodeSingleLinkPool() noexcept override { return m_PtrNodeSingleLinkPool; }; private: // Pools @@ -111,6 +113,7 @@ class CPoolsSA : public CPools CBuildingsPoolSA m_BuildingsPool; CDummyPoolSA m_DummyPool; CTxdPoolSA m_TxdPool; + CPtrNodeSingleLinkPoolSA m_PtrNodeSingleLinkPool; bool m_bGetVehicleEnabled; }; diff --git a/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp b/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp new file mode 100644 index 0000000000..6bed46f048 --- /dev/null +++ b/Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp @@ -0,0 +1,68 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CPtrNodeSingleLinkPoolSA.cpp + * PURPOSE: Custom implementation for the CPtrNodeSingleLinkPool pool + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#include "StdInc.h" +#include "CPtrNodeSingleLinkPoolSA.h" + +CPtrNodeSingleLinkPoolSA::pool_t* CPtrNodeSingleLinkPoolSA::m_customPool = nullptr; + +CPtrNodeSingleLinkPoolSA::CPtrNodeSingleLinkPoolSA() +{ + if (!m_customPool) + m_customPool = new CPtrNodeSingleLinkPoolSA::pool_t(); +} + +constexpr std::uint32_t HOOKPOS_SingleLinkNodeConstructor = 0x552380; +constexpr std::size_t HOOKSIZE_SingleLinkNodeConstructor = 6; +static CPtrNodeSingleLinkPoolSA::pool_item_t* __cdecl HOOK_SingleLinkNodeConstructor() +{ + return CPtrNodeSingleLinkPoolSA::GetPoolInstance()->AllocateItem(); +} + +constexpr std::uint32_t HOOKPOS_SingleLinkNodeDestructor = 0x552390; +constexpr std::size_t HOOKSIZE_SingleLinkNodeDestructor = 6; +static CPtrNodeSingleLinkPoolSA::pool_item_t* __cdecl HOOK_SingleLinkNodeDestructor(CPtrNodeSingleLinkPoolSA::pool_item_t* item) +{ + CPtrNodeSingleLinkPoolSA::GetPoolInstance()->RemoveItem(item); + // The game doesen't use the return value + return item; +} + +// Replace pool->RemoveItem here +constexpr std::uint32_t HOOKPOS_CPtrListSingleLink_Flush = 0x55243B; +constexpr std::size_t HOOKSIZE_CPtrListSingleLink_Flush = 6; +constexpr std::uint32_t CONTINUE_CPtrListSingleLink_Flush = 0x55245B; +static void _declspec(naked) HOOK_CPtrListSingleLink_Flush() +{ + __asm { + mov edi, ecx ; save register + + ; CPtrNodeSingleLinkPoolSA::m_customPool->RemoveItem(eax) + + mov ecx, CPtrNodeSingleLinkPoolSA::m_customPool + push eax + call CPtrNodeSingleLinkPoolSA::pool_t::RemoveItem + + mov ecx, edi ; restore + jmp CONTINUE_CPtrListSingleLink_Flush + } +} + +void CPtrNodeSingleLinkPoolSA::StaticSetHooks() +{ + EZHookInstall(SingleLinkNodeConstructor); + EZHookInstall(SingleLinkNodeDestructor); + EZHookInstall(CPtrListSingleLink_Flush); + + // Skip the original pool initialization + MemCpy((void*)0x550F26, "\xEB\x2D", 2); +} + diff --git a/Client/game_sa/CPtrNodeSingleLinkPoolSA.h b/Client/game_sa/CPtrNodeSingleLinkPoolSA.h new file mode 100644 index 0000000000..afc760d0e1 --- /dev/null +++ b/Client/game_sa/CPtrNodeSingleLinkPoolSA.h @@ -0,0 +1,37 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto v1.0 + * LICENSE: See LICENSE in the top level directory + * FILE: game_sa/CPtrNodeSingleLinkPoolSA.h + * PURPOSE: Custom implementation for the CPtrNodeSingleLinkPool pool + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +#include "CPoolSAInterface.h" +#include "CDynamicPool.h" +#include "CPtrNodeSingleListSA.h" +#include + +class CPtrNodeSingleLinkPoolSA final : public CPtrNodeSingleLinkPool +{ +public: + using pool_item_t = CPtrNodeSingleLink; + using pool_t = CDynamicPool>; + + CPtrNodeSingleLinkPoolSA(); + + std::size_t GetCapacity() const override { return m_customPool->GetCapacity(); } + std::size_t GetUsedSize() const override { return m_customPool->GetUsedSize(); } + + bool Resize(std::size_t newSize) override { return m_customPool->SetCapacity(newSize); }; + void ResetCapacity() override { m_customPool->SetCapacity(MAX_POINTER_SINGLE_LINKS); }; + + static auto* GetPoolInstance() { return m_customPool; } + static void StaticSetHooks(); +private: + static pool_t* m_customPool; +}; diff --git a/Client/mods/deathmatch/logic/CClientGame.cpp b/Client/mods/deathmatch/logic/CClientGame.cpp index e860393472..b8a89c1109 100644 --- a/Client/mods/deathmatch/logic/CClientGame.cpp +++ b/Client/mods/deathmatch/logic/CClientGame.cpp @@ -515,6 +515,7 @@ CClientGame::~CClientGame() g_pGame->SetPreWeaponFireHandler(NULL); g_pGame->SetPostWeaponFireHandler(NULL); g_pGame->SetTaskSimpleBeHitHandler(NULL); + g_pGame->GetPools()->GetPtrNodeSingleLinkPool().ResetCapacity(); g_pGame->GetAudioEngine()->SetWorldSoundHandler(NULL); g_pCore->SetMessageProcessor(NULL); g_pCore->GetKeyBinds()->SetKeyStrokeHandler(NULL); @@ -5998,7 +5999,7 @@ bool CClientGame::IsGlitchEnabled(unsigned char ucGlitch) return ucGlitch < NUM_GLITCHES && m_Glitches[ucGlitch]; } -bool CClientGame::SetWorldSpecialProperty(WorldSpecialProperty property, bool isEnabled) noexcept +bool CClientGame::SetWorldSpecialProperty(const WorldSpecialProperty property, const bool enabled) noexcept { switch (property) { @@ -6006,66 +6007,58 @@ bool CClientGame::SetWorldSpecialProperty(WorldSpecialProperty property, bool is case WorldSpecialProperty::AIRCARS: case WorldSpecialProperty::EXTRABUNNY: case WorldSpecialProperty::EXTRAJUMP: - g_pGame->SetCheatEnabled(EnumToString(property), isEnabled); + g_pGame->SetCheatEnabled(EnumToString(property), enabled); break; case WorldSpecialProperty::RANDOMFOLIAGE: - g_pGame->SetRandomFoliageEnabled(isEnabled); + g_pGame->SetRandomFoliageEnabled(enabled); break; case WorldSpecialProperty::SNIPERMOON: - g_pGame->SetMoonEasterEggEnabled(isEnabled); + g_pGame->SetMoonEasterEggEnabled(enabled); break; case WorldSpecialProperty::EXTRAAIRRESISTANCE: - g_pGame->SetExtraAirResistanceEnabled(isEnabled); + g_pGame->SetExtraAirResistanceEnabled(enabled); break; case WorldSpecialProperty::UNDERWORLDWARP: - g_pGame->SetUnderWorldWarpEnabled(isEnabled); + g_pGame->SetUnderWorldWarpEnabled(enabled); break; case WorldSpecialProperty::VEHICLESUNGLARE: - g_pGame->SetVehicleSunGlareEnabled(isEnabled); + g_pGame->SetVehicleSunGlareEnabled(enabled); break; case WorldSpecialProperty::CORONAZTEST: - g_pGame->SetCoronaZTestEnabled(isEnabled); + g_pGame->SetCoronaZTestEnabled(enabled); break; case WorldSpecialProperty::WATERCREATURES: - g_pGame->SetWaterCreaturesEnabled(isEnabled); + g_pGame->SetWaterCreaturesEnabled(enabled); break; case WorldSpecialProperty::BURNFLIPPEDCARS: - g_pGame->SetBurnFlippedCarsEnabled(isEnabled); + g_pGame->SetBurnFlippedCarsEnabled(enabled); break; case WorldSpecialProperty::FIREBALLDESTRUCT: - g_pGame->SetFireballDestructEnabled(isEnabled); + g_pGame->SetFireballDestructEnabled(enabled); break; case WorldSpecialProperty::EXTENDEDWATERCANNONS: - g_pGame->SetExtendedWaterCannonsEnabled(isEnabled); + g_pGame->SetExtendedWaterCannonsEnabled(enabled); break; case WorldSpecialProperty::ROADSIGNSTEXT: - g_pGame->SetRoadSignsTextEnabled(isEnabled); + g_pGame->SetRoadSignsTextEnabled(enabled); break; case WorldSpecialProperty::TUNNELWEATHERBLEND: - g_pGame->SetTunnelWeatherBlendEnabled(isEnabled); + g_pGame->SetTunnelWeatherBlendEnabled(enabled); break; case WorldSpecialProperty::IGNOREFIRESTATE: - g_pGame->SetIgnoreFireStateEnabled(isEnabled); + g_pGame->SetIgnoreFireStateEnabled(enabled); break; case WorldSpecialProperty::FLYINGCOMPONENTS: - m_pVehicleManager->SetSpawnFlyingComponentEnabled(isEnabled); + m_pVehicleManager->SetSpawnFlyingComponentEnabled(enabled); break; default: return false; } - if (g_pNet->CanServerBitStream(eBitStreamVersion::WorldSpecialPropertyEvent)) { - NetBitStreamInterface* stream = g_pNet->AllocateNetBitStream(); - stream->WriteString(EnumToString(property)); - stream->WriteBit(isEnabled); - g_pNet->SendPacket(PACKET_ID_PLAYER_WORLD_SPECIAL_PROPERTY, stream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); - g_pNet->DeallocateNetBitStream(stream); - } - return true; } -bool CClientGame::IsWorldSpecialProperty(WorldSpecialProperty property) +bool CClientGame::IsWorldSpecialProperty(const WorldSpecialProperty property) { switch (property) { @@ -6103,6 +6096,7 @@ bool CClientGame::IsWorldSpecialProperty(WorldSpecialProperty property) case WorldSpecialProperty::FLYINGCOMPONENTS: return m_pVehicleManager->IsSpawnFlyingComponentEnabled(); } + return false; } diff --git a/Client/mods/deathmatch/logic/CClientGame.h b/Client/mods/deathmatch/logic/CClientGame.h index b5819d8ee2..401cf5dee5 100644 --- a/Client/mods/deathmatch/logic/CClientGame.h +++ b/Client/mods/deathmatch/logic/CClientGame.h @@ -410,8 +410,8 @@ class CClientGame bool SetGlitchEnabled(unsigned char cGlitch, bool bEnabled); bool IsGlitchEnabled(unsigned char cGlitch); - bool SetWorldSpecialProperty(WorldSpecialProperty property, bool isEnabled) noexcept; - bool IsWorldSpecialProperty(WorldSpecialProperty property); + bool SetWorldSpecialProperty(const WorldSpecialProperty property, const bool enabled) noexcept; + bool IsWorldSpecialProperty(const WorldSpecialProperty property); bool SetCloudsEnabled(bool bEnabled); bool GetCloudsEnabled(); diff --git a/Client/mods/deathmatch/logic/CClientObjectManager.cpp b/Client/mods/deathmatch/logic/CClientObjectManager.cpp index 45cc2a0408..c59483b4db 100644 --- a/Client/mods/deathmatch/logic/CClientObjectManager.cpp +++ b/Client/mods/deathmatch/logic/CClientObjectManager.cpp @@ -230,22 +230,7 @@ void CClientObjectManager::OnDestruction(CClientObject* pObject) void CClientObjectManager::UpdateLimitInfo() { m_iEntryInfoNodeEntries = g_pMultiplayer->EntryInfoNodePool_NoOfUsedSpaces(); - m_iPointerNodeSingleLinkEntries = g_pMultiplayer->PtrNodeSingleLinkPool_NoOfUsedSpaces(); m_iPointerNodeDoubleLinkEntries = g_pMultiplayer->PtrNodeDoubleLinkPool_NoOfUsedSpaces(); - - /* - CPools* pPools = g_pGame->GetPools(); - unsigned int nEntryInfoNodeEntries = pPools->GetEntryInfoNodePool()->GetNumberOfUsedSpaces(); - unsigned int nPointerNodeSingleLinkEntries = pPools->GetPointerNodeSingleLinkPool()->GetNumberOfUsedSpaces(); - unsigned int nPointerNodeDoubleLinkEntries = pPools->GetPointerNodeDoubleLinkPool()->GetNumberOfUsedSpaces(); - - g_pCore->ChatPrintf("%d = %d ### %d = %d ### %d = %d", false, nEntryInfoNodeEntries, m_iEntryInfoNodeEntries, nPointerNodeSingleLinkEntries, - m_iPointerNodeSingleLinkEntries, nPointerNodeDoubleLinkEntries, m_iPointerNodeDoubleLinkEntries); - - assert(nEntryInfoNodeEntries == m_iEntryInfoNodeEntries); - assert(nPointerNodeSingleLinkEntries == m_iPointerNodeSingleLinkEntries); - assert(nPointerNodeDoubleLinkEntries == m_iPointerNodeDoubleLinkEntries); - */ } bool CClientObjectManager::StaticIsObjectLimitReached() @@ -278,8 +263,7 @@ bool CClientObjectManager::IsHardObjectLimitReached() return true; // If we've run out of either of these limit, don't allow more objects - if (m_iEntryInfoNodeEntries >= MAX_ENTRY_INFO_NODES_MTA || m_iPointerNodeSingleLinkEntries >= MAX_POINTER_SINGLE_LINKS_MTA || - m_iPointerNodeDoubleLinkEntries >= MAX_POINTER_DOUBLE_LINKS_MTA) + if (m_iEntryInfoNodeEntries >= MAX_ENTRY_INFO_NODES_MTA || m_iPointerNodeDoubleLinkEntries >= MAX_POINTER_DOUBLE_LINKS_MTA) { if (!m_bDoneLimitWarning) { @@ -287,9 +271,8 @@ bool CClientObjectManager::IsHardObjectLimitReached() SString strMessage( "CClientObjectManager reached limit -" " ENTRY_INFO_NODES:%d/%d" - " POINTER_SINGLE_LINKS:%d/%d" " POINTER_DOUBLE_LINKS:%d/%d", - m_iEntryInfoNodeEntries, MAX_ENTRY_INFO_NODES_MTA, m_iPointerNodeSingleLinkEntries, MAX_POINTER_SINGLE_LINKS_MTA, + m_iEntryInfoNodeEntries, MAX_ENTRY_INFO_NODES_MTA, m_iPointerNodeDoubleLinkEntries, MAX_POINTER_DOUBLE_LINKS_MTA); g_pCore->GetConsole()->Echo(strMessage); AddReportLog(7430, strMessage); diff --git a/Client/mods/deathmatch/logic/CClientObjectManager.h b/Client/mods/deathmatch/logic/CClientObjectManager.h index 113e33db9b..7be7aa70ab 100644 --- a/Client/mods/deathmatch/logic/CClientObjectManager.h +++ b/Client/mods/deathmatch/logic/CClientObjectManager.h @@ -56,7 +56,6 @@ class CClientObjectManager void UpdateLimitInfo(); int m_iEntryInfoNodeEntries; - int m_iPointerNodeSingleLinkEntries; int m_iPointerNodeDoubleLinkEntries; uint m_uiMaxStreamedInCount; uint m_uiMaxLowLodStreamedInCount; diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp index a6a688c366..0ad88113b1 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaEngineDefs.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include "CLuaEngineDefs.h" @@ -2505,6 +2506,10 @@ bool CLuaEngineDefs::EngineSetPoolCapacity(lua_State* luaVM, ePools pool, size_t { return m_pBuildingManager->SetPoolCapacity(newSize); } + case ePools::POINTER_SINGLE_LINK_POOL: + { + return g_pGame->GetPools()->GetPtrNodeSingleLinkPool().Resize(newSize); + } default: throw std::invalid_argument("Can not change this pool capacity"); } diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp index 32d838a332..5f93d1fbc2 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.cpp @@ -1266,14 +1266,28 @@ int CLuaWorldDefs::SetOcclusionsEnabled(lua_State* luaVM) return 1; } -bool CLuaWorldDefs::IsWorldSpecialPropertyEnabled(WorldSpecialProperty property) +bool CLuaWorldDefs::IsWorldSpecialPropertyEnabled(const WorldSpecialProperty property) noexcept { return m_pClientGame->IsWorldSpecialProperty(property); } -bool CLuaWorldDefs::SetWorldSpecialPropertyEnabled(WorldSpecialProperty property, bool isEnabled) +bool CLuaWorldDefs::SetWorldSpecialPropertyEnabled(const WorldSpecialProperty property, const bool enabled) noexcept { - return m_pClientGame->SetWorldSpecialProperty(property, isEnabled); + if (!m_pClientGame->SetWorldSpecialProperty(property, enabled)) + return false; + + if (!g_pNet->CanServerBitStream(eBitStreamVersion::WorldSpecialPropertyEvent)) + return true; + + if (auto stream = g_pNet->AllocateNetBitStream()) + { + stream->WriteString(EnumToString(property)); + stream->WriteBit(enabled); + g_pNet->SendPacket(PACKET_ID_PLAYER_WORLD_SPECIAL_PROPERTY, stream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED); + g_pNet->DeallocateNetBitStream(stream); + } + + return true; } int CLuaWorldDefs::SetCloudsEnabled(lua_State* luaVM) diff --git a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h index 7cf1eb91d7..1eb5e6da30 100644 --- a/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h +++ b/Client/mods/deathmatch/logic/luadefs/CLuaWorldDefs.h @@ -34,7 +34,7 @@ class CLuaWorldDefs : public CLuaDefs LUA_DECLARE(GetGaragePosition); LUA_DECLARE(GetGarageSize); LUA_DECLARE(GetGarageBoundingBox); - static bool IsWorldSpecialPropertyEnabled(WorldSpecialProperty property); + static bool IsWorldSpecialPropertyEnabled(const WorldSpecialProperty property) noexcept; LUA_DECLARE(GetBlurLevel); LUA_DECLARE(GetTrafficLightState); LUA_DECLARE(AreTrafficLightsLocked); @@ -57,7 +57,7 @@ class CLuaWorldDefs : public CLuaDefs LUA_DECLARE(SetMinuteDuration); LUA_DECLARE(SetWaveHeight); LUA_DECLARE(SetGarageOpen); - static bool SetWorldSpecialPropertyEnabled(WorldSpecialProperty property, bool isEnabled); + static bool SetWorldSpecialPropertyEnabled(const WorldSpecialProperty property, const bool enabled) noexcept; LUA_DECLARE(SetBlurLevel); LUA_DECLARE(ResetBlurLevel); LUA_DECLARE(SetJetpackMaxHeight); diff --git a/Client/multiplayer_sa/CMultiplayerSA.h b/Client/multiplayer_sa/CMultiplayerSA.h index 0dd642cb4b..b4339fae47 100644 --- a/Client/multiplayer_sa/CMultiplayerSA.h +++ b/Client/multiplayer_sa/CMultiplayerSA.h @@ -354,7 +354,6 @@ class CMultiplayerSA : public CMultiplayer DWORD GetLastAnimArrayAddress() { return m_dwLastAnimArrayAddress; } unsigned int EntryInfoNodePool_NoOfUsedSpaces() const noexcept override; - unsigned int PtrNodeSingleLinkPool_NoOfUsedSpaces() const noexcept override; unsigned int PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept override; CVector m_vecAkimboTarget; diff --git a/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp b/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp index 2fb73247c3..976eefb98b 100644 --- a/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp +++ b/Client/multiplayer_sa/CMultiplayerSA_ObjectStreamerOptimization.cpp @@ -11,7 +11,6 @@ #include "StdInc.h" static unsigned int CEntryInfoNodePool_UsedSpaces = 0; -static unsigned int CPtrNodeSingleLinkPool_UsedSpaces = 0; static unsigned int CPtrNodeDoubleLinkPool_UsedSpaces = 0; #define HOOKPOS_CEntryInfoNodePool__New 0x536D6E @@ -55,46 +54,6 @@ static void _declspec(naked) HOOK_CEntryInfoList__Flush() } } -#define HOOKPOS_CPtrNodeSingleLinkPool__New 0x55229B -#define HOOKSIZE_CPtrNodeSingleLinkPool__New 0x5 -static void _declspec(naked) HOOK_CPtrNodeSingleLinkPool__New() -{ - _asm { - inc CPtrNodeSingleLinkPool_UsedSpaces - - lea eax, [ecx+eax*8] - pop esi - ret - } -} -#define HOOKPOS_CPtrNodeSingleLink__operator_delete 0x5523AA -#define HOOKSIZE_CPtrNodeSingleLink__operator_delete 0x5 -static const unsigned int RETURN_CPtrNodeSingleLink__operator_delete = 0x5523AF; -static void _declspec(naked) HOOK_CPtrNodeSingleLink__operator_delete() -{ - _asm { - dec CPtrNodeSingleLinkPool_UsedSpaces - - or bl, 0x80 - mov [ecx], bl - jmp RETURN_CPtrNodeSingleLink__operator_delete - } -} - -#define HOOKPOS_CPtrListSingleLink__Flush 0x55244D -#define HOOKSIZE_CPtrListSingleLink__Flush 0x6 -static const unsigned int RETURN_CPtrListSingleLink__Flush = 0x552453; -static void _declspec(naked) HOOK_CPtrListSingleLink__Flush() -{ - _asm { - dec CPtrNodeSingleLinkPool_UsedSpaces - - or byte ptr [edx+eax], 0x80 - add edx, eax - jmp RETURN_CPtrListSingleLink__Flush - } -} - #define HOOKPOS_CPtrNodeDoubleLinkPool__New 0x55233E #define HOOKSIZE_CPtrNodeDoubleLinkPool__New 0x6 static void _declspec(naked) HOOK_CPtrNodeDoubleLinkPool__New() @@ -142,10 +101,6 @@ void CMultiplayerSA::InitHooks_ObjectStreamerOptimization() EZHookInstall(CEntryInfoNode__operator_delete); EZHookInstall(CEntryInfoList__Flush); - EZHookInstall(CPtrNodeSingleLinkPool__New); - EZHookInstall(CPtrNodeSingleLink__operator_delete); - EZHookInstall(CPtrListSingleLink__Flush); - EZHookInstall(CPtrNodeDoubleLinkPool__New); EZHookInstall(CPtrNodeDoubleLink__operator_delete); EZHookInstall(CPtrListDoubleLink__Flush); @@ -156,11 +111,6 @@ unsigned int CMultiplayerSA::EntryInfoNodePool_NoOfUsedSpaces() const noexcept return CEntryInfoNodePool_UsedSpaces; } -unsigned int CMultiplayerSA::PtrNodeSingleLinkPool_NoOfUsedSpaces() const noexcept -{ - return CPtrNodeSingleLinkPool_UsedSpaces; -} - unsigned int CMultiplayerSA::PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept { return CPtrNodeDoubleLinkPool_UsedSpaces; diff --git a/Client/sdk/game/CPools.h b/Client/sdk/game/CPools.h index 46359a02a6..0fc8555134 100644 --- a/Client/sdk/game/CPools.h +++ b/Client/sdk/game/CPools.h @@ -15,6 +15,7 @@ #include "CBuildingsPool.h" #include "CDummyPool.h" #include "CTxdPool.h" +#include "CPtrNodeSingleLinkPool.h" class CClientEntity; class CEntity; @@ -111,4 +112,5 @@ class CPools virtual CBuildingsPool& GetBuildingsPool() noexcept = 0; virtual CDummyPool& GetDummyPool() noexcept = 0; virtual CTxdPool& GetTxdPool() noexcept = 0; + virtual CPtrNodeSingleLinkPool& GetPtrNodeSingleLinkPool() noexcept = 0; }; diff --git a/Client/sdk/game/CPtrNodeSingleLinkPool.h b/Client/sdk/game/CPtrNodeSingleLinkPool.h new file mode 100644 index 0000000000..125820edf8 --- /dev/null +++ b/Client/sdk/game/CPtrNodeSingleLinkPool.h @@ -0,0 +1,20 @@ +/***************************************************************************** + * + * PROJECT: Multi Theft Auto + * LICENSE: See LICENSE in the top level directory + * FILE: sdk/game/CPtrNodeSingleLinkPool.h + * + * Multi Theft Auto is available from http://www.multitheftauto.com/ + * + *****************************************************************************/ + +#pragma once + +class CPtrNodeSingleLinkPool +{ +public: + virtual bool Resize(std::size_t size) = 0; + virtual void ResetCapacity() = 0; + virtual std::size_t GetCapacity() const = 0; + virtual std::size_t GetUsedSize() const = 0; +}; diff --git a/Client/sdk/game/Common.h b/Client/sdk/game/Common.h index 11e5a31554..be4d18a643 100644 --- a/Client/sdk/game/Common.h +++ b/Client/sdk/game/Common.h @@ -29,7 +29,7 @@ #define MAX_BUILDINGS 13000 #define MAX_DUMMIES 2500 #define MAX_ENTRY_INFO_NODES ( MAX_ENTRY_INFO_NODES_MTA + 600 ) // 72600 -#define MAX_POINTER_SINGLE_LINKS ( MAX_POINTER_SINGLE_LINKS_MTA + 5000 ) // 90000 +#define MAX_POINTER_SINGLE_LINKS ( MAX_POINTER_SINGLE_LINKS_MTA + 5000 ) // 90000 May be changed in runtime #define MAX_POINTER_DOUBLE_LINKS ( MAX_POINTER_DOUBLE_LINKS_MTA + 800 ) // 74800 #define MAX_RWOBJECT_INSTANCES 2500 diff --git a/Client/sdk/multiplayer/CMultiplayer.h b/Client/sdk/multiplayer/CMultiplayer.h index 33e349ea71..d9dd4ab571 100644 --- a/Client/sdk/multiplayer/CMultiplayer.h +++ b/Client/sdk/multiplayer/CMultiplayer.h @@ -460,6 +460,5 @@ class CMultiplayer virtual DWORD GetLastAnimArrayAddress() = 0; virtual unsigned int EntryInfoNodePool_NoOfUsedSpaces() const noexcept = 0; - virtual unsigned int PtrNodeSingleLinkPool_NoOfUsedSpaces() const noexcept = 0; virtual unsigned int PtrNodeDoubleLinkPool_NoOfUsedSpaces() const noexcept = 0; }; diff --git a/Server/mods/deathmatch/logic/CGame.cpp b/Server/mods/deathmatch/logic/CGame.cpp index 632b65d98b..0d684789df 100644 --- a/Server/mods/deathmatch/logic/CGame.cpp +++ b/Server/mods/deathmatch/logic/CGame.cpp @@ -1641,7 +1641,7 @@ void CGame::AddBuiltInEvents() m_Events.AddEvent("onPlayerTriggerInvalidEvent", "eventName, isAdded, isRemote", nullptr, false); m_Events.AddEvent("onPlayerChangesProtectedData", "element, key, value", nullptr, false); m_Events.AddEvent("onPlayerChangesWorldSpecialProperty", "property, enabled", nullptr, false); - m_Events.AddEvent("onPlayerTeleport", "", nullptr, false); + m_Events.AddEvent("onPlayerTeleport", "previousX, previousY, previousZ, currentX, currentY, currentZ", nullptr, false); // Ped events m_Events.AddEvent("onPedVehicleEnter", "vehicle, seat, jacked", NULL, false); diff --git a/Server/mods/deathmatch/logic/CMapManager.cpp b/Server/mods/deathmatch/logic/CMapManager.cpp index 0af22ff885..eb161ceb8e 100644 --- a/Server/mods/deathmatch/logic/CMapManager.cpp +++ b/Server/mods/deathmatch/logic/CMapManager.cpp @@ -593,6 +593,7 @@ void CMapManager::SpawnPlayer(CPlayer& Player, const CVector& vecPosition, float // Update the player data Player.SetSpawned(true); + Player.SetTeleported(true); Player.SetHealth(Player.GetMaxHealth()); Player.SetIsDead(false); Player.SetWearingGoggles(false); diff --git a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp index 2079adf2d2..144cdc661c 100644 --- a/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp +++ b/Server/mods/deathmatch/logic/CStaticFunctionDefinitions.cpp @@ -1477,6 +1477,12 @@ bool CStaticFunctionDefinitions::SetElementInterior(CElement* pElement, unsigned BitStream.pBitStream->Write(static_cast((bSetPosition) ? 1 : 0)); if (bSetPosition) { + if (IS_PLAYER(pElement)) + { + CPlayer* player = static_cast(pElement); + player->SetTeleported(true); + } + BitStream.pBitStream->Write(vecPosition.fX); BitStream.pBitStream->Write(vecPosition.fY); BitStream.pBitStream->Write(vecPosition.fZ); diff --git a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp index 8fee7a61fb..151106979b 100644 --- a/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp +++ b/Server/mods/deathmatch/logic/packets/CPlayerPuresyncPacket.cpp @@ -132,15 +132,26 @@ bool CPlayerPuresyncPacket::Read(NetBitStreamInterface& BitStream) position.data.vecPosition += vecTempPos; } - CVector playerPosition = pSourcePlayer->GetPosition(); - float playerDistancePosition = DistanceBetweenPoints3D(playerPosition, position.data.vecPosition); - if (playerDistancePosition >= g_TickRateSettings.playerTeleportAlert) { - if (!pSourcePlayer->GetTeleported()) { - CLuaArguments arguments; - pSourcePlayer->CallEvent("onPlayerTeleport", arguments, nullptr); - } + if (position.data.vecPosition.fX != 0.0f && position.data.vecPosition.fY != 0.0f && position.data.vecPosition.fZ != 0.0f) + { + CVector playerPosition = pSourcePlayer->GetPosition(); + float playerDistancePosition = DistanceBetweenPoints3D(playerPosition, position.data.vecPosition); + if (playerDistancePosition >= g_TickRateSettings.playerTeleportAlert) + { + if (!pSourcePlayer->GetTeleported()) + { + CLuaArguments arguments; + arguments.PushNumber(playerPosition.fX); + arguments.PushNumber(playerPosition.fY); + arguments.PushNumber(playerPosition.fZ); + arguments.PushNumber(position.data.vecPosition.fX); + arguments.PushNumber(position.data.vecPosition.fY); + arguments.PushNumber(position.data.vecPosition.fZ); + pSourcePlayer->CallEvent("onPlayerTeleport", arguments, nullptr); + } - pSourcePlayer->SetTeleported(false); + pSourcePlayer->SetTeleported(false); + } } pSourcePlayer->SetPosition(position.data.vecPosition); diff --git a/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot b/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot index 63d281a298..c187de69fd 100644 --- a/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot +++ b/Shared/data/MTA San Andreas/MTA/locale/en_US/client.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: MTA San Andreas 1.x\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-01-26 16:31+0000\n" +"POT-Creation-Date: 2025-02-06 15:53+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -134,7 +134,7 @@ msgid "(Development mode) prints world sound ids into the debug window" msgstr "" #: Client/mods/deathmatch/logic/CResource.cpp:372 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1095 Client/core/CCore.cpp:674 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1096 Client/core/CCore.cpp:674 #: Client/core/CSettings.cpp:3520 msgid "In-game" msgstr "" @@ -170,17 +170,17 @@ msgstr "" #. Show a message that the connection timed out and abort #. Show failed message and abort the attempt #: Client/mods/deathmatch/logic/CResourceFileDownloadManager.cpp:145 -#: Client/mods/deathmatch/logic/CClientGame.cpp:647 -#: Client/mods/deathmatch/logic/CClientGame.cpp:721 -#: Client/mods/deathmatch/logic/CClientGame.cpp:745 -#: Client/mods/deathmatch/logic/CClientGame.cpp:767 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1180 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1260 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1270 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1339 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1376 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1425 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1437 +#: Client/mods/deathmatch/logic/CClientGame.cpp:648 +#: Client/mods/deathmatch/logic/CClientGame.cpp:722 +#: Client/mods/deathmatch/logic/CClientGame.cpp:746 +#: Client/mods/deathmatch/logic/CClientGame.cpp:768 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1181 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1261 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1271 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1340 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1377 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1426 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 #: Client/loader/MainFunctions.cpp:252 Client/loader/MainFunctions.cpp:267 #: Client/loader/MainFunctions.cpp:269 Client/loader/MainFunctions.cpp:846 #: Client/loader/CInstallManager.cpp:552 Client/loader/CInstallManager.cpp:561 @@ -196,7 +196,7 @@ msgstr "" #: Client/core/ServerBrowser/CServerBrowser.cpp:1283 #: Client/core/ServerBrowser/CServerBrowser.cpp:1340 #: Client/core/ServerBrowser/CServerBrowser.cpp:1389 -#: Client/game_sa/CGameSA.cpp:257 Client/game_sa/CGameSA.cpp:268 +#: Client/game_sa/CGameSA.cpp:259 Client/game_sa/CGameSA.cpp:270 #: Shared/mods/deathmatch/logic/CLatentTransferManager.cpp:378 #: Shared/sdk/SharedUtil.Misc.hpp:137 msgid "Error" @@ -603,146 +603,146 @@ msgstr "" msgid "Choking to death in" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:539 +#: Client/mods/deathmatch/logic/CClientGame.cpp:540 #: Client/core/CMainMenu.cpp:304 Client/core/CCore.cpp:674 #: Client/core/CSettings.cpp:3516 msgid "Main menu" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:647 -#: Client/mods/deathmatch/logic/CClientGame.cpp:745 +#: Client/mods/deathmatch/logic/CClientGame.cpp:648 +#: Client/mods/deathmatch/logic/CClientGame.cpp:746 #: Client/core/ServerBrowser/CServerBrowser.cpp:1283 #: Client/core/ServerBrowser/CServerBrowser.cpp:1340 msgid "Invalid nickname! Please go to Settings and set a new one!" msgstr "" #. Display the status box -#: Client/mods/deathmatch/logic/CClientGame.cpp:663 +#: Client/mods/deathmatch/logic/CClientGame.cpp:664 #: Client/core/CConnectManager.cpp:150 msgid "CONNECTING" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:663 +#: Client/mods/deathmatch/logic/CClientGame.cpp:664 msgid "Entering the game ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:721 +#: Client/mods/deathmatch/logic/CClientGame.cpp:722 msgid "" "Not connected; please use Quick Connect or the 'connect' command to connect " "to a server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:767 +#: Client/mods/deathmatch/logic/CClientGame.cpp:768 msgid "Could not start the local server. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:777 -#: Client/mods/deathmatch/logic/CClientGame.cpp:1249 +#: Client/mods/deathmatch/logic/CClientGame.cpp:778 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1250 msgid "Local Server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:777 +#: Client/mods/deathmatch/logic/CClientGame.cpp:778 msgid "Starting local server ..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1025 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1026 msgid "Area 51" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1034 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1035 msgid "Walking around " msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1180 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1181 #, c-format msgid "You were kicked from the game ( %s )" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1249 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1250 msgid "Connecting to local server..." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1260 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1261 msgid "Error connecting to server." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1270 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1271 msgid "Connecting to local server timed out. See console for details." msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1339 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1340 #: Client/core/CConnectManager.cpp:265 msgid "Connection timed out" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1376 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1377 msgid "Connection with the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1387 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1388 #: Client/core/CConnectManager.cpp:279 Client/core/CConnectManager.cpp:283 msgid "Disconnected: unknown protocol error" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1391 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1392 #: Client/core/CConnectManager.cpp:287 msgid "Disconnected: disconnected remotely" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1395 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1396 #: Client/core/CConnectManager.cpp:291 msgid "Disconnected: connection lost remotely" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1399 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1400 #: Client/core/CConnectManager.cpp:295 msgid "Disconnected: you are banned from this server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1403 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1404 msgid "Disconnected: the server is currently full" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1407 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1408 #: Client/core/CConnectManager.cpp:302 msgid "Disconnected: disconnected from the server" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1411 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1412 #: Client/core/CConnectManager.cpp:306 msgid "Disconnected: connection to the server was lost" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1415 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1416 msgid "Disconnected: invalid password specified" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1419 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1420 #: Client/core/CConnectManager.cpp:313 msgid "Disconnected: connection was refused" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:1437 +#: Client/mods/deathmatch/logic/CClientGame.cpp:1438 msgid "MTA Client verification failed!" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5636 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5637 msgid "In a ditch" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5636 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5637 msgid "En-route to hospital" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5636 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5637 msgid "Meeting their maker" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5637 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5638 msgid "Regretting their decisions" msgstr "" -#: Client/mods/deathmatch/logic/CClientGame.cpp:5637 +#: Client/mods/deathmatch/logic/CClientGame.cpp:5638 msgid "Wasted" msgstr "" @@ -854,7 +854,7 @@ msgstr "" #: Client/loader/MainFunctions.cpp:603 Client/loader/MainFunctions.cpp:610 #: Client/loader/MainFunctions.cpp:1219 #: Client/core/ServerBrowser/CServerBrowser.cpp:1363 -#: Client/core/ServerBrowser/CServerInfo.cpp:319 Client/game_sa/CGameSA.cpp:264 +#: Client/core/ServerBrowser/CServerInfo.cpp:319 Client/game_sa/CGameSA.cpp:266 msgid "Information" msgstr "" @@ -3337,11 +3337,11 @@ msgstr "" msgid "Querying..." msgstr "" -#: Client/game_sa/CGameSA.cpp:251 Client/game_sa/CGameSA.cpp:262 +#: Client/game_sa/CGameSA.cpp:253 Client/game_sa/CGameSA.cpp:264 msgid "Failed initialization game_sa" msgstr "" -#: Client/game_sa/CGameSA.cpp:253 +#: Client/game_sa/CGameSA.cpp:255 msgid "Memory allocations failed" msgstr "" diff --git a/Shared/sdk/SharedUtil.Misc.hpp b/Shared/sdk/SharedUtil.Misc.hpp index 5697da49f4..0506d11f21 100644 --- a/Shared/sdk/SharedUtil.Misc.hpp +++ b/Shared/sdk/SharedUtil.Misc.hpp @@ -59,7 +59,7 @@ CDuplicateLineFilter ms_ReportLineFilter; #define PRODUCT_REGISTRY_PATH "Software\\Multi Theft Auto: San Andreas All" // HKLM #define PRODUCT_COMMON_DATA_DIR "MTA San Andreas All" // C:\ProgramData -#define TROUBLE_URL1 "http://updatesa.multitheftauto.com/sa/trouble/?v=_VERSION_&id=_ID_&tr=_TROUBLE_" +#define TROUBLE_URL1 "https://help.multitheftauto.com/sa/trouble/?v=_VERSION_&id=_ID_&tr=_TROUBLE_" // // Output a UTF8 encoded messagebox diff --git a/utils/buildactions/install_cef.lua b/utils/buildactions/install_cef.lua index 0b45e8ac7e..7b4b656ea7 100644 --- a/utils/buildactions/install_cef.lua +++ b/utils/buildactions/install_cef.lua @@ -9,8 +9,8 @@ local CEF_URL_PREFIX = "https://cef-builds.spotifycdn.com/cef_binary_" local CEF_URL_SUFFIX = "_windows32_minimal.tar.bz2" -- Change here to update CEF version -local CEF_VERSION = "132.3.1+g144febe+chromium-132.0.6834.83" -local CEF_HASH = "085933ced379bcb5d03ec5f2837f3eb0123dceb22c88e5a24547f0437a6e3851" +local CEF_VERSION = "132.3.2+g4997b2f+chromium-132.0.6834.161" +local CEF_HASH = "9910e4180df0e5f400a033aba33c418c8eda57adbaac68aa005b649d5b2ea52b" function make_cef_download_url() return CEF_URL_PREFIX..CEF_VERSION..CEF_URL_SUFFIX @@ -111,7 +111,7 @@ newaction { else -- Download CEF print("Downloading CEF " .. CEF_VERSION .. "...") - if not http.download_print_errors(make_cef_download_url(), archive_path) then + if not http.download_print_errors(make_cef_download_url(), archive_path, { progress = http.create_download_progress_handler{update_interval_s = 5} }) then os.exit(1) return end diff --git a/utils/buildactions/utils.lua b/utils/buildactions/utils.lua index 42899f4769..2268d8c7d7 100644 --- a/utils/buildactions/utils.lua +++ b/utils/buildactions/utils.lua @@ -129,6 +129,24 @@ function os.extract_archive(archive_path, target_path, override) return false end +function http.create_download_progress_handler(options) + local last_update = 0 + + return function (total, current) + local tick = os.clock() + if tick - last_update < options.update_interval_s then + return + end + + last_update = tick + + local ratio = current / total; + ratio = math.min(math.max(ratio, 0), 1) + local percent = math.floor(ratio * 100) + print(string.format("Downloading (%d/%d) %d%%", current, total, percent)) + end +end + function http.download_print_errors(url, file, options) local result_str, response_code = http.download(url, file, options) if result_str ~= "OK" then