Merge remote-tracking branch 'upstream/main' into mods

This commit is contained in:
BrentVL-1952840 2023-04-24 14:34:01 +02:00
commit 8fe2325cdf
6 changed files with 238 additions and 68 deletions

View File

@ -87,7 +87,10 @@ end
local addCustomButtons = function(controller, menuId, buttonTable, isLeader) local addCustomButtons = function(controller, menuId, buttonTable, isLeader)
if menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id then if menuId == LobbyData.UITargets.UI_MPLOBBYMAIN.id then
utils.RemoveSpaces(buttonTable) utils.RemoveSpaces(buttonTable)
utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.THEATER_MP) - 1) local theaterIndex = utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.THEATER_MP)
if theaterIndex ~= nil then
utils.AddSpacer(buttonTable, theaterIndex - 1)
end
end end
if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then if menuId == LobbyData.UITargets.UI_MPLOBBYONLINE.id or menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then
@ -121,11 +124,14 @@ local addCustomButtons = function(controller, menuId, buttonTable, isLeader)
if menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then if menuId == LobbyData.UITargets.UI_ZMLOBBYONLINE.id then
utils.RemoveButton(buttonTable, CoD.LobbyButtons.THEATER_ZM) utils.RemoveButton(buttonTable, CoD.LobbyButtons.THEATER_ZM)
utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.THEATER_ZM, #buttonTable + 1) utils.AddLargeButton(controller, buttonTable, CoD.LobbyButtons.THEATER_ZM)
utils.RemoveSpaces(buttonTable) utils.RemoveSpaces(buttonTable)
utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.SERVER_BROWSER)) utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.SERVER_BROWSER))
utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.ZM_BUBBLEGUM_BUFFS) - 1) local bgbIndex = utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.ZM_BUBBLEGUM_BUFFS)
if bgbIndex ~= nil then
utils.AddSpacer(buttonTable, bgbIndex - 1)
end
utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.STATS)) utils.AddSpacer(buttonTable, utils.GetButtonIndex(buttonTable, CoD.LobbyButtons.STATS))
end end
end end

View File

@ -17,6 +17,9 @@ local SetButtonState = function(button, state)
end end
local RemoveButton = function(buttonTable, button) local RemoveButton = function(buttonTable, button)
if not button then
return
end
for id, v in pairs(buttonTable) do for id, v in pairs(buttonTable) do
if buttonTable[id].optionDisplay == button.stringRef then if buttonTable[id].optionDisplay == button.stringRef then
table.remove(buttonTable, id) table.remove(buttonTable, id)
@ -31,6 +34,9 @@ local RemoveSpaces = function(buttonTable)
end end
local GetButtonIndex = function(buttonTable, button) local GetButtonIndex = function(buttonTable, button)
if not button then
return nil
end
for id, v in pairs(buttonTable) do for id, v in pairs(buttonTable) do
if buttonTable[id].optionDisplay == button.stringRef then if buttonTable[id].optionDisplay == button.stringRef then
return id return id

View File

@ -7,6 +7,7 @@
#include <utils/string.hpp> #include <utils/string.hpp>
#include <utils/concurrency.hpp> #include <utils/concurrency.hpp>
#include <utils/hook.hpp> #include <utils/hook.hpp>
#include <utils/io.hpp>
#include "network.hpp" #include "network.hpp"
#include "scheduler.hpp" #include "scheduler.hpp"
@ -27,6 +28,8 @@ namespace server_list
utils::concurrency::container<state> master_state; utils::concurrency::container<state> master_state;
utils::concurrency::container<server_list> favorite_servers{};
void handle_server_list_response(const game::netadr_t& target, void handle_server_list_response(const game::netadr_t& target,
const network::data_view& data, state& s) const network::data_view& data, state& s)
{ {
@ -87,6 +90,48 @@ namespace server_list
game::Lua_SetTableInt("botCount", botCount, state); game::Lua_SetTableInt("botCount", botCount, state);
} }
} }
std::string get_favorite_servers_file_path()
{
return "players/user/favorite_servers.txt";
}
void write_favorite_servers()
{
favorite_servers.access([&](std::unordered_set<game::netadr_t>& servers)
{
std::string servers_buffer = "";
for (auto itr : servers)
{
servers_buffer.append(utils::string::va("%i.%i.%i.%i:%u\n", itr.ipv4.a, itr.ipv4.b, itr.ipv4.c, itr.ipv4.d, itr.port));
}
utils::io::write_file(get_favorite_servers_file_path(), servers_buffer);
});
}
void read_favorite_servers()
{
const std::string path = get_favorite_servers_file_path();
if (!utils::io::file_exists(path))
{
return;
}
favorite_servers.access([&path](std::unordered_set<game::netadr_t>& servers)
{
servers.clear();
std::string filedata;
if (utils::io::read_file(path, &filedata))
{
auto srv = utils::string::split(filedata, '\n');
for (auto server_address : srv)
{
auto server = network::address_from_string(server_address);
servers.insert(server);
}
}
});
}
} }
bool get_master_server(game::netadr_t& address) bool get_master_server(game::netadr_t& address)
@ -114,6 +159,36 @@ namespace server_list
}); });
} }
void add_favorite_server(game::netadr_t addr)
{
favorite_servers.access([&addr](std::unordered_set<game::netadr_t>& servers)
{
servers.insert(addr);
});
write_favorite_servers();
}
void remove_favorite_server(game::netadr_t addr)
{
favorite_servers.access([&addr](std::unordered_set<game::netadr_t>& servers)
{
for (auto it = servers.begin(); it != servers.end(); ++it)
{
if (network::are_addresses_equal(*it, addr))
{
servers.erase(it);
break;
}
}
});
write_favorite_servers();
}
utils::concurrency::container<server_list>& get_favorite_servers()
{
return favorite_servers;
}
struct component final : client_component struct component final : client_component
{ {
void post_unpack() override void post_unpack() override
@ -148,6 +223,11 @@ namespace server_list
}, scheduler::async, 200ms); }, scheduler::async, 200ms);
lua_serverinfo_to_table_hook.create(0x141F1FD10_g, lua_serverinfo_to_table_stub); lua_serverinfo_to_table_hook.create(0x141F1FD10_g, lua_serverinfo_to_table_stub);
scheduler::once([]
{
read_favorite_servers();
}, scheduler::main);
} }
void pre_destroy() override void pre_destroy() override

View File

@ -1,10 +1,17 @@
#pragma once #pragma once
#include <game/game.hpp> #include <game/game.hpp>
#include <utils/concurrency.hpp>
namespace server_list namespace server_list
{ {
bool get_master_server(game::netadr_t& address); bool get_master_server(game::netadr_t& address);
using callback = std::function<void(bool, const std::unordered_set<game::netadr_t>&)>; using callback = std::function<void(bool, const std::unordered_set<game::netadr_t>&)>;
void request_servers(callback callback); void request_servers(callback callback);
void add_favorite_server(game::netadr_t addr);
void remove_favorite_server(game::netadr_t addr);
using server_list = std::unordered_set<game::netadr_t>;
utils::concurrency::container<server_list>& get_favorite_servers();
} }

View File

@ -1,6 +1,9 @@
#include <std_include.hpp> #include <std_include.hpp>
#include "../steam.hpp" #include "../steam.hpp"
#include "component/network.hpp"
#include "component/server_list.hpp"
namespace steam namespace steam
{ {
int matchmaking::GetFavoriteGameCount() int matchmaking::GetFavoriteGameCount()
@ -19,12 +22,16 @@ namespace steam
unsigned short nQueryPort, unsigned int unFlags, unsigned short nQueryPort, unsigned int unFlags,
unsigned int rTime32LastPlayedOnServer) unsigned int rTime32LastPlayedOnServer)
{ {
auto addr = network::address_from_ip(htonl(nIP), nConnPort);
server_list::add_favorite_server(addr);
return 0; return 0;
} }
bool matchmaking::RemoveFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort, bool matchmaking::RemoveFavoriteGame(unsigned int nAppID, unsigned int nIP, unsigned short nConnPort,
unsigned short nQueryPort, unsigned int unFlags) unsigned short nQueryPort, unsigned int unFlags)
{ {
auto addr = network::address_from_ip(htonl(nIP), nConnPort);
server_list::remove_favorite_server(addr);
return false; return false;
} }

View File

@ -22,11 +22,14 @@ namespace steam
}; };
auto* const internet_request = reinterpret_cast<void*>(1); auto* const internet_request = reinterpret_cast<void*>(1);
auto* const favorites_request = reinterpret_cast<void*>(4);
using servers = std::vector<server>; using servers = std::vector<server>;
::utils::concurrency::container<servers> queried_servers{}; ::utils::concurrency::container<servers> internet_servers{};
std::atomic<matchmaking_server_list_response*> current_response{}; ::utils::concurrency::container<servers> favorites_servers{};
std::atomic<matchmaking_server_list_response*> internet_response{};
std::atomic<matchmaking_server_list_response*> favorites_response{};
template <typename T> template <typename T>
void copy_safe(T& dest, const char* in) void copy_safe(T& dest, const char* in)
@ -84,11 +87,12 @@ namespace steam
} }
void handle_server_respone(const bool success, const game::netadr_t& host, const ::utils::info_string& info, void handle_server_respone(const bool success, const game::netadr_t& host, const ::utils::info_string& info,
const uint32_t ping) const uint32_t ping, ::utils::concurrency::container<servers>& server_list,
std::atomic<matchmaking_server_list_response*>& response, void* request)
{ {
bool all_handled = false; bool all_handled = false;
std::optional<int> index{}; std::optional<int> index{};
queried_servers.access([&](servers& srvs) server_list.access([&](servers& srvs)
{ {
size_t i = 0; size_t i = 0;
for (; i < srvs.size(); ++i) for (; i < srvs.size(); ++i)
@ -122,7 +126,7 @@ namespace steam
all_handled = true; all_handled = true;
}); });
const auto res = current_response.load(); const auto res = response.load();
if (!index || !res) if (!index || !res)
{ {
return; return;
@ -130,33 +134,46 @@ namespace steam
if (success) if (success)
{ {
res->ServerResponded(internet_request, *index); res->ServerResponded(request, *index);
} }
else else
{ {
res->ServerFailedToRespond(internet_request, *index); res->ServerFailedToRespond(request, *index);
} }
if (all_handled) if (all_handled)
{ {
res->RefreshComplete(internet_request, eServerResponded); res->RefreshComplete(request, eServerResponded);
} }
} }
void ping_server(const game::netadr_t& server) void handle_internet_server_response(const bool success, const game::netadr_t& host, const ::utils::info_string& info,
const uint32_t ping)
{ {
party::query_server(server, handle_server_respone); handle_server_respone(success, host, info, ping, internet_servers, internet_response, internet_request);
}
void handle_favorites_server_response(const bool success, const game::netadr_t& host, const ::utils::info_string& info,
const uint32_t ping)
{
handle_server_respone(success, host, info, ping, favorites_servers, favorites_response, favorites_request);
}
void ping_server(const game::netadr_t& server, party::query_callback callback)
{
party::query_server(server, callback);
} }
} }
void* matchmaking_servers::RequestInternetServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, void* matchmaking_servers::RequestInternetServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
matchmaking_server_list_response* pRequestServersResponse) matchmaking_server_list_response* pRequestServersResponse)
{ {
current_response = pRequestServersResponse; internet_response = pRequestServersResponse;
server_list::request_servers([](const bool success, const std::unordered_set<game::netadr_t>& s) server_list::request_servers([](const bool success, const std::unordered_set<game::netadr_t>& s)
{ {
const auto res = current_response.load(); const auto res = internet_response.load();
if (!res) if (!res)
{ {
return; return;
@ -174,7 +191,7 @@ namespace steam
return; return;
} }
queried_servers.access([&s](servers& srvs) internet_servers.access([&s](servers& srvs)
{ {
srvs = {}; srvs = {};
srvs.reserve(s.size()); srvs.reserve(s.size());
@ -191,7 +208,7 @@ namespace steam
for (auto& srv : s) for (auto& srv : s)
{ {
ping_server(srv); ping_server(srv, handle_internet_server_response);
} }
}); });
@ -213,7 +230,45 @@ namespace steam
void* matchmaking_servers::RequestFavoritesServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, void* matchmaking_servers::RequestFavoritesServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
matchmaking_server_list_response* pRequestServersResponse) matchmaking_server_list_response* pRequestServersResponse)
{ {
return reinterpret_cast<void*>(4); favorites_response = pRequestServersResponse;
auto& srvs = server_list::get_favorite_servers();
srvs.access([&](std::unordered_set<game::netadr_t> s)
{
const auto res = favorites_response.load();
if (!res)
{
return;
}
if (s.empty())
{
res->RefreshComplete(favorites_request, eNoServersListedOnMasterServer);
return;
}
favorites_servers.access([s](servers& srvs)
{
srvs = {};
srvs.reserve(s.size());
for (auto& address : s)
{
server new_server{};
new_server.address = address;
new_server.server_item = create_server_item(address, {}, 0, false);
srvs.push_back(new_server);
}
});
for (auto& srv : s)
{
ping_server(srv, handle_favorites_server_response);
}
});
return favorites_request;
} }
void* matchmaking_servers::RequestHistoryServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters, void* matchmaking_servers::RequestHistoryServerList(unsigned int iApp, void** ppchFilters, unsigned int nFilters,
@ -232,19 +287,25 @@ namespace steam
{ {
if (internet_request == hServerListRequest) if (internet_request == hServerListRequest)
{ {
current_response = nullptr; internet_response = nullptr;
}
if (favorites_request == hServerListRequest)
{
favorites_response = nullptr;
} }
} }
gameserveritem_t* matchmaking_servers::GetServerDetails(void* hRequest, int iServer) gameserveritem_t* matchmaking_servers::GetServerDetails(void* hRequest, int iServer)
{ {
if (internet_request != hRequest) if (internet_request != hRequest && favorites_request != hRequest)
{ {
return nullptr; return nullptr;
} }
auto& servers_list = hRequest == favorites_request ? favorites_servers : internet_servers;
static thread_local gameserveritem_t server_item{}; static thread_local gameserveritem_t server_item{};
return queried_servers.access<gameserveritem_t*>([iServer](const servers& s) -> gameserveritem_t* { return servers_list.access<gameserveritem_t*>([iServer](const servers& s) -> gameserveritem_t* {
if (iServer < 0 || static_cast<size_t>(iServer) >= s.size()) if (iServer < 0 || static_cast<size_t>(iServer) >= s.size())
{ {
return nullptr; return nullptr;
@ -270,12 +331,13 @@ namespace steam
int matchmaking_servers::GetServerCount(void* hRequest) int matchmaking_servers::GetServerCount(void* hRequest)
{ {
if (internet_request != hRequest) if (internet_request != hRequest && favorites_request != hRequest)
{ {
return 0; return 0;
} }
return queried_servers.access<int>([](const servers& s) auto& servers_list = hRequest == favorites_request ? favorites_servers : internet_servers;
return servers_list.access<int>([](const servers& s)
{ {
return static_cast<int>(s.size()); return static_cast<int>(s.size());
}); });
@ -283,13 +345,14 @@ namespace steam
void matchmaking_servers::RefreshServer(void* hRequest, const int iServer) void matchmaking_servers::RefreshServer(void* hRequest, const int iServer)
{ {
if (internet_request != hRequest) if (internet_request != hRequest && favorites_request != hRequest)
{ {
return; return;
} }
std::optional<game::netadr_t> address{}; std::optional<game::netadr_t> address{};
queried_servers.access([&](const servers& s) auto& servers_list = hRequest == favorites_request ? favorites_servers : internet_servers;
servers_list.access([&](const servers& s)
{ {
if (iServer < 0 || static_cast<size_t>(iServer) >= s.size()) if (iServer < 0 || static_cast<size_t>(iServer) >= s.size())
{ {
@ -301,7 +364,8 @@ namespace steam
if (address) if (address)
{ {
ping_server(*address); auto callback = hRequest == favorites_request ? handle_favorites_server_response : handle_internet_server_response;
ping_server(*address, callback);
} }
} }