From 630ae6b20cf64ad1ae5a3a02fa884b5b2e6cdc3a Mon Sep 17 00:00:00 2001 From: universal963 <36097923+universal963@users.noreply.github.com> Date: Fri, 27 Jun 2025 22:28:28 +0800 Subject: [PATCH 1/3] Fix for missing callback and result --- dll/steam_networking_sockets.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dll/steam_networking_sockets.cpp b/dll/steam_networking_sockets.cpp index 35e494dc..c2bf3504 100644 --- a/dll/steam_networking_sockets.cpp +++ b/dll/steam_networking_sockets.cpp @@ -1243,6 +1243,10 @@ ESteamNetworkingAvailability Steam_Networking_Sockets::InitAuthentication() { PRINT_DEBUG_TODO(); std::lock_guard lock(global_mutex); + SteamNetAuthenticationStatus_t data{}; + data.m_eAvail = k_ESteamNetworkingAvailability_Current; + memcpy(data.m_debugMsg, "OK", 3); + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); return k_ESteamNetworkingAvailability_Current; } @@ -1257,6 +1261,12 @@ ESteamNetworkingAvailability Steam_Networking_Sockets::GetAuthenticationStatus( { PRINT_DEBUG_TODO(); std::lock_guard lock(global_mutex); + if (pDetails) + { + *pDetails = {}; + pDetails->m_eAvail = k_ESteamNetworkingAvailability_Current; + memcpy(pDetails->m_debugMsg, "OK", 3); + } return k_ESteamNetworkingAvailability_Current; } From b4b05c3ce8ee83f3676262254acba86dd59db18c Mon Sep 17 00:00:00 2001 From: universal963 <36097923+universal963@users.noreply.github.com> Date: Sat, 5 Jul 2025 02:53:45 +0800 Subject: [PATCH 2/3] Implement `Steam_User_Stats::GetUserStat()` (#261) * Initial implementation of `Steam_User_Stats::GetUserStat()` --- dll/dll/network.h | 1 + dll/dll/settings.h | 2 +- dll/dll/steam_gameserverstats.h | 2 +- dll/dll/steam_user_stats.h | 16 ++- dll/net.proto | 52 ++++--- dll/network.cpp | 5 + dll/settings_parser.cpp | 6 +- dll/steam_gameserverstats.cpp | 12 +- dll/steam_user_stats.cpp | 28 +++- dll/steam_user_stats_stats.cpp | 235 ++++++++++++++++++++++++++------ 10 files changed, 281 insertions(+), 78 deletions(-) diff --git a/dll/dll/network.h b/dll/dll/network.h index 9f255a23..a6c366b2 100644 --- a/dll/dll/network.h +++ b/dll/dll/network.h @@ -66,6 +66,7 @@ enum Callback_Ids { CALLBACK_ID_NETWORKING_MESSAGES, CALLBACK_ID_GAMESERVER_STATS, CALLBACK_ID_LEADERBOARDS_STATS, + CALLBACK_ID_USER_STATS, CALLBACK_IDS_MAX }; diff --git a/dll/dll/settings.h b/dll/dll/settings.h index 81b03a4b..98e8a099 100644 --- a/dll/dll/settings.h +++ b/dll/dll/settings.h @@ -88,7 +88,7 @@ struct Leaderboard_config { }; struct Stat_config { - GameServerStats_Messages::StatInfo::Stat_Type type{}; + StatInfo::Stat_Type type{}; union { float default_value_float; int32 default_value_int; diff --git a/dll/dll/steam_gameserverstats.h b/dll/dll/steam_gameserverstats.h index c889981d..31cb431b 100644 --- a/dll/dll/steam_gameserverstats.h +++ b/dll/dll/steam_gameserverstats.h @@ -42,7 +42,7 @@ public ISteamGameServerStats struct CachedStat { bool dirty = false; // true means it was changed on the server and should be sent to the user - GameServerStats_Messages::StatInfo stat{}; + StatInfo stat{}; }; struct CachedAchievement { bool dirty = false; // true means it was changed on the server and should be sent to the user diff --git a/dll/dll/steam_user_stats.h b/dll/dll/steam_user_stats.h index 4f8556e2..55eac320 100644 --- a/dll/dll/steam_user_stats.h +++ b/dll/dll/steam_user_stats.h @@ -57,6 +57,12 @@ struct achievement_trigger { bool should_indicate_progress(int32 stat) const; }; +struct Pending_User_Stats_Request { + SteamAPICall_t api_id{}; + std::chrono::high_resolution_clock::time_point created_time{}; + bool is_sent{}; +}; + class Steam_User_Stats : public ISteamUserStats001, public ISteamUserStats002, @@ -110,6 +116,9 @@ private: GameServerStats_Messages::AllStats pending_server_updates{}; + std::map pending_user_stats_requests; + std::map received_user_stats_data; + void load_achievements_db(); void load_achievements(); void save_achievements(); @@ -133,13 +142,16 @@ private: // change stats/achievements without sending back to server bool clear_stats_internal(); InternalSetResult set_stat_internal( const char *pchName, int32 nData ); - InternalSetResult> set_stat_internal( const char *pchName, float fData ); - InternalSetResult> update_avg_rate_stat_internal( const char *pchName, float flCountThisSession, double dSessionLength ); + InternalSetResult> set_stat_internal( const char *pchName, float fData ); + InternalSetResult> update_avg_rate_stat_internal( const char *pchName, float flCountThisSession, double dSessionLength ); InternalSetResult set_achievement_internal( const char *pchName ); InternalSetResult clear_achievement_internal( const char *pchName ); + SteamAPICall_t trigger_user_stats_received(CSteamID steam_id_user, SteamAPICall_t api_id = k_uAPICallInvalid, bool success = true); void send_updated_stats(); void load_achievements_icons(); + void send_pending_user_stats_requests(); + void process_pending_user_stats_requests(Common_Message *msg); void steam_run_callback(); // requests from server diff --git a/dll/net.proto b/dll/net.proto index 5dc6178e..052531eb 100644 --- a/dll/net.proto +++ b/dll/net.proto @@ -216,26 +216,27 @@ message Steam_Messages { } } +message StatInfo { + enum Stat_Type { + STAT_TYPE_INT = 0; + STAT_TYPE_FLOAT = 1; + STAT_TYPE_AVGRATE = 2; + } + message AvgStatInfo { + float count_this_session = 1; + double session_length = 2; + } + + Stat_Type stat_type = 1; + oneof stat_value { + float value_float = 2; + int32 value_int = 3; + } + optional AvgStatInfo value_avg = 4; // only set when type != INT +} + message GameServerStats_Messages { // --- basic definitions - message StatInfo { - enum Stat_Type { - STAT_TYPE_INT = 0; - STAT_TYPE_FLOAT = 1; - STAT_TYPE_AVGRATE = 2; - } - message AvgStatInfo { - float count_this_session = 1; - double session_length = 2; - } - - Stat_Type stat_type = 1; - oneof stat_value { - float value_float = 2; - int32 value_int = 3; - } - optional AvgStatInfo value_avg = 4; // only set when type != INT - } message AchievementInfo { bool achieved = 1; } @@ -295,6 +296,20 @@ message Leaderboards_Messages { } } +message Steam_User_Stats_Data { + map user_stats = 1; +} + +message Steam_User_Stats_Messages { + enum Types { + REQUEST_USERSTATS = 0; + RESPONSE_USERSTATS = 1; + } + + Types type = 1; + optional Steam_User_Stats_Data steam_user_stats_data = 2; +} + message Common_Message { uint64 source_id = 1; // SteamID64 of the sender uint64 dest_id = 2; // SteamID64 of the target receiver @@ -314,6 +329,7 @@ message Common_Message { Networking_Messages networking_messages = 15; GameServerStats_Messages gameserver_stats_messages = 16; Leaderboards_Messages leaderboards_messages = 17; + Steam_User_Stats_Messages steam_user_stats_messages = 18; } uint32 source_ip = 128; diff --git a/dll/network.cpp b/dll/network.cpp index 60b6b4cd..9b595c47 100644 --- a/dll/network.cpp +++ b/dll/network.cpp @@ -608,6 +608,11 @@ void Networking::do_callbacks_message(Common_Message *msg) PRINT_DEBUG("has_leaderboards_messages"); run_callbacks(CALLBACK_ID_LEADERBOARDS_STATS, msg); } + + if (msg->has_steam_user_stats_messages()) { + PRINT_DEBUG("has_steam_user_stats_messages"); + run_callbacks(CALLBACK_ID_USER_STATS, msg); + } } diff --git a/dll/settings_parser.cpp b/dll/settings_parser.cpp index 4db623ce..1e53fe00 100644 --- a/dll/settings_parser.cpp +++ b/dll/settings_parser.cpp @@ -859,15 +859,15 @@ static void parse_stats(class Settings *settings_client, class Settings *setting try { if (stat_type == "float") { - config.type = GameServerStats_Messages::StatInfo::STAT_TYPE_FLOAT; + config.type = StatInfo::STAT_TYPE_FLOAT; config.default_value_float = std::stof(stat_default_value); config.global_value_double = std::stod(stat_global_value); } else if (stat_type == "int") { - config.type = GameServerStats_Messages::StatInfo::STAT_TYPE_INT; + config.type = StatInfo::STAT_TYPE_INT; config.default_value_int = std::stol(stat_default_value); config.global_value_int64 = std::stoll(stat_global_value); } else if (stat_type == "avgrate") { - config.type = GameServerStats_Messages::StatInfo::STAT_TYPE_AVGRATE; + config.type = StatInfo::STAT_TYPE_AVGRATE; config.default_value_float = std::stof(stat_default_value); config.global_value_double = std::stod(stat_global_value); } else { diff --git a/dll/steam_gameserverstats.cpp b/dll/steam_gameserverstats.cpp index 580b0d6a..b96a8baf 100644 --- a/dll/steam_gameserverstats.cpp +++ b/dll/steam_gameserverstats.cpp @@ -164,7 +164,7 @@ bool Steam_GameServerStats::GetUserStat( CSteamID steamIDUser, const char *pchNa auto stat = find_stat(steamIDUser, pchName); if (!stat) return false; - if (stat->stat.stat_type() != GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return false; + if (stat->stat.stat_type() != StatInfo::STAT_TYPE_INT) return false; if (pData) *pData = stat->stat.value_int(); return true; @@ -180,7 +180,7 @@ bool Steam_GameServerStats::GetUserStat( CSteamID steamIDUser, const char *pchNa auto stat = find_stat(steamIDUser, pchName); if (!stat) return false; - if (stat->stat.stat_type() == GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return false; + if (stat->stat.stat_type() == StatInfo::STAT_TYPE_INT) return false; if (pData) *pData = stat->stat.value_float(); return true; @@ -216,7 +216,7 @@ bool Steam_GameServerStats::SetUserStat( CSteamID steamIDUser, const char *pchNa auto stat = find_stat(steamIDUser, pchName); if (!stat) return false; - if (stat->stat.stat_type() != GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return false; + if (stat->stat.stat_type() != StatInfo::STAT_TYPE_INT) return false; if (stat->stat.value_int() == nData) return true; // don't waste time stat->dirty = true; @@ -237,7 +237,7 @@ bool Steam_GameServerStats::SetUserStat( CSteamID steamIDUser, const char *pchNa auto stat = find_stat(steamIDUser, pchName); if (!stat) return false; - if (stat->stat.stat_type() == GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return false; + if (stat->stat.stat_type() == StatInfo::STAT_TYPE_INT) return false; if (stat->stat.value_float() == fData) return true; // don't waste time stat->dirty = true; @@ -258,7 +258,7 @@ bool Steam_GameServerStats::UpdateUserAvgRateStat( CSteamID steamIDUser, const c auto stat = find_stat(steamIDUser, pchName); if (!stat) return false; - if (stat->stat.stat_type() == GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return false; + if (stat->stat.stat_type() == StatInfo::STAT_TYPE_INT) return false; // don't waste time if (stat->stat.has_value_avg() && stat->stat.value_avg().count_this_session() == flCountThisSession && @@ -270,7 +270,7 @@ bool Steam_GameServerStats::UpdateUserAvgRateStat( CSteamID steamIDUser, const c // https://protobuf.dev/reference/cpp/cpp-generated/#string // set_allocated_xxx() takes ownership of the allocated object, no need to delete - auto avg_info = new GameServerStats_Messages::StatInfo::AvgStatInfo(); + auto avg_info = new StatInfo::AvgStatInfo(); avg_info->set_count_this_session(flCountThisSession); avg_info->set_session_length(dSessionLength); stat->stat.set_allocated_value_avg(avg_info); diff --git a/dll/steam_user_stats.cpp b/dll/steam_user_stats.cpp index ada7f481..237dbb5f 100644 --- a/dll/steam_user_stats.cpp +++ b/dll/steam_user_stats.cpp @@ -113,6 +113,7 @@ Steam_User_Stats::Steam_User_Stats(Settings *settings, class Networking *network if (settings->share_leaderboards_over_network) { this->network->setCallback(CALLBACK_ID_LEADERBOARDS_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_leaderboards, this); } + this->network->setCallback(CALLBACK_ID_USER_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_stats, this); this->network->setCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_low_level, this); this->run_every_runcb->add(&Steam_User_Stats::steam_user_stats_run_every_runcb, this); } @@ -125,6 +126,7 @@ Steam_User_Stats::~Steam_User_Stats() if (settings->share_leaderboards_over_network) { this->network->rmCallback(CALLBACK_ID_LEADERBOARDS_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_leaderboards, this); } + this->network->rmCallback(CALLBACK_ID_USER_STATS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_stats, this); this->network->rmCallback(CALLBACK_ID_USER_STATUS, settings->get_local_steam_id(), &Steam_User_Stats::steam_user_stats_network_low_level, this); this->run_every_runcb->remove(&Steam_User_Stats::steam_user_stats_run_every_runcb, this); } @@ -195,9 +197,9 @@ ESteamUserStatType Steam_User_Stats::GetStatType( CGameID nGameID, const char *p switch (stat_info->second.type) { - case GameServerStats_Messages::StatInfo::STAT_TYPE_INT: return ESteamUserStatType::k_ESteamUserStatTypeINT; - case GameServerStats_Messages::StatInfo::STAT_TYPE_FLOAT: return ESteamUserStatType::k_ESteamUserStatTypeFLOAT; - case GameServerStats_Messages::StatInfo::STAT_TYPE_AVGRATE: return ESteamUserStatType::k_ESteamUserStatTypeAVGRATE; + case StatInfo::STAT_TYPE_INT: return ESteamUserStatType::k_ESteamUserStatTypeINT; + case StatInfo::STAT_TYPE_FLOAT: return ESteamUserStatType::k_ESteamUserStatTypeFLOAT; + case StatInfo::STAT_TYPE_AVGRATE: return ESteamUserStatType::k_ESteamUserStatTypeAVGRATE; default: PRINT_DEBUG("[X] unhandled type %i", (int)stat_info->second.type); break; } @@ -440,6 +442,7 @@ void Steam_User_Stats::steam_run_callback() { send_updated_stats(); load_achievements_icons(); + send_pending_user_stats_requests(); } @@ -465,6 +468,25 @@ void Steam_User_Stats::network_callback_low_level(Common_Message *msg) board.remove_entries(steamid); } + // TODO: need tests on real steam + bool had_data = false; + + auto it_res_r = received_user_stats_data.find(steamid.ConvertToUint64()); + if (it_res_r != received_user_stats_data.end()) { + had_data = true; + it_res_r = received_user_stats_data.erase(it_res_r); + } + auto it_res_p = pending_user_stats_requests.find(steamid.ConvertToUint64()); + if (it_res_p != pending_user_stats_requests.end()) { + trigger_user_stats_received(steamid, it_res_p->second.api_id); + it_res_p = pending_user_stats_requests.erase(it_res_p); + } + else if (had_data) { + UserStatsUnloaded_t data{}; + data.m_steamIDUser = steamid; + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), 0.0); + } + // PRINT_DEBUG("removed user %llu", (uint64)steamid.ConvertToUint64()); } break; diff --git a/dll/steam_user_stats_stats.cpp b/dll/steam_user_stats_stats.cpp index aaea1486..fc1ba63e 100644 --- a/dll/steam_user_stats_stats.cpp +++ b/dll/steam_user_stats_stats.cpp @@ -32,7 +32,7 @@ bool Steam_User_Stats::clear_stats_internal() switch (stat.second.type) { - case GameServerStats_Messages::StatInfo::STAT_TYPE_INT: { + case StatInfo::STAT_TYPE_INT: { auto data = stat.second.default_value_int; bool needs_disk_write = false; @@ -48,8 +48,8 @@ bool Steam_User_Stats::clear_stats_internal() } break; - case GameServerStats_Messages::StatInfo::STAT_TYPE_FLOAT: - case GameServerStats_Messages::StatInfo::STAT_TYPE_AVGRATE: { + case StatInfo::STAT_TYPE_FLOAT: + case StatInfo::STAT_TYPE_AVGRATE: { auto data = stat.second.default_value_float; bool needs_disk_write = false; @@ -85,13 +85,13 @@ Steam_User_Stats::InternalSetResult Steam_User_Stats::set_stat_internal( auto stats_data = stats_config.find(stat_name); if (stats_config.end() == stats_data && settings->allow_unknown_stats) { Stat_config cfg{}; - cfg.type = GameServerStats_Messages::StatInfo::STAT_TYPE_INT; + cfg.type = StatInfo::STAT_TYPE_INT; cfg.default_value_int = 0; stats_data = settings->setStatDefiniton(stat_name, cfg); } if (stats_config.end() == stats_data) return result; - if (stats_data->second.type != GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return result; + if (stats_data->second.type != StatInfo::STAT_TYPE_INT) return result; result.internal_name = stat_name; result.current_val = nData; @@ -145,11 +145,11 @@ Steam_User_Stats::InternalSetResult Steam_User_Stats::set_stat_internal( return result; } -Steam_User_Stats::InternalSetResult> Steam_User_Stats::set_stat_internal( const char *pchName, float fData ) +Steam_User_Stats::InternalSetResult> Steam_User_Stats::set_stat_internal( const char *pchName, float fData ) { PRINT_DEBUG(" '%s' = %f", pchName, fData); std::lock_guard lock(global_mutex); - Steam_User_Stats::InternalSetResult> result{}; + Steam_User_Stats::InternalSetResult> result{}; if (!pchName) return result; std::string stat_name(common_helpers::to_lower(pchName)); @@ -158,13 +158,13 @@ Steam_User_Stats::InternalSetResultallow_unknown_stats) { Stat_config cfg{}; - cfg.type = GameServerStats_Messages::StatInfo::STAT_TYPE_FLOAT; + cfg.type = StatInfo::STAT_TYPE_FLOAT; cfg.default_value_float = 0; stats_data = settings->setStatDefiniton(stat_name, cfg); } if (stats_config.end() == stats_data) return result; - if (stats_data->second.type == GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return result; + if (stats_data->second.type == StatInfo::STAT_TYPE_INT) return result; result.internal_name = stat_name; result.current_val.first = stats_data->second.type; @@ -219,11 +219,11 @@ Steam_User_Stats::InternalSetResult> Steam_User_Stats::update_avg_rate_stat_internal( const char *pchName, float flCountThisSession, double dSessionLength ) +Steam_User_Stats::InternalSetResult> Steam_User_Stats::update_avg_rate_stat_internal( const char *pchName, float flCountThisSession, double dSessionLength ) { PRINT_DEBUG("%s", pchName); std::lock_guard lock(global_mutex); - Steam_User_Stats::InternalSetResult> result{}; + Steam_User_Stats::InternalSetResult> result{}; if (!pchName) return result; std::string stat_name(common_helpers::to_lower(pchName)); @@ -232,13 +232,13 @@ Steam_User_Stats::InternalSetResultallow_unknown_stats) { Stat_config cfg{}; - cfg.type = GameServerStats_Messages::StatInfo::STAT_TYPE_AVGRATE; + cfg.type = StatInfo::STAT_TYPE_AVGRATE; cfg.default_value_float = 0; stats_data = settings->setStatDefiniton(stat_name, cfg); } if (stats_config.end() == stats_data) return result; - if (stats_data->second.type == GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return result; + if (stats_data->second.type == StatInfo::STAT_TYPE_INT) return result; result.internal_name = stat_name; @@ -281,6 +281,26 @@ void Steam_User_Stats::steam_user_stats_network_stats(void *object, Common_Messa inst->network_callback_stats(msg); } +SteamAPICall_t Steam_User_Stats::trigger_user_stats_received(CSteamID steam_id_user, SteamAPICall_t api_id, bool success) +{ + UserStatsReceived_t data{}; + data.m_nGameID = settings->get_local_game_id().ToUint64(); + data.m_eResult = success ? k_EResultOK : k_EResultFail; // TODO: based on doc, real steam tests needed + data.m_steamIDUser = steam_id_user; + + // appid 756800 expects both: a callback (global event occurring in the Steam environment), + // and a callresult (the specific result of this function call) + // otherwise it will lock-up and hang at startup + SteamAPICall_t ret{}; + if (api_id == k_uAPICallInvalid) { + ret = callback_results->addCallResult(data.k_iCallback, &data, sizeof(data), 0.1); + } + else { + ret = callback_results->addCallResult(api_id, data.k_iCallback, &data, sizeof(data), 0.1); + } + callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), 0.1); + return ret; +} // Ask the server to send down this user's data and achievements for this game STEAM_CALL_BACK( UserStatsReceived_t ) @@ -311,13 +331,13 @@ bool Steam_User_Stats::GetStat( const char *pchName, int32 *pData ) auto stats_data = stats_config.find(stat_name); if (stats_config.end() == stats_data && settings->allow_unknown_stats) { Stat_config cfg{}; - cfg.type = GameServerStats_Messages::StatInfo::STAT_TYPE_INT; + cfg.type = StatInfo::STAT_TYPE_INT; cfg.default_value_int = 0; stats_data = settings->setStatDefiniton(stat_name, cfg); } if (stats_config.end() == stats_data) return false; - if (stats_data->second.type != GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return false; + if (stats_data->second.type != StatInfo::STAT_TYPE_INT) return false; auto cached_stat = stats_cache_int.find(stat_name); if (cached_stat != stats_cache_int.end()) { @@ -350,13 +370,13 @@ bool Steam_User_Stats::GetStat( const char *pchName, float *pData ) auto stats_data = stats_config.find(stat_name); if (stats_config.end() == stats_data && settings->allow_unknown_stats) { Stat_config cfg{}; - cfg.type = GameServerStats_Messages::StatInfo::STAT_TYPE_FLOAT; + cfg.type = StatInfo::STAT_TYPE_FLOAT; cfg.default_value_float = 0; stats_data = settings->setStatDefiniton(stat_name, cfg); } if (stats_config.end() == stats_data) return false; - if (stats_data->second.type == GameServerStats_Messages::StatInfo::STAT_TYPE_INT) return false; + if (stats_data->second.type == StatInfo::STAT_TYPE_INT) return false; auto cached_stat = stats_cache_float.find(stat_name); if (cached_stat != stats_cache_float.end()) { @@ -387,7 +407,7 @@ bool Steam_User_Stats::SetStat( const char *pchName, int32 nData ) auto ret = set_stat_internal(pchName, nData ); if (ret.success && ret.notify_server ) { auto &new_stat = (*pending_server_updates.mutable_user_stats())[ret.internal_name]; - new_stat.set_stat_type(GameServerStats_Messages::StatInfo::STAT_TYPE_INT); + new_stat.set_stat_type(StatInfo::STAT_TYPE_INT); new_stat.set_value_int(ret.current_val); if (settings->immediate_gameserver_stats) send_updated_stats(); @@ -475,16 +495,17 @@ SteamAPICall_t Steam_User_Stats::RequestUserStats( CSteamID steamIDUser ) // load_achievements(); //} - UserStatsReceived_t data{}; - data.m_nGameID = settings->get_local_game_id().ToUint64(); - data.m_eResult = k_EResultOK; - data.m_steamIDUser = steamIDUser; - // appid 756800 expects both: a callback (global event occurring in the Steam environment), - // and a callresult (the specific result of this function call) - // otherwise it will lock-up and hang at startup - auto ret = callback_results->addCallResult(data.k_iCallback, &data, sizeof(data), 0.1); - callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), 0.1); - return ret; + if (steamIDUser == settings->get_local_steam_id()) { + return trigger_user_stats_received(steamIDUser); + } + + Pending_User_Stats_Request pusr{}; + pusr.api_id = callback_results->reserveCallResult(); + pusr.created_time = std::chrono::high_resolution_clock::now(); + pusr.is_sent = false; + pending_user_stats_requests[steamIDUser.ConvertToUint64()] = pusr; + + return pusr.api_id; } @@ -497,9 +518,28 @@ bool Steam_User_Stats::GetUserStat( CSteamID steamIDUser, const char *pchName, i if (!pchName) return false; if (steamIDUser == settings->get_local_steam_id()) { - GetStat(pchName, pData); - } else { + return GetStat(pchName, pData); + } + + if (pData) *pData = 0; + + std::string stat_name = common_helpers::to_lower(pchName); + const auto &stats_config = settings->getStats(); + auto stats_data = stats_config.find(stat_name); + if (stats_data != stats_config.end()) { + if (stats_data->second.type != StatInfo::STAT_TYPE_INT) + return false; + } + + auto it_rusd = received_user_stats_data.find(steamIDUser.ConvertToUint64()); + if (it_rusd != received_user_stats_data.end()) { + auto stats_map = it_rusd->second.user_stats(); + auto it_user_data = stats_map.find(stat_name); + if (it_user_data != stats_map.end()) { + if (pData) + *pData = it_user_data->second.value_int(); + } } return true; @@ -513,9 +553,28 @@ bool Steam_User_Stats::GetUserStat( CSteamID steamIDUser, const char *pchName, f if (!pchName) return false; if (steamIDUser == settings->get_local_steam_id()) { - GetStat(pchName, pData); - } else { - *pData = 0; + return GetStat(pchName, pData); + } + + if (pData) + *pData = 0.0f; + + std::string stat_name = common_helpers::to_lower(pchName); + const auto &stats_config = settings->getStats(); + auto stats_data = stats_config.find(stat_name); + if (stats_data != stats_config.end()) { + if (stats_data->second.type == StatInfo::STAT_TYPE_INT) + return false; + } + + auto it_rusd = received_user_stats_data.find(steamIDUser.ConvertToUint64()); + if (it_rusd != received_user_stats_data.end()) { + auto stats_map = it_rusd->second.user_stats(); + auto it_user_data = stats_map.find(stat_name); + if (it_user_data != stats_map.end()) { + if (pData) + *pData = it_user_data->second.value_float(); + } } return true; @@ -538,12 +597,12 @@ bool Steam_User_Stats::ResetAllStats( bool bAchievementsToo ) switch (stat.second.type) { - case GameServerStats_Messages::StatInfo::STAT_TYPE_INT: + case StatInfo::STAT_TYPE_INT: new_stat.set_value_int(stat.second.default_value_int); break; - case GameServerStats_Messages::StatInfo::STAT_TYPE_AVGRATE: - case GameServerStats_Messages::StatInfo::STAT_TYPE_FLOAT: + case StatInfo::STAT_TYPE_AVGRATE: + case StatInfo::STAT_TYPE_FLOAT: new_stat.set_value_float(stat.second.default_value_float); break; @@ -630,7 +689,7 @@ bool Steam_User_Stats::GetGlobalStat( const char *pchStatName, int64 *pData ) const auto &stats_config = settings->getStats(); auto stats_data = stats_config.find(stat_name); if (stats_data != stats_config.end()) { - if (stats_data->second.type != GameServerStats_Messages::StatInfo::STAT_TYPE_INT) + if (stats_data->second.type != StatInfo::STAT_TYPE_INT) return false; if (pData) @@ -649,7 +708,7 @@ bool Steam_User_Stats::GetGlobalStat( const char *pchStatName, double *pData ) const auto &stats_config = settings->getStats(); auto stats_data = stats_config.find(stat_name); if (stats_data != stats_config.end()) { - if (stats_data->second.type == GameServerStats_Messages::StatInfo::STAT_TYPE_INT) + if (stats_data->second.type == StatInfo::STAT_TYPE_INT) return false; if (pData) @@ -733,15 +792,15 @@ void Steam_User_Stats::network_stats_initial(Common_Message *msg) this_stat.set_stat_type(stat.second.type); switch (stat.second.type) { - case GameServerStats_Messages::StatInfo::STAT_TYPE_INT: { + case StatInfo::STAT_TYPE_INT: { int32 val = 0; GetStat(stat.first.c_str(), &val); this_stat.set_value_int(val); } break; - case GameServerStats_Messages::StatInfo::STAT_TYPE_AVGRATE: // we set the float value also for avg - case GameServerStats_Messages::StatInfo::STAT_TYPE_FLOAT: { + case StatInfo::STAT_TYPE_AVGRATE: // we set the float value also for avg + case StatInfo::STAT_TYPE_FLOAT: { float val = 0; GetStat(stat.first.c_str(), &val); this_stat.set_value_float(val); @@ -804,13 +863,13 @@ void Steam_User_Stats::network_stats_updated(Common_Message *msg) for (auto &new_stat : new_user_data.user_stats()) { switch (new_stat.second.stat_type()) { - case GameServerStats_Messages::StatInfo::STAT_TYPE_INT: { + case StatInfo::STAT_TYPE_INT: { set_stat_internal(new_stat.first.c_str(), new_stat.second.value_int()); } break; - case GameServerStats_Messages::StatInfo::STAT_TYPE_AVGRATE: - case GameServerStats_Messages::StatInfo::STAT_TYPE_FLOAT: { + case StatInfo::STAT_TYPE_AVGRATE: + case StatInfo::STAT_TYPE_FLOAT: { set_stat_internal(new_stat.first.c_str(), new_stat.second.value_float()); // non-INT values could have avg values if (new_stat.second.has_value_avg()) { @@ -840,6 +899,91 @@ void Steam_User_Stats::network_stats_updated(Common_Message *msg) ); } +void Steam_User_Stats::send_pending_user_stats_requests() +{ + if (!pending_user_stats_requests.empty()) { + for (auto it_pusr = pending_user_stats_requests.begin(); it_pusr != pending_user_stats_requests.end();) { + if (check_timedout(it_pusr->second.created_time, 3.0)) { + PRINT_DEBUG("send_pending_user_stats_requests time out"); + trigger_user_stats_received(CSteamID(it_pusr->first), it_pusr->second.api_id); + it_pusr = pending_user_stats_requests.erase(it_pusr); + continue; + } + if (!it_pusr->second.is_sent) { + PRINT_DEBUG("send_pending_user_stats_requests send"); + Common_Message msg; + msg.set_source_id(static_cast(settings->get_local_steam_id().ConvertToUint64())); + msg.set_dest_id(static_cast(it_pusr->first)); + Steam_User_Stats_Messages *sus_msg = new Steam_User_Stats_Messages(); + sus_msg->set_type(Steam_User_Stats_Messages::REQUEST_USERSTATS); + msg.set_allocated_steam_user_stats_messages(sus_msg); + network->sendTo(&msg, true); + + it_pusr->second.is_sent = true; + } + ++it_pusr; + } + } +} + +void Steam_User_Stats::process_pending_user_stats_requests(Common_Message *msg) +{ + switch (msg->steam_user_stats_messages().type()) + { + case Steam_User_Stats_Messages::REQUEST_USERSTATS: { + PRINT_DEBUG("steam_user_stats_messages REQUEST_USERSTATS"); + Steam_User_Stats_Data *susd_alloc = new Steam_User_Stats_Data(); + + const auto &stats_config = settings->getStats(); + for (const auto &sc : stats_config) { + std::string stats_name = sc.first; + StatInfo::Stat_Type stats_type = sc.second.type; + if (stats_type == StatInfo::STAT_TYPE_INT) { + int32 stats_value = 0; + GetStat(stats_name.c_str(), &stats_value); + (*susd_alloc->mutable_user_stats())[stats_name].set_value_int(stats_value); + } + else { + float stats_value = 0.0f; + GetStat(stats_name.c_str(), &stats_value); + (*susd_alloc->mutable_user_stats())[stats_name].set_value_float(stats_value); + } + } + + Common_Message msg_; + msg_.set_source_id(static_cast(settings->get_local_steam_id().ConvertToUint64())); + msg_.set_dest_id(msg->source_id()); + Steam_User_Stats_Messages *response_message = new Steam_User_Stats_Messages(); + response_message->set_type(Steam_User_Stats_Messages::RESPONSE_USERSTATS); + response_message->set_allocated_steam_user_stats_data(susd_alloc); + msg_.set_allocated_steam_user_stats_messages(response_message); + network->sendTo(&msg_, true); + + break; + } + case Steam_User_Stats_Messages::RESPONSE_USERSTATS: { + PRINT_DEBUG("steam_user_stats_messages RESPONSE_USERSTATS"); + if (msg->steam_user_stats_messages().has_steam_user_stats_data()) { + PRINT_DEBUG("received user stats messages"); + const Steam_User_Stats_Data &received_user_stats = msg->steam_user_stats_messages().steam_user_stats_data(); + uint64 received_steam_stats_id = static_cast(msg->source_id()); + auto it_pusr = pending_user_stats_requests.find(received_steam_stats_id); + if (it_pusr == pending_user_stats_requests.end()) { + PRINT_DEBUG("received but timed out, ignoring"); + } + else { + PRINT_DEBUG("received, refreshing or adding to cache"); + received_user_stats_data[received_steam_stats_id] = received_user_stats; + trigger_user_stats_received(CSteamID(received_steam_stats_id), it_pusr->second.api_id); + it_pusr = pending_user_stats_requests.erase(it_pusr); + } + } + + break; + } + } +} + void Steam_User_Stats::network_callback_stats(Common_Message *msg) { // network->sendToAll() sends to current user also @@ -868,4 +1012,7 @@ void Steam_User_Stats::network_callback_stats(Common_Message *msg) PRINT_DEBUG("unhandled type %i", (int)msg->gameserver_stats_messages().type()); break; } + + if (msg->has_steam_user_stats_messages()) + process_pending_user_stats_requests(msg); } From e916bba19006ef690d781e9ce06a657bd5059f94 Mon Sep 17 00:00:00 2001 From: NicknineTheEagle Date: Tue, 8 Jul 2025 19:39:14 +0300 Subject: [PATCH 3/3] Fixed old SteamGameServer interfaces --- dll/auth.cpp | 59 +++++++++++++++ dll/dll/auth.h | 2 + dll/steam_gameserver.cpp | 127 ++++++++++++++++++++------------ sdk/steam/isteamgameserver002.h | 16 ++++ 4 files changed, 157 insertions(+), 47 deletions(-) diff --git a/dll/auth.cpp b/dll/auth.cpp index b36d192d..9737950f 100644 --- a/dll/auth.cpp +++ b/dll/auth.cpp @@ -631,6 +631,35 @@ void Auth_Manager::launch_callback(CSteamID id, EAuthSessionResponse resp, doubl callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), delay); } +void Auth_Manager::launch_callback_gs_steam2(CSteamID steam_id, uint32_t user_id, bool approved) +{ + if (approved) { + // Fire Steam2 callback. + GSClientSteam2Accept_t data2{}; + data2.m_UserID = user_id; + data2.m_SteamID = steam_id.ConvertToUint64(); + callbacks->addCBResult(data2.k_iCallback, &data2, sizeof(data2)); + + // Fire Steam3 callback. + GSClientApprove_t data3{}; + data3.m_SteamID = data3.m_OwnerSteamID = steam_id; + callbacks->addCBResult(data3.k_iCallback, &data3, sizeof(data3)); + } else { + // Fire Steam2 callback. This will kick the client so no need to send Steam3 callback. + GSClientSteam2Deny_t data2{}; + data2.m_UserID = user_id; + data2.m_eSteamError = k_EDenyNotLoggedOn; + callbacks->addCBResult(data2.k_iCallback, &data2, sizeof(data2)); + + /* + GSClientDeny_t data3{}; + data3.m_SteamID = steam_id; + data3.m_eDenyReason = k_EDenyNotLoggedOn; //TODO: other reasons? + callbacks->addCBResult(data3.k_iCallback, &data3, sizeof(data3)); + */ + } +} + void Auth_Manager::launch_callback_gs(CSteamID id, bool approved) { if (approved) { @@ -796,6 +825,36 @@ void Auth_Manager::cancelTicket(uint32 number) outbound.erase(ticket); } +bool Auth_Manager::SendSteam2UserConnect( uint32 unUserID, const void *pvRawKey, uint32 unKeyLen, uint32 unIPPublic, uint16 usPort, const void *pvCookie, uint32 cubCookie, CSteamID *pSteamIDUser ) +{ + // pvRawKey is Steam2 auth ticket, it comes from Steam.dll. + // pvCookie is Steam3 auth ticket, it comes from us. + // Steam3 ticket is technically optional but it should always be there if the client is using Goldberg + // so there's no real need to check Steam2 ticket. + if (cubCookie < STEAM_TICKET_MIN_SIZE) return false; + + Auth_Data data; + uint64 id; + memcpy(&id, (char *)pvCookie + STEAM_ID_OFFSET_TICKET, sizeof(id)); + uint32 number; + memcpy(&number, ((char *)pvCookie) + sizeof(uint64), sizeof(number)); + data.id = CSteamID(id); + data.number = number; + if (pSteamIDUser) *pSteamIDUser = data.id; + + for (auto & t : inbound) { + if (t.id == data.id) { + //Should this return false? + launch_callback_gs_steam2(id, unUserID, true); + return true; + } + } + + inbound.push_back(data); + launch_callback_gs_steam2(id, unUserID, true); + return true; +} + bool Auth_Manager::SendUserConnectAndAuthenticate( uint32 unIPClient, const void *pvAuthBlob, uint32 cubAuthBlobSize, CSteamID *pSteamIDUser ) { if (cubAuthBlobSize < STEAM_TICKET_MIN_SIZE) return false; diff --git a/dll/dll/auth.h b/dll/dll/auth.h index dfa2a236..79e80b6a 100644 --- a/dll/dll/auth.h +++ b/dll/dll/auth.h @@ -76,6 +76,7 @@ class Auth_Manager { std::vector outbound{}; void launch_callback(CSteamID id, EAuthSessionResponse resp, double delay=0); + void launch_callback_gs_steam2(CSteamID steam_id, uint32_t user_id, bool approved); void launch_callback_gs(CSteamID id, bool approved); static void ticket_callback(void *object, Common_Message *msg); @@ -94,6 +95,7 @@ public: uint32 countInboundAuth(); + bool SendSteam2UserConnect( uint32 unUserID, const void *pvRawKey, uint32 unKeyLen, uint32 unIPPublic, uint16 usPort, const void *pvCookie, uint32 cubCookie, CSteamID *pSteamIDUser ); bool SendUserConnectAndAuthenticate( uint32 unIPClient, const void *pvAuthBlob, uint32 cubAuthBlobSize, CSteamID *pSteamIDUser ); CSteamID fakeUser(); diff --git a/dll/steam_gameserver.cpp b/dll/steam_gameserver.cpp index acdbd28c..f3ae5b52 100644 --- a/dll/steam_gameserver.cpp +++ b/dll/steam_gameserver.cpp @@ -519,7 +519,7 @@ bool Steam_GameServer::BSetServerType( uint32 unServerFlags, uint32 unGameIP, ui } bool Steam_GameServer::BSetServerType( int32 nGameAppId, uint32 unServerFlags, uint32 unGameIP, uint16 unGamePort, - uint16 unSpectatorPort, uint16 usQueryPort, const char *pchGameDir, const char *pchVersion, bool bLANMode ) + uint16 unSpectatorPort, uint16 usQueryPort, const char *pchGameDir, const char *pchVersion, bool bLANMode ) { return BSetServerType(unServerFlags, unGameIP, unGamePort, unSpectatorPort, usQueryPort, pchGameDir, pchVersion, bLANMode); } @@ -887,48 +887,65 @@ void Steam_GameServer::RunCallbacks() void Steam_GameServer::GSSetSpawnCount( uint32 ucSpawn ) { PRINT_DEBUG_TODO(); - std::lock_guard lock(global_mutex); - - SetBotPlayerCount((int)ucSpawn); } bool Steam_GameServer::GSGetSteam2GetEncryptionKeyToSendToNewClient( void *pvEncryptionKey, uint32 *pcbEncryptionKey, uint32 cbMaxEncryptionKey ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - - return false; + + if (cbMaxEncryptionKey < 160) + return false; + + // This key is used in Steam.dll to encrypt the auth ticket. None of Steam.dll emulators are known to use it + // so it doesn't really matter what we put in it. + memset(pvEncryptionKey, 0xab, 160); + *pcbEncryptionKey = 160; + return true; } -bool Steam_GameServer::GSSendSteam2UserConnect( uint32 unUserID, const void *pvRawKey, uint32 unKeyLen, uint32 unIPPublic, uint16 usPort, const void *pvCookie, uint32 cubCookie ) +bool Steam_GameServer::GSSendSteam2UserConnect( uint32 unUserID, const void *pvRawKey, uint32 unKeyLen, uint32 unIPPublic, uint16 usPort, const void *pvCookie, uint32 cubCookie ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - - return SendUserConnectAndAuthenticate(unIPPublic, pvRawKey, unKeyLen, nullptr); + + CSteamID steam_id; + bool res = auth_manager->SendSteam2UserConnect(unUserID, pvRawKey, unKeyLen, unIPPublic, usPort, pvCookie, cubCookie, &steam_id); + + if (res) { + std::pair infos; + infos.first = steam_id; + infos.second.join_time = std::chrono::steady_clock::now(); + infos.second.score = 0; + infos.second.name = "unnamed"; + players.emplace_back(std::move(infos)); + } + + return res; } bool Steam_GameServer::GSSendSteam3UserConnect( CSteamID steamID, uint32 unIPPublic, const void *pvCookie, uint32 cubCookie ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - - return SendUserConnectAndAuthenticate(unIPPublic, pvCookie, cubCookie, nullptr); + + CSteamID steam_id; + return SendUserConnectAndAuthenticate(unIPPublic, pvCookie, cubCookie, &steam_id); } bool Steam_GameServer::GSRemoveUserConnect( uint32 unUserID ) { PRINT_DEBUG_TODO(); std::lock_guard lock(global_mutex); - + return false; } bool Steam_GameServer::GSSendUserDisconnect( CSteamID steamID, uint32 unUserID ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - + SendUserDisconnect(steamID); return true; } @@ -937,7 +954,7 @@ bool Steam_GameServer::GSSendUserStatusResponse( CSteamID steamID, int nSecondsC { PRINT_DEBUG_TODO(); std::lock_guard lock(global_mutex); - + return false; } @@ -945,48 +962,50 @@ bool Steam_GameServer::Obsolete_GSSetStatus( int32 nAppIdServed, uint32 unServer { PRINT_DEBUG_TODO(); std::lock_guard lock(global_mutex); - + return false; } bool Steam_GameServer::GSUpdateStatus( int cPlayers, int cPlayersMax, int cBotPlayers, const char *pchServerName, const char *pchMapName ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - - return false; + + UpdateServerStatus(cPlayers, cPlayersMax, cBotPlayers, pchServerName, "", pchMapName); + return true; } bool Steam_GameServer::GSSetServerType( int32 nGameAppId, uint32 unServerFlags, uint32 unGameIP, uint32 unGamePort, const char *pchGameDir, const char *pchVersion ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - - return BSetServerType(unServerFlags, unGameIP, unGamePort, 0, 0, pchGameDir, pchVersion, true); + + return BSetServerType(unServerFlags, unGameIP, unGamePort, 0, 0, pchGameDir, pchVersion, false); } bool Steam_GameServer::GSSetServerType2( int32 nGameAppId, uint32 unServerFlags, uint32 unGameIP, uint16 unGamePort, uint16 unSpectatorPort, uint16 usQueryPort, const char *pchGameDir, const char *pchVersion, bool bLANMode ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - + SetSpectatorPort(unSpectatorPort); return BSetServerType(unServerFlags, unGameIP, unGamePort, unSpectatorPort, usQueryPort, pchGameDir, pchVersion, bLANMode); } bool Steam_GameServer::GSUpdateStatus2( int cPlayers, int cPlayersMax, int cBotPlayers, const char *pchServerName, const char *pSpectatorServerName, const char *pchMapName ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - - return false; + + UpdateServerStatus(cPlayers, cPlayersMax, cBotPlayers, pchServerName, pSpectatorServerName, pchMapName); + return true; } bool Steam_GameServer::GSCreateUnauthenticatedUser( CSteamID *pSteamID ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - + CSteamID steamId = CreateUnauthenticatedUserConnection(); if (pSteamID) *pSteamID = steamId; return true; @@ -994,23 +1013,23 @@ bool Steam_GameServer::GSCreateUnauthenticatedUser( CSteamID *pSteamID ) bool Steam_GameServer::GSSetUserData( CSteamID steamID, const char *pPlayerName, uint32 nFrags ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - + return BUpdateUserData(steamID, pPlayerName, nFrags); } void Steam_GameServer::GSUpdateSpectatorPort( uint16 unSpectatorPort ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - + UpdateSpectatorPort(unSpectatorPort); } void Steam_GameServer::GSSetGameType( const char *pchType ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); SetGameType(pchType); @@ -1018,34 +1037,48 @@ void Steam_GameServer::GSSetGameType( const char *pchType ) bool Steam_GameServer::GSSendUserConnect( uint32 unUserID, uint32 unIPPublic, uint16 usPort, const void *pvCookie, uint32 cubCookie ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - - return SendUserConnectAndAuthenticate(unIPPublic, pvCookie, cubCookie, nullptr); + + // SteamGameServer003 still sends Steam2 callbacks, probably for backwards compatibility. + CSteamID steam_id; + bool res = auth_manager->SendSteam2UserConnect(unUserID, nullptr, 0, unIPPublic, usPort, pvCookie, cubCookie, &steam_id); + + if (res) { + std::pair infos; + infos.first = steam_id; + infos.second.join_time = std::chrono::steady_clock::now(); + infos.second.score = 0; + infos.second.name = "unnamed"; + players.emplace_back(std::move(infos)); + } + + return res; } bool Steam_GameServer::GSSetServerType( int32 nGameAppId, uint32 unServerFlags, uint32 unGameIP, uint16 unGamePort, uint16 unSpectatorPort, uint16 usQueryPort, const char *pchGameDir, const char *pchVersion, bool bLANMode ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - + SetSpectatorPort(unSpectatorPort); return BSetServerType(unServerFlags, unGameIP, unGamePort, unSpectatorPort, usQueryPort, pchGameDir, pchVersion, bLANMode); } bool Steam_GameServer::GSUpdateStatus( int cPlayers, int cPlayersMax, int cBotPlayers, const char *pchServerName, const char *pSpectatorServerName, const char *pchMapName ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - - return false; + + UpdateServerStatus(cPlayers, cPlayersMax, cBotPlayers, pchServerName, pSpectatorServerName, pchMapName); + return true; } bool Steam_GameServer::GSGetUserAchievementStatus( CSteamID steamID, const char *pchAchievementName ) { - PRINT_DEBUG_TODO(); + PRINT_DEBUG_ENTRY(); std::lock_guard lock(global_mutex); - + return BGetUserAchievementStatus(steamID, pchAchievementName); } // older sdk ----------------------------------------------- diff --git a/sdk/steam/isteamgameserver002.h b/sdk/steam/isteamgameserver002.h index a6989cf2..3c6c8faa 100644 --- a/sdk/steam/isteamgameserver002.h +++ b/sdk/steam/isteamgameserver002.h @@ -33,4 +33,20 @@ public: virtual void GSSetGameType( const char *pchType ) = 0; }; +// client has been denied to connect to this game server because of a Steam2 auth failure +struct GSClientSteam2Deny_t +{ + enum { k_iCallback = k_iSteamGameServerCallbacks + 4 }; + uint32 m_UserID; + uint32 m_eSteamError; +}; + +// client has been accepted by Steam2 to connect to this game server +struct GSClientSteam2Accept_t +{ + enum { k_iCallback = k_iSteamGameServerCallbacks + 5 }; + uint32 m_UserID; + uint64 m_SteamID; +}; + #endif // ISTEAMGAMESERVER002_H