diff --git a/.gitignore b/.gitignore index ff61067..42ca560 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .vscode +.vs build/ *.suo *.db diff --git a/network/CNetComplaintMgr.hpp b/network/CNetComplaintMgr.hpp new file mode 100644 index 0000000..3090493 --- /dev/null +++ b/network/CNetComplaintMgr.hpp @@ -0,0 +1,70 @@ +#pragma once +#include + +class CNetRemoteComplaint +{ +public: + uint64_t m_complainer_token; //0x0000 + uint64_t m_complainee_token; //0x0008 + uint32_t m_flags; //0x0010 + uint32_t m_time; //0x0014 +}; //Size: 0x0018 +static_assert(sizeof(CNetRemoteComplaint) == 0x18); + +class CNetComplaintMgr +{ +public: + uint64_t m_host_token; //0x0000 + uint32_t m_host_peer_id; //0x0008 + char pad_000C[4]; //0x000C + void* m_net_connection_mgr; //0x0010 + char pad_0018[64]; //0x0018 + uint64_t m_host_tokens_in_scope[64]; //0x0058 + uint32_t m_num_tokens_in_scope; //0x0258 + char pad_025C[4]; //0x025C + class CNetRemoteComplaint m_remote_complaints[64]; //0x0260 + uint32_t m_num_remote_complaints; //0x0860 + char pad_0864[4]; //0x0864 + uint64_t m_host_tokens_complained[64]; //0x0868 + uint32_t m_num_tokens_complained; //0x0A68 + char pad_0A6C[520]; //0x0A6C + uint32_t m_connection_identifier; //0x0C74 + uint32_t m_last_resend_time; //0x0C78 + char pad_0C7C[4]; //0x0C7C + uint32_t m_time_to_resend; //0x0C80 + uint32_t m_flags; //0x0C84 + char pad_0C88[16]; //0x0C88 + + inline bool has_local_complaint(uint64_t host_token) + { + for (std::uint32_t i = 0; i < m_num_tokens_complained; i++) + if (m_host_tokens_complained[i] == host_token) + return true; + + return false; + } + + inline void raise_complaint(uint64_t host_token) + { + if (has_local_complaint(host_token)) + return; + + m_host_tokens_complained[m_num_tokens_complained++] = host_token; + + // big::g_pointers->m_raise_network_complaint(this, host_token); + } + + inline void remove_complaint(uint64_t host_token) + { + if (!has_local_complaint(host_token)) + return; + + for (std::uint32_t i = 0; i < m_num_tokens_complained; i++) + if (m_host_tokens_complained[i] == host_token) + m_host_tokens_complained[i] = m_host_tokens_complained[m_num_tokens_complained - 1]; + + m_num_tokens_complained--; + } + +}; //Size: 0x0C98 +static_assert(sizeof(CNetComplaintMgr) == 0xC98); \ No newline at end of file diff --git a/network/Network.hpp b/network/Network.hpp new file mode 100644 index 0000000..965e6c6 --- /dev/null +++ b/network/Network.hpp @@ -0,0 +1,217 @@ +#pragma once +#include "../rage/rlMetric.hpp" +#include "../security/Obf32.hpp" +#include "CNetComplaintMgr.hpp" +#include "snSession.hpp" + +#pragma pack(push, 1) + +class MetricSessionMigrated : public rage::rlMetric +{ +public: + char pad_0008[804]; //0x0008 + uint32_t m_num_players; //0x032C +}; //Size: 0x0330 +static_assert(sizeof(MetricSessionMigrated) == 0x330); + +class NetworkGameConfig +{ +public: + char pad_0000[48]; //0x0000 + uint32_t m_public_slots; //0x0030 + uint32_t m_private_slots; //0x0034 + char pad_0038[272]; //0x0038 +}; //Size: 0x0148 +static_assert(sizeof(NetworkGameConfig) == 0x148); + +class NetworkGameFilter +{ +public: + char pad_0000[16]; //0x0000 + char m_game_mode[24]; //0x0010 + char pad_0028[8]; //0x0028 + uint32_t m_attribute_values[8]; //0x0030 + char m_attribute_names[8][24]; //0x0050 + char pad_0110[564]; //0x0110 +}; //Size: 0x0344 +static_assert(sizeof(NetworkGameFilter) == 0x344); + +class SessionInfoBackup +{ +public: + class rage::rlSessionInfo m_session_info; + uint32_t m_unk; //0x0070 + char pad_0074[4]; //0x0074 + uint32_t m_flags; //0x0078 +}; //Size: 0x007C +static_assert(sizeof(SessionInfoBackup) == 0x7C); + +class MatchmakingSessionResult +{ +public: + class rage::rlSessionDetail m_detail; + char pad_03B8[24]; //0x03B8 +}; //Size: 0x03D0 +static_assert(sizeof(MatchmakingSessionResult) == 0x3D0); + +class PlayerNameMapNode +{ +public: + char m_name[24]; //0x0000 + class rage::rlGamerHandle m_handle; //0x0018 + class PlayerNameMapNode* m_next; //0x0028 + class PlayerNameMapNode* m_prev; //0x0030 +}; //Size: 0x0038 +static_assert(sizeof(PlayerNameMapNode) == 0x38); + +class JoiningPlayerNameMap +{ +public: + class PlayerNameMapNode m_names[100]; //0x0000 + char pad_15E0[40]; //0x15E0 + uint32_t m_num_name_nodes; //0x1608 + char pad_160C[796]; //0x160C +}; //Size: 0x1928 +static_assert(sizeof(JoiningPlayerNameMap) == 0x1928); + +class CNetBlacklistNode : public rage::rlGamerHandle +{ +public: + bool m_block_rejoin; //0x0010 + char pad_0011[3]; //0x0011 + uint32_t m_added_time; //0x0014 + class CNetBlacklistNode* m_next; //0x0018 + class CNetBlacklistNode* m_prev; //0x0020 +}; //Size: 0x0028 +static_assert(sizeof(CNetBlacklistNode) == 0x28); + +class CNetBlacklist +{ +public: + class CNetBlacklistNode m_nodes[16]; //0x0000 + class CNetBlacklistNode* m_head; //0x0280 + class CNetBlacklistNode* m_tail; //0x0288 + uint32_t m_free_nodes; //0x0290 + char pad_0294[4]; //0x0294 + class CNetBlacklistNode* m_start; //0x0298 + char pad_02A0[24]; //0x02A0 +}; //Size: 0x02B8 +static_assert(sizeof(CNetBlacklist) == 0x2B8); + +class RemotePlayerData +{ +public: + class rage::netGamePlayerData m_data[32]; //0x0000 + uint32_t m_count; //0x0600 + char pad_0604[4]; //0x0604 +}; //Size: 0x0608 +static_assert(sizeof(RemotePlayerData) == 0x608); + +class InvitedGamer +{ +public: + class rage::rlGamerHandle m_handle; + char pad_0010[12]; //0x0010 + uint32_t m_flags; //0x001C +}; //Size: 0x0020 +static_assert(sizeof(InvitedGamer) == 0x20); + +class InvitedGamers +{ +public: + class InvitedGamer m_invited_gamers[100]; //0x0000 + uint32_t m_num_invited_gamers; //0x0C80 + char pad_0C84[4]; //0x0C84 +}; //Size: 0x0C88 +static_assert(sizeof(InvitedGamers) == 0xC88); + +class Network +{ +public: + class Obf32 m_num_dinput8_instances; + class Obf32 m_last_time_dinput8_checked; //0x0010 + class rage::snSession* m_game_session_ptr; //0x0020 + class rage::snSession* m_transition_session_ptr; //0x0028 + char pad_0030[24]; //0x0030 + class rage::snSession m_game_session; //0x0048 + class rage::snSession m_transition_session; //0x3EB8 + char pad_7D28[16]; //0x7D28 + class NetworkGameConfig m_network_game_config; //0x7D38 + class NetworkGameConfig m_network_transition_config; //0x7E80 + bool m_session_attributes_dirty; //0x7FC8 + char pad_7FC9[19]; //0x7FC9 + uint32_t m_session_visibility_flags; //0x7FDC + uint32_t m_transition_visibility_flags; //0x7FE0 + char pad_7FE4[36]; //0x7FE4 + class MetricSessionMigrated m_metric_session_migrated; //0x8008 + bool m_migrated_metric_enabled; //0x8338 + char pad_8339[3]; //0x8339 + uint32_t m_game_session_state; //0x833C + class NetworkGameFilter m_network_game_filter; //0x8340 + char pad_8684[33]; //0x8684 + bool m_was_invited; //0x86A5 + char pad_86A6[757]; //0x86A6 + bool m_need_host_change; //0x899B + char pad_899C[2620]; //0x899C + class rage::rlSessionDetail m_joining_session_detail; //0x93D8 + class SessionInfoBackup m_last_joined_session; //0x9790 + char pad_980C[40]; //0x980C + uint32_t m_current_matchmaking_group; //0x9834 + uint32_t m_matchmaking_group_max_players[5]; //0x9838 + uint32_t m_num_active_matchmaking_groups; //0x984C + char pad_9850[8]; //0x9850 + uint8_t m_matchmaking_property_id; //0x9858 + uint8_t m_matchmaking_mental_state; //0x9859 + char pad_985A[374]; //0x985A + class rage::rlMatchmakingFindResult m_game_session_matchmaking[3]; //0x99D0 + char pad_14320[40]; //0x14320 + class MatchmakingSessionResult m_game_matchmaking_session_results[10]; //0x14348 + char pad_16968[320]; //0x16968 + class rage::rlGamerHandle m_transition_creator_handle; //0x16AA8 + char pad_16AB8[24]; //0x16AB8 + bool m_local_player_info_dirty; //0x16AD0 + char pad_16AD1[495]; //0x16AD1 + class rage::rlGamerHandle m_inviter_handle; //0x16CC0 + class CNetComplaintMgr m_game_complaint_mgr; //0x16CD0 + class CNetComplaintMgr m_transition_complaint_mgr; //0x17968 + char pad_18600[32]; //0x18600 + class JoiningPlayerNameMap m_unused_joining_player_name_map; //0x18620 + char pad_19F48[8]; //0x19F48 + class CNetBlacklist m_blacklist; //0x19F50 + char pad_1A208[8]; //0x1A208 + class InvitedGamers m_game_invited_gamers; //0x1A210 + char pad_1AE98[56]; //0x1AE98 + class SessionInfoBackup m_last_joined_transition; //0x1AED0 + char pad_1AF4C[4]; //0x1AF4C + uint32_t m_activity_spectator_max_players; //0x1AF50 + char pad_1AF54[56]; //0x1AF54 + bool m_is_activity_session; //0x1AF8C + char pad_1AF8D[35]; //0x1AF8D + class RemotePlayerData m_remote_player_data; //0x1AFB0 + char pad_1B5B8[8]; //0x1B5B8 + class rage::netGamePlayerData m_local_net_game_player_data; //0x1B5C0 + char pad_1B5F0[600]; //0x1B5F0 + class rage::rlMatchmakingFindResult m_transition_matchmaking[4]; //0x1B848 + class NetworkGameFilter m_transition_filters[4]; //0x29A08 + char pad_2A718[20]; //0x2A718 + uint32_t m_transition_quickmatch_group_handle_count; //0x2A72C + class rage::rlGamerHandle m_transition_quickmatch_group_handles[32]; //0x2A730 + char pad_2A930[8]; //0x2A930 + class rage::rlSessionInfo m_transition_to_activity_session_info; //0x2A938 + char pad_2A9A8[48]; //0x2A9A8 + class MatchmakingSessionResult m_transition_matchmaking_session_results[10]; //0x2A9D8 + char pad_2CFF8[8]; //0x2CFF8 + class InvitedGamers m_transition_invited_gamers; //0x2D000 + char pad_2DC88[16]; //0x2DC88 + class rage::rlGamerHandle m_transition_to_game_handle; //0x2DC98 + class rage::rlSessionInfo m_transition_to_game_session_info; //0x2DCA8 + char pad_2DD18[4]; //0x2DD18 + uint32_t m_transition_to_game_session_participant_count; //0x2DD1C + class rage::rlGamerHandle m_transition_to_game_session_participants[32]; //0x2DD20 + char pad_2DF20[72]; //0x2DF20 + class rage::rlGamerHandle m_follower_handles[32]; //0x2DF68 + uint32_t m_follower_count; //0x2E168 + char pad_2E16C[628]; //0x2E16C +}; //Size: 0x2E3E0 +static_assert(sizeof(Network) == 0x2E3E0); +#pragma(pop) \ No newline at end of file diff --git a/network/snSession.hpp b/network/snSession.hpp new file mode 100644 index 0000000..e512ac8 --- /dev/null +++ b/network/snSession.hpp @@ -0,0 +1,170 @@ +#pragma once + +#include "../rage/rlGamerInfo.hpp" +#include "../rage/rlSessionInfo.hpp" + +#pragma pack(push, 1) +namespace rage +{ + class netConnectionManager; + class sysMemAllocator; + + class snPlayer + { + public: + uint64_t m_msg_id; //0x0000 + class rage::rlGamerInfo m_player_data; //0x0008 + }; //Size: 0x00A0 + static_assert(sizeof(rage::snPlayer) == 0xA0); + + class snPeer + { + public: + class rage::rlGamerInfo m_peer_data; //0x0000 + char pad_0098[40]; //0x0098 + }; //Size: 0x00C0 + static_assert(sizeof(rage::snPeer) == 0xC0); + + class rlRemoteGamer + { + public: + rage::rlGamerHandle m_handle; + char pad_0010[4]; //0x0010 + uint32_t m_timeout_time; //0x0014 + uint32_t m_time_unk; //0x0018 + char pad_001C[4]; //0x001C + }; //Size: 0x0020 + static_assert(sizeof(rage::rlRemoteGamer) == 0x20); + + + class rlSession + { + public: + char pad_0008[168]; //0x0008 + class rage::rlSessionInfo m_session_info; //0x00B0 + char pad_0120[288]; //0x0120 + uint64_t m_session_id; //0x0240 + char pad_0248[1648]; //0x0248 + + virtual ~rlSession() = default; + }; //Size: 0x08B8 + static_assert(sizeof(rage::rlSession) == 0x8B8); + + class rlSessionDetail + { + public: + class rage::rlGamerInfo m_gamer_info; + class rage::rlSessionInfo m_session_info; //0x0098 + char pad_0108[308]; //0x0108 + uint8_t m_matchmaking_property_ids[32]; //0x023C + char pad_025C[5]; //0x025C + uint8_t m_mental_state; //0x0261 + char pad_0262[342]; //0x0262 + }; //Size: 0x03B8 + static_assert(sizeof(rage::rlSessionDetail) == 0x3B8); + + + class rlMatchmakingFindResult + { + public: + class rage::rlSessionDetail m_result_session_details[15]; //0x0000 + char pad_37C8[168]; //0x37C8 + }; //Size: 0x3870 + static_assert(sizeof(rage::rlMatchmakingFindResult) == 0x3870); + + class netGamePlayerData + { + public: + class rlGamerHandle m_handle; + bool m_is_activity_spectator; //0x0010 + char pad_0011[7]; //0x0011 + uint64_t m_crew_id; //0x0018 + uint16_t m_rank; //0x0020 + uint16_t m_debug_unk; //0x0022 + char pad_0024[4]; //0x0024 + uint32_t m_nat_type; //0x0028 + bool m_is_rockstar_dev; //0x002C + char pad_002D[3]; //0x002D + }; //Size: 0x0030 + static_assert(sizeof(rage::netGamePlayerData) == 0x30); + + + class snSession + { + public: + rage::sysMemAllocator* m_memory_allocator; //0x0000 + char pad_0008[64]; //0x0008 + rage::netConnectionManager* m_net_connection_mgr; //0x0048 + char pad_0050[48]; //0x0050 + class rage::rlSession m_rline_session; //0x0080 + class rage::snPlayer m_local_player; //0x0938 + uint64_t m_host_token; //0x09D8 + char pad_09E0[144]; //0x09E0 + class rage::snPeer m_peer_storage[32]; //0x0A70 + char pad_2270[24]; //0x2270 + class rage::snPeer* m_peers[32]; //0x2288 + uint32_t m_peer_count; //0x2388 + char pad_238C[4]; //0x238C + class rage::snPlayer m_player_storage[32]; //0x2390 + char pad_3790[24]; //0x3790 + class rage::snPlayer* m_players[32]; //0x37A8 + uint32_t m_player_count; //0x38A8 + char pad_38AC[4]; //0x38AC + class rage::rlRemoteGamer m_remote_gamers[32]; //0x38B0 + uint32_t m_num_remote_gamers; //0x3CB0 + bool m_player_joining; //0x3CB4 + char pad_3CB5[107]; //0x3CB5 + uint32_t m_connection_identifier; //0x3D20 + char pad_3D24[8]; //0x3D24 + char m_token_key[64]; //0x3D2C + char m_id_key[64]; //0x3D6C + char m_info_key[64]; //0x3DAC + char m_host_key[64]; //0x3DEC + char m_join_key[64]; //0x3E2C + char pad_3E6C[4]; //0x3E6C + + inline bool is_host() + { + return m_local_player.m_player_data.m_host_token == m_host_token; + } + + inline snPlayer* get_player_by_token(uint64_t token) + { + for (std::uint32_t i = 0; i < m_player_count; i++) + { + if (m_players[i]->m_player_data.m_host_token == token) + { + return m_players[i]; + } + } + + return nullptr; + } + + inline snPeer* get_peer_by_rockstar_id(uint64_t rid) + { + for (uint32_t i = 0; i < m_peer_count; i++) + { + if (m_peers[i]->m_peer_data.m_gamer_handle_2.m_rockstar_id == rid) + { + return m_peers[i]; + } + } + + return nullptr; + } + + }; //Size: 0x3E70 + static_assert(sizeof(rage::snSession) == 0x3E70); + + class snMsgRemoveGamersFromSessionCmd + { + public: + uint64_t m_session_id; //0x0000 + uint64_t m_peer_ids[32]; //0x0008 + int32_t m_unk = -1; //0x0108 + uint32_t m_num_peers; //0x010C + }; //Size: 0x0110 + static_assert(sizeof(rage::snMsgRemoveGamersFromSessionCmd) == 0x110); +} +#pragma pack(pop); \ No newline at end of file diff --git a/rage/rlGamerInfo.hpp b/rage/rlGamerInfo.hpp index 9ca80ab..cc7aed5 100644 --- a/rage/rlGamerInfo.hpp +++ b/rage/rlGamerInfo.hpp @@ -10,7 +10,7 @@ namespace rage { public: uint64_t m_host_token; - uint64_t m_platform_data; + uint64_t m_peer_id_2; rlGamerHandle m_gamer_handle_2; uint32_t m_ros_privilege; char m_name[20]; diff --git a/rage/rlGamerInfoBase.hpp b/rage/rlGamerInfoBase.hpp index 1567cf8..974d637 100644 --- a/rage/rlGamerInfoBase.hpp +++ b/rage/rlGamerInfoBase.hpp @@ -23,7 +23,7 @@ namespace rage public: uint64_t m_peer_id; rlGamerHandle m_gamer_handle; - char unk_0018[32]; + char m_aes_key[32]; uint8_t unk_0038; netAddress m_unk_ip; uint16_t m_unk_port; diff --git a/rage/rlMetric.hpp b/rage/rlMetric.hpp new file mode 100644 index 0000000..0eaa53a --- /dev/null +++ b/rage/rlMetric.hpp @@ -0,0 +1,23 @@ +#pragma once +#include "joaat.hpp" + +namespace rage +{ + class rlMetric + { + public: + virtual ~rlMetric() = default; + + virtual int _0x08() { return 0; }; // returns a constant integer + + virtual int _0x10() { return 0; }; // returns a constant integer + + virtual const char* get_name() { return ""; }; + + virtual bool serialize(void* serializer) { return false; }; + + virtual int get_size() { return 0; }; + + virtual joaat_t get_name_hash() { return 0; }; + }; +}; \ No newline at end of file diff --git a/security/Obf32.hpp b/security/Obf32.hpp new file mode 100644 index 0000000..73d1412 --- /dev/null +++ b/security/Obf32.hpp @@ -0,0 +1,25 @@ +#pragma once +#include + +#pragma pack(push, 1) +class Obf32 +{ + std::uint32_t a; + std::uint32_t b; + std::uint32_t c; + std::uint32_t d; + +public: + inline void operator=(std::uint32_t val) + { + a = val & d; + b = val & ~d; + } + + inline operator std::uint32_t() + { + return (a & d) | (b & ~d); + } +}; +static_assert(sizeof(Obf32) == 0x10); +#pragma pack(pop) \ No newline at end of file