mirror of
https://github.com/Detanup01/gbe_fork.git
synced 2024-11-27 05:04:01 +08:00
allow empty board entries, don't force and entry for current user
This commit is contained in:
parent
4d03c5b402
commit
a36cadbf12
@ -5,6 +5,7 @@
|
||||
- if the script was ran without root, and `-packages_skip` wasn't specified,
|
||||
the script will attempt to detect and use the built-in tool `sudo` if it was available
|
||||
* share leaderboards scores with connected players, adjust players ranks locally, and sort entries as needed by the game, suggested by **[M4RCK5]**
|
||||
this will only work when people connected on the same network are playing the same game, once they disconnect their leaderboard entry will be lost (no data persistence for other players)
|
||||
* implemented the missing interface `ISteamGameServerStats`, allowing game servers to exchange user stats & achievements with players
|
||||
* for windows: updated stub drm patterns and added a workaround for older variants,
|
||||
this increases the compatibility, but makes it easier to be detected
|
||||
|
@ -192,7 +192,7 @@ bool Steam_GameServerStats::GetUserAchievement( CSteamID steamIDUser, const char
|
||||
// Set the IP range of your official servers on the Steamworks page
|
||||
bool Steam_GameServerStats::SetUserStat( CSteamID steamIDUser, const char *pchName, int32 nData )
|
||||
{
|
||||
PRINT_DEBUG("Steam_GameServerStats::SetUserStat <int32> %llu '%s' %i\n", (uint64)steamIDUser.ConvertToUint64(), pchName, nData);
|
||||
PRINT_DEBUG("Steam_GameServerStats::SetUserStat <int32> %llu '%s'=%i\n", (uint64)steamIDUser.ConvertToUint64(), pchName, nData);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
if (!pchName) return false;
|
||||
@ -209,7 +209,7 @@ bool Steam_GameServerStats::SetUserStat( CSteamID steamIDUser, const char *pchNa
|
||||
|
||||
bool Steam_GameServerStats::SetUserStat( CSteamID steamIDUser, const char *pchName, float fData )
|
||||
{
|
||||
PRINT_DEBUG("Steam_GameServerStats::SetUserStat <float> %llu '%s' %f\n", (uint64)steamIDUser.ConvertToUint64(), pchName, fData);
|
||||
PRINT_DEBUG("Steam_GameServerStats::SetUserStat <float> %llu '%s'=%f\n", (uint64)steamIDUser.ConvertToUint64(), pchName, fData);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
if (!pchName) return false;
|
||||
|
@ -188,18 +188,20 @@ std::vector<Steam_Leaderboard_Entry> Steam_User_Stats::load_leaderboard_entries(
|
||||
|
||||
void Steam_User_Stats::save_my_leaderboard_entry(const Steam_Leaderboard &leaderboard)
|
||||
{
|
||||
auto my_entry = leaderboard.find_recent_entry(settings->get_local_steam_id());
|
||||
if (!my_entry) return; // we don't have a score entry
|
||||
|
||||
PRINT_DEBUG("Steam_User_Stats::save_my_leaderboard_entry saving entries for leaderboard '%s'\n", leaderboard.name.c_str());
|
||||
|
||||
const auto &my_entry = *leaderboard.find_recent_entry(settings->get_local_steam_id());
|
||||
std::vector<uint32_t> output{};
|
||||
|
||||
uint64_t steam_id = my_entry.steam_id.ConvertToUint64();
|
||||
uint64_t steam_id = my_entry->steam_id.ConvertToUint64();
|
||||
output.push_back((uint32_t)(steam_id & 0xFFFFFFFF)); // lower 4 bytes
|
||||
output.push_back((uint32_t)(steam_id >> 32)); // higher 4 bytes
|
||||
|
||||
output.push_back(my_entry.score);
|
||||
output.push_back((uint32_t)my_entry.score_details.size());
|
||||
for (const auto &detail : my_entry.score_details) {
|
||||
output.push_back(my_entry->score);
|
||||
output.push_back((uint32_t)my_entry->score_details.size());
|
||||
for (const auto &detail : my_entry->score_details) {
|
||||
output.push_back(detail);
|
||||
}
|
||||
|
||||
@ -254,13 +256,10 @@ unsigned int Steam_User_Stats::cache_leaderboard_ifneeded(const std::string &nam
|
||||
new_board.sort_method = eLeaderboardSortMethod;
|
||||
new_board.display_type = eLeaderboardDisplayType;
|
||||
new_board.entries = load_leaderboard_entries(name);
|
||||
|
||||
new_board.sort_entries();
|
||||
new_board.remove_duplicate_entries();
|
||||
|
||||
Steam_Leaderboard_Entry my_new_entry{};
|
||||
my_new_entry.steam_id = settings->get_local_steam_id();
|
||||
auto my_entry = update_leaderboard_entry(new_board, my_new_entry, false);
|
||||
|
||||
// save it in memory for later
|
||||
cached_leaderboards.push_back(new_board);
|
||||
board_handle = cached_leaderboards.size();
|
||||
@ -274,11 +273,14 @@ unsigned int Steam_User_Stats::cache_leaderboard_ifneeded(const std::string &nam
|
||||
|
||||
void Steam_User_Stats::send_my_leaderboard_score(const Steam_Leaderboard &board, const CSteamID *steamid, bool want_scores_back)
|
||||
{
|
||||
const auto &my_entry = *board.find_recent_entry(settings->get_local_steam_id());
|
||||
const auto my_entry = board.find_recent_entry(settings->get_local_steam_id());
|
||||
Leaderboards_Messages::UserScoreEntry *score_entry_msg = nullptr;
|
||||
|
||||
auto score_entry_msg = new Leaderboards_Messages::UserScoreEntry();
|
||||
score_entry_msg->set_score(my_entry.score);
|
||||
score_entry_msg->mutable_score_details()->Assign(my_entry.score_details.begin(), my_entry.score_details.end());
|
||||
if (my_entry) {
|
||||
score_entry_msg = new Leaderboards_Messages::UserScoreEntry();
|
||||
score_entry_msg->set_score(my_entry->score);
|
||||
score_entry_msg->mutable_score_details()->Assign(my_entry->score_details.begin(), my_entry->score_details.end());
|
||||
}
|
||||
|
||||
auto board_info_msg = new Leaderboards_Messages::LeaderboardInfo();
|
||||
board_info_msg->set_allocated_board_name(new std::string(board.name));
|
||||
@ -290,7 +292,8 @@ void Steam_User_Stats::send_my_leaderboard_score(const Steam_Leaderboard &board,
|
||||
else board_msg->set_type(Leaderboards_Messages::UpdateUserScore);
|
||||
board_msg->set_appid(settings->get_local_game_id().AppID());
|
||||
board_msg->set_allocated_leaderboard_info(board_info_msg);
|
||||
board_msg->set_allocated_user_score_entry(score_entry_msg);
|
||||
// if we have an entry
|
||||
if (score_entry_msg) board_msg->set_allocated_user_score_entry(score_entry_msg);
|
||||
|
||||
Common_Message common_msg{};
|
||||
common_msg.set_source_id(settings->get_local_steam_id().ConvertToUint64());
|
||||
@ -1337,7 +1340,7 @@ SteamAPICall_t Steam_User_Stats::DownloadLeaderboardEntriesForUsers( SteamLeader
|
||||
// once you've accessed all the entries, the data will be free'd, and the SteamLeaderboardEntries_t handle will become invalid
|
||||
bool Steam_User_Stats::GetDownloadedLeaderboardEntry( SteamLeaderboardEntries_t hSteamLeaderboardEntries, int index, LeaderboardEntry_t *pLeaderboardEntry, int32 *pDetails, int cDetailsMax )
|
||||
{
|
||||
PRINT_DEBUG("Steam_User_Stats::GetDownloadedLeaderboardEntry\n");
|
||||
PRINT_DEBUG("Steam_User_Stats::GetDownloadedLeaderboardEntry [%i] (%i) %llu %p %p\n", index, cDetailsMax, hSteamLeaderboardEntries, pLeaderboardEntry, pDetails);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
if (hSteamLeaderboardEntries > cached_leaderboards.size() || hSteamLeaderboardEntries <= 0) return false;
|
||||
|
||||
@ -1377,28 +1380,34 @@ SteamAPICall_t Steam_User_Stats::UploadLeaderboardScore( SteamLeaderboard_t hSte
|
||||
if (hSteamLeaderboard > cached_leaderboards.size() || hSteamLeaderboard <= 0) return k_uAPICallInvalid; //TODO: might return callresult even if hSteamLeaderboard is invalid
|
||||
|
||||
auto &board = cached_leaderboards[hSteamLeaderboard - 1];
|
||||
auto &my_entry = *board.find_recent_entry(settings->get_local_steam_id());
|
||||
int current_rank = (int)(&my_entry - &board.entries[0]);
|
||||
auto my_entry = board.find_recent_entry(settings->get_local_steam_id());
|
||||
int current_rank = my_entry
|
||||
? 1 + (int)(my_entry - &board.entries[0])
|
||||
: 0;
|
||||
int new_rank = current_rank;
|
||||
|
||||
bool score_updated = false;
|
||||
switch (eLeaderboardUploadScoreMethod)
|
||||
{
|
||||
case k_ELeaderboardUploadScoreMethodKeepBest: { // keep user's best score
|
||||
if (board.sort_method == k_ELeaderboardSortMethodAscending) { // keep user's lowest score
|
||||
score_updated = nScore < my_entry.score;
|
||||
} else { // keep user's highest score
|
||||
score_updated = nScore > my_entry.score;
|
||||
if (my_entry) {
|
||||
switch (eLeaderboardUploadScoreMethod)
|
||||
{
|
||||
case k_ELeaderboardUploadScoreMethodKeepBest: { // keep user's best score
|
||||
if (board.sort_method == k_ELeaderboardSortMethodAscending) { // keep user's lowest score
|
||||
score_updated = nScore < my_entry->score;
|
||||
} else { // keep user's highest score
|
||||
score_updated = nScore > my_entry->score;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
|
||||
case k_ELeaderboardUploadScoreMethodForceUpdate: { // always replace score with specified
|
||||
score_updated = my_entry.score != nScore;
|
||||
}
|
||||
break;
|
||||
case k_ELeaderboardUploadScoreMethodForceUpdate: { // always replace score with specified
|
||||
score_updated = my_entry->score != nScore;
|
||||
}
|
||||
break;
|
||||
|
||||
default: break;
|
||||
default: break;
|
||||
}
|
||||
} else { // no entry yet for us
|
||||
score_updated = true;
|
||||
}
|
||||
|
||||
if (score_updated || (eLeaderboardUploadScoreMethod == k_ELeaderboardUploadScoreMethodForceUpdate)) {
|
||||
@ -1410,12 +1419,15 @@ SteamAPICall_t Steam_User_Stats::UploadLeaderboardScore( SteamLeaderboard_t hSte
|
||||
new_entry.score_details.push_back(pScoreDetails[i]);
|
||||
}
|
||||
}
|
||||
|
||||
update_leaderboard_entry(board, new_entry);
|
||||
new_rank = 1 + (int)(board.find_recent_entry(settings->get_local_steam_id()) - &board.entries[0]);
|
||||
|
||||
// check again in case this was a forced update
|
||||
// avoid disk write if score is the same
|
||||
if (score_updated) save_my_leaderboard_entry(board);
|
||||
send_my_leaderboard_score(board);
|
||||
|
||||
new_rank = (int)(board.find_recent_entry(settings->get_local_steam_id()) - &board.entries[0]);
|
||||
}
|
||||
|
||||
LeaderboardScoreUploaded_t data{};
|
||||
@ -1423,8 +1435,8 @@ SteamAPICall_t Steam_User_Stats::UploadLeaderboardScore( SteamLeaderboard_t hSte
|
||||
data.m_hSteamLeaderboard = hSteamLeaderboard;
|
||||
data.m_nScore = nScore;
|
||||
data.m_bScoreChanged = score_updated;
|
||||
data.m_nGlobalRankNew = 1 + new_rank;
|
||||
data.m_nGlobalRankPrevious = 1 + current_rank;
|
||||
data.m_nGlobalRankNew = new_rank;
|
||||
data.m_nGlobalRankPrevious = current_rank;
|
||||
return callback_results->addCallResult(data.k_iCallback, &data, sizeof(data), 0.1); // TODO is this timing ok?
|
||||
}
|
||||
|
||||
@ -1814,6 +1826,11 @@ void Steam_User_Stats::network_callback_stats(Common_Message *msg)
|
||||
network_stats_updated(msg);
|
||||
break;
|
||||
|
||||
// a user has updated/new stats
|
||||
case GameServerStats_Messages::UpdateUserStatsFromUser:
|
||||
// nothing
|
||||
break;
|
||||
|
||||
default:
|
||||
PRINT_DEBUG("Steam_User_Stats::network_callback_stats unhandled type %i\n", (int)msg->gameserver_stats_messages().type());
|
||||
break;
|
||||
@ -1824,25 +1841,24 @@ void Steam_User_Stats::network_callback_stats(Common_Message *msg)
|
||||
// someone updated their score
|
||||
void Steam_User_Stats::network_leaderboard_update_score(Common_Message *msg, Steam_Leaderboard &board, bool send_score_back)
|
||||
{
|
||||
if (!msg->leaderboards_messages().has_user_score_entry()) {
|
||||
PRINT_DEBUG("Steam_User_Stats::network_leaderboard_update_score error empty msg\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CSteamID sender_steamid((uint64)msg->source_id());
|
||||
PRINT_DEBUG(
|
||||
"Steam_User_Stats::network_leaderboard_update_score got score for user %llu on leaderboard '%s' (send our score back=%i)\n",
|
||||
(uint64)msg->source_id(), board.name.c_str(), (int)send_score_back
|
||||
);
|
||||
|
||||
const auto &user_score_msg = msg->leaderboards_messages().user_score_entry();
|
||||
// when players initally load a board, and they don't have an entry in it,
|
||||
// they send this msg but without their user score entry
|
||||
if (msg->leaderboards_messages().has_user_score_entry()) {
|
||||
const auto &user_score_msg = msg->leaderboards_messages().user_score_entry();
|
||||
|
||||
Steam_Leaderboard_Entry updated_entry{};
|
||||
updated_entry.steam_id = sender_steamid;
|
||||
updated_entry.score = user_score_msg.score();
|
||||
updated_entry.score_details.reserve(user_score_msg.score_details().size());
|
||||
updated_entry.score_details.assign(user_score_msg.score_details().begin(), user_score_msg.score_details().end());
|
||||
update_leaderboard_entry(board, updated_entry);
|
||||
Steam_Leaderboard_Entry updated_entry{};
|
||||
updated_entry.steam_id = sender_steamid;
|
||||
updated_entry.score = user_score_msg.score();
|
||||
updated_entry.score_details.reserve(user_score_msg.score_details().size());
|
||||
updated_entry.score_details.assign(user_score_msg.score_details().begin(), user_score_msg.score_details().end());
|
||||
update_leaderboard_entry(board, updated_entry);
|
||||
}
|
||||
|
||||
// if the sender wants back our score, send it to all, not just them
|
||||
// in case we have 3 or more players and none of them have our data
|
||||
|
Loading…
Reference in New Issue
Block a user