feat(network): add more stuff

This commit is contained in:
maybegreat48 2025-03-16 10:34:14 -04:00
parent b4a83aac3b
commit 4b11be70ef
41 changed files with 557 additions and 12 deletions

View File

@ -9,7 +9,7 @@
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "msvc_x64_x64" ]
"inheritEnvironments": [ "msvc_x64_x64" ],
},
{
"name": "x64-Release-Clang",
@ -20,7 +20,9 @@
"cmakeCommandArgs": "",
"buildCommandArgs": "",
"ctestCommandArgs": "",
"inheritEnvironments": [ "clang_cl_x64_x64" ]
"inheritEnvironments": [ "clang_cl_x64_x64" ],
"enableClangTidyCodeAnalysis": true,
"clangTidyChecks": "clang-analyzer-*"
}
]
}

View File

@ -0,0 +1,35 @@
#include "PlayerCommand.hpp"
#include "game/backend/Players.hpp"
namespace YimMenu
{
PlayerAllCommand::PlayerAllCommand(std::string name, std::string label, std::string description, int num_args, PlayerCommand* parent) :
Command(name + "all", label, description, num_args),
m_PlayerCommand(parent)
{
}
void PlayerAllCommand::OnCall()
{
for (auto& p : Players::GetPlayers())
m_PlayerCommand->Call(p.second);
}
PlayerCommand::PlayerCommand(std::string name, std::string label, std::string description, int num_args, bool all_version) :
Command::Command(name, label, description, num_args + 1)
{
if (all_version)
m_AllCommand = std::make_unique<PlayerAllCommand>(name, label, description, num_args, this);
}
void PlayerCommand::OnCall()
{
LOG(WARNING) << GetName() << " requires a player argument";
}
void PlayerCommand::Call(Player target)
{
OnCall(target);
}
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "core/commands/Command.hpp"
#include "game/gta/Player.hpp"
namespace YimMenu
{
class PlayerCommand;
class PlayerAllCommand : public Command
{
PlayerCommand* m_PlayerCommand;
public:
PlayerAllCommand(std::string name, std::string label, std::string description, int num_args, PlayerCommand* parent);
virtual void OnCall() override;
};
class PlayerCommand : public Command
{
virtual void OnCall() override;
std::unique_ptr<PlayerAllCommand> m_AllCommand;
protected:
virtual void OnCall(Player) = 0;
public:
PlayerCommand(std::string name, std::string label, std::string description, int num_args = 0, bool all_version = true);
void Call(Player target); // TODO
};
}

View File

@ -0,0 +1,17 @@
#include "game/commands/PlayerCommand.hpp"
#include "types/fx/ExplosionType.hpp"
namespace YimMenu::Features
{
class Explode : public PlayerCommand
{
using PlayerCommand::PlayerCommand;
virtual void OnCall(Player player) override
{
player.GetPed().Explode(ExplosionType::ORBITAL_CANNON, 900.f);
}
};
static Explode _Explode{"explode", "Explode", "Blows the player up"};
}

View File

@ -8,6 +8,7 @@
#include "game/frontend/fonts/Fonts.hpp"
#include "game/pointers/Pointers.hpp"
#include "submenus/Self.hpp"
#include "submenus/Network.hpp"
#include "submenus/Players.hpp"
namespace YimMenu
@ -16,6 +17,7 @@ namespace YimMenu
{
// Arguably the only place this file should be edited at for more menus
UIManager::AddSubmenu(std::make_shared<Submenus::Self>());
UIManager::AddSubmenu(std::make_shared<Submenus::Network>());
UIManager::AddSubmenu(std::make_shared<Submenus::Players>());
Renderer::AddRendererCallBack(

View File

@ -1,10 +1,9 @@
#include "Items.hpp"
//#include "game/commands/PlayerCommand.hpp"
#include "game/commands/PlayerCommand.hpp"
#include "core/commands/Commands.hpp"
//#include "game/backend/FiberPool.hpp"
//#include "game/backend/Players.hpp"
#include "core/backend/FiberPool.hpp"
#include "game/backend/Players.hpp"
#if 0
namespace YimMenu
{
PlayerCommandItem::PlayerCommandItem(joaat_t id, std::optional<std::string> label_override) :
@ -31,8 +30,7 @@ namespace YimMenu
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip(m_Command->GetDescription().data());
ImGui::SetTooltip("%s", m_Command->GetDescription().data());
}
}
}
#endif
}

View File

@ -0,0 +1,19 @@
#include "Network.hpp"
#include "game/frontend/items/Items.hpp"
namespace YimMenu::Submenus
{
Network::Network() :
Submenu::Submenu("Network")
{
// TODO: this needs a rework
auto session = std::make_shared<Category>("Session");
auto toxicGroup = std::make_shared<Group>("Toxic");
toxicGroup->AddItem(std::make_shared<CommandItem>("explodeall"_J, "Explode All"));
session->AddItem(toxicGroup);
AddCategory(std::move(session));
}
}

View File

@ -0,0 +1,11 @@
#pragma once
#include "core/frontend/manager/UIManager.hpp"
namespace YimMenu::Submenus
{
class Network : public Submenu
{
public:
Network();
};
}

View File

@ -32,6 +32,9 @@ namespace YimMenu::Submenus
playerOptionsGroup->AddItem(std::make_shared<ImGuiItem>([] {
if (Players::GetSelected().IsValid())
{
ImGui::Text("Rank: %d (%d RP)", Players::GetSelected().GetRank(), Players::GetSelected().GetRank());
ImGui::Text("Money: %d", Players::GetSelected().GetMoney());
if (Players::GetSelected().GetPed())
{
auto health = Players::GetSelected().GetPed().GetHealth();

View File

@ -0,0 +1,17 @@
#include "Toxic.hpp"
namespace YimMenu::Submenus
{
std::shared_ptr<Category> BuildToxicMenu()
{
auto menu = std::make_shared<Category>("Toxic");
auto general = std::make_shared<Group>("General");
// general->AddItem(std::make_shared<PlayerCommandItem>("kill"_J));
general->AddItem(std::make_shared<PlayerCommandItem>("explode"_J));
menu->AddItem(general);
return menu;
}
}

View File

@ -0,0 +1,8 @@
#pragma once
#include "core/frontend/manager/Category.hpp"
#include "game/frontend/items/Items.hpp"
namespace YimMenu::Submenus
{
std::shared_ptr<Category> BuildToxicMenu();
}

View File

@ -1,6 +1,7 @@
#include "Players.hpp"
#include "Player/Info.hpp"
#include "Player/Toxic.hpp"
#include "core/frontend/widgets/imgui_colors.h"
#include "game/backend/PlayerData.hpp"
#include "game/backend/Players.hpp"
@ -114,6 +115,7 @@ namespace YimMenu::Submenus
Submenu::Submenu("Players")
{
AddCategory(std::move(BuildInfoMenu()));
AddCategory(std::move(BuildToxicMenu()));
for (auto& category : m_Categories)
category->PrependItem(std::make_shared<ImGuiItem>([] {

View File

@ -4,6 +4,7 @@
#include "core/util/Joaat.hpp"
#include "game/pointers/Pointers.hpp"
#include "types/rage/tlsContext.hpp"
#include "game/gta/Scripts.hpp"
namespace YimMenu
{
@ -391,6 +392,21 @@ namespace YimMenu
return INTERIOR::GET_INTERIOR_FROM_ENTITY(GetHandle()) != 0;
}
void Entity::Explode(ExplosionType explosion, float damage, bool is_visible, bool is_audible, float camera_shake)
{
ENTITY_ASSERT_VALID();
ENTITY_ASSERT_SCRIPT_CONTEXT();
if (!IsValid())
return;
auto pos = GetPosition();
Scripts::RunWithSpoofedThreadName("am_mp_orbital_cannon"_J, [&] {
// add_owned_explosion is more or less useless now
FIRE::ADD_EXPLOSION(pos.x, pos.y, pos.z, static_cast<int>(explosion), damage, is_audible, !is_visible, camera_shake, damage == 0.0f);
});
}
bool Entity::operator==(const Entity& other)
{
if (m_Handle != 0 && other.m_Handle != 0)

View File

@ -14,6 +14,8 @@
#define ENTITY_ASSERT_SCRIPT_CONTEXT()
#endif
enum class ExplosionType;
namespace rage
{
class netObject;
@ -141,6 +143,9 @@ namespace YimMenu
bool HasInterior();
// explosions
void Explode(ExplosionType explosion, float damage = 1.0f, bool is_visible = true, bool is_audible = true, float camera_shake = 1.0f);
bool operator==(const Entity& other);
bool operator!=(const Entity& other)
{

View File

@ -5,6 +5,8 @@
#include "types/network/rlGamerInfo.hpp"
#include "types/network/CNetGamePlayer.hpp"
#include "types/script/globals/GPBD_FM.hpp"
namespace YimMenu
{
Player::Player(uint8_t id)
@ -142,6 +144,39 @@ namespace YimMenu
return NETWORK::NETWORK_GET_AVERAGE_PACKET_LOSS(GetId());
}
int Player::GetRank()
{
if (!IsValid())
return 0;
if (auto fm = GPBD_FM::Get())
return fm->Entries[GetId()].PlayerStats.Rank;
return 0;
}
int Player::GetRP()
{
if (!IsValid())
return 0;
if (auto fm = GPBD_FM::Get())
return fm->Entries[GetId()].PlayerStats.RP;
return 0;
}
int Player::GetMoney()
{
if (!IsValid())
return 0;
if (auto fm = GPBD_FM::Get())
return fm->Entries[GetId()].PlayerStats.Money;
return 0;
}
void Player::SetVisibleLocally(bool visible)
{
if (!IsValid())

View File

@ -52,6 +52,10 @@ namespace YimMenu
float GetAverageLatency();
float GetAveragePacketLoss();
int GetRank();
int GetRP();
int GetMoney();
#if 0
// backend/data store (should be refactored?)
PlayerData& GetData();

View File

@ -7,4 +7,9 @@ namespace YimMenu
{
return Pointers.ScriptGlobals[m_Index >> 0x12 & 0x3F] + (m_Index & 0x3FFFF);
}
bool ScriptGlobal::CanAccess() const
{
return Pointers.ScriptGlobals && (m_Index >> 0x12 & 0x3F) < 0x40 && Pointers.ScriptGlobals[m_Index >> 0x12 & 0x3F];
}
}

View File

@ -36,6 +36,8 @@ namespace YimMenu
return *static_cast<std::add_pointer_t<std::remove_reference_t<T>>>(Get());
}
bool CanAccess() const;
private:
void* Get() const;

View File

@ -2,7 +2,9 @@
#include "game/pointers/Pointers.hpp"
#include "types/rage/atArray.hpp"
#include "types/rage/tlsContext.hpp"
#include "types/script/scrThread.hpp"
#include "types/script/GtaThread.hpp"
#include "types/script/CGameScriptHandler.hpp"
#include "types/script/CGameScriptId.hpp"
namespace YimMenu::Scripts
{
@ -30,4 +32,31 @@ namespace YimMenu::Scripts
rage::tlsContext::Get()->m_ScriptThreadActive = og_running_in_scrthread;
rage::tlsContext::Get()->m_CurrentScriptThread = og_thread;
}
void RunWithSpoofedThreadName(std::uint32_t name, std::function<void()> callback)
{
if (auto thread = reinterpret_cast<GtaThread*>(rage::tlsContext::Get()->m_CurrentScriptThread))
{
auto hash_1 = thread->m_Context.m_ScriptHash;
auto hash_2 = thread->m_ScriptHash;
auto hash_3 = thread->m_ScriptHash2;
std::optional<std::uint32_t> hash_4;
if (auto handler = thread->m_ScriptHandler)
hash_4 = handler->GetId()->m_Hash;
thread->m_Context.m_ScriptHash = name;
thread->m_ScriptHash = name;
thread->m_ScriptHash2 = name;
if (hash_4)
thread->m_ScriptHandler->GetId()->m_Hash = name;
callback();
thread->m_Context.m_ScriptHash = hash_1;
thread->m_ScriptHash = hash_2;
thread->m_ScriptHash2 = hash_3;
if (hash_4)
thread->m_ScriptHandler->GetId()->m_Hash = *hash_4;
}
}
}

View File

@ -10,6 +10,6 @@ namespace rage
namespace YimMenu::Scripts
{
extern rage::scrThread* FindScriptThread(joaat_t hash);
// extern rage::scrProgram* FindScriptProgram(joaat_t hash);
extern void RunAsScript(rage::scrThread* thread, std::function<void()> callback);
extern void RunWithSpoofedThreadName(std::uint32_t name, std::function<void()> callback); // consider using RunAsScript if possible
}

View File

@ -3,6 +3,11 @@
class CNetworkPlayerMgr;
class CNetGamePlayer;
namespace rage
{
class netConnectionManager;
class netEvent;
}
namespace YimMenu::Hooks
{
@ -10,7 +15,6 @@ namespace YimMenu::Hooks
{
constexpr auto VMTPresentIdx = 8;
constexpr auto VMTResizeBuffersIdx = 13;
constexpr auto VMTSize = 19;
extern HRESULT Present(IDXGISwapChain* that, UINT syncInterval, UINT flags);
extern HRESULT ResizeBuffers(IDXGISwapChain* that, UINT bufferCount, UINT width, UINT height, DXGI_FORMAT newFormat, UINT swapChainFlags);
}

View File

@ -83,6 +83,11 @@ namespace YimMenu
AssignPhysicalIndex = ptr.Sub(0x13).As<PVOID>();
});
constexpr auto scriptGlobalsPtrn = Pattern<"48 8B 8E B8 00 00 00 48 8D 15 ? ? ? ? 49 89 D8">("ScriptGlobals");
scanner.Add(scriptGlobalsPtrn, [this](PointerCalculator ptr) {
ScriptGlobals = ptr.Add(7).Add(3).Rip().As<std::int64_t**>();
});
if (!scanner.Scan())
{
LOG(FATAL) << "Some patterns could not be found, unloading.";

View File

@ -0,0 +1,90 @@
#pragma once
enum class ExplosionType
{
DONTCARE = -1,
GRENADE,
GRENADELAUNCHER,
STICKYBOMB,
MOLOTOV,
ROCKET,
TANKSHELL,
HI_OCTANE,
CAR,
PLANE,
PETROL_PUMP,
BIKE,
DIR_STEAM,
DIR_FLAME,
DIR_WATER_HYDRANT,
DIR_GAS_CANISTER,
BOAT,
SHIP_DESTROY,
TRUCK,
BULLET,
SMOKEGRENADELAUNCHER,
SMOKEGRENADE,
BZGAS,
FLARE,
GAS_CANISTER,
EXTINGUISHER,
PROGRAMMABLEAR,
TRAIN,
BARREL,
PROPANE,
BLIMP,
DIR_FLAME_EXPLODE,
TANKER,
PLANE_ROCKET,
VEHICLE_BULLET,
GAS_TANK,
BIRD_CRAP,
RAILGUN,
BLIMP2,
FIREWORK,
SNOWBALL,
PROXMINE,
VALKYRIE_CANNON,
AIR_DEFENCE,
PIPEBOMB,
VEHICLEMINE,
EXPLOSIVEAMMO,
APCSHELL,
BOMB_CLUSTER,
BOMB_GAS,
BOMB_INCENDIARY,
BOMB_STANDARD,
TORPEDO,
TORPEDO_UNDERWATER,
BOMBUSHKA_CANNON,
BOMB_CLUSTER_SECONDARY,
HUNTER_BARRAGE,
HUNTER_CANNON,
ROGUE_CANNON,
MINE_UNDERWATER,
ORBITAL_CANNON,
BOMB_STANDARD_WIDE,
EXPLOSIVEAMMO_SHOTGUN,
OPPRESSOR2_CANNON,
MORTAR_KINETIC,
VEHICLEMINE_KINETIC,
VEHICLEMINE_EMP,
VEHICLEMINE_SPIKE,
VEHICLEMINE_SLICK,
VEHICLEMINE_TAR,
SCRIPT_DRONE,
RAYGUN,
BURIEDMINE,
SCRIPT_MISSILE,
RCTANK_ROCKET,
BOMB_WATER,
BOMB_WATER_SECONDARY,
_0xF728C4A9,
_0xBAEC056F,
FLASHGRENADE,
STUNGRENADE,
_0x763D3B3B,
SCRIPT_MISSILE_LARGE,
SUBMARINE_BIG,
EMPLAUNCHER_EMP
};

View File

@ -0,0 +1,32 @@
#pragma once
namespace rage
{
class netEvent
{
public:
enum class Type
{
ConnectionRequested = 0, // seems to be identical to rage::netConnection::InFrame
ConnectionError = 2,
ConnectionClosed = 3,
FrameReceived = 4, // rage::netConnection::InFrame
BandwidthExceeded = 6,
OutOfMemory = 7
};
virtual ~netEvent() = default;
virtual void Destroy() = 0;
virtual Type GetEventType() = 0;
virtual uint32_t _0x18() = 0;
std::uint32_t m_Timestamp; // 0x0008
char pad_0008[52]; // 0x000C
std::uint32_t m_MsgId; // 0x0040
std::uint32_t m_CxnId; // 0x0044
rage::netEvent* m_This; // 0x0048
uint32_t m_PeerId; // 0x0050
};
static_assert(sizeof(rage::netEvent) == 0x58);
}

View File

@ -0,0 +1,8 @@
#pragma once
#include "scriptHandler.hpp"
class CGameScriptHandler : public rage::scriptHandler
{
public:
// TODO
};

View File

@ -0,0 +1,12 @@
#pragma once
#include "scriptId.hpp"
class CGameScriptId : public rage::scriptId
{
public:
std::int32_t m_Timestamp; // 0x30
std::int32_t m_PositionHash; // 0x34
std::int32_t m_InstanceId; // 0x38
std::int32_t m_UniqueId; // 0x3C
};
static_assert(sizeof(CGameScriptId) == 0x40);

View File

@ -691,5 +691,7 @@ static_assert(sizeof(GPBD_FM_Entry) == 892 * 8);
struct GPBD_FM
{
SCR_ARRAY<GPBD_FM_Entry, 32> Entries;
static GPBD_FM* Get();
};
static_assert(sizeof(GPBD_FM) == 28545 * 8);

View File

@ -353,5 +353,7 @@ static_assert(sizeof(GBPD_FM_3_Entry) == 611 * 8);
struct GPBD_FM_3
{
SCR_ARRAY<GBPD_FM_3_Entry, 32> Entries;
static GPBD_FM_3* Get();
};
static_assert(sizeof(GPBD_FM_3) == 19553 * 8);

View File

@ -13,5 +13,7 @@ static_assert(sizeof(GPBD_KickingEntry) == 100 * 8);
struct GPBD_Kicking
{
SCR_ARRAY<GPBD_KickingEntry, 32> Entries;
static GPBD_Kicking* Get();
};
static_assert(sizeof(GPBD_Kicking) == 3201 * 8);

View File

@ -4,5 +4,7 @@
struct GPBD_MissionName
{
SCR_ARRAY<TEXT_LABEL_63, 32> MissionNames;
static GPBD_MissionName* Get();
};
static_assert(sizeof(GPBD_MissionName) == 513 * 8);

View File

@ -91,5 +91,7 @@ struct GSBD
NETWORK_INDEX IAATurretCameraVehicleId; // used by DDH act 1
uint64_t PAD_1399[97];
SCR_INT CayoPericoStrandedAnimalChoice;
static GSBD* Get();
};
static_assert(sizeof(GSBD) == 1498 * 8);

View File

@ -92,5 +92,7 @@ struct GSBD_BlockB
SCR_ARRAY<uint64_t, 32> CarMeetModShopSlotIndices;
SCR_ARRAY<uint64_t, 32> CarMeetModShopOccupiedGoons;
SCR_ARRAY<SCR_ARRAY<uint64_t, 3>, 32> CarMeetModShopOccupiedVehicleSlots;
static GSBD_BlockB* Get();
};
static_assert(sizeof(GSBD_BlockB) == 2156 * 8);

View File

@ -63,5 +63,7 @@ struct GSBD_FM
WEAPON_PICKUPS WeaponPickups;
BIKER_CONTRACTS_SERVER BikerContracts;
SCR_ARRAY<uint64_t, 32> DoubleActionCacheLocationRevealed;
static GSBD_FM* Get();
};
static_assert(sizeof(GSBD_FM) == 648 * 8);

View File

@ -4,5 +4,7 @@
struct GSBD_Kicking
{
SCR_ARRAY<uint64_t, 32> KickedPlayers;
static GSBD_Kicking* Get();
};
static_assert(sizeof(GSBD_Kicking) == 33 * 8);

View File

@ -7,5 +7,7 @@ struct GSBD_PropertyInstances
SCR_ARRAY<GAMER_HANDLE, 32> PropertyOwners;
uint64_t PAD_0417[14]; // unused
SCR_ARRAY<uint64_t, 32> PropertyOwnerInstances;
static GSBD_PropertyInstances* Get();
};
static_assert(sizeof(GSBD_PropertyInstances) == 464 * 8);

View File

@ -686,5 +686,7 @@ static_assert(sizeof(GlobalPlayerBDEntry) == 467 * 8);
struct GlobalPlayerBD
{
SCR_ARRAY<GlobalPlayerBDEntry, 32> Entries;
static GlobalPlayerBD* Get();
};
static_assert(sizeof(GlobalPlayerBD) == 14945 * 8);

View File

@ -0,0 +1,32 @@
#include "GlobalPlayerBD.hpp"
#include "GPBD_FM.hpp"
#include "GPBD_FM_3.hpp"
#include "GPBD_Kicking.hpp"
#include "GPBD_MissionName.hpp"
#include "GSBD.hpp"
#include "GSBD_BlockB.hpp"
#include "GSBD_FM.hpp"
#include "GSBD_Kicking.hpp"
#include "GSBD_PropertyInstances.hpp"
#include "g_AMC_playerBD.hpp"
#include "game/gta/ScriptGlobal.hpp"
#define DEFINE_GLOBAL_ACCESSOR(str, global) str* str::Get()\
{ \
auto glb = YimMenu::ScriptGlobal(global); \
if (!glb.CanAccess()) \
return nullptr; \
return glb.As<str*>(); \
}
DEFINE_GLOBAL_ACCESSOR(GlobalPlayerBD, 2657994);
DEFINE_GLOBAL_ACCESSOR(GPBD_FM, 1845270);
DEFINE_GLOBAL_ACCESSOR(GPBD_FM_3, 1887694);
DEFINE_GLOBAL_ACCESSOR(GPBD_Kicking, 1874328);
DEFINE_GLOBAL_ACCESSOR(GPBD_MissionName, 1873815);
DEFINE_GLOBAL_ACCESSOR(GSBD, 2648917);
DEFINE_GLOBAL_ACCESSOR(GSBD_BlockB, 2650415);
DEFINE_GLOBAL_ACCESSOR(GSBD_FM, 1835557);
DEFINE_GLOBAL_ACCESSOR(GSBD_Kicking, 1877529);
DEFINE_GLOBAL_ACCESSOR(GSBD_PropertyInstances, 1937699);
DEFINE_GLOBAL_ACCESSOR(g_AMC_playerBD, 2699624);

View File

@ -12,5 +12,7 @@ static_assert(sizeof(g_AMC_playerBD_Entry) == 251 * 8); // -> 251 in b812g9
struct g_AMC_playerBD
{
SCR_ARRAY<g_AMC_playerBD_Entry, 32> Entries;
static g_AMC_playerBD* Get();
};
static_assert(sizeof(g_AMC_playerBD) == 8033 * 8);

View File

@ -0,0 +1,31 @@
#pragma once
#include "scrThread.hpp"
#include "scriptId.hpp"
#include <cstdint>
#pragma pack(push, 1)
namespace rage
{
class scriptHandlerObject;
class scriptHandler
{
public:
virtual ~scriptHandler() = default; // 0 (0x00)
virtual bool _0x08() = 0; // 1 (0x08)
virtual void _0x10() = 0; // 2 (0x10)
virtual void CleanupObjects() = 0; // 3 (0x18)
virtual scriptId* _0x20() = 0; // 4 (0x20)
virtual scriptId* GetId() = 0; // 5 (0x28)
// TODO more fields
public:
// TODO
};
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "scriptIdBase.hpp"
namespace rage
{
class scriptId : public scriptIdBase
{
public:
std::uint32_t m_Hash; // 0x08
char m_Name[32]; // 0x0C
};
static_assert(sizeof(scriptId) == 0x30);
}

View File

@ -0,0 +1,57 @@
#pragma once
#include <cstdint>
namespace rage
{
class datBitBuffer;
class netLoggingInterface;
class scrThread;
class scriptIdBase
{
public:
virtual ~scriptIdBase() = default; // 0 (0x00)
// Assumes the script thread's identity.
virtual void Reset(scrThread*) {}; // 1 (0x08)
// Returns whether the hash of the script id is valid.
virtual bool IsValid() { return false; }; // 2 (0x10)
// Gets the hash of the script id.
virtual std::uint32_t* GetHash(std::uint32_t* out) { return 0; }; // 3 (0x18)
// Gets an unknown value from the script id.
virtual std::uint32_t* GetUniqueId(std::uint32_t* out) { return 0; }; // 4 (0x20)
// Gets the name of the script id. This function is not thread-safe and the resulting name must be copied out of the ptr immediately
virtual const char* GetDebugName() { return nullptr; }; // 5 (0x28)
// Serializes the script id from the buffer.
virtual void Deserialize(datBitBuffer* buffer) {}; // 6 (0x30)
// Serializes the script id to the buffer.
virtual void Serialize(datBitBuffer* buffer) {}; // 7 (0x38)
// Calculates some information with the position hash & instance id.
virtual std::uint32_t GetSize() { return 0; }; // 8 (0x40)
// Calls _0x40 and returns it's value added to another value.
virtual std::uint32_t GetSizeWithHeader() { return 0; }; // 9 (0x48)
// Logs some information about the script id.
virtual void LogInfo(netLoggingInterface* logger) {}; // 10 (0x50)
// Copies the information of other to this object.
virtual void CopyData(scriptIdBase* other) {} // 11 (0x58)
// Returns whether the other script id is equal.
virtual bool operator==(scriptIdBase*) { return false; }; // 12 (0x60)
// Populates the script name from the hash
virtual void PopulateScriptName() {}; // 13 (0x68)
// return this->IsValid() && this->m_Hash == other->m_Hash;
virtual bool IsHandlerForSameScript(scriptIdBase* other) { return false; }; // 14 (0x70)
};
}