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

94 lines
2.8 KiB
C++
Raw Normal View History

#include "STDInclude.hpp"
2016-01-03 13:28:47 -05:00
namespace Components
{
2016-06-02 09:11:31 -04:00
Discovery::Container Discovery::DiscoveryContainer = { false, false, std::thread() };
2016-01-03 21:27:43 -05:00
2016-01-03 18:00:07 -05:00
void Discovery::Perform()
{
2016-01-03 21:27:43 -05:00
Discovery::DiscoveryContainer.Perform = true;
}
2016-01-03 18:00:07 -05:00
2016-01-03 21:27:43 -05:00
Discovery::Discovery()
{
2016-01-22 07:18:26 -05:00
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-01-03 21:27:43 -05:00
Discovery::DiscoveryContainer.Perform = false;
Discovery::DiscoveryContainer.Terminate = false;
2016-06-02 09:11:31 -04:00
Discovery::DiscoveryContainer.Thread = std::thread([] ()
2016-01-03 18:00:07 -05:00
{
2016-01-03 21:27:43 -05:00
while (!Discovery::DiscoveryContainer.Terminate)
{
if (Discovery::DiscoveryContainer.Perform)
{
2016-06-30 06:11:51 -04:00
int start = Game::Sys_Milliseconds();
2016-01-03 21:27:43 -05:00
Logger::Print("Starting local server discovery...\n");
2016-01-04 05:32:05 -05:00
2016-02-10 11:18:45 -05:00
Discovery::DiscoveryContainer.Challenge = Utils::VA("%X", Utils::Cryptography::Rand::GenerateInt());
2016-01-04 05:32:05 -05:00
2016-01-22 07:18:26 -05:00
unsigned int minPort = Dvar::Var("net_discoveryPortRangeMin").Get<unsigned int>();
unsigned int maxPort = Dvar::Var("net_discoveryPortRangeMax").Get<unsigned int>();
2016-02-10 11:18:45 -05:00
Network::BroadcastRange(minPort, maxPort, Utils::VA("discovery %s", Discovery::DiscoveryContainer.Challenge.data()));
2016-01-04 05:32:05 -05:00
2016-06-30 06:11:51 -04:00
Logger::Print("Discovery sent within %dms, awaiting responses...\n", Game::Sys_Milliseconds() - start);
2016-01-03 18:00:07 -05:00
2016-01-03 21:27:43 -05:00
Discovery::DiscoveryContainer.Perform = false;
}
2016-01-03 18:00:07 -05:00
2016-01-03 21:27:43 -05:00
std::this_thread::sleep_for(50ms);
}
2016-01-03 18:00:07 -05:00
});
Network::Handle("discovery", [] (Network::Address address, std::string data)
2016-01-03 13:28:47 -05:00
{
2016-01-03 18:00:07 -05:00
if (address.IsSelf()) return;
if (!address.IsLocal())
{
2016-06-04 15:24:03 -04:00
Logger::Print("Received discovery request from non-local address: %s\n", address.GetCString());
2016-01-03 18:00:07 -05:00
return;
}
2016-06-04 15:24:03 -04:00
Logger::Print("Received discovery request from %s\n", address.GetCString());
2016-02-10 11:18:45 -05:00
Network::SendCommand(address, "discoveryResponse", data);
2016-01-03 18:00:07 -05:00
});
Network::Handle("discoveryResponse", [] (Network::Address address, std::string data)
{
if (address.IsSelf()) return;
if (!address.IsLocal())
{
2016-06-04 15:24:03 -04:00
Logger::Print("Received discovery response from non-local address: %s\n", address.GetCString());
2016-01-03 18:00:07 -05:00
return;
}
2016-01-04 05:32:05 -05:00
if (Utils::ParseChallenge(data) != Discovery::DiscoveryContainer.Challenge)
{
2016-06-04 15:24:03 -04:00
Logger::Print("Received discovery with invalid challenge from: %s\n", address.GetCString());
2016-01-04 05:32:05 -05:00
return;
}
2016-06-04 15:24:03 -04:00
Logger::Print("Received discovery response from: %s\n", address.GetCString());
2016-01-03 18:00:07 -05:00
if (ServerList::IsOfflineList())
{
ServerList::InsertRequest(address, true);
}
2016-01-03 13:28:47 -05:00
});
}
Discovery::~Discovery()
{
2016-01-03 21:27:43 -05:00
Discovery::DiscoveryContainer.Perform = false;
Discovery::DiscoveryContainer.Terminate = true;
2016-06-02 09:11:31 -04:00
if (Discovery::DiscoveryContainer.Thread.joinable())
2016-01-03 21:27:43 -05:00
{
2016-06-02 09:11:31 -04:00
Discovery::DiscoveryContainer.Thread.join();
2016-01-03 21:27:43 -05:00
}
2016-01-03 13:28:47 -05:00
}
}