From 1ab0374b20ca3677062175d9b555260efe2d35ec Mon Sep 17 00:00:00 2001 From: maybegreat48 <96936658+maybegreat48@users.noreply.github.com> Date: Sat, 22 Mar 2025 16:09:21 -0400 Subject: [PATCH] feat: add more trolling stuff --- src/core/hooking/Hooking.cpp | 5 + src/game/backend/NodeHooks.cpp | 111 ++++ src/game/backend/NodeHooks.hpp | 85 +++ src/game/features/network/HarassPlayers.cpp | 106 ++++ src/game/features/network/SpamKillfeed.cpp | 59 ++ .../network/SpoofMatchmakingRegion.cpp | 44 ++ .../players/toxic/KillLoopExploit.cpp | 23 + src/game/frontend/submenus/Network.cpp | 12 + src/game/frontend/submenus/Player/Toxic.cpp | 3 +- src/game/gta/Entity.cpp | 46 +- src/game/gta/Entity.hpp | 9 +- src/game/gta/Nodes.cpp | 515 ++++++++++++++++++ src/game/gta/Nodes.hpp | 110 ++++ src/game/hooks/Hooks.hpp | 11 + src/game/hooks/Spoofing/IsNodeInScope.cpp | 14 + .../hooks/Spoofing/ShouldUseNodeCache.cpp | 14 + src/game/hooks/Spoofing/WriteNodeData.cpp | 29 + src/game/hooks/Spoofing/WriteSyncTree.cpp | 19 + src/game/pointers/Pointers.cpp | 31 ++ src/game/pointers/Pointers.hpp | 10 + src/types/entity/CDynamicEntity.hpp | 16 + src/types/entity/CEntity.hpp | 46 ++ src/types/entity/fwEntity.hpp | 111 ++++ src/types/network/netObject.hpp | 52 ++ .../network/sync/CProjectBaseSyncDataNode.hpp | 46 ++ .../network/sync/NodeCommonDataOperations.hpp | 23 + src/types/network/sync/netSyncDataNode.hpp | 21 + src/types/network/sync/netSyncNodeBase.hpp | 38 ++ src/types/network/sync/netSyncTree.hpp | 24 + .../network/sync/nodes/CPedComponents.hpp | 44 ++ .../automobile/CAutomobileCreationNode.hpp | 10 + .../sync/nodes/door/CDoorCreationDataNode.hpp | 16 + .../sync/nodes/door/CDoorMovementDataNode.hpp | 15 + .../door/CDoorScriptGameStateDataNode.hpp | 16 + .../nodes/door/CDoorScriptInfoDataNode.hpp | 17 + .../CDynamicEntityGameStateDataNode.hpp | 22 + .../entity/CEntityOrientationDataNode.hpp | 13 + .../entity/CEntityScriptGameStateDataNode.hpp | 10 + .../entity/CEntityScriptInfoDataNode.hpp | 11 + .../sync/nodes/heli/CHeliControlDataNode.hpp | 25 + .../sync/nodes/heli/CHeliHealthDataNode.hpp | 25 + .../nodes/object/CObjectCreationDataNode.hpp | 45 ++ .../network/sync/nodes/ped/CPedAIDataNode.hpp | 11 + .../sync/nodes/ped/CPedAppearanceDataNode.hpp | 33 ++ .../sync/nodes/ped/CPedAttachDataNode.hpp | 20 + .../ped/CPedComponentReservationDataNode.hpp | 11 + .../sync/nodes/ped/CPedCreationDataNode.hpp | 26 + .../sync/nodes/ped/CPedGameStateDataNode.hpp | 76 +++ .../sync/nodes/ped/CPedHealthDataNode.hpp | 25 + .../sync/nodes/ped/CPedInventoryDataNode.hpp | 22 + .../sync/nodes/ped/CPedMovementDataNode.hpp | 15 + .../nodes/ped/CPedMovementGroupDataNode.hpp | 22 + .../nodes/ped/CPedOrientationDataNode.hpp | 12 + .../nodes/ped/CPedScriptCreationDataNode.hpp | 9 + .../nodes/ped/CPedTaskSequenceDataNode.hpp | 22 + .../nodes/ped/CPedTaskSpecificDataNode.hpp | 12 + .../sync/nodes/ped/CPedTaskTreeDataNode.hpp | 23 + .../physical/CPhysicalAngVelocityDataNode.hpp | 12 + .../physical/CPhysicalAttachDataNode.hpp | 27 + .../physical/CPhysicalGameStateDataNode.hpp | 17 + .../physical/CPhysicalHealthDataNode.hpp | 15 + .../physical/CPhysicalMigrationDataNode.hpp | 10 + .../CPhysicalScriptGameStateDataNode.hpp | 34 ++ .../CPhysicalScriptMigrationDataNode.hpp | 12 + .../physical/CPhysicalVelocityDataNode.hpp | 12 + .../nodes/pickup/CPickupCreationDataNode.hpp | 24 + .../CPickupPlacementCreationDataNode.hpp | 20 + .../CPlayerAmbientModelStreamingNode.hpp | 12 + .../player/CPlayerAppearanceDataNode.hpp | 91 ++++ .../nodes/player/CPlayerCameraDataNode.hpp | 25 + .../nodes/player/CPlayerCreationDataNode.hpp | 17 + .../player/CPlayerExtendedGameStateNode.hpp | 16 + .../nodes/player/CPlayerGameStateDataNode.hpp | 145 +++++ .../nodes/player/CPlayerGamerDataNode.hpp | 43 ++ .../nodes/player/CPlayerPedGroupDataNode.hpp | 31 ++ .../nodes/player/CPlayerSectorPosNode.hpp | 23 + .../player/CPlayerWantedAndLOSDataNode.hpp | 28 + .../CGlobalFlagsDataNode.hpp | 11 + .../CMigrationDataNode.hpp | 12 + .../proximity_migrateable/CSectorDataNode.hpp | 12 + .../CSectorPositionDataNode.hpp | 11 + .../nodes/task/CClonedGeneralSweepInfo.hpp | 23 + .../task/ClonedTakeOffPedVariationInfo.hpp | 35 ++ .../nodes/train/CTrainGameStateDataNode.hpp | 28 + .../CVehicleComponentReservationDataNode.hpp | 11 + .../nodes/vehicle/CVehicleControlDataNode.hpp | 39 ++ .../vehicle/CVehicleCreationDataNode.hpp | 19 + .../vehicle/CVehicleDamageStatusDataNode.hpp | 30 + .../nodes/vehicle/CVehicleGadgetDataNode.hpp | 35 ++ .../vehicle/CVehicleGameStateDataNode.hpp | 78 +++ .../nodes/vehicle/CVehicleHealthDataNode.hpp | 33 ++ .../CVehicleProximityMigrationDataNode.hpp | 19 + .../vehicle/CVehicleSteeringDataNode.hpp | 11 + .../nodes/vehicle/CVehicleTaskDataNode.hpp | 12 + src/types/rage/datBitBuffer.hpp | 228 ++++++++ src/types/rage/fwExtensibleBase.hpp | 15 + src/types/rage/fwExtension.hpp | 16 + src/types/rage/fwExtensionContainer.hpp | 14 + src/types/rage/fwRefAwareBase.hpp | 14 + src/types/rage/fwRefAwareBaseImpl.hpp | 11 + src/types/script/CGameScriptObjInfo.hpp | 13 + src/types/script/ScriptEvent.cpp | 2 +- 102 files changed, 3555 insertions(+), 32 deletions(-) create mode 100644 src/game/backend/NodeHooks.cpp create mode 100644 src/game/backend/NodeHooks.hpp create mode 100644 src/game/features/network/HarassPlayers.cpp create mode 100644 src/game/features/network/SpamKillfeed.cpp create mode 100644 src/game/features/network/SpoofMatchmakingRegion.cpp create mode 100644 src/game/features/players/toxic/KillLoopExploit.cpp create mode 100644 src/game/gta/Nodes.cpp create mode 100644 src/game/gta/Nodes.hpp create mode 100644 src/game/hooks/Spoofing/IsNodeInScope.cpp create mode 100644 src/game/hooks/Spoofing/ShouldUseNodeCache.cpp create mode 100644 src/game/hooks/Spoofing/WriteNodeData.cpp create mode 100644 src/game/hooks/Spoofing/WriteSyncTree.cpp create mode 100644 src/types/entity/CDynamicEntity.hpp create mode 100644 src/types/entity/CEntity.hpp create mode 100644 src/types/entity/fwEntity.hpp create mode 100644 src/types/network/netObject.hpp create mode 100644 src/types/network/sync/CProjectBaseSyncDataNode.hpp create mode 100644 src/types/network/sync/NodeCommonDataOperations.hpp create mode 100644 src/types/network/sync/netSyncDataNode.hpp create mode 100644 src/types/network/sync/netSyncNodeBase.hpp create mode 100644 src/types/network/sync/netSyncTree.hpp create mode 100644 src/types/network/sync/nodes/CPedComponents.hpp create mode 100644 src/types/network/sync/nodes/automobile/CAutomobileCreationNode.hpp create mode 100644 src/types/network/sync/nodes/door/CDoorCreationDataNode.hpp create mode 100644 src/types/network/sync/nodes/door/CDoorMovementDataNode.hpp create mode 100644 src/types/network/sync/nodes/door/CDoorScriptGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/door/CDoorScriptInfoDataNode.hpp create mode 100644 src/types/network/sync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/entity/CEntityOrientationDataNode.hpp create mode 100644 src/types/network/sync/nodes/entity/CEntityScriptGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/entity/CEntityScriptInfoDataNode.hpp create mode 100644 src/types/network/sync/nodes/heli/CHeliControlDataNode.hpp create mode 100644 src/types/network/sync/nodes/heli/CHeliHealthDataNode.hpp create mode 100644 src/types/network/sync/nodes/object/CObjectCreationDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedAIDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedAppearanceDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedAttachDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedComponentReservationDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedCreationDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedHealthDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedInventoryDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedMovementDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedMovementGroupDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedOrientationDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedScriptCreationDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedTaskSequenceDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedTaskSpecificDataNode.hpp create mode 100644 src/types/network/sync/nodes/ped/CPedTaskTreeDataNode.hpp create mode 100644 src/types/network/sync/nodes/physical/CPhysicalAngVelocityDataNode.hpp create mode 100644 src/types/network/sync/nodes/physical/CPhysicalAttachDataNode.hpp create mode 100644 src/types/network/sync/nodes/physical/CPhysicalGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/physical/CPhysicalHealthDataNode.hpp create mode 100644 src/types/network/sync/nodes/physical/CPhysicalMigrationDataNode.hpp create mode 100644 src/types/network/sync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp create mode 100644 src/types/network/sync/nodes/physical/CPhysicalVelocityDataNode.hpp create mode 100644 src/types/network/sync/nodes/pickup/CPickupCreationDataNode.hpp create mode 100644 src/types/network/sync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerAmbientModelStreamingNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerAppearanceDataNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerCameraDataNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerCreationDataNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerExtendedGameStateNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerGamerDataNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerPedGroupDataNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerSectorPosNode.hpp create mode 100644 src/types/network/sync/nodes/player/CPlayerWantedAndLOSDataNode.hpp create mode 100644 src/types/network/sync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp create mode 100644 src/types/network/sync/nodes/proximity_migrateable/CMigrationDataNode.hpp create mode 100644 src/types/network/sync/nodes/proximity_migrateable/CSectorDataNode.hpp create mode 100644 src/types/network/sync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp create mode 100644 src/types/network/sync/nodes/task/CClonedGeneralSweepInfo.hpp create mode 100644 src/types/network/sync/nodes/task/ClonedTakeOffPedVariationInfo.hpp create mode 100644 src/types/network/sync/nodes/train/CTrainGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleControlDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleCreationDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleGadgetDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleGameStateDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleHealthDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleSteeringDataNode.hpp create mode 100644 src/types/network/sync/nodes/vehicle/CVehicleTaskDataNode.hpp create mode 100644 src/types/rage/datBitBuffer.hpp create mode 100644 src/types/rage/fwExtensibleBase.hpp create mode 100644 src/types/rage/fwExtension.hpp create mode 100644 src/types/rage/fwExtensionContainer.hpp create mode 100644 src/types/rage/fwRefAwareBase.hpp create mode 100644 src/types/rage/fwRefAwareBaseImpl.hpp create mode 100644 src/types/script/CGameScriptObjInfo.hpp diff --git a/src/core/hooking/Hooking.cpp b/src/core/hooking/Hooking.cpp index 0930f41..571536c 100644 --- a/src/core/hooking/Hooking.cpp +++ b/src/core/hooking/Hooking.cpp @@ -20,6 +20,11 @@ namespace YimMenu BaseHook::Add(new DetourHook("InitNativeTables", Pointers.InitNativeTables, Hooks::Script::InitNativeTables)); BaseHook::Add(new DetourHook("AssignPhysicalIndex", Pointers.AssignPhysicalIndex, Hooks::Info::AssignPhysicalIndex)); + + BaseHook::Add(new DetourHook("IsNodeInScope", Pointers.IsNodeInScope, Hooks::Spoofing::IsNodeInScope)); + BaseHook::Add(new DetourHook("ShouldUseNodeCache", Pointers.ShouldUseNodeCache, Hooks::Spoofing::ShouldUseNodeCache)); + BaseHook::Add(new DetourHook("WriteNodeData", Pointers.WriteNodeData, Hooks::Spoofing::WriteNodeData)); + BaseHook::Add(new DetourHook("WriteSyncTree", Pointers.WriteSyncTree, Hooks::Spoofing::WriteSyncTree)); } Hooking::~Hooking() diff --git a/src/game/backend/NodeHooks.cpp b/src/game/backend/NodeHooks.cpp new file mode 100644 index 0000000..daeec03 --- /dev/null +++ b/src/game/backend/NodeHooks.cpp @@ -0,0 +1,111 @@ +#include "NodeHooks.hpp" + +namespace YimMenu +{ + NodeHooks::Hook::Hook(SyncNodeId node, std::function inScope, std::function modifyFunc, bool perPlayer, bool forceInScope) : + m_Node(node), + m_InScopeCallback(inScope), + m_Callback(modifyFunc), + m_PerPlayer(perPlayer), + m_ForceInScope(forceInScope), + m_Enabled(false) + { + } + + void NodeHooks::Hook::Enable() + { + m_Enabled = true; + } + + void NodeHooks::Hook::Disable() + { + m_Enabled = false; + } + + std::shared_ptr NodeHooks::TryGetHook(CProjectBaseSyncDataNode* node) + { + auto object = GetSyncingObject(); + + if (!Nodes::IsInitialized()) + return nullptr; + + auto& node_id = Nodes::Find(reinterpret_cast(node)); + + if (auto it = m_Hooks.find(node_id); + it != m_Hooks.end() && it->second->m_Enabled && it->second->m_InScopeCallback(object, it->second->m_PerPlayer ? GetSyncingPlayer() : nullptr)) + return it->second; + + return nullptr; + } + + rage::netObject* NodeHooks::GetSyncingObject() + { + std::lock_guard lock(m_Mutex); + if (auto it = m_SyncingObjects.find(GetCurrentThreadId()); it != m_SyncingObjects.end()) + return it->second; + + return nullptr; + } + + Player NodeHooks::GetSyncingPlayer() + { + std::lock_guard lock(m_Mutex); + if (auto it = m_SyncingPlayers.find(GetCurrentThreadId()); it != m_SyncingPlayers.end()) + return it->second; + + return nullptr; + } + + std::shared_ptr NodeHooks::AddHookImpl(SyncNodeId node, std::function inScope, std::function modifyFunc, bool perPlayer, bool forceInScope) + { + auto hook = std::make_shared(node, inScope, modifyFunc, perPlayer, forceInScope); + m_Hooks.emplace(node, std::move(hook)); + return m_Hooks[node]; + } + + bool NodeHooks::ShouldSkipNodeCacheImpl(CProjectBaseSyncDataNode* node) + { + if (auto hook = TryGetHook(node)) + return hook->m_PerPlayer && GetSyncingObject(); + + return false; + } + + bool NodeHooks::ShouldForceInScopeImpl(CProjectBaseSyncDataNode* node) + { + if (auto hook = TryGetHook(node)) + return hook->m_ForceInScope; + + return false; + } + + bool NodeHooks::ModifyNodeDataImpl(CProjectBaseSyncDataNode* node, rage::netObject* object) + { + SetSyncingObjectImpl(object); + if (auto hook = TryGetHook(node)) + { + hook->m_Callback(object, GetSyncingPlayer(), node); + return true; + } + + return false; + } + + void NodeHooks::SetSyncingObjectImpl(rage::netObject* object) + { + std::lock_guard lock(m_Mutex); + if (auto it = m_SyncingObjects.find(GetCurrentThreadId()); it != m_SyncingObjects.end()) + it->second = object; + else + m_SyncingObjects.emplace(GetCurrentThreadId(), object); + } + + void NodeHooks::SetSyncingPlayerImpl(Player player) + { + std::lock_guard lock(m_Mutex); + if (auto it = m_SyncingPlayers.find(GetCurrentThreadId()); it != m_SyncingPlayers.end()) + it->second = player; + else + m_SyncingPlayers.emplace(GetCurrentThreadId(), player); + } +} \ No newline at end of file diff --git a/src/game/backend/NodeHooks.hpp b/src/game/backend/NodeHooks.hpp new file mode 100644 index 0000000..1f0ddb5 --- /dev/null +++ b/src/game/backend/NodeHooks.hpp @@ -0,0 +1,85 @@ +#pragma once +#include "game/gta/Nodes.hpp" +#include "game/gta/Player.hpp" +#include "core/util/Joaat.hpp" + +class CProjectBaseSyncDataNode; + +namespace rage +{ + class scrProgram; +} + +namespace YimMenu +{ + class NodeHooks + { + public: + struct Hook + { + SyncNodeId m_Node; + std::function m_InScopeCallback; + std::function m_Callback; + bool m_PerPlayer; + bool m_ForceInScope; + bool m_Enabled; + + Hook(SyncNodeId node, std::function inScope, std::function modifyFunc, bool perPlayer = false, bool forceInScope = false); + void Enable(); + void Disable(); + }; + + static std::shared_ptr AddHook(SyncNodeId node, std::function inScope, std::function modifyFunc, bool perPlayer = false, bool forceInScope = false) + { + return GetInstance().AddHookImpl(node, inScope, modifyFunc, perPlayer, forceInScope); + } + + static bool ShouldSkipNodeCache(CProjectBaseSyncDataNode* node) + { + return GetInstance().ShouldSkipNodeCacheImpl(node); + } + + static bool ShouldForceInScope(CProjectBaseSyncDataNode* node) + { + return GetInstance().ShouldForceInScopeImpl(node); + } + + static bool ModifyNodeData(CProjectBaseSyncDataNode* node, rage::netObject* object) + { + return GetInstance().ModifyNodeDataImpl(node, object); + } + + static void SetSyncingObject(rage::netObject* object) + { + GetInstance().SetSyncingObjectImpl(object); + } + + static void SetSyncingPlayer(Player player) + { + GetInstance().SetSyncingPlayerImpl(player); + } + + private: + static NodeHooks& GetInstance() + { + static NodeHooks Instance; + return Instance; + } + + std::shared_ptr TryGetHook(CProjectBaseSyncDataNode* node); + rage::netObject* GetSyncingObject(); + Player GetSyncingPlayer(); + + std::shared_ptr AddHookImpl(SyncNodeId node, std::function inScope, std::function modifyFunc, bool perPlayer = false, bool forceInScope = false); + bool ShouldSkipNodeCacheImpl(CProjectBaseSyncDataNode* node); + bool ShouldForceInScopeImpl(CProjectBaseSyncDataNode* node); + bool ModifyNodeDataImpl(CProjectBaseSyncDataNode* node, rage::netObject* object); + void SetSyncingObjectImpl(rage::netObject* object); + void SetSyncingPlayerImpl(Player player); + + std::mutex m_Mutex; + std::unordered_map> m_Hooks; + std::unordered_map m_SyncingObjects; + std::unordered_map m_SyncingPlayers; + }; +} \ No newline at end of file diff --git a/src/game/features/network/HarassPlayers.cpp b/src/game/features/network/HarassPlayers.cpp new file mode 100644 index 0000000..e312088 --- /dev/null +++ b/src/game/features/network/HarassPlayers.cpp @@ -0,0 +1,106 @@ +#include "core/commands/BoolCommand.hpp" +#include "game/backend/NodeHooks.hpp" +#include "game/backend/Self.hpp" + +#include "types/network/sync/nodes/ped/CPedGameStateDataNode.hpp" +#include "types/network/sync/nodes/proximity_migrateable/CSectorDataNode.hpp" +#include "types/network/sync/nodes/player/CPlayerSectorPosNode.hpp" + +namespace YimMenu::Features +{ + class HarassPlayers : public BoolCommand + { + using BoolCommand::BoolCommand; + + std::shared_ptr m_PedGameStateHook; + std::shared_ptr m_SectorDataNodeHook; + std::shared_ptr m_PlayerSectorPosNodeHook; + + virtual void OnEnable() override + { + if (!m_PedGameStateHook) + { + m_PedGameStateHook = NodeHooks::AddHook( + "CPedGameStateDataNode", + [] (rage::netObject* object, Player target) + { + return object == Self::GetPed().GetNetworkObject(); + }, + [] (rage::netObject* object, Player target, CProjectBaseSyncDataNode* node) + { + auto ped_game_state = reinterpret_cast(node); + if (auto player_ped = target.GetPed(); player_ped && player_ped.GetNetworkObject()) + { + ped_game_state->m_VehicleId = *reinterpret_cast(reinterpret_cast<__int64>(player_ped.GetNetworkObject()) + 0x3D8); + ped_game_state->m_VehicleSeat = 2; + ped_game_state->m_InVehicle = true; + ped_game_state->m_InSeat = true; + } + }, true, true); + } + + if (!m_SectorDataNodeHook) + { + m_SectorDataNodeHook = NodeHooks::AddHook( + "CSectorDataNode", + [](rage::netObject* object, Player target) { + return object == Self::GetPed().GetNetworkObject(); + }, + [](rage::netObject* object, Player target, CProjectBaseSyncDataNode* node) { + auto sector_data = reinterpret_cast(node); + if (auto player_ped = target.GetPed()) + { + auto pos = player_ped.GetPosition(); + + sector_data->m_SectorX = int((pos.x / 54.0f) + 512.0f); + sector_data->m_SectorY = int((pos.y / 54.0f) + 512.0f); + sector_data->m_SectorZ = int((pos.z + 1700.0f) / 69.0f); + } + }, + true, + true); + } + + if (!m_PlayerSectorPosNodeHook) + { + m_PlayerSectorPosNodeHook = NodeHooks::AddHook( + "CPlayerSectorPosNode", + [](rage::netObject* object, Player target) { + return object == Self::GetPed().GetNetworkObject(); + }, + [](rage::netObject* object, Player target, CProjectBaseSyncDataNode* node) { + auto sector_pos_data = reinterpret_cast(node); + if (auto player_ped = target.GetPed()) + { + auto pos = player_ped.GetPosition(); + + int sectorX = int((pos.x / 54.0f) + 512.0f); + int sectorY = int((pos.y / 54.0f) + 512.0f); + int sectorZ = int((pos.z + 1700.0f) / 69.0f); + + sector_pos_data->m_SectorPosX = pos.x - ((sectorX - 512.0f) * 54.0f); + sector_pos_data->m_SectorPosY = pos.y - ((sectorY - 512.0f) * 54.0f); + sector_pos_data->m_SectorPosZ = pos.z - ((sectorZ * 69.0f) - 1700.0f); + + sector_pos_data->m_IsStandingOnEntity = false; + } + }, + true, + true); + } + + m_PedGameStateHook->Enable(); + m_SectorDataNodeHook->Enable(); + m_PlayerSectorPosNodeHook->Enable(); + } + + virtual void OnDisable() override + { + m_PedGameStateHook->Disable(); + m_SectorDataNodeHook->Disable(); + m_PlayerSectorPosNodeHook->Disable(); + } + }; + + static HarassPlayers _HarassPlayers{"harassplayers", "Harass Players", "Spoofs your position to make it appear as if you're next to all the players in the session at all times. Use with caution"}; +} \ No newline at end of file diff --git a/src/game/features/network/SpamKillfeed.cpp b/src/game/features/network/SpamKillfeed.cpp new file mode 100644 index 0000000..5c8d0ea --- /dev/null +++ b/src/game/features/network/SpamKillfeed.cpp @@ -0,0 +1,59 @@ +#include "core/commands/BoolCommand.hpp" +#include "game/backend/NodeHooks.hpp" +#include "game/backend/Self.hpp" +#include "game/backend/Players.hpp" +#include "types/network/sync/nodes/ped/CPedHealthDataNode.hpp" + +namespace YimMenu::Features +{ + class SpamKillfeed : public BoolCommand + { + using BoolCommand::BoolCommand; + + std::shared_ptr m_PedHealthHook; + + virtual void OnEnable() override + { + if (!m_PedHealthHook) + { + m_PedHealthHook = NodeHooks::AddHook( + "CPedHealthDataNode", + [](rage::netObject* object, Player target) { + return object == Self::GetPed().GetNetworkObject(); + }, + [](rage::netObject* object, Player target, CProjectBaseSyncDataNode* node) { + auto ped_health = reinterpret_cast(node); + if (std::rand() % 2) + { + // dead + if (auto random = Players::GetRandom(); random.IsValid() && random.GetPed()) + ped_health->m_WeaponDamageEntity = random.GetPed().GetNetworkObjectId(); + ped_health->m_WeaponDamageHash = "WEAPON_EXPLOSION"_J; + ped_health->m_HasMaxHealth = false; + ped_health->m_HurtStarted = true; + ped_health->m_Health = 0; + ped_health->m_WeaponDamageComponent = 5; + } + else + { + // alive + ped_health->m_HasMaxHealth = true; + ped_health->m_Health = 100; + } + }, + true, + true); + } + + m_PedHealthHook->Enable(); + } + + virtual void OnDisable() override + { + if (m_PedHealthHook) + m_PedHealthHook->Disable(); + } + }; + + static SpamKillfeed _SpamKillfeed{"spamkillfeed", "Spam Killfeed", "Spams the killfeed of all players with fake kill entries. Use with caution"}; +} \ No newline at end of file diff --git a/src/game/features/network/SpoofMatchmakingRegion.cpp b/src/game/features/network/SpoofMatchmakingRegion.cpp new file mode 100644 index 0000000..f991b8e --- /dev/null +++ b/src/game/features/network/SpoofMatchmakingRegion.cpp @@ -0,0 +1,44 @@ +#include "core/commands/LoopedCommand.hpp" +#include "core/commands/ListCommand.hpp" +#include "game/pointers/Pointers.hpp" + +namespace YimMenu::Features +{ + static std::vector> g_RegionCodes = { + {0, "CIS"}, + {1, "South America"}, + {2, "US East"}, + {3, "Europe"}, + {4, "China"}, + {5, "Australia"}, + {6, "US West"}, + {7, "Japan"}, + {8, "Unknown"}, + }; + + static ListCommand _SpoofedRegion{"mmregion", "Matchmaking Region", "Matchmaking region to spoof to", g_RegionCodes, 0}; + + class SpoofMatchmakingRegion : public LoopedCommand + { + using LoopedCommand::LoopedCommand; + + int m_OldRegion; + + virtual void OnEnable() override + { + m_OldRegion = *Pointers.RegionCode; + } + + virtual void OnTick() override + { + *Pointers.RegionCode = _SpoofedRegion.GetState(); + } + + virtual void OnDisable() override + { + *Pointers.RegionCode = m_OldRegion; + } + }; + + static SpoofMatchmakingRegion _SpoofMatchmakingRegion{"spoofmmregion", "Spoof Matchmaking Region", "Change the region you matchmake in to the specified value"}; +} \ No newline at end of file diff --git a/src/game/features/players/toxic/KillLoopExploit.cpp b/src/game/features/players/toxic/KillLoopExploit.cpp new file mode 100644 index 0000000..555e074 --- /dev/null +++ b/src/game/features/players/toxic/KillLoopExploit.cpp @@ -0,0 +1,23 @@ +#include "game/commands/PlayerCommand.hpp" +#include "game/backend/Self.hpp" +#include "game/pointers/Pointers.hpp" + +namespace YimMenu::Features +{ + class KillLoopExploit : public PlayerCommand + { + using PlayerCommand::PlayerCommand; + + virtual void OnCall(Player player) override + { + if (auto ped = player.GetPed(); ped && Self::GetPed()) + { + auto pos = ped.GetPosition(); + auto self = Self::GetPed().GetPointer(); + Pointers.TriggerWeaponDamageEvent(self, ped.GetPointer(), &pos, 0, true, "WEAPON_TRANQUILIZER"_J, 9999.0f, 0, 0, (1 << 0) | (1 << 4) | (1 << 12) | (1 << 19), 0, 0, 0, false, false, false, false, nullptr); + } + } + }; + + static KillLoopExploit _KillLoopExploit{"killexploit", "Permadeath", "Forces player into permadeath that can only be fixed after a game restart"}; +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Network.cpp b/src/game/frontend/submenus/Network.cpp index 68a2a3c..f54db25 100644 --- a/src/game/frontend/submenus/Network.cpp +++ b/src/game/frontend/submenus/Network.cpp @@ -18,8 +18,11 @@ namespace YimMenu::Submenus bountyGroup->AddItem(std::make_shared("setbountyall"_J, "Set Bounties")); trollGroup->AddItem(std::make_shared("sendsextall"_J, "Send Sexts")); + trollGroup->AddItem(std::make_shared("harassplayers"_J)); + trollGroup->AddItem(std::make_shared("spamkillfeed"_J)); toxicGroup->AddItem(std::make_shared("killall"_J, "Kill All")); + toxicGroup->AddItem(std::make_shared("killexploitall"_J, "Permadeath All")); toxicGroup->AddItem(std::make_shared("explodeall"_J, "Explode All")); enhancements->AddItem(std::make_shared("fastjoin"_J)); @@ -28,7 +31,16 @@ namespace YimMenu::Submenus session->AddItem(trollGroup); session->AddItem(toxicGroup); session->AddItem(enhancements); + + auto spoofing = std::make_shared("Spoofing"); + auto matchmakingGroup = std::make_shared("Matchmaking"); + auto spoofMMRegion = std::make_shared("", 1); + spoofMMRegion->AddItem(std::make_shared("spoofmmregion"_J, "Spoof Region")); + spoofMMRegion->AddItem(std::make_shared("spoofmmregion"_J, std::make_shared("mmregion"_J, "##mmregion"))); + matchmakingGroup->AddItem(spoofMMRegion); + spoofing->AddItem(matchmakingGroup); AddCategory(std::move(session)); + AddCategory(std::move(spoofing)); } } \ No newline at end of file diff --git a/src/game/frontend/submenus/Player/Toxic.cpp b/src/game/frontend/submenus/Player/Toxic.cpp index 6b7d570..67157a1 100644 --- a/src/game/frontend/submenus/Player/Toxic.cpp +++ b/src/game/frontend/submenus/Player/Toxic.cpp @@ -6,8 +6,9 @@ namespace YimMenu::Submenus { auto menu = std::make_shared("Toxic"); - auto general = std::make_shared("General"); + auto general = std::make_shared("Damage", 1); general->AddItem(std::make_shared("kill"_J)); + general->AddItem(std::make_shared("killexploit"_J)); general->AddItem(std::make_shared("explode"_J)); menu->AddItem(general); diff --git a/src/game/gta/Entity.cpp b/src/game/gta/Entity.cpp index 19cf39b..d346404 100644 --- a/src/game/gta/Entity.cpp +++ b/src/game/gta/Entity.cpp @@ -4,6 +4,8 @@ #include "core/util/Joaat.hpp" #include "game/pointers/Pointers.hpp" #include "types/rage/tlsContext.hpp" +#include "types/entity/CDynamicEntity.hpp" +#include "types/network/netObject.hpp" #include "game/gta/Scripts.hpp" #include "types/ped/CPedFactory.hpp" @@ -33,12 +35,10 @@ namespace YimMenu if (!IsValid()) return; -#if 0 if (!HasControl()) { LOG(WARNING) << "HasControl() assertion failed for " << function_name; } -#endif } void Entity::AssertScriptContext(std::string_view function_name) @@ -66,34 +66,29 @@ namespace YimMenu bool Entity::IsPed() { ENTITY_ASSERT_VALID(); -#if 0 + if (auto ptr = GetPointer()) - return ptr->m_EntityType == 4; + return ptr->IsPed(); return false; -#endif - return ENTITY::IS_ENTITY_A_PED(GetHandle()); + } bool Entity::IsVehicle() { ENTITY_ASSERT_VALID(); -#if 0 + if (auto ptr = GetPointer()) - return ptr->m_EntityType == 3; + return ptr->IsVehicle(); return false; -#endif - return ENTITY::IS_ENTITY_A_VEHICLE(GetHandle()); } bool Entity::IsObject() { ENTITY_ASSERT_VALID(); -#if 0 + if (auto ptr = GetPointer()) - return ptr->m_EntityType == 5; + return ptr->IsObject(); return false; -#endif - return ENTITY::IS_ENTITY_AN_OBJECT(GetHandle()); } bool Entity::IsPlayer() @@ -217,7 +212,6 @@ namespace YimMenu #endif } -#if 0 bool Entity::IsNetworked() { return GetNetworkObject() != nullptr; @@ -248,16 +242,6 @@ namespace YimMenu return GetNetworkObject()->m_ObjectId; } - void Entity::ForceControl() - { - ENTITY_ASSERT_VALID(); - - if (!IsNetworked() || HasControl()) - return; - - (*Pointers.NetworkObjectMgr)->ChangeOwner(GetNetworkObject(), Pointers.NetworkPlayerMgr->m_LocalPlayer, 5, true); - } - void Entity::PreventMigration() { ENTITY_ASSERT_VALID(); @@ -274,10 +258,20 @@ namespace YimMenu return; } - NETWORK::PREVENT_NETWORK_ID_MIGRATION(NETWORK::PED_TO_NET(GetHandle())); NETWORK::NETWORK_DISABLE_PROXIMITY_MIGRATION(NETWORK::PED_TO_NET(GetHandle())); } +#if 0 + void Entity::ForceControl() + { + ENTITY_ASSERT_VALID(); + + if (!IsNetworked() || HasControl()) + return; + + (*Pointers.NetworkObjectMgr)->ChangeOwner(GetNetworkObject(), Pointers.NetworkPlayerMgr->m_LocalPlayer, 5, true); + } + void Entity::ForceSync(Player* for_player) { ENTITY_ASSERT_VALID(); diff --git a/src/game/gta/Entity.hpp b/src/game/gta/Entity.hpp index 4a14656..1814579 100644 --- a/src/game/gta/Entity.hpp +++ b/src/game/gta/Entity.hpp @@ -110,20 +110,21 @@ namespace YimMenu void SetFrozen(bool enabled); void Delete(); - bool HasControl(); - -#if 0 // networking bool IsNetworked(); + bool HasControl(); rage::netObject* GetNetworkObject(); int GetOwner(); // index because we want to avoid cyclic imports std::uint16_t GetNetworkObjectId(); + + void PreventMigration(); + +#if 0 /// /// WARNING: This function is potentially unstable when used on vehicles and horses. Use RequestControl instead /// void ForceControl(); - void PreventMigration(); /// /// Forces creation of a networked entity for a specified player or the entire session /// diff --git a/src/game/gta/Nodes.cpp b/src/game/gta/Nodes.cpp new file mode 100644 index 0000000..e1d4a7c --- /dev/null +++ b/src/game/gta/Nodes.cpp @@ -0,0 +1,515 @@ +#include "Nodes.hpp" +#include "game/pointers/Pointers.hpp" +#include "types/network/sync/netSyncTree.hpp" + +namespace YimMenu +{ + SyncNodeId& Nodes::FindImpl(uintptr_t addr) + { + return m_Finder.m_SyncNodeMap[addr]; + } + + void Nodes::InitImpl() + { + std::unordered_set vistedNodeIds; + for (int i = (int)rage::netObject::Type::AUTOMOBILE; i < (int)rage::netObject::Type::MAX; i++) + { + rage::netSyncTree* tree = Pointers.GetSyncTreeForType(nullptr, i); + + if (tree->m_ChildNodeCount != m_Finder.m_SyncTreeNodeIdsMap[i].size()) + { + LOG(FATAL) << "Cache nodes failed " << i << " " << tree->m_ChildNodeCount << " != " << m_Finder.m_SyncTreeNodeIdsMap[i].size(); + + throw std::runtime_error("Failed to cache nodes"); + } + + for (int j = 0; j < tree->m_ChildNodeCount; j++) + { + const uintptr_t addr = (uintptr_t)tree->m_ChildNodes[j]; + + const SyncNodeId node_id = m_Finder.m_SyncTreeNodeIdsMap[i][j]; + + m_Finder.m_SyncNodeMap.emplace(addr, node_id); + + if (!vistedNodeIds.contains(node_id)) + { + m_Finder.m_GlobalNodeIds.push_back(node_id); + vistedNodeIds.insert(node_id); + } + } + } + + m_Initialized = true; + } + + SyncNodeFinder::SyncNodeFinder() + { + m_SyncTreeNodeIdsMap = { + { + // AUTOMOBILE + { + {"CVehicleCreationDataNode"}, + {"CAutomobileCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CVehicleGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CVehicleScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CVehicleAppearanceDataNode"}, + {"CVehicleDamageStatusDataNode"}, + {"CVehicleComponentReservationDataNode"}, + {"CVehicleHealthDataNode"}, + {"CVehicleTaskDataNode"}, + + {"CSectorDataNode"}, + {"CSectorPositionDataNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CVehicleAngVelocityDataNode"}, + + {"CVehicleSteeringDataNode"}, + {"CVehicleControlDataNode"}, + {"CVehicleGadgetDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CVehicleProximityMigrationDataNode"}, + }, + // BIKE + { + {"CVehicleCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CVehicleGameStateDataNode"}, + {"CBikeGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CVehicleScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CVehicleAppearanceDataNode"}, + {"CVehicleDamageStatusDataNode"}, + {"CVehicleComponentReservationDataNode"}, + {"CVehicleHealthDataNode"}, + {"CVehicleTaskDataNode"}, + + {"CSectorDataNode"}, + {"CSectorPositionDataNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CVehicleAngVelocityDataNode"}, + + {"CVehicleSteeringDataNode"}, + {"CVehicleControlDataNode"}, + {"CVehicleGadgetDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CVehicleProximityMigrationDataNode"}, + }, + // BOAT + { + {"CVehicleCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CVehicleGameStateDataNode"}, + {"CBoatGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CVehicleScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CVehicleAppearanceDataNode"}, + {"CVehicleDamageStatusDataNode"}, + {"CVehicleComponentReservationDataNode"}, + {"CVehicleHealthDataNode"}, + {"CVehicleTaskDataNode"}, + + {"CSectorDataNode"}, + {"CSectorPositionDataNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CVehicleAngVelocityDataNode"}, + + {"CVehicleSteeringDataNode"}, + {"CVehicleControlDataNode"}, + {"CVehicleGadgetDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CVehicleProximityMigrationDataNode"}, + }, + // DOOR + { + {"CDoorCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDoorScriptInfoDataNode"}, + {"CDoorScriptGameStateDataNode"}, + + {"CDoorMovementDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + }, + // HELI + { + {"CVehicleCreationDataNode"}, + {"CAutomobileCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CVehicleGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CVehicleScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CVehicleAppearanceDataNode"}, + {"CVehicleDamageStatusDataNode"}, + {"CVehicleComponentReservationDataNode"}, + {"CVehicleHealthDataNode"}, + {"CVehicleTaskDataNode"}, + {"CHeliHealthDataNode"}, + + {"CSectorDataNode"}, + {"CSectorPositionDataNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CVehicleAngVelocityDataNode"}, + + {"CVehicleSteeringDataNode"}, + {"CVehicleControlDataNode"}, + {"CVehicleGadgetDataNode"}, + {"CHeliControlDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CVehicleProximityMigrationDataNode"}, + }, + // OBJECT + { + {"CObjectCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CObjectGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CObjectScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CPhysicalHealthDataNode"}, + + {"CSectorDataNode"}, + {"CObjectSectorPosNode"}, + {"CObjectOrientationNode"}, + {"CPhysicalVelocityDataNode"}, + {"CPhysicalAngVelocityDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + }, + // PED + { + {"CPedCreationDataNode"}, + {"CPedScriptCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CPedGameStateDataNode"}, + {"CPedComponentReservationDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CPedScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPedAttachDataNode"}, + {"CPedHealthDataNode"}, + {"CPedMovementGroupDataNode"}, + {"CPedAIDataNode"}, + {"CPedAppearanceDataNode"}, + + {"CPedOrientationDataNode"}, + {"CPedMovementDataNode"}, + + {"CPedTaskTreeDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + + {"CSectorDataNode"}, + {"CPedSectorPosMapNode"}, + {"CPedSectorPosNavMeshNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CPedInventoryDataNode"}, + {"CPedTaskSequenceDataNode"}, + }, + // PICKUP + { + {"CPickupCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + + {"CPickupScriptGameStateNode"}, + {"CPhysicalGameStateDataNode"}, + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + {"CPhysicalHealthDataNode"}, + + {"CPhysicalAttachDataNode"}, + + {"CSectorDataNode"}, + {"CPickupSectorPosNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CPhysicalAngVelocityDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + }, + // PICKUP_PLACEMENT + { + {"CPickupPlacementCreationDataNode"}, + {"CMigrationDataNode"}, + {"CGlobalFlagsDataNode"}, + {"CPickupPlacementStateDataNode"}, + }, + // PLANE + { + {"CVehicleCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CVehicleGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CVehicleScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CVehicleAppearanceDataNode"}, + {"CVehicleDamageStatusDataNode"}, + {"CVehicleComponentReservationDataNode"}, + {"CVehicleHealthDataNode"}, + {"CVehicleTaskDataNode"}, + {"CPlaneGameStateDataNode"}, + + {"CSectorDataNode"}, + {"CSectorPositionDataNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CVehicleAngVelocityDataNode"}, + + {"CVehicleSteeringDataNode"}, + {"CVehicleControlDataNode"}, + {"CVehicleGadgetDataNode"}, + {"CPlaneControlDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CVehicleProximityMigrationDataNode"}, + }, + // SUBMARINE + { + {"CVehicleCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CVehicleGameStateDataNode"}, + {"CSubmarineGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CVehicleScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CVehicleAppearanceDataNode"}, + {"CVehicleDamageStatusDataNode"}, + {"CVehicleComponentReservationDataNode"}, + {"CVehicleHealthDataNode"}, + {"CVehicleTaskDataNode"}, + + {"CSectorDataNode"}, + {"CSectorPositionDataNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CVehicleAngVelocityDataNode"}, + + {"CVehicleSteeringDataNode"}, + {"CVehicleControlDataNode"}, + {"CVehicleGadgetDataNode"}, + {"CSubmarineControlDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CVehicleProximityMigrationDataNode"}, + }, + // PLAYER + { + {"CPlayerCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CPedGameStateDataNode"}, + {"CPedComponentReservationDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPlayerGameStateDataNode"}, + + {"CPedAttachDataNode"}, + {"CPedHealthDataNode"}, + {"CPedMovementGroupDataNode"}, + {"CPedAIDataNode"}, + {"CPlayerAppearanceDataNode"}, + {"CPlayerPedGroupDataNode"}, + {"CPlayerAmbientModelStreamingNode"}, + {"CPlayerGamerDataNode"}, + {"CPlayerExtendedGameStateNode"}, + + {"CPedOrientationDataNode"}, + {"CPedMovementDataNode"}, + + {"CPedTaskTreeDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + {"CPedTaskSpecificDataNode"}, + + {"CSectorDataNode"}, + {"CPlayerSectorPosNode"}, + {"CPlayerCameraDataNode"}, + {"CPlayerWantedAndLOSDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + }, + // TRAILER + { + {"CVehicleCreationDataNode"}, + {"CAutomobileCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CVehicleGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CVehicleScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CVehicleAppearanceDataNode"}, + {"CVehicleDamageStatusDataNode"}, + {"CVehicleComponentReservationDataNode"}, + {"CVehicleHealthDataNode"}, + {"CVehicleTaskDataNode"}, + + {"CSectorDataNode"}, + {"CSectorPositionDataNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CVehicleAngVelocityDataNode"}, + + {"CVehicleSteeringDataNode"}, + {"CVehicleControlDataNode"}, + {"CVehicleGadgetDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CVehicleProximityMigrationDataNode"}, + }, + // TRAIN + { + {"CVehicleCreationDataNode"}, + + {"CGlobalFlagsDataNode"}, + {"CDynamicEntityGameStateDataNode"}, + {"CPhysicalGameStateDataNode"}, + {"CVehicleGameStateDataNode"}, + {"CTrainGameStateDataNode"}, + + {"CEntityScriptGameStateDataNode"}, + {"CPhysicalScriptGameStateDataNode"}, + {"CVehicleScriptGameStateDataNode"}, + {"CEntityScriptInfoDataNode"}, + + {"CPhysicalAttachDataNode"}, + {"CVehicleAppearanceDataNode"}, + {"CVehicleDamageStatusDataNode"}, + {"CVehicleComponentReservationDataNode"}, + {"CVehicleHealthDataNode"}, + {"CVehicleTaskDataNode"}, + + {"CSectorDataNode"}, + {"CSectorPositionDataNode"}, + {"CEntityOrientationDataNode"}, + {"CPhysicalVelocityDataNode"}, + {"CVehicleAngVelocityDataNode"}, + + {"CVehicleSteeringDataNode"}, + {"CVehicleControlDataNode"}, + {"CVehicleGadgetDataNode"}, + + {"CMigrationDataNode"}, + {"CPhysicalMigrationDataNode"}, + {"CPhysicalScriptMigrationDataNode"}, + {"CVehicleProximityMigrationDataNode"}, + }, + }, + }; + } +} \ No newline at end of file diff --git a/src/game/gta/Nodes.hpp b/src/game/gta/Nodes.hpp new file mode 100644 index 0000000..b79f2b5 --- /dev/null +++ b/src/game/gta/Nodes.hpp @@ -0,0 +1,110 @@ +#pragma once +#include "core/util/Joaat.hpp" +#include "types/network/netObject.hpp" + +// Credits to Aure7138 + +namespace YimMenu +{ + struct SyncNodeId + { + joaat_t id; + const char* name; + + constexpr SyncNodeId() + { + id = 0; + name = "INVALID NODE ID!"; + } + + template + constexpr SyncNodeId(char const (&pp)[N]) + { + id = Joaat(pp); + name = pp; + } + + // implicit conversion + constexpr operator joaat_t() const + { + return id; + } + }; + + // Sync Node Virtual Function Table address to all sync node identifiers that also have that vft address. + using SyncNodeVftToIds = std::unordered_map; + + // Sync Tree node array index to node identifier. + using SyncTreeNodeArrayIndexToNodeId = std::vector; + + struct SyncNodeFinder + { + static constexpr size_t sm_SyncTreeCount = size_t(rage::netObject::Type::MAX); + + SyncNodeVftToIds m_SyncNodeMap; + std::array m_SyncTreeNodeIdsMap; + std::vector m_GlobalNodeIds; + + SyncNodeFinder(); + }; + + class Nodes + { + private: + SyncNodeFinder m_Finder; + bool m_Initialized = false; + std::mutex m_InitMutex; + + SyncNodeId& FindImpl(uintptr_t addr); + void InitImpl(); + + static Nodes& GetInstance() + { + static Nodes Instance; + return Instance; + } + + public: + static void Init() + { + std::lock_guard guard(GetInstance().m_InitMutex); + if (!GetInstance().m_Initialized) + GetInstance().InitImpl(); + } + + static void Reset() + { + std::lock_guard guard(GetInstance().m_InitMutex); + GetInstance().m_Finder.m_SyncNodeMap = {}; + GetInstance().m_Finder.m_GlobalNodeIds = {}; + GetInstance().m_Initialized = false; + } + + static bool IsInitialized() + { + return GetInstance().m_Initialized; + } + + static SyncNodeId& Find(uintptr_t addr) + { + return GetInstance().FindImpl(addr); + } + + static std::vector& GetAllNodeIds() + { + return GetInstance().m_Finder.m_GlobalNodeIds; + } + }; +} + +namespace std +{ + template<> + struct hash + { + size_t operator()(const YimMenu::SyncNodeId& x) const + { + return x.id; + } + }; +} \ No newline at end of file diff --git a/src/game/hooks/Hooks.hpp b/src/game/hooks/Hooks.hpp index 9fe2b6c..ee5b829 100644 --- a/src/game/hooks/Hooks.hpp +++ b/src/game/hooks/Hooks.hpp @@ -3,11 +3,14 @@ class CNetworkPlayerMgr; class CNetGamePlayer; +class CProjectBaseSyncDataNode; namespace rage { class netConnectionManager; class netEvent; class scrProgram; + class netObject; + class datBitBuffer; } namespace YimMenu::Hooks @@ -31,6 +34,14 @@ namespace YimMenu::Hooks extern void InitNativeTables(rage::scrProgram* program); } + namespace Spoofing + { + extern void WriteNodeData(CProjectBaseSyncDataNode* node, rage::netObject* object, rage::datBitBuffer* buffer, void* logger, bool update); + extern bool ShouldUseNodeCache(void* node, int flags); + extern bool IsNodeInScope(void* node, void* a2, std::uint8_t playerId, int flags, unsigned int a5, int a6); + extern bool WriteSyncTree(void* tree, int type, int flags, rage::netObject* object, rage::datBitBuffer* buffer, int unk, void* a6, std::uint8_t player_id, void* a8); + } + namespace Window { extern LRESULT WndProc(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam); diff --git a/src/game/hooks/Spoofing/IsNodeInScope.cpp b/src/game/hooks/Spoofing/IsNodeInScope.cpp new file mode 100644 index 0000000..be1fb64 --- /dev/null +++ b/src/game/hooks/Spoofing/IsNodeInScope.cpp @@ -0,0 +1,14 @@ +#include "core/hooking/DetourHook.hpp" +#include "game/backend/NodeHooks.hpp" +#include "game/hooks/Hooks.hpp" + +namespace YimMenu::Hooks +{ + bool Hooks::Spoofing::IsNodeInScope(void* node, void* a2, std::uint8_t playerId, int flags, unsigned int a5, int a6) + { + if (NodeHooks::ShouldForceInScope(reinterpret_cast(node))) + return true; + + return BaseHook::Get>()->Original()(node, a2, playerId, flags, a5, a6); + } +} \ No newline at end of file diff --git a/src/game/hooks/Spoofing/ShouldUseNodeCache.cpp b/src/game/hooks/Spoofing/ShouldUseNodeCache.cpp new file mode 100644 index 0000000..122b6c2 --- /dev/null +++ b/src/game/hooks/Spoofing/ShouldUseNodeCache.cpp @@ -0,0 +1,14 @@ +#include "core/hooking/DetourHook.hpp" +#include "game/backend/NodeHooks.hpp" +#include "game/hooks/Hooks.hpp" + +namespace YimMenu::Hooks +{ + bool Hooks::Spoofing::ShouldUseNodeCache(void* node, int flags) + { + if (NodeHooks::ShouldSkipNodeCache(reinterpret_cast(node))) + return false; + + return BaseHook::Get>()->Original()(node, flags); + } +} \ No newline at end of file diff --git a/src/game/hooks/Spoofing/WriteNodeData.cpp b/src/game/hooks/Spoofing/WriteNodeData.cpp new file mode 100644 index 0000000..bfa3b7f --- /dev/null +++ b/src/game/hooks/Spoofing/WriteNodeData.cpp @@ -0,0 +1,29 @@ +#include "core/commands/BoolCommand.hpp" +#include "core/hooking/DetourHook.hpp" +#include "game/backend/NodeHooks.hpp" +#include "game/backend/Self.hpp" +#include "game/hooks/Hooks.hpp" +#include "game/gta/Nodes.hpp" + +#include "types/rage/datBitBuffer.hpp" + +namespace YimMenu::Hooks +{ + void Spoofing::WriteNodeData(CProjectBaseSyncDataNode* node, rage::netObject* object, rage::datBitBuffer* buffer, void* logger, bool update) + { + auto orig_buffer = *buffer; + bool node_dirty = false; + Nodes::Init(); + + BaseHook::Get>()->Original()(node, object, buffer, logger, update); + + if (NodeHooks::ModifyNodeData(node, object)) + node_dirty = true; + + if (node_dirty) + { + *buffer = orig_buffer; + BaseHook::Get>()->Original()(node, object, buffer, logger, false); + } + } +} \ No newline at end of file diff --git a/src/game/hooks/Spoofing/WriteSyncTree.cpp b/src/game/hooks/Spoofing/WriteSyncTree.cpp new file mode 100644 index 0000000..7aba47b --- /dev/null +++ b/src/game/hooks/Spoofing/WriteSyncTree.cpp @@ -0,0 +1,19 @@ +#include "core/hooking/DetourHook.hpp" +#include "game/backend/NodeHooks.hpp" +#include "game/hooks/Hooks.hpp" + +namespace YimMenu::Hooks +{ + bool Hooks::Spoofing::WriteSyncTree(void* tree, int type, int flags, rage::netObject* object, rage::datBitBuffer* buffer, int unk, void* a6, std::uint8_t player_id, void* a8) + { + NodeHooks::SetSyncingObject(object); + NodeHooks::SetSyncingPlayer(Player(player_id)); + + auto ret = BaseHook::Get>()->Original()(tree, type, flags, object, buffer, unk, a6, player_id, a8); + + NodeHooks::SetSyncingObject(nullptr); + NodeHooks::SetSyncingPlayer(nullptr); + + return ret; + } +} \ No newline at end of file diff --git a/src/game/pointers/Pointers.cpp b/src/game/pointers/Pointers.cpp index dba95bb..5d6851e 100644 --- a/src/game/pointers/Pointers.cpp +++ b/src/game/pointers/Pointers.cpp @@ -98,6 +98,37 @@ namespace YimMenu ScriptPrograms = ptr.Add(0x13).Add(3).Rip().Add(0xD8).As(); }); + constexpr auto regionCodePtrn = Pattern<"4C 8D 05 ? ? ? ? 48 89 F1 48 89 FA E8 ? ? ? ? 84 C0 74 3D">("RegionCode"); + scanner.Add(regionCodePtrn, [this](PointerCalculator ptr) { + RegionCode = ptr.Add(3).Rip().As(); + }); + + constexpr auto networkObjectMgrPtrn = Pattern<"41 83 7E FA 02 40 0F 9C C5 C1 E5 02">("NetworkObjectMgr&GetSyncTreeForType"); + scanner.Add(networkObjectMgrPtrn, [this](PointerCalculator ptr) { + NetworkObjectMgr = ptr.Add(0xC).Add(3).Rip().As(); + GetSyncTreeForType = ptr.Add(0x13).Add(1).Rip().As(); + }); + + constexpr auto writeNodeDataPtrn = Pattern<"48 8B 89 A8 00 00 00 48 8B 01 48 8B 40 10 48 FF E0">("WriteNodeData"); + scanner.Add(writeNodeDataPtrn, [this](PointerCalculator ptr) { + WriteNodeData = ptr.As(); + }); + + constexpr auto shouldUseNodeCachePtrn = Pattern<"83 FA 20 74 1D 48 89 CE">("ShouldUseNodeCache"); + scanner.Add(shouldUseNodeCachePtrn, [this](PointerCalculator ptr) { + ShouldUseNodeCache = ptr.Sub(5).As(); + }); + + constexpr auto isNodeInScopePtrn = Pattern<"41 83 F9 02 74 22 48 8B 06">("IsNodeInScope"); + scanner.Add(isNodeInScopePtrn, [this](PointerCalculator ptr) { + IsNodeInScope = ptr.Sub(0x26).As(); + }); + + constexpr auto writeSyncTreePtrn = Pattern<"4D 89 CD 45 89 C6 41 89 D7 48 89 CF 8B 05 ? ? ? ? 65 48 8B 0C 25 58 00 00 00">("WriteSyncTree"); + scanner.Add(writeSyncTreePtrn, [this](PointerCalculator ptr) { + WriteSyncTree = ptr.Sub(0x10).As(); + }); + if (!scanner.Scan()) { LOG(FATAL) << "Some patterns could not be found, unloading."; diff --git a/src/game/pointers/Pointers.hpp b/src/game/pointers/Pointers.hpp index e93e2ec..bcb4b69 100644 --- a/src/game/pointers/Pointers.hpp +++ b/src/game/pointers/Pointers.hpp @@ -10,10 +10,12 @@ namespace rage class atArray; class scrThread; class scrProgram; + class netSyncTree; } class CPedFactory; class CNetGamePlayer; class CEntity; +class CNetworkObjectMgr; namespace YimMenu { @@ -23,6 +25,7 @@ namespace YimMenu using PtrToHandle = int (*)(void* pointer); using GetNetPlayerFromPid = CNetGamePlayer* (*)(int id); using TriggerWeaponDamageEvent = void (*)(CEntity* source, CEntity* target, rage::fvector3* position, int hit_component, bool override_default_damage, int weapon_type, float override_damage, int tire_index, int suspension_index, int flags, uint32_t action_result_hash, int16_t action_result_id, int action_unk, bool hit_weapon, bool hit_weapon_ammo_attachment, bool silenced, bool unk, rage::fvector3* impact_direction); + using GetSyncTreeForType = rage::netSyncTree* (*)(void* netObjMgr, uint16_t type); } struct PointerData @@ -45,6 +48,13 @@ namespace YimMenu PVOID AssignPhysicalIndex; Functions::TriggerWeaponDamageEvent TriggerWeaponDamageEvent; rage::scrProgram** ScriptPrograms; + int* RegionCode; + Functions::GetSyncTreeForType GetSyncTreeForType; + CNetworkObjectMgr** NetworkObjectMgr; + PVOID WriteNodeData; + PVOID ShouldUseNodeCache; + PVOID IsNodeInScope; + PVOID WriteSyncTree; }; struct Pointers : PointerData diff --git a/src/types/entity/CDynamicEntity.hpp b/src/types/entity/CDynamicEntity.hpp new file mode 100644 index 0000000..ca0d4ac --- /dev/null +++ b/src/types/entity/CDynamicEntity.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "CEntity.hpp" + +namespace rage +{ + class netObject; +} + +class CDynamicEntity : public CEntity +{ +public: + class rage::netObject* m_NetObject; //0x00D0 + char gapD8[16]; + uint64_t qwordE8; +}; +static_assert(sizeof(CDynamicEntity) == 0xF0); \ No newline at end of file diff --git a/src/types/entity/CEntity.hpp b/src/types/entity/CEntity.hpp new file mode 100644 index 0000000..5e46a46 --- /dev/null +++ b/src/types/entity/CEntity.hpp @@ -0,0 +1,46 @@ +#pragma once + +#include "fwEntity.hpp" + +#include + +class CEntityDrawHandler; + +class CEntity : public rage::fwEntity +{ +public: + virtual void* _0x120() = 0; // implemented only by CPed + virtual void UpdatePositionImpl() = 0; // 0x128 + virtual void _0x130() = 0; + virtual void _0x138(void*) = 0; + virtual void _0x140() = 0; + virtual void _0x148(int) = 0; + virtual bool _0x150() = 0; + virtual CEntityDrawHandler* CreateDrawHandler() = 0; // 0x158 + virtual int GetTypeFlags() = 0; // 0x160 + virtual int GetTypeFlags2() = 0; // 0x168 + virtual bool _0x170() = 0; // implemented only by CPickup + virtual bool _0x178() = 0; + virtual void _0x180(bool) = 0; + virtual bool _0x188() = 0; + virtual bool _0x190() = 0; + virtual void ClearDecals() = 0; // 0x198 + virtual void GetModelBounds(rage::fvector3* bounds) = 0; // 0x1A0 + virtual void GetModelBounds2(rage::fvector3* bounds) = 0; // 0x1A8 + virtual float GetBoundingBoxSize() = 0; // 0x1B0 + virtual float _0x1B8(void*) = 0; + virtual float _0x1C0(void*) = 0; + virtual rage::fvector3* _0x1C8() = 0; + virtual rage::fvector3* GetCameraOffset() = 0; // 0x1D0 + virtual void GetCameraBasePosition(rage::fvector3* pos) = 0; // 0x1D8 + virtual bool _0x1E0() = 0; + virtual bool Update() = 0; // 0x1E8 always returns true + virtual bool _0x1F0() = 0; + virtual void Warp(rage::fvector3* pos, float heading, bool) = 0; // 0x1F8 + + uint32_t m_flags_3; //0x00C0 + uint32_t m_flags_4; //0x00C4 + uint32_t dwordC8; + uint32_t dwordCC; +}; +static_assert(sizeof(CEntity) == 0xD0); \ No newline at end of file diff --git a/src/types/entity/fwEntity.hpp b/src/types/entity/fwEntity.hpp new file mode 100644 index 0000000..913ad32 --- /dev/null +++ b/src/types/entity/fwEntity.hpp @@ -0,0 +1,111 @@ +#pragma once + + +#include "../rage/RTTI.hpp" +#include "../rage/fwExtensibleBase.hpp" +#include "../rage/vector.hpp" + +#include + +class CMoveObjectPooledObject; +class CNavigation; + +namespace rage +{ + class fwDynamicEntityComponent; + class crmtRequestPose; + class crmtRequestIk; + class crFrameFilter; + class fwAudEntity; + class fwDrawData; + + class fwEntity : public fwExtensibleBase + { + public: + DEFINE_RAGE_RTTI(rage::fwEntity); + + virtual void* _0x38(void*, void*) = 0; + virtual void AddExtension(void* extension) = 0; // 0x40 + virtual void _0x48() = 0; // not implemented + virtual void _0x50() = 0; // only implemented by CEntityBatch + virtual void _0x58() = 0; + virtual void SetModelInfo(std::uint16_t* model_index) = 0; // 0x60 + virtual void _0x68(int, vector4*) = 0; + virtual void* _0x70(int) = 0; + virtual CNavigation* GetNavigation() = 0; // 0x78 + virtual CMoveObjectPooledObject* CreateMoveObject() = 0; // 0x80 + virtual std::uint32_t* GetType() = 0; // 0x88 + virtual void _0x90() = 0; + virtual float _0x98() = 0; + virtual bool TryRequestInverseKinematics(rage::crmtRequestPose* pose, rage::crmtRequestIk* ik) = 0; // 0xA0 implemented only by CPed + virtual bool TryRequestFacialAnims(void*) = 0; // 0xA8 implemented only by CPed + virtual void* _0xB0() = 0; + virtual std::uint8_t _0xB8() = 0; // implemented only by CPed + virtual rage::crFrameFilter* GetFrameFilter() = 0; // 0xC0 + virtual rage::fwAudEntity* GetEntityAudio() = 0; // 0xC8 + virtual void _0xD0() = 0; + virtual void SetTransform(matrix44* matrix, bool update_pos) = 0; // 0xD8 + virtual void SetTransform2(matrix44* matrix, bool update_pos) = 0; // 0xE0 + virtual void SetPosition(fvector4* pos, bool update_pos) = 0; // 0xE8 + virtual void SetHeading(float heading, bool update_pos) = 0; // 0xF0 + virtual void SetEntityTypeFlags() = 0; // 0xF8 + virtual void _0x100() = 0; // not implemented + virtual void UpdatePhysics(CNavigation* navigation) = 0; // 0x108 + virtual void UpdatePhysics2(CNavigation* navigation) = 0; // 0x110 + virtual void UpdatePosition() = 0; // 0x118 + + enum class Flags + { + IS_VISIBLE = (1 << 0) + }; + + enum class Type : std::uint8_t + { + VEHICLE = 3, + PED, + OBJECT + }; + + class CBaseModelInfo* m_ModelInfo; //0x0020 + Type m_Type; //0x0028 + char gap29; //0x0029 + uint16_t gap2A; //0x002A + uint32_t m_Flags; //0x002D + class CNavigation* m_Navigation; //0x0030 + uint16_t gap38; //0x0038 + uint16_t gap3A; //0x003A + uint32_t gap3C; //0x003C + class rage::fwDynamicEntityComponent* m_DynamicEntityComponent; //0x0040 (stores attachments and stuff) + class rage::fwDrawData* m_DrawData; //0x0048 + class rage::fwDynamicEntityComponent* gap50; //0x0050 + uint64_t gap58; //0x0058 + matrix44 m_Transform; //0x0060 + rage::fwEntity* m_RenderFocusEntity; //0x00A0 + uint32_t m_RenderFocusDistance; //0x00A8 + uint32_t m_Flags2; //0x00AC + uint32_t m_ShadowFlags; //0x00B0 + char gapB4[4]; //0x00B4 + std::uint8_t byteB8; //0x00B8 + + rage::fvector3* GetPosition() + { + return reinterpret_cast(&m_Transform.rows[3]); + } + + bool IsVehicle() const + { + return m_Type == Type::VEHICLE; + } + + bool IsPed() const + { + return m_Type == Type::PED; + } + + bool IsObject() const + { + return m_Type == Type::OBJECT; + } + }; + static_assert(sizeof(fwEntity) == 0xC0); +} \ No newline at end of file diff --git a/src/types/network/netObject.hpp b/src/types/network/netObject.hpp new file mode 100644 index 0000000..1ec3346 --- /dev/null +++ b/src/types/network/netObject.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include "../rage/RTTI.hpp" +#include + +class CDynamicEntity; +namespace rage +{ + class netObject + { + public: + enum class Type : std::uint16_t + { + AUTOMOBILE, + BIKE, + BOAT, + DOOR, + HELI, + OBJECT, + PED, + PICKUP, + PICKUP_PLACEMENT, + PLANE, + SUBMARINE, + PLAYER, + TRAILER, + TRAIN, + GLASS_PANE, // new in Enhanced, but doesn't actually seem to have a sync tree associated with it + MAX = GLASS_PANE // for compatibility + }; + + Type m_ObjectType; //0x0008 + int16_t m_ObjectId; //0x000A + char pad_000C[61]; //0x000C + int8_t m_OwnerId; //0x0049 + int8_t m_NextOwnerId; //0x004A + bool m_IsRemote; //0x004B + uint16_t m_Flags; //0x004C + uint16_t m_Flags2; //0x004E + class CObject* m_GameObject; //0x0050 + char pad_0058[48]; //0x0058 + uint32_t m_OwnershipToken; //0x0088 + + DEFINE_RAGE_RTTI(rage::netObject); + + inline bool IsVehicle() const + { + return m_ObjectType == Type::AUTOMOBILE || m_ObjectType == Type::BIKE || m_ObjectType == Type::BOAT || m_ObjectType == Type::HELI || m_ObjectType == Type::PLANE || m_ObjectType == Type::SUBMARINE || m_ObjectType == Type::TRAILER; + } + }; //Size: 0x008C + static_assert(sizeof(netObject) == 0x90); +} \ No newline at end of file diff --git a/src/types/network/sync/CProjectBaseSyncDataNode.hpp b/src/types/network/sync/CProjectBaseSyncDataNode.hpp new file mode 100644 index 0000000..920c11a --- /dev/null +++ b/src/types/network/sync/CProjectBaseSyncDataNode.hpp @@ -0,0 +1,46 @@ +#pragma once +#include "netSyncDataNode.hpp" +#include "NodeCommonDataOperations.hpp" + +namespace rage +{ + class netSyncData; + class netObject; +} + +class CProjectBaseSyncDataNode : public rage::netSyncDataNode +{ +public: + virtual bool IsSyncNode() { return false; } // 0x50 + virtual bool _0x58() { return false; } // 0x58 + virtual bool IsGlobalFlags() { return false; } // 0x60 + virtual void DoPreCache(rage::netSyncData* data) {} // 0x68 + virtual std::uint8_t GetSyncFrequency(int index) { return 0; } // 0x70 + virtual int GetSyncInterval(int index) { return 0; } // 0x78 + virtual int GetBandwidthForPlayer(int player) { return 200; } // 0x80 (should always return 200) + virtual void _0x88(void*) {} // 0x88 + virtual bool _0x90(void*, void*, int, int, int) { return false; } // 0x90 + virtual int CalculateSize() { return 0; } // 0x98 need to verify later + virtual bool IsPreCacheDisabled() { return false; } // 0xA0 + virtual bool CanApply(rage::netObject* object) { return false; } // 0xA8 + virtual int GetPlayersInScope() { return -1; } // 0xB0 + virtual void DeserializeImpl() {} // 0xB8 need to verify later + virtual void SerializeImpl() {} // 0xC0 need to verify later + virtual int CalculateSize2() { return 0; } // 0xC8 + virtual int _0xD0() { return 0; } // 0xD0 calls NodeCommonDataOperations::Unk() + virtual void Log() {} // 0xD8 + virtual bool CanPreCache(int) { return false; } // 0xE0 arg is always zero afaik + virtual bool CanBeEmpty() { return false; } // 0xE8 + virtual bool IsEmpty() { return false; } // 0xF0 returns true if all data is default + virtual void SetEmpty() {} // 0xF8 sets all data to their default values + virtual void Log2() {} // 0x100 + virtual void ResetScriptData() {} // 0x108 + virtual bool _0x110() { return false; } // 0x110 + +private: + NodeCommonDataOperations m_common_data_operations; // 0xB0 this is generally invalidated by MoveCommonDataOpsVFT() +}; +static_assert(sizeof(CProjectBaseSyncDataNode) == 0xC0); + +class CSyncDataNodeFrequent : public CProjectBaseSyncDataNode {}; +class CSyncDataNodeInfrequent : public CProjectBaseSyncDataNode {}; \ No newline at end of file diff --git a/src/types/network/sync/NodeCommonDataOperations.hpp b/src/types/network/sync/NodeCommonDataOperations.hpp new file mode 100644 index 0000000..713efc9 --- /dev/null +++ b/src/types/network/sync/NodeCommonDataOperations.hpp @@ -0,0 +1,23 @@ +#pragma once + +namespace rage +{ + class datBitBuffer; + class netSyncDataNode; +} + +class NodeCommonDataOperations +{ +public: + virtual ~NodeCommonDataOperations() = default; + virtual void ReadFromBuffer(rage::netSyncDataNode* node) {}; // 0x08 + virtual void WriteToBuffer(rage::netSyncDataNode* node) {}; // 0x10 + virtual void Unk() {}; // 0x18 + virtual int CalculateSize(rage::netSyncDataNode* node) { return 0; }; // 0x20 + virtual int CalculateSize2(rage::netSyncDataNode* node) { return 0; }; // 0x28 + virtual void LogSyncData(rage::netSyncDataNode* node) {}; // 0x30 + virtual void LogSyncData2(rage::netSyncDataNode* node) {}; // 0x38 + + rage::datBitBuffer* m_Buffer; +}; +static_assert(sizeof(NodeCommonDataOperations) == 0x10); \ No newline at end of file diff --git a/src/types/network/sync/netSyncDataNode.hpp b/src/types/network/sync/netSyncDataNode.hpp new file mode 100644 index 0000000..7f7b46b --- /dev/null +++ b/src/types/network/sync/netSyncDataNode.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "netSyncNodeBase.hpp" + +namespace rage +{ + class netSyncDataNode : public netSyncNodeBase + { + public: + uint32_t m_Flags4; //0x40 + uint32_t pad3; //0x44 + uint64_t pad4; //0x48 + + netSyncDataNode* m_ParentData; //0x50 + uint32_t m_ChildCount; //0x58 + netSyncDataNode* m_Children[8]; //0x5C + uint8_t m_SyncFrequencies[8]; //0x9C + void* m_CommonDataOpsVFT; //0xA8 wtf + }; + static_assert(sizeof(netSyncDataNode) == 0xB0); +} \ No newline at end of file diff --git a/src/types/network/sync/netSyncNodeBase.hpp b/src/types/network/sync/netSyncNodeBase.hpp new file mode 100644 index 0000000..808eb17 --- /dev/null +++ b/src/types/network/sync/netSyncNodeBase.hpp @@ -0,0 +1,38 @@ +#pragma once + +#include + +namespace rage +{ + class datBitBuffer; + class netSyncTree; + + class netSyncNodeBase + { + public: + virtual ~netSyncNodeBase() = default; // 0x00 + virtual bool IsDataNode() = 0; // 0x08 + virtual bool IsParentNode() = 0; // 0x10 + virtual void MoveCommonDataOpsVFT() = 0; // 0x18 + virtual void ClearChildren() = 0; // 0x20 + virtual void _0x28(void*, void*, void*, int* out_count) = 0; // 0x28 + virtual bool Serialize(int flags, int flags2, void*, rage::datBitBuffer* buffer, int, void*, bool, int*, int* num_serialized) = 0; // 0x30 + virtual bool Deserialize(int flags, int flags2, rage::datBitBuffer* buffer, void*) = 0; // 0x38 + virtual int CalculateSize(int flags, int flags2, void*) = 0; // 0x40 + virtual int CalculateSize2(int flags, int flags2, bool) = 0; // 0x48 + + netSyncNodeBase* m_NextSibling; //0x0008 + netSyncNodeBase* m_PrevSibling; //0x0010 + netSyncTree* m_Root; //0x0018 + netSyncNodeBase* m_Parent; //0x0020 + + uint32_t m_Flags1; //0x0028 + uint32_t m_Flags2; //0x002C + uint32_t m_Flags3; //0x0030 + + uint32_t m_Pad2; //0x0034 + + netSyncNodeBase* m_FirstChild; //0x0038 + }; //Size: 0x0040 + static_assert(sizeof(netSyncNodeBase) == 0x40); +} \ No newline at end of file diff --git a/src/types/network/sync/netSyncTree.hpp b/src/types/network/sync/netSyncTree.hpp new file mode 100644 index 0000000..df4b5a6 --- /dev/null +++ b/src/types/network/sync/netSyncTree.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "netSyncNodeBase.hpp" + +namespace rage +{ + class netSyncTree + { + public: + virtual ~netSyncTree() = default; + + char pad_0008[8]; //0x0008 + netSyncNodeBase* m_NextSyncNode; //0x0010 + netSyncNodeBase* m_LastSyncNode; //0x0018 + uint32_t m_ChildNodeCount; //0x0020 + uint32_t m_UnkArrayCount; //0x0024 + char pad_0028[8]; //0x0028 + netSyncNodeBase* m_ChildNodes[42]; //0x0030 + uint32_t m_ChildNodeMaxCount; //0x0180 + netSyncNodeBase* m_UnkArray[32]; //0x0188 + uint32_t m_UnkArrayMaxCount; //0x0288 + char pad_0290[560]; //0x0290 + }; //Size: 0x0030 + static_assert(sizeof(netSyncTree) == 0x4C0); +} \ No newline at end of file diff --git a/src/types/network/sync/nodes/CPedComponents.hpp b/src/types/network/sync/nodes/CPedComponents.hpp new file mode 100644 index 0000000..7dc5adb --- /dev/null +++ b/src/types/network/sync/nodes/CPedComponents.hpp @@ -0,0 +1,44 @@ +#pragma once +#include + +class CPedComponents +{ +public: + uint32_t m_ComponentBitset; //0x0 + char pad_0x4[4]; //0x4 + uint32_t unk_0x8[12]; //0x8 + uint32_t m_Drawables[12]; //0x38 + uint32_t m_Textures[12]; //0x68 + uint32_t m_Palettes[12]; //0x98 + + inline uint32_t GetDrawable(int index) const + { + if (m_ComponentBitset & (1 << index)) + { + return m_Drawables[index]; + } + + return 0; + } + + inline uint32_t GetTexture(int index) const + { + if (m_ComponentBitset & (1 << index)) + { + return m_Textures[index]; + } + + return 0; + } + + inline uint32_t GetPalette(int index) const + { + if (m_ComponentBitset & (1 << index)) + { + return m_Palettes[index]; + } + + return 0; + } +}; +static_assert(sizeof(CPedComponents) == 0xC8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/automobile/CAutomobileCreationNode.hpp b/src/types/network/sync/nodes/automobile/CAutomobileCreationNode.hpp new file mode 100644 index 0000000..09e8f99 --- /dev/null +++ b/src/types/network/sync/nodes/automobile/CAutomobileCreationNode.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CAutomobileCreationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_AllDoorsClosed; //0x00C0 + bool m_DoorsClosed[10]; //0x00C1 +}; +static_assert(sizeof(CAutomobileCreationDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/door/CDoorCreationDataNode.hpp b/src/types/network/sync/nodes/door/CDoorCreationDataNode.hpp new file mode 100644 index 0000000..05c6b98 --- /dev/null +++ b/src/types/network/sync/nodes/door/CDoorCreationDataNode.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CDoorCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_ModelHash; //0x00C0 + char pad_00C4[12]; //0x00C4 + rage::fvector3 m_Position; //0x00D0 + char pad_00E0[8]; //0x00E0 + bool m_IsScriptDoor; //0x00E8 + bool m_PlayerWantsControl; //0x00E9 +}; //Size: 0x00EC +static_assert(sizeof(CDoorCreationDataNode) == 0xF0); diff --git a/src/types/network/sync/nodes/door/CDoorMovementDataNode.hpp b/src/types/network/sync/nodes/door/CDoorMovementDataNode.hpp new file mode 100644 index 0000000..0eced52 --- /dev/null +++ b/src/types/network/sync/nodes/door/CDoorMovementDataNode.hpp @@ -0,0 +1,15 @@ +#pragma once +#include +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CDoorMovementDataNode : CSyncDataNodeFrequent +{ +public: + bool m_IsManualDoor; // 0xC0 + float m_OpenRatio; // 0xC4 + bool m_Opening; // 0xC8 + bool m_FullyOpen; // 0xC9 + bool m_Closed; // 0xCA +}; +static_assert(sizeof(CDoorMovementDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/door/CDoorScriptGameStateDataNode.hpp b/src/types/network/sync/nodes/door/CDoorScriptGameStateDataNode.hpp new file mode 100644 index 0000000..244e167 --- /dev/null +++ b/src/types/network/sync/nodes/door/CDoorScriptGameStateDataNode.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +struct CDoorScriptGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_DoorSystemState; // 0xC0 + float m_AutomaticDistance; // 0xC4 + float m_SlideRate; // 0xC8 + bool m_HasBrokenFlags; // 0xCC + uint32_t m_BrokenFlags; // 0xD0 + bool m_HasDamagedFlags; // 0xD4 + uint32_t m_DamagedFlags; // 0xD8 + bool m_HoldOpen; // 0xDC +}; +static_assert(sizeof(CDoorScriptGameStateDataNode) == 0xE0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/door/CDoorScriptInfoDataNode.hpp b/src/types/network/sync/nodes/door/CDoorScriptInfoDataNode.hpp new file mode 100644 index 0000000..004e1fc --- /dev/null +++ b/src/types/network/sync/nodes/door/CDoorScriptInfoDataNode.hpp @@ -0,0 +1,17 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +#if 0 +#pragma pack(push, 4) +struct CDoorScriptInfoDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_has_script_info; + int m_pad; + CGameScriptObjInfo m_script_info; + uint32_t m_door_system_hash; + bool m_existing_door_system_entry; +}; +static_assert(sizeof(CDoorScriptInfoDataNode) == 0x120); +#pragma pack(pop) +#endif \ No newline at end of file diff --git a/src/types/network/sync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp b/src/types/network/sync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp new file mode 100644 index 0000000..e5dd85a --- /dev/null +++ b/src/types/network/sync/nodes/dynamic_entity/CDynamicEntityGameStateDataNode.hpp @@ -0,0 +1,22 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +struct CDecorator +{ + uint32_t m_Type; + uint32_t m_NameHash; + uint32_t m_Value; +}; + +class CDynamicEntityGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_InteriorIndex; // 0x00C0 + bool unk_00C4; // 0x00C4 + bool unk_00C5; // 0x00C5 + uint32_t m_DecorCount; // 0x00C8 + CDecorator m_Decors[10]; // 0x00CC + char pad[8]; // TODO! +}; +static_assert(sizeof(CDynamicEntityGameStateDataNode) == 0x150); \ No newline at end of file diff --git a/src/types/network/sync/nodes/entity/CEntityOrientationDataNode.hpp b/src/types/network/sync/nodes/entity/CEntityOrientationDataNode.hpp new file mode 100644 index 0000000..25f1aa0 --- /dev/null +++ b/src/types/network/sync/nodes/entity/CEntityOrientationDataNode.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +#if 0 +#pragma pack(push, 4) +class CEntityOrientationDataNode : CSyncDataNodeFrequent +{ +public: + rage::fmatrix44 m_eulers; +}; //Size: 0x00EC +static_assert(sizeof(CEntityOrientationDataNode) == 0x100); +#pragma pack(pop) +#endif \ No newline at end of file diff --git a/src/types/network/sync/nodes/entity/CEntityScriptGameStateDataNode.hpp b/src/types/network/sync/nodes/entity/CEntityScriptGameStateDataNode.hpp new file mode 100644 index 0000000..5dfb7b9 --- /dev/null +++ b/src/types/network/sync/nodes/entity/CEntityScriptGameStateDataNode.hpp @@ -0,0 +1,10 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +struct CEntityScriptGameStateDataNode : CSyncDataNodeInfrequent +{ + bool m_Fixed; //0x00C0 + bool m_UsesCollision; //0x00C1 + bool m_CompletelyDisabledCollision; //0x00C2 +}; //Size: 0x00C3 +static_assert(sizeof(CEntityScriptGameStateDataNode) == 0xC8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/entity/CEntityScriptInfoDataNode.hpp b/src/types/network/sync/nodes/entity/CEntityScriptInfoDataNode.hpp new file mode 100644 index 0000000..7ffc18e --- /dev/null +++ b/src/types/network/sync/nodes/entity/CEntityScriptInfoDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" +#include "types/script/CGameScriptObjInfo.hpp" + +struct CEntityScriptInfoDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_HasScriptInfo; + CGameScriptObjInfo m_ScriptInfo; +}; +static_assert(sizeof(CEntityScriptInfoDataNode) == 0x118); \ No newline at end of file diff --git a/src/types/network/sync/nodes/heli/CHeliControlDataNode.hpp b/src/types/network/sync/nodes/heli/CHeliControlDataNode.hpp new file mode 100644 index 0000000..aaaaa1e --- /dev/null +++ b/src/types/network/sync/nodes/heli/CHeliControlDataNode.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "netsync/nodes/vehicle/CVehicleControlDataNode.hpp" + +#pragma pack(push, 8) +class CHeliControlDataNode : CVehicleControlDataNode +{ +public: + char m_pad[0x10]; // 0x130 + float m_yaw_control; // 0x140 + float m_pitch_control; // 0x144 + float m_roll_control; // 0x148 + float m_throttle_control; // 0x14C + bool m_engine_off; // 0x150 + int m_landing_gear_state; // 0x154 + bool m_has_landing_gear; // 0x158 + bool m_has_vehicle_task; // 0x159 + bool m_is_thruster_model; // 0x15A + float m_thruster_side_rcs_throttle; // 0x15C + float m_thruster_throttle; // 0x160 + bool m_unk8; // 0x164 +}; +static_assert(sizeof(CHeliControlDataNode) == 0x168); +#pragma pack(pop) \ No newline at end of file diff --git a/src/types/network/sync/nodes/heli/CHeliHealthDataNode.hpp b/src/types/network/sync/nodes/heli/CHeliHealthDataNode.hpp new file mode 100644 index 0000000..4369d84 --- /dev/null +++ b/src/types/network/sync/nodes/heli/CHeliHealthDataNode.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include "netsync/CProjectBaseSyncDataNode.hpp" +#include "netsync/nodes/physical/CPhysicalHealthDataNode.hpp" + +#pragma pack(push, 8) +class CHeliHealthDataNode : CPhysicalHealthDataNode // intentionally private since the physical health node fields aren't serialized +{ +public: + char m_pad[0x10]; // 0xF0 + uint32_t m_main_rotor_health; + uint32_t m_rear_rotor_health; + bool m_can_tail_boom_break_off; + bool m_is_tail_boom_broken; + bool m_unk; + bool m_disable_explode_from_body_damage; + uint32_t m_body_health; + uint32_t m_petrol_tank_health; + uint32_t m_engine_health; + float m_unk_deformation_level; + float m_unk2_deformation_level; + float m_unk3_deformation_level; +}; +static_assert(sizeof(CHeliHealthDataNode) == 0x118); +#pragma pack(pop) \ No newline at end of file diff --git a/src/types/network/sync/nodes/object/CObjectCreationDataNode.hpp b/src/types/network/sync/nodes/object/CObjectCreationDataNode.hpp new file mode 100644 index 0000000..7657b8e --- /dev/null +++ b/src/types/network/sync/nodes/object/CObjectCreationDataNode.hpp @@ -0,0 +1,45 @@ +#pragma once +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +// TODO: verify if this is right +class CObjectCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t unk_00C0; //0x00C0 + uint32_t unk_00C4; //0x00C4 + uint32_t unk_00C8; //0x00C8 + bool unk_00CC; + bool unk_00CD; + uint16_t unk_00D0; //0x00D0 + char pad_0xC2[14]; //0x00D2 + rage::fvector4 m_ObjectOrientation; //0x00E0 + char pad_00E0[30]; //0x00F0 + rage::fvector3 m_ObjectPosition; //0x0110 + char pad_010C[4]; //0x011C + rage::fvector3 m_DummyPosition; //0x011E + char pad_011A[16]; //0x012C + rage::fvector3 m_ScriptGrabPosition; //0x0140 + char pad_013C[8]; //0x013C + float m_ScriptGrabRadius; //0x0148 + uint32_t m_CreatedBy; //0x014C + uint32_t m_Model; //0x0150 + uint32_t m_FragGroupIndex; //0x0154 + uint32_t m_OwnershipToken; //0x0158 + uint32_t unk_015C; //0x015C + + // everything after this is probably wrong + bool m_NoReassign; //0x0160 + bool unk_0161; //0x0161 + bool m_PlayerWantsControl; //0x0162 + bool m_HasInitPhysics; //0x0163 + bool m_ScriptGrabbedFromWorld; //0x0164 + bool m_IsFragObject; //0x0165 + bool m_IsBroken; //0x0166 + bool m_HasExploded; //0x0167 + bool m_KeepRegistered; //0x0168 + bool unk_0169; //0x0169 + bool unk_016A; //0x016A + bool unk_016B; //0x016B +}; //Size: 0x016C +static_assert(sizeof(CObjectCreationDataNode) == 0x180); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedAIDataNode.hpp b/src/types/network/sync/nodes/ped/CPedAIDataNode.hpp new file mode 100644 index 0000000..f0209eb --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedAIDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedAIDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_RelationshipGroup; //0x00C0 + uint32_t m_DecisionMakerType; //0x00C4 +}; //Size: 0x00C8 +static_assert(sizeof(CPedAIDataNode) == 0xC8); diff --git a/src/types/network/sync/nodes/ped/CPedAppearanceDataNode.hpp b/src/types/network/sync/nodes/ped/CPedAppearanceDataNode.hpp new file mode 100644 index 0000000..85a5f86 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedAppearanceDataNode.hpp @@ -0,0 +1,33 @@ +#pragma once +#include "../CPedComponents.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedAppearanceDataNode : CSyncDataNodeInfrequent +{ +private: + uint32_t unk_0xC0[6]; //0xC0 + uint32_t unk_0xD8[6]; //0xD8 +public: + class CPedComponents m_Components; //0xF0 +private: + char pad_0x1B8[8]; //0x1B8 + uint32_t unk_0x1C0; //0x1C0 + uint8_t unk_0x1C4; //0x1C4 + uint8_t unk_0x1C5; //0x1C5 + char pad_0x1C6[2]; //0x1C6 + uint32_t unk_0x1C8; //0x1C8 + uint32_t unk_0x1CC; //0x1CC + uint32_t unk_0x1D0; //0x1D0 + bool unk_0x1D4; //0x1D4 + bool unk_0x1D5; //0x1D5 + bool unk_0x1D6; //0x1D6 + uint8_t unk_0x1D7; //0x1D7 + uint16_t unk_0x1D8; //0x1D8 + uint16_t unk_0x1DA; //0x1DA + uint16_t unk_0x1DC; //0x1DC + bool unk_0x1DE; //0x1DE + bool unk_0x1DF; //0x1DF + bool unk_0x1E0; //0x1E0 + uint8_t unk_0x1E1; //0x1E1 +}; +static_assert(sizeof(CPedAppearanceDataNode) == 0x1E8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedAttachDataNode.hpp b/src/types/network/sync/nodes/ped/CPedAttachDataNode.hpp new file mode 100644 index 0000000..0247dc4 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedAttachDataNode.hpp @@ -0,0 +1,20 @@ +#pragma once +#include +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedAttachDataNode : CSyncDataNodeInfrequent +{ +public: + rage::fvector3 m_Offset; //0x00C0 + char pad_00CC[4]; //0x00CC + rage::fvector4 m_Orientation; //0x00D0 + uint16_t m_AttachedTo; //0x00E0 + uint16_t m_AttachmentBone; //0x00E2 + uint32_t m_AttachmentFlags; //0x00E4 + float m_Heading; //0x00E8 + float m_Heading2; //0x00EC + bool m_IsAttached; //0x00F0 + bool unk_00F1; //0x00F1 +}; +static_assert(sizeof(CPedAttachDataNode) == 0xF8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedComponentReservationDataNode.hpp b/src/types/network/sync/nodes/ped/CPedComponentReservationDataNode.hpp new file mode 100644 index 0000000..10f22a2 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedComponentReservationDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedComponentReservationDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_NumPedsUsingComponent; //0x00C0 + uint16_t m_PedsUsingComponent[32]; //0x00C4 +}; //Size: 0x00C8 +static_assert(sizeof(CPedComponentReservationDataNode) == 0x108); diff --git a/src/types/network/sync/nodes/ped/CPedCreationDataNode.hpp b/src/types/network/sync/nodes/ped/CPedCreationDataNode.hpp new file mode 100644 index 0000000..ae37b78 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedCreationDataNode.hpp @@ -0,0 +1,26 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_PopType; //0x00C0 + uint32_t m_ModelHash; //0x00C4 + uint32_t m_RandomSeed; //0x00C8 + uint32_t m_MaxHealth; //0x00CC + bool m_SpawnInVehicle; //0x00D0 + char pad_0xD1[1]; //0x00D1 + uint16_t m_VehicleId; //0x00D2 + uint32_t m_VehicleSeat; //0x00D4 + bool m_HasProp; //0x00D8 + char pad_0xD9[3]; //0x00D9 + uint32_t m_PropModel; //0x00DC + bool m_IsStanding; //0x00E0 + bool m_IsRespawnObjectId; //0x00E1 + bool m_IsRespawnFlaggedForRemoval; //0x00E2 + bool m_HasAttrDamageToPlayer; //0x00E3 + uint8_t m_AttrDamageToPlayer; //0x00E4 + uint32_t m_VoiceHash; //0x00E8 +}; //Size: 0x00EC +static_assert(sizeof(CPedCreationDataNode) == 0xF0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedGameStateDataNode.hpp b/src/types/network/sync/nodes/ped/CPedGameStateDataNode.hpp new file mode 100644 index 0000000..54e8819 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedGameStateDataNode.hpp @@ -0,0 +1,76 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_WeaponComponentSomething[12]; //0x0C0 + uint32_t m_WeaponComponentHash[12]; //0x0CC + uint32_t m_GadgetHash[3]; //0x0F8 + uint32_t unk_0104; // 0x0104 + uint32_t unk_0108; // 0x0108 + uint32_t unk_010C; // 0x010C + float unk_0110; // 0x0110 + float unk_0114; // 0x0114 + float unk_0118; // 0x0118 + bool unk_011C; // 0x011C + char pad_011D[3]; //0x011D + uint32_t m_ArrestState; //0x0120 + uint32_t m_DeathState; //0x0124 + uint32_t m_WeaponHash; //0x0128 + uint32_t m_NumWeaponComponents; //0x012C + uint32_t m_NumEquippedGadgets; //0x0130 + uint32_t m_VehicleSeat; //0x0134 + uint32_t m_ActionModeOverride; //0x0138 + uint32_t unk_013C; // 0x013C + uint16_t m_VehicleId; //0x0140 + uint16_t m_MountId; //0x0142 + uint16_t m_CustodianId; //0x0144 + uint16_t unk_0146; // 0x0146 + uint8_t new_014C; + bool m_TintIndex; //0x0148 + char pad_0149; //0x0149 + uint8_t unk_014A; // 0x014A + bool m_IsHandcuffed; //0x014B + bool m_CanPerformArrest; //0x014C + bool m_CanPerformUncuff; //0x014D + bool m_CanBeArrested; //0x014E + bool m_IsInCustody; //0x014F + char pad_0150; //0x0150 + bool m_WeaponExists; //0x0151 + bool m_WeaponVisible; //0x0152 + bool m_WeaponHasAmmo; //0x0153 + bool m_WeaponAttachLeft; //0x0154 + char pad_0155; //0x0155 + bool m_InSeat; //0x0156 + bool m_InVehicle; //0x0157 + bool m_OnMount; //0x0158 + bool m_HasCustodianOrArrestFlags; //0x0159 + char pad_015A; //0x015A + bool m_ActionModeEnabled; //0x015B + bool m_StealthModeEnabled; //0x015C + bool unk_015D; // 0x015D + bool unk_015E; // 0x015E + bool unk_015F; // 0x015F + bool unk_0160; // 0x0160 + bool unk_0161; // 0x0161 + bool unk_0162; // 0x0162 + bool unk_0163; // 0x0163 + bool unk_0164; // 0x0164 + bool unk_0165; // 0x0165 + bool unk_0166; // 0x0166 + bool unk_0167; // 0x0167 + bool unk_0168; // 0x0168 + bool unk_0169; // 0x0169 + bool unk_016A; // 0x016A + bool unk_016B; // 0x016B + bool unk_016C; // 0x016C + bool unk_016D; // 0x016D + bool unk_016E; // 0x016E + bool unk_016F; // 0x016F + bool unk_0170; // 0x0170 + bool unk_0171; // 0x0171 + bool unk_0172; // 0x0172 +}; //Size: 0x0174 +static_assert(sizeof(CPedGameStateDataNode) == 0x178); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedHealthDataNode.hpp b/src/types/network/sync/nodes/ped/CPedHealthDataNode.hpp new file mode 100644 index 0000000..121372c --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedHealthDataNode.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedHealthDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t unk_00C0; //0x00C0 + uint32_t m_Health; //0x00C4 + uint32_t m_Armor; //0x00C8 + uint32_t unk_00CC; //0x00CC + uint32_t unk_00D0; //0x00D0 + uint32_t m_WeaponDamageHash; //0x00D4 + uint32_t m_HurtEndTime; //0x00D8 + uint32_t m_WeaponDamageComponent; //0x00DC + uint16_t m_WeaponDamageEntity; //0x00E0 + bool m_HasMaxHealth; //0x00E2 + bool m_HasDefaultArmor; //0x00E3 + bool unk_00E4; //0x00E4 + bool m_KilledWithHeadshot; //0x00E5 + bool m_KilledWithMelee; //0x00E6 + char m_HurtStarted; //0x00E7 + bool unk_00E8; //0x00E8 + bool unk_00E9; //0x00E9 +}; +static_assert(sizeof(CPedHealthDataNode) == 0xF0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedInventoryDataNode.hpp b/src/types/network/sync/nodes/ped/CPedInventoryDataNode.hpp new file mode 100644 index 0000000..98099fb --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedInventoryDataNode.hpp @@ -0,0 +1,22 @@ +#pragma once +#include + +// todo? +#pragma pack(push, 4) +class CPedInventoryDataNode +{ +public: + char pad_0000[5232]; + uint32_t m_items[105]; + uint32_t m_num_items; + uint32_t m_ammos[65]; + uint32_t m_ammo_quantities[65]; + uint32_t m_num_ammos; + uint8_t unk_1680[105]; + uint8_t unk_16E9[105]; + char pad_1680[1260]; + bool m_infinite_ammos[65]; + bool m_ammo_all_infinite; +}; +static_assert(sizeof(CPedInventoryDataNode) == 0x1E24); +#pragma pack(pop) \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedMovementDataNode.hpp b/src/types/network/sync/nodes/ped/CPedMovementDataNode.hpp new file mode 100644 index 0000000..75dfb04 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedMovementDataNode.hpp @@ -0,0 +1,15 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedMovementDataNode : CSyncDataNodeFrequent +{ +public: + bool m_HasDesiredMoveBlendRatioX; //0x00C0 + bool m_HasDesiredMoveBlendRatioY; //0x00C1 + bool unk_00C2; //0x00C2 + float m_DesiredMoveBlendRatioX; //0x00C4 + float m_DesiredMoveBlendRatioY; //0x00C8 + float unk_00CC; //0x00CC + float m_DesiredPitch; //0x00D0 +}; //Size: 0x00D4 +static_assert(sizeof(CPedMovementDataNode) == 0xD8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedMovementGroupDataNode.hpp b/src/types/network/sync/nodes/ped/CPedMovementGroupDataNode.hpp new file mode 100644 index 0000000..551f2de --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedMovementGroupDataNode.hpp @@ -0,0 +1,22 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedMovementGroupDataNode : CSyncDataNodeFrequent +{ +public: + float m_unk; // 0xC0 (CTaskMotionInAutomobile+0x1EC) + uint32_t m_MovementTaskInded; // 0xC4 + uint32_t m_MovementTaskStage; // 0xC8 + uint32_t m_MovementGroup; // 0xCC + uint32_t m_OverriddenWeaponGroup; // 0xD0 + uint32_t m_OverriddenUnkGroup; // 0xD4 (SET_PED_ALTERNATE_MOVEMENT_ANIM?) + bool m_IsCrouching; // 0xD8 + bool m_IsStealthy; // 0xD9 + bool m_IsStrafing; // 0xDA + bool m_IsRagdolling; // 0xDB + bool m_IsRagdollConstraintAnkleActive; // 0xDC + bool m_IsRagdollConstraintWristActive; // 0xDD + char m_pad1[2]; // 0xDE + char m_TennisData[0x20]; // 0xE0 TODO +}; +static_assert(sizeof(CPedMovementGroupDataNode) == 0x100); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedOrientationDataNode.hpp b/src/types/network/sync/nodes/ped/CPedOrientationDataNode.hpp new file mode 100644 index 0000000..2b33b7a --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedOrientationDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedOrientationDataNode : CSyncDataNodeFrequent +{ +public: + bool m_HasDesiredHeadingX; //000C1 + bool m_HasDesiredHeadingY; //000C2 + float m_DesiredHeadingX; //0x00C4 + float m_DesiredHeadingY; //0x00C8 +}; +static_assert(sizeof(CPedOrientationDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedScriptCreationDataNode.hpp b/src/types/network/sync/nodes/ped/CPedScriptCreationDataNode.hpp new file mode 100644 index 0000000..228b7e3 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedScriptCreationDataNode.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedScriptCreationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_StayInCarWhenJacked; //0x00C0 +}; //Size: 0x00C1 +static_assert(sizeof(CPedScriptCreationDataNode) == 0xC8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedTaskSequenceDataNode.hpp b/src/types/network/sync/nodes/ped/CPedTaskSequenceDataNode.hpp new file mode 100644 index 0000000..e881024 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedTaskSequenceDataNode.hpp @@ -0,0 +1,22 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +struct CPedTaskSequenceData +{ + int m_TaskType; // 0x00 + int m_TaskDataSize; // 0x04 + char m_TaskData[602]; // 0x08 +}; +static_assert(sizeof(CPedTaskSequenceData) == 0x264); + +class CPedTaskSequenceDataNode : CSyncDataNodeFrequent +{ +public: + bool m_HasSequence; // 0xC0 + int m_SequenceResourceId; // 0xC4 + int m_NumTasksInSequence; // 0xC8 + CPedTaskSequenceData m_TaskData[10]; // 0xCC + int m_Unk; // 0x18B4 +}; +static_assert(sizeof(CPedTaskSequenceDataNode) == 0x18B8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedTaskSpecificDataNode.hpp b/src/types/network/sync/nodes/ped/CPedTaskSpecificDataNode.hpp new file mode 100644 index 0000000..cb13995 --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedTaskSpecificDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPedTaskSpecificDataNode : CSyncDataNodeFrequent +{ +public: + uint32_t m_TaskIndex; //0x00C0 + uint32_t m_TaskType; //0x00C4 + uint32_t m_BufferSize; //0x00C8 + uint8_t m_TaskDataBuffer[603]; //0x00CC +}; //Size: 0x0328 +static_assert(sizeof(CPedTaskSpecificDataNode) == 0x328); \ No newline at end of file diff --git a/src/types/network/sync/nodes/ped/CPedTaskTreeDataNode.hpp b/src/types/network/sync/nodes/ped/CPedTaskTreeDataNode.hpp new file mode 100644 index 0000000..b810ccd --- /dev/null +++ b/src/types/network/sync/nodes/ped/CPedTaskTreeDataNode.hpp @@ -0,0 +1,23 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +struct CPedTaskData +{ + int m_TaskType; // 0x00 + int m_Priority; // 0x04 + int m_TreeDepth; // 0x08 + int m_SequenceId; // 0x0C + bool m_Active; // 0x10 +}; +static_assert(sizeof(CPedTaskData) == 0x14); + +class CPedTaskTreeDataNode : CSyncDataNodeFrequent +{ +public: + CPedTaskData m_Tasks[8]; // 0xC0 + int m_TaskBitset; // 0x160 + int m_ScriptCommand; // 0x164 + int m_ScriptCommandStage; // 0x168 +}; +static_assert(sizeof(CPedTaskTreeDataNode) == 0x170); \ No newline at end of file diff --git a/src/types/network/sync/nodes/physical/CPhysicalAngVelocityDataNode.hpp b/src/types/network/sync/nodes/physical/CPhysicalAngVelocityDataNode.hpp new file mode 100644 index 0000000..097ad50 --- /dev/null +++ b/src/types/network/sync/nodes/physical/CPhysicalAngVelocityDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPhysicalAngVelocityDataNode : CSyncDataNodeFrequent +{ +public: + int32_t m_AngVelocityX; + int32_t m_AngVelocityY; + int32_t m_AngVelocityZ; +}; // 0x00CC +static_assert(sizeof(CPhysicalAngVelocityDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/physical/CPhysicalAttachDataNode.hpp b/src/types/network/sync/nodes/physical/CPhysicalAttachDataNode.hpp new file mode 100644 index 0000000..4cceb53 --- /dev/null +++ b/src/types/network/sync/nodes/physical/CPhysicalAttachDataNode.hpp @@ -0,0 +1,27 @@ +#pragma once +#include +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPhysicalAttachDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_IsAttached; //0x00C0 + bool unk_00C1; //0x00C1 + uint16_t m_Attachedto; //0x00C2 + char pad_00C4[12]; //0x00C4 + rage::fvector3 m_Offset; //0x00D0 + rage::fvector4 m_Orientation; //0x00E0 + rage::fvector3 m_ParentOffset; //0x00F0 + uint16_t m_OtherAttachBone; //0x0100 + uint16_t m_AttachBone; //0x0102 + uint32_t m_AttachFlags; //0x0104 + bool m_AllowInitialSeparation; //0x0108 + char pad_00109[3]; //0x0109 + float unk_010C; //0x010C + float unk_0110; //0x0110 + bool unk_0114; //0x0114 + bool unk_0115; //0x0115 + bool m_IsCargoVehicle; //0x0116 +}; //Size: 0x0118 +static_assert(sizeof(CPhysicalAttachDataNode) == 0x118); \ No newline at end of file diff --git a/src/types/network/sync/nodes/physical/CPhysicalGameStateDataNode.hpp b/src/types/network/sync/nodes/physical/CPhysicalGameStateDataNode.hpp new file mode 100644 index 0000000..0e1297e --- /dev/null +++ b/src/types/network/sync/nodes/physical/CPhysicalGameStateDataNode.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPhysicalGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_IsVisible; // 0xC0 + bool m_flag2; // 0xC1 + bool m_flag3; // 0xC2 + bool m_flag4; // 0xC3 + char m_pad; // 0xC4 + uint32_t m_val1; // 0xC8 + int16_t m_unk204; // 0xCC + bool m_unk5; // 0xCE +}; // 0x00CC +static_assert(sizeof(CPhysicalGameStateDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/physical/CPhysicalHealthDataNode.hpp b/src/types/network/sync/nodes/physical/CPhysicalHealthDataNode.hpp new file mode 100644 index 0000000..e152505 --- /dev/null +++ b/src/types/network/sync/nodes/physical/CPhysicalHealthDataNode.hpp @@ -0,0 +1,15 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +struct CPhysicalHealthDataNode : CSyncDataNodeInfrequent +{ + bool unk_00C0; //0x00C0 + bool m_HasMaxHealthChanged; //0x00C1 + uint32_t m_MaxHealth; //0x00C4 + uint32_t m_CurrentHealth; //0x00C8 + uint16_t m_WeaponDamageEntity; //0x00CC + uint32_t m_WeaponDamageHash; //0x00D0 + uint64_t unk_00D8; //0x00D8 +}; +static_assert(sizeof(CPhysicalHealthDataNode) == 0xE0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/physical/CPhysicalMigrationDataNode.hpp b/src/types/network/sync/nodes/physical/CPhysicalMigrationDataNode.hpp new file mode 100644 index 0000000..9b048b5 --- /dev/null +++ b/src/types/network/sync/nodes/physical/CPhysicalMigrationDataNode.hpp @@ -0,0 +1,10 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPhysicalMigrationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_Unk; +}; +static_assert(sizeof(CPhysicalMigrationDataNode) == 0xC8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp b/src/types/network/sync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp new file mode 100644 index 0000000..98a43d6 --- /dev/null +++ b/src/types/network/sync/nodes/physical/CPhysicalScriptGameStateDataNode.hpp @@ -0,0 +1,34 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPhysicalScriptGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_godmode; + bool m_dont_load_collision; + bool m_freeze_on_collision_load; + bool m_only_damaged_by_player; + bool m_bullet_proof; + bool m_fire_proof; + bool m_explosion_proof; + bool m_collision_proof; + bool m_melee_proof; + bool m_cannot_be_damaged_by_relationship_group; + bool m_can_only_be_damaged_by_relationship_group; + bool m_smoke_proof; + bool m_steam_proof; + bool m_can_only_be_damaged_by_participants; + bool m_dont_reset_proofs_on_cleanup_mission; + bool m_no_reassign; + bool m_pass_control_in_tutorial; + bool m_visible_in_cutscene; + bool m_visible_in_cutscene_remain_hack; + bool m_pickup_by_cargobob_disabled; + uint32_t m_relationship_group; + uint32_t m_always_cloned_for_players; + bool m_modified_max_speed; + bool m_trigger_damage_event_for_zero_damage; + float m_max_speed; +}; +static_assert(sizeof(CPhysicalScriptGameStateDataNode) == 0xE8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp b/src/types/network/sync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp new file mode 100644 index 0000000..f751972 --- /dev/null +++ b/src/types/network/sync/nodes/physical/CPhysicalScriptMigrationDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPhysicalScriptMigrationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_HasData; // 0xC0 + int m_ScriptParticipants; // 0xC4 + uint16_t m_HostToken; // 0xC8 +}; +static_assert(sizeof(CPhysicalScriptMigrationDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/physical/CPhysicalVelocityDataNode.hpp b/src/types/network/sync/nodes/physical/CPhysicalVelocityDataNode.hpp new file mode 100644 index 0000000..6a85e86 --- /dev/null +++ b/src/types/network/sync/nodes/physical/CPhysicalVelocityDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPhysicalVelocityDataNode : CSyncDataNodeFrequent +{ +public: + int32_t m_VelocityX; + int32_t m_VelocityY; + int32_t m_VelocityZ; +}; +static_assert(sizeof(CPhysicalVelocityDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/pickup/CPickupCreationDataNode.hpp b/src/types/network/sync/nodes/pickup/CPickupCreationDataNode.hpp new file mode 100644 index 0000000..4224170 --- /dev/null +++ b/src/types/network/sync/nodes/pickup/CPickupCreationDataNode.hpp @@ -0,0 +1,24 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" +#include "types/script/CGameScriptObjInfo.hpp" + +class CPickupCreationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_HasPlacement; //0x00C0 + char pad_00C1[7]; //0x00C1 + CGameScriptObjInfo m_ScriptObjectInfo; //0x00C8 + uint32_t m_PickupHash; //0x0118 + uint32_t m_Amount; //0x011C + uint32_t m_CustomModel; //0x0120 + uint32_t m_LifeTime; //0x0124 + uint32_t m_WeaponComponent[12]; //0x0128 + uint32_t m_NumWeaponComponents; //0x0154 + uint32_t m_TintIndex; //0x0158 + bool m_PlayerGift; //0x015C + bool unk_015D; //0x015D + char pad_015E[6]; //0x015E + uint32_t unk_0164; //0x0164 + bool unk_0168; //0x0168 +}; //Size: 0x0170 +static_assert(sizeof(CPickupCreationDataNode) == 0x170); \ No newline at end of file diff --git a/src/types/network/sync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp b/src/types/network/sync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp new file mode 100644 index 0000000..085414e --- /dev/null +++ b/src/types/network/sync/nodes/pickup_placement/CPickupPlacementCreationDataNode.hpp @@ -0,0 +1,20 @@ +#pragma once +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPickupPlacementCreationDataNode : CProjectBaseSyncDataNode +{ +public: + bool m_HasPickupData; //0x00C0 + char pad_00C1[15]; //0x00C1 + rage::fvector3 m_PickupPos; //0x00D0 + rage::fvector4 m_PickupOrientation; //0x00E0 + uint32_t m_PickupType; //0x00F0 + uint32_t m_PickupFlags; //0x00F4 + uint32_t m_Amount; //0x00F8 + uint32_t m_CustomModel; //0x00FC + uint32_t m_CustomRegenerationTime; //0x0100 + uint32_t m_TeamPermits; //0x0104 + uint64_t *unk_struct_0108; //0x0108 +}; //Size: 0x0110 +static_assert(sizeof(CPickupPlacementCreationDataNode) == 0x110); diff --git a/src/types/network/sync/nodes/player/CPlayerAmbientModelStreamingNode.hpp b/src/types/network/sync/nodes/player/CPlayerAmbientModelStreamingNode.hpp new file mode 100644 index 0000000..1501349 --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerAmbientModelStreamingNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPlayerAmbientModelStreamingNode : CSyncDataNodeInfrequent +{ +public: + int m_AllowedPedModelStartOffset; // 0xC0 + int m_AllowedVehicleModelStartOffset; // 0xC4 + int m_VehicleAnimStreamingTargetEntrypoint; // 0xC8 + int16_t m_VehicleAnimStreamingTarget; // 0xCC +}; +static_assert(sizeof(CPlayerAmbientModelStreamingNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/player/CPlayerAppearanceDataNode.hpp b/src/types/network/sync/nodes/player/CPlayerAppearanceDataNode.hpp new file mode 100644 index 0000000..b75665a --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerAppearanceDataNode.hpp @@ -0,0 +1,91 @@ +#pragma once +#include "../CPedComponents.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPlayerAppearanceDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t unk_0xC0[60]; //0xC0 + class CPedComponents m_Components; //0x1A0 + char pad_0x268[8]; //0x268 + uint32_t unk_0x270[6]; //0x270 + uint32_t unk_0x288[6]; //0x288 + char pad_0x2A0[8]; //0x2A0 + float unk_0x2A8; //0x2A8 + uint8_t unk_0x2AC; //0x2AC + uint8_t unk_0x2AD; //0x2AD + char pad_0x2AE[26]; //0x2AE + float m_shape_mix; //0x2C8 + float m_skin_mix; //0x2CC + float m_third_mix; //0x2D0 + float unk_0x2D4; //0x2D4 + float unk_0x2D8[13]; //0x2D8 + float unk_0x30C[13]; //0x30C + float unk_0x340[20]; //0x340 + uint8_t unk_0x390[13]; //0x390 + uint8_t unk_0x39D[13]; //0x39D + uint8_t unk_0x3AA[13]; //0x3AA + uint8_t m_shape_first; //0x3B7 + uint8_t m_shape_second; //0x3B8 + uint8_t m_shape_third; //0x3B9 + uint8_t m_skin_first; //0x3BA + uint8_t m_skin_second; //0x3BB + uint8_t m_skin_third; //0x3BC + uint8_t unk_0x3BD[13]; //0x3BD + uint8_t unk_0x3CA[11]; //0x3CA + int16_t unk_0x3D6; //0x3D6 + uint8_t unk_0x3D8; //0x3D8 + uint8_t unk_0x3D9; //0x3D9 + char pad_0x3DA[1]; //0x3DA + bool unk_0x3DB; //0x3DB + bool unk_0x3DC; //0x3DC + char pad_0x3DD[3]; //0x3DD + uint32_t unk_0x3E0; //0x3E0 + uint32_t unk_0x3E4; //0x3E4 + uint32_t unk_0x3E8; //0x3E8 + uint32_t unk_0x3EC; //0x3EC + uint32_t unk_0x3F0; //0x3F0 + float unk_0x3F4; //0x3F4 + float m_blend_in_duration; //0x3F8 + float m_blend_out_duration; //0x3FC + uint32_t m_anim_name_hash; //0x400 + uint32_t m_anim_dict_index; //0x404 + uint32_t m_anim_flags; //0x408 + uint32_t unk_0x40C; //0x40C + uint32_t unk_0x410; //0x410 + bool m_anim_task_active; //0x414 + bool unk_0x415; //0x415 + bool m_task_move_active; //0x416 + bool m_mobile_phone_task_active; //0x417 + bool m_mobile_phone_gesture_active; //0x418 + bool unk_0x419; //0x419 + uint32_t unk_0x41C; //0x41C + uint32_t m_model_hash; //0x420 + uint32_t m_voice_hash; //0x424 + uint32_t m_phone_mode; //0x428 + uint32_t unk_0x42C; //0x42C + uint8_t m_parachute_tint_index; //0x430 + uint8_t m_parachute_pack_tint_index; //0x431 + uint16_t m_respawn_object; //0x432 + bool m_has_head_blend_data; //0x434 + bool unk_0x435; //0x435 + bool m_has_respawn_object; //0x436 + char pad_0x437; //0x437 + uint32_t unk_0x438_clip_maybe; //0x438 + uint32_t unk_0x43C; //0x43C + uint32_t unk_0x440; //0x440 + bool unk_0x444; //0x444 + bool unk_0x445; //0x445 + bool unk_0x446; //0x446 + uint8_t unk_0x447; //0x447 + uint16_t unk_0x448; //0x448 + uint16_t unk_0x44A; //0x44A + uint16_t unk_0x44C; //0x44C + bool unk_0x44E; //0x44E + bool unk_0x44F; //0x44F + bool unk_0x450; //0x450 + uint8_t unk_0x451; //0x451 + uint32_t unk_0x452; //0x452 + uint32_t unk_0x456; //0x456 +}; +static_assert(sizeof(CPlayerAppearanceDataNode) == 0x470); \ No newline at end of file diff --git a/src/types/network/sync/nodes/player/CPlayerCameraDataNode.hpp b/src/types/network/sync/nodes/player/CPlayerCameraDataNode.hpp new file mode 100644 index 0000000..ff9a280 --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerCameraDataNode.hpp @@ -0,0 +1,25 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPlayerCameraDataNode : CSyncDataNodeFrequent +{ +public: + float m_FreeCamPosX; //0x00C0 + float m_FreeCamPosY; //0x00C4 + float m_FreeCamPosZ; //0x00C8 + char pad_00CC[4]; //0x00CC + float m_LockOnTargetOffsetX; //0x00D0 + float m_LockOnTargetOffsetY; //0x00D4 + char pad_00D8[40]; //0x00D8 + float m_CameraX; //0x0100 + float m_CameraZ; //0x0104 + int16_t m_FreeAimLockedOnTarget; //0x0108 + bool m_FreeCam; //0x010A + char pad_010B[2]; //0x010B + bool m_HasPositionOffset; //0x010D + char pad_010E[1]; //0x010E + bool m_IsLongRangeTarget; //0x010F + char pad_0110[48]; //0x0110 +}; //Size: 0x0140 +static_assert(sizeof(CPlayerCameraDataNode) == 0x140); \ No newline at end of file diff --git a/src/types/network/sync/nodes/player/CPlayerCreationDataNode.hpp b/src/types/network/sync/nodes/player/CPlayerCreationDataNode.hpp new file mode 100644 index 0000000..082d2ec --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerCreationDataNode.hpp @@ -0,0 +1,17 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPlayerCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_ModelHash; //0x00C0 + uint32_t m_NumScars; //0x00C4 + char unk_struct_0xC8[192]; //0x00C8 + uint32_t unk_0188; //0x0188 + char pad_018C[4]; //0x018C + char m_scar_struct[176]; //0x0190 + bool unk_0240; //0x0240 + char pad_0241[19]; //0x0241 +}; //Size: 0x0254 +static_assert(sizeof(CPlayerCreationDataNode) == 0x258); \ No newline at end of file diff --git a/src/types/network/sync/nodes/player/CPlayerExtendedGameStateNode.hpp b/src/types/network/sync/nodes/player/CPlayerExtendedGameStateNode.hpp new file mode 100644 index 0000000..0db9c17 --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerExtendedGameStateNode.hpp @@ -0,0 +1,16 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPlayerExtendedGameStateNode : CSyncDataNodeInfrequent +{ +public: + float m_WaypointX; //0x00C0 + float m_WaypointY; //0x00C4 + bool unk1; //0x00C5 + bool unk2; //0x00C6 + bool unk3; //0x00C7 + bool unk4; //0x00C8 + bool unk5; //0x00C9 + bool m_HasWaypointData; //0x00CA + bool m_IsWaypointSet; //0x00CB +}; \ No newline at end of file diff --git a/src/types/network/sync/nodes/player/CPlayerGameStateDataNode.hpp b/src/types/network/sync/nodes/player/CPlayerGameStateDataNode.hpp new file mode 100644 index 0000000..cf1a1ac --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerGameStateDataNode.hpp @@ -0,0 +1,145 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPlayerGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_player_state; //0x00C0 + bool m_controls_disabled_by_script; //0x00C4 + bool m_is_max_armor_and_health_default; //0x00C5 + bool unk_000C6; //0x00C6 + bool m_is_spectating; //0x00C7 + bool m_is_antagonistic_to_another_player; //0x00C8 + bool m_never_target; //0x00C9 + bool m_use_kinematic_physics; //0x00CA + bool m_has_tutorial_data; //0x00CB + bool m_pending_tutorial_change; //0x00CC + bool unk_00CD; //0x00CD + bool m_respawning; //0x00CE + bool m_will_jack_any_player; //0x00CF + bool m_will_jack_wanted_players; //0x00D0 + bool m_dont_drag_from_car; //0x00D1 + bool m_random_peds_flee; //0x00D2 + bool m_every_ped_back_away; //0x00D3 + bool m_has_microphone; //0x00D4 + bool m_is_invincible; //0x00D5 + bool unk_00D6; //0x00D6 + bool unk_00D7; //0x00D7 + bool m_seatbelt; //0x00D8 + bool unk_00D9; //0x00D9 + bool m_bullet_proof; //0x00DA + bool m_fire_proof; //0x00DB + bool m_explosion_proof; //0x00DC + bool m_collision_proof; //0x00DD + bool m_melee_proof; //0x00DE + bool m_water_proof; //0x00DF + bool m_steam_proof; //0x00E0 + bool unk_00E1; //0x00E1 + bool unk_00E2; //0x00E2 + bool unk_00E3; //0x00E3 + bool unk_00E4; //0x00E4 + bool unk_00E5; //0x00E5 + bool unk_00E6; //0x00E6 + bool unk_00E7; //0x00E7 + bool unk_00E8; //0x00E8 + bool unk_00E9; //0x00E9 + bool unk_00EA; //0x00EA + bool unk_00EB; //0x00EB + bool unk_00EC; //0x00EC + bool unk_00ED; //0x00ED + bool unk_00EE; //0x00EE + bool unk_00EF; //0x00EF + bool unk_00F0; //0x00F0 + bool unk_00F1; //0x00F1 + bool unk_00F2; //0x00F2 + bool unk_00F3; //0x00F3 + bool unk_00F4; //0x00F4 + bool unk_00F5; //0x00F5 + bool unk_00F6; //0x00F6 + bool unk_00F7; //0x00F7 + bool unk_00F8; //0x00F8 + bool unk_00F9; //0x00F9 + bool unk_00FA; //0x00FA + bool unk_00FB; //0x00FB + uint32_t unk_00FC; //0x00FC + uint32_t m_mobile_ring_state; //0x0100 + int32_t m_player_team; //0x0104 + float m_air_drag_multiplier; //0x0108 + uint32_t m_max_health; //0x010C + uint32_t m_max_armor; //0x0110 + uint32_t m_jack_speed; //0x0114 + uint16_t m_player_is_targetable_by_team; //0x0118 + uint32_t m_override_receive_chat; //0x011C + uint32_t m_override_send_chat; //0x0120 + bool unk_0124; //0x0124 + bool unk_0125; //0x0125 + bool unk_0126; //0x0126 + bool unk_0127; //0x0127 + uint16_t m_spectating_net_id; //0x0128 + uint8_t m_antagonistic_to_player_id; //0x012C + uint8_t m_tutorial_index; //0x012B + uint8_t m_tutorial_instance_id; //0x012C + char pad_012D[2]; //0x012D + float m_microphone_volume; //0x0130 + uint32_t m_voice_channel; //0x0134 + bool m_is_overriding_voice_proximity; //0x0138 + char pad_0139[7]; //0x0139 + float m_voice_proximity_x; //0x0140 + float m_voice_proximity_y; //0x0144 + float m_voice_proximity_z; //0x0148 + float m_voice_proximity_radius_maybe; //0x014C + uint32_t unk_0150; //0x0150 + uint32_t m_vehicle_weapon_index; //0x0154 + bool m_has_vehicle_weapon_index; //0x0158 + uint32_t m_decor_count; //0x015C + uint32_t m_decor_type[3]; // 0x0160 + uint32_t m_decor_value[3]; // 0x016C + uint32_t m_decor_name_hash[3]; // 0x0178 + bool m_friendly_fire_allowed; //0x0184 + bool unk_0185; //0x0185 + uint8_t m_current_garage_instance_index; //0x0186 + uint8_t m_current_property_id; //0x0187 + uint8_t unk_0188; //0x0188 + uint8_t m_city_density; //0x0189 + bool m_battle_aware; //0x018A + bool m_vehicle_jump_down; //0x018B + float m_weapon_defence_modifier; //0x018C + float m_weapon_defence_modifier_2; //0x0190 + bool m_is_overriding_population_control_sphere; //0x0194 + char pad_0195[11]; //0x0195 + float m_population_control_sphere_x; //0x01A0 + float m_population_control_sphere_y; //0x01A4 + float m_population_control_sphere_z; //0x01A8 + uint16_t unk_01AC; //0x01AC + uint16_t unk_01AE; //0x01AE + uint16_t unk_01B0; //0x01B0 + bool new_01B2; + bool new_01B3; + bool pad_01B2; //0x01B2 + bool unk_01B3; //0x01B3 + bool m_no_collision; //0x01B4 + bool unk_01B5; //0x01B5 + bool unk_01B6; //0x01B6 + bool m_super_jump; //0x01B7 + bool unk_01B8; //0x01B8 + bool unk_01B9; //0x01B9 + uint16_t unk_01BA; //0x01BA + uint32_t unk_01BC; //0x01BC + float unk_01C0; //0x01C0 + float m_weapon_damage_modifier; //0x01C4 + float m_melee_weapon_damage_modifier; //0x01C8 + float unk_01CC; //0x01CC + bool unk_01D0; //0x01D0 + char pad_01D1[11]; //0x01D1 + float unk_01E0; //0x01E0 + float unk_01E4; //0x01E4 + float unk_01E8; //0x01E8 + uint32_t unk_01EC; //0x01EC + uint8_t unk_01F0; //0x01F0 + uint8_t unk_01F1; //0x01F1 + bool unk_01F2; //0x01F2 + uint8_t unk_01F3; //0x01F3 + bool unk_01F4; //0x01F4 + bool unk_01F5; //0x01F5 +}; //Size: 0x01F8 +static_assert(sizeof(CPlayerGameStateDataNode) == 0x1F8); diff --git a/src/types/network/sync/nodes/player/CPlayerGamerDataNode.hpp b/src/types/network/sync/nodes/player/CPlayerGamerDataNode.hpp new file mode 100644 index 0000000..eff95a9 --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerGamerDataNode.hpp @@ -0,0 +1,43 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +struct ClanData +{ + int64_t m_clan_member_id; //0x0000 + int64_t m_clan_id; //0x0008 + int32_t m_clan_color; //0x0010 + int32_t m_clan_member_count; //0x0014 + int32_t m_clan_created_time; //0x0018 + bool m_is_system_clan; //0x001C + bool m_is_clan_open; //0x001D + char m_clan_name[25]; //0x001E + char m_clan_tag[5]; //0x0037 + char m_clan_motto[65]; //0x003C + char pad_007D[3]; //0x007D + int64_t m_clan_id_2; //0x0080 + char m_clan_rank_name[25]; //0x0088 + char pad_00A1[3]; //0x00A1 + int32_t m_clan_rank_order; //0x00A4 + int64_t m_clan_rank_flags; //0x00A8 + char unk_00B0[8]; //0x00B0 +}; + +class CPlayerGamerDataNode : CSyncDataNodeInfrequent +{ +public: + ClanData m_CanData; //0x00C0 + bool m_NeedCrewRankSysFlags; //0x0178 + bool m_NeedCrewRankTitle; //0x0179 + char m_CrewRankTitle[25]; //0x017A + bool m_HasStartedTransition; //0x0193 + bool m_HasTransitionInfo; //0x0194 + char m_TransitionInfoBuffer[169]; //0x0195 + int m_PlayerPrivilegeFlags; //0x0240 + uint32_t m_MatchmakingGroup; //0x0244 + bool m_NeedMuteData; //0x0248 + int32_t m_MuteCount; //0x024C + int32_t m_MuteTalkersCount; //0x0250 + uint32_t m_unk; //0x0254 + int32_t m_AccountId; //0x0258 +}; +static_assert(sizeof(CPlayerGamerDataNode) == 0x260); \ No newline at end of file diff --git a/src/types/network/sync/nodes/player/CPlayerPedGroupDataNode.hpp b/src/types/network/sync/nodes/player/CPlayerPedGroupDataNode.hpp new file mode 100644 index 0000000..5995db8 --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerPedGroupDataNode.hpp @@ -0,0 +1,31 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CGroup; +class CPed; +struct CGroupMember +{ + std::int16_t m_ObjectId; + CPed* m_Ped; // this isn't serialized +}; +static_assert(sizeof(CGroupMember) == 0x10); + +// this node is kinda sus, need to check if the fields are in the right order +class CPlayerPedGroupDataNode : CSyncDataNodeInfrequent +{ +public: + char m_unused[0x10]; // 0xC0 + CGroup* m_Group; // 0xD0 (not serialized) + CGroupMember m_Members[7]; // 0xD8 + CGroupMember m_Leader; // 0x148 + char m_unused2[8]; // 0x158 + float m_MaxSeparation; // 0x160 + char m_unused3[0xC]; // 0x164 + int m_PopType; // 0x170 + bool m_NeedsGroupEventScan; // 0x175 + char m_unused4[6]; // 0x176 + int m_FormationType; // 0x17C + float m_FormationDistance; // 0x180 + char m_unused5[0xC]; // 0x184 +}; +static_assert(sizeof(CPlayerPedGroupDataNode) == 0x190); \ No newline at end of file diff --git a/src/types/network/sync/nodes/player/CPlayerSectorPosNode.hpp b/src/types/network/sync/nodes/player/CPlayerSectorPosNode.hpp new file mode 100644 index 0000000..efdcdf4 --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerSectorPosNode.hpp @@ -0,0 +1,23 @@ +#pragma once +#include +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CPlayerSectorPosNode : CSyncDataNodeFrequent +{ +public: + // this is not a vector! + float m_SectorPosX; // 0xC0 + float m_SectorPosY; // 0xC4 + float m_SectorPosZ; // 0xC8 + bool m_IsStandingOnEntity; //0x00CC + bool unk_00CD; //0x00CD + bool unk_00CE; //0x00CE + char pad_00CF[1]; //0x00CF + uint16_t m_EntityStandingOn; //0x00D0 + char pad_00D2[12]; //0x00D2 + rage::fvector3 m_StandingOnEntityOffset; //0x00E0 + char pad_00EC[4]; //0x00EC + uint32_t m_StealthNoise; //0x00F4 +}; //Size: 0x00F8 +static_assert(sizeof(CPlayerSectorPosNode) == 0xF8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/player/CPlayerWantedAndLOSDataNode.hpp b/src/types/network/sync/nodes/player/CPlayerWantedAndLOSDataNode.hpp new file mode 100644 index 0000000..d6f1207 --- /dev/null +++ b/src/types/network/sync/nodes/player/CPlayerWantedAndLOSDataNode.hpp @@ -0,0 +1,28 @@ +#pragma once +#include +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +// very sus, probably best to disable this for now +#if 0 +class CPlayerWantedAndLOSDataNode : CSyncDataNodeInfrequent +{ +public: + rage::fvector3 m_wanted_position; // 0xC0 + int m_time_in_prev_pursuit; // 0xCC + rage::fvector3 m_unk_position; // 0xD0 + int m_time_in_pursuit; // 0xDC + int m_wanted_level; // 0xE0 + int m_unk_wanted_level; // 0xE4 + int m_current_time; // 0xE8 + int m_unk_player_bitset; // 0xEC + int m_pursuit_start_time; // 0xF0 + uint8_t m_fake_wanted_level; // 0xF4 + bool m_cops_cant_see_player; // 0xF5 + bool m_is_evading; // 0xF6 + bool m_pending_wanted_level; // 0xF7 + bool m_unk3; // 0xF8 + uint8_t m_unk_player_index; // 0xF9 +}; +static_assert(sizeof(CPlayerWantedAndLOSDataNode) == 0x100); +#endif \ No newline at end of file diff --git a/src/types/network/sync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp b/src/types/network/sync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp new file mode 100644 index 0000000..9d5e4d7 --- /dev/null +++ b/src/types/network/sync/nodes/proximity_migrateable/CGlobalFlagsDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CGlobalFlagsDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_GlobalFlags; //0x00C0 + uint32_t m_OwnershipToken; //0x00C4 +}; //Size: 0x00C8 +static_assert(sizeof(CGlobalFlagsDataNode) == 0xC8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/proximity_migrateable/CMigrationDataNode.hpp b/src/types/network/sync/nodes/proximity_migrateable/CMigrationDataNode.hpp new file mode 100644 index 0000000..057f5b1 --- /dev/null +++ b/src/types/network/sync/nodes/proximity_migrateable/CMigrationDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CMigrationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_ClonedState; //0x00C0 + uint32_t m_ClonedPlayersThatLeft; //0x00C4 + uint32_t m_UnsyncedNodes; //0x00C8 +}; //Size: 0x00CC +static_assert(sizeof(CMigrationDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/proximity_migrateable/CSectorDataNode.hpp b/src/types/network/sync/nodes/proximity_migrateable/CSectorDataNode.hpp new file mode 100644 index 0000000..9440bec --- /dev/null +++ b/src/types/network/sync/nodes/proximity_migrateable/CSectorDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CSectorDataNode : CSyncDataNodeFrequent +{ +public: + uint16_t m_SectorX; //0xC0 + uint16_t m_SectorY; //0xC2 + uint16_t m_SectorZ; //0xC4 +}; +static_assert(sizeof(CSectorDataNode) == 0xC8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp b/src/types/network/sync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp new file mode 100644 index 0000000..41991aa --- /dev/null +++ b/src/types/network/sync/nodes/proximity_migrateable/CSectorPositionDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CSectorPositionDataNode : CSyncDataNodeFrequent +{ +public: + float m_SectorPosX; //0x00C0 + float m_SectorPosY; //0x00C4 + float m_SectorPosZ; //0x00C8 +}; //Size: 0x00CC +static_assert(sizeof(CSectorPositionDataNode) == 0xD0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/task/CClonedGeneralSweepInfo.hpp b/src/types/network/sync/nodes/task/CClonedGeneralSweepInfo.hpp new file mode 100644 index 0000000..bfc1c39 --- /dev/null +++ b/src/types/network/sync/nodes/task/CClonedGeneralSweepInfo.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include + +#pragma pack(push, 1) +class CClonedGeneralSweepInfo +{ +public: + char pad_0000[48]; //0x0000 + float m_track_point[4]; //0x0030 + uint16_t m_tracked_entity; //0x0040 + char pad_0042[14]; //0x0042 + float m_delta_per_second; //0x0050 + char pad_0054[4]; //0x0054 + uint32_t m_low_clip; //0x0058 + uint32_t m_med_clip; //0x005C + uint32_t m_high_clip; //0x0060 + uint32_t m_clip_set_id; //0x0064 + uint32_t m_sweep_flags; //0x0068 + float m_turn_rate; //0x006C +}; +static_assert(sizeof(CClonedGeneralSweepInfo) == 0x70); +#pragma pack(pop) \ No newline at end of file diff --git a/src/types/network/sync/nodes/task/ClonedTakeOffPedVariationInfo.hpp b/src/types/network/sync/nodes/task/ClonedTakeOffPedVariationInfo.hpp new file mode 100644 index 0000000..5d98385 --- /dev/null +++ b/src/types/network/sync/nodes/task/ClonedTakeOffPedVariationInfo.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#if 0 + +#pragma pack(push, 1) +class ClonedTakeOffPedVariationInfo +{ +public: + char pad_0000[48]; //0x0000 + rage::fvector3 m_attach_offset; //0x0030 + char pad_003C[4]; //0x003C + rage::fvector3 m_velocity; //0x0040 + char pad_004C[4]; //0x004C + rage::fvector3 m_attach_offset_rotation; //0x0050 + char pad_005C[4]; //0x005C + uint32_t m_clip_set_id; //0x0060 + uint32_t m_clip_id_ped; //0x0064 + uint32_t m_clip_id_prop; //0x0068 + int32_t m_variation_component; //0x006C + uint32_t m_prop_hash; //0x0070 + int32_t m_attach_bone_tag; //0x0074 + float m_blend_in_delta_ped; //0x0078 + float m_blend_in_delta_prop; //0x007C + float m_phase_to_blend_out; //0x0080 + float m_blend_out_delta; //0x0084 + float m_force_to_apply; //0x0088 + uint8_t m_variation_drawable_id; //0x008C + uint8_t m_variation_drawable_alt_id; //0x008D + char pad_008E[1]; //0x008E Drawable texture maybe? + uint8_t m_running_flags; //0x008F +}; //Size: 0x0090 +static_assert(sizeof(ClonedTakeOffPedVariationInfo) == 0x90); +#pragma pack(pop) +#endif \ No newline at end of file diff --git a/src/types/network/sync/nodes/train/CTrainGameStateDataNode.hpp b/src/types/network/sync/nodes/train/CTrainGameStateDataNode.hpp new file mode 100644 index 0000000..a4f6bb2 --- /dev/null +++ b/src/types/network/sync/nodes/train/CTrainGameStateDataNode.hpp @@ -0,0 +1,28 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CTrainGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_IsEngine; //0x00C0 + bool m_IsCaboose; //0x00C1 + bool m_IsMissionTrain; //0x00C2 + bool m_Direction; //0x00C3 + bool m_HasPassengerCarriages; //0x00C4 + bool m_RenderDerailed; //0x00C5 + bool unk_00C6; //0x00C6 + bool unk_00C7; //0x00C7 + uint16_t m_EngineId; //0x00C8 + int8_t m_TrainConfigIndex; //0x00CA + int8_t m_CarriageConfigIndex; //0x00CB + int8_t m_TrackId; //0x00CC + char pad_00CD[3]; //0x00CD + float m_DistanceFromEngine; //0x00D0 + float m_CruiseSpeed; //0x00D4 + uint16_t m_LinkedToBackwardId; //0x00D8 + uint16_t m_LinkedToForwardId; //0x00DA + uint32_t m_TrainState; //0x0DC + bool unk_00E0; //0x00E0 + bool m_ForceDoorsOpen; //0x0E1 +}; //Size: 0x00E4 +static_assert(sizeof(CTrainGameStateDataNode) == 0xE8); \ No newline at end of file diff --git a/src/types/network/sync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp new file mode 100644 index 0000000..cbc9c69 --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleComponentReservationDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleComponentReservationDataNode : CSyncDataNodeInfrequent +{ +public: + bool m_HasComponentReservations; //0x00C0 + uint32_t m_NumPedsUsingComponent; //0x00C4 + uint16_t m_PedsUsingComponent[32]; //0x00C8 +}; //Size: 0x00C8 +static_assert(sizeof(CVehicleComponentReservationDataNode) == 0x108); diff --git a/src/types/network/sync/nodes/vehicle/CVehicleControlDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleControlDataNode.hpp new file mode 100644 index 0000000..8f5c65b --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleControlDataNode.hpp @@ -0,0 +1,39 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleControlDataNode : CSyncDataNodeFrequent +{ +public: + uint32_t m_NumWheels; + uint32_t dwordC4; + uint32_t m_BrakeControl; + uint32_t dwordCC; + uint32_t m_RoadNodeAddress; + bool m_KersActive; + bool m_BringingVehicleToHalt; + float m_HaltDistance; + bool m_ControlVerticalVelocity; + bool m_HasSuspensionData; + bool byteDE; + float m_SuspensionHeights[10]; + bool byte108; + bool byte109; + bool byte10A; + bool byte10B; + bool byte10C; + bool byte10D; + bool byte10E; + float float110; + uint32_t dword114; + char byte118; + bool m_IsSubmarineCar; + char gap11A[2]; + float m_RudderRotationX; + float m_RudderRotationY; + float m_RudderRotationZ; + char byte128; + char byte129; + char pad[5]; +}; +static_assert(sizeof(CVehicleControlDataNode) == 0x130); diff --git a/src/types/network/sync/nodes/vehicle/CVehicleCreationDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleCreationDataNode.hpp new file mode 100644 index 0000000..63f4007 --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleCreationDataNode.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleCreationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_PopType; //0x00C0 + uint32_t m_RandomSeed; //0x00C4 + uint32_t m_ModelHash; //0x00C8 + uint32_t m_VehicleStatus; //0x00CC + uint32_t m_MaxHealth; //0x00D0 + uint32_t m_CreationToken; //0x00D4 + bool m_CarBudget; //0x00D8 + bool m_NeedsToBeHotwired; //0x00D9 + bool m_TiresDontBurst; //0x00DA + char pad_00DB[165]; //0x00DB +}; //Size: 0x0180 +static_assert(sizeof(CVehicleCreationDataNode) == 0x180); diff --git a/src/types/network/sync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp new file mode 100644 index 0000000..30fa6f8 --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleDamageStatusDataNode.hpp @@ -0,0 +1,30 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleDamageStatusDataNode : CSyncDataNodeInfrequent +{ +public: + uint8_t m_bullet_counts[6]; // 0xC0 + uint8_t m_front_damage_level; // 0xC6 + uint8_t m_rear_damage_level; // 0xC7 + uint8_t m_left_damage_level; // 0xC8 + uint8_t m_right_damage_level; // 0xC9 + uint8_t m_rear_left_damage_level; // 0xCA + uint8_t m_rear_right_damage_level; // 0xCB + uint8_t m_windows_state[8]; // 0xCC + float m_unk2[8]; // 0xD4 + bool m_sirens_broken[20]; // 0xF4 + bool m_lights_broken[20]; // 0x108 + uint8_t m_front_bumper_state; // 0x11E + uint8_t m_rear_bumper_state; // 0x11F + uint8_t m_unk3[8]; // 0x120 + bool m_has_damage_levels; // 0x128 + bool m_has_broken_lights; // 0x129 + bool m_has_broken_sirens; // 0x12A + bool m_has_broken_windows; // 0x12B + bool m_has_broken_bumpers; // 0x12C + bool m_has_bullets; // 0x12D + bool m_has_unk; // 0x12E +}; //Size: 0x00C8 +static_assert(sizeof(CVehicleDamageStatusDataNode) == 0x130); diff --git a/src/types/network/sync/nodes/vehicle/CVehicleGadgetDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleGadgetDataNode.hpp new file mode 100644 index 0000000..ec284b4 --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleGadgetDataNode.hpp @@ -0,0 +1,35 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +enum eVehicleGadgetType : uint32_t +{ + FORKS, + SEARCH_LIGHT, + PICK_UP_ROPE_WITH_HOOK, + PICK_UP_ROPE_WITH_MAGNET, + DIGGER_ARM, + HANDLER_FRAME, + BOMB_BAY, +}; + +struct CVehicleGadgetData +{ + eVehicleGadgetType m_Type; //0x0000 + uint8_t m_Data[94]; //0x0004 +}; //Size: 0x64 +static_assert(sizeof(CVehicleGadgetData) == 0x64); + +class CVehicleGadgetDataNode : CSyncDataNodeFrequent +{ +public: + bool m_HasParentOffset; //0x00C0 + char pad_00C1[15]; //0x00C1 + uint32_t m_ParentOffsetX; //0x00D0 + uint32_t m_ParentOffsetY; //0x00D4 + uint32_t m_ParentOffsetZ; //0x00D8 + uint32_t m_ParentOffsetW; //0x00DC + uint32_t m_GadgetCount; //0x00E0 + CVehicleGadgetData m_GadgetData[2]; //0x00E4 +}; //Size: 0x01AC +static_assert(sizeof(CVehicleGadgetDataNode) == 0x1B0); \ No newline at end of file diff --git a/src/types/network/sync/nodes/vehicle/CVehicleGameStateDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleGameStateDataNode.hpp new file mode 100644 index 0000000..2032bcd --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleGameStateDataNode.hpp @@ -0,0 +1,78 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleGameStateDataNode : CSyncDataNodeInfrequent +{ +public: + float m_unk66; + float m_unk32; + float m_unk200; + float m_unk204; + int m_radio_station; + uint32_t m_lock_status; + uint32_t m_unk17; + uint32_t m_unbreakable_doors; + uint32_t m_open_windows; + uint32_t m_unk34; + uint8_t m_unk49[4]; + unsigned int m_unk62_1; + uint32_t m_unk240; + uint16_t m_unk35; + uint16_t m_unk37[2]; + uint16_t m_unk39; + uint8_t m_unk252; + char m_light_state; + uint8_t m_unk21; + char m_unk27[8]; + uint8_t m_doors_open; + char m_door_positions[8]; + uint32_t m_locked_players; + uint8_t m_is_engine_on; + bool m_is_engine_starting; + bool unk4; + bool m_handbrake; + bool m_unk6; + uint8_t m_siren_on; + bool m_unk1; + uint8_t m_unk13; + uint8_t m_unk12; + uint8_t m_unk14; + uint8_t m_unk25; + uint8_t m_unk26; + bool m_no_longer_needed; + uint8_t m_unk28; + uint8_t m_unk33; + uint8_t m_unk30; + bool m_lights_on; + bool m_highbeams_on; + char m_unk43; + char m_unk44; + bool m_unk7; + char m_unk29; + char m_unk45; + char m_unk46; + char m_unk47; + char m_unk48; + uint8_t m_unk38; + char m_unk51; + bool m_has_been_owned_by_player; + char m_unk53; + char m_unk54; + char m_unk55; + char m_unk56; + char m_unk57; + char m_unk58; + char m_unk61; + uint8_t m_unk62; + char m_unk63; + char m_unk64; + char m_unk67; + char m_unk68; + char m_unk138; + char m_unk139; + char m_unk59; + char m_unk60; + char pad[6]; +}; +static_assert(sizeof(CVehicleGameStateDataNode) == 0x148); \ No newline at end of file diff --git a/src/types/network/sync/nodes/vehicle/CVehicleHealthDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleHealthDataNode.hpp new file mode 100644 index 0000000..ae8eb26 --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleHealthDataNode.hpp @@ -0,0 +1,33 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleHealthDataNode : CSyncDataNodeInfrequent +{ +public: + float m_tires_unk14[10]; //0x00C0 + float m_tires_open_wheel_heat[10]; //0x00E8 + bool m_tires_bursted[10]; //0x0110 + bool m_tires_bursted_on_rim[10]; //0x011A + bool m_tires_unk11[10]; //0x0124 + bool m_tires_unk12[10]; //0x012E + uint64_t m_unk24; //0x0138 + int32_t m_engine_health; //0x0140 + uint32_t m_petrol_tank_health; //0x0144 + uint32_t m_num_tires; //0x0148 + bool m_tires_fine; //0x014C + bool m_unk7; //0x014D + char pad_014E[1]; //0x014E + bool m_health_changed; //0x014F + uint32_t m_health; //0x0150 + uint32_t m_body_health; //0x0154 + uint32_t m_damage_weapon; //0x0158 + int16_t m_damager_net_id; //0x015C + uint8_t m_total_repairs; //0x015E + uint8_t m_unk21; //0x015F + bool m_unk1; //0x0160 + bool m_unk2; //0x0161 + bool m_body_health_changed; //0x0162 + uint32_t m_pad2; // 0x0164 +}; //Size: 0x0380 +static_assert(sizeof(CVehicleHealthDataNode) == 0x168); \ No newline at end of file diff --git a/src/types/network/sync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp new file mode 100644 index 0000000..ad6d10c --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleProximityMigrationDataNode.hpp @@ -0,0 +1,19 @@ +#pragma once +#include "types/rage/vector.hpp" +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleProximityMigrationDataNode : CProjectBaseSyncDataNode +{ +public: + uint32_t m_MaxOccupants; + bool m_HasOccupants[16]; + int16_t m_Occupants[16]; + char pad[16]; + bool m_OverridePosition; + rage::fvector3 m_Position; + std::int32_t m_VelocityX; + std::int32_t m_VelocityY; + std::int32_t m_VelocityZ; + char pad3[352]; +}; //Size: 0x0180 +static_assert(sizeof(CVehicleProximityMigrationDataNode) == 0x288); \ No newline at end of file diff --git a/src/types/network/sync/nodes/vehicle/CVehicleSteeringDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleSteeringDataNode.hpp new file mode 100644 index 0000000..418d08e --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleSteeringDataNode.hpp @@ -0,0 +1,11 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleSteeringDataNode : CSyncDataNodeFrequent +{ +public: + float m_SteeringHandle; // 0xC0 + char pad[4]; // 0xC4 +}; //Size: 0x00C8 +static_assert(sizeof(CVehicleSteeringDataNode) == 0xC8); diff --git a/src/types/network/sync/nodes/vehicle/CVehicleTaskDataNode.hpp b/src/types/network/sync/nodes/vehicle/CVehicleTaskDataNode.hpp new file mode 100644 index 0000000..dbcec7e --- /dev/null +++ b/src/types/network/sync/nodes/vehicle/CVehicleTaskDataNode.hpp @@ -0,0 +1,12 @@ +#pragma once +#include +#include "types/network/sync/CProjectBaseSyncDataNode.hpp" + +class CVehicleTaskDataNode : CSyncDataNodeInfrequent +{ +public: + uint32_t m_TaskType; // 0xC0 + uint32_t m_TaskDataSize; // 0xC4 + char m_TaskData[255]; // 0xC8 +}; //Size: 0x0180 +static_assert(sizeof(CVehicleTaskDataNode) == 0x1C8); \ No newline at end of file diff --git a/src/types/rage/datBitBuffer.hpp b/src/types/rage/datBitBuffer.hpp new file mode 100644 index 0000000..4ad6b76 --- /dev/null +++ b/src/types/rage/datBitBuffer.hpp @@ -0,0 +1,228 @@ +#pragma once +#include + +namespace rage +{ + class datBitBuffer + { + public: + datBitBuffer(void* data, uint32_t size, bool read = false) + { + m_Data = data; + m_BitOffset = 0; + m_MaxBit = size * 8; + m_BitsRead = 0; + m_CurBit = 0; + m_HighestBitsRead = 0; + m_FlagBits = read ? 1 : 0; + } + + static void ReadBitsSingle(uint8_t* data, int* out, int size, int offset) + { + int v5; // r11d + int v6; // ebx + uint8_t* v7; // r14 + char v8; // cl + int v9; // r11d + unsigned int v10; // r8d + int v11; // esi + __int64 v12; // r9 + + v5 = offset; + v6 = 1; + v7 = &data[offset >> 3]; + v8 = offset & 7; + if (size > 0) + v5 = size + offset - 1; + v9 = (v5 >> 3) - (offset >> 3); + v10 + = (unsigned __int8)(*v7 << v8); + v11 = 8; + if (size > 8) + { + v12 = 1i64; + do + { + if (v12 > v9) + break; + ++v6; + v10 + = (v10 << 8) | (v7[v12++] << v8); + v11 += 8; + } while (v11 < size); + } + if (v6 <= v9) + v10 + |= v7[v6] >> (8 - v8); + *out = v10 >> (((size + 7) & 0xF8) - size); + } + + static void WriteBitsSingle(uint8_t* data, int value, int size, int offset) + { + uint8_t* v4; // r10 + int v5; // r9d + unsigned int v6; // r11d + uint8_t* v7; // r10 + unsigned int v8; // r11d + int v9; // ebx + __int64 v10; // rdx + char v11; // cl + + v4 = &data[(__int64)offset >> 3]; + v5 = offset & 7; + v6 = value << (32 - size); + *v4 = ((v6 >> 24) >> v5) | *v4 & ~((unsigned int)(-1 << (32 - size)) >> 24 >> v5); + v7 = v4 + 1; + v8 = v6 << (8 - v5); + v9 = -1 << (32 - size) << (8 - v5); + if (8 - v5 < size) + { + v10 + = ((unsigned int)(size - (8 - v5) - 1) >> 3) + 1; + do + { + v11 = (v8 >> 24) | *v7 & ~(v9 >> 24); + v8 <<= 8; + *v7++ = v11; + v9 <<= 8; + --v10; + } while (v10); + } + } + + inline bool IsReadBuffer() + { + return m_FlagBits & 1; + } + + inline bool IsSizeCalculator() + { + return m_FlagBits & 2; + } + + void Seek(int bits, bool read) + { + m_BitsRead += bits; + + if (read) + { + if (m_HighestBitsRead > m_CurBit) + m_CurBit = m_HighestBitsRead; + } + else + { + if (m_BitsRead > m_CurBit) + m_CurBit = m_BitsRead; + } + } + + inline bool ReadDword(int* out, int size) + { + if (IsSizeCalculator()) + return false; + + if (m_BitsRead + size > (IsReadBuffer() ? m_MaxBit : m_CurBit)) + return false; + + ReadBitsSingle(static_cast(m_Data), out, size, m_BitsRead + m_BitOffset); + Seek(size, true); + return true; + } + + inline bool WriteDword(int val, int size) + { + if (IsReadBuffer()) + return false; + + if (m_BitsRead + size > m_MaxBit) + return false; + + if (!IsSizeCalculator()) + WriteBitsSingle(static_cast(m_Data), val, size, m_BitsRead + m_BitOffset); + Seek(size, false); + return true; + } + + inline bool ReadQword(uint64_t* out, int size) + { + if (size <= 32) + return ReadDword(reinterpret_cast(out), size); + + return ReadDword(reinterpret_cast(out), 32) && !ReadDword(reinterpret_cast(out) + 1, size - 32); + } + + inline bool WriteQword(uint64_t value, int size) + { + if (size <= 32) + return WriteDword(static_cast(value), size); + + int low = (int)(value) & 0xFFFFFFFF; + int high = (int)((uint64_t)value >> 32); + + return WriteDword(low, 32) && WriteDword(high, size - 32); + } + + inline bool ReadInt64(int64_t* value, int size) + { + unsigned int last_bit{}; + uint64_t rest{}; + + if (!ReadQword((uint64_t*)&last_bit, 1) || ReadQword(&rest, size - 1)) + return false; + + *value = ((uint64_t)last_bit << 63) | rest ^ -(int64_t)last_bit; + return true; + } + + inline bool WriteInt64(int64_t value, int size) + { + auto last_bit = value >> 63; + if (!WriteQword(last_bit, 1) || !WriteQword((uint64_t)value ^ -(__int64)(unsigned int)last_bit, size - 1)) + return false; + + return true; + } + + // unsigned + // TODO: signed likely only works for 64 bit values! + template + T Read(int size, bool _signed = false) + { + static_assert(sizeof(T) <= 8); + + uint64_t data{}; + int64_t data_signed{}; + if (_signed) + ReadInt64(&data_signed, size); + else + ReadQword(&data, size); + + if (_signed) + return T(data_signed); + else + return T(data); + } + + // unsigned + // TODO: signed likely only works for 64 bit values! + template + void Write(T data, int size, bool _signed = false) + { + static_assert(sizeof(T) <= 8); + + if (_signed) + WriteInt64(int64_t(data), size); + else + WriteQword(uint64_t(data), size); + } + + public: + void* m_Data; //0x0000 + uint32_t m_BitOffset; //0x0008 + uint32_t m_MaxBit; //0x000C + uint32_t m_BitsRead; //0x0010 + uint32_t m_CurBit; //0x0014 + uint32_t m_HighestBitsRead; //0x0018 + uint8_t m_FlagBits; //0x001C + }; +} \ No newline at end of file diff --git a/src/types/rage/fwExtensibleBase.hpp b/src/types/rage/fwExtensibleBase.hpp new file mode 100644 index 0000000..986cc32 --- /dev/null +++ b/src/types/rage/fwExtensibleBase.hpp @@ -0,0 +1,15 @@ +#pragma once +#include "fwExtensionContainer.hpp" +#include "fwRefAwareBase.hpp" + +namespace rage +{ + class fwExtensibleBase : public fwRefAwareBase + { + public: + fwExtensionContainer* m_ExtensionContainer; // 0x0010 + void* m_ExtensibleUnk; // 0x0018 + }; //Size: 0x0020 + static_assert(sizeof(fwExtensibleBase) == 0x20); + +} \ No newline at end of file diff --git a/src/types/rage/fwExtension.hpp b/src/types/rage/fwExtension.hpp new file mode 100644 index 0000000..e220bf7 --- /dev/null +++ b/src/types/rage/fwExtension.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace rage +{ + class fwExtension + { + public: + virtual ~fwExtension() = default; + virtual void unk_0x08() = 0; + virtual void unk_0x10() = 0; + virtual uint32_t GetId() = 0; + }; //Size: 0x0008 + static_assert(sizeof(fwExtension) == 0x8); +} \ No newline at end of file diff --git a/src/types/rage/fwExtensionContainer.hpp b/src/types/rage/fwExtensionContainer.hpp new file mode 100644 index 0000000..0b6c68a --- /dev/null +++ b/src/types/rage/fwExtensionContainer.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "fwExtension.hpp" + +namespace rage +{ + class fwExtensionContainer + { + public: + fwExtension* m_Entry; //0x0000 + fwExtensionContainer* m_Next; //0x0008 + }; //Size: 0x0010 + static_assert(sizeof(fwExtensionContainer) == 0x10); +} \ No newline at end of file diff --git a/src/types/rage/fwRefAwareBase.hpp b/src/types/rage/fwRefAwareBase.hpp new file mode 100644 index 0000000..3ab90e7 --- /dev/null +++ b/src/types/rage/fwRefAwareBase.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "datBase.hpp" +#include "fwRefAwareBaseImpl.hpp" + +namespace rage +{ + + class fwRefAwareBase : public fwRefAwareBaseImpl + { + }; + static_assert(sizeof(fwRefAwareBase) == 0x10); + +} \ No newline at end of file diff --git a/src/types/rage/fwRefAwareBaseImpl.hpp b/src/types/rage/fwRefAwareBaseImpl.hpp new file mode 100644 index 0000000..24e0caa --- /dev/null +++ b/src/types/rage/fwRefAwareBaseImpl.hpp @@ -0,0 +1,11 @@ +#pragma once + +namespace rage +{ + template + class fwRefAwareBaseImpl : public T + { + private: + void* m_Ref; // 0x08 + }; +} \ No newline at end of file diff --git a/src/types/script/CGameScriptObjInfo.hpp b/src/types/script/CGameScriptObjInfo.hpp new file mode 100644 index 0000000..e489d5b --- /dev/null +++ b/src/types/script/CGameScriptObjInfo.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "CGameScriptId.hpp" + +class CGameScriptObjInfo +{ +public: + virtual ~CGameScriptObjInfo() = default; + + int m_NetworkId; // 0x8 (the one you get from VEH_TO_NET etc., not the network object id) + uint16_t m_Unk; // 0xC + CGameScriptId m_ScriptId; // 0x10 +}; +static_assert(sizeof(CGameScriptObjInfo) == 0x50); \ No newline at end of file diff --git a/src/types/script/ScriptEvent.cpp b/src/types/script/ScriptEvent.cpp index d2e190c..2a8460f 100644 --- a/src/types/script/ScriptEvent.cpp +++ b/src/types/script/ScriptEvent.cpp @@ -5,6 +5,6 @@ void SCRIPT_EVENT::Send() { auto size = __SizeOfEvent; __SizeOfEvent = 0; - SCRIPT::_SEND_TU_SCRIPT_EVENT_NEW(1, this, size / sizeof(std::uint32_t), PlayerBits, EventIndex); + SCRIPT::_SEND_TU_SCRIPT_EVENT_NEW(1, this, size / sizeof(std::uint64_t), PlayerBits, EventIndex); __SizeOfEvent = size; }