2017-01-19 16:23:59 -05:00
|
|
|
#include "STDInclude.hpp"
|
|
|
|
|
|
|
|
namespace Components
|
|
|
|
{
|
|
|
|
bool Discovery::IsTerminating = false;
|
|
|
|
bool Discovery::IsPerforming = false;
|
|
|
|
std::thread Discovery::Thread;
|
|
|
|
std::string Discovery::Challenge;
|
|
|
|
|
|
|
|
void Discovery::Perform()
|
|
|
|
{
|
|
|
|
Discovery::IsPerforming = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
// An additional thread prevents lags
|
|
|
|
// Not sure if that's the best way though
|
|
|
|
Discovery::IsPerforming = false;
|
|
|
|
Discovery::IsTerminating = false;
|
2017-01-25 08:34:53 -05:00
|
|
|
Discovery::Thread = std::thread([]()
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2017-01-25 08:34:53 -05:00
|
|
|
while (!Discovery::IsTerminating)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2017-01-25 08:34:53 -05:00
|
|
|
if (Discovery::IsPerforming)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
2017-01-25 08:34:53 -05:00
|
|
|
int start = Game::Sys_Milliseconds();
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2017-01-25 08:34:53 -05:00
|
|
|
Logger::Print("Starting local server discovery...\n");
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2017-01-25 08:34:53 -05:00
|
|
|
Discovery::Challenge = Utils::Cryptography::Rand::GenerateChallenge();
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2017-01-25 08:34:53 -05: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, Utils::String::VA("discovery %s", Discovery::Challenge.data()));
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2017-01-25 08:34:53 -05:00
|
|
|
Logger::Print("Discovery sent within %dms, awaiting responses...\n", Game::Sys_Milliseconds() - start);
|
2017-01-19 16:23:59 -05:00
|
|
|
|
2017-01-25 08:34:53 -05:00
|
|
|
Discovery::IsPerforming = false;
|
2017-01-22 14:12:36 -05:00
|
|
|
}
|
2017-01-25 08:34:53 -05:00
|
|
|
|
|
|
|
std::this_thread::sleep_for(50ms);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-06-14 06:06:04 -04:00
|
|
|
Network::Handle("discovery", [](Network::Address address, std::string data)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
if (address.isSelf()) return;
|
|
|
|
|
|
|
|
if (!address.isLocal())
|
|
|
|
{
|
|
|
|
Logger::Print("Received discovery request from non-local address: %s\n", address.getCString());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger::Print("Received discovery request from %s\n", address.getCString());
|
|
|
|
Network::SendCommand(address, "discoveryResponse", data);
|
|
|
|
});
|
|
|
|
|
2017-06-14 06:06:04 -04:00
|
|
|
Network::Handle("discoveryResponse", [](Network::Address address, std::string data)
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
if (address.isSelf()) return;
|
|
|
|
|
|
|
|
if (!address.isLocal())
|
|
|
|
{
|
|
|
|
Logger::Print("Received discovery response from non-local address: %s\n", address.getCString());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (Utils::ParseChallenge(data) != Discovery::Challenge)
|
|
|
|
{
|
|
|
|
Logger::Print("Received discovery with invalid challenge from: %s\n", address.getCString());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger::Print("Received discovery response from: %s\n", address.getCString());
|
|
|
|
|
|
|
|
if (ServerList::IsOfflineList())
|
|
|
|
{
|
2017-02-28 13:58:03 -05:00
|
|
|
ServerList::InsertRequest(address);
|
2017-01-19 16:23:59 -05:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// This is placed here in case the anticheat has been disabled!
|
|
|
|
// Make sure this is called after the memory scan!
|
2017-06-23 04:04:43 -04:00
|
|
|
#ifndef DISABLE_ANTICHEAT
|
2017-06-14 06:06:04 -04:00
|
|
|
Utils::Hook(0x5ACB9E, []() // Somewhere in the renderer, past the scan check
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
AntiCheat::ScanIntegrityCheck();
|
|
|
|
return Utils::Hook::Call<void()>(0x4AA720)();
|
|
|
|
}, HOOK_CALL).install()->quick();
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
Discovery::~Discovery()
|
2017-01-23 16:06:50 -05:00
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Discovery::preDestroy()
|
2017-01-19 16:23:59 -05:00
|
|
|
{
|
|
|
|
Discovery::IsPerforming = false;
|
|
|
|
Discovery::IsTerminating = true;
|
|
|
|
|
|
|
|
if (Discovery::Thread.joinable())
|
|
|
|
{
|
|
|
|
Discovery::Thread.join();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|