iw4x-client/src/Components/Modules/Discovery.cpp

109 lines
3.2 KiB
C++
Raw Normal View History

2016-07-11 11:14:58 -04:00
#include "STDInclude.hpp"
namespace Components
{
bool Discovery::IsTerminating = false;
bool Discovery::IsPerforming = false;
std::thread Discovery::Thread;
std::string Discovery::Challenge;
2016-07-11 11:14:58 -04:00
void Discovery::Perform()
{
Discovery::IsPerforming = true;
2016-07-11 11:14:58 -04:00
}
Discovery::Discovery()
{
Dvar::Register<int>("net_discoveryPortRangeMin", 25000, 0, 65535, Game::dvar_flag::DVAR_FLAG_SAVED, "Minimum scan range port for local server discovery");
Dvar::Register<int>("net_discoveryPortRangeMax", 35000, 1, 65536, Game::dvar_flag::DVAR_FLAG_SAVED, "Maximum scan range port for local server discovery");
2016-08-07 10:50:04 -04:00
// An additional thread prevents lags
// Not sure if that's the best way though
Discovery::IsPerforming = false;
Discovery::IsTerminating = false;
Discovery::Thread = std::thread([] ()
2016-07-11 11:14:58 -04:00
{
while (!Discovery::IsTerminating)
2016-07-11 11:14:58 -04:00
{
if (Discovery::IsPerforming)
2016-07-11 11:14:58 -04:00
{
int start = Game::Sys_Milliseconds();
Logger::Print("Starting local server discovery...\n");
Discovery::Challenge = fmt::sprintf("%X", Utils::Cryptography::Rand::GenerateInt());
2016-07-11 11:14:58 -04:00
unsigned int minPort = Dvar::Var("net_discoveryPortRangeMin").get<unsigned int>();
unsigned int maxPort = Dvar::Var("net_discoveryPortRangeMax").get<unsigned int>();
Network::BroadcastRange(minPort, maxPort, fmt::sprintf("discovery %s", Discovery::Challenge.data()));
2016-07-11 11:14:58 -04:00
Logger::Print("Discovery sent within %dms, awaiting responses...\n", Game::Sys_Milliseconds() - start);
Discovery::IsPerforming = false;
2016-07-11 11:14:58 -04:00
}
std::this_thread::sleep_for(50ms);
}
});
Network::Handle("discovery", [] (Network::Address address, std::string data)
{
if (address.isSelf()) return;
2016-07-11 11:14:58 -04:00
if (!address.isLocal())
2016-07-11 11:14:58 -04:00
{
Logger::Print("Received discovery request from non-local address: %s\n", address.getCString());
2016-07-11 11:14:58 -04:00
return;
}
Logger::Print("Received discovery request from %s\n", address.getCString());
2016-07-11 11:14:58 -04:00
Network::SendCommand(address, "discoveryResponse", data);
});
Network::Handle("discoveryResponse", [] (Network::Address address, std::string data)
{
if (address.isSelf()) return;
2016-07-11 11:14:58 -04:00
if (!address.isLocal())
2016-07-11 11:14:58 -04:00
{
Logger::Print("Received discovery response from non-local address: %s\n", address.getCString());
2016-07-11 11:14:58 -04:00
return;
}
if (Utils::ParseChallenge(data) != Discovery::Challenge)
2016-07-11 11:14:58 -04:00
{
Logger::Print("Received discovery with invalid challenge from: %s\n", address.getCString());
2016-07-11 11:14:58 -04:00
return;
}
Logger::Print("Received discovery response from: %s\n", address.getCString());
2016-07-11 11:14:58 -04:00
if (ServerList::IsOfflineList())
{
ServerList::InsertRequest(address, true);
}
});
2016-11-05 07:56:12 -04:00
// This is placed here in case the anticheat has been disabled!
2016-11-05 08:13:41 -04:00
// Make sure this is called after the memory scan!
2016-11-05 07:56:12 -04:00
#ifndef DEBUG
2016-11-05 08:13:41 -04:00
Utils::Hook(0x5ACB9E, [] () // Somewhere in the renderer, past the scan check
{
AntiCheat::ScanIntegrityCheck();
return Utils::Hook::Call<void()>(0x4AA720)();
}, HOOK_CALL).install()->quick();
2016-11-05 07:56:12 -04:00
#endif
2016-07-11 11:14:58 -04:00
}
Discovery::~Discovery()
{
Discovery::IsPerforming = false;
Discovery::IsPerforming = true;
2016-07-11 11:14:58 -04:00
if (Discovery::Thread.joinable())
2016-07-11 11:14:58 -04:00
{
Discovery::Thread.join();
2016-07-11 11:14:58 -04:00
}
}
}