Some discovery stuff.

This commit is contained in:
momo5502 2016-01-04 00:00:07 +01:00
parent 7c6ce6f2a8
commit 1fd40424e4
17 changed files with 306 additions and 83 deletions

View File

@ -6,7 +6,7 @@ namespace Components
void Loader::Initialize() void Loader::Initialize()
{ {
Loader::Register(new Dedicated()); Loader::Register(new Flags());
Loader::Register(new Singleton()); Loader::Register(new Singleton());
Loader::Register(new Dvar()); Loader::Register(new Dvar());
@ -26,8 +26,9 @@ namespace Components
Loader::Register(new Renderer()); Loader::Register(new Renderer());
Loader::Register(new UIFeeder()); Loader::Register(new UIFeeder());
Loader::Register(new UIScript()); Loader::Register(new UIScript());
Loader::Register(new FastFiles()); Loader::Register(new Dedicated());
Loader::Register(new Discovery()); Loader::Register(new Discovery());
Loader::Register(new FastFiles());
Loader::Register(new Materials()); Loader::Register(new Materials());
Loader::Register(new FileSystem()); Loader::Register(new FileSystem());
Loader::Register(new QuickPatch()); Loader::Register(new QuickPatch());

View File

@ -23,6 +23,7 @@ namespace Components
#include "Modules\Dvar.hpp" #include "Modules\Dvar.hpp"
#include "Modules\Maps.hpp" #include "Modules\Maps.hpp"
#include "Modules\News.hpp" #include "Modules\News.hpp"
#include "Modules\Flags.hpp"
#include "Modules\Menus.hpp" #include "Modules\Menus.hpp"
#include "Modules\Colors.hpp" #include "Modules\Colors.hpp"
#include "Modules\Logger.hpp" #include "Modules\Logger.hpp"

View File

@ -7,7 +7,7 @@ namespace Components
bool Dedicated::IsDedicated() bool Dedicated::IsDedicated()
{ {
return (Dedicated::Dedi.Get<int>() != 0); return Flags::HasFlag("dedicated");
} }
void Dedicated::InitDedicatedServer() void Dedicated::InitDedicatedServer()
@ -23,7 +23,7 @@ namespace Components
"patch_mp" "patch_mp"
}; };
memcpy((void*)0x66E1CB0, &fastfiles, sizeof(fastfiles)); memcpy(reinterpret_cast<void*>(0x66E1CB0), &fastfiles, sizeof(fastfiles));
Game::LoadInitialFF(); Game::LoadInitialFF();
Utils::Hook::Call<void()>(0x4F84C0)(); Utils::Hook::Call<void()>(0x4F84C0)();
@ -163,32 +163,10 @@ namespace Components
Dedicated::Dedicated() Dedicated::Dedicated()
{ {
Dedicated::Dedi = Dvar::Register<int>("dedicated", 0, 0, 2, Game::dvar_flag::DVAR_FLAG_SERVERINFO | Game::dvar_flag::DVAR_FLAG_WRITEPROTECTED, "Start as dedicated");
// TODO: Beautify!
char* cmd = GetCommandLineA();
char* value = strstr(cmd, " dedicated");
if (value)
{
value += 10;
while (*value == ' ' || *value == '"')
value++;
char num[2] = { 0, 0 };
num[0] = *value;
int dediVal = atoi(num);
if (dediVal && dediVal < 3)
{
Dedicated::Dedi.SetRaw(dediVal);
}
}
if (Dedicated::IsDedicated()) if (Dedicated::IsDedicated())
{ {
Dvar::Register<bool>("sv_lanOnly", false, Game::dvar_flag::DVAR_FLAG_NONE, "Don't register at the master server");
Utils::Hook(0x60BE98, Dedicated::InitDedicatedServer, HOOK_CALL).Install()->Quick(); Utils::Hook(0x60BE98, Dedicated::InitDedicatedServer, HOOK_CALL).Install()->Quick();
Utils::Hook::Set<BYTE>(0x683370, 0xC3); // steam sometimes doesn't like the server Utils::Hook::Set<BYTE>(0x683370, 0xC3); // steam sometimes doesn't like the server

View File

@ -1,19 +1,60 @@
#include "..\..\STDInclude.hpp" #include "..\..\STDInclude.hpp"
#include <future>
namespace Components namespace Components
{ {
void Discovery::Perform()
{
static bool performing = false;
if (performing) return;
std::async([] ()
{
performing = true;
int start = Game::Com_Milliseconds();
Logger::Print("Starting local server discovery...\n");
//Network::BroadcastAll("discovery\n");
Network::BroadcastRange(28960, 38960, "discovery\n");
Logger::Print("Discovery sent within %dms, awaiting responses...\n", Game::Com_Milliseconds() - start);
performing = false;
});
}
Discovery::Discovery() Discovery::Discovery()
{ {
Command::Add("bcast", [] (Command::Params params) Network::Handle("discovery", [] (Network::Address address, std::string data)
{ {
std::async([]() if (address.IsSelf()) return;
{
int start = Game::Com_Milliseconds(); if (!address.IsLocal())
OutputDebugStringA("Start!"); {
Network::BroadcastAll("getinfo xxx\n"); Logger::Print("Received discovery request from non-local address: %s\n", address.GetString());
OutputDebugStringA(Utils::VA("End: %d", Game::Com_Milliseconds() - start)); return;
}); }
Logger::Print("Received discovery request from %s\n", address.GetString());
Network::Send(address, "discoveryResponse\n");
});
Network::Handle("discoveryResponse", [] (Network::Address address, std::string data)
{
if (address.IsSelf()) return;
if (!address.IsLocal())
{
Logger::Print("Received discovery response from non-local address: %s\n", address.GetString());
return;
}
Logger::Print("Received discovery response from %s\n", address.GetString());
if (ServerList::IsOfflineList())
{
OutputDebugStringA("Inserting!");
ServerList::InsertRequest(address, true);
}
}); });
} }

View File

@ -6,5 +6,7 @@ namespace Components
Discovery(); Discovery();
~Discovery(); ~Discovery();
const char* GetName() { return "Discovery"; }; const char* GetName() { return "Discovery"; };
static void Perform();
}; };
} }

View File

@ -0,0 +1,46 @@
#include "..\..\STDInclude.hpp"
namespace Components
{
std::vector<std::string> Flags::EnabledFlags;
bool Flags::HasFlag(std::string flag)
{
for (auto entry : Flags::EnabledFlags)
{
if (Utils::StrToLower(entry) == Utils::StrToLower(flag))
{
return true;
}
}
return false;
}
void Flags::ParseFlags()
{
int numArgs;
LPCWSTR commandLine = GetCommandLineW();
LPWSTR* argv = CommandLineToArgvW(commandLine, &numArgs);
for (int i = 0; i < numArgs;i++)
{
std::wstring wFlag = argv[i];
if (wFlag[0] == L'-')
{
Flags::EnabledFlags.push_back(std::string(++wFlag.begin(), wFlag.end()));
OutputDebugStringA(Flags::EnabledFlags[Flags::EnabledFlags.size() - 1].data());
}
}
}
Flags::Flags()
{
Flags::ParseFlags();
}
Flags::~Flags()
{
Flags::EnabledFlags.clear();
}
}

View File

@ -0,0 +1,17 @@
namespace Components
{
class Flags : public Component
{
public:
Flags();
~Flags();
const char* GetName() { return "Flags"; };
static bool HasFlag(std::string flag);
private:
static std::vector<std::string> EnabledFlags;
static void ParseFlags();
};
}

View File

@ -23,11 +23,15 @@ namespace Components
} }
void Network::Address::SetIP(DWORD ip) void Network::Address::SetIP(DWORD ip)
{ {
*(DWORD*)this->address.ip = ip; this->address.ip.full = ip;
} }
DWORD Network::Address::GetIP() void Network::Address::SetIP(Game::netIP_t ip)
{ {
return *(DWORD*)this->address.ip; this->address.ip = ip;
}
Game::netIP_t Network::Address::GetIP()
{
return this->address.ip;
} }
void Network::Address::SetType(Game::netadrtype_t type) void Network::Address::SetType(Game::netadrtype_t type)
{ {
@ -45,6 +49,38 @@ namespace Components
{ {
return Game::NET_AdrToString(this->address); return Game::NET_AdrToString(this->address);
} }
bool Network::Address::IsLocal()
{
// According to: https://en.wikipedia.org/wiki/Private_network
// 10.X.X.X
if (this->GetIP().bytes[0] == 10) return true;
// 192.168.X.X
if (this->GetIP().bytes[0] == 192 && this->GetIP().bytes[1] == 168) return true;
// 172.16.X.X - 172.31.X.X
if (this->GetIP().bytes[0] == 172 && (this->GetIP().bytes[1] >= 16) && (this->GetIP().bytes[1] < 32)) return true;
// TODO: Maybe check for matching localIPs and subnet mask
return false;
}
bool Network::Address::IsSelf()
{
if (Game::NET_IsLocalAddress(this->address)) return true; // Loopback
if (this->GetPort() != (Dvar::Var("net_port").Get<int>() & 0xFFFF)) return false; // Port not equal
for (int i = 0; i < *Game::numIP; i++)
{
if (this->GetIP().full == Game::localIP[i].full)
{
return true;
}
}
return false;
}
void Network::Handle(std::string packet, Network::Callback callback) void Network::Handle(std::string packet, Network::Callback callback)
{ {
@ -107,7 +143,14 @@ namespace Components
// Check if custom handler exists // Check if custom handler exists
for (auto i = Network::PacketHandlers.begin(); i != Network::PacketHandlers.end(); i++) for (auto i = Network::PacketHandlers.begin(); i != Network::PacketHandlers.end(); i++)
{ {
if (!_strnicmp(i->first.data(), packet, i->first.size())) std::string packetCommand = packet;
auto pos = packetCommand.find_first_of("\n ");
if (pos != std::string::npos)
{
packetCommand = packetCommand.substr(0, pos);
}
if (Utils::StrToLower(i->first) == Utils::StrToLower(packetCommand))
{ {
Network::SelectedPacket = i->first; Network::SelectedPacket = i->first;
return 0; return 0;

View File

@ -18,7 +18,8 @@ namespace Components
unsigned short GetPort(); unsigned short GetPort();
void SetIP(DWORD ip); void SetIP(DWORD ip);
DWORD GetIP(); void SetIP(Game::netIP_t ip);
Game::netIP_t GetIP();
void SetType(Game::netadrtype_t type); void SetType(Game::netadrtype_t type);
Game::netadrtype_t GetType(); Game::netadrtype_t GetType();
@ -26,6 +27,8 @@ namespace Components
Game::netadr_t* Get(); Game::netadr_t* Get();
const char* GetString(); const char* GetString();
bool IsLocal();
bool IsSelf();
private: private:
Game::netadr_t address; Game::netadr_t address;

View File

@ -43,11 +43,11 @@ namespace Components
if (key == "addr") if (key == "addr")
{ {
return Utils::VA("%d", address.Get()->ip[0] | (address.Get()->ip[1] << 8) | (address.Get()->ip[2] << 16) | (address.Get()->ip[3] << 24)); return Utils::VA("%d", address.GetIP().full);
} }
else if (key =="port") else if (key =="port")
{ {
return Utils::VA("%d", htons(address.GetPort())); return Utils::VA("%d", address.GetPort());
} }
} }
@ -228,7 +228,6 @@ namespace Components
// Basic info handler // Basic info handler
Network::Handle("getInfo", [] (Network::Address address, std::string data) Network::Handle("getInfo", [] (Network::Address address, std::string data)
{ {
OutputDebugStringA(Utils::VA("Received inforequest from: %s", address.GetString()));
int clientCount = 0; int clientCount = 0;
int maxclientCount = *Game::svs_numclients; int maxclientCount = *Game::svs_numclients;
@ -295,7 +294,6 @@ namespace Components
Network::Handle("infoResponse", [] (Network::Address address, std::string data) Network::Handle("infoResponse", [] (Network::Address address, std::string data)
{ {
OutputDebugStringA(Utils::VA("Received inforesponse from: %s", address.GetString()));
Utils::InfoString info(data); Utils::InfoString info(data);
// Handle connection // Handle connection

View File

@ -4,11 +4,49 @@ namespace Components
{ {
bool ServerList::SortAsc = true; bool ServerList::SortAsc = true;
int ServerList::SortKey = ServerList::Column::Ping; int ServerList::SortKey = ServerList::Column::Ping;
unsigned int ServerList::CurrentServer = 0; unsigned int ServerList::CurrentServer = 0;
ServerList::Container ServerList::RefreshContainer; ServerList::Container ServerList::RefreshContainer;
std::vector<ServerList::ServerInfo> ServerList::OnlineList; std::vector<ServerList::ServerInfo> ServerList::OnlineList;
std::vector<ServerList::ServerInfo> ServerList::OfflineList;
std::vector<ServerList::ServerInfo> ServerList::FavouriteList;
std::vector<int> ServerList::VisibleList; std::vector<int> ServerList::VisibleList;
std::vector<ServerList::ServerInfo>& ServerList::GetList()
{
int source = Dvar::Var("ui_netSource").Get<int>();
if (ServerList::IsFavouriteList())
{
return ServerList::FavouriteList;
}
else if (ServerList::IsOfflineList())
{
return ServerList::OfflineList;
}
else
{
return ServerList::OnlineList;
}
}
bool ServerList::IsFavouriteList()
{
return (Dvar::Var("ui_netSource").Get<int>() == 2);
}
bool ServerList::IsOfflineList()
{
return (Dvar::Var("ui_netSource").Get<int>() == 0);
}
bool ServerList::IsOnlineList()
{
return (Dvar::Var("ui_netSource").Get<int>() == 1);
}
int ServerList::GetServerCount() int ServerList::GetServerCount()
{ {
return (int)ServerList::VisibleList.size(); return (int)ServerList::VisibleList.size();
@ -71,7 +109,10 @@ namespace Components
void ServerList::Refresh() void ServerList::Refresh()
{ {
ServerList::OnlineList.clear(); // ServerList::OnlineList.clear();
// ServerList::OfflineList.clear();
// ServerList::FavouriteList.clear();
ServerList::GetList().clear();
ServerList::VisibleList.clear(); ServerList::VisibleList.clear();
ServerList::RefreshContainer.Mutex.lock(); ServerList::RefreshContainer.Mutex.lock();
@ -81,18 +122,56 @@ namespace Components
ServerList::RefreshContainer.SendCount = 0; ServerList::RefreshContainer.SendCount = 0;
ServerList::RefreshContainer.SentCount = 0; ServerList::RefreshContainer.SentCount = 0;
ServerList::RefreshContainer.AwatingList = true; if (ServerList::IsOfflineList())
ServerList::RefreshContainer.AwaitTime = Game::Com_Milliseconds(); {
Discovery::Perform();
}
else if (ServerList::IsOnlineList())
{
ServerList::RefreshContainer.AwatingList = true;
ServerList::RefreshContainer.AwaitTime = Game::Com_Milliseconds();
int masterPort = Dvar::Var("masterPort").Get<int>(); int masterPort = Dvar::Var("masterPort").Get<int>();
const char* masterServerName = Dvar::Var("masterServerName").Get<const char*>(); const char* masterServerName = Dvar::Var("masterServerName").Get<const char*>();
ServerList::RefreshContainer.Host = Network::Address(Utils::VA("%s:%u", masterServerName, masterPort)); ServerList::RefreshContainer.Host = Network::Address(Utils::VA("%s:%u", masterServerName, masterPort));
Logger::Print("Sending serverlist request to master: %s:%u\n", masterServerName, masterPort); Logger::Print("Sending serverlist request to master: %s:%u\n", masterServerName, masterPort);
Network::Send(ServerList::RefreshContainer.Host, Utils::VA("getservers IW4 %i full empty", PROTOCOL)); Network::Send(ServerList::RefreshContainer.Host, Utils::VA("getservers IW4 %i full empty", PROTOCOL));
//Network::Send(ServerList::RefreshContainer.Host, "getservers 0 full empty\n"); //Network::Send(ServerList::RefreshContainer.Host, "getservers 0 full empty\n");
}
else if (ServerList::IsFavouriteList())
{
// TODO: Whatever
}
}
void ServerList::InsertRequest(Network::Address address, bool accquireMutex)
{
if (accquireMutex) ServerList::RefreshContainer.Mutex.lock();
ServerList::Container::ServerContainer container;
container.Sent = false;
container.Target = address;
bool alreadyInserted = false;
for (auto &server : ServerList::RefreshContainer.Servers)
{
if (server.Target == container.Target)
{
alreadyInserted = true;
break;
}
}
if (!alreadyInserted)
{
ServerList::RefreshContainer.Servers.push_back(container);
ServerList::RefreshContainer.SendCount++;
}
if (accquireMutex) ServerList::RefreshContainer.Mutex.unlock();
} }
void ServerList::Insert(Network::Address address, Utils::InfoString info) void ServerList::Insert(Network::Address address, Utils::InfoString info)
@ -131,11 +210,11 @@ namespace Components
// Check if already inserted and remove // Check if already inserted and remove
int k = 0; int k = 0;
for (auto j = ServerList::OnlineList.begin(); j != ServerList::OnlineList.end(); j++, k++) for (auto j = ServerList::GetList().begin(); j != ServerList::GetList().end(); j++, k++)
{ {
if (j->Addr == address) if (j->Addr == address)
{ {
ServerList::OnlineList.erase(j); ServerList::GetList().erase(j);
break; break;
} }
} }
@ -151,10 +230,12 @@ namespace Components
if (info.Get("gamename") == "IW4" && server.MatchType && server.Shortversion == VERSION_STR) if (info.Get("gamename") == "IW4" && server.MatchType && server.Shortversion == VERSION_STR)
{ {
int index = ServerList::OnlineList.size(); int index = ServerList::GetList().size();
ServerList::OnlineList.push_back(server); ServerList::GetList().push_back(server);
ServerList::VisibleList.push_back(index); ServerList::VisibleList.push_back(index);
ServerList::SortList(); ServerList::SortList();
OutputDebugStringA(Utils::VA("Inserted with IP: %s", server.Addr.GetString()));
} }
break; break;
@ -202,9 +283,9 @@ namespace Components
{ {
if (ServerList::VisibleList.size() > (unsigned int)index) if (ServerList::VisibleList.size() > (unsigned int)index)
{ {
if (ServerList::OnlineList.size() > (unsigned int)ServerList::VisibleList[index]) if (ServerList::GetList().size() > (unsigned int)ServerList::VisibleList[index])
{ {
return &ServerList::OnlineList[ServerList::VisibleList[index]]; return &ServerList::GetList()[ServerList::VisibleList[index]];
} }
} }
@ -286,27 +367,9 @@ namespace Components
Network::Address serverAddr = address; Network::Address serverAddr = address;
serverAddr.SetIP(entry[i].IP); serverAddr.SetIP(entry[i].IP);
serverAddr.SetPort(ntohs(entry[i].Port)); serverAddr.SetPort(ntohs(entry[i].Port));
serverAddr.Get()->type = Game::NA_IP; serverAddr.SetType(Game::NA_IP);
ServerList::Container::ServerContainer container; ServerList::InsertRequest(serverAddr, false);
container.Sent = false;
container.Target = serverAddr;
bool alreadyInserted = false;
for (auto &server : ServerList::RefreshContainer.Servers)
{
if (server.Target == container.Target)
{
alreadyInserted = true;
break;
}
}
if (!alreadyInserted)
{
ServerList::RefreshContainer.Servers.push_back(container);
ServerList::RefreshContainer.SendCount++;
}
} }
Logger::Print("Parsed %d servers from master\n", ServerList::RefreshContainer.Servers.size() - count); Logger::Print("Parsed %d servers from master\n", ServerList::RefreshContainer.Servers.size() - count);
@ -356,6 +419,8 @@ namespace Components
ServerList::~ServerList() ServerList::~ServerList()
{ {
ServerList::OnlineList.clear(); ServerList::OnlineList.clear();
ServerList::OfflineList.clear();
ServerList::FavouriteList.clear();
ServerList::VisibleList.clear(); ServerList::VisibleList.clear();
} }
} }

View File

@ -26,8 +26,13 @@ namespace Components
const char* GetName() { return "ServerList"; }; const char* GetName() { return "ServerList"; };
static void Refresh(); static void Refresh();
static void InsertRequest(Network::Address address, bool accquireMutex = true);
static void Insert(Network::Address address, Utils::InfoString info); static void Insert(Network::Address address, Utils::InfoString info);
static bool IsFavouriteList();
static bool IsOfflineList();
static bool IsOnlineList();
private: private:
enum Column enum Column
{ {
@ -93,13 +98,18 @@ namespace Components
static void SortList(); static void SortList();
static ServerInfo* GetServer(int index); static ServerInfo* GetServer(int index);
static std::vector<ServerInfo>& GetList();
static int SortKey; static int SortKey;
static bool SortAsc; static bool SortAsc;
static unsigned int CurrentServer; static unsigned int CurrentServer;
static Container RefreshContainer; static Container RefreshContainer;
static std::vector<ServerInfo> OnlineList; static std::vector<ServerInfo> OnlineList;
static std::vector<ServerInfo> OfflineList;
static std::vector<ServerInfo> FavouriteList;
static std::vector<int> VisibleList; static std::vector<int> VisibleList;
}; };
} }

View File

@ -25,7 +25,7 @@ namespace Components
else else
{ {
//No connect command was provided, continuing with normal processing. //No connect command was provided, continuing with normal processing.
if (!Singleton::FirstInstance && MessageBoxA(0, "Do you want to start a second instance?", "Game already running", MB_ICONEXCLAMATION | MB_YESNO) == IDNO) if (!Singleton::FirstInstance && MessageBoxA(0, "Do you want to start another instance?", "Game already running", MB_ICONEXCLAMATION | MB_YESNO) == IDNO)
{ {
ExitProcess(0); ExitProcess(0);
} }

View File

@ -62,6 +62,7 @@ namespace Game
NET_AdrToString_t NET_AdrToString = (NET_AdrToString_t)0x469880; NET_AdrToString_t NET_AdrToString = (NET_AdrToString_t)0x469880;
NET_CompareAdr_t NET_CompareAdr = (NET_CompareAdr_t)0x4D0AA0; NET_CompareAdr_t NET_CompareAdr = (NET_CompareAdr_t)0x4D0AA0;
NET_IsLocalAddress_t NET_IsLocalAddress = (NET_IsLocalAddress_t)0x402BD0;
NET_StringToAdr_t NET_StringToAdr = (NET_StringToAdr_t)0x409010; NET_StringToAdr_t NET_StringToAdr = (NET_StringToAdr_t)0x409010;
Live_MPAcceptInvite_t Live_MPAcceptInvite = (Live_MPAcceptInvite_t)0x420A6D; Live_MPAcceptInvite_t Live_MPAcceptInvite = (Live_MPAcceptInvite_t)0x420A6D;
@ -128,6 +129,9 @@ namespace Game
party_t** partyIngame = (party_t**)0x1081C00; party_t** partyIngame = (party_t**)0x1081C00;
PartyData_s** partyData = (PartyData_s**)0x107E500; PartyData_s** partyData = (PartyData_s**)0x107E500;
int* numIP = (int*)0x64A1E68;
netIP_t* localIP = (netIP_t*)0x64A1E28;
void* ReallocateAssetPool(XAssetType type, unsigned int newSize) void* ReallocateAssetPool(XAssetType type, unsigned int newSize)
{ {
int elSize = DB_GetXAssetSizeHandlers[type](); int elSize = DB_GetXAssetSizeHandlers[type]();

View File

@ -145,6 +145,9 @@ namespace Game
typedef bool(__cdecl * NET_CompareAdr_t)(netadr_t, netadr_t); typedef bool(__cdecl * NET_CompareAdr_t)(netadr_t, netadr_t);
extern NET_CompareAdr_t NET_CompareAdr; extern NET_CompareAdr_t NET_CompareAdr;
typedef bool(__cdecl * NET_IsLocalAddress_t)(netadr_t);
extern NET_IsLocalAddress_t NET_IsLocalAddress;
typedef bool(__cdecl * NET_StringToAdr_t)(const char*, netadr_t*); typedef bool(__cdecl * NET_StringToAdr_t)(const char*, netadr_t*);
extern NET_StringToAdr_t NET_StringToAdr; extern NET_StringToAdr_t NET_StringToAdr;
@ -247,6 +250,9 @@ namespace Game
extern party_t** partyIngame; extern party_t** partyIngame;
extern PartyData_s** partyData; extern PartyData_s** partyData;
extern int* numIP;
extern netIP_t* localIP;
void* ReallocateAssetPool(XAssetType type, unsigned int newSize); void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
void Menu_FreeItemMemory(Game::itemDef_t* item); void Menu_FreeItemMemory(Game::itemDef_t* item);
void OOBPrintT(int type, netadr_t netadr, const char* message); void OOBPrintT(int type, netadr_t netadr, const char* message);

View File

@ -626,10 +626,16 @@ namespace Game
NS_SERVER NS_SERVER
} netsrc_t; } netsrc_t;
typedef union
{
BYTE bytes[4];
DWORD full;
} netIP_t;
typedef struct typedef struct
{ {
netadrtype_t type; netadrtype_t type;
BYTE ip[4]; netIP_t ip;
unsigned short port; unsigned short port;
BYTE ipx[10]; BYTE ipx[10];
} netadr_t; } netadr_t;

View File

@ -8,6 +8,7 @@
#include <wincrypt.h> #include <wincrypt.h>
#include <time.h> #include <time.h>
#include <timeapi.h> #include <timeapi.h>
#include <shellapi.h>
#include <WinSock2.h> #include <WinSock2.h>
#include <map> #include <map>
@ -22,6 +23,7 @@
#include <locale> #include <locale>
#include <regex> #include <regex>
#include <thread> #include <thread>
#include <future>
#include <version.hpp> #include <version.hpp>