234 lines
7.8 KiB
C#
234 lines
7.8 KiB
C#
using Steamworks;
|
|
using UnityEngine;
|
|
using UnityEngine.Events;
|
|
|
|
namespace HeathenEngineering.SteamApi.PlayerServices
|
|
{
|
|
[CreateAssetMenu(menuName = "Steamworks/Player Services/Leaderboard Data")]
|
|
public class SteamworksLeaderboardData : ScriptableObject
|
|
{
|
|
public bool createIfMissing;
|
|
|
|
public ELeaderboardSortMethod sortMethod;
|
|
|
|
public ELeaderboardDisplayType displayType;
|
|
|
|
public string leaderboardName;
|
|
|
|
public int MaxDetailEntries;
|
|
|
|
[HideInInspector]
|
|
public SteamLeaderboard_t? LeaderboardId;
|
|
|
|
[HideInInspector]
|
|
public LeaderboardEntry_t? UserEntry;
|
|
|
|
public UnityEvent BoardFound = new UnityEvent();
|
|
|
|
public LeaderboardScoresDownloadedEvent OnQueryResults = new LeaderboardScoresDownloadedEvent();
|
|
|
|
public UnityLeaderboardRankUpdateEvent UserRankLoaded = new UnityLeaderboardRankUpdateEvent();
|
|
|
|
public UnityLeaderboardRankChangeEvent UserRankChanged = new UnityLeaderboardRankChangeEvent();
|
|
|
|
public UnityLeaderboardRankChangeEvent UserNewHighRank = new UnityLeaderboardRankChangeEvent();
|
|
|
|
private CallResult<LeaderboardFindResult_t> OnLeaderboardFindResultCallResult;
|
|
|
|
private CallResult<LeaderboardScoresDownloaded_t> OnLeaderboardScoresDownloadedCallResult;
|
|
|
|
private CallResult<LeaderboardScoreUploaded_t> OnLeaderboardScoreUploadedCallResult;
|
|
|
|
public void Register()
|
|
{
|
|
OnLeaderboardFindResultCallResult = CallResult<LeaderboardFindResult_t>.Create(OnLeaderboardFindResult);
|
|
OnLeaderboardScoresDownloadedCallResult = CallResult<LeaderboardScoresDownloaded_t>.Create(OnLeaderboardScoresDownloaded);
|
|
OnLeaderboardScoreUploadedCallResult = CallResult<LeaderboardScoreUploaded_t>.Create(OnLeaderboardScoreUploaded);
|
|
if (createIfMissing)
|
|
{
|
|
FindOrCreateLeaderboard(sortMethod, displayType);
|
|
}
|
|
else
|
|
{
|
|
FindLeaderboard();
|
|
}
|
|
}
|
|
|
|
private void FindOrCreateLeaderboard(ELeaderboardSortMethod sortMethod, ELeaderboardDisplayType displayType)
|
|
{
|
|
SteamAPICall_t hAPICall = SteamUserStats.FindOrCreateLeaderboard(leaderboardName, sortMethod, displayType);
|
|
OnLeaderboardFindResultCallResult.Set(hAPICall);
|
|
}
|
|
|
|
private void FindLeaderboard()
|
|
{
|
|
SteamAPICall_t hAPICall = SteamUserStats.FindLeaderboard(leaderboardName);
|
|
OnLeaderboardFindResultCallResult.Set(hAPICall);
|
|
}
|
|
|
|
public void RefreshUserEntry()
|
|
{
|
|
if (!LeaderboardId.HasValue)
|
|
{
|
|
Debug.LogError(base.name + " Leaderboard Data Object, cannot download scores, the leaderboard has not been initalized and cannot download scores.");
|
|
return;
|
|
}
|
|
CSteamID[] prgUsers = new CSteamID[1] { SteamUser.GetSteamID() };
|
|
SteamAPICall_t hAPICall = SteamUserStats.DownloadLeaderboardEntriesForUsers(LeaderboardId.Value, prgUsers, 1);
|
|
OnLeaderboardScoresDownloadedCallResult.Set(hAPICall, OnLeaderboardUserRefreshRequest);
|
|
}
|
|
|
|
public void UploadScore(int score, ELeaderboardUploadScoreMethod method)
|
|
{
|
|
if (!LeaderboardId.HasValue)
|
|
{
|
|
Debug.LogError(base.name + " Leaderboard Data Object, cannot upload scores, the leaderboard has not been initalized and cannot upload scores.");
|
|
return;
|
|
}
|
|
SteamAPICall_t hAPICall = SteamUserStats.UploadLeaderboardScore(LeaderboardId.Value, method, score, null, 0);
|
|
OnLeaderboardScoreUploadedCallResult.Set(hAPICall);
|
|
}
|
|
|
|
public void UploadScore(int score, int[] scoreDetails, ELeaderboardUploadScoreMethod method)
|
|
{
|
|
if (!LeaderboardId.HasValue)
|
|
{
|
|
Debug.LogError(base.name + " Leaderboard Data Object, cannot upload scores, the leaderboard has not been initalized and cannot upload scores.");
|
|
return;
|
|
}
|
|
SteamAPICall_t hAPICall = SteamUserStats.UploadLeaderboardScore(LeaderboardId.Value, method, score, scoreDetails, scoreDetails.Length);
|
|
OnLeaderboardScoreUploadedCallResult.Set(hAPICall);
|
|
}
|
|
|
|
public void QueryTopEntries(int count)
|
|
{
|
|
QueryEntries(ELeaderboardDataRequest.k_ELeaderboardDataRequestGlobal, 0, count);
|
|
}
|
|
|
|
public void QueryFriendEntries(int aroundPlayer)
|
|
{
|
|
QueryEntries(ELeaderboardDataRequest.k_ELeaderboardDataRequestFriends, -aroundPlayer, aroundPlayer);
|
|
}
|
|
|
|
public void QueryPeerEntries(int aroundPlayer)
|
|
{
|
|
QueryEntries(ELeaderboardDataRequest.k_ELeaderboardDataRequestGlobalAroundUser, -aroundPlayer, aroundPlayer);
|
|
}
|
|
|
|
public void QueryEntries(ELeaderboardDataRequest requestType, int rangeStart, int rangeEnd)
|
|
{
|
|
if (!LeaderboardId.HasValue)
|
|
{
|
|
Debug.LogError(base.name + " Leaderboard Data Object, cannot download scores, the leaderboard has not been initalized and cannot download scores.");
|
|
return;
|
|
}
|
|
SteamAPICall_t hAPICall = SteamUserStats.DownloadLeaderboardEntries(LeaderboardId.Value, requestType, rangeStart, rangeEnd);
|
|
OnLeaderboardScoresDownloadedCallResult.Set(hAPICall, OnLeaderboardScoresDownloaded);
|
|
}
|
|
|
|
private void OnLeaderboardScoreUploaded(LeaderboardScoreUploaded_t param, bool bIOFailure)
|
|
{
|
|
if (param.m_bSuccess == 0 || bIOFailure)
|
|
{
|
|
Debug.LogError(base.name + " Leaderboard Data Object, failed to upload score to Steam: Success code = " + param.m_bSuccess, this);
|
|
}
|
|
RefreshUserEntry();
|
|
}
|
|
|
|
private void OnLeaderboardUserRefreshRequest(LeaderboardScoresDownloaded_t param, bool bIOFailure)
|
|
{
|
|
ProcessScoresDownloaded(param, bIOFailure);
|
|
}
|
|
|
|
private void OnLeaderboardScoresDownloaded(LeaderboardScoresDownloaded_t param, bool bIOFailure)
|
|
{
|
|
bool playerIncluded = ProcessScoresDownloaded(param, bIOFailure);
|
|
OnQueryResults.Invoke(new LeaderboardScoresDownloaded
|
|
{
|
|
bIOFailure = bIOFailure,
|
|
scoreData = param,
|
|
playerIncluded = playerIncluded
|
|
});
|
|
}
|
|
|
|
private bool ProcessScoresDownloaded(LeaderboardScoresDownloaded_t param, bool bIOFailure)
|
|
{
|
|
bool result = false;
|
|
if (!bIOFailure)
|
|
{
|
|
CSteamID steamID = SteamUser.GetSteamID();
|
|
for (int i = 0; i < param.m_cEntryCount; i++)
|
|
{
|
|
int[] array = null;
|
|
LeaderboardEntry_t pLeaderboardEntry;
|
|
if (MaxDetailEntries < 1)
|
|
{
|
|
SteamUserStats.GetDownloadedLeaderboardEntry(param.m_hSteamLeaderboardEntries, i, out pLeaderboardEntry, array, MaxDetailEntries);
|
|
}
|
|
else
|
|
{
|
|
array = new int[MaxDetailEntries];
|
|
SteamUserStats.GetDownloadedLeaderboardEntry(param.m_hSteamLeaderboardEntries, i, out pLeaderboardEntry, array, MaxDetailEntries);
|
|
}
|
|
if (pLeaderboardEntry.m_steamIDUser.m_SteamID != steamID.m_SteamID)
|
|
{
|
|
continue;
|
|
}
|
|
result = true;
|
|
if (!UserEntry.HasValue || UserEntry.Value.m_nGlobalRank != pLeaderboardEntry.m_nGlobalRank)
|
|
{
|
|
LeaderboardUserData arg = new LeaderboardUserData
|
|
{
|
|
leaderboardName = leaderboardName,
|
|
leaderboardId = LeaderboardId.Value,
|
|
entry = pLeaderboardEntry,
|
|
details = array
|
|
};
|
|
LeaderboardRankChangeData arg2 = new LeaderboardRankChangeData
|
|
{
|
|
leaderboardName = leaderboardName,
|
|
leaderboardId = LeaderboardId.Value,
|
|
newEntry = pLeaderboardEntry,
|
|
oldEntry = (UserEntry.HasValue ? new LeaderboardEntry_t?(UserEntry.Value) : ((LeaderboardEntry_t?)null))
|
|
};
|
|
UserEntry = pLeaderboardEntry;
|
|
UserRankLoaded.Invoke(arg);
|
|
UserRankChanged.Invoke(arg2);
|
|
if (arg2.newEntry.m_nGlobalRank < (arg2.oldEntry.HasValue ? arg2.oldEntry.Value.m_nGlobalRank : int.MaxValue))
|
|
{
|
|
UserNewHighRank.Invoke(arg2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LeaderboardUserData arg3 = new LeaderboardUserData
|
|
{
|
|
leaderboardName = leaderboardName,
|
|
leaderboardId = LeaderboardId.Value,
|
|
entry = pLeaderboardEntry,
|
|
details = array
|
|
};
|
|
UserEntry = pLeaderboardEntry;
|
|
UserRankLoaded.Invoke(arg3);
|
|
}
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private void OnLeaderboardFindResult(LeaderboardFindResult_t param, bool bIOFailure)
|
|
{
|
|
if (param.m_bLeaderboardFound == 0 || bIOFailure)
|
|
{
|
|
Debug.LogError("Failed to find leaderboard", this);
|
|
}
|
|
else if (param.m_bLeaderboardFound != 0)
|
|
{
|
|
LeaderboardId = param.m_hSteamLeaderboard;
|
|
BoardFound.Invoke();
|
|
RefreshUserEntry();
|
|
}
|
|
}
|
|
}
|
|
}
|