diff --git a/README.md b/README.md
index a9c15669..4f3d7011 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,6 @@
# H1-Mod 1.4
-- *This project supports only singleplayer for now*
-- ***YOU CAN'T** get in multiplayer, networking development is slow.*
+- *Note: Multiplayer support is in progress!*
diff --git a/src/client/component/demonware.cpp b/src/client/component/demonware.cpp
index 7d4c5b56..b745023b 100644
--- a/src/client/component/demonware.cpp
+++ b/src/client/component/demonware.cpp
@@ -129,19 +129,43 @@ namespace demonware
server = udp_servers.find(name);
}
- const auto result = getaddrinfo(name, service, hints, res);
-
if (!server)
{
- return result;
+ return getaddrinfo(name, service, hints, res);
}
- auto address = reinterpret_cast(res[0]->ai_addr);
- address->sin_addr.s_addr = server->get_address();
+ const auto address = utils::memory::get_allocator()->allocate();
+ const auto ai = utils::memory::get_allocator()->allocate();
+
+ auto in_addr = reinterpret_cast(address);
+ in_addr->sin_addr.s_addr = server->get_address();
+ in_addr->sin_family = AF_INET;
+
+ ai->ai_family = AF_INET;
+ ai->ai_socktype = SOCK_STREAM;
+ ai->ai_addr = address;
+ ai->ai_addrlen = sizeof(sockaddr);
+ ai->ai_next = nullptr;
+ ai->ai_flags = 0;
+ ai->ai_protocol = 0;
+ ai->ai_canonname = const_cast(name);
+
+ *res = ai;
return 0;
}
+ void freeaddrinfo_stub(addrinfo* ai)
+ {
+ if (!utils::memory::get_allocator()->find(ai))
+ {
+ return freeaddrinfo(ai);
+ }
+
+ utils::memory::get_allocator()->free(ai->ai_addr);
+ utils::memory::get_allocator()->free(ai);
+ }
+
int getpeername_stub(const SOCKET s, sockaddr* addr, socklen_t* addrlen)
{
auto* server = find_server(s);
@@ -500,6 +524,7 @@ namespace demonware
if (function == "#20") return io::sendto_stub;
if (function == "#52") return io::gethostbyname_stub;
if (function == "getaddrinfo") return io::getaddrinfo_stub;
+ if (function == "freeaddrinfo") return io::freeaddrinfo_stub;
}
if (function == "InternetGetConnectedState")
diff --git a/src/client/component/game_console.cpp b/src/client/component/game_console.cpp
index ca629513..e4189453 100644
--- a/src/client/component/game_console.cpp
+++ b/src/client/component/game_console.cpp
@@ -190,7 +190,7 @@ namespace game_console
for (const auto& dvar : dvars::dvar_list)
{
auto name = utils::string::to_lower(dvar);
- if (match_compare(input, name, exact))
+ if (game::Dvar_FindVar(name.data()) && match_compare(input, name, exact))
{
suggestions.push_back(dvar);
}
@@ -245,9 +245,6 @@ namespace game_console
con.globals.y + con.globals.font_height, 1.0f, 1.0f, 0, color_white, 0,
con.cursor, '|');
- game::R_AddCmdDrawText(con.buffer, 0x7FFF, console_font, con.globals.x,
- con.globals.y + con.globals.font_height, 1.0f, 1.0f, 0.0f, color_white, 0);
-
// check if using a prefixed '/' or not
const auto input = con.buffer[1] && (con.buffer[0] == '/' || con.buffer[0] == '\\')
? std::string(con.buffer).substr(1)
diff --git a/src/common/utils/memory.cpp b/src/common/utils/memory.cpp
index 52d46771..99a03916 100644
--- a/src/common/utils/memory.cpp
+++ b/src/common/utils/memory.cpp
@@ -62,6 +62,14 @@ namespace utils
return data;
}
+ bool memory::allocator::find(const void* data)
+ {
+ std::lock_guard _(this->mutex_);
+
+ const auto j = std::find(this->pool_.begin(), this->pool_.end(), data);
+ return j != this->pool_.end();
+ }
+
void* memory::allocate(const size_t length)
{
return calloc(length, 1);
diff --git a/src/common/utils/memory.hpp b/src/common/utils/memory.hpp
index 5af5645e..01f9554f 100644
--- a/src/common/utils/memory.hpp
+++ b/src/common/utils/memory.hpp
@@ -37,6 +37,8 @@ namespace utils
char* duplicate_string(const std::string& string);
+ bool find(const void* data);
+
private:
std::mutex mutex_;
std::vector pool_;