mirror of
https://gitlab.com/Mr_Goldberg/goldberg_emulator.git
synced 2025-12-05 11:44:53 +01:00
Initial commit.
This commit is contained in:
commit
d968c3e1b5
238 changed files with 86384 additions and 0 deletions
514
dll/steam_matchmaking_servers.cpp
Normal file
514
dll/steam_matchmaking_servers.cpp
Normal file
|
|
@ -0,0 +1,514 @@
|
|||
/* Copyright (C) 2019 Mr Goldberg
|
||||
This file is part of the Goldberg Emulator
|
||||
|
||||
The Goldberg Emulator is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
The Goldberg Emulator is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the Goldberg Emulator; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "steam_matchmaking_servers.h"
|
||||
|
||||
|
||||
static void network_callback(void *object, Common_Message *msg)
|
||||
{
|
||||
PRINT_DEBUG("steam_matchmaking_servers_callback\n");
|
||||
|
||||
Steam_Matchmaking_Servers *obj = (Steam_Matchmaking_Servers *)object;
|
||||
obj->Callback(msg);
|
||||
}
|
||||
|
||||
Steam_Matchmaking_Servers::Steam_Matchmaking_Servers(class Settings *settings, class Networking *network)
|
||||
{
|
||||
this->settings = settings;
|
||||
this->network = network;
|
||||
this->network->setCallback(CALLBACK_ID_GAMESERVER, (uint64) 0, &network_callback, this);
|
||||
}
|
||||
|
||||
static int server_list_request;
|
||||
|
||||
// Request a new list of servers of a particular type. These calls each correspond to one of the EMatchMakingType values.
|
||||
// Each call allocates a new asynchronous request object.
|
||||
// Request object must be released by calling ReleaseRequest( hServerListRequest )
|
||||
HServerListRequest Steam_Matchmaking_Servers::RequestInternetServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("RequestInternetServerList\n");
|
||||
//TODO
|
||||
return RequestLANServerList(iApp, pRequestServersResponse);
|
||||
}
|
||||
|
||||
HServerListRequest Steam_Matchmaking_Servers::RequestLANServerList( AppId_t iApp, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("RequestLANServerList %u\n", iApp);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
struct Steam_Matchmaking_Request request;
|
||||
request.appid = iApp;
|
||||
request.callbacks = pRequestServersResponse;
|
||||
request.cancelled = false;
|
||||
request.completed = false;
|
||||
requests.push_back(request);
|
||||
++server_list_request;
|
||||
requests[requests.size() - 1].id = (void *)server_list_request;
|
||||
HServerListRequest id = requests[requests.size() - 1].id;
|
||||
PRINT_DEBUG("request id: %p\n", id);
|
||||
return id;
|
||||
}
|
||||
|
||||
HServerListRequest Steam_Matchmaking_Servers::RequestFriendsServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("RequestFriendsServerList\n");
|
||||
//TODO
|
||||
return RequestLANServerList(iApp, pRequestServersResponse);
|
||||
}
|
||||
|
||||
HServerListRequest Steam_Matchmaking_Servers::RequestFavoritesServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("RequestFavoritesServerList\n");
|
||||
//TODO
|
||||
return RequestLANServerList(iApp, pRequestServersResponse);
|
||||
}
|
||||
|
||||
HServerListRequest Steam_Matchmaking_Servers::RequestHistoryServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("RequestHistoryServerList\n");
|
||||
//TODO
|
||||
return RequestLANServerList(iApp, pRequestServersResponse);
|
||||
}
|
||||
|
||||
HServerListRequest Steam_Matchmaking_Servers::RequestSpectatorServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("RequestSpectatorServerList\n");
|
||||
//TODO
|
||||
return RequestLANServerList(iApp, pRequestServersResponse);
|
||||
}
|
||||
|
||||
|
||||
// Releases the asynchronous request object and cancels any pending query on it if there's a pending query in progress.
|
||||
// RefreshComplete callback is not posted when request is released.
|
||||
void Steam_Matchmaking_Servers::ReleaseRequest( HServerListRequest hServerListRequest )
|
||||
{
|
||||
PRINT_DEBUG("ReleaseRequest %p\n", hServerListRequest);
|
||||
auto g = std::begin(requests);
|
||||
while (g != std::end(requests)) {
|
||||
if (g->id == hServerListRequest) {
|
||||
//NOTE: some garbage games release the request before getting server details from it.
|
||||
// g = requests.erase(g);
|
||||
// } else {
|
||||
//TODO: eventually delete the released request.
|
||||
g->cancelled = true;
|
||||
g->released = true;
|
||||
}
|
||||
|
||||
++g;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* the filter operation codes that go in the key part of MatchMakingKeyValuePair_t should be one of these:
|
||||
|
||||
"map"
|
||||
- Server passes the filter if the server is playing the specified map.
|
||||
"gamedataand"
|
||||
- Server passes the filter if the server's game data (ISteamGameServer::SetGameData) contains all of the
|
||||
specified strings. The value field is a comma-delimited list of strings to match.
|
||||
"gamedataor"
|
||||
- Server passes the filter if the server's game data (ISteamGameServer::SetGameData) contains at least one of the
|
||||
specified strings. The value field is a comma-delimited list of strings to match.
|
||||
"gamedatanor"
|
||||
- Server passes the filter if the server's game data (ISteamGameServer::SetGameData) does not contain any
|
||||
of the specified strings. The value field is a comma-delimited list of strings to check.
|
||||
"gametagsand"
|
||||
- Server passes the filter if the server's game tags (ISteamGameServer::SetGameTags) contains all
|
||||
of the specified strings. The value field is a comma-delimited list of strings to check.
|
||||
"gametagsnor"
|
||||
- Server passes the filter if the server's game tags (ISteamGameServer::SetGameTags) does not contain any
|
||||
of the specified strings. The value field is a comma-delimited list of strings to check.
|
||||
"and" (x1 && x2 && ... && xn)
|
||||
"or" (x1 || x2 || ... || xn)
|
||||
"nand" !(x1 && x2 && ... && xn)
|
||||
"nor" !(x1 || x2 || ... || xn)
|
||||
- Performs Boolean operation on the following filters. The operand to this filter specifies
|
||||
the "size" of the Boolean inputs to the operation, in Key/value pairs. (The keyvalue
|
||||
pairs must immediately follow, i.e. this is a prefix logical operator notation.)
|
||||
In the simplest case where Boolean expressions are not nested, this is simply
|
||||
the number of operands.
|
||||
|
||||
For example, to match servers on a particular map or with a particular tag, would would
|
||||
use these filters.
|
||||
|
||||
( server.map == "cp_dustbowl" || server.gametags.contains("payload") )
|
||||
"or", "2"
|
||||
"map", "cp_dustbowl"
|
||||
"gametagsand", "payload"
|
||||
|
||||
If logical inputs are nested, then the operand specifies the size of the entire
|
||||
"length" of its operands, not the number of immediate children.
|
||||
|
||||
( server.map == "cp_dustbowl" || ( server.gametags.contains("payload") && !server.gametags.contains("payloadrace") ) )
|
||||
"or", "4"
|
||||
"map", "cp_dustbowl"
|
||||
"and", "2"
|
||||
"gametagsand", "payload"
|
||||
"gametagsnor", "payloadrace"
|
||||
|
||||
Unary NOT can be achieved using either "nand" or "nor" with a single operand.
|
||||
|
||||
"addr"
|
||||
- Server passes the filter if the server's query address matches the specified IP or IP:port.
|
||||
"gameaddr"
|
||||
- Server passes the filter if the server's game address matches the specified IP or IP:port.
|
||||
|
||||
The following filter operations ignore the "value" part of MatchMakingKeyValuePair_t
|
||||
|
||||
"dedicated"
|
||||
- Server passes the filter if it passed true to SetDedicatedServer.
|
||||
"secure"
|
||||
- Server passes the filter if the server is VAC-enabled.
|
||||
"notfull"
|
||||
- Server passes the filter if the player count is less than the reported max player count.
|
||||
"hasplayers"
|
||||
- Server passes the filter if the player count is greater than zero.
|
||||
"noplayers"
|
||||
- Server passes the filter if it doesn't have any players.
|
||||
"linux"
|
||||
- Server passes the filter if it's a linux server
|
||||
*/
|
||||
|
||||
void Steam_Matchmaking_Servers::server_details(Gameserver *g, gameserveritem_t *server)
|
||||
{
|
||||
uint16 query_port = g->query_port();
|
||||
if (g->query_port() == 0xFFFF) {
|
||||
query_port = g->port();
|
||||
}
|
||||
|
||||
server->m_NetAdr.Init(g->ip(), query_port, g->port());
|
||||
server->m_nPing = 10; //TODO
|
||||
server->m_bHadSuccessfulResponse = true;
|
||||
server->m_bDoNotRefresh = false;
|
||||
strncpy(server->m_szGameDir, g->mod_dir().c_str(), k_cbMaxGameServerGameDir - 1);
|
||||
strncpy(server->m_szMap, g->map_name().c_str(), k_cbMaxGameServerMapName - 1);
|
||||
strncpy(server->m_szGameDescription, g->game_description().c_str(), k_cbMaxGameServerGameDescription - 1);
|
||||
|
||||
server->m_szGameDir[k_cbMaxGameServerGameDir - 1] = 0;
|
||||
server->m_szMap[k_cbMaxGameServerMapName - 1] = 0;
|
||||
server->m_szGameDescription[k_cbMaxGameServerGameDescription - 1] = 0;
|
||||
|
||||
server->m_nAppID = g->appid();
|
||||
server->m_nPlayers = g->num_players();
|
||||
server->m_nMaxPlayers = g->max_player_count();
|
||||
server->m_nBotPlayers = g->bot_player_count();
|
||||
server->m_bPassword = g->password_protected();
|
||||
server->m_bSecure = g->secure();
|
||||
server->m_ulTimeLastPlayed = 0;
|
||||
server->m_nServerVersion = g->version();
|
||||
server->SetName(g->server_name().c_str());
|
||||
server->m_steamID = CSteamID((uint64)g->id());
|
||||
PRINT_DEBUG("server_details %llu\n", g->id());
|
||||
|
||||
strncpy(server->m_szGameTags, g->tags().c_str(), k_cbMaxGameServerTags - 1);
|
||||
server->m_szGameTags[k_cbMaxGameServerTags - 1] = 0;
|
||||
}
|
||||
|
||||
// Get details on a given server in the list, you can get the valid range of index
|
||||
// values by calling GetServerCount(). You will also receive index values in
|
||||
// ISteamMatchmakingServerListResponse::ServerResponded() callbacks
|
||||
gameserveritem_t *Steam_Matchmaking_Servers::GetServerDetails( HServerListRequest hRequest, int iServer )
|
||||
{
|
||||
PRINT_DEBUG("GetServerDetails %p %i\n", hRequest, iServer);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
std::vector <struct Steam_Matchmaking_Servers_Gameserver> gameservers_filtered;
|
||||
auto g = std::begin(requests);
|
||||
while (g != std::end(requests)) {
|
||||
PRINT_DEBUG("equal? %p %p\n", hRequest, g->id);
|
||||
if (g->id == hRequest) {
|
||||
gameservers_filtered = g->gameservers_filtered;
|
||||
PRINT_DEBUG("found %u\n", gameservers_filtered.size());
|
||||
break;
|
||||
}
|
||||
|
||||
++g;
|
||||
}
|
||||
|
||||
if (iServer >= gameservers_filtered.size() || iServer < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Gameserver *gs = &gameservers_filtered[iServer].server;
|
||||
gameserveritem_t *server = new gameserveritem_t(); //TODO: is the new here ok?
|
||||
server_details(gs, server);
|
||||
PRINT_DEBUG("Returned server details\n");
|
||||
return server;
|
||||
}
|
||||
|
||||
|
||||
// Cancel an request which is operation on the given list type. You should call this to cancel
|
||||
// any in-progress requests before destructing a callback object that may have been passed
|
||||
// to one of the above list request calls. Not doing so may result in a crash when a callback
|
||||
// occurs on the destructed object.
|
||||
// Canceling a query does not release the allocated request handle.
|
||||
// The request handle must be released using ReleaseRequest( hRequest )
|
||||
void Steam_Matchmaking_Servers::CancelQuery( HServerListRequest hRequest )
|
||||
{
|
||||
PRINT_DEBUG("CancelQuery %p\n", hRequest);
|
||||
auto g = std::begin(requests);
|
||||
while (g != std::end(requests)) {
|
||||
if (g->id == hRequest) {
|
||||
g->cancelled = true;
|
||||
}
|
||||
|
||||
++g;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Ping every server in your list again but don't update the list of servers
|
||||
// Query callback installed when the server list was requested will be used
|
||||
// again to post notifications and RefreshComplete, so the callback must remain
|
||||
// valid until another RefreshComplete is called on it or the request
|
||||
// is released with ReleaseRequest( hRequest )
|
||||
void Steam_Matchmaking_Servers::RefreshQuery( HServerListRequest hRequest )
|
||||
{
|
||||
PRINT_DEBUG("RefreshQuery %p\n", hRequest);
|
||||
}
|
||||
|
||||
|
||||
// Returns true if the list is currently refreshing its server list
|
||||
bool Steam_Matchmaking_Servers::IsRefreshing( HServerListRequest hRequest )
|
||||
{
|
||||
PRINT_DEBUG("IsRefreshing %p\n", hRequest);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// How many servers in the given list, GetServerDetails above takes 0... GetServerCount() - 1
|
||||
int Steam_Matchmaking_Servers::GetServerCount( HServerListRequest hRequest )
|
||||
{
|
||||
PRINT_DEBUG("GetServerCount %p\n", hRequest);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
int size = 0;
|
||||
auto g = std::begin(requests);
|
||||
while (g != std::end(requests)) {
|
||||
if (g->id == hRequest) {
|
||||
size = g->gameservers_filtered.size();
|
||||
break;
|
||||
}
|
||||
|
||||
++g;
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
// Refresh a single server inside of a query (rather than all the servers )
|
||||
void Steam_Matchmaking_Servers::RefreshServer( HServerListRequest hRequest, int iServer )
|
||||
{
|
||||
PRINT_DEBUG("RefreshServer %p\n", hRequest);
|
||||
//TODO
|
||||
}
|
||||
|
||||
static HServerQuery new_server_query()
|
||||
{
|
||||
static int a;
|
||||
++a;
|
||||
if (!a) ++a;
|
||||
return a;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Queries to individual servers directly via IP/Port
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// Request updated ping time and other details from a single server
|
||||
HServerQuery Steam_Matchmaking_Servers::PingServer( uint32 unIP, uint16 usPort, ISteamMatchmakingPingResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("PingServer %hhu.%hhu.%hhu.%hhu:%hu\n", ((unsigned char *)&unIP)[3], ((unsigned char *)&unIP)[2], ((unsigned char *)&unIP)[1], ((unsigned char *)&unIP)[0], usPort);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
Steam_Matchmaking_Servers_Direct_IP_Request r;
|
||||
r.id = new_server_query();
|
||||
r.ip = unIP;
|
||||
r.port = usPort;
|
||||
r.ping_response = pRequestServersResponse;
|
||||
direct_ip_requests.push_back(r);
|
||||
return r.id;
|
||||
}
|
||||
|
||||
// Request the list of players currently playing on a server
|
||||
HServerQuery Steam_Matchmaking_Servers::PlayerDetails( uint32 unIP, uint16 usPort, ISteamMatchmakingPlayersResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("PlayerDetails %hhu.%hhu.%hhu.%hhu:%hu\n", ((unsigned char *)&unIP)[3], ((unsigned char *)&unIP)[2], ((unsigned char *)&unIP)[1], ((unsigned char *)&unIP)[0], usPort);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
Steam_Matchmaking_Servers_Direct_IP_Request r;
|
||||
r.id = new_server_query();
|
||||
r.ip = unIP;
|
||||
r.port = usPort;
|
||||
r.players_response = pRequestServersResponse;
|
||||
direct_ip_requests.push_back(r);
|
||||
return r.id;
|
||||
}
|
||||
|
||||
|
||||
// Request the list of rules that the server is running (See ISteamGameServer::SetKeyValue() to set the rules server side)
|
||||
HServerQuery Steam_Matchmaking_Servers::ServerRules( uint32 unIP, uint16 usPort, ISteamMatchmakingRulesResponse *pRequestServersResponse )
|
||||
{
|
||||
PRINT_DEBUG("ServerRules %hhu.%hhu.%hhu.%hhu:%hu\n", ((unsigned char *)&unIP)[3], ((unsigned char *)&unIP)[2], ((unsigned char *)&unIP)[1], ((unsigned char *)&unIP)[0], usPort);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
Steam_Matchmaking_Servers_Direct_IP_Request r;
|
||||
r.id = new_server_query();
|
||||
r.ip = unIP;
|
||||
r.port = usPort;
|
||||
r.rules_response = pRequestServersResponse;
|
||||
direct_ip_requests.push_back(r);
|
||||
return r.id;
|
||||
}
|
||||
|
||||
|
||||
// Cancel an outstanding Ping/Players/Rules query from above. You should call this to cancel
|
||||
// any in-progress requests before destructing a callback object that may have been passed
|
||||
// to one of the above calls to avoid crashing when callbacks occur.
|
||||
void Steam_Matchmaking_Servers::CancelServerQuery( HServerQuery hServerQuery )
|
||||
{
|
||||
PRINT_DEBUG("CancelServerQuery\n");
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
auto r = std::find_if(direct_ip_requests.begin(), direct_ip_requests.end(), [&hServerQuery](Steam_Matchmaking_Servers_Direct_IP_Request const& item) { return item.id == hServerQuery; });
|
||||
if (direct_ip_requests.end() == r) return;
|
||||
direct_ip_requests.erase(r);
|
||||
}
|
||||
|
||||
void Steam_Matchmaking_Servers::RunCallbacks()
|
||||
{
|
||||
PRINT_DEBUG("Steam_Matchmaking_Servers::RunCallbacks\n");
|
||||
|
||||
{
|
||||
auto g = std::begin(gameservers);
|
||||
while (g != std::end(gameservers)) {
|
||||
if (check_timedout(g->last_recv, SERVER_TIMEOUT)) {
|
||||
g = gameservers.erase(g);
|
||||
PRINT_DEBUG("SERVER TIMEOUT\n");
|
||||
} else {
|
||||
++g;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PRINT_DEBUG("REQUESTS %zu gs: %zu\n", requests.size(), gameservers.size());
|
||||
|
||||
for (auto &r : requests) {
|
||||
if (r.cancelled || r.completed) continue;
|
||||
|
||||
r.gameservers_filtered.clear();
|
||||
for (auto &g : gameservers) {
|
||||
if (g.server.appid() == r.appid) {
|
||||
PRINT_DEBUG("REQUESTS server found\n");
|
||||
r.gameservers_filtered.push_back(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector <struct Steam_Matchmaking_Request> requests_temp(requests);
|
||||
PRINT_DEBUG("REQUESTS_TEMP %zu\n", requests_temp.size());
|
||||
for (auto &r : requests) {
|
||||
r.completed = true;
|
||||
}
|
||||
|
||||
for (auto &r : requests_temp) {
|
||||
if (r.cancelled || r.completed) continue;
|
||||
int i = 0;
|
||||
|
||||
for (auto &g : r.gameservers_filtered) {
|
||||
PRINT_DEBUG("REQUESTS server responded cb %p\n", r.id);
|
||||
r.callbacks->ServerResponded(r.id, i);
|
||||
++i;
|
||||
}
|
||||
|
||||
if (i) {
|
||||
r.callbacks->RefreshComplete(r.id, eServerResponded);
|
||||
} else {
|
||||
r.callbacks->RefreshComplete(r.id, eNoServersListedOnMasterServer);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector <struct Steam_Matchmaking_Servers_Direct_IP_Request> direct_ip_requests_temp = direct_ip_requests;
|
||||
direct_ip_requests.clear();
|
||||
|
||||
for (auto &r : direct_ip_requests_temp) {
|
||||
PRINT_DEBUG("dip request: %lu:%hu\n", r.ip, r.port);
|
||||
for (auto &g : gameservers) {
|
||||
PRINT_DEBUG("server: %lu:%hu\n", g.server.ip(), g.server.query_port());
|
||||
uint16 query_port = g.server.query_port();
|
||||
if (query_port == 0xFFFF) {
|
||||
query_port = g.server.port();
|
||||
}
|
||||
|
||||
if (query_port == r.port && g.server.ip() == r.ip) {
|
||||
if (r.rules_response) {
|
||||
int number_rules = g.server.values().size();
|
||||
PRINT_DEBUG("rules: %lu\n", number_rules);
|
||||
auto rule = g.server.values().begin();
|
||||
for (int i = 0; i < number_rules; ++i) {
|
||||
PRINT_DEBUG("RULE %s %s\n", rule->first.c_str(), rule->second.c_str());
|
||||
r.rules_response->RulesResponded(rule->first.c_str(), rule->second.c_str());
|
||||
++rule;
|
||||
}
|
||||
|
||||
r.rules_response->RulesRefreshComplete();
|
||||
r.rules_response = NULL;
|
||||
}
|
||||
|
||||
if (r.ping_response) {
|
||||
gameserveritem_t server;
|
||||
server_details(&(g.server), &server);
|
||||
r.ping_response->ServerResponded(server);
|
||||
r.ping_response = NULL;
|
||||
}
|
||||
//TODO: players response
|
||||
}
|
||||
}
|
||||
|
||||
if (r.rules_response) r.rules_response->RulesRefreshComplete();
|
||||
//TODO: player response
|
||||
if (r.players_response) r.players_response->PlayersRefreshComplete();
|
||||
if (r.ping_response) r.ping_response->ServerFailedToRespond();
|
||||
}
|
||||
}
|
||||
|
||||
void Steam_Matchmaking_Servers::Callback(Common_Message *msg)
|
||||
{
|
||||
if (msg->has_gameserver()) {
|
||||
if (msg->gameserver().offline()) {
|
||||
for (auto &g : gameservers) {
|
||||
if (g.server.id() == msg->gameserver().id()) {
|
||||
g.last_recv = std::chrono::high_resolution_clock::time_point();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bool already = false;
|
||||
for (auto &g : gameservers) {
|
||||
if (g.server.id() == msg->gameserver().id()) {
|
||||
g.last_recv = std::chrono::high_resolution_clock::now();
|
||||
g.server = msg->gameserver();
|
||||
g.server.set_ip(msg->source_ip());
|
||||
already = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!already) {
|
||||
struct Steam_Matchmaking_Servers_Gameserver g;
|
||||
g.last_recv = std::chrono::high_resolution_clock::now();
|
||||
g.server = msg->gameserver();
|
||||
g.server.set_ip(msg->source_ip());
|
||||
gameservers.push_back(g);
|
||||
PRINT_DEBUG("SERVER ADDED\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue