Desync protection improvements (#3094)
This commit is contained in:
parent
4ab201bd59
commit
44269fcf35
@ -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();
|
||||
|
@ -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();
|
||||
|
@ -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)
|
||||
{
|
||||
|
60
src/backend/looped/session/modder_detection.cpp
Normal file
60
src/backend/looped/session/modder_detection.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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*);
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -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]]
|
||||
|
13
src/hooks/protections/searchlight_crash.cpp
Normal file
13
src/hooks/protections/searchlight_crash.cpp
Normal 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);
|
||||
}
|
||||
}
|
@ -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",
|
||||
|
Reference in New Issue
Block a user