diff --git a/src/Components/Loader.cpp b/src/Components/Loader.cpp
index 65882eea..7a08886b 100644
--- a/src/Components/Loader.cpp
+++ b/src/Components/Loader.cpp
@@ -6,7 +6,7 @@ namespace Components
 
 	void Loader::Initialize()
 	{
-		Loader::Register(new Dedicated());
+		Loader::Register(new Flags());
 		Loader::Register(new Singleton());
 
 		Loader::Register(new Dvar());
@@ -26,8 +26,9 @@ namespace Components
 		Loader::Register(new Renderer());
 		Loader::Register(new UIFeeder());
 		Loader::Register(new UIScript());
-		Loader::Register(new FastFiles());
+		Loader::Register(new Dedicated());
 		Loader::Register(new Discovery());
+		Loader::Register(new FastFiles());
 		Loader::Register(new Materials());
 		Loader::Register(new FileSystem());
 		Loader::Register(new QuickPatch());
diff --git a/src/Components/Loader.hpp b/src/Components/Loader.hpp
index db1292ad..08af4696 100644
--- a/src/Components/Loader.hpp
+++ b/src/Components/Loader.hpp
@@ -23,6 +23,7 @@ namespace Components
 #include "Modules\Dvar.hpp"
 #include "Modules\Maps.hpp"
 #include "Modules\News.hpp"
+#include "Modules\Flags.hpp"
 #include "Modules\Menus.hpp"
 #include "Modules\Colors.hpp"
 #include "Modules\Logger.hpp"
diff --git a/src/Components/Modules/Dedicated.cpp b/src/Components/Modules/Dedicated.cpp
index 135defd2..285c9c14 100644
--- a/src/Components/Modules/Dedicated.cpp
+++ b/src/Components/Modules/Dedicated.cpp
@@ -7,7 +7,7 @@ namespace Components
 
 	bool Dedicated::IsDedicated()
 	{
-		return (Dedicated::Dedi.Get<int>() != 0);
+		return Flags::HasFlag("dedicated");
 	}
 
 	void Dedicated::InitDedicatedServer()
@@ -23,7 +23,7 @@ namespace Components
 			"patch_mp"
 		};
 
-		memcpy((void*)0x66E1CB0, &fastfiles, sizeof(fastfiles));
+		memcpy(reinterpret_cast<void*>(0x66E1CB0), &fastfiles, sizeof(fastfiles));
 		Game::LoadInitialFF();
 
 		Utils::Hook::Call<void()>(0x4F84C0)();
@@ -163,32 +163,10 @@ namespace Components
 
 	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())
 		{
+			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::Set<BYTE>(0x683370, 0xC3); // steam sometimes doesn't like the server
diff --git a/src/Components/Modules/Discovery.cpp b/src/Components/Modules/Discovery.cpp
index 2b82cd93..24621995 100644
--- a/src/Components/Modules/Discovery.cpp
+++ b/src/Components/Modules/Discovery.cpp
@@ -1,19 +1,60 @@
 #include "..\..\STDInclude.hpp"
-#include <future>
 
 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()
 	{
-		Command::Add("bcast", [] (Command::Params params)
+		Network::Handle("discovery", [] (Network::Address address, std::string data)
 		{
-			std::async([]()
-			{			
-				int start = Game::Com_Milliseconds();
-				OutputDebugStringA("Start!");
-				Network::BroadcastAll("getinfo xxx\n");
-				OutputDebugStringA(Utils::VA("End: %d", Game::Com_Milliseconds() - start));
-			});
+			if (address.IsSelf()) return;
+
+			if (!address.IsLocal())
+			{
+				Logger::Print("Received discovery request from non-local address: %s\n", address.GetString());
+				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);
+			}
 		});
 	}
 
diff --git a/src/Components/Modules/Discovery.hpp b/src/Components/Modules/Discovery.hpp
index 504b8c9e..96640e4c 100644
--- a/src/Components/Modules/Discovery.hpp
+++ b/src/Components/Modules/Discovery.hpp
@@ -6,5 +6,7 @@ namespace Components
 		Discovery();
 		~Discovery();
 		const char* GetName() { return "Discovery"; };
+
+		static void Perform();
 	};
 }
diff --git a/src/Components/Modules/Flags.cpp b/src/Components/Modules/Flags.cpp
new file mode 100644
index 00000000..2075a338
--- /dev/null
+++ b/src/Components/Modules/Flags.cpp
@@ -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();
+	}
+}
diff --git a/src/Components/Modules/Flags.hpp b/src/Components/Modules/Flags.hpp
new file mode 100644
index 00000000..fdafc839
--- /dev/null
+++ b/src/Components/Modules/Flags.hpp
@@ -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();
+	};
+}
diff --git a/src/Components/Modules/Network.cpp b/src/Components/Modules/Network.cpp
index 8e8565a0..3fc1c8bc 100644
--- a/src/Components/Modules/Network.cpp
+++ b/src/Components/Modules/Network.cpp
@@ -23,11 +23,15 @@ namespace Components
 	}
 	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)
 	{
@@ -45,6 +49,38 @@ namespace Components
 	{
 		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)
 	{
@@ -107,7 +143,14 @@ namespace Components
 		// Check if custom handler exists
 		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;
 				return 0;
diff --git a/src/Components/Modules/Network.hpp b/src/Components/Modules/Network.hpp
index 9aae8068..6aaeb531 100644
--- a/src/Components/Modules/Network.hpp
+++ b/src/Components/Modules/Network.hpp
@@ -18,7 +18,8 @@ namespace Components
 			unsigned short GetPort();
 
 			void SetIP(DWORD ip);
-			DWORD GetIP();
+			void SetIP(Game::netIP_t ip);
+			Game::netIP_t GetIP();
 
 			void SetType(Game::netadrtype_t type);
 			Game::netadrtype_t GetType();
@@ -26,6 +27,8 @@ namespace Components
 			Game::netadr_t* Get();
 			const char* GetString();
 
+			bool IsLocal();
+			bool IsSelf();
 
 		private:
 			Game::netadr_t address;
diff --git a/src/Components/Modules/Party.cpp b/src/Components/Modules/Party.cpp
index 1ea43f1c..147da77d 100644
--- a/src/Components/Modules/Party.cpp
+++ b/src/Components/Modules/Party.cpp
@@ -43,11 +43,11 @@ namespace Components
 
 			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")
 			{
-				return Utils::VA("%d", htons(address.GetPort()));
+				return Utils::VA("%d", address.GetPort());
 			}
 		}
 
@@ -228,7 +228,6 @@ namespace Components
 		// Basic info handler
 		Network::Handle("getInfo", [] (Network::Address address, std::string data)
 		{
-			OutputDebugStringA(Utils::VA("Received inforequest from: %s", address.GetString()));
 			int clientCount = 0;
 			int maxclientCount = *Game::svs_numclients;
 
@@ -295,7 +294,6 @@ namespace Components
 
 		Network::Handle("infoResponse", [] (Network::Address address, std::string data)
 		{
-			OutputDebugStringA(Utils::VA("Received inforesponse from: %s", address.GetString()));
 			Utils::InfoString info(data);
 
 			// Handle connection
diff --git a/src/Components/Modules/ServerList.cpp b/src/Components/Modules/ServerList.cpp
index 8f8fa335..b476bd0e 100644
--- a/src/Components/Modules/ServerList.cpp
+++ b/src/Components/Modules/ServerList.cpp
@@ -4,11 +4,49 @@ namespace Components
 {
 	bool ServerList::SortAsc = true;
 	int ServerList::SortKey = ServerList::Column::Ping;
+
 	unsigned int ServerList::CurrentServer = 0;
 	ServerList::Container ServerList::RefreshContainer;
+
 	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<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()
 	{
 		return (int)ServerList::VisibleList.size();
@@ -71,7 +109,10 @@ namespace Components
 
 	void ServerList::Refresh()
 	{
-		ServerList::OnlineList.clear();
+// 		ServerList::OnlineList.clear();
+// 		ServerList::OfflineList.clear();
+// 		ServerList::FavouriteList.clear();
+		ServerList::GetList().clear();
 		ServerList::VisibleList.clear();
 
 		ServerList::RefreshContainer.Mutex.lock();
@@ -81,18 +122,56 @@ namespace Components
 		ServerList::RefreshContainer.SendCount = 0;
 		ServerList::RefreshContainer.SentCount = 0;
 
-		ServerList::RefreshContainer.AwatingList = true;
-		ServerList::RefreshContainer.AwaitTime = Game::Com_Milliseconds();
+		if (ServerList::IsOfflineList())
+		{
+			Discovery::Perform();
+		}
+		else if (ServerList::IsOnlineList())
+		{
+			ServerList::RefreshContainer.AwatingList = true;
+			ServerList::RefreshContainer.AwaitTime = Game::Com_Milliseconds();
 
-		int masterPort = Dvar::Var("masterPort").Get<int>();
-		const char* masterServerName = Dvar::Var("masterServerName").Get<const char*>();
+			int masterPort = Dvar::Var("masterPort").Get<int>();
+			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, "getservers 0 full empty\n");
+			Network::Send(ServerList::RefreshContainer.Host, Utils::VA("getservers IW4 %i full empty", PROTOCOL));
+			//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)
@@ -131,11 +210,11 @@ namespace Components
 
 				// Check if already inserted and remove
 				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)
 					{
-						ServerList::OnlineList.erase(j);
+						ServerList::GetList().erase(j);
 						break;
 					}
 				}
@@ -151,10 +230,12 @@ namespace Components
 
 				if (info.Get("gamename") == "IW4" && server.MatchType && server.Shortversion == VERSION_STR)
 				{
-					int index = ServerList::OnlineList.size();
-					ServerList::OnlineList.push_back(server);
+					int index = ServerList::GetList().size();
+					ServerList::GetList().push_back(server);
 					ServerList::VisibleList.push_back(index);
 					ServerList::SortList();
+
+					OutputDebugStringA(Utils::VA("Inserted with IP: %s", server.Addr.GetString()));
 				}
 
 				break;
@@ -202,9 +283,9 @@ namespace Components
 	{
 		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;
 				serverAddr.SetIP(entry[i].IP);
 				serverAddr.SetPort(ntohs(entry[i].Port));
-				serverAddr.Get()->type = Game::NA_IP;
+				serverAddr.SetType(Game::NA_IP);
 
-				ServerList::Container::ServerContainer container;
-				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++;
-				}
+				ServerList::InsertRequest(serverAddr, false);
 			}
 
 			Logger::Print("Parsed %d servers from master\n", ServerList::RefreshContainer.Servers.size() - count);
@@ -356,6 +419,8 @@ namespace Components
 	ServerList::~ServerList()
 	{
 		ServerList::OnlineList.clear();
+		ServerList::OfflineList.clear();
+		ServerList::FavouriteList.clear();
 		ServerList::VisibleList.clear();
 	}
 }
diff --git a/src/Components/Modules/ServerList.hpp b/src/Components/Modules/ServerList.hpp
index 4f4e2634..24d1cdcf 100644
--- a/src/Components/Modules/ServerList.hpp
+++ b/src/Components/Modules/ServerList.hpp
@@ -26,8 +26,13 @@ namespace Components
 		const char* GetName() { return "ServerList"; };
 
 		static void Refresh();
+		static void InsertRequest(Network::Address address, bool accquireMutex = true);
 		static void Insert(Network::Address address, Utils::InfoString info);
 
+		static bool IsFavouriteList();
+		static bool IsOfflineList();
+		static bool IsOnlineList();
+
 	private:
 		enum Column
 		{
@@ -93,13 +98,18 @@ namespace Components
 		static void SortList();
 
 		static ServerInfo* GetServer(int index);
+		static std::vector<ServerInfo>& GetList();
 
 		static int SortKey;
 		static bool SortAsc;
 
 		static unsigned int CurrentServer;
 		static Container RefreshContainer;
+
 		static std::vector<ServerInfo> OnlineList;
+		static std::vector<ServerInfo> OfflineList;
+		static std::vector<ServerInfo> FavouriteList;
+
 		static std::vector<int> VisibleList;
 	};
 }
diff --git a/src/Components/Modules/Singleton.cpp b/src/Components/Modules/Singleton.cpp
index 9774c09b..4f4c6640 100644
--- a/src/Components/Modules/Singleton.cpp
+++ b/src/Components/Modules/Singleton.cpp
@@ -25,7 +25,7 @@ namespace Components
 			else
 			{
 				//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);
 				}
diff --git a/src/Game/Functions.cpp b/src/Game/Functions.cpp
index feba05d8..4455cc58 100644
--- a/src/Game/Functions.cpp
+++ b/src/Game/Functions.cpp
@@ -62,6 +62,7 @@ namespace Game
 
 	NET_AdrToString_t NET_AdrToString = (NET_AdrToString_t)0x469880;
 	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;
 
 	Live_MPAcceptInvite_t Live_MPAcceptInvite = (Live_MPAcceptInvite_t)0x420A6D;
@@ -128,6 +129,9 @@ namespace Game
 	party_t** partyIngame = (party_t**)0x1081C00;
 	PartyData_s** partyData = (PartyData_s**)0x107E500;
 
+	int* numIP = (int*)0x64A1E68;
+	netIP_t* localIP = (netIP_t*)0x64A1E28;
+
 	void* ReallocateAssetPool(XAssetType type, unsigned int newSize)
 	{
 		int elSize = DB_GetXAssetSizeHandlers[type]();
diff --git a/src/Game/Functions.hpp b/src/Game/Functions.hpp
index 6d83c1c3..701fb32a 100644
--- a/src/Game/Functions.hpp
+++ b/src/Game/Functions.hpp
@@ -145,6 +145,9 @@ namespace Game
 	typedef bool(__cdecl * NET_CompareAdr_t)(netadr_t, netadr_t);
 	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*);
 	extern NET_StringToAdr_t NET_StringToAdr;
 
@@ -247,6 +250,9 @@ namespace Game
 	extern party_t** partyIngame;
 	extern PartyData_s** partyData;
 
+	extern int* numIP;
+	extern netIP_t* localIP;
+
 	void* ReallocateAssetPool(XAssetType type, unsigned int newSize);
 	void Menu_FreeItemMemory(Game::itemDef_t* item);
 	void OOBPrintT(int type, netadr_t netadr, const char* message);
diff --git a/src/Game/Structs.hpp b/src/Game/Structs.hpp
index f6719f28..1affdd2f 100644
--- a/src/Game/Structs.hpp
+++ b/src/Game/Structs.hpp
@@ -626,10 +626,16 @@ namespace Game
 		NS_SERVER
 	} netsrc_t;
 
+	typedef union
+	{
+		BYTE bytes[4];
+		DWORD full;
+	} netIP_t;
+
 	typedef struct 
 	{
 		netadrtype_t type;
-		BYTE ip[4];
+		netIP_t ip;
 		unsigned short	port;
 		BYTE	ipx[10];
 	} netadr_t;
diff --git a/src/STDInclude.hpp b/src/STDInclude.hpp
index 42d9856d..0b5c2426 100644
--- a/src/STDInclude.hpp
+++ b/src/STDInclude.hpp
@@ -8,6 +8,7 @@
 #include <wincrypt.h>
 #include <time.h>
 #include <timeapi.h>
+#include <shellapi.h>
 #include <WinSock2.h>
 
 #include <map>
@@ -22,6 +23,7 @@
 #include <locale>
 #include <regex>
 #include <thread>
+#include <future>
 
 #include <version.hpp>