/// <summary> /// Get and display all gamers' high scores from the given leaderboard. /// </summary> /// <param name="boardName">Name of the board from wich to get the scores.</param> /// <param name="scoresPerPage">Number of scores to get per page.</param> /// <param name="centeredBoard">If the page to show is the one containing the current logged in gamer's score.</param> public static void Handling_DisplayAllHighScores(string boardName, int scoresPerPage, bool centeredBoard) { // A LeaderboardHandler instance should be attached to an active object of the scene to display the result if (!LeaderboardHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "LeaderboardFeatures", "LeaderboardHandler")); } // The board name should not be empty else if (string.IsNullOrEmpty(boardName)) { DebugLogs.LogError("[CotcSdkTemplate:LeaderboardFeatures] The board name is empty ›› Please enter a valid board name"); } // The scores per page amount should be positive else if (scoresPerPage <= 0) { DebugLogs.LogError("[CotcSdkTemplate:LeaderboardFeatures] The scores per page amount is invalid ›› Please enter a number superior to 0"); } else { LeaderboardHandler.Instance.ShowLeaderboardPanel(boardName); // Display only the page in which the logged in gamer's score is on the given leaderboard if (centeredBoard) { Backend_CenteredScore(boardName, scoresPerPage, neverScoredOnLeaderboardErrorMessage, DisplayPagedScores_OnSuccess, DisplayPagedScores_OnError); } // Display the first page of the given leaderboard else { Backend_BestHighScores(boardName, scoresPerPage, 1, emptyLeaderboardErrorMessage, DisplayPagedScores_OnSuccess, DisplayPagedScores_OnError); } } }
/// <summary> /// Send an email to a gamer who has lost its email account's password. /// </summary> /// <param name="toEmailAddress">Email address of the gamer to who the email will be sent.</param> /// <param name="fromEmailAddress">Email address of the company from which the email will be sent.</param> /// <param name="emailTitle">Title of the email to send.</param> /// <param name="emailBody">Body of the email to send. (needs to contain the [[SHORTCODE]] tag)</param> public static void Handling_SendLostPasswordEmail(string toEmailAddress, string fromEmailAddress, string emailTitle, string emailBody) { // The to email address should not be empty if (string.IsNullOrEmpty(toEmailAddress)) { DebugLogs.LogError("[CotcSdkTemplate:AccountFeatures] The to email address is empty ›› Please enter a valid to email address"); } // The from email address should not be empty else if (string.IsNullOrEmpty(fromEmailAddress)) { DebugLogs.LogError("[CotcSdkTemplate:AccountFeatures] The from email address is empty ›› Please enter a valid from email address"); } // The email title should not be empty else if (string.IsNullOrEmpty(emailTitle)) { DebugLogs.LogError("[CotcSdkTemplate:AccountFeatures] The email title is empty ›› Please enter a valid email title"); } // The email body should not be empty else if (string.IsNullOrEmpty(emailBody)) { DebugLogs.LogError("[CotcSdkTemplate:AccountFeatures] The email body is empty ›› Please enter a valid email body"); } else { Backend_SendResetPasswordEmail(toEmailAddress, fromEmailAddress, emailTitle, emailBody, SendResetPasswordEmail_OnSuccess, SendResetPasswordEmail_OnError); } }
/// <summary> /// What to do if any InitializeCloud request failed. /// </summary> /// <param name="exceptionError">Request error details under the ExceptionError format.</param> private static void InitializeCloud_OnError(ExceptionError exceptionError) { switch (exceptionError.type) { // Unhandled error types default: DebugLogs.LogError(string.Format(ExceptionTools.unhandledErrorFormat, "CloudFeatures", exceptionError)); break; } }
/// <summary> /// Login the gamer to its email account with a short code previously received by email. /// </summary> /// <param name="shortCode">Short code received by email to allow login without credentials.</param> public static void Handling_LoginWithShortCode(string shortCode) { // The short code should not be empty if (string.IsNullOrEmpty(shortCode)) { DebugLogs.LogError("[CotcSdkTemplate:LoginFeatures] The short code is empty ›› Please enter a valid short code"); } else { Backend_LoginWithShortCode(shortCode, Login_OnSuccess, Login_OnError); } }
/// <summary> /// Use a referral code to set the current logged in gamer's godfather. /// </summary> /// <param name="referralCode">Godfather's code to use to set the current logged in gamer as its godchild.</param> public static void Handling_UseReferralCode(string referralCode) { // The referral code should not be empty if (string.IsNullOrEmpty(referralCode)) { DebugLogs.LogError("[CotcSdkTemplate:GodfatherFeatures] The referral code is empty ›› Please enter a valid referral code"); } else { Backend_UseCode(referralCode, UseReferralCode_OnSuccess, UseReferralCode_OnError); } }
/// <summary> /// Register the singleton instance at Awake. /// </summary> protected virtual void Awake() { if (instance == null) { instance = this; } else { DebugLogs.LogError("[MonoSingleton:Awake] Found more than one instance of " + this.GetType().Name + " ›› Destroying the last one"); Destroy(this); } }
/// <summary> /// Delete the given key associated to the current logged in gamer. /// </summary> /// <param name="key">Name of the key to delete.</param> public static void Handling_DeleteGamerKey(string key) { // The key name should not be empty if (string.IsNullOrEmpty(key)) { DebugLogs.LogError("[CotcSdkTemplate:GamerVFSFeatures] The key name is empty ›› Please enter a valid key name"); } else { Backend_DeleteValue(key, DeleteGamerKey_OnSuccess, DeleteGamerKey_OnError); } }
/// <summary> /// Get and display the current logged in gamer's godfather. /// </summary> public static void Handling_DisplayGodfather() { // A GodfatherHandler instance should be attached to an active object of the scene to display the result if (!GodfatherHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "GodfatherFeatures", "GodfatherHandler")); } else { GodfatherHandler.Instance.ShowGodfatherPanel("Current Godfather"); Backend_GetGodfather(DisplayGodfather_OnSuccess, DisplayGodfather_OnError); } }
/// <summary> /// Get and display a list of gamers matching with the given match pattern (tested against display name and email). /// </summary> /// <param name="matchPattern">What users' display name or email must contain.</param> /// <param name="usersPerPage">Number of users to get per page.</param> public static void Handling_FindGamers(string matchPattern, int usersPerPage) { // A CommunityHandler instance should be attached to an active object of the scene to display the result if (!CommunityHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "CommunityFeatures", "CommunityHandler")); } else { CommunityHandler.Instance.ShowCommunityPanel("Matching Users List"); Backend_ListUsers(matchPattern, usersPerPage, 0, FindGamers_OnSuccess, FindGamers_OnError); } }
/// <summary> /// Get and display the value of the given key (or all keys if null or empty) associated to the current logged in gamer. /// </summary> /// <param name="key">Name of the key to get.</param> public static void Handling_DisplayGamerKey(string key) { // A VFSHandler instance should be attached to an active object of the scene to display the result if (!VFSHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "GamerVFSFeatures", "VFSHandler")); } else { VFSHandler.Instance.ShowVFSPanel("Gamer VFS Keys"); Backend_GetValue(key, DisplayGamerKey_OnSuccess, DisplayGamerKey_OnError); } }
/// <summary> /// Set the relationship between the current logged in gamer and the given other gamer. /// </summary> /// <param name="gamerID">Identifier of the gamer with who to change the relationship.</param> /// <param name="relationship">Type of relationship to set.</param> /// <param name="notificationJson">Message to send as notification if the target gamer is offline under {"languageCode1":"text1", "languageCode2":"text2", ...} format. (optional)</param> public static void Handling_SetGamerRelationship(string gamerID, FriendRelationshipStatus relationship, string notificationJson = null) { // The gamer ID should not be empty if (string.IsNullOrEmpty(gamerID)) { DebugLogs.LogError("[CotcSdkTemplate:CommunityFeatures] The gamer ID is empty ›› Please enter a valid gamer ID"); } else { PushNotification pushNotification = CotcConverter.GetPushNotificationFromJson(notificationJson); Backend_ChangeRelationshipStatus(gamerID, relationship, SetGamerRelationship_OnSuccess, SetGamerRelationship_OnError, pushNotification); } }
/// <summary> /// When a "BackOffice message" event is received, display it on the event handler. /// </summary> /// <param name="eventData">Event details under the expected format {"type":"...","event":{"message":"..."}}.</param> private static void OnBackOfficeMessage(Bundle eventData) { // An EventHandler instance should be attached to an active object of the scene to display the result if (!EventHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "EventFeatures", "EventHandler")); } else { string backOfficeMessage = eventData["event"]["message"].AsString(); EventHandler.Instance.BuildAndAddEventItem_BackOfficeMessage(backOfficeMessage); } }
/// <summary> /// When a "new godchild" event is received, display it on the event handler. /// </summary> /// <param name="eventData">Event details under the expected format {"type":"...","event":{"godchildren":{"gamer_id":"...","profile":{...}}}}.</param> private static void OnNewGodchild(Bundle eventData) { // An EventHandler instance should be attached to an active object of the scene to display the result if (!EventHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "EventFeatures", "EventHandler")); } else { Bundle godchildProfile = eventData["event"]["godchildren"]["profile"]; EventHandler.Instance.BuildAndAddEventItem_NewGodchild("You've got a new godchild!", godchildProfile); } }
/// <summary> /// Get and display the list of current logged in gamer's friends. /// </summary> public static void Handling_DisplayFriends() { // A CommunityHandler instance should be attached to an active object of the scene to display the result if (!CommunityHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "CommunityFeatures", "CommunityHandler")); } else { CommunityHandler.Instance.ShowCommunityPanel("Friends List"); Backend_ListFriends(DisplayFriends_OnSuccess, DisplayFriends_OnError, false); } }
/// <summary> /// Get and display the current logged in gamer's best scores from all leaderboards in which he scored at least once. /// </summary> public static void Handling_DisplayGamerHighScores() { // A LeaderboardHandler instance should be attached to an active object of the scene to display the result if (!LeaderboardHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "LeaderboardFeatures", "LeaderboardHandler")); } else { LeaderboardHandler.Instance.ShowLeaderboardPanel(LoginFeatures.gamer["profile"]["displayName"].AsString()); Backend_ListUserBestScores(neverScoredErrorMessage, DisplayGamerHighScores_OnSuccess, DisplayGamerHighScores_OnError); } }
/// <summary> /// Get and display logged in gamer's progress on all game's achievements. /// </summary> public static void Handling_DisplayAchievements() { // An AchievementHandler instance should be attached to an active object of the scene to display the result if (!AchievementHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "AchievementFeatures", "AchievementHandler")); } else { AchievementHandler.Instance.ShowAchievementPanel("Achievements Progress"); Backend_ListAchievements(DisplayAchievements_OnSuccess, DisplayAchievements_OnError); } }
/// <summary> /// Get and display the current logged in gamer's history of the given currency (or all currencies if null or empty). /// </summary> /// <param name="currencyName">Name of the currency to get.</param> /// <param name="transactionsPerPage">Number of transactions to get per page.</param> public static void Handling_DisplayCurrencyHistory(string currencyName, int transactionsPerPage) { // A TransactionHandler instance should be attached to an active object of the scene to display the result if (!TransactionHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "TransactionFeatures", "TransactionHandler")); } else { TransactionHandler.Instance.ShowTransactionPanel("Transactions History"); Backend_History(currencyName, transactionsPerPage, 0, DisplayCurrencyHistory_OnSuccess, DisplayCurrencyHistory_OnError); } }
/// <summary> /// Get and display the current logged in gamer currencies balance. /// </summary> public static void Handling_DisplayBalance() { // A TransactionHandler instance should be attached to an active object of the scene to display the result if (!TransactionHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "TransactionFeatures", "TransactionHandler")); } else { TransactionHandler.Instance.ShowTransactionPanel("Currencies Balance"); Backend_Balance(DisplayBalance_OnSuccess, DisplayBalance_OnError); } }
/// <summary> /// Stop the events loop to retrieve server pending events. A stopped events loop shouldn't be started again. /// </summary> public static void Handling_StopEventsListening() { // Stop the events loop if (eventLoop != null) { eventLoop.Stop(); eventLoop = null; if (verboseEventLoop) { DebugLogs.LogVerbose("[CotcSdkTemplate:EventFeatures] Unregistered from gamer's events loop"); } } }
/// <summary> /// When a "friend's relationship changed" event is received, display it on the event handler. /// </summary> /// <param name="eventData">Event details under the expected format {"type":"...","message":"...","friendProfile":{...}}.</param> /// <param name="relationship">Type of relationship which has been set.</param> private static void OnFriendRelationshipChanged(Bundle eventData, FriendRelationshipStatus relationship) { // An EventHandler instance should be attached to an active object of the scene to display the result if (!EventHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "EventFeatures", "EventHandler")); } else { string message = eventData["message"].AsString(); Bundle friendProfile = Bundle.FromJson(eventData["friendProfile"]); EventHandler.Instance.BuildAndAddEventItem_FriendRelationshipChanged(message, friendProfile, relationship); } }
/// <summary> /// Start the events loop to retrieve server pending events as soon as possible. /// </summary> /// <param name="loggedInGamer">The logged in gamer's instance.</param> /// <param name="verbose">If the events loop registering / unregistering and the received events should be logged into the console.</param> public static void Handling_StartEventsListening(Gamer loggedInGamer, bool verbose = true) { // Start the events loop from the currently logged in gamer then register a received event callback eventLoop = loggedInGamer.StartEventLoop(); eventLoop.ReceivedEvent += OnEventReceived; // Set if the events handling should be verbose verboseEventLoop = verbose; if (verboseEventLoop) { DebugLogs.LogVerbose("[CotcSdkTemplate:EventFeatures] Registered to gamer's events loop"); } }
/// <summary> /// Retry failed HTTP requests once. /// </summary> /// <param name="httpRequestFailedEventArgs">The exception event details.</param> private static void RetryFailedRequestOnce(HttpRequestFailedEventArgs httpRequestFailedEventArgs) { if (httpRequestFailedEventArgs.UserData == null) { DebugLogs.LogWarning(string.Format("[CotcSdkTemplate:CloudFeatures] HTTP request failed ›› Retry in {0}ms ({1})", httpRequestRetryDelay, httpRequestFailedEventArgs.Url)); httpRequestFailedEventArgs.UserData = new object(); httpRequestFailedEventArgs.RetryIn(httpRequestRetryDelay); } else { DebugLogs.LogError(string.Format("[CotcSdkTemplate:CloudFeatures] HTTP request failed ›› Abort ({0})", httpRequestFailedEventArgs.Url)); httpRequestFailedEventArgs.Abort(); } }
/// <summary> /// Check if the CotcSdk's Cloud instance is initialized. /// </summary> /// <param name="verbose">If the check should log in case of error.</param> public static bool IsCloudInitialized(bool verbose = true) { if (cloud == null) { if (verbose) { DebugLogs.LogError("[CotcSdkTemplate:CloudFeatures] Cloud is not initialized ›› Please call CloudFeatures.InitializeCloud() first (CotcSdk features are not available otherwise)"); } return(false); } return(true); }
/// <summary> /// What to do if any DisplayGamerKey request succeeded. /// </summary> /// <param name="keysValues">List of keys and their values under the Bundle format.</param> private static void DisplayGamerKey_OnSuccess(Bundle keysValues) { string resultField = "result"; // TODO: You may want to parse the result Bundle fields (e.g.: if (keyValue["result"]["TestString"].Type == Bundle.DataType.String) { string testString = keyValue["result"]["TestString"].AsString(); }) if (!keysValues.Has(resultField)) { DebugLogs.LogError(string.Format("[CotcSdkTemplate:GamerVFSFeatures] No {0} field found in the key value result", resultField)); } else { VFSHandler.Instance.FillVFSPanel(keysValues[resultField].AsDictionary()); } }
/// <summary> /// What to do if any SetGamerRelationship request failed. /// </summary> /// <param name="exceptionError">Request error details under the ExceptionError format.</param> /// <param name="gamerID">Identifier of the gamer with who to change the relationship.</param> /// <param name="relationship">Type of relationship to set.</param> private static void SetGamerRelationship_OnError(ExceptionError exceptionError, string gamerID, FriendRelationshipStatus relationship) { switch (exceptionError.type) { // Error type: not initialized Cloud or no logged in gamer case ExceptionTools.notLoggedInErrorType: // Do whatever... break; // Unhandled error types default: DebugLogs.LogError(string.Format(ExceptionTools.unhandledErrorFormat, "CommunityFeatures", exceptionError)); break; } }
/// <summary> /// What to do if any PostTransaction request failed. /// </summary> /// <param name="exceptionError">Request error details under the ExceptionError format.</param> private static void PostTransaction_OnError(ExceptionError exceptionError) { switch (exceptionError.type) { // Error type: not initialized Cloud or no logged in gamer case ExceptionTools.notLoggedInErrorType: // Do whatever... break; // Unhandled error types default: DebugLogs.LogError(string.Format(ExceptionTools.unhandledErrorFormat, "TransactionFeatures", exceptionError)); break; } }
/// <summary> /// What to do if any SendResetPasswordEmail request failed. /// </summary> /// <param name="exceptionError">Request error details under the ExceptionError format.</param> private static void SendResetPasswordEmail_OnError(ExceptionError exceptionError) { switch (exceptionError.type) { // Error type: not initialized Cloud case ExceptionTools.notInitializedCloudErrorType: // Do whatever... break; // Unhandled error types default: DebugLogs.LogError(string.Format(ExceptionTools.unhandledErrorFormat, "AccountFeatures", exceptionError)); break; } }
/// <summary> /// Login the gamer on a given network with specific credentials. (create a new account if it doesn't exist yet) /// </summary> /// <param name="network">Name of the network to use (lowercase from the LoginNetwork enum).</param> /// <param name="accountID">Identifier (email, ID, ...) of the gamer's account.</param> /// <param name="accountSecret">Secret (password, token, ...) of the gamer's account.</param> /// <param name="OnSuccess">The callback in case of request success.</param> /// <param name="OnError">The callback in case of request error.</param> public static void Backend_Login(string network, string accountID, string accountSecret, Action <Gamer> OnSuccess = null, Action <ExceptionError> OnError = null) { DebugLogs.LogVerbose(string.Format("void Backend_Login : {0} {1} {2}", network, accountID, accountSecret)); // Need an initialized Cloud to proceed if (!CloudFeatures.IsCloudInitialized()) { OnError(ExceptionTools.GetExceptionError(new CotcException(ErrorCode.NotSetup), ExceptionTools.notInitializedCloudErrorType)); return; } // Call the API method which returns a Gamer result CloudFeatures.cloud.Login(network, accountID, accountSecret) // Result if everything went well .Done(delegate(Gamer loggedInGamer) { DebugLogs.LogVerbose(string.Format("[CotcSdkTemplate:LoginFeatures] Login success ›› Logged In Gamer: {0}", loggedInGamer)); // Keep the Gamer's reference gamer = loggedInGamer; // Call the OnSuccess action if any callback registered to it if (OnSuccess != null) { OnSuccess(loggedInGamer); } // Call the GamerLoggedIn event if any callback registered to it if (Event_GamerLoggedIn != null) { Event_GamerLoggedIn(gamer); } }, // Result if an error occured delegate(Exception exception) { // Call the OnError action if any callback registered to it if (OnError != null) { OnError(ExceptionTools.GetExceptionError(exception)); } // Else, log the error (expected to be a CotcException) else { ExceptionTools.LogCotcException("LoginFeatures", "Login", exception); } }); }
/// <summary> /// What to do if any PostTransaction request succeeded. /// </summary> /// <param name="postedTransaction">Posted transaction details.</param> private static void PostTransaction_OnSuccess(TransactionResult postedTransaction) { // An EventHandler instance should be attached to an active object of the scene to display the result if (!EventHandler.HasInstance) { DebugLogs.LogError(string.Format(ExceptionTools.noInstanceErrorFormat, "TransactionFeatures", "EventHandler")); } // For each achievement unlocked by the transaction post, display it as if it was an event else { foreach (KeyValuePair <string, AchievementDefinition> triggeredAchievement in postedTransaction.TriggeredAchievements) { EventHandler.Instance.BuildAndAddEventItem_AchievementUnlocked("An achievement has been unlocked!", triggeredAchievement.Value); } } }
/// <summary> /// What to do if any DisplayCurrencyHistory request failed. /// </summary> /// <param name="exceptionError">Request error details under the ExceptionError format.</param> private static void DisplayCurrencyHistory_OnError(ExceptionError exceptionError) { switch (exceptionError.type) { // Error type: not initialized Cloud or no logged in gamer case ExceptionTools.notLoggedInErrorType: TransactionHandler.Instance.ShowError(ExceptionTools.notLoggedInMessage); break; // Unhandled error types default: DebugLogs.LogError(string.Format(ExceptionTools.unhandledErrorFormat, "TransactionFeatures", exceptionError)); TransactionHandler.Instance.ShowError(ExceptionTools.unhandledErrorMessage); break; } }