mirror of
https://github.com/Mr-X-GTA/YimMenu.git
synced 2024-12-22 20:17:24 +08:00
Force relay connections (#1813)
* feat(protections): add force relay servers * feat(network): add support for non-direct connections * feat(info): add helpful tooltip to prevent unnecessary bug reports
This commit is contained in:
parent
b6ee8e38bc
commit
57f6eab74a
@ -3,7 +3,7 @@ include(FetchContent)
|
||||
FetchContent_Declare(
|
||||
gtav_classes
|
||||
GIT_REPOSITORY https://github.com/Yimura/GTAV-Classes.git
|
||||
GIT_TAG fe0893ffb589da617442015b97a62c117ac5bed4
|
||||
GIT_TAG 468161a36d95a355d9783eef5b245f3f1542e2bb
|
||||
GIT_PROGRESS TRUE
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ""
|
||||
|
23
src/backend/looped/system/force_relay_connections.cpp
Normal file
23
src/backend/looped/system/force_relay_connections.cpp
Normal file
@ -0,0 +1,23 @@
|
||||
#include "backend/looped_command.hpp"
|
||||
#include "pointers.hpp"
|
||||
|
||||
namespace big
|
||||
{
|
||||
class force_relay_connections : looped_command
|
||||
{
|
||||
using looped_command::looped_command;
|
||||
|
||||
virtual void on_tick() override
|
||||
{
|
||||
*g_pointers->m_gta.m_force_relay_connections = true;
|
||||
}
|
||||
|
||||
virtual void on_disable() override
|
||||
{
|
||||
*g_pointers->m_gta.m_force_relay_connections = false;
|
||||
}
|
||||
};
|
||||
|
||||
force_relay_connections g_force_relay_connections("forcerelays", "Force Relay Connections", "Hides your IP address by rerouting your connection through dedicated servers and other players",
|
||||
g.protections.force_relay_connections);
|
||||
}
|
@ -274,12 +274,13 @@ namespace big
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(script_events, bounty, ceo_money, clear_wanted_level, fake_deposit, force_mission, force_teleport, gta_banner, mc_teleport, personal_vehicle_destroyed, remote_off_radar, rotate_cam, send_to_cutscene, send_to_location, sound_spam, spectate, give_collectible, vehicle_kick, teleport_to_warehouse, start_activity, send_sms)
|
||||
} script_events{};
|
||||
|
||||
bool rid_join = false;
|
||||
bool receive_pickup = false;
|
||||
bool admin_check = true;
|
||||
bool kick_rejoin = true;
|
||||
bool rid_join = false;
|
||||
bool receive_pickup = false;
|
||||
bool admin_check = true;
|
||||
bool kick_rejoin = true;
|
||||
bool force_relay_connections = true;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(protections, script_events, rid_join, receive_pickup, admin_check, kick_rejoin)
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(protections, script_events, rid_join, receive_pickup, admin_check, kick_rejoin, force_relay_connections)
|
||||
} protections{};
|
||||
|
||||
struct self
|
||||
|
@ -16,6 +16,7 @@ namespace rage
|
||||
class netConnection;
|
||||
class netMessageQueue;
|
||||
class netQueuedMessage;
|
||||
class netConnectionPeer;
|
||||
class snMsgRemoveGamersFromSessionCmd;
|
||||
class snSession;
|
||||
class snPlayer;
|
||||
@ -120,7 +121,7 @@ namespace big::functions
|
||||
using request_ragdoll = void (*)(uint16_t object_id);
|
||||
using request_control = void (*)(rage::netObject* net_object);
|
||||
|
||||
using get_peer_address = rage::netPeerAddress* (*)(rage::netConnectionManager* manager, int peer_id);
|
||||
using get_connection_peer = rage::netConnectionPeer* (*)(rage::netConnectionManager* manager, int peer_id);
|
||||
using send_remove_gamer_cmd = void (*)(rage::netConnectionManager* net_connection_mgr, rage::netPeerAddress* adde, int connection_id, rage::snMsgRemoveGamersFromSessionCmd* cmd, int flags);
|
||||
using handle_remove_gamer_cmd = void* (*)(rage::snSession* session, rage::snPlayer* origin, rage::snMsgRemoveGamersFromSessionCmd* cmd);
|
||||
|
||||
|
@ -194,7 +194,7 @@ namespace big
|
||||
functions::request_control m_request_control;
|
||||
functions::clear_ped_tasks_network m_clear_ped_tasks_network;
|
||||
|
||||
functions::get_peer_address m_get_peer_address;
|
||||
functions::get_connection_peer m_get_connection_peer;
|
||||
functions::send_remove_gamer_cmd m_send_remove_gamer_cmd;
|
||||
functions::handle_remove_gamer_cmd m_handle_remove_gamer_cmd;
|
||||
|
||||
@ -298,6 +298,8 @@ namespace big
|
||||
PVOID m_render_ped;
|
||||
PVOID m_render_entity;
|
||||
PVOID m_render_big_ped;
|
||||
|
||||
bool* m_force_relay_connections;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
static_assert(sizeof(gta_pointers) % 8 == 0, "Pointers are not properly aligned");
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "services/players/player_service.hpp"
|
||||
|
||||
#include <network/Network.hpp>
|
||||
#include <network/netConnection.hpp>
|
||||
|
||||
namespace big
|
||||
{
|
||||
@ -27,7 +28,7 @@ namespace big
|
||||
void packet::send(int peer_id, int connection_id)
|
||||
{
|
||||
auto mgr = gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr;
|
||||
auto peer = g_pointers->m_gta.m_get_peer_address(mgr, peer_id);
|
||||
g_pointers->m_gta.m_send_packet(mgr, peer, connection_id, m_data, (m_buffer.m_curBit + 7) >> 3, 0x1000000);
|
||||
auto peer = g_pointers->m_gta.m_get_connection_peer(mgr, peer_id);
|
||||
g_pointers->m_gta.m_send_packet(mgr, &peer->m_peer_address, connection_id, m_data, (m_buffer.m_curBit + 7) >> 3, 0x1000000);
|
||||
}
|
||||
}
|
@ -754,16 +754,24 @@ namespace big
|
||||
g_pointers->m_gta.m_request_control = ptr.add(1).rip().as<functions::request_control>();
|
||||
}
|
||||
},
|
||||
// Get Connection Peer & Send Remove Gamer Command
|
||||
// Send Remove Gamer Command
|
||||
{
|
||||
"GCP&SRGC",
|
||||
"SRGC",
|
||||
"8D 42 FF 83 F8 FD 77 3D",
|
||||
[](memory::handle ptr)
|
||||
{
|
||||
g_pointers->m_gta.m_get_peer_address = ptr.add(23).rip().as<functions::get_peer_address>();
|
||||
g_pointers->m_gta.m_send_remove_gamer_cmd = ptr.add(65).rip().as<functions::send_remove_gamer_cmd>();
|
||||
}
|
||||
},
|
||||
// Get Connection Peer
|
||||
{
|
||||
"GCP",
|
||||
"48 89 5C 24 08 48 89 74 24 18 89 54 24 10 57 48 83 EC 40 48",
|
||||
[](memory::handle ptr)
|
||||
{
|
||||
g_pointers->m_gta.m_get_connection_peer = ptr.as<functions::get_connection_peer>();
|
||||
}
|
||||
},
|
||||
// Handle Remove Gamer Command
|
||||
{
|
||||
"HRGC",
|
||||
@ -1282,6 +1290,15 @@ namespace big
|
||||
g_pointers->m_gta.m_render_big_ped = ptr.as<PVOID*>();
|
||||
}
|
||||
},
|
||||
// Force Relay Connections
|
||||
{
|
||||
"FRC",
|
||||
"8A 05 ? ? ? ? 88 83 BC 00 00 00",
|
||||
[](memory::handle ptr)
|
||||
{
|
||||
g_pointers->m_gta.m_force_relay_connections = ptr.add(2).rip().as<bool*>();
|
||||
}
|
||||
},
|
||||
// Max Wanted Level
|
||||
{
|
||||
"MWL",
|
||||
|
@ -83,17 +83,30 @@ namespace big
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
netAddress player::get_ip_address()
|
||||
rage::netConnectionPeer* player::get_connection_peer()
|
||||
{
|
||||
if (auto session_player = get_session_player())
|
||||
if (auto peer = g_pointers->m_gta.m_get_connection_peer(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr,
|
||||
(int)get_session_player()->m_player_data.m_peer_id_2))
|
||||
return peer;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::optional<netAddress> player::get_ip_address()
|
||||
{
|
||||
if (this == g_player_service->get_self().get() && get_net_data())
|
||||
return get_net_data()->m_external_ip;
|
||||
|
||||
if (auto session_player = get_session_player())
|
||||
if (auto peer = g_pointers->m_gta.m_get_peer_address(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr,
|
||||
(int)get_session_player()->m_player_data.m_peer_id_2))
|
||||
return netAddress{((rage::netPeerAddress*)peer)->m_external_ip};
|
||||
if (auto peer = get_connection_peer())
|
||||
{
|
||||
if (peer->m_peer_address.m_connection_type != 1)
|
||||
return std::nullopt;
|
||||
|
||||
return {0};
|
||||
return peer->m_peer_address.m_external_ip;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
uint16_t player::get_port()
|
||||
@ -101,10 +114,13 @@ namespace big
|
||||
if (this == g_player_service->get_self().get() && get_net_data())
|
||||
return get_net_data()->m_external_port;
|
||||
|
||||
if (auto session_player = get_session_player())
|
||||
if (auto peer = g_pointers->m_gta.m_get_peer_address(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr,
|
||||
(int)get_session_player()->m_player_data.m_peer_id_2))
|
||||
return ((rage::netPeerAddress*)peer)->m_external_port;
|
||||
if (auto peer = get_connection_peer())
|
||||
{
|
||||
if (peer->m_peer_address.m_connection_type != 1)
|
||||
return 0;
|
||||
|
||||
return peer->m_peer_address.m_external_port;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ namespace rage
|
||||
class snPlayer;
|
||||
class snPeer;
|
||||
class rlGamerInfo;
|
||||
class netConnectionPeer;
|
||||
}
|
||||
|
||||
namespace big
|
||||
@ -44,7 +45,8 @@ namespace big
|
||||
[[nodiscard]] CPlayerInfo* get_player_info() const;
|
||||
[[nodiscard]] class rage::snPlayer* get_session_player();
|
||||
[[nodiscard]] class rage::snPeer* get_session_peer();
|
||||
[[nodiscard]] netAddress get_ip_address();
|
||||
[[nodiscard]] class rage::netConnectionPeer* get_connection_peer();
|
||||
[[nodiscard]] std::optional<netAddress> get_ip_address();
|
||||
[[nodiscard]] uint16_t get_port();
|
||||
|
||||
[[nodiscard]] uint8_t id() const;
|
||||
|
@ -72,16 +72,17 @@ namespace big::spam
|
||||
|
||||
inline void log_chat(char* msg, player_ptr player, bool is_spam)
|
||||
{
|
||||
std::ofstream spam_log(g_file_manager.get_project_file(is_spam ? "./spam.log" : "./chat.log").get_path(), std::ios::app);
|
||||
std::ofstream log(g_file_manager.get_project_file(is_spam ? "./spam.log" : "./chat.log").get_path(), std::ios::app);
|
||||
|
||||
auto& plData = *player->get_net_data();
|
||||
auto ip = player->get_ip_address();
|
||||
auto& data = *player->get_net_data();
|
||||
auto ip = player->get_ip_address();
|
||||
|
||||
spam_log << player->get_name() << " (" << plData.m_gamer_handle.m_rockstar_id << ") <" << (int)ip.m_field1 << "."
|
||||
<< (int)ip.m_field2 << "." << (int)ip.m_field3 << "." << (int)ip.m_field4 << ">: " << msg << std::endl;
|
||||
if (ip)
|
||||
log << player->get_name() << " (" << data.m_gamer_handle.m_rockstar_id << ") <" << (int)ip.value().m_field1 << "."
|
||||
<< (int)ip.value().m_field2 << "." << (int)ip.value().m_field3 << "." << (int)ip.value().m_field4 << ">: " << msg << std::endl;
|
||||
else
|
||||
log << player->get_name() << " (" << data.m_gamer_handle.m_rockstar_id << ") <UNKNOWN>: " << msg << std::endl;
|
||||
|
||||
spam_log.close();
|
||||
log.close();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "util/system.hpp"
|
||||
|
||||
#include <network/Network.hpp>
|
||||
#include <network/netConnection.hpp>
|
||||
#include <network/netTime.hpp>
|
||||
#include <script/globals/GPBD_FM_3.hpp>
|
||||
#include <timeapi.h>
|
||||
@ -83,13 +84,15 @@ namespace big::toxic
|
||||
.count();
|
||||
msg.increment = millis;
|
||||
|
||||
auto peer = g_pointers->m_gta.m_get_peer_address(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr,
|
||||
(int)target->get_session_player()->m_player_data.m_peer_id_2);
|
||||
auto peer = target->get_connection_peer();
|
||||
|
||||
if (!peer)
|
||||
return false;
|
||||
|
||||
for (int j = 0; j < 100; j++)
|
||||
{
|
||||
g_pointers->m_gta.m_sync_network_time(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr,
|
||||
peer,
|
||||
&peer->m_peer_address,
|
||||
(*g_pointers->m_gta.m_network_time)->m_connection_identifier,
|
||||
&msg,
|
||||
0x1000000); // repeatedly spamming the event will eventually cause certain bounds checks to disable for some reason
|
||||
@ -149,13 +152,15 @@ namespace big::toxic
|
||||
.count();
|
||||
msg.increment = millis;
|
||||
|
||||
auto peer = g_pointers->m_gta.m_get_peer_address(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr,
|
||||
(int)plyr.second->get_session_player()->m_player_data.m_peer_id_2);
|
||||
auto peer = plyr.second->get_connection_peer();
|
||||
|
||||
if (!peer)
|
||||
return;
|
||||
|
||||
for (int j = 0; j < 25; j++)
|
||||
{
|
||||
g_pointers->m_gta.m_sync_network_time(gta_util::get_network()->m_game_session_ptr->m_net_connection_mgr,
|
||||
peer,
|
||||
&peer->m_peer_address,
|
||||
(*g_pointers->m_gta.m_network_time)->m_connection_identifier,
|
||||
&msg,
|
||||
0x1000000);
|
||||
|
@ -5,12 +5,37 @@
|
||||
#include "services/player_database/player_database_service.hpp"
|
||||
#include "views/view.hpp"
|
||||
|
||||
#include <network/netConnection.hpp>
|
||||
#include <script/globals/GPBD_FM.hpp>
|
||||
#include <script/globals/GPBD_FM_3.hpp>
|
||||
#include <script/globals/GlobalPlayerBD.hpp>
|
||||
|
||||
namespace big
|
||||
{
|
||||
const char* get_nat_type_str(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1: return "Open";
|
||||
case 2: return "Moderate";
|
||||
case 3: return "Strict";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
const char* get_connection_type_str(int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1: return "Direct";
|
||||
case 2: return "Relay";
|
||||
case 3: return "Peer Relay";
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
void view::player_info()
|
||||
{
|
||||
ImGui::BeginGroup();
|
||||
@ -36,6 +61,8 @@ namespace big
|
||||
components::options_modal(
|
||||
"Extra Info",
|
||||
[ped_health, ped_maxhealth] {
|
||||
ImGui::BeginGroup();
|
||||
|
||||
auto id = g_player_service->get_selected()->id();
|
||||
|
||||
if (id != -1)
|
||||
@ -65,9 +92,41 @@ namespace big
|
||||
ImGui::Text("PLAYER_INFO_METLDOWN_COMPLETE"_T.data(),
|
||||
scr_globals::gpbd_fm_1.as<GPBD_FM*>()->Entries[id].MeltdownComplete ? "YES"_T.data() :
|
||||
"NO"_T.data()); // curious to see if anyone has actually played singleplayer
|
||||
ImGui::Separator();
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginGroup();
|
||||
|
||||
ImGui::Text("NAT Type: %s", get_nat_type_str(g_player_service->get_selected()->get_net_data()->m_nat_type));
|
||||
|
||||
if (auto peer = g_player_service->get_selected()->get_connection_peer())
|
||||
{
|
||||
ImGui::Text("Connection Type: %s", get_connection_type_str(peer->m_peer_address.m_connection_type));
|
||||
|
||||
if (peer->m_peer_address.m_connection_type == 2)
|
||||
{
|
||||
auto ip = peer->m_relay_address.m_relay_address;
|
||||
ImGui::Text("Relay IP: %d.%d.%d.%d", ip.m_field1, ip.m_field2, ip.m_field3, ip.m_field4);
|
||||
}
|
||||
else if (peer->m_peer_address.m_connection_type == 3)
|
||||
{
|
||||
auto ip = peer->m_peer_address.m_relay_address;
|
||||
ImGui::Text("Peer Relay IP: %d.%d.%d.%d", ip.m_field1, ip.m_field2, ip.m_field3, ip.m_field4);
|
||||
}
|
||||
|
||||
ImGui::Text("Num Messages Sent: %d", peer->m_num_messages_batched);
|
||||
ImGui::Text("Num Reliables Sent: %d", peer->m_num_reliable_messages_batched);
|
||||
ImGui::Text("Num Reliables Resent: %d", peer->m_num_resent_reliable_messages_batched);
|
||||
ImGui::Text("Num Encryption Attempts: %d", peer->m_num_encryption_attempts);
|
||||
}
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
ImGui::Checkbox("Block Explosions", &g_player_service->get_selected()->block_explosions);
|
||||
ImGui::Checkbox("Block Clone Creates", &g_player_service->get_selected()->block_clone_create);
|
||||
ImGui::Checkbox("Block Clone Syncs", &g_player_service->get_selected()->block_clone_sync);
|
||||
@ -201,15 +260,47 @@ namespace big
|
||||
auto ip = g_player_service->get_selected()->get_ip_address();
|
||||
auto port = g_player_service->get_selected()->get_port();
|
||||
|
||||
ImGui::Text("PLAYER_INFO_IP"_T.data(), ip.m_field1, ip.m_field2, ip.m_field3, ip.m_field4, port);
|
||||
if (ip)
|
||||
{
|
||||
ImGui::Text("PLAYER_INFO_IP"_T.data(),
|
||||
ip.value().m_field1,
|
||||
ip.value().m_field2,
|
||||
ip.value().m_field3,
|
||||
ip.value().m_field4,
|
||||
port);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::PushID("##ip");
|
||||
if (ImGui::SmallButton("COPY"_T.data()))
|
||||
ImGui::SetClipboardText(
|
||||
std::format("{}.{}.{}.{}:{}", ip.m_field1, ip.m_field2, ip.m_field3, ip.m_field4, port).data());
|
||||
ImGui::PopID();
|
||||
// clang-format off
|
||||
ImGui::PushID("##ip");
|
||||
if (ImGui::SmallButton("COPY"_T.data()))
|
||||
ImGui::SetClipboardText(std::format("{}.{}.{}.{}:{}",
|
||||
ip.value().m_field1,
|
||||
ip.value().m_field2,
|
||||
ip.value().m_field3,
|
||||
ip.value().m_field4,
|
||||
port).data());
|
||||
ImGui::PopID();
|
||||
// clang-format on
|
||||
}
|
||||
else
|
||||
{
|
||||
if (net_player_data->m_force_relays)
|
||||
ImGui::Text("IP Address: Hidden");
|
||||
else
|
||||
ImGui::Text("IP Address: Unknown");
|
||||
|
||||
auto cxn_type = g_player_service->get_selected()->get_connection_peer() ?
|
||||
g_player_service->get_selected()->get_connection_peer()->m_peer_address.m_connection_type :
|
||||
0;
|
||||
|
||||
if (g.protections.force_relay_connections && ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("IP addresses cannot be seen when Force Relay Connections is enabled");
|
||||
else if (cxn_type == 2 && ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Cannot retrieve IP address since this player is connected through dedicated servers");
|
||||
else if (cxn_type == 3 && ImGui::IsItemHovered())
|
||||
ImGui::SetTooltip("Cannot retrieve IP address since this player is connected through another player");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::EndListBox();
|
||||
|
@ -57,6 +57,7 @@ namespace big
|
||||
ImGui::SetTooltip("This prevents the collection of pickups such as unwanted money bags\nNote: Normal pickups are also no longer possible to collect with this enabled");
|
||||
ImGui::Checkbox("ADMIN_CHECK"_T.data(), &g.protections.admin_check);
|
||||
ImGui::Checkbox("Kick Rejoin", &g.protections.kick_rejoin);
|
||||
components::command_checkbox<"forcerelays">();
|
||||
ImGui::EndGroup();
|
||||
|
||||
ImGui::SeparatorText("Options");
|
||||
|
Loading…
Reference in New Issue
Block a user