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

104 lines
2.8 KiB
C++
Raw Normal View History

2022-02-27 07:53:44 -05:00
#include <STDInclude.hpp>
#include "Discovery.hpp"
#include "ServerList.hpp"
2017-01-19 16:23:59 -05:00
namespace Components
{
bool Discovery::IsTerminating = false;
bool Discovery::IsPerforming = false;
std::thread Discovery::Thread;
std::string Discovery::Challenge;
Dvar::Var Discovery::NetDiscoveryPortRangeMin;
Dvar::Var Discovery::NetDiscoveryPortRangeMax;
2017-01-19 16:23:59 -05:00
void Discovery::Perform()
{
IsPerforming = true;
2017-01-19 16:23:59 -05:00
}
Discovery::Discovery()
{
NetDiscoveryPortRangeMin = Dvar::Register<int>("net_discoveryPortRangeMin", 25000, 0, 65535, Game::DVAR_NONE, "Minimum scan range port for local server discovery");
NetDiscoveryPortRangeMax = Dvar::Register<int>("net_discoveryPortRangeMax", 35000, 1, 65536, Game::DVAR_NONE, "Maximum scan range port for local server discovery");
2017-01-19 16:23:59 -05:00
// An additional thread prevents lags
// Not sure if that's the best way though
IsPerforming = false;
IsTerminating = false;
Thread = std::thread([]
2017-01-19 16:23:59 -05:00
{
while (!IsTerminating)
2017-01-19 16:23:59 -05:00
{
if (IsPerforming)
2017-01-19 16:23:59 -05:00
{
const auto 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
Challenge = Utils::Cryptography::Rand::GenerateChallenge();
2017-01-19 16:23:59 -05:00
const auto minPort = NetDiscoveryPortRangeMin.get<unsigned int>();
const auto maxPort = NetDiscoveryPortRangeMax.get<unsigned int>();
Network::BroadcastRange(minPort, maxPort, std::format("discovery {}", Challenge));
2017-01-19 16:23:59 -05:00
2022-06-12 17:07:53 -04:00
Logger::Print("Discovery sent within {}ms, awaiting responses...\n", Game::Sys_Milliseconds() - start);
2017-01-19 16:23:59 -05:00
IsPerforming = false;
}
2017-01-25 08:34:53 -05:00
std::this_thread::sleep_for(50ms);
2017-01-19 16:23:59 -05:00
}
});
2022-08-19 19:10:35 -04:00
Network::OnClientPacket("discovery", [](Network::Address& address, [[maybe_unused]] const std::string& data)
2017-01-19 16:23:59 -05:00
{
if (address.isSelf()) return;
if (!address.isLocal())
{
2022-08-19 19:10:35 -04:00
Logger::Print("Received discovery request from non-local address: {}\n", address.getString());
2017-01-19 16:23:59 -05:00
return;
}
2022-08-19 19:10:35 -04:00
Logger::Print("Received discovery request from {}\n", address.getString());
2017-01-19 16:23:59 -05:00
Network::SendCommand(address, "discoveryResponse", data);
});
2022-08-19 19:10:35 -04:00
Network::OnClientPacket("discoveryResponse", [](Network::Address& address, [[maybe_unused]] const std::string& data)
2017-01-19 16:23:59 -05:00
{
if (address.isSelf()) return;
if (!address.isLocal())
{
2022-08-19 19:10:35 -04:00
Logger::Print("Received discovery response from non-local address: {}\n", address.getString());
2017-01-19 16:23:59 -05:00
return;
}
if (Utils::ParseChallenge(data) != Challenge)
2017-01-19 16:23:59 -05:00
{
2022-08-19 19:10:35 -04:00
Logger::Print("Received discovery with invalid challenge from: {}\n", address.getString());
2017-01-19 16:23:59 -05:00
return;
}
2022-08-19 19:10:35 -04:00
Logger::Print("Received discovery response from: {}\n", address.getString());
2017-01-19 16:23:59 -05:00
if (ServerList::IsOfflineList())
{
2017-02-28 13:58:03 -05:00
ServerList::InsertRequest(address);
2017-01-19 16:23:59 -05:00
}
});
}
void Discovery::preDestroy()
2017-01-19 16:23:59 -05:00
{
IsPerforming = false;
IsTerminating = true;
2017-01-19 16:23:59 -05:00
if (Thread.joinable())
2017-01-19 16:23:59 -05:00
{
Thread.join();
2017-01-19 16:23:59 -05:00
}
}
}