Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes for some crashes + behavior enhancements #3

Merged
merged 17 commits into from
Aug 3, 2024
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
2 changes: 2 additions & 0 deletions dll/dll/steam_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ public ISteamClient
Steam_Networking_Messages *steam_gameserver_networking_messages{};
Steam_Game_Coordinator *steam_gameserver_game_coordinator{};
Steam_Masterserver_Updater *steam_masterserver_updater{};
Steam_GameStats *steam_gameserver_gamestats{};

Steam_AppTicket *steam_app_ticket{};

Steam_Overlay* steam_overlay{};
Expand Down
173 changes: 90 additions & 83 deletions dll/dll/steam_gamestats.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,91 +26,98 @@
class Steam_GameStats :
public ISteamGameStats
{
enum class AttributeType_t
{
Int, Str, Float, Int64,
};

struct Attribute_t
{
AttributeType_t type{};
union {
int32 n_data;
std::string s_data;
float f_data;
int64 ll_data{};
};

Attribute_t();
Attribute_t(const Attribute_t &other);
Attribute_t(Attribute_t &&other);
~Attribute_t();
};

struct Row_t
{
bool committed = false;
std::map<std::string, Attribute_t> attributes{};
};

struct Table_t
{
std::vector<Row_t> rows{};
};

struct Session_t
{
EGameStatsAccountType nAccountType{};
RTime32 rtTimeStarted{};
RTime32 rtTimeEnded{};
int nReasonCode{};
bool ended = false;
std::map<std::string, Attribute_t> attributes{};

std::vector<std::pair<std::string, Table_t>> tables{};
};

class Settings *settings{};
class Networking *network{};
class SteamCallResults *callback_results{};
class SteamCallBacks *callbacks{};
class RunEveryRunCB *run_every_runcb{};

std::vector<Session_t> sessions{};


bool valid_stats_account_type(int8 nAccountType);
Table_t *get_or_create_session_table(Session_t &session, const char *table_name);
Attribute_t *get_or_create_session_att(const char *att_name, Session_t &session, AttributeType_t type_if_create);
Attribute_t *get_or_create_row_att(uint64 ulRowID, const char *att_name, Table_t &table, AttributeType_t type_if_create);

void steam_run_callback();

// user connect/disconnect
void network_callback_low_level(Common_Message *msg);

static void steam_gamestats_network_low_level(void *object, Common_Message *msg);
static void steam_gamestats_run_every_runcb(void *object);
private:
// how much time to wait before removing ended sessions
constexpr const static int MAX_DEAD_SESSION_SECONDS = 15; // TODO not sure what would be sensible in this case

enum class AttributeType_t
{
Int, Str, Float, Int64,
};

struct Attribute_t
{
const AttributeType_t type;
union {
int32 n_data;
std::string s_data;
float f_data;
int64 ll_data;
};

Attribute_t(AttributeType_t type);
Attribute_t(const Attribute_t &other);
Attribute_t(Attribute_t &&other);
~Attribute_t();
};

struct Row_t
{
bool committed = false;
std::map<std::string, Attribute_t> attributes{};
};

struct Table_t
{
std::vector<Row_t> rows{};
};

struct Session_t
{
EGameStatsAccountType nAccountType{};
RTime32 rtTimeStarted{};
RTime32 rtTimeEnded{};
int nReasonCode{};
bool ended = false;
std::map<std::string, Attribute_t> attributes{};

std::vector<std::pair<std::string, Table_t>> tables{};
};

class Settings *settings{};
class Networking *network{};
class SteamCallResults *callback_results{};
class SteamCallBacks *callbacks{};
class RunEveryRunCB *run_every_runcb{};

std::map<uint64, Session_t> sessions{};


uint64 create_session_id() const;
bool valid_stats_account_type(int8 nAccountType);
Table_t *get_or_create_session_table(Session_t &session, const char *table_name);
Attribute_t *get_or_create_session_att(const char *att_name, Session_t &session, AttributeType_t type_if_create);
Attribute_t *get_or_create_row_att(uint64 ulRowID, const char *att_name, Table_t &table, AttributeType_t type_if_create);
Session_t* get_last_active_session();

void steam_run_callback();

// user connect/disconnect
void network_callback_low_level(Common_Message *msg);

static void steam_gamestats_network_low_level(void *object, Common_Message *msg);
static void steam_gamestats_run_every_runcb(void *object);


public:
Steam_GameStats(class Settings *settings, class Networking *network, class SteamCallResults *callback_results, class SteamCallBacks *callbacks, class RunEveryRunCB *run_every_runcb);
~Steam_GameStats();
SteamAPICall_t GetNewSession( int8 nAccountType, uint64 ulAccountID, int32 nAppID, RTime32 rtTimeStarted );
SteamAPICall_t EndSession( uint64 ulSessionID, RTime32 rtTimeEnded, int nReasonCode );
EResult AddSessionAttributeInt( uint64 ulSessionID, const char* pstrName, int32 nData );
EResult AddSessionAttributeString( uint64 ulSessionID, const char* pstrName, const char *pstrData );
EResult AddSessionAttributeFloat( uint64 ulSessionID, const char* pstrName, float fData );

EResult AddNewRow( uint64 *pulRowID, uint64 ulSessionID, const char *pstrTableName );
EResult CommitRow( uint64 ulRowID );
EResult CommitOutstandingRows( uint64 ulSessionID );
EResult AddRowAttributeInt( uint64 ulRowID, const char *pstrName, int32 nData );
EResult AddRowAtributeString( uint64 ulRowID, const char *pstrName, const char *pstrData );
EResult AddRowAttributeFloat( uint64 ulRowID, const char *pstrName, float fData );

EResult AddSessionAttributeInt64( uint64 ulSessionID, const char *pstrName, int64 llData );
EResult AddRowAttributeInt64( uint64 ulRowID, const char *pstrName, int64 llData );
Steam_GameStats(class Settings *settings, class Networking *network, class SteamCallResults *callback_results, class SteamCallBacks *callbacks, class RunEveryRunCB *run_every_runcb);
~Steam_GameStats();
SteamAPICall_t GetNewSession( int8 nAccountType, uint64 ulAccountID, int32 nAppID, RTime32 rtTimeStarted );
SteamAPICall_t EndSession( uint64 ulSessionID, RTime32 rtTimeEnded, int nReasonCode );
EResult AddSessionAttributeInt( uint64 ulSessionID, const char* pstrName, int32 nData );
EResult AddSessionAttributeString( uint64 ulSessionID, const char* pstrName, const char *pstrData );
EResult AddSessionAttributeFloat( uint64 ulSessionID, const char* pstrName, float fData );

EResult AddNewRow( uint64 *pulRowID, uint64 ulSessionID, const char *pstrTableName );
EResult CommitRow( uint64 ulRowID );
EResult CommitOutstandingRows( uint64 ulSessionID );
EResult AddRowAttributeInt( uint64 ulRowID, const char *pstrName, int32 nData );
EResult AddRowAtributeString( uint64 ulRowID, const char *pstrName, const char *pstrData );
EResult AddRowAttributeFloat( uint64 ulRowID, const char *pstrName, float fData );

EResult AddSessionAttributeInt64( uint64 ulSessionID, const char *pstrName, int64 llData );
EResult AddRowAttributeInt64( uint64 ulRowID, const char *pstrName, int64 llData );

};

Expand Down
32 changes: 16 additions & 16 deletions dll/dll/steam_remote_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,30 +36,29 @@ struct Stream_Write {
};

struct Downloaded_File {
// --- these are needed due to the usage of union
Downloaded_File();
~Downloaded_File();
// ---

enum DownloadSource {
enum class DownloadSource {
AfterFileShare, // attempted download after a call to Steam_Remote_Storage::FileShare()
AfterSendQueryUGCRequest, // attempted download after a call to Steam_UGC::SendQueryUGCRequest()
FromUGCDownloadToLocation, // attempted download via Steam_Remote_Storage::UGCDownloadToLocation()
} source{};
};

private:
DownloadSource source;

public:
Downloaded_File(DownloadSource src);

DownloadSource get_source() const;

// *** used in any case
std::string file{};
uint64 total_size{};

// put any additional data needed by other sources here

union {
// *** used when source = SendQueryUGCRequest only
Ugc_Remote_Storage_Bridge::QueryInfo mod_query_info;
// *** used when source = AfterSendQueryUGCRequest and FromUGCDownloadToLocation
Ugc_Remote_Storage_Bridge::QueryInfo mod_query_info{};

// *** used when source = FromUGCDownloadToLocation only
std::string download_to_location_fullpath;
};
// *** used when source = FromUGCDownloadToLocation only
std::string download_to_location_fullpath{};

};

Expand All @@ -85,6 +84,7 @@ public ISteamRemoteStorage
class Ugc_Remote_Storage_Bridge *ugc_bridge{};
class Local_Storage *local_storage{};
class SteamCallResults *callback_results{};
class SteamCallBacks *callbacks{};

std::vector<struct Async_Read> async_reads{};
std::vector<struct Stream_Write> stream_writes{};
Expand All @@ -95,7 +95,7 @@ public ISteamRemoteStorage

public:

Steam_Remote_Storage(class Settings *settings, class Ugc_Remote_Storage_Bridge *ugc_bridge, class Local_Storage *local_storage, class SteamCallResults *callback_results);
Steam_Remote_Storage(class Settings *settings, class Ugc_Remote_Storage_Bridge *ugc_bridge, class Local_Storage *local_storage, class SteamCallResults *callback_results, class SteamCallBacks *callbacks);

// NOTE
//
Expand Down
4 changes: 3 additions & 1 deletion dll/dll/steam_timeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ class Steam_Timeline :
public ISteamTimeline
{
private:
constexpr const static float PRIORITY_CLIP_MIN_SEC = 8.0f;

struct TimelineEvent_t
{
// emu specific: time when this event was added to the list via 'Steam_Timeline::AddTimelineEvent()'
Expand Down Expand Up @@ -68,7 +70,7 @@ public ISteamTimeline
class RunEveryRunCB *run_every_runcb{};

std::vector<TimelineEvent_t> timeline_events{};
std::vector<TimelineState_t> timeline_states{TimelineState_t{}}; // it seems to always start with a default event
std::vector<TimelineState_t> timeline_states{};

// unconditional periodic callback
void RunCallbacks();
Expand Down
6 changes: 3 additions & 3 deletions dll/settings_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,7 +1114,7 @@ static void try_detect_mods_folder(class Settings *settings_client, Settings *se
PRINT_DEBUG(" preview_filename: '%s'", newMod.previewFileName.c_str());
PRINT_DEBUG(" preview_filesize: %i bytes", newMod.previewFileSize);
PRINT_DEBUG(" preview file handle: %llu", settings_client->getMod(newMod.id).handlePreviewFile);
PRINT_DEBUG(" total_files_sizes: '%s'", newMod.total_files_sizes);
PRINT_DEBUG(" total_files_sizes: '%llu'", newMod.total_files_sizes);
PRINT_DEBUG(" min_game_branch: '%s'", newMod.min_game_branch.c_str());
PRINT_DEBUG(" max_game_branch: '%s'", newMod.max_game_branch.c_str());
PRINT_DEBUG(" workshop_item_url: '%s'", newMod.workshopItemURL.c_str());
Expand Down Expand Up @@ -1379,8 +1379,8 @@ static void parse_simple_features(class Settings *settings_client, class Setting
settings_client->matchmaking_server_details_via_source_query = ini.GetBoolValue("main::general", "matchmaking_server_details_via_source_query", settings_client->matchmaking_server_details_via_source_query);
settings_server->matchmaking_server_details_via_source_query = ini.GetBoolValue("main::general", "matchmaking_server_details_via_source_query", settings_server->matchmaking_server_details_via_source_query);

settings_client->matchmaking_server_list_always_lan_type = ini.GetBoolValue("main::general", "matchmaking_server_list_actual_type", settings_client->matchmaking_server_list_always_lan_type);
settings_server->matchmaking_server_list_always_lan_type = ini.GetBoolValue("main::general", "matchmaking_server_list_actual_type", settings_server->matchmaking_server_list_always_lan_type);
settings_client->matchmaking_server_list_always_lan_type = !ini.GetBoolValue("main::general", "matchmaking_server_list_actual_type", !settings_client->matchmaking_server_list_always_lan_type);
settings_server->matchmaking_server_list_always_lan_type = !ini.GetBoolValue("main::general", "matchmaking_server_list_actual_type", !settings_server->matchmaking_server_list_always_lan_type);


// [main::connectivity]
Expand Down
3 changes: 2 additions & 1 deletion dll/steam_client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Steam_Client::Steam_Client()
steam_user_stats = new Steam_User_Stats(settings_client, network, local_storage, callback_results_client, callbacks_client, run_every_runcb, steam_overlay);
steam_apps = new Steam_Apps(settings_client, callback_results_client, callbacks_client);
steam_networking = new Steam_Networking(settings_client, network, callbacks_client, run_every_runcb);
steam_remote_storage = new Steam_Remote_Storage(settings_client, ugc_bridge, local_storage, callback_results_client);
steam_remote_storage = new Steam_Remote_Storage(settings_client, ugc_bridge, local_storage, callback_results_client, callbacks_client);
steam_screenshots = new Steam_Screenshots(local_storage, callbacks_client);
steam_http = new Steam_HTTP(settings_client, network, callback_results_client, callbacks_client);
steam_controller = new Steam_Controller(settings_client, callback_results_client, callbacks_client, run_every_runcb);
Expand Down Expand Up @@ -143,6 +143,7 @@ Steam_Client::Steam_Client()
steam_gameserver_networking_messages = new Steam_Networking_Messages(settings_server, network, callback_results_server, callbacks_server, run_every_runcb);
steam_gameserver_game_coordinator = new Steam_Game_Coordinator(settings_server, network, callback_results_server, callbacks_server, run_every_runcb);
steam_masterserver_updater = new Steam_Masterserver_Updater(settings_server, network, callback_results_server, callbacks_server, run_every_runcb);
steam_gameserver_gamestats = new Steam_GameStats(settings_server, network, callback_results_server, callbacks_server, run_every_runcb);

PRINT_DEBUG("init AppTicket");
steam_app_ticket = new Steam_AppTicket(settings_client);
Expand Down
14 changes: 12 additions & 2 deletions dll/steam_client_interface_getter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,16 @@ ISteamGameStats *Steam_Client::GetISteamGameStats( HSteamUser hSteamUser, HSteam
PRINT_DEBUG("%s", pchVersion);
if (!steam_pipes.count(hSteamPipe) || !hSteamUser) return nullptr;

Steam_GameStats *steam_gamestats_tmp{};

if (steam_pipes[hSteamPipe] == Steam_Pipe::SERVER) {
steam_gamestats_tmp = steam_gameserver_gamestats;
} else {
steam_gamestats_tmp = steam_gamestats;
}

if (strcmp(pchVersion, STEAMGAMESTATS_INTERFACE_VERSION) == 0) {
return reinterpret_cast<ISteamGameStats *>(static_cast<ISteamGameStats *>(steam_gamestats));
return reinterpret_cast<ISteamGameStats *>(static_cast<ISteamGameStats *>(steam_gamestats_tmp));
}

report_missing_impl_and_exit(pchVersion, EMU_FUNC_NAME);
Expand Down Expand Up @@ -249,13 +257,15 @@ ISteamMatchmakingServers *Steam_Client::GetISteamMatchmakingServers( HSteamUser
// returns the a generic interface
void *Steam_Client::GetISteamGenericInterface( HSteamUser hSteamUser, HSteamPipe hSteamPipe, const char *pchVersion )
{
PRINT_DEBUG("%s", pchVersion);
PRINT_DEBUG("'%s' %i %i", pchVersion, hSteamUser, hSteamPipe);
if (!steam_pipes.count(hSteamPipe)) return NULL;

bool server = false;
if (steam_pipes[hSteamPipe] == Steam_Pipe::SERVER) {
// PRINT_DEBUG("requesting interface with server pipe");
server = true;
} else {
// PRINT_DEBUG("requesting interface with client pipe");
// if this is a user pipe, and version != "SteamNetworkingUtils", and version != "SteamUtils"
if ((strstr(pchVersion, "SteamNetworkingUtils") != pchVersion) && (strstr(pchVersion, "SteamUtils") != pchVersion)) {
if (!hSteamUser) return NULL;
Expand Down
18 changes: 8 additions & 10 deletions dll/steam_friends.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,21 +209,16 @@ SteamAPICall_t Steam_Friends::SetPersonaName( const char *pchPersonaName )
PRINT_DEBUG_ENTRY();
std::lock_guard<std::recursive_mutex> lock(global_mutex);

// send PersonaStateChange_t callbacks
persona_change(settings->get_local_steam_id(), EPersonaChange::k_EPersonaChangeName);

SetPersonaNameResponse_t data{};
data.m_bSuccess = true;
data.m_bLocalSuccess = false;
data.m_result = k_EResultOK;
persona_change(settings->get_local_steam_id(), k_EPersonaChangeName);

auto ret = callback_results->addCallResult(data.k_iCallback, &data, sizeof(data));

{
PersonaStateChange_t data2{};
data2.m_nChangeFlags = EPersonaChange::k_EPersonaChangeName;
data2.m_ulSteamID = settings->get_local_steam_id().ConvertToUint64();
callbacks->addCBResult(data2.k_iCallback, &data2, sizeof(data2));
}

callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
return ret;
}

Expand Down Expand Up @@ -1032,7 +1027,10 @@ SteamAPICall_t Steam_Friends::JoinClanChatRoom( CSteamID steamIDClan )
JoinClanChatRoomCompletionResult_t data;
data.m_steamIDClanChat = steamIDClan;
data.m_eChatRoomEnterResponse = k_EChatRoomEnterResponseSuccess;
return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data));

auto ret = callback_results->addCallResult(data.k_iCallback, &data, sizeof(data));
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
return ret;
}

bool Steam_Friends::LeaveClanChatRoom( CSteamID steamIDClan )
Expand Down
Loading