feat: add support for favorites in the server browser
This commit is contained in:
parent
e8dba61553
commit
b58c514261
@ -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;
|
||||||
|
|
||||||
|
std::vector<game::netadr_t> 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,52 @@ 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.csv";
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_favorite_servers()
|
||||||
|
{
|
||||||
|
std::string servers_buffer = "";
|
||||||
|
for (auto itr : favorite_servers)
|
||||||
|
{
|
||||||
|
servers_buffer.append(utils::string::va("%u,%u\n", itr.addr, itr.port));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (servers_buffer.empty())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.clear();
|
||||||
|
|
||||||
|
std::string filedata;
|
||||||
|
if (utils::io::read_file(path, &filedata))
|
||||||
|
{
|
||||||
|
auto servers = utils::string::split(filedata, '\n');
|
||||||
|
for (auto server_data : servers)
|
||||||
|
{
|
||||||
|
auto data = utils::string::split(server_data, ',');
|
||||||
|
auto addr = std::stoul(data[0].c_str());
|
||||||
|
auto port = (uint16_t)atoi(data[1].c_str());
|
||||||
|
auto server = network::address_from_ip(addr, port);
|
||||||
|
favorite_servers.push_back(server);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool get_master_server(game::netadr_t& address)
|
bool get_master_server(game::netadr_t& address)
|
||||||
@ -114,6 +163,37 @@ namespace server_list
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void add_favorite_server(game::netadr_t addr)
|
||||||
|
{
|
||||||
|
if (has_favorited_server(addr))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
favorite_servers.push_back(addr);
|
||||||
|
write_favorite_servers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_favorite_server(game::netadr_t addr)
|
||||||
|
{
|
||||||
|
for (auto it = favorite_servers.begin(); it != favorite_servers.end(); ++it)
|
||||||
|
{
|
||||||
|
if (network::are_addresses_equal(*it, addr))
|
||||||
|
{
|
||||||
|
favorite_servers.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
write_favorite_servers();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_favorited_server(game::netadr_t addr)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(favorite_servers.begin(), favorite_servers.end(), [&addr](const game::netadr_t& obj) { return network::are_addresses_equal(addr, obj); });
|
||||||
|
return it != favorite_servers.end();
|
||||||
|
}
|
||||||
|
|
||||||
struct component final : client_component
|
struct component final : client_component
|
||||||
{
|
{
|
||||||
void post_unpack() override
|
void post_unpack() override
|
||||||
@ -148,6 +228,8 @@ 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);
|
||||||
|
|
||||||
|
read_favorite_servers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pre_destroy() override
|
void pre_destroy() override
|
||||||
|
@ -7,4 +7,8 @@ namespace server_list
|
|||||||
|
|
||||||
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);
|
||||||
|
bool has_favorited_server(game::netadr_t addr);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ 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>;
|
||||||
|
|
||||||
@ -198,7 +199,54 @@ 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);
|
current_response = pRequestServersResponse;
|
||||||
|
|
||||||
|
server_list::request_servers([](const bool success, const std::unordered_set<game::netadr_t>& s)
|
||||||
|
{
|
||||||
|
const auto res = current_response.load();
|
||||||
|
if (!res)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
res->RefreshComplete(favorites_request, eServerFailedToRespond);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.empty())
|
||||||
|
{
|
||||||
|
res->RefreshComplete(favorites_request, eNoServersListedOnMasterServer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
queried_servers.access([&s](servers& srvs)
|
||||||
|
{
|
||||||
|
srvs = {};
|
||||||
|
srvs.reserve(s.size());
|
||||||
|
|
||||||
|
for (auto& address : s)
|
||||||
|
{
|
||||||
|
if (!server_list::has_favorited_server(address))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user