TmpMenu/src/gta/natives.hpp

119 lines
3.2 KiB
C++
Raw Normal View History

2019-03-21 20:18:31 +01:00
#pragma once
#include "fwddec.hpp"
#include <cstdint>
#include <script/types.hpp>
#include <utility>
2019-03-21 20:18:31 +01:00
namespace rage
{
class scrNativeCallContext
{
public:
void reset()
{
m_arg_count = 0;
2019-03-21 20:18:31 +01:00
m_data_count = 0;
}
template<typename T>
void push_arg(T&& value)
2019-03-21 20:18:31 +01:00
{
static_assert(sizeof(T) <= sizeof(std::uint64_t));
*reinterpret_cast<std::remove_cv_t<std::remove_reference_t<T>>*>(reinterpret_cast<std::uint64_t*>(m_args) + (m_arg_count++)) = std::forward<T>(value);
}
template<typename T>
T& get_arg(std::size_t index)
2019-03-21 20:18:31 +01:00
{
static_assert(sizeof(T) <= sizeof(std::uint64_t));
return *reinterpret_cast<T*>(reinterpret_cast<std::uint64_t*>(m_args) + index);
}
template<typename T>
void set_arg(std::size_t index, T&& value)
2019-03-21 20:18:31 +01:00
{
static_assert(sizeof(T) <= sizeof(std::uint64_t));
*reinterpret_cast<std::remove_cv_t<std::remove_reference_t<T>>*>(reinterpret_cast<std::uint64_t*>(m_args) + index) = std::forward<T>(value);
}
template<typename T>
T* get_return_value()
2019-03-21 20:18:31 +01:00
{
return reinterpret_cast<T*>(m_return_value);
}
template<typename T>
void set_return_value(T&& value)
2019-03-21 20:18:31 +01:00
{
*reinterpret_cast<std::remove_cv_t<std::remove_reference_t<T>>*>(m_return_value) = std::forward<T>(value);
}
2022-12-30 02:09:33 +01:00
template<typename T>
2022-12-30 02:09:33 +01:00
void set_return_value(T& value)
{
*reinterpret_cast<std::remove_cv_t<std::remove_reference_t<T>>*>(m_return_value) = std::forward<T>(value);
}
2019-03-21 20:18:31 +01:00
protected:
void* m_return_value;
2019-03-21 20:18:31 +01:00
std::uint32_t m_arg_count;
void* m_args;
2019-03-21 20:18:31 +01:00
std::int32_t m_data_count;
std::uint32_t m_data[48];
};
static_assert(sizeof(scrNativeCallContext) == 0xE0);
using scrNativeHash = std::uint64_t;
2019-03-21 20:18:31 +01:00
using scrNativeMapping = std::pair<scrNativeHash, scrNativeHash>;
using scrNativeHandler = void (*)(scrNativeCallContext*);
2019-03-21 20:18:31 +01:00
class scrNativeRegistration
{
public:
uint64_t m_nextRegistration1;
uint64_t m_nextRegistration2;
void* m_handlers[7];
uint32_t m_numEntries1;
uint32_t m_numEntries2;
uint64_t m_hashes;
scrNativeRegistration* get_next_registration()
{
std::uintptr_t result;
auto nextReg = uintptr_t(&m_nextRegistration1);
auto newReg = nextReg ^ m_nextRegistration2;
auto charTableOfRegs = (char*)&result - nextReg;
for (auto i = 0; i < 3; i++)
{
*(DWORD*)&charTableOfRegs[nextReg] = static_cast<DWORD>(newReg) ^ *(DWORD*)nextReg;
nextReg += 4;
}
return reinterpret_cast<scrNativeRegistration*>(result);
}
std::uint32_t get_num_entries()
{
return static_cast<std::uint32_t>(((std::uintptr_t)&m_numEntries1) ^ m_numEntries1 ^ m_numEntries2);
}
std::uint64_t get_hash(std::uint32_t index)
{
auto nativeAddress = 16 * index + std::uintptr_t(&m_nextRegistration1) + 0x54;
std::uint64_t result;
auto charTableOfRegs = (char*)&result - nativeAddress;
auto addressIndex = nativeAddress ^ *(DWORD*)(nativeAddress + 8);
for (auto i = 0; i < 3; i++)
{
*(DWORD*)&charTableOfRegs[nativeAddress] = static_cast<DWORD>(addressIndex ^ *(DWORD*)(nativeAddress));
nativeAddress += 4;
}
return result;
}
};
2019-03-21 20:18:31 +01:00
#pragma pack(push, 1)
class scrNativeRegistrationTable
{
scrNativeRegistration* m_entries[0xFF];
2019-03-21 20:18:31 +01:00
std::uint32_t m_unk;
bool m_initialized;
};
#pragma pack(pop)
}