Desync protection improvements (#3094)

This commit is contained in:
maybegreat48 2024-05-13 17:01:47 +00:00 committed by GitHub
parent b626140916
commit 7195f5f069
14 changed files with 127 additions and 2 deletions

View File

@ -126,6 +126,7 @@ namespace big
looped::session_auto_kick_host();
looped::session_block_jobs();
looped::session_chat_translator();
looped::session_modder_detection();
if (g_script_connection_service)
g_script_connection_service->on_tick();

View File

@ -36,6 +36,7 @@ namespace big
static void session_randomize_ceo_colors();
static void session_auto_kick_host();
static void session_chat_translator();
static void session_modder_detection();
static void system_self_globals();
static void system_update_pointers();

View File

@ -9,7 +9,7 @@ namespace big
void looped::session_chat_translator()
{
if (!translate_queue.empty() and !translate_lock and g.session.chat_translator.enabled)
if (!translate_queue.empty() && !translate_lock && g.session.chat_translator.enabled)
{
if (translate_queue.size() >= 3)
{

View File

@ -0,0 +1,60 @@
#include "backend/looped/looped.hpp"
#include "gta_util.hpp"
#include "natives.hpp"
#include "pointers.hpp"
#include "util/session.hpp"
namespace big
{
static bool bLastInSession = false;
void looped::session_modder_detection()
{
if (!bLastInSession && *g_pointers->m_gta.m_is_session_started)
{
if (!g_player_service->get_self()->is_host())
{
player_ptr host;
int players{}; // except you
int opens{};
std::vector<player_ptr> modded{};
for (auto& player : g_player_service->players())
{
if (player.second->is_valid() && player.second->get_net_data())
{
if (player.second->is_host())
host = player.second;
if (player.second->get_net_data()->m_nat_type == 0)
modded.push_back(player.second);
else if (player.second->get_net_data()->m_nat_type == 1)
opens++;
players++;
}
}
if (players > 5 && host && host->get_net_data()->m_nat_type != 0) // safe threshold
{
if ((modded.size() / (float)(players - 1)) < 0.5) // anything higher than this indicates that something fishy went on with the last host
{
for (auto& player : modded)
session::add_infraction(player, Infraction::DESYNC_PROTECTION);
}
if (opens == (players - 1) && host->get_net_data()->m_nat_type > 1) // some dumb menus actually do this
{
session::add_infraction(host, Infraction::DESYNC_PROTECTION); // false positives are possible (like the moment a modder host leaves), but should be hopefully rare
}
}
}
bLastInSession = true;
}
else if (bLastInSession && !*g_pointers->m_gta.m_is_session_started)
{
bLastInSession = false;
}
}
}

View File

@ -7,7 +7,7 @@ namespace big
{
// Add new values to the bottom (for serialization)
DESYNC_PROTECTION, // do not use
DESYNC_PROTECTION,
BREAKUP_KICK_DETECTED, // do not use
LOST_CONNECTION_KICK_DETECTED, // do not use
SPOOFED_ROCKSTAR_ID, // do not use

View File

@ -211,4 +211,6 @@ namespace big::functions
using received_clone_remove = void (*)(CNetworkObjectMgr*, CNetGamePlayer*, CNetGamePlayer*, int16_t, uint32_t);
using can_create_vehicle = bool (*)();
using get_unk_weapon = void* (*) (CPed*);
}

View File

@ -372,6 +372,11 @@ namespace big
functions::can_create_vehicle m_can_create_vehicle;
PVOID m_format_int;
PVOID m_searchlight_crash;
functions::get_unk_weapon m_get_unk_weapon;
GenericPool** m_clone_create_pool; // this is not a normal pool
PVOID m_write_physical_script_game_state_data_node;
};

View File

@ -144,7 +144,10 @@ namespace big
detour_hook_helper::add<hooks::format_int>("FI", g_pointers->m_gta.m_format_int);
detour_hook_helper::add<hooks::searchlight_crash>("SLC", g_pointers->m_gta.m_searchlight_crash);
detour_hook_helper::add<hooks::write_physical_script_game_state_data_node>("WPSGSDN", g_pointers->m_gta.m_write_physical_script_game_state_data_node);
g_hooking = this;
}

View File

@ -197,6 +197,8 @@ namespace big
static void format_int(int64_t integer_to_format, char* format_string, size_t size_always_64, bool use_commas);
static void searchlight_crash(void* a1, CPed* ped);
static void write_physical_script_game_state_data_node(rage::CPhysical* this_ptr, CPhysicalScriptGameStateDataNode* node);
};

View File

@ -1,5 +1,6 @@
#include "gta_util.hpp"
#include "hooking/hooking.hpp"
#include "services/players/player_service.hpp"
#include <network/CNetGamePlayerDataMsg.hpp>
#include <network/Network.hpp>

View File

@ -146,6 +146,16 @@ namespace big
{
session::add_infraction(plyr, Infraction::SPOOFED_HOST_TOKEN);
}
if (g_player_service->get_self()->is_host() && plyr->get_net_data()->m_nat_type == 0)
{
session::add_infraction(plyr, Infraction::DESYNC_PROTECTION);
}
if (plyr->is_host() && plyr->get_net_data()->m_nat_type == 0)
{
session::add_infraction(plyr, Infraction::DESYNC_PROTECTION); // some broken menus may do this
}
}
});
}

View File

@ -1,6 +1,7 @@
#include "hooking/hooking.hpp"
#include "services/players/player_service.hpp"
#include "util/notify.hpp"
#include "gta/pools.hpp"
namespace big
{
@ -12,6 +13,13 @@ namespace big
return;
}
if (*g_pointers->m_gta.m_clone_create_pool && (*g_pointers->m_gta.m_clone_create_pool)->m_size < 2)
{
// We don't have enough memory to handle this
g_notification_service.push_warning("Protections", "Low net object pool size");
return;
}
auto plyr = g_player_service->get_by_id(src->m_player_id);
if (plyr && plyr->block_clone_create) [[unlikely]]

View File

@ -0,0 +1,13 @@
#include "hooking/hooking.hpp"
#include "pointers.hpp"
namespace big
{
void hooks::searchlight_crash(void* a1, CPed* ped)
{
if (!ped || !g_pointers->m_gta.m_get_unk_weapon(ped)) [[unlikely]]
return;
return g_hooking->get_original<hooks::searchlight_crash>()(a1, ped);
}
}

View File

@ -1774,6 +1774,25 @@ namespace big
g_pointers->m_gta.m_format_int = ptr.as<PVOID>();
}
},
// Searchlight Crash
{
"SLC",
"0F 29 70 E8 0F 29 78 D8 48 8B F9 48 8B CA",
[](memory::handle ptr)
{
g_pointers->m_gta.m_searchlight_crash = ptr.sub(0x1E).as<PVOID>();
g_pointers->m_gta.m_get_unk_weapon = ptr.add(0x28).rip().as<functions::get_unk_weapon>();
}
},
// Clone Create Pool
{
"CCP",
"48 8B 0D ? ? ? ? 45 33 C9 BA ? ? ? ? 41",
[](memory::handle ptr)
{
g_pointers->m_gta.m_clone_create_pool = ptr.add(3).rip().as<GenericPool**>();
}
},
// Write Physical Script Game State Data Node
{
"WPSGSDN",