Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions dll/dll/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down
2 changes: 1 addition & 1 deletion dll/dll/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion dll/dll/steam_gameserverstats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 14 additions & 2 deletions dll/dll/steam_user_stats.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -110,6 +116,9 @@ public ISteamUserStats

GameServerStats_Messages::AllStats pending_server_updates{};

std::map<uint64, Pending_User_Stats_Request> pending_user_stats_requests;
std::map<uint64, Steam_User_Stats_Data> received_user_stats_data;

void load_achievements_db();
void load_achievements();
void save_achievements();
Expand All @@ -133,13 +142,16 @@ public ISteamUserStats
// change stats/achievements without sending back to server
bool clear_stats_internal();
InternalSetResult<int32> set_stat_internal( const char *pchName, int32 nData );
InternalSetResult<std::pair<GameServerStats_Messages::StatInfo::Stat_Type, float>> set_stat_internal( const char *pchName, float fData );
InternalSetResult<std::pair<GameServerStats_Messages::StatInfo::Stat_Type, float>> update_avg_rate_stat_internal( const char *pchName, float flCountThisSession, double dSessionLength );
InternalSetResult<std::pair<StatInfo::Stat_Type, float>> set_stat_internal( const char *pchName, float fData );
InternalSetResult<std::pair<StatInfo::Stat_Type, float>> update_avg_rate_stat_internal( const char *pchName, float flCountThisSession, double dSessionLength );
InternalSetResult<bool> set_achievement_internal( const char *pchName );
InternalSetResult<bool> 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
Expand Down
52 changes: 34 additions & 18 deletions dll/net.proto
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -295,6 +296,20 @@ message Leaderboards_Messages {
}
}

message Steam_User_Stats_Data {
map<string, StatInfo> 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
Expand All @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions dll/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

}

Expand Down
6 changes: 3 additions & 3 deletions dll/settings_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 6 additions & 6 deletions dll/steam_gameserverstats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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 &&
Expand All @@ -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);
Expand Down
28 changes: 25 additions & 3 deletions dll/steam_user_stats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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);
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -440,6 +442,7 @@ void Steam_User_Stats::steam_run_callback()
{
send_updated_stats();
load_achievements_icons();
send_pending_user_stats_requests();
}


Expand All @@ -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
Comment thread
Detanup01 marked this conversation as resolved.
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;
Expand Down
Loading