|
|
|
@ -53,7 +53,7 @@ HServerListRequest Steam_Matchmaking_Servers::RequestServerList(AppId_t iApp, IS
|
|
|
|
|
requests.push_back(request);
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers::request id: %p\n", id);
|
|
|
|
|
|
|
|
|
|
if (type == eLANServer) return id;
|
|
|
|
|
if (type == eLANServer || settings->matchmaking_server_list_always_lan_type) return id;
|
|
|
|
|
|
|
|
|
|
if (type == eFriendsServer) {
|
|
|
|
|
for (auto &g : gameservers_friends) {
|
|
|
|
@ -145,7 +145,7 @@ HServerListRequest Steam_Matchmaking_Servers::RequestServerList(AppId_t iApp, IS
|
|
|
|
|
HServerListRequest Steam_Matchmaking_Servers::RequestInternetServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
|
|
|
|
{
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers::RequestInternetServerList\n");
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eLANServer);
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eInternetServer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HServerListRequest Steam_Matchmaking_Servers::RequestLANServerList( AppId_t iApp, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
|
|
|
@ -157,27 +157,29 @@ HServerListRequest Steam_Matchmaking_Servers::RequestLANServerList( AppId_t iApp
|
|
|
|
|
HServerListRequest Steam_Matchmaking_Servers::RequestFriendsServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
|
|
|
|
{
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers::RequestFriendsServerList\n");
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eLANServer);
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eFriendsServer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HServerListRequest Steam_Matchmaking_Servers::RequestFavoritesServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
|
|
|
|
{
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers::RequestFavoritesServerList\n");
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eLANServer);
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eFavoritesServer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HServerListRequest Steam_Matchmaking_Servers::RequestHistoryServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
|
|
|
|
{
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers::RequestHistoryServerList\n");
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eLANServer);
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eHistoryServer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
HServerListRequest Steam_Matchmaking_Servers::RequestSpectatorServerList( AppId_t iApp, STEAM_ARRAY_COUNT(nFilters) MatchMakingKeyValuePair_t **ppchFilters, uint32 nFilters, ISteamMatchmakingServerListResponse *pRequestServersResponse )
|
|
|
|
|
{
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers::RequestSpectatorServerList\n");
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eLANServer);
|
|
|
|
|
return RequestServerList(iApp, pRequestServersResponse, eSpectatorServer);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// old server list request
|
|
|
|
|
|
|
|
|
|
void Steam_Matchmaking_Servers::RequestOldServerList(AppId_t iApp, ISteamMatchmakingServerListResponse001 *pRequestServersResponse, EMatchMakingType type)
|
|
|
|
|
{
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers::RequestOldServerList %u\n", iApp);
|
|
|
|
@ -338,13 +340,78 @@ void Steam_Matchmaking_Servers::ReleaseRequest( HServerListRequest hServerListRe
|
|
|
|
|
|
|
|
|
|
void Steam_Matchmaking_Servers::server_details(Gameserver *g, gameserveritem_t *server)
|
|
|
|
|
{
|
|
|
|
|
int latency = 10;
|
|
|
|
|
|
|
|
|
|
if (settings->matchmaking_server_details_via_source_query && !(g->ip() < 0) && !(g->query_port() < 0)) {
|
|
|
|
|
unsigned char ip[4]{};
|
|
|
|
|
char newip[24];
|
|
|
|
|
ip[0] = g->ip() & 0xFF;
|
|
|
|
|
ip[1] = (g->ip() >> 8) & 0xFF;
|
|
|
|
|
ip[2] = (g->ip() >> 16) & 0xFF;
|
|
|
|
|
ip[3] = (g->ip() >> 24) & 0xFF;
|
|
|
|
|
snprintf(newip, sizeof(newip), "%d.%d.%d.%d", ip[3], ip[2], ip[1], ip[0]);
|
|
|
|
|
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details connecting to ssq server on %s:%u\n", newip, g->query_port());
|
|
|
|
|
SSQ_SERVER *ssq = ssq_server_new(newip, g->query_port());
|
|
|
|
|
if (ssq != NULL && ssq_server_eok(ssq)) {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details ssq server connection ok\n");
|
|
|
|
|
ssq_server_timeout(ssq, (SSQ_TIMEOUT_SELECTOR)(SSQ_TIMEOUT_RECV | SSQ_TIMEOUT_SEND), 1200);
|
|
|
|
|
|
|
|
|
|
std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now();
|
|
|
|
|
A2S_INFO *ssq_a2s_info = ssq_info(ssq);
|
|
|
|
|
std::chrono::high_resolution_clock::time_point t2 = std::chrono::high_resolution_clock::now();
|
|
|
|
|
latency = (int)std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1).count();
|
|
|
|
|
if (latency < 10) latency = 10; // TODO I don't know if low latency is problematic or not
|
|
|
|
|
|
|
|
|
|
if (ssq_server_eok(ssq)) {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details ssq server info ok\n");
|
|
|
|
|
if (ssq_info_has_steamid(ssq_a2s_info)) g->set_id(ssq_a2s_info->steamid);
|
|
|
|
|
g->set_game_description(ssq_a2s_info->game);
|
|
|
|
|
g->set_mod_dir(ssq_a2s_info->folder);
|
|
|
|
|
if (ssq_a2s_info->server_type == A2S_SERVER_TYPE_DEDICATED) g->set_dedicated_server(true);
|
|
|
|
|
else if (ssq_a2s_info->server_type == A2S_SERVER_TYPE_STV_RELAY) g->set_dedicated_server(true);
|
|
|
|
|
else g->set_dedicated_server(false);
|
|
|
|
|
g->set_max_player_count(ssq_a2s_info->max_players);
|
|
|
|
|
g->set_bot_player_count(ssq_a2s_info->bots);
|
|
|
|
|
g->set_server_name(ssq_a2s_info->name);
|
|
|
|
|
g->set_map_name(ssq_a2s_info->map);
|
|
|
|
|
if (ssq_a2s_info->visibility) g->set_password_protected(true);
|
|
|
|
|
else g->set_password_protected(false);
|
|
|
|
|
if (ssq_info_has_stv(ssq_a2s_info)) {
|
|
|
|
|
g->set_spectator_port(ssq_a2s_info->stv_port);
|
|
|
|
|
g->set_spectator_server_name(ssq_a2s_info->stv_name);
|
|
|
|
|
}
|
|
|
|
|
//g->set_tags(ssq_a2s_info->keywords);
|
|
|
|
|
//g->set_gamedata();
|
|
|
|
|
//g->set_region();
|
|
|
|
|
g->set_product(ssq_a2s_info->game);
|
|
|
|
|
if (ssq_a2s_info->vac) g->set_secure(true);
|
|
|
|
|
else g->set_secure(false);
|
|
|
|
|
g->set_num_players(ssq_a2s_info->players);
|
|
|
|
|
g->set_version(std::stoull(ssq_a2s_info->version, NULL, 0));
|
|
|
|
|
if (ssq_info_has_port(ssq_a2s_info)) g->set_port(ssq_a2s_info->port);
|
|
|
|
|
if (ssq_info_has_gameid(ssq_a2s_info)) g->set_appid(ssq_a2s_info->gameid);
|
|
|
|
|
else g->set_appid(ssq_a2s_info->id);
|
|
|
|
|
g->set_offline(false);
|
|
|
|
|
} else {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details ssq server info failed: %s\n", ssq_server_emsg(ssq));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ssq_a2s_info != NULL) ssq_info_free(ssq_a2s_info);
|
|
|
|
|
} else {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details ssq server connection failed: %s\n", (ssq ? ssq_server_emsg(ssq) : "NULL instance"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ssq != NULL) ssq_server_free(ssq);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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_nPing = latency;
|
|
|
|
|
server->m_bHadSuccessfulResponse = true;
|
|
|
|
|
server->m_bDoNotRefresh = false;
|
|
|
|
|
|
|
|
|
@ -374,6 +441,104 @@ void Steam_Matchmaking_Servers::server_details(Gameserver *g, gameserveritem_t *
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details " "%" PRIu64 "\n", g->id());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Steam_Matchmaking_Servers::server_details_players(Gameserver *g, Steam_Matchmaking_Servers_Direct_IP_Request *r)
|
|
|
|
|
{
|
|
|
|
|
if (settings->matchmaking_server_details_via_source_query && !(g->ip() < 0) && !(g->query_port() < 0)) {
|
|
|
|
|
unsigned char ip[4]{};
|
|
|
|
|
char newip[24];
|
|
|
|
|
ip[0] = g->ip() & 0xFF;
|
|
|
|
|
ip[1] = (g->ip() >> 8) & 0xFF;
|
|
|
|
|
ip[2] = (g->ip() >> 16) & 0xFF;
|
|
|
|
|
ip[3] = (g->ip() >> 24) & 0xFF;
|
|
|
|
|
snprintf(newip, sizeof(newip), "%d.%d.%d.%d", ip[3], ip[2], ip[1], ip[0]);
|
|
|
|
|
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_players connecting to ssq server on %s:%u\n", newip, g->query_port());
|
|
|
|
|
SSQ_SERVER *ssq = ssq_server_new(newip, g->query_port());
|
|
|
|
|
if (ssq != NULL && ssq_server_eok(ssq)) {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_players ssq server connection ok\n");
|
|
|
|
|
ssq_server_timeout(ssq, (SSQ_TIMEOUT_SELECTOR)(SSQ_TIMEOUT_RECV | SSQ_TIMEOUT_SEND), 1200);
|
|
|
|
|
|
|
|
|
|
uint8_t ssq_a2s_player_count = 0;
|
|
|
|
|
A2S_PLAYER *ssq_a2s_player = ssq_player(ssq, &ssq_a2s_player_count);
|
|
|
|
|
|
|
|
|
|
if (ssq_server_eok(ssq)) {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_players ssq server players ok\n");
|
|
|
|
|
for (int i = 0; i < ssq_a2s_player_count; i++) {
|
|
|
|
|
r->players_response->AddPlayerToList(ssq_a2s_player[i].name, ssq_a2s_player[i].score, ssq_a2s_player[i].duration);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_players ssq server players failed: %s\n", ssq_server_emsg(ssq));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ssq_a2s_player != NULL) ssq_player_free(ssq_a2s_player, ssq_a2s_player_count);
|
|
|
|
|
} else {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_players ssq server connection failed: %s\n", (ssq ? ssq_server_emsg(ssq) : "NULL instance"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ssq != NULL) ssq_server_free(ssq);
|
|
|
|
|
} else if (!settings->matchmaking_server_details_via_source_query) { // original behavior
|
|
|
|
|
uint32_t number_players = g->num_players();
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_players players: %u\n", number_players);
|
|
|
|
|
const auto &players = get_steam_client()->steam_gameserver->get_players();
|
|
|
|
|
auto &player = players->cbegin();
|
|
|
|
|
for (int i = 0; i < number_players && player != players->end(); ++i, ++player) {
|
|
|
|
|
float playtime = static_cast<float>(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - player->second.join_time).count());
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_players PLAYER [%u] '%s' %u %f\n", i, player->second.name.c_str(), player->second.score, playtime);
|
|
|
|
|
r->players_response->AddPlayerToList(player->second.name.c_str(), player->second.score, playtime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_players " "%" PRIu64 "\n", g->id());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Steam_Matchmaking_Servers::server_details_rules(Gameserver *g, Steam_Matchmaking_Servers_Direct_IP_Request *r)
|
|
|
|
|
{
|
|
|
|
|
if (settings->matchmaking_server_details_via_source_query && !(g->ip() < 0) && !(g->query_port() < 0)) {
|
|
|
|
|
unsigned char ip[4]{};
|
|
|
|
|
char newip[24];
|
|
|
|
|
ip[0] = g->ip() & 0xFF;
|
|
|
|
|
ip[1] = (g->ip() >> 8) & 0xFF;
|
|
|
|
|
ip[2] = (g->ip() >> 16) & 0xFF;
|
|
|
|
|
ip[3] = (g->ip() >> 24) & 0xFF;
|
|
|
|
|
snprintf(newip, sizeof(newip), "%d.%d.%d.%d", ip[3], ip[2], ip[1], ip[0]);
|
|
|
|
|
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_rules connecting to ssq server on %s:%u\n", newip, g->query_port());
|
|
|
|
|
SSQ_SERVER *ssq = ssq_server_new(newip, g->query_port());
|
|
|
|
|
if (ssq != NULL && ssq_server_eok(ssq)) {
|
|
|
|
|
ssq_server_timeout(ssq, (SSQ_TIMEOUT_SELECTOR)(SSQ_TIMEOUT_RECV | SSQ_TIMEOUT_SEND), 1200);
|
|
|
|
|
|
|
|
|
|
uint16_t ssq_a2s_rules_count = 0;
|
|
|
|
|
A2S_RULES *ssq_a2s_rules = ssq_rules(ssq, &ssq_a2s_rules_count);
|
|
|
|
|
|
|
|
|
|
if (ssq_server_eok(ssq)) {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_rules ssq server rules ok\n");
|
|
|
|
|
for (int i = 0; i < ssq_a2s_rules_count; i++) {
|
|
|
|
|
r->rules_response->RulesResponded(ssq_a2s_rules[i].name, ssq_a2s_rules[i].value);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_rules ssq server rules failed: %s\n", ssq_server_emsg(ssq));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ssq_a2s_rules != NULL) ssq_rules_free(ssq_a2s_rules, ssq_a2s_rules_count);
|
|
|
|
|
} else {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_rules ssq server connection failed: %s\n", (ssq ? ssq_server_emsg(ssq) : "NULL instance"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ssq != NULL) ssq_server_free(ssq);
|
|
|
|
|
} else if (!settings->matchmaking_server_details_via_source_query) { // original behavior
|
|
|
|
|
int number_rules = (int)g->values().size();
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_rules rules: %i\n", number_rules);
|
|
|
|
|
auto rule = g->values().begin();
|
|
|
|
|
for (int i = 0; i < number_rules; ++i) {
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_rules 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PRINT_DEBUG(" Steam_Matchmaking_Servers::server_details_rules " "%" PRIu64 "\n", g->id());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
@ -637,35 +802,19 @@ void Steam_Matchmaking_Servers::RunCallbacks()
|
|
|
|
|
|
|
|
|
|
if (query_port == r.port && g.server.ip() == r.ip) {
|
|
|
|
|
if (r.rules_response) {
|
|
|
|
|
int number_rules = (int)g.server.values().size();
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers rules: %i\n", number_rules);
|
|
|
|
|
auto rule = g.server.values().begin();
|
|
|
|
|
for (int i = 0; i < number_rules; ++i) {
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
server_details_rules(&(g.server), &r);
|
|
|
|
|
r.rules_response->RulesRefreshComplete();
|
|
|
|
|
r.rules_response = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r.players_response) {
|
|
|
|
|
uint32_t number_players = g.server.num_players();
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers players: %u\n", number_players);
|
|
|
|
|
const auto &players = get_steam_client()->steam_gameserver->get_players();
|
|
|
|
|
auto &player = players->cbegin();
|
|
|
|
|
for (int i = 0; i < number_players && player != players->end(); ++i, ++player) {
|
|
|
|
|
float playtime = static_cast<float>(std::chrono::duration_cast<std::chrono::seconds>(std::chrono::steady_clock::now() - player->second.join_time).count());
|
|
|
|
|
PRINT_DEBUG("Steam_Matchmaking_Servers PLAYER [%u] '%s' %u %f\n", i, player->second.name.c_str(), player->second.score, playtime);
|
|
|
|
|
r.players_response->AddPlayerToList(player->second.name.c_str(), player->second.score, playtime);
|
|
|
|
|
}
|
|
|
|
|
server_details_players(&(g.server), &r);
|
|
|
|
|
r.players_response->PlayersRefreshComplete();
|
|
|
|
|
r.players_response = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (r.ping_response) {
|
|
|
|
|
gameserveritem_t server;
|
|
|
|
|
gameserveritem_t server{};
|
|
|
|
|
server_details(&(g.server), &server);
|
|
|
|
|
r.ping_response->ServerResponded(server);
|
|
|
|
|
r.ping_response = NULL;
|
|
|
|
|