Skip to content

Commit

Permalink
Merge branch 'master' into nitro
Browse files Browse the repository at this point in the history
  • Loading branch information
Proxy-99 authored Feb 7, 2025
2 parents 15db2a6 + dce38ee commit 40831e7
Show file tree
Hide file tree
Showing 31 changed files with 462 additions and 187 deletions.
4 changes: 2 additions & 2 deletions Client/core/CVersionUpdater.Util.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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%"

/*
Expand Down
8 changes: 0 additions & 8 deletions Client/game_sa/CAnimManagerSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
3 changes: 0 additions & 3 deletions Client/game_sa/CAnimManagerSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -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];
};
2 changes: 1 addition & 1 deletion Client/game_sa/CBuildingsPoolSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::uint32_t>(-1))
return nullptr;
Expand Down
178 changes: 178 additions & 0 deletions Client/game_sa/CDynamicPool.h
Original file line number Diff line number Diff line change
@@ -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 <vector>
#include <array>
#include <memory>

template <typename PoolObjT>
class CDynamicPoolPart
{
public:
explicit CDynamicPoolPart(std::size_t size) : m_size{size}
{
m_items = std::make_unique<PoolObjT[]>(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<PoolObjT[]> m_items;
std::vector<std::size_t> m_unusedIndices;
const std::size_t m_size;
};

template <std::size_t InitialSize, std::size_t AddSize>
struct PoolGrowAddStrategy
{
static constexpr std::size_t GetInitialSize() { return InitialSize; }
static constexpr std::size_t GetNextSize(std::size_t index) { return AddSize; }
};

template <typename PoolObjT, typename GrowStrategy>
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<PoolObjT>& AllocateNewPart()
{
const std::size_t nextSize = GrowStrategy::GetNextSize(m_poolParts.size());
m_poolParts.emplace_back(nextSize);
return m_poolParts.back();
}

private:
std::list<CDynamicPoolPart<PoolObjT>> m_poolParts;
};
2 changes: 2 additions & 0 deletions Client/game_sa/CGameSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include "CIplStoreSA.h"
#include "CBuildingRemovalSA.h"
#include "CCheckpointSA.h"
#include "CPtrNodeSingleLinkPoolSA.h"

extern CGameSA* pGame;

Expand Down Expand Up @@ -245,6 +246,7 @@ CGameSA::CGameSA()
CVehicleSA::StaticSetHooks();
CCheckpointSA::StaticSetHooks();
CHudSA::StaticSetHooks();
CPtrNodeSingleLinkPoolSA::StaticSetHooks();
}
catch (const std::bad_alloc& e)
{
Expand Down
7 changes: 2 additions & 5 deletions Client/game_sa/CPoolsSA.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down
3 changes: 3 additions & 0 deletions Client/game_sa/CPoolsSA.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "CBuildingsPoolSA.h"
#include "CDummyPoolSA.h"
#include "CTxdPoolSA.h"
#include "CPtrNodeSingleLinkPoolSA.h"

#define INVALID_POOL_ARRAY_ID 0xFFFFFFFF

Expand Down Expand Up @@ -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
Expand All @@ -111,6 +113,7 @@ class CPoolsSA : public CPools
CBuildingsPoolSA m_BuildingsPool;
CDummyPoolSA m_DummyPool;
CTxdPoolSA m_TxdPool;
CPtrNodeSingleLinkPoolSA m_PtrNodeSingleLinkPool;

bool m_bGetVehicleEnabled;
};
Expand Down
68 changes: 68 additions & 0 deletions Client/game_sa/CPtrNodeSingleLinkPoolSA.cpp
Original file line number Diff line number Diff line change
@@ -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);
}

37 changes: 37 additions & 0 deletions Client/game_sa/CPtrNodeSingleLinkPoolSA.h
Original file line number Diff line number Diff line change
@@ -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 <game/CPtrNodeSingleLinkPool.h>

class CPtrNodeSingleLinkPoolSA final : public CPtrNodeSingleLinkPool
{
public:
using pool_item_t = CPtrNodeSingleLink<void*>;
using pool_t = CDynamicPool<pool_item_t, PoolGrowAddStrategy<MAX_POINTER_SINGLE_LINKS, MAX_POINTER_SINGLE_LINKS / 2>>;

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;
};
Loading

0 comments on commit 40831e7

Please sign in to comment.