Assorted network research (#176)

This commit is contained in:
maybegreat48 2024-06-06 13:58:11 +00:00 committed by GitHub
parent c2f0ddd904
commit 8ee05940af
10 changed files with 254 additions and 53 deletions

View File

@ -33,6 +33,7 @@
#include "enums/eExplosionTag.hpp"
#include "enums/eHandlingType.hpp"
#include "game_files/CGameConfig.hpp"
#include "game_files/GameDataHash.hpp"
#include "misc/CTunables.hpp"
#include "misc/vfx/TimecycleKeyframeData.hpp"
#include "netsync/CProjectBaseSyncDataNode.hpp"
@ -113,6 +114,7 @@
#include "network/ChatData.hpp"
#include "network/CJoinRequestContext.hpp"
#include "network/ClanData.hpp"
#include "network/CMsgJoinRequest.hpp"
#include "network/CMsgJoinResponse.hpp"
#include "network/CMsgTextMessage.hpp"
#include "network/CNetComplaintMgr.hpp"
@ -122,11 +124,13 @@
#include "network/MatchmakingAttributes.hpp"
#include "network/MatchmakingId.hpp"
#include "network/netObject.hpp"
#include "network/netObjectIds.hpp"
#include "network/netPeerAddress.hpp"
#include "network/netPlayer.hpp"
#include "network/netPlayerMgrBase.hpp"
#include "network/netTime.hpp"
#include "network/Network.hpp"
#include "network/P2pSecurity.hpp"
#include "network/RemoteGamerInfoMsg.hpp"
#include "network/snConnectToPeerTask.hpp"
#include "network/snSession.hpp"

View File

@ -0,0 +1,13 @@
#pragma once
#include "security/ObfVar.hpp"
#include <array>
#pragma pack(push, 8)
class GameDataHash
{
public:
bool m_is_japanese_version;
std::array<rage::Obf32, 15> m_data;
};
static_assert(sizeof(GameDataHash) == 0xF4);
#pragma pack(pop)

View File

@ -0,0 +1,25 @@
#pragma once
#include <cstdint>
#include "game_files/GameDataHash.hpp"
#include "CNetGamePlayerDataMsg.hpp"
#include "rage/rlGamerHandle.hpp"
#pragma pack(push, 8)
class CMsgJoinRequest
{
public:
std::uint32_t m_version_number;
std::uint32_t m_flags;
std::uint32_t m_unk_zero;
std::uint32_t m_magic;
GameDataHash m_game_data_hash;
std::uint32_t m_dlc_hash;
std::uint32_t m_timeout_time;
std::uint32_t dword10C;
bool m_no_handle;
rage::rlGamerHandle m_gamer_handle;
CNetGamePlayerDataMsg m_player_data_msg;
};
static_assert(sizeof(CMsgJoinRequest) == 0x168);
#pragma pack(pop)

View File

@ -4,16 +4,16 @@
class datBitBuffer;
#pragma pack(push,8)
#pragma pack(push, 8)
namespace rage {
class playerDataMsg
{
public:
virtual ~playerDataMsg() = 0;
virtual int GetBufferSize() = 0;
virtual void Log() = 0;
virtual bool Serialize(datBitBuffer* buffer) = 0;
virtual bool Deserialize(datBitBuffer* buffer) = 0;
virtual ~playerDataMsg() = default;
virtual int GetBufferSize() { return 0; };
virtual void Log() {};
virtual bool Serialize(datBitBuffer* buffer) { return true; };
virtual bool Deserialize(datBitBuffer* buffer) { return true; };
uint32_t m_game_version; //0x0008
uint32_t m_nat_type; //0x000C

67
network/P2pSecurity.hpp Normal file
View File

@ -0,0 +1,67 @@
#pragma once
#include "rage/rlGamerInfo.hpp"
#pragma pack(push, 2)
namespace rage
{
class SecurityPeer
{
public:
#pragma pack(push, 8)
struct Info
{
uint8_t platform;
rage::rlGamerHandle handle;
char name[16];
};
#pragma pack(pop)
std::uint8_t gap0[80];
int m_security_id_2;
std::uint8_t gap54[52];
int m_time_initialized;
std::uint8_t gap8C[4];
int dword90;
int m_security_id;
int gap98;
std::uint8_t gap9C[4];
rage::netPeerAddress m_address;
rage::netPeerAddress m_real_address;
std::uint64_t qwordE0; // unk data from the bitbuffer
std::uint64_t qwordE8;
std::uint64_t qwordF0;
std::uint64_t m_peer_id;
rage::rlGamerHandle m_unverified_handle;
char m_dtls_cxn_type;
std::uint8_t gap111[3];
char m_timeouts[0x40];
std::uint8_t gap154[4];
char m_decryption_lock[0x28];
void* m_WolfSSL;
rage::SecurityPeer::Info m_info;
std::uint8_t gap1B0[48];
rage::netPeerAddress m_last_provided_address;
int m_last_provided_security_id;
std::uint8_t gap204[44];
char m_peer_query_stage;
std::uint8_t gap231[3];
int m_get_peer_address_status;
std::uint8_t gap238[8];
rage::netPeerAddress m_peer_query_result;
bool m_errored;
std::uint8_t m_dtls_cxn_establish_state;
char aaaa[2];
int m_error_code;
std::uint8_t gap268[96]; // error queue
std::uint8_t m_info_requests;
std::uint8_t m_failed_decryption_attempts;
std::uint8_t gap2CA[6];
int m_certificate_verify_error_code;
int m_certificate_verify_status;
std::uint8_t gap2D8[8];
char m_flags;
std::uint8_t gap2E1[761];
};
static_assert(sizeof(rage::SecurityPeer) == 0x5DA);
}
#pragma pack(pop)

View File

@ -54,38 +54,59 @@ namespace rage
uint64_t m_count;
};
#pragma pack(push, 8)
class netEvent
{
public:
enum class Type
{
ConnectionRequested = 0, // seems to be identical to rage::netConnection::InFrame
ConnectionError = 2,
ConnectionClosed = 3,
FrameReceived = 4, // rage::netConnection::InFrame
BandwidthExceeded = 6,
OutOfMemory = 7
};
virtual ~netEvent() = default;
virtual void destroy() = 0;
virtual Type get_event_type() = 0;
virtual uint32_t _0x18() = 0;
std::uint32_t m_timestamp; // 0x0008
char pad_0008[52]; // 0x000C
std::uint32_t m_msg_id; // 0x0040
std::uint32_t m_connection_identifier; // 0x0044
rage::netEvent* m_this; // 0x0048
uint32_t m_peer_id; // 0x0050
};
static_assert(sizeof(rage::netEvent) == 0x58);
class netEventConnectionError : public rage::netEvent
{
public:
std::uint64_t m_unk; // 0x0058 (always 2)
char m_data[0x80]; // 0x0060
std::uint32_t m_size; // 0x00E0
};
static_assert(sizeof(rage::netEventConnectionError) == 0xE8);
#pragma pack(pop)
class netConnection
{
public:
class InFrame
#pragma pack(push, 8)
class InFrame : public rage::netEvent
{
public:
enum class EventType
{
ConnectionClosed = 3,
FrameReceived = 4,
BandwidthExceeded = 6,
OutOfMemory = 7
};
virtual ~InFrame() = default;
virtual void destroy() = 0;
virtual EventType get_event_type() = 0;
virtual uint32_t _0x18() = 0;
uint32_t m_timestamp; //0x0008
char pad_0008[52]; //0x000C
uint32_t m_msg_id; //0x0040
uint32_t m_connection_identifier; //0x0044
InFrame* m_this; //0x0048
uint32_t m_peer_id; //0x0050
char pad_0050[44]; //0x0058
uint32_t m_length; //0x0080
char pad_007C[4]; //0x0084
void* m_data; //0x0088
alignas(8) int m_security_id; // 0x0058
rage::netPeerAddress m_peer_address; // 0x0060
std::uint32_t m_length; // 0x0080
void* m_data; // 0x0088
};
static_assert(sizeof(rage::netConnection::InFrame) == 0x90);
#pragma pack(pop)
char gap0[8];
rage::netConnectionPeer* m_connection_peer;

View File

@ -4,6 +4,7 @@
#include "../netsync/netSyncTree.hpp"
#include "../base/atRTTI.hpp"
#pragma pack(push, 4)
class CObject;
namespace rage
{
@ -20,6 +21,8 @@ namespace rage
bool m_wants_to_delete; //0x004D
char pad_004E[1]; //0x004E
bool m_should_not_be_delete; //0x004F
char pad_0050[0x38]; //0x0050
int m_ownership_token; //0x0088
DEFINE_RAGE_RTTI(rage::netObject)
@ -129,5 +132,6 @@ namespace rage
virtual void m_320() = 0;
virtual void UpdatePendingVisibilityChanges() = 0;
}; //Size: 0x0050
static_assert(sizeof(netObject) == 0x50);
static_assert(sizeof(netObject) == 0x8C); // incorrect, but will do for now
}
#pragma pack(pop)

62
network/netObjectIds.hpp Normal file
View File

@ -0,0 +1,62 @@
#pragma once
#include <cstdint>
#pragma pack(push, 4)
namespace rage
{
class netObjectIds
{
public:
char gap0[41];
char byte29;
int m_local_player_id;
int m_object_id_response_pending_players;
int m_last_object_id_response_time;
char gap38[4];
uint16_t m_usable_object_ids[8000];
int m_next_usable_object_id_write_slot;
int m_next_usable_object_id_read_slot;
int m_usable_object_id_count;
inline bool is_object_id_usable(std::uint16_t id)
{
if (m_usable_object_id_count <= 0)
return false;
int count = 0;
for (int i = m_next_usable_object_id_read_slot + 1; m_usable_object_ids[i % 8000] != id; i++)
if (++count > m_usable_object_id_count)
return false;
return true;
}
std::uint16_t get_usable_object_id()
{
int slot = ++m_next_usable_object_id_read_slot;
m_usable_object_id_count--;
if (slot == 8000)
slot = 0;
m_next_usable_object_id_read_slot = slot;
return m_usable_object_ids[slot];
}
// this operation is fundamentally unsupported by the data structure the IDs are stored in, unforeseen problems may occur
void remove_object_id(std::uint16_t id)
{
if (m_usable_object_id_count < 2)
return; // we need at least 2 items
int count = 0;
int i;
for (i = m_next_usable_object_id_read_slot + 1; m_usable_object_ids[i % 8000] != id; i++)
if (++count > m_usable_object_id_count)
return;
auto new_id = get_usable_object_id();
if (new_id != id)
m_usable_object_ids[i % 8000] = new_id;
}
};
}
#pragma pack(pop)

View File

@ -14,7 +14,7 @@ static_assert(sizeof(netAddress) == 0x04);
namespace rage
{
#pragma pack(push, 4)
#pragma pack(push, 8)
class netPeerAddress
{
public:

View File

@ -1,21 +1,26 @@
#pragma once
#include <cstdint>
namespace rage
{
class snConnectToPeerTaskData
{
public:
int m_unk;
int m_reason;
uint64_t m_session_token;
};
class snConnectToPeerTaskResult
{
public:
char pad[0x10]{};
int m_peer_id;
char pad2[0x400]{};
};
#pragma once
#include <cstdint>
namespace rage
{
#pragma pack(push, 8)
class snConnectToPeerTaskData
{
public:
std::uint8_t m_host_flag;
std::uint8_t m_connect_reason;
std::uint64_t m_session_token;
std::uint8_t m_flag2;
std::uint8_t m_flag3;
};
static_assert(sizeof(rage::snConnectToPeerTaskData) == 0x18);
#pragma pack(pop)
class snConnectToPeerTaskResult
{
public:
char pad[0x10]{};
int m_peer_id;
char pad2[0x400]{};
};
}