namespace Oculus.Platform.Samples.VrHoops { using UnityEngine; using System.Collections.Generic; using Oculus.Platform; using Oculus.Platform.Models; // Coordinates updating leaderboard scores and polling for leaderboard updates. public class LeaderboardManager { // API NAME for the leaderboard where we store how many matches the user has won private const string MOST_MATCHES_WON = "MOST_MATCHES_WON"; // API NAME for the leaderboard where we store the user's match score private const string HIGHEST_MATCH_SCORE = "HIGHEST_MATCH_SCORE"; // the top number of entries to query private const int TOP_N_COUNT = 5; // how often to poll the service for leaderboard updates private const float LEADERBOARD_POLL_FREQ = 30.0f; // the next time to check for leaderboard updates private float m_nextCheckTime; // cache to hold most-wins leaderboard entries as they come in private volatile SortedDictionary m_mostWins; // whether we've found the local user's entry yet private bool m_foundLocalUserMostWinsEntry; // number of times the local user has won private long m_numWins; // callback to deliver the most-wins leaderboard entries private OnMostWinsLeaderboardUpdated m_mostWinsCallback; // cache to hold high-score leaderboard entries as they come in private volatile SortedDictionary m_highScores; // whether we've found the local user's entry yet private bool m_foundLocalUserHighScore; // callback to deliver the high-scores leaderboard entries private OnHighScoreLeaderboardUpdated m_highScoreCallback; public void CheckForUpdates() { if (Time.time >= m_nextCheckTime && PlatformManager.CurrentState == PlatformManager.State.WAITING_TO_PRACTICE_OR_MATCHMAKE) { m_nextCheckTime = Time.time + LEADERBOARD_POLL_FREQ; QueryMostWinsLeaderboard(); QueryHighScoreLeaderboard(); } } #region Most Wins Leaderboard public delegate void OnMostWinsLeaderboardUpdated(SortedDictionary entries); public OnMostWinsLeaderboardUpdated MostWinsLeaderboardUpdatedCallback { set { m_mostWinsCallback = value; } } void QueryMostWinsLeaderboard() { // if a query is already in progress, don't start a new one. if (m_mostWins != null) return; m_mostWins = new SortedDictionary(); m_foundLocalUserMostWinsEntry = false; Leaderboards.GetEntries(MOST_MATCHES_WON, TOP_N_COUNT, LeaderboardFilterType.None, LeaderboardStartAt.Top).OnComplete(MostWinsGetEntriesCallback); } void MostWinsGetEntriesCallback(Message msg) { if (!msg.IsError) { foreach (LeaderboardEntry entry in msg.Data) { m_mostWins[entry.Rank] = entry; if (entry.User.ID == PlatformManager.MyID) { m_foundLocalUserMostWinsEntry = true; m_numWins = entry.Score; } } // results might be paged for large requests if (msg.Data.HasNextPage) { Leaderboards.GetNextEntries(msg.Data).OnComplete(MostWinsGetEntriesCallback); return; } // if local user not in the top, get their position specifically if (!m_foundLocalUserMostWinsEntry) { Leaderboards.GetEntries(MOST_MATCHES_WON, 1, LeaderboardFilterType.None, LeaderboardStartAt.CenteredOnViewer).OnComplete(MostWinsGetEntriesCallback); return; } } // else an error is returned if the local player isn't ranked - we can ignore that if (m_mostWinsCallback != null) { m_mostWinsCallback(m_mostWins); } m_mostWins = null; } #endregion #region Highest Score Board public delegate void OnHighScoreLeaderboardUpdated(SortedDictionary entries); public OnHighScoreLeaderboardUpdated HighScoreLeaderboardUpdatedCallback { set { m_highScoreCallback = value; } } void QueryHighScoreLeaderboard() { // if a query is already in progress, don't start a new one. if (m_highScores != null) return; m_highScores = new SortedDictionary(); m_foundLocalUserHighScore = false; Leaderboards.GetEntries(HIGHEST_MATCH_SCORE, TOP_N_COUNT, LeaderboardFilterType.None, LeaderboardStartAt.Top).OnComplete(HighestScoreGetEntriesCallback); } void HighestScoreGetEntriesCallback(Message msg) { if (!msg.IsError) { foreach (LeaderboardEntry entry in msg.Data) { m_highScores[entry.Rank] = entry; if (entry.User.ID == PlatformManager.MyID) { m_foundLocalUserHighScore = true; } } // results might be paged for large requests if (msg.Data.HasNextPage) { Leaderboards.GetNextEntries(msg.Data).OnComplete(HighestScoreGetEntriesCallback);; return; } // if local user not in the top, get their position specifically if (!m_foundLocalUserHighScore) { Leaderboards.GetEntries(HIGHEST_MATCH_SCORE, 1, LeaderboardFilterType.None, LeaderboardStartAt.CenteredOnViewer).OnComplete(HighestScoreGetEntriesCallback); return; } } // else an error is returned if the local player isn't ranked - we can ignore that if (m_highScoreCallback != null) { m_highScoreCallback(m_highScores); } m_highScores = null; } #endregion // submit the local player's match score to the leaderboard service public void SubmitMatchScores(bool wonMatch, uint score) { if (wonMatch) { m_numWins += 1; Leaderboards.WriteEntry(MOST_MATCHES_WON, m_numWins); } if (score > 0) { Leaderboards.WriteEntry(HIGHEST_MATCH_SCORE, score); } } } }