From 4bca0f32b1bf5731a8c02ead9ff7a6cc98d5a319 Mon Sep 17 00:00:00 2001 From: gir489 Date: Thu, 12 Mar 2020 02:41:46 -0400 Subject: [PATCH] Added proper atArray implementation. --- BigBaseV2/src/gta/array.hpp | 209 ++++++++++++++++++++------ BigBaseV2/src/gta/sysMemAllocator.hpp | 72 +++++++++ 2 files changed, 231 insertions(+), 50 deletions(-) create mode 100644 BigBaseV2/src/gta/sysMemAllocator.hpp diff --git a/BigBaseV2/src/gta/array.hpp b/BigBaseV2/src/gta/array.hpp index c39f15fa..4c4e77a7 100644 --- a/BigBaseV2/src/gta/array.hpp +++ b/BigBaseV2/src/gta/array.hpp @@ -1,65 +1,174 @@ #pragma once #include #include "fwddec.hpp" +#include "sysMemAllocator.hpp" namespace rage { - template - class atArray - { - public: - T *begin() - { - return m_data; - } + template + class atArray + { + public: + atArray() + { + m_data = nullptr; + m_count = 0; + m_size = 0; + } - T *end() - { - return m_data + m_size; - } + atArray(const atArray& right) + { + m_count = right.m_count; + m_size = right.m_size; - const T *begin() const - { - return m_data; - } + m_data = (T*)rage::GetAllocator()->allocate(m_size * sizeof(T), 16, 0); + std::uninitialized_copy(right.m_data, right.m_data + right.m_count, m_data); + } - const T *end() const - { - return m_data + m_size; - } + atArray(int capacity) + { + m_data = (T*)rage::GetAllocator()->allocate(capacity * sizeof(T), 16, 0); + m_count = 0; + m_size = capacity; + } - T *data() - { - return m_data; - } + void clear() + { + m_count = 0; + m_size = 0; - const T *data() const - { - return m_data; - } + if (m_data) + { + rage::GetAllocator()->free(m_data); - std::uint16_t size() const - { - return m_size; - } + m_data = nullptr; + } + } - std::uint16_t capacity() const - { - return m_capacity; - } + void append(const std::initializer_list value_array) + { + auto value_array_size = value_array.size(); + auto old_capacity = m_count; - T &operator[](std::uint16_t index) - { - return m_data[index]; - } + if ((value_array_size + m_count) > std::numeric_limits::max()) + LOG(FATAL) << "RAGE atArray was given too large of a list to append"; - const T &operator[](std::uint16_t index) const - { - return m_data[index]; - } - private: - T *m_data; - std::uint16_t m_size; - std::uint16_t m_capacity; - }; -} + auto size = (uint16_t)value_array_size; + expand(m_count + size); + m_size += size; + + auto i = old_capacity; + for (const T* it = value_array.begin(); it != value_array.end(); ++it) + { + m_data[i] = *it; + i++; + } + } + + void append(T value) + { + set(m_count, value); + } + + void set(uint16_t offset, const T& value) + { + if (offset >= m_count) + { + expand(offset + 1); + } + + if (offset >= m_size) + { + m_size = offset + 1; + } + + m_data[offset] = value; + } + + void expand(uint16_t newSize) + { + if (m_count >= newSize) + { + return; + } + + T* newOffset = (T*)rage::GetAllocator()->allocate(newSize * sizeof(T), 16, 0); + + // initialize the new entries + std::uninitialized_fill(newOffset, newOffset + newSize, T()); + + // copy the existing entries + if (m_data) + { + std::copy(m_data, m_data + m_size, newOffset); + + rage::GetAllocator()->free(m_data); + } + + m_data = newOffset; + m_count = newSize; + } + + T* begin() + { + return m_data; + } + + T* end() + { + return m_data + m_size; + } + + const T* begin() const + { + return m_data; + } + + const T* end() const + { + return m_data + m_size; + } + + T* data() + { + return m_data; + } + + const T* data() const + { + return m_data; + } + + std::uint16_t size() const + { + return m_size; + } + + std::uint16_t count() const + { + return m_count; + } + + T& operator[](std::uint16_t index) + { + return m_data[index]; + } + + friend std::ostream& operator<<(std::ostream& o, const atArray& j) + { + o << "Array Size: " << j.size() << std::endl; + for (T item : j) + o << "\tArray Item: " << item << " [" << HEX_TO_UPPER(item) << "]" << (j.end() == item) ? "" : std::endl; + return o; + } + + const T& operator[](std::uint16_t index) const + { + return m_data[index]; + } + private: + T* m_data; + std::uint16_t m_size; + std::uint16_t m_count; + }; +} \ No newline at end of file diff --git a/BigBaseV2/src/gta/sysMemAllocator.hpp b/BigBaseV2/src/gta/sysMemAllocator.hpp new file mode 100644 index 00000000..a63811b6 --- /dev/null +++ b/BigBaseV2/src/gta/sysMemAllocator.hpp @@ -0,0 +1,72 @@ +#pragma once +#include "fwddec.hpp" + +namespace rage +{ + class sysMemAllocator + { + public: + virtual ~sysMemAllocator() = 0; + + virtual void SetQuitOnFail(bool) = 0; + virtual void* Allocate(size_t size, size_t align, int subAllocator) = 0; + + inline void* allocate(size_t size, size_t align, int subAllocator) + { + return Allocate(size, align, subAllocator); + } + + virtual void* TryAllocate(size_t size, size_t align, int subAllocator) = 0; + + virtual void Free(void* pointer) = 0; + + virtual void free(void* pointer) + { + return Free(pointer); + } + + virtual void TryFree(void* pointer) = 0; + + virtual void Resize(void* pointer, size_t size) = 0; + + virtual sysMemAllocator* GetAllocator(int allocator) const = 0; + + virtual sysMemAllocator* GetAllocator(int allocator) = 0; + + virtual sysMemAllocator* GetPointerOwner(void* pointer) = 0; + + virtual size_t GetSize(void* pointer) const = 0; + + virtual size_t GetMemoryUsed(int memoryBucket) = 0; + + virtual size_t GetMemoryAvailable() = 0; + + public: + + static sysMemAllocator* sysMemAllocator::UpdateAllocatorValue() + { + //B9 ? ? ? ? 48 8B 0C 01 45 33 C9 49 8B D2 48 + auto g_gtaTlsEntry = *(sysMemAllocator**)(*(uintptr_t*)(__readgsqword(88)) + 0xC8); //This has been 0xC8 since 323, I'm not adding this signature to pointers... + + if (g_gtaTlsEntry == nullptr) + LOG(FATAL) << "Failed to find tlsEntry within GTA5.exe via __readgsqword"; + + *(sysMemAllocator**)(*(uintptr_t*)(__readgsqword(88)) + 0xC8) = g_gtaTlsEntry; + *(sysMemAllocator**)(*(uintptr_t*)(__readgsqword(88)) + 0xC8 - 8) = g_gtaTlsEntry; + + return g_gtaTlsEntry; + } + }; + + inline sysMemAllocator* GetAllocator() + { + sysMemAllocator* allocator = *(sysMemAllocator**)(*(uintptr_t*)(__readgsqword(88)) + 0xC8); + + if (!allocator) + { + return sysMemAllocator::UpdateAllocatorValue(); + } + + return allocator; + } +} \ No newline at end of file