Add network classes (#34)
This commit is contained in:
parent
504851b1d1
commit
8fab9b1bb0
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
.vscode
|
||||
.vs
|
||||
build/
|
||||
*.suo
|
||||
*.db
|
||||
|
70
network/CNetComplaintMgr.hpp
Normal file
70
network/CNetComplaintMgr.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
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);
|
217
network/Network.hpp
Normal file
217
network/Network.hpp
Normal file
@ -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)
|
170
network/snSession.hpp
Normal file
170
network/snSession.hpp
Normal file
@ -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);
|
@ -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];
|
||||
|
@ -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;
|
||||
|
23
rage/rlMetric.hpp
Normal file
23
rage/rlMetric.hpp
Normal file
@ -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; };
|
||||
};
|
||||
};
|
25
security/Obf32.hpp
Normal file
25
security/Obf32.hpp
Normal file
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
#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)
|
Loading…
Reference in New Issue
Block a user