From ad824270b961feaf08c86f01c57797444e642c49 Mon Sep 17 00:00:00 2001 From: Ryan <80224521+Rxann@users.noreply.github.com> Date: Wed, 7 Aug 2024 20:11:50 -0400 Subject: [PATCH] Improved Node Classes & More (#33) --- classes.cpp | 10 ++ entity/CDynamicEntity.hpp | 21 +++ entity/CEntity.hpp | 9 ++ entity/fwEntity.hpp | 17 +- network/CFriend.hpp | 10 ++ network/netObject.hpp | 4 +- network/rlGamerHandle.cpp | 4 +- network/rlGamerHandle.hpp | 4 +- network/sync/animal/CAnimalCreationData.hpp | 15 ++ network/sync/ped/CPedCreationData.hpp | 2 +- network/sync/ped/CPedTaskTreeData.hpp | 8 +- .../sync/player/CPlayerCameraUncommonData.hpp | 16 ++ network/sync/player/CPlayerCreationData.hpp | 10 ++ .../player/CPlayerGameStateUncommonData.hpp | 22 +++ .../projectile/CProjectileCreationData.hpp | 30 ++++ network/sync/propset/CPropSetCreationData.hpp | 13 ++ .../CVehicleProximityMigrationData.hpp | 4 +- ped/CPed.hpp | 9 +- physical/CPhysical.hpp | 9 ++ rage/datBitBuffer.hpp | 44 +++++- rage/tlsContext.hpp | 10 +- rage/vector.hpp | 147 +++++++++--------- 22 files changed, 312 insertions(+), 106 deletions(-) create mode 100644 entity/CDynamicEntity.hpp create mode 100644 entity/CEntity.hpp create mode 100644 network/CFriend.hpp create mode 100644 network/sync/animal/CAnimalCreationData.hpp create mode 100644 network/sync/player/CPlayerCameraUncommonData.hpp create mode 100644 network/sync/player/CPlayerCreationData.hpp create mode 100644 network/sync/player/CPlayerGameStateUncommonData.hpp create mode 100644 network/sync/projectile/CProjectileCreationData.hpp create mode 100644 network/sync/propset/CPropSetCreationData.hpp create mode 100644 physical/CPhysical.hpp diff --git a/classes.cpp b/classes.cpp index 39d25dd..17a1788 100644 --- a/classes.cpp +++ b/classes.cpp @@ -3,10 +3,13 @@ #include "base/fwRefAwareBase.hpp" #include "base/fwRefAwareBaseImpl.hpp" #include "base/pgBase.hpp" +#include "entity/CDynamicEntity.hpp" +#include "entity/CEntity.hpp" #include "entity/fwEntity.hpp" #include "event/CEvent.hpp" #include "event/CEventGroup.hpp" #include "event/CEventInventoryItemPickedUp.hpp" +#include "network/CFriend.hpp" #include "network/CNetGamePlayer.hpp" #include "network/CNetworkPlayerMgr.hpp" #include "network/CNetworkScObjMgr.hpp" @@ -37,6 +40,7 @@ #include "network/sync/netSyncDataNode.hpp" #include "network/sync/netSyncNodeBase.hpp" #include "network/sync/netSyncTree.hpp" +#include "network/sync/animal/CAnimalCreationData.hpp" #include "network/sync/object/CObjectCreationData.hpp" #include "network/sync/ped/CPedAttachData.hpp" #include "network/sync/ped/CPedCreationData.hpp" @@ -44,11 +48,17 @@ #include "network/sync/physical/CPhysicalAttachData.hpp" #include "network/sync/pickup/CPickupCreationData.hpp" #include "network/sync/player/CPlayerAppearanceData.hpp" +#include "network/sync/player/CPlayerCameraUncommonData.hpp" +#include "network/sync/player/CPlayerCreationData.hpp" +#include "network/sync/player/CPlayerGameStateUncommonData.hpp" #include "network/sync/player/CPlayerHealthData.hpp" +#include "network/sync/projectile/CProjectileCreationData.hpp" +#include "network/sync/propset/CPropSetCreationData.hpp" #include "network/sync/vehicle/CVehicleCreationData.hpp" #include "network/sync/vehicle/CVehicleGadgetData.hpp" #include "network/sync/vehicle/CVehicleProximityMigrationData.hpp" #include "ped/CPed.hpp" +#include "physical/CPhysical.hpp" #include "player/CPlayerInfo.hpp" #include "rage/Guid.hpp" #include "rage/atArray.hpp" diff --git a/entity/CDynamicEntity.hpp b/entity/CDynamicEntity.hpp new file mode 100644 index 0000000..2f18dfb --- /dev/null +++ b/entity/CDynamicEntity.hpp @@ -0,0 +1,21 @@ +#pragma once +#include "entity/CEntity.hpp" + +class CPortalTracker +{ +public: + virtual ~CPortalTracker() = default; + + char m_Pad[0x90]; // 0x0008 +}; +static_assert(sizeof(CPortalTracker) == 0x98); // TODO: confirm + +class CDynamicEntity : public CEntity +{ +public: + class rage::netObject* m_NetObject; // 0x00E0 + char m_Pad3[0x28]; // 0x00E8 + CPortalTracker m_PortalTracker; // 0x0110 + char m_Pad4[8]; // 0x01A8 +}; +static_assert(sizeof(CDynamicEntity) == 0x1B0); \ No newline at end of file diff --git a/entity/CEntity.hpp b/entity/CEntity.hpp new file mode 100644 index 0000000..5f78ac0 --- /dev/null +++ b/entity/CEntity.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "entity/fwEntity.hpp" + +class CEntity : public rage::fwEntity +{ +public: + char m_Pad2[0x30]; // 0xB0 +}; +static_assert(sizeof(CEntity) == 0xE0); \ No newline at end of file diff --git a/entity/fwEntity.hpp b/entity/fwEntity.hpp index c10afb0..d490d65 100644 --- a/entity/fwEntity.hpp +++ b/entity/fwEntity.hpp @@ -1,6 +1,7 @@ #pragma once #include #include "../base/fwExtensibleBase.hpp" +#include "rage/vector.hpp" class CMoveObjectPooledObject; class CNavigation; @@ -21,16 +22,16 @@ namespace rage class CBaseModelInfo* m_ModelInfo; // 0x0020 void* m_Unk; // 0x0028 uint8_t m_EntityType; // 0x0030 - char m_Pad1[0x64]; // 0x0038 - uint32_t m_EntityPoolSlot; // 0x009C - char m_Pad2[0x40]; // 0x00A0 - // TODO: move these out of rage::fwEntity - class rage::netObject* m_NetObject; // 0x00E0 + char m_Pad1[0x38]; // 0x0038 + rage::vector3 m_Position; // 0x0070 + char m_Pad0080[0x1C]; // 0x0080 + uint32_t m_ComponentIndex; // 0x009C + char m_Pad2[0x10]; // 0x00A0 - uint32_t GetEntityPoolSlot() + uint32_t GetComponentIndex() const { - return (m_EntityPoolSlot & 0x1FFFFu); + return (m_ComponentIndex & 0x1FFFFu); } }; - static_assert(sizeof(fwEntity) == 0xE8); + static_assert(sizeof(fwEntity) == 0xB0); } diff --git a/network/CFriend.hpp b/network/CFriend.hpp new file mode 100644 index 0000000..33194a3 --- /dev/null +++ b/network/CFriend.hpp @@ -0,0 +1,10 @@ +#pragma once +#include + +class CFriend +{ +public: + std::uint64_t m_RockstarId; + char m_Pad[0x8]; + char m_Name[24]; +}; \ No newline at end of file diff --git a/network/netObject.hpp b/network/netObject.hpp index 3d59716..da90ac1 100644 --- a/network/netObject.hpp +++ b/network/netObject.hpp @@ -16,6 +16,8 @@ namespace rage uint8_t m_OwnerId; // 0x45 uint8_t m_MigratingOwnerId; // 0x46 bool m_IsRemotelyControlled; // 0x47 + char m_Pad2[0xA8]; // 0x48 + int m_OwnershipToken; // 0xF0 }; - static_assert(sizeof(rage::netObject) == 0x48); + static_assert(sizeof(rage::netObject) == 0xF8); } \ No newline at end of file diff --git a/network/rlGamerHandle.cpp b/network/rlGamerHandle.cpp index 8bd6e39..a1a29e1 100644 --- a/network/rlGamerHandle.cpp +++ b/network/rlGamerHandle.cpp @@ -6,7 +6,7 @@ bool rage::rlGamerHandle::Serialize(rage::datBitBuffer& buf) const buf.Write(m_Platform, 8); if (m_Platform != 3) return false; - buf.Write(m_RockstarId, 64); + buf.Write(m_RockstarId, 64, true); buf.Write(m_UnkData, 16); return true; } @@ -16,7 +16,7 @@ bool rage::rlGamerHandle::Deserialize(rage::datBitBuffer& buf) m_Platform = buf.Read(8); if (m_Platform != 3) return false; - m_RockstarId = buf.Read(64); + m_RockstarId = buf.Read(64, true); m_UnkData = buf.Read(16); return true; } diff --git a/network/rlGamerHandle.hpp b/network/rlGamerHandle.hpp index 725630e..1131602 100644 --- a/network/rlGamerHandle.hpp +++ b/network/rlGamerHandle.hpp @@ -10,13 +10,13 @@ namespace rage class rlGamerHandle { public: - uint64_t m_RockstarId; // 0x00 + int64_t m_RockstarId; // 0x00 uint16_t m_UnkData; // 0x08 uint8_t m_Platform; // 0x0A inline rlGamerHandle() = default; - inline rlGamerHandle(uint64_t rockstar_id) : + inline rlGamerHandle(int64_t rockstar_id) : m_RockstarId(rockstar_id), m_Platform(3), m_UnkData(0) diff --git a/network/sync/animal/CAnimalCreationData.hpp b/network/sync/animal/CAnimalCreationData.hpp new file mode 100644 index 0000000..305d1e1 --- /dev/null +++ b/network/sync/animal/CAnimalCreationData.hpp @@ -0,0 +1,15 @@ +#pragma once +#include + +// TODO, CPedBaseCreationData +class CAnimalCreationData +{ +public: + char pad_0000[4]; //0x0000 + uint32_t m_PopulationType; //0x0004 + uint32_t m_ModelHash; //0x0008 + char pad_000C[18]; //0x000C + bool m_BannedPed; //0x001E + char pad_001F[5]; //0x001F +}; //Size: 0x0024 +static_assert(sizeof(CAnimalCreationData) == 0x24); \ No newline at end of file diff --git a/network/sync/ped/CPedCreationData.hpp b/network/sync/ped/CPedCreationData.hpp index 029dddb..e70e93d 100644 --- a/network/sync/ped/CPedCreationData.hpp +++ b/network/sync/ped/CPedCreationData.hpp @@ -1,7 +1,7 @@ #pragma once #include -// TODO +// TODO, CPedBaseCreationData class CPedCreationData { public: diff --git a/network/sync/ped/CPedTaskTreeData.hpp b/network/sync/ped/CPedTaskTreeData.hpp index d6f43ae..cf14168 100644 --- a/network/sync/ped/CPedTaskTreeData.hpp +++ b/network/sync/ped/CPedTaskTreeData.hpp @@ -5,14 +5,17 @@ class CPedTaskData { public: uint32_t m_TaskType; //0x0000 - char pad_0004[16]; //0x0004 + uint32_t m_TaskUnk1; //0x0004 + uint32_t m_TaskTreeType; //0x0008 + uint32_t m_TaskSequenceId; //0x000C + uint32_t m_TaskTreeDepth; //0x0010 }; //Size: 0x0014 static_assert(sizeof(CPedTaskData) == 0x14); class CPedTaskTree { public: - uint32_t m_TreeType; //0x0000 + uint32_t m_TreeType; //0x0000 not serialized char pad_0004[4]; //0x0004 unused uint32_t m_NumTasks; //0x0008 bool m_SequenceTree; //0x000C @@ -21,6 +24,7 @@ public: }; //Size: 0x0110 static_assert(sizeof(CPedTaskTree) == 0x110); +// TODO: incorrect name class CPedTaskTreeData { public: diff --git a/network/sync/player/CPlayerCameraUncommonData.hpp b/network/sync/player/CPlayerCameraUncommonData.hpp new file mode 100644 index 0000000..d7d61f7 --- /dev/null +++ b/network/sync/player/CPlayerCameraUncommonData.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include "rage/vector.hpp" + +#pragma pack(push, 8) +class CPlayerCameraUncommonData +{ +public: + rage::vector3 m_UnkCameraOffset; // 0x0 + char m_Pad[8]; // 0x10 + bool m_IsSpectating; // 0x18 +private: + char m_Pad2[7]; // 0x19 +}; //Size: 0x0010 +static_assert(sizeof(CPlayerCameraUncommonData) == 0x20); +#pragma pack(pop) \ No newline at end of file diff --git a/network/sync/player/CPlayerCreationData.hpp b/network/sync/player/CPlayerCreationData.hpp new file mode 100644 index 0000000..bd27ed5 --- /dev/null +++ b/network/sync/player/CPlayerCreationData.hpp @@ -0,0 +1,10 @@ +#pragma once +#include + +class CPlayerCreationData +{ +public: + uint32_t m_Hash; // 0x0000 + char m_Pad[20]; // 0x0004 +}; //Size: 0x18 +static_assert(sizeof(CPlayerCreationData) == 0x18); \ No newline at end of file diff --git a/network/sync/player/CPlayerGameStateUncommonData.hpp b/network/sync/player/CPlayerGameStateUncommonData.hpp new file mode 100644 index 0000000..e14baa5 --- /dev/null +++ b/network/sync/player/CPlayerGameStateUncommonData.hpp @@ -0,0 +1,22 @@ +#pragma once +#include +#include "rage/vector.hpp" + +#pragma pack(push, 8) +class CPlayerGameStateUncommonData +{ +private: + char m_Pad[0x78]; +public: + std::uint16_t m_SpectatorId; // 0x78 + alignas(8) rage::vector3 m_SpectatePos; // 0x80 +private: + char m_Pad2[0x4]; // 0x90 +public: + bool m_IsSpectating; // 0x94 + bool m_IsSpectatingStaticPos; // 0x95 +private: + char m_Pad3[0xA]; // 0x96 +}; //Size: 0x0010 +static_assert(sizeof(CPlayerGameStateUncommonData) == 0xA0); +#pragma pack(pop) \ No newline at end of file diff --git a/network/sync/projectile/CProjectileCreationData.hpp b/network/sync/projectile/CProjectileCreationData.hpp new file mode 100644 index 0000000..00ff27c --- /dev/null +++ b/network/sync/projectile/CProjectileCreationData.hpp @@ -0,0 +1,30 @@ +#pragma once +#include +#include "rage/vector.hpp" + +struct CProjectileCreationData +{ + uint16_t unk_0000; + uint16_t m_OwnerObjectId; + uint32_t m_AmmoHash; + uint32_t m_WeaponHash; + uint32_t unk_000C; + rage::vector3 m_Vector; + uint32_t unk_0020; + uint16_t m_ObjectId2; + char pad_0026[2]; + bool unk_0028; + char pad_0029[3]; + uint32_t unk_002C; + bool pad_0030; + bool unk_0031; + char pad_0032[2]; + float unk_0034; + bool unk_0038; + bool unk_0039; + bool unk_003A; + bool unk_003B; + char pad_003C[4]; + rage::matrix34 m_Matrix; +}; +static_assert(sizeof(CProjectileCreationData) == 0x80); \ No newline at end of file diff --git a/network/sync/propset/CPropSetCreationData.hpp b/network/sync/propset/CPropSetCreationData.hpp new file mode 100644 index 0000000..0f06e4e --- /dev/null +++ b/network/sync/propset/CPropSetCreationData.hpp @@ -0,0 +1,13 @@ +#pragma once +#include + +class CPropSetCreationData +{ +public: + char m_Pad[16]; // 0x0000 + uint32_t m_Hash; // 0x0010 + char m_Pad1[8]; // 0x0014 + int32_t m_Type; // 0x001C + char m_Pad2[544]; // 0x0020 +}; //Size: 0x240 +static_assert(sizeof(CPropSetCreationData) == 0x240); \ No newline at end of file diff --git a/network/sync/vehicle/CVehicleProximityMigrationData.hpp b/network/sync/vehicle/CVehicleProximityMigrationData.hpp index e526774..783b106 100644 --- a/network/sync/vehicle/CVehicleProximityMigrationData.hpp +++ b/network/sync/vehicle/CVehicleProximityMigrationData.hpp @@ -14,7 +14,9 @@ public: uint32_t m_Timestamp; //0x0044 bool m_HasPositionData; //0x0048 alignas(16) rage::fvector3 m_Position; //0x0050 - rage::vector3 m_Velocity; //0x0060 + int m_VelocityX; + int m_VelocityY; + int m_VelocityZ; uint32_t m_UnkAmount; //0x006C }; //Size: 0x0070 static_assert(sizeof(CVehicleProximityMigrationData) == 0x70); diff --git a/ped/CPed.hpp b/ped/CPed.hpp index 064ae4d..d118355 100644 --- a/ped/CPed.hpp +++ b/ped/CPed.hpp @@ -1,7 +1,8 @@ #pragma once -#include "entity/fwEntity.hpp" +#include "physical/CPhysical.hpp" -// TODO -class CPed : public rage::fwEntity +class CPed : public CPhysical { -}; \ No newline at end of file + char m_Pad6[0x18]; // 0x0368 +}; +static_assert(sizeof(CPed) == 0x380); \ No newline at end of file diff --git a/physical/CPhysical.hpp b/physical/CPhysical.hpp new file mode 100644 index 0000000..3bf55b9 --- /dev/null +++ b/physical/CPhysical.hpp @@ -0,0 +1,9 @@ +#pragma once +#include "entity/CDynamicEntity.hpp" + +class CPhysical : public CDynamicEntity +{ +public: + char m_Pad5[0x1B8]; // 0x01B0 +}; +static_assert(sizeof(CPhysical) == 0x368); \ No newline at end of file diff --git a/rage/datBitBuffer.hpp b/rage/datBitBuffer.hpp index b59eaf9..6e1b196 100644 --- a/rage/datBitBuffer.hpp +++ b/rage/datBitBuffer.hpp @@ -159,24 +159,58 @@ namespace rage 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) + T Read(int size, bool _signed = false) { static_assert(sizeof(T) <= 8); uint64_t data{}; - ReadQword(&data, size); - return 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) + void Write(T data, int size, bool _signed = false) { static_assert(sizeof(T) <= 8); - WriteQword(uint64_t(data), size); + if (_signed) + WriteInt64(int64_t(data), size); + else + WriteQword(uint64_t(data), size); } public: diff --git a/rage/tlsContext.hpp b/rage/tlsContext.hpp index 95369d1..6667366 100644 --- a/rage/tlsContext.hpp +++ b/rage/tlsContext.hpp @@ -10,10 +10,10 @@ namespace rage class tlsContext { public: - char pad[0x410]; // 0x0000 - int m_SyncThreadIndex; // 0x0410 - char pad2[0x12EC]; // 0x0414 - bool m_RunningScript; // 0x1700 + char pad[0x600]; // 0x0000 + int m_SyncThreadIndex; // 0x0600 + char pad2[0x12EC]; // 0x0604 + bool m_RunningScript; // 0x18F0 #if _WIN32 static tlsContext* Get() @@ -24,5 +24,5 @@ namespace rage #endif }; #pragma pack(pop) - static_assert(sizeof(rage::tlsContext) == 0x1704); + static_assert(sizeof(rage::tlsContext) == 0x18F4); } \ No newline at end of file diff --git a/rage/vector.hpp b/rage/vector.hpp index 6496eaf..153672e 100644 --- a/rage/vector.hpp +++ b/rage/vector.hpp @@ -4,13 +4,13 @@ #pragma pack(push, 0x10) namespace rage { - template + // atVector? class vector2 { public: - T x, y; + float x, y; - constexpr vector2(T x, T y) : + constexpr vector2(float x, float y) : x(x), y(y) { @@ -23,13 +23,16 @@ namespace rage } }; - template + // atVector? class vector3 { public: - T x, y, z; + float x, y, z; + private: + int _PAD; // because alignof doesn't work + public: - constexpr vector3(T x, T y, T z) : + constexpr vector3(float x, float y, float z) : x(x), y(y), z(z) @@ -43,26 +46,72 @@ namespace rage { } - template - bool operator==(const vector3& other) const + bool operator==(const vector3& other) const { return this->x == other.x && this->y == other.y && this->z == other.z; } template - bool operator!=(const vector3& other) const + bool operator!=(const vector3& other) const { return this->x != other.x || this->y != other.y || this->z != other.z; } - }; - template + vector3 operator+(const vector3& other) const + { + vector3 vec; + vec.x = this->x + other.x; + vec.y = this->y + other.y; + vec.z = this->z + other.z; + return vec; + } + + vector3 operator-(const vector3& other) const + { + vector3 vec; + vec.x = this->x - other.x; + vec.y = this->y - other.y; + vec.z = this->z - other.z; + return vec; + } + + vector3 operator*(const vector3& other) const + { + vector3 vec; + vec.x = this->x * other.x; + vec.y = this->y * other.y; + vec.z = this->z * other.z; + return vec; + } + + vector3 operator*(const float& other) const + { + vector3 vec; + vec.x = this->x * other; + vec.y = this->y * other; + vec.z = this->z * other; + return vec; + } + + inline float GetMagnitude() const + { + return sqrt(x * x + y * y + z * z); + } + + inline float GetDistance(const vector3& other) const + { + return (*this - other).GetMagnitude(); + } + }; + static_assert(sizeof(rage::vector3) == 0x10); + + // atVector? class vector4 { public: - T x, y, z, w; + float x, y, z, w; - constexpr vector4(T x, T y, T z, T w) : + constexpr vector4(float x, float y, float z, float w) : x(x), y(y), z(z), @@ -79,75 +128,23 @@ namespace rage } }; - template union matrix34 { - T data[3][4]; - struct { struct { T x, y, z, w; } rows[3]; }; + float data[4][4]; // yes, the underlying representation is 4x4 + struct { struct { float x, y, z, w; } rows[3]; }; }; - template union matrix44 { - T data[4][4]; - struct { struct { T x, y, z, w; } rows[4]; }; + float data[4][4]; + struct { struct { float x, y, z, w; } rows[4]; }; }; - typedef vector2 fvector2; - typedef vector4 fvector4; - typedef matrix34 fmatrix34; - typedef matrix44 fmatrix44; - class fvector3 : public vector3 - { - public: - using vector3::vector3; - - fvector3 operator+(const fvector3& other) const - { - fvector3 vec; - vec.x = this->x + other.x; - vec.y = this->y + other.y; - vec.z = this->z + other.z; - return vec; - } - - fvector3 operator-(const fvector3& other) const - { - fvector3 vec; - vec.x = this->x - other.x; - vec.y = this->y - other.y; - vec.z = this->z - other.z; - return vec; - } - - fvector3 operator*(const fvector3& other) const - { - fvector3 vec; - vec.x = this->x * other.x; - vec.y = this->y * other.y; - vec.z = this->z * other.z; - return vec; - } - - fvector3 operator*(const float& other) const - { - fvector3 vec; - vec.x = this->x * other; - vec.y = this->y * other; - vec.z = this->z * other; - return vec; - } - - inline float GetMagnitude() const - { - return std::sqrt(x * x + y * y + z * z); - } - - inline float GetDistance(const rage::fvector3& other) const - { - return (*this - other).GetMagnitude(); - } - }; -} + // backwards compatibility + // TODO: remove these! + using fvector2 = vector2; + using fvector3 = vector3; + using fvector4 = vector4; +}; #pragma pack(pop) \ No newline at end of file