diff --git a/Assets/Tests/API/XsollaAuthTests/XsollaAuthAccountLinkingTests.cs b/Assets/Tests/API/XsollaAuthTests/XsollaAuthAccountLinkingTests.cs deleted file mode 100644 index c401d8478..000000000 --- a/Assets/Tests/API/XsollaAuthTests/XsollaAuthAccountLinkingTests.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Collections; -using System.Runtime.CompilerServices; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Auth; -using System.Collections.Generic; -using NUnit.Framework; - -namespace Xsolla.Tests -{ - public class XsollaAuthAccountLinkingTests - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [UnityTest] - public IEnumerator SignInConsoleAccount_nintendo_shop_Success() - { - yield return SignInConsoleAccount(platform:"nintendo_shop"); - } - - [UnityTest] - public IEnumerator SignInConsoleAccount_xbox_live_Success() - { - yield return SignInConsoleAccount(platform:"xbox_live"); - } - - private IEnumerator SignInConsoleAccount([CallerMemberName]string testName = null, string platform = "") - { - yield return TestSignInHelper.Instance.SignOut(); - - var currentTime = DateTime.Now.ToString(); - var digits = new List(); - foreach (var symbol in currentTime) - { - if (char.IsDigit(symbol)) - digits.Add(symbol); - } - var testAccount = $"TestAcc{new string(digits.ToArray())}"; - - UnityEngine.Debug.Log($"Console test account: {testAccount}"); - - bool? success = default; - string consoleToken = default; - string errorMessage = default; - - XsollaAuth.Instance.SignInConsoleAccount( - userId: testAccount, - platform: platform, - successCase: token => - { - consoleToken = token; - success = true; - }, - failedCase: error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value && !string.IsNullOrEmpty(consoleToken)) - TestHelper.Pass(consoleToken, testName); - else - TestHelper.Fail(errorMessage, testName); - } - } -} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaAuthTests/XsollaAuthOAuthRefreshTokenTests.cs b/Assets/Tests/API/XsollaAuthTests/XsollaAuthOAuthRefreshTokenTests.cs deleted file mode 100644 index a0b822327..000000000 --- a/Assets/Tests/API/XsollaAuthTests/XsollaAuthOAuthRefreshTokenTests.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System.Collections; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Core; -using Xsolla.Auth; -using NUnit.Framework; - -namespace Xsolla.Tests -{ - public class XsollaAuthOAuthRefreshTokenTests - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [UnityTest] - public IEnumerator RefreshOAuthToken_TokenChanged() - { - yield return TestSignInHelper.Instance.GenerateNewSession(); - - string prevToken = Token.Instance; - bool? success = default; - string errorMessage = default; - - XsollaAuth.Instance.RefreshOAuthToken( - onSuccess: _ => - { - success = true; - }, - onError: error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.CheckTokenChanged(oldToken: prevToken); - else - TestHelper.Fail(errorMessage); - } - - [UnityTest] - public IEnumerator RefreshOAuthToken_OldRefreshToken_Failure() - { - yield return TestSignInHelper.Instance.GenerateNewSession(); - - bool? success = default; - string errorMessage = default; - var errorType = ErrorType.Undefined; - - var oldToken = "W0qQwxh5rJe4wK3VREv1qsGnxUKQfZNvJkYJq7lMPCA.6HeK7wKy1cZAy2STRk8sTcplcA7TiglrT5K3kn-lClc"; - - XsollaAuth.Instance.RefreshOAuthToken( - refreshToken: oldToken, - onSuccess: _ => - { - success = true; - }, - onError: error => - { - errorType = error?.ErrorType ?? ErrorType.Undefined; - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Fail(additionalInfo: "Expected call to fail"); - else if (errorType != ErrorType.InvalidToken) - TestHelper.Fail(additionalInfo: $"Unexpected error type: {errorType}"); - else - TestHelper.Pass(additionalInfo: errorMessage); - } - } -} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaAuthTests/XsollaAuthSocialTests.cs b/Assets/Tests/API/XsollaAuthTests/XsollaAuthSocialTests.cs deleted file mode 100644 index 0f308584c..000000000 --- a/Assets/Tests/API/XsollaAuthTests/XsollaAuthSocialTests.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Auth; -using Xsolla.Core; - -namespace Xsolla.Tests -{ - public class XsollaAuthSocialTests - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [Test] - public void GetSocialNetworkAuthUrl_Success() - { - var testName = nameof(GetSocialNetworkAuthUrl_Success); - var url = XsollaAuth.Instance.GetSocialNetworkAuthUrl(providerName: SocialProvider.Facebook); - if (!string.IsNullOrEmpty(url)) - TestHelper.Pass($"auth URL: {url}",testName); - else - TestHelper.Fail("auth URL is NULL",testName); - } - - [UnityTest] - public IEnumerator GetLinksForSocialAuth_NoLocale_Success() - { - yield return GetLinksForSocialAuth(locale: null); - } - - [UnityTest] - public IEnumerator GetLinksForSocialAuth_deDE_Locale_Success() - { - yield return GetLinksForSocialAuth(locale: "de_DE"); - } - - [UnityTest] - public IEnumerator GetLinksForSocialAuth_InvalidToken_SuccessAndTokenRefreshed() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return GetLinksForSocialAuth(locale: null); - TestHelper.CheckTokenChanged(); - } - - private IEnumerator GetLinksForSocialAuth([CallerMemberName] string testName = null, string locale = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action> onSuccess = links => - { - if (links != null) - success = true; - else - { - success = false; - errorMessage = "LINKS ARE NULL"; - } - }; - - Action onError = error => - { - success = false; - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - }; - - XsollaAuth.Instance.GetLinksForSocialAuth(locale, onSuccess, onError); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - } -} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaAuthTests/XsollaAuthUserTests.cs b/Assets/Tests/API/XsollaAuthTests/XsollaAuthUserTests.cs deleted file mode 100644 index 00bef31d4..000000000 --- a/Assets/Tests/API/XsollaAuthTests/XsollaAuthUserTests.cs +++ /dev/null @@ -1,274 +0,0 @@ -using System.Collections; -using System.Runtime.CompilerServices; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Auth; -using Xsolla.Core; - -namespace Xsolla.Tests -{ - public class XsollaAuthUserTests - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [UnityTest] - public IEnumerator SignIn_OAuth_Success() - { - yield return SignIn(); - } - - [UnityTest] - public IEnumerator SignIn_OAuth_IncorrectData_Failure() - { - yield return SignIn(login:"k4TCNgHs", password:"k4TCNgHs", isSuccessExpected: false); - } - - private IEnumerator SignIn([CallerMemberName] string testName = null, string login = "xsolla", string password = "xsolla", bool isSuccessExpected = true) - { - TestSignInHelper.SignInResult signInResult = null; - - yield return TestSignInHelper.Instance.SignIn(login, password, result => signInResult = result); - yield return new WaitUntil(() => signInResult != null); - - if (signInResult.success == isSuccessExpected) - TestHelper.Pass(signInResult,testName); - else - TestHelper.Fail(signInResult,testName); - } - - [UnityTest] - public IEnumerator GetUserInfo_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = null; - Error getInfoError = null; - - XsollaAuth.Instance.GetUserInfo( - token: Token.Instance, - onSuccess: userInfo => success = userInfo != null, - onError: error => - { - success = false; - getInfoError = error; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(); - else - TestHelper.Fail(getInfoError); - } - - //There is a limit for this request, so test only one arguments combination - high risk of request error because of backend rules - [UnityTest] - public IEnumerator StartAuthByPhoneNumber_Success() - { - bool? success = null; - string operationID = null; - Error startAuthError = null; - - XsollaAuth.Instance.StartAuthByPhoneNumber( - phoneNumber: "+79008007060", - linkUrl: null, - sendLink: false, - onSuccess: opID => - { - operationID = opID; - success = true; - }, - onError: error => - { - startAuthError = error; - success = false; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(additionalInfo: operationID); - else - TestHelper.Fail(error: startAuthError); - } - - [UnityTest] - public IEnumerator OAuthLogout_Sso_Success() - { - yield return OAuthLogout(logoutType: OAuthLogoutType.Sso); - } - - [UnityTest] - public IEnumerator OAuthLogout_All_Success() - { - yield return OAuthLogout(logoutType: OAuthLogoutType.All); - } - - private IEnumerator OAuthLogout([CallerMemberName]string testName = null, OAuthLogoutType logoutType = OAuthLogoutType.All) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = null; - Error getInfoError = null; - - XsollaAuth.Instance.OAuthLogout( - token: Token.Instance, - sessions: logoutType, - onSuccess: () => success = true, - onError: error => - { - success = false; - getInfoError = error; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - { - TestHelper.Pass(testName); - Token.Instance = null; - } - else - TestHelper.Fail(getInfoError, testName); - } - - [UnityTest] - public IEnumerator ResetPassword_DefaultValues_Success() - { - yield return ResetPassword(); - } - - [UnityTest] - public IEnumerator ResetPassword_de_DE_Locale_Success() - { - yield return ResetPassword(locale:"de_DE"); - } - - private IEnumerator ResetPassword([CallerMemberName]string testName = null, string redirectUri = null, string locale = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - string userEmail = null; - Error getInfoError = null; - bool busy = true; - - XsollaAuth.Instance.GetUserInfo( - token: Token.Instance, - onSuccess: userInfo => - { - userEmail = userInfo?.email; - busy = false; - }, - onError: error => - { - getInfoError = error; - busy = false; - }); - - yield return new WaitWhile(() => busy); - if (getInfoError != null) - { - TestHelper.Fail(getInfoError, testName); - yield break; - } - if (userEmail == null) - { - TestHelper.Fail("UserEmail is NULL", testName); - yield break; - } - - bool? success = null; - Error resetPasswordError = null; - - XsollaAuth.Instance.ResetPassword( - email: userEmail, - redirectUri: redirectUri, - locale: locale, - onSuccess: () => success = true, - onError: error => - { - resetPasswordError = error; - success = false; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(); - else - TestHelper.Fail(error: resetPasswordError); - } - - [UnityTest] - public IEnumerator ResendConfirmationLink_DefaultValues_Success() - { - yield return ResendConfirmationLink(); - } - - [UnityTest] - public IEnumerator ResendConfirmationLink_de_DE_Locale_Success() - { - yield return ResendConfirmationLink(locale:"de_DE"); - } - - private IEnumerator ResendConfirmationLink([CallerMemberName]string testName = null, string redirectUri = null, string state = null, string payload = null, string locale = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - string userEmail = null; - Error getInfoError = null; - bool busy = true; - - XsollaAuth.Instance.GetUserInfo( - token: Token.Instance, - onSuccess: userInfo => - { - userEmail = userInfo?.email; - busy = false; - }, - onError: error => - { - getInfoError = error; - busy = false; - }); - - yield return new WaitWhile(() => busy); - if (getInfoError != null) - { - TestHelper.Fail(getInfoError, testName); - yield break; - } - if (userEmail == null) - { - TestHelper.Fail("UserEmail is NULL", testName); - yield break; - } - - bool? success = null; - Error resendLinkError = null; - - XsollaAuth.Instance.ResendConfirmationLink( - username: userEmail, - redirectUri: redirectUri, - state: state, - payload: payload, - locale: locale, - onSuccess: () => success = true, - onError: error => - { - resendLinkError = error; - success = false; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(); - else - TestHelper.Fail(error: resendLinkError); - } - } -} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaCartTests/XsollaCartTests.cs b/Assets/Tests/API/XsollaCartTests/XsollaCartTests.cs deleted file mode 100644 index a4a915b4b..000000000 --- a/Assets/Tests/API/XsollaCartTests/XsollaCartTests.cs +++ /dev/null @@ -1,764 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Runtime.CompilerServices; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Cart; -using Xsolla.Core; - -namespace Xsolla.Tests -{ - public class XsollaCartTests - { - private Cart.Cart _currentCart; - - [OneTimeSetUp] - public void Clear() => TestHelper.Clear(); - - [OneTimeTearDown] - public void OneTimeTearDown() - { - TestHelper.Clear(); - _currentCart = null; - } - - private IEnumerator PrepareCurrentCart([CallerMemberName]string testName = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - if (_currentCart != null) - yield break; - - bool busy = true; - Error cartGetError = null; - - Action onSuccess = cart => - { - _currentCart = cart; - busy = false; - }; - - Action onError = error => - { - cartGetError = error; - busy = false; - }; - - XsollaCart.Instance.GetCartItems( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - - yield return new WaitUntil(() => !busy); - - if (cartGetError != null) - TestHelper.Fail(cartGetError, $"PrepareCurrentCart for {testName}"); - } - - [UnityTest] - public IEnumerator GetCartItems_DefaultValues_Success() - { - yield return GetCartItems(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetCartItems_Parametrized_Success() - { - yield return GetCartItems(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetCartItems_DefaultValues_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return GetCartItems(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetCartItems_DefaultValues_CartID_Success() - { - yield return PrepareCurrentCart(); - yield return GetCartItems(defaultValues: true, cartID: _currentCart.cart_id); - } - - [UnityTest] - public IEnumerator GetCartItems_Parametrized_CartID_Success() - { - yield return PrepareCurrentCart(); - yield return GetCartItems(defaultValues: false, cartID: _currentCart.cart_id); - } - - [UnityTest] - public IEnumerator GetCartItems_DefaultValues_CartID_InvalidToken_Success() - { - yield return PrepareCurrentCart(); - yield return TestSignInHelper.Instance.SetOldToken(); - yield return GetCartItems(defaultValues: true, cartID: _currentCart.cart_id); - } - - private IEnumerator GetCartItems([CallerMemberName]string testName = null, string cartID = null, bool defaultValues = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (cartID == null && defaultValues) - { - XsollaCart.Instance.GetCartItems( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else if (cartID == null && !defaultValues) - { - XsollaCart.Instance.GetCartItems( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - locale: "de", - currency: "USD"); - } - else if (cartID != null && defaultValues) - { - XsollaCart.Instance.GetCartItems( - projectId: XsollaSettings.StoreProjectId, - cartId: cartID, - onSuccess: onSuccess, - onError: onError); - } - else/*if (cartID != null && !defaultValues)*/ - { - XsollaCart.Instance.GetCartItems( - projectId: XsollaSettings.StoreProjectId, - cartId: cartID, - onSuccess: onSuccess, - onError: onError, - locale: "de", - currency: "USD"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator FillCart_NoCartId_Success() - { - yield return FillCart(fillItems: new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}); - } - - [UnityTest] - public IEnumerator FillCart_NoCartId_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}); - } - - [UnityTest] - public IEnumerator FillCart_CartId_Success() - { - yield return PrepareCurrentCart(); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}, cartID: _currentCart.cart_id); - } - - [UnityTest] - public IEnumerator FillCart_CartId_InvalidToken_Success() - { - yield return PrepareCurrentCart(); - yield return TestSignInHelper.Instance.SetOldToken(); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}, cartID: _currentCart.cart_id); - } - - private IEnumerator FillCart([CallerMemberName]string testName = null, List fillItems = null, string cartID = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = () => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (cartID == null) - { - XsollaCart.Instance.FillCart( - projectId: XsollaSettings.StoreProjectId, - items: fillItems, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCart.Instance.FillCart( - projectId: XsollaSettings.StoreProjectId, - items: fillItems, - cartId: cartID, - onSuccess: onSuccess, - onError: onError); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator UpdateItemInCart_NoCartId_Success() - { - yield return UpdateItemInCart(); - } - - [UnityTest] - public IEnumerator UpdateItemInCart_NoCartId_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return UpdateItemInCart(); - } - - [UnityTest] - public IEnumerator UpdateItemInCart_CartId_Success() - { - yield return PrepareCurrentCart(); - yield return UpdateItemInCart(cartID: _currentCart.cart_id); - } - - [UnityTest] - public IEnumerator UpdateItemInCart_CartId_InvalidToken_Success() - { - yield return PrepareCurrentCart(); - yield return TestSignInHelper.Instance.SetOldToken(); - yield return UpdateItemInCart(cartID: _currentCart.cart_id); - } - - private IEnumerator UpdateItemInCart([CallerMemberName]string testName = null, string cartID = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = () => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (cartID == null) - { - XsollaCart.Instance.UpdateItemInCart( - projectId: XsollaSettings.StoreProjectId, - itemSku: "lootbox_1", - quantity: 1, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCart.Instance.UpdateItemInCart( - projectId: XsollaSettings.StoreProjectId, - itemSku: "lootbox_1", - quantity: 1, - cartId: cartID, - onSuccess: onSuccess, - onError: onError); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator RemoveItemFromCart_NoCartId_Success() - { - yield return RemoveItemFromCart(); - } - - [UnityTest] - public IEnumerator RemoveItemFromCart_NoCartId_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return RemoveItemFromCart(); - } - - [UnityTest] - public IEnumerator RemoveItemFromCart_CartId_Success() - { - yield return PrepareCurrentCart(); - yield return RemoveItemFromCart(cartID: _currentCart.cart_id); - } - - [UnityTest] - public IEnumerator RemoveItemFromCart_CartId_InvalidToken_Success() - { - yield return PrepareCurrentCart(); - yield return TestSignInHelper.Instance.SetOldToken(); - yield return RemoveItemFromCart(cartID: _currentCart.cart_id); - } - - private IEnumerator RemoveItemFromCart([CallerMemberName]string testName = null, string cartID = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = () => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (cartID == null) - { - XsollaCart.Instance.RemoveItemFromCart( - projectId: XsollaSettings.StoreProjectId, - itemSku: "lootbox_1", - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCart.Instance.RemoveItemFromCart( - projectId: XsollaSettings.StoreProjectId, - itemSku: "lootbox_1", - cartId: cartID, - onSuccess: onSuccess, - onError: onError); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator ClearCart_NoCartId_Success() - { - yield return ClearCart(); - } - - [UnityTest] - public IEnumerator ClearCart_NoCartId_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return ClearCart(); - } - - [UnityTest] - public IEnumerator ClearCart_CartId_Success() - { - yield return PrepareCurrentCart(); - yield return ClearCart(cartID: _currentCart.cart_id); - } - - [UnityTest] - public IEnumerator ClearCart_CartId_InvalidToken_Success() - { - yield return PrepareCurrentCart(); - yield return TestSignInHelper.Instance.SetOldToken(); - yield return ClearCart(cartID: _currentCart.cart_id); - } - - private IEnumerator ClearCart([CallerMemberName]string testName = null, string cartID = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = () => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (cartID == null) - { - XsollaCart.Instance.ClearCart( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCart.Instance.ClearCart( - projectId: XsollaSettings.StoreProjectId, - cartId: cartID, - onSuccess: onSuccess, - onError: onError); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator RedeemPromocode_Success() - { - yield return PrepareCurrentCart(); - yield return RedeemPromocode(); - } - - [UnityTest] - public IEnumerator RedeemPromocode_InvalidToken_Success() - { - yield return PrepareCurrentCart(); - yield return TestSignInHelper.Instance.SetOldToken(); - yield return RedeemPromocode(); - } - - private IEnumerator RedeemPromocode([CallerMemberName]string testName = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = _ => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - XsollaCart.Instance.RedeemPromocode( - projectId: XsollaSettings.StoreProjectId, - promocode: "NEWGAMER2020", - cartId: _currentCart.cart_id, - onSuccess: onSuccess, - onError: onError); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - // [UnityTest] - // public IEnumerator GetPromocodeReward_Success() - // { - // yield return GetPromocodeReward(); - // } - - // [UnityTest] - // public IEnumerator GetPromocodeReward_InvalidToken_Success() - // { - // yield return TestSignInHelper.Instance.SetOldToken(); - // yield return GetPromocodeReward(); - // } - - private IEnumerator GetPromocodeReward([CallerMemberName]string testName = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = _ => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - XsollaCart.Instance.GetPromocodeReward( - projectId: XsollaSettings.StoreProjectId, - promocode: "NEWGAMER2020", - onSuccess: onSuccess, - onError: onError); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - // [UnityTest] - // public IEnumerator RemovePromocodeFromCart_Success() - // { - // yield return PrepareCurrentCart(); - // yield return RemovePromocodeFromCart(); - // } - - // [UnityTest] - // public IEnumerator RemovePromocodeFromCart_InvalidToken_Success() - // { - // yield return PrepareCurrentCart(); - // yield return TestSignInHelper.Instance.SetOldToken(); - // yield return RemovePromocodeFromCart(); - // } - - private IEnumerator RemovePromocodeFromCart([CallerMemberName]string testName = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = _ => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - XsollaCart.Instance.RemovePromocodeFromCart( - projectId: XsollaSettings.StoreProjectId, - cartId: _currentCart.cart_id, - onSuccess: onSuccess, - onError: onError); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator PurchaseCart_NoCartId_Success() - { - yield return PurchaseCart(); - } - - [UnityTest] - public IEnumerator PurchaseCart_CartId_Success() - { - yield return PrepareCurrentCart(); - yield return PurchaseCart(cartID: _currentCart.cart_id); - } - - private IEnumerator PurchaseCart([CallerMemberName]string testName = null, string cartID = null, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = _ => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (cartID == null) - { - XsollaCart.Instance.PurchaseCart( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - purchaseParams, - customHeaders); - } - else - { - XsollaCart.Instance.PurchaseCart( - projectId: XsollaSettings.StoreProjectId, - cartId: _currentCart.cart_id, - onSuccess: onSuccess, - onError: onError, - purchaseParams, - customHeaders); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator CreateOrderWithFreeCart_Success() - { - yield return TestSignInHelper.Instance.SignInAsTestUser(); - yield return ClearCart(); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "Xsolla_free_item", quantity = 1}}); - yield return CreateOrderWithFreeCart(); - } - - [UnityTest] - public IEnumerator CreateOrderWithFreeCart_NotFreeItem_Failure() - { - yield return TestSignInHelper.Instance.SignInAsTestUser(); - yield return ClearCart(); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}); - yield return CreateOrderWithFreeCart(isSuccessExpected: false); - } - - [UnityTest] - public IEnumerator CreateOrderWithFreeCart_InvalidUser_Failure() - { - yield return TestSignInHelper.Instance.SignIn(); - yield return ClearCart(); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "Xsolla_free_item", quantity = 1}}); - yield return CreateOrderWithFreeCart(isSuccessExpected: false); - } - - [UnityTest] - public IEnumerator CreateOrderWithFreeParticularCart_Success() - { - yield return TestSignInHelper.Instance.SignInAsTestUser(); - yield return PrepareCurrentCart(); - yield return ClearCart(cartID: _currentCart.cart_id); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "Xsolla_free_item", quantity = 1}}, cartID: _currentCart.cart_id); - yield return CreateOrderWithFreeCart(cartID: _currentCart.cart_id); - } - - [UnityTest] - public IEnumerator CreateOrderWithFreeParticularCart_NotFreeItem_Failure() - { - yield return TestSignInHelper.Instance.SignInAsTestUser(); - yield return PrepareCurrentCart(); - yield return ClearCart(cartID: _currentCart.cart_id); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}, cartID: _currentCart.cart_id); - yield return CreateOrderWithFreeCart(cartID: _currentCart.cart_id, isSuccessExpected: false); - } - - [UnityTest] - public IEnumerator CreateOrderWithFreeParticularCart_InvalidUser_Failure() - { - yield return TestSignInHelper.Instance.SignIn(); - yield return PrepareCurrentCart(); - yield return ClearCart(cartID: _currentCart.cart_id); - yield return FillCart(fillItems: new List {new CartFillItem {sku = "Xsolla_free_item", quantity = 1}}, cartID: _currentCart.cart_id); - yield return CreateOrderWithFreeCart(cartID: _currentCart.cart_id, isSuccessExpected: false); - } - - private IEnumerator CreateOrderWithFreeCart([CallerMemberName]string testName = null, string cartID = null, bool isSuccessExpected = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = orderId => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (cartID == null) - { - XsollaCart.Instance.CreateOrderWithFreeCart( - XsollaSettings.StoreProjectId, - onSuccess, - onError - ); - } - else - { - XsollaCart.Instance.CreateOrderWithParticularFreeCart( - XsollaSettings.StoreProjectId, - cartID, - onSuccess, - onError - ); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value == isSuccessExpected) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - } -} diff --git a/Assets/Tests/API/XsollaCartTests/XsollaCartTests.cs.meta b/Assets/Tests/API/XsollaCartTests/XsollaCartTests.cs.meta deleted file mode 100644 index 925a9efde..000000000 --- a/Assets/Tests/API/XsollaCartTests/XsollaCartTests.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: fc289dd5a47124f69b1cb96740ac0444 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Tests/API/XsollaCatalogTests/XsollaCatalogTests.cs b/Assets/Tests/API/XsollaCatalogTests/XsollaCatalogTests.cs deleted file mode 100644 index d650e4716..000000000 --- a/Assets/Tests/API/XsollaCatalogTests/XsollaCatalogTests.cs +++ /dev/null @@ -1,1041 +0,0 @@ -using System; -using System.Collections; -using System.Runtime.CompilerServices; -using System.Linq; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Catalog; -using Xsolla.Core; - -namespace Xsolla.Tests -{ - public class XsollaCatalogTests - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [UnityTest] - public IEnumerator GetCatalog_DefaultValues_Success() - { - yield return GetCatalog(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetCatalog_Parametrized_Success() - { - yield return GetCatalog(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetCatalog_Personalized_HasPersonalizedItem() - { - yield return GetCatalog(personalized: true); - } - - [UnityTest] - public IEnumerator GetCatalog_NonPersonalized_NoPersonalizedItem() - { - yield return GetCatalog(personalized: false); - } - - [UnityTest] - public IEnumerator GetCatalog_PromotionItem_HasPromotionItem() - { - yield return GetCatalog(personalized: true, checkPromotion: true); - } - - private IEnumerator GetCatalog([CallerMemberName]string testName = null, bool defaultValues = true, bool personalized = false, bool checkPromotion = false) - { - if (personalized) - yield return TestSignInHelper.Instance.CheckSession(); - else - Token.Instance = null; - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - if (!defaultValues && items.items.Length != 10) - { - errorMessage = "LIMIT ERROR"; - success = false; - return; - } - - var hasPersonalizedItem = items.items.FirstOrDefault(x => x.sku.Equals("xsollus_personalized_item")) != null; - if (personalized != hasPersonalizedItem) - { - errorMessage = $"PERSONALIZATION ERROR, EXPECTED {personalized} ACTUAL {hasPersonalizedItem}"; - success = false; - return; - }; - - if (checkPromotion && !IsPromotionItemPreset(items.items, out errorMessage)) - { - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaCatalog.Instance.GetCatalog( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCatalog.Instance.GetCatalog( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - limit: 10, - offset: 10, - locale: "en_US", - additionalFields: null, - country: "US"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetCatalogSimplified_DefaultValues_Success() - { - yield return GetCatalogSmplified(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetCatalogSimplified_Parametrized_Success() - { - yield return GetCatalogSmplified(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetCatalogSimplified_Personalized_HasPersonalizedItem() - { - yield return GetCatalogSmplified(personalized: true); - } - - [UnityTest] - public IEnumerator GetCatalogSimplified_NonPersonalized_NoPersonalizedItem() - { - yield return GetCatalogSmplified(personalized: false); - } - - // [UnityTest] - // public IEnumerator GetCatalogSimplified_PromotionItem_HasPromotionItem() - // { - // yield return GetCatalogSmplified(checkPromotion: true); - // } - - private IEnumerator GetCatalogSmplified([CallerMemberName]string testName = null, bool defaultValues = true, bool personalized = false, bool checkPromotion = false) - { - if (personalized) - yield return TestSignInHelper.Instance.CheckSession(); - else - Token.Instance = null; - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - var hasPersonalizedItem = items.items.FirstOrDefault(x => x.sku.Equals("xsollus_personalized_item")) != null; - if (personalized != hasPersonalizedItem) - { - errorMessage = $"PERSONALIZATION ERROR, EXPECTED {personalized} ACTUAL {hasPersonalizedItem}"; - success = false; - return; - }; - - //We can not follow DRY here because items are different - if (checkPromotion) - { - var itemWithPromotion = items.items.FirstOrDefault(x => x.sku.Equals("sdk_team_special")); - if (itemWithPromotion == null) - { - errorMessage = "PROMOTION ERROR, EXPECTED ITEM NOT FOUND"; - success = false; - return; - } - - var promotionContainer = itemWithPromotion.promotions; - if (promotionContainer == null || promotionContainer.Length == 0) - { - errorMessage = "PROMOTION ERROR, PROMOTION CONTAINER IS NULL OR EMPTY"; - success = false; - return; - } - - var promotionItem = promotionContainer[0]; - if (string.IsNullOrEmpty(promotionItem.name) || - string.IsNullOrEmpty(promotionItem.date_start) || - string.IsNullOrEmpty(promotionItem.date_end)) - { - errorMessage = $"PROMOTION ERROR, PROMOTION FIELDS: name:'{promotionItem.name}' date_start:'{promotionItem.date_start}' date_end:'{promotionItem.date_end}'"; - success = false; - return; - } - - UnityEngine.Debug.Log("PERSONALIZATION PASSED SUCCESSFULLY"); - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaCatalog.Instance.GetCatalogSimplified( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCatalog.Instance.GetCatalogSimplified( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - locale: "de_DE"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetGroupItems_DefaultValues_Success() - { - yield return GetGroupItems(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetGroupItems_Parametrized_Success() - { - yield return GetGroupItems(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetGroupItems_PromotionItem_HasPromotionItem() - { - yield return GetGroupItems(checkPromotion: true); - } - - private IEnumerator GetGroupItems([CallerMemberName]string testName = null, bool defaultValues = true, bool checkPromotion = false) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - if (!defaultValues && items.items.Length != 5) - { - errorMessage = "LIMIT ERROR"; - success = false; - return; - } - - if (checkPromotion && !IsPromotionItemPreset(items.items, out errorMessage)) - { - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaCatalog.Instance.GetGroupItems( - projectId: XsollaSettings.StoreProjectId, - groupExternalId: "Featured", - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCatalog.Instance.GetGroupItems( - projectId: XsollaSettings.StoreProjectId, - groupExternalId: "Featured", - onSuccess: onSuccess, - onError: onError, - limit: 5, - offset: 5, - locale: "en_US", - additionalFields: "long_description", - country: "US"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetItemGroups_DefaultValues_Success() - { - yield return GetItemGroups(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetItemGroups_Parametrized_Success() - { - yield return GetItemGroups(defaultValues: false); - } - - private IEnumerator GetItemGroups([CallerMemberName]string testName = null, bool defaultValues = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = groups => - { - if (groups == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (groups.groups == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (groups.groups.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaCatalog.Instance.GetItemGroups( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCatalog.Instance.GetItemGroups( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - limit: 2, - offset: 1, - locale: "en_US"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetVirtualCurrencyList_DefaultValues_Success() - { - yield return GetVirtualCurrencyList(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetVirtualCurrencyList_Parametrized_Success() - { - yield return GetVirtualCurrencyList(defaultValues: false); - } - - private IEnumerator GetVirtualCurrencyList([CallerMemberName]string testName = null, bool defaultValues = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - if (!defaultValues && items.items.Length != 1) - { - errorMessage = "LIMIT ERROR"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaCatalog.Instance.GetVirtualCurrencyList( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCatalog.Instance.GetVirtualCurrencyList( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - limit: 1, - offset: 1, - locale: "en_US", - additionalFields: "long_description", - country: "US"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetVirtualCurrencyPackagesList_DefaultValues_Success() - { - yield return GetVirtualCurrencyPackagesList(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetVirtualCurrencyPackagesList_Parametrized_Success() - { - yield return GetVirtualCurrencyPackagesList(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetVirtualCurrencyPackagesList_Personalized_HasPersonalizedItem() - { - yield return GetVirtualCurrencyPackagesList(personalized: true); - } - - [UnityTest] - public IEnumerator GetVirtualCurrencyPackagesList_NonPersonalized_NoPersonalizedItem() - { - yield return GetVirtualCurrencyPackagesList(personalized: false); - } - - private IEnumerator GetVirtualCurrencyPackagesList([CallerMemberName]string testName = null, bool defaultValues = true, bool personalized = false) - { - if (personalized) - yield return TestSignInHelper.Instance.CheckSession(); - else - Token.Instance = null; - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Count == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - if (!defaultValues && items.items.Count != 1) - { - errorMessage = "LIMIT ERROR"; - success = false; - return; - } - - var hasPersonalizedItem = items.items.FirstOrDefault(x => x.sku.Equals("crystal_pack_specialxsollus")) != null; - if (personalized != hasPersonalizedItem) - { - errorMessage = $"PERSONALIZATION ERROR, EXPECTED {personalized} ACTUAL {hasPersonalizedItem}"; - success = false; - return; - }; - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaCatalog.Instance.GetVirtualCurrencyPackagesList( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCatalog.Instance.GetVirtualCurrencyPackagesList( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - limit: 1, - offset: 1, - locale: "en_US", - additionalFields: "long_description", - country: "US"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetBundles_DefaultValues_Success() - { - yield return GetBundles(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetBundles_Parametrized_Success() - { - yield return GetBundles(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetBundles_Personalized_HasPersonalizedItem() - { - yield return GetBundles(personalized: true); - } - - [UnityTest] - public IEnumerator GetBundles_NonPersonalized_NoPersonalizedItem() - { - yield return GetBundles(personalized: false); - } - - private IEnumerator GetBundles([CallerMemberName]string testName = null, bool defaultValues = true, bool personalized = false) - { - if (personalized) - yield return TestSignInHelper.Instance.CheckSession(); - else - Token.Instance = null; - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - if (!defaultValues && items.items.Length != 1) - { - errorMessage = "LIMIT ERROR"; - success = false; - return; - } - - var hasPersonalizedItem = items.items.FirstOrDefault(x => x.sku.Equals("sdk_special_pack_forxsollus")) != null; - if (personalized != hasPersonalizedItem) - { - errorMessage = $"PERSONALIZATION ERROR, EXPECTED {personalized} ACTUAL {hasPersonalizedItem}"; - success = false; - return; - }; - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaCatalog.Instance.GetBundles( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCatalog.Instance.GetBundles( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - limit: 1, - offset: 1, - locale: "en_US", - additionalFields: "long_description", - country: "US"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetBundle_DefaultValues_Success() - { - yield return GetBundle(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetBundle_Parametrized_Success() - { - yield return GetBundle(defaultValues: false); - } - - private IEnumerator GetBundle([CallerMemberName]string testName = null, bool defaultValues = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = bundle => - { - if (bundle == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaCatalog.Instance.GetBundle( - projectId: XsollaSettings.StoreProjectId, - sku: "starter_pack", - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaCatalog.Instance.GetBundle( - projectId: XsollaSettings.StoreProjectId, - sku: "starter_pack", - onSuccess: onSuccess, - onError: onError, - locale: "en_US", - country: "US"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator RedeemCouponCode_TEST2022_Success() - { - yield return RedeemCouponCode(couponCode: "TEST2022", isSuccessExpected: true); - } - - [UnityTest] - public IEnumerator RedeemCouponCode_IncorrectCode_Failure() - { - yield return RedeemCouponCode(couponCode: "SUMMER1967", isSuccessExpected: false); - } - - [UnityTest] - public IEnumerator RedeemCouponCode_TEST2022_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return RedeemCouponCode(couponCode: "TEST2022", isSuccessExpected: true); - } - - private IEnumerator RedeemCouponCode([CallerMemberName]string testName = null, string couponCode = null, bool isSuccessExpected = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - XsollaCatalog.Instance.RedeemCouponCode( - projectId: XsollaSettings.StoreProjectId, - couponCode: new CouponCode() { coupon_code = couponCode }, - onSuccess: onSuccess, - onError: onError); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value == isSuccessExpected) - TestHelper.Pass(errorMessage, testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetCouponRewards_TEST2022_Success() - { - yield return GetCouponRewards(couponCode: "TEST2022", isSuccessExpected: true); - } - - [UnityTest] - public IEnumerator GetCouponRewards_IncorrectCode_Failure() - { - yield return GetCouponRewards(couponCode: "SUMMER1967", isSuccessExpected: false); - } - - [UnityTest] - public IEnumerator GetCouponRewards_TEST2022_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return GetCouponRewards(couponCode: "TEST2022", isSuccessExpected: true); - } - - private IEnumerator GetCouponRewards([CallerMemberName]string testName = null, string couponCode = null, bool isSuccessExpected = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = bonus => - { - if (bonus == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (bonus.bonus == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (bonus.bonus.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - XsollaCatalog.Instance.GetCouponRewards( - projectId: XsollaSettings.StoreProjectId, - couponCode: couponCode, - onSuccess: onSuccess, - onError: onError); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value == isSuccessExpected) - TestHelper.Pass(errorMessage, testName); - else - TestHelper.Fail(errorMessage, testName); - } - - private bool IsPromotionItemPreset(StoreItem[] items, out string errorMessage) - { - var itemWithPromotion = items.FirstOrDefault(x => x.sku.Equals("sdk_team_special")); - if (itemWithPromotion == null) - { - errorMessage = "PROMOTION ERROR, EXPECTED ITEM NOT FOUND"; - return false; - } - - var promotionContainer = itemWithPromotion.promotions; - if (promotionContainer == null || promotionContainer.Length == 0) - { - errorMessage = "PROMOTION ERROR, PROMOTION CONTAINER IS NULL OR EMPTY"; - return false; - } - - var promotionItem = promotionContainer[0]; - if (string.IsNullOrEmpty(promotionItem.name) || - string.IsNullOrEmpty(promotionItem.date_start) || - string.IsNullOrEmpty(promotionItem.date_end)) - { - errorMessage = $"PROMOTION ERROR, PROMOTION FIELDS: name:'{promotionItem.name}' date_start:'{promotionItem.date_start}' date_end:'{promotionItem.date_end}'"; - return false; - } - - UnityEngine.Debug.Log("PERSONALIZATION PASSED SUCCESSFULLY"); - errorMessage = null; - return true; - } - - [UnityTest] - public IEnumerator CreateOrderWithSpecifiedFreeItem_Success() - { - yield return TestSignInHelper.Instance.SignInAsTestUser(); - yield return CreateOrderWithSpecifiedFreeItem(itemSku: "Xsolla_free_item", isSuccessExpected: true); - } - - [UnityTest] - public IEnumerator CreateOrderWithSpecifiedFreeItem_NonExistentSku_Failure() - { - yield return TestSignInHelper.Instance.SignInAsTestUser(); - yield return CreateOrderWithSpecifiedFreeItem(itemSku: "abcdef", isSuccessExpected: false); - } - - [UnityTest] - public IEnumerator CreateOrderWithSpecifiedFreeItem_InvalidUser_Failure() - { - yield return TestSignInHelper.Instance.SignIn(); - yield return CreateOrderWithSpecifiedFreeItem(itemSku: "Xsolla_free_item", isSuccessExpected: false); - } - - private IEnumerator CreateOrderWithSpecifiedFreeItem([CallerMemberName]string testName = null, string itemSku = null, bool isSuccessExpected = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaCatalog.Instance.CreateOrderWithSpecifiedFreeItem( - XsollaSettings.StoreProjectId, - itemSku, - orderId => success = true, - error => - { - errorMessage = error.errorMessage; - success = false; - }); - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value == isSuccessExpected) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - } -} diff --git a/Assets/Tests/API/XsollaCatalogTests/XsollaCatalogTests.cs.meta b/Assets/Tests/API/XsollaCatalogTests/XsollaCatalogTests.cs.meta deleted file mode 100644 index e7f3e457b..000000000 --- a/Assets/Tests/API/XsollaCatalogTests/XsollaCatalogTests.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 4c2d0e8170f266b4d97d20b465f12ac2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Tests/API/XsollaInventoryTests/XsollaInventoryTests.cs b/Assets/Tests/API/XsollaInventoryTests/XsollaInventoryTests.cs deleted file mode 100644 index fadb32cec..000000000 --- a/Assets/Tests/API/XsollaInventoryTests/XsollaInventoryTests.cs +++ /dev/null @@ -1,337 +0,0 @@ -using System; -using System.Collections; -using System.Runtime.CompilerServices; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Core; -using Xsolla.Inventory; - -namespace Xsolla.Tests -{ - public class XsollaInventoryTests - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [UnityTest] - public IEnumerator GetVirtualCurrencyBalance_DefaultValues_Success() - { - yield return GetVirtualCurrencyBalance(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetVirtualCurrencyBalance_Parametrized_Success() - { - yield return GetVirtualCurrencyBalance(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetVirtualCurrencyBalance_DefaultValues_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return GetVirtualCurrencyBalance(defaultValues: true); - } - - private IEnumerator GetVirtualCurrencyBalance([CallerMemberName]string testName = null, bool defaultValues = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = balances => - { - if (balances == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (balances.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (balances.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaInventory.Instance.GetVirtualCurrencyBalance( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaInventory.Instance.GetVirtualCurrencyBalance( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - platform: "xsolla"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetInventoryItems_DefaultValues_Success() - { - yield return GetInventoryItems(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetInventoryItems_Parametrized_Success() - { - yield return GetInventoryItems(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetInventoryItems_DefaultValues_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return GetInventoryItems(defaultValues: true); - } - - private IEnumerator GetInventoryItems([CallerMemberName]string testName = null, bool defaultValues = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - if (!defaultValues && items.items.Length != 5) - { - errorMessage = "LIMIT ERROR"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaInventory.Instance.GetInventoryItems( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaInventory.Instance.GetInventoryItems( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - limit: 5, - offset: 5, - locale: "en_US", - platform: "xsolla"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator ConsumeInventoryItem_DefaultValues_Success() - { - yield return ConsumeInventoryItem(defaultValues: true); - } - - [UnityTest] - public IEnumerator ConsumeInventoryItem_Parametrized_Success() - { - yield return ConsumeInventoryItem(defaultValues: false); - } - - [UnityTest] - public IEnumerator ConsumeInventoryItem_DefaultValues_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return ConsumeInventoryItem(defaultValues: true); - } - - private IEnumerator ConsumeInventoryItem([CallerMemberName]string testName = null, bool defaultValues = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = () => - { - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaInventory.Instance.ConsumeInventoryItem( - projectId: XsollaSettings.StoreProjectId, - item: new ConsumeItem() { sku = "lootbox_1", quantity = 1 }, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaInventory.Instance.ConsumeInventoryItem( - projectId: XsollaSettings.StoreProjectId, - item: new ConsumeItem() { sku = "lootbox_1", quantity = 1 }, - onSuccess: onSuccess, - onError: onError, - platform: "xsolla"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - - [UnityTest] - public IEnumerator GetTimeLimitedItems_DefaultValues_Success() - { - yield return GetTimeLimitedItems(defaultValues: true); - } - - [UnityTest] - public IEnumerator GetTimeLimitedItems_Parametrized_Success() - { - yield return GetTimeLimitedItems(defaultValues: false); - } - - [UnityTest] - public IEnumerator GetTimeLimitedItems_DefaultValues_InvalidToken_Success() - { - yield return TestSignInHelper.Instance.SetOldToken(); - yield return GetTimeLimitedItems(defaultValues: true); - } - - private IEnumerator GetTimeLimitedItems([CallerMemberName]string testName = null, bool defaultValues = true) - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - Action onSuccess = items => - { - if (items == null) - { - errorMessage = "CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items == null) - { - errorMessage = "NESTED CONTAINER IS NULL"; - success = false; - return; - } - - if (items.items.Length == 0) - { - errorMessage = "NESTED CONTAINER IS EMPTY"; - success = false; - return; - } - - success = true; - }; - - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }; - - if (defaultValues) - { - XsollaInventory.Instance.GetTimeLimitedItems( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError); - } - else - { - XsollaInventory.Instance.GetTimeLimitedItems( - projectId: XsollaSettings.StoreProjectId, - onSuccess: onSuccess, - onError: onError, - platform: "xsolla"); - } - - yield return new WaitUntil(() => success.HasValue); - - if (success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(errorMessage, testName); - } - } -} diff --git a/Assets/Tests/API/XsollaInventoryTests/XsollaInventoryTests.cs.meta b/Assets/Tests/API/XsollaInventoryTests/XsollaInventoryTests.cs.meta deleted file mode 100644 index 0733fb5cd..000000000 --- a/Assets/Tests/API/XsollaInventoryTests/XsollaInventoryTests.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ec8d0dc0823f169439edf0f4063b2fc3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionPublicPlanTests.cs b/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionPublicPlanTests.cs deleted file mode 100644 index 01cb353f4..000000000 --- a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionPublicPlanTests.cs +++ /dev/null @@ -1,328 +0,0 @@ -using System.Collections; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Subscriptions; - -namespace Xsolla.Tests -{ - public class XsollaSubscriptionPublicPlanTests : XsollaSubscriptionTestsBase - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [UnityTest] - public IEnumerator GetSubscriptionPublicPlans_Default_Success() - { - yield return TestSignInHelper.Instance.SignOut(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPublicPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.has_more), false, plans.has_more, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPublicPlans_Default_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPublicPlans_FilteredByPlanId_Success() - { - yield return TestSignInHelper.Instance.SignOut(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPublicPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 1, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planId: new[]{ - 269503 - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPublicPlans_FilteredByPlanId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPublicPlans_FilteredByNonExistentPlanId_Success() - { - yield return TestSignInHelper.Instance.SignOut(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPublicPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 0, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planId: new[]{ - 123 - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPublicPlans_FilteredByNonExistentPlanId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPublicPlans_FilteredByExternalId_Success() - { - yield return TestSignInHelper.Instance.SignOut(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPublicPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 1, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planExternalId: new[]{ - "Zt0C7jHW" - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPublicPlans_FilteredByExternalId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPublicPlans_FilteredBNonExistentExternalId_Success() - { - yield return TestSignInHelper.Instance.SignOut(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPublicPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 0, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planExternalId: new[]{ - "123" - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPublicPlans_FilteredBNonExistentExternalId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPublicPlans_Pagination_Success() - { - yield return TestSignInHelper.Instance.SignOut(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPublicPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 1, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.has_more), true, plans.has_more, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - limit: 1 - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPublicPlans_Pagination_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPublicPlans_PlanFields_Success() - { - yield return TestSignInHelper.Instance.SignOut(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPublicPlans( - TEST_PROJECT_ID, - plans => - { - var plan = plans.items[0]; - - if (!AreEqual(nameof(plan.plan_id), 269503, plan.plan_id, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.plan_external_id), "WT4xCan8", plan.plan_external_id, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.PlanType), PlanType.All, plan.PlanType, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.period.value), 1, plan.period.value, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.period.Unit), PeriodUnit.Month, plan.period.Unit, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.charge.amount), 0.49f, plan.charge.amount, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.charge.currency), "USD", plan.charge.currency, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planId: new[]{ - 269503 - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPublicPlans_PlanFields_Success), success, errorMessage); - } - } -} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionPublicPlanTests.cs.meta b/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionPublicPlanTests.cs.meta deleted file mode 100644 index a7322d51f..000000000 --- a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionPublicPlanTests.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 75047663f63f42cfaecf8cba89accb71 -timeCreated: 1652370745 \ No newline at end of file diff --git a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionTestsBase.cs b/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionTestsBase.cs deleted file mode 100644 index 1d3361777..000000000 --- a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionTestsBase.cs +++ /dev/null @@ -1,51 +0,0 @@ -namespace Xsolla.Tests -{ - public class XsollaSubscriptionTestsBase - { - protected const string TEST_PROJECT_ID = "149697"; - - protected bool AreEqual(string parameterName, T expected, T actual, ref string errorMessage) - { - if (expected.Equals(actual)) - return true; - - errorMessage = $"{parameterName.ToUpperInvariant()} EXPECTED: \"{expected.ToString().ToUpperInvariant()}\" BUT WAS: \"{actual.ToString().ToUpperInvariant()}\""; - return false; - } - - protected bool IsNull(string parameterName, T actual, ref string errorMessage) - { - if (actual == null) - return true; - - errorMessage = $"{parameterName.ToUpperInvariant()} EXPECTED: NULL BUT WAS: NOT NULL"; - return false; - } - - protected bool NotNull(string parameterName, T actual, ref string errorMessage) - { - if (actual != null) - return true; - - errorMessage = $"{parameterName.ToUpperInvariant()} EXPECTED: NOT NULL BUT WAS: NULL"; - return false; - } - - protected bool NotNull(string parameterName, string actual, ref string errorMessage) - { - if (!string.IsNullOrEmpty(actual)) - return true; - - errorMessage = $"{parameterName.ToUpperInvariant()} EXPECTED: NOT NULL BUT WAS: NULL"; - return false; - } - - protected void HandleResult(string testName, bool? success, string errorMessage) - { - if (success.HasValue && success.Value) - TestHelper.Pass(testName); - else - TestHelper.Fail(testName, errorMessage); - } - } -} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionTestsBase.cs.meta b/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionTestsBase.cs.meta deleted file mode 100644 index bda8eea2a..000000000 --- a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionTestsBase.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 6187379b2db64732b396de27cd5c28ce -timeCreated: 1652806624 \ No newline at end of file diff --git a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserPlanTests.cs b/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserPlanTests.cs deleted file mode 100644 index f76c9c31e..000000000 --- a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserPlanTests.cs +++ /dev/null @@ -1,375 +0,0 @@ -using System.Collections; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Core; -using Xsolla.Subscriptions; - -namespace Xsolla.Tests -{ - public class XsollaSubscriptionUserPlanTests : XsollaSubscriptionTestsBase - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [UnityTest] - public IEnumerator GetSubscriptionPlans_Default_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPlans( - XsollaSettings.StoreProjectId, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 2, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.has_more), false, plans.has_more, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPlans_Default_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPlans_FilteredByPlanId_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 1, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planId: new[]{ - 269503 - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPlans_FilteredByPlanId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPlans_FilteredByNonExistentPlanId_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 0, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planId: new[]{ - 123 - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPlans_FilteredByNonExistentPlanId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPlans_FilteredByExternalId_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 1, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planExternalId: new[]{ - "Zt0C7jHW" - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPlans_FilteredByExternalId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPlans_MultipleExternalIds_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPlans( - "77640", - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 2, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planExternalId: new[]{ - "tNuy9WMo","IFIwBTne" - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPlans_FilteredByExternalId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPlans_FilteredBNonExistentExternalId_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 0, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planExternalId: new[]{ - "123" - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPlans_FilteredBNonExistentExternalId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPlans_Pagination_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPlans( - TEST_PROJECT_ID, - plans => - { - if (!NotNull(nameof(plans.items), plans.items, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.items.Length), 1, plans.items.Length, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plans.has_more), true, plans.has_more, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - limit: 1 - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPlans_Pagination_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPlans_CheckFields_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPlans( - TEST_PROJECT_ID, - plans => - { - var plan = plans.items[0]; - - if (!AreEqual(nameof(plan.plan_id), 269503, plan.plan_id, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.plan_external_id), "WT4xCan8", plan.plan_external_id, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.PlanType), PlanType.All, plan.PlanType, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.period.value), 1, plan.period.value, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.period.Unit), PeriodUnit.Month, plan.period.Unit, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.charge.amount), 0.49f, plan.charge.amount, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(plan.charge.currency), "USD", plan.charge.currency, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - }, - planId: new[]{ - 269503 - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPlans_CheckFields_Success), success, errorMessage); - } - } -} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserPlanTests.cs.meta b/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserPlanTests.cs.meta deleted file mode 100644 index bd0b94841..000000000 --- a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserPlanTests.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: afd9b6a15acb42c989725373fd2cc765 -timeCreated: 1652806535 \ No newline at end of file diff --git a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserSubscriptionTests.cs b/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserSubscriptionTests.cs deleted file mode 100644 index 34390aec2..000000000 --- a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserSubscriptionTests.cs +++ /dev/null @@ -1,467 +0,0 @@ -using System.Collections; -using NUnit.Framework; -using UnityEngine; -using UnityEngine.TestTools; -using Xsolla.Core; -using Xsolla.Subscriptions; - -namespace Xsolla.Tests -{ - public class XsollaSubscriptionUserSubscriptionTests : XsollaSubscriptionTestsBase - { - [OneTimeSetUp] - [OneTimeTearDown] - public void Clear() => TestHelper.Clear(); - - [UnityTest] - public IEnumerator GetSubscriptions_Default_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptions( - XsollaSettings.StoreProjectId, - subscriptions => - { - if (!NotNull(nameof(subscriptions.items), subscriptions.items, ref errorMessage)) - { - success = false; - return; - } - - // if (!AreEqual(nameof(subscriptions.items.Length), 1, subscriptions.items.Length, ref errorMessage)) - // { - // success = false; - // return; - // } - - if (!AreEqual(nameof(subscriptions.has_more), false, subscriptions.has_more, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptions_Default_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionDetails_Default_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionDetails( - XsollaSettings.StoreProjectId, - 65045530, - subscription => - { - if (!AreEqual(nameof(subscription.id), 65045530, subscription.id, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(subscription.plan_id), 268799, subscription.plan_id, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(subscription.plan_external_id), "IFIwBTne", subscription.plan_external_id, ref errorMessage)) - { - success = false; - return; - } - - if (!NotNull(nameof(subscription.date_create), subscription.date_create, ref errorMessage)) - { - success = false; - return; - } - - if (!NotNull(nameof(subscription.date_next_charge), subscription.date_next_charge, ref errorMessage)) - { - success = false; - return; - } - - if (!NotNull(nameof(subscription.date_last_charge), subscription.date_last_charge, ref errorMessage)) - { - success = false; - return; - } - - // if (!IsNull(nameof(subscription.date_end), subscription.date_end, ref errorMessage)) - // { - // success = false; - // return; - // } - - if (!NotNull(nameof(subscription.charge), subscription.charge, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(subscription.charge.amount), 0.01f, subscription.charge.amount, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(subscription.charge.currency), "USD", subscription.charge.currency, ref errorMessage)) - { - success = false; - return; - } - - if (!NotNull(nameof(subscription.period), subscription.period, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(subscription.period.value), 1, subscription.period.value, ref errorMessage)) - { - success = false; - return; - } - - if (!AreEqual(nameof(subscription.period.Unit), PeriodUnit.Month, subscription.period.Unit, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionDetails_Default_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionDetails_NonExistentId_Failure() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionDetails( - XsollaSettings.StoreProjectId, - 123456, - subscription => { success = false; }, - error => - { - if (!NotNull(nameof(error), error, ref errorMessage)) - { - success = false; - return; - } - - if (!NotNull(nameof(error.errorMessage), error.errorMessage, ref errorMessage)) - { - success = false; - return; - } - - success = true; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionDetails_NonExistentId_Failure), success, errorMessage); - } - - [UnityTest] - public IEnumerator CancelSubscription_NonExistentSubscriptionId_Failure() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.CancelSubscription( - XsollaSettings.StoreProjectId, - 12345, - () => success = false, - error => - { - if (!NotNull(nameof(error), error, ref errorMessage)) - { - success = false; - return; - } - - if (!NotNull(nameof(error.errorMessage), error.errorMessage, ref errorMessage)) - { - success = false; - return; - } - - success = true; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(CancelSubscription_NonExistentSubscriptionId_Failure), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionRenewalUrl_NonExistentSubscriptionId_Failure() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionRenewalUrl( - XsollaSettings.StoreProjectId, - 12345, - link => { success = false; }, - error => - { - if (!NotNull(nameof(error), error, ref errorMessage)) - { - success = false; - return; - } - - if (!NotNull(nameof(error.errorMessage), error.errorMessage, ref errorMessage)) - { - success = false; - return; - } - - success = true; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionRenewalUrl_NonExistentSubscriptionId_Failure), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPurchaseUrl_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPurchaseUrl( - XsollaSettings.StoreProjectId, - "tNuy9WMo", - link => - { - if (!NotNull(nameof(link.link_to_ps), link.link_to_ps, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPurchaseUrl_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPurchaseUrl_NonExistentPlanExternalId_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPurchaseUrl( - XsollaSettings.StoreProjectId, - "abc", - link => { success = false; }, - error => - { - if (!NotNull(nameof(error), error, ref errorMessage)) - { - success = false; - return; - } - - if (!NotNull(nameof(error.errorMessage), error.errorMessage, ref errorMessage)) - { - success = false; - return; - } - - success = true; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPurchaseUrl_NonExistentPlanExternalId_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionPurchaseUrl_DefaultPaymentSettings_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionPurchaseUrl( - XsollaSettings.StoreProjectId, - "tNuy9WMo", - GenerateSettings(), - link => - { - if (!NotNull(nameof(link.link_to_ps), link.link_to_ps, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionPurchaseUrl_DefaultPaymentSettings_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionManagementUrl_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionManagementUrl( - XsollaSettings.StoreProjectId, - link => - { - if (!NotNull(nameof(link.link_to_ps), link.link_to_ps, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionManagementUrl_Success), success, errorMessage); - } - - [UnityTest] - public IEnumerator GetSubscriptionManagementUrl_DefaultPaymentSettings_Success() - { - yield return TestSignInHelper.Instance.CheckSession(); - - bool? success = default; - string errorMessage = default; - - XsollaSubscriptions.Instance.GetSubscriptionManagementUrl( - XsollaSettings.StoreProjectId, - GenerateSettings(), - link => - { - if (!NotNull(nameof(link.link_to_ps), link.link_to_ps, ref errorMessage)) - { - success = false; - return; - } - - success = true; - }, - error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - success = false; - } - ); - - yield return new WaitUntil(() => success.HasValue); - HandleResult(nameof(GetSubscriptionManagementUrl_Success), success, errorMessage); - } - - private PaymentSettings GenerateSettings() - { - var settings = new PaymentSettings(); - settings.sandbox = true; - settings.ui = new PaymentSettings.UI(); - settings.ui.size = "large"; - settings.ui.theme = "ps4-default-dark"; - settings.ui.version = "desktop"; - settings.ui.desktop = new PaymentSettings.UI.Desktop(); - settings.ui.desktop.header = new PaymentSettings.UI.Desktop.Header(); - settings.ui.desktop.header.is_visible = true; - settings.ui.desktop.header.visible_logo = true; - settings.ui.desktop.header.visible_name = true; - settings.ui.desktop.header.type = "compact"; - settings.ui.desktop.header.close_button = true; - settings.ui.mobile = new PaymentSettings.UI.Mobile(); - settings.ui.mobile.mode = "saved_accounts"; - settings.ui.mobile.footer = new PaymentSettings.UI.Mobile.Footer(){is_visible=true}; - settings.ui.mobile.header = new PaymentSettings.UI.Mobile.Header(){close_button=true}; - //settings.ui.license_url = "string"; - settings.ui.mode = "user_account"; - settings.ui.user_account = new PaymentSettings.UI.UserAccount(); - settings.ui.user_account.history = new PaymentSettings.UI.UserAccount.EnableAndOrder(){enable=true,order=1}; - settings.ui.user_account.payment_accounts = new PaymentSettings.UI.UserAccount.EnableAndOrder(){enable=true,order=1}; - settings.ui.user_account.info = new PaymentSettings.UI.UserAccount.EnableAndOrder(){enable=true,order=1}; - settings.ui.user_account.subscriptions = new PaymentSettings.UI.UserAccount.EnableAndOrder(){enable=true,order=1}; - settings.currency = "USD"; - settings.locale = "en"; - // settings.external_id = "string"; - settings.payment_method = 1; - settings.return_url = Constants.DEFAULT_REDIRECT_URL; - settings.redirect_policy = new PaymentSettings.RedirectPolicy(); - settings.redirect_policy.redirect_conditions = "none"; - settings.redirect_policy.delay = 0; - settings.redirect_policy.status_for_manual_redirection = "none"; - settings.redirect_policy.redirect_button_caption = "string"; - - return settings; - } - } -} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserSubscriptionTests.cs.meta b/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserSubscriptionTests.cs.meta deleted file mode 100644 index ee0419d7d..000000000 --- a/Assets/Tests/API/XsollaSubscriptionsTests/XsollaSubscriptionUserSubscriptionTests.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c9e607c1823e49128eef24f92dd8a3b6 -timeCreated: 1652806730 \ No newline at end of file diff --git a/Assets/Tests/API/XsollaAuthTests.meta b/Assets/Tests/Auth.meta similarity index 100% rename from Assets/Tests/API/XsollaAuthTests.meta rename to Assets/Tests/Auth.meta diff --git a/Assets/Tests/Auth/AccountLinkingTests.cs b/Assets/Tests/Auth/AccountLinkingTests.cs new file mode 100644 index 000000000..f779eebbe --- /dev/null +++ b/Assets/Tests/Auth/AccountLinkingTests.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Globalization; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Tests.Auth +{ + public class AccountLinkingTests : AuthTestsBase + { + [UnityTest] + public IEnumerator SignInConsoleAccount_NintendoShop_Success() + { + yield return SignInConsoleAccount("nintendo_shop"); + } + + [UnityTest] + public IEnumerator SignInConsoleAccount_XBoxLive_Success() + { + yield return SignInConsoleAccount("xbox_live"); + } + + private static IEnumerator SignInConsoleAccount(string platform) + { + yield return SignOut(); + + var currentTime = DateTime.Now.ToString(CultureInfo.InvariantCulture); + var digits = new List(); + foreach (var symbol in currentTime) + { + if (char.IsDigit(symbol)) + digits.Add(symbol); + } + + var account = $"TestAcc{new string(digits.ToArray())}"; + + var isComplete = false; + XsollaAuth.SignInConsoleAccount( + account, + platform, + () => + { + isComplete = true; + Assert.NotNull(XsollaToken.AccessToken); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaAuthTests/XsollaAuthAccountLinkingTests.cs.meta b/Assets/Tests/Auth/AccountLinkingTests.cs.meta similarity index 100% rename from Assets/Tests/API/XsollaAuthTests/XsollaAuthAccountLinkingTests.cs.meta rename to Assets/Tests/Auth/AccountLinkingTests.cs.meta diff --git a/Assets/Tests/Auth/AuthTestsBase.cs b/Assets/Tests/Auth/AuthTestsBase.cs new file mode 100644 index 000000000..297dadc1c --- /dev/null +++ b/Assets/Tests/Auth/AuthTestsBase.cs @@ -0,0 +1,14 @@ +using NUnit.Framework; + +namespace Xsolla.Tests.Auth +{ + public class AuthTestsBase : TestBase + { + [OneTimeSetUp] + [OneTimeTearDown] + public void Clear() + { + ClearEnv(); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Auth/AuthTestsBase.cs.meta b/Assets/Tests/Auth/AuthTestsBase.cs.meta new file mode 100644 index 000000000..3bb5b5fa7 --- /dev/null +++ b/Assets/Tests/Auth/AuthTestsBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 12083ae3552e4895a32c9baef23f8f3f +timeCreated: 1683639227 \ No newline at end of file diff --git a/Assets/Tests/Auth/RefreshTokenTests.cs b/Assets/Tests/Auth/RefreshTokenTests.cs new file mode 100644 index 000000000..c467103cf --- /dev/null +++ b/Assets/Tests/Auth/RefreshTokenTests.cs @@ -0,0 +1,58 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Tests.Auth +{ + public class RefreshTokenTests : AuthTestsBase + { + [UnityTest] + public IEnumerator RefreshToken_Success() + { + yield return SignIn(); + var prevToken = XsollaToken.AccessToken; + + var isComplete = false; + XsollaAuth.RefreshToken( + () => + { + isComplete = true; + Assert.AreNotEqual(prevToken, XsollaToken.AccessToken); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator RefreshToken_OldRefreshToken_Failure() + { + yield return SignIn(); + yield return SetOldRefreshToken(); + + var isComplete = false; + XsollaAuth.RefreshToken( + () => + { + isComplete = true; + Assert.Fail("Refresh token is old"); + }, + error => + { + isComplete = true; + Assert.NotNull(error); + Assert.NotNull(error.errorMessage); + Assert.AreEqual(error.ErrorType, ErrorType.InvalidToken); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaAuthTests/XsollaAuthOAuthRefreshTokenTests.cs.meta b/Assets/Tests/Auth/RefreshTokenTests.cs.meta similarity index 100% rename from Assets/Tests/API/XsollaAuthTests/XsollaAuthOAuthRefreshTokenTests.cs.meta rename to Assets/Tests/Auth/RefreshTokenTests.cs.meta diff --git a/Assets/Tests/Auth/SignInTests.cs b/Assets/Tests/Auth/SignInTests.cs new file mode 100644 index 000000000..7383872aa --- /dev/null +++ b/Assets/Tests/Auth/SignInTests.cs @@ -0,0 +1,203 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Tests.Auth +{ + public class SignInTests : AuthTestsBase + { + [UnityTest] + public IEnumerator SignIn_Success() + { + var isComplete = false; + XsollaAuth.SignIn( + "xsolla", + "xsolla", + () => + { + isComplete = true; + Assert.NotNull(XsollaToken.AccessToken); + Assert.NotNull(XsollaToken.RefreshToken); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator SignIn_IncorrectData_Failure() + { + var isComplete = false; + XsollaAuth.SignIn( + "k4TCNgHs", + "k4TCNgHs", + () => + { + isComplete = true; + Assert.Fail("Incorrect username and password should not be accepted"); + }, + error => + { + isComplete = true; + Assert.NotNull(error); + Assert.NotNull(error.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetUserInfo_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaAuth.GetUserInfo( + userInfo => + { + isComplete = true; + Assert.NotNull(userInfo); + Assert.NotNull(userInfo.id); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator Logout_Sso_Success() + { + yield return Logout(LogoutType.Sso); + } + + [UnityTest] + public IEnumerator Logout_All_Success() + { + yield return Logout(LogoutType.All); + } + + private static IEnumerator Logout(LogoutType logoutType) + { + yield return CheckSession(); + + var isComplete = false; + XsollaAuth.Logout( + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + logoutType); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator ResetPassword_Default_Success() + { + yield return ResetPassword(); + } + + [UnityTest] + public IEnumerator ResetPassword_Locale_Success() + { + yield return ResetPassword("de_DE"); + } + + private IEnumerator ResetPassword(string locale = null) + { + yield return CheckSession(); + + string userEmail = null; + + var isComplete = false; + XsollaAuth.GetUserInfo( + userInfo => + { + isComplete = true; + userEmail = userInfo?.email; + Assert.NotNull(userEmail); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + + isComplete = false; + XsollaAuth.ResetPassword( + userEmail, + () => { isComplete = true; }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + locale: locale); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator ResendConfirmationLink_DefaultValues_Success() + { + yield return ResendConfirmationLink(); + } + + [UnityTest] + public IEnumerator ResendConfirmationLink_de_DE_Locale_Success() + { + yield return ResendConfirmationLink("de_DE"); + } + + private static IEnumerator ResendConfirmationLink(string locale = null) + { + yield return CheckSession(); + + string userEmail = null; + + var isComplete = false; + XsollaAuth.GetUserInfo( + userInfo => + { + isComplete = true; + userEmail = userInfo?.email; + Assert.NotNull(userEmail); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + + isComplete = false; + XsollaAuth.ResendConfirmationLink( + userEmail, + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + locale: locale); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaAuthTests/XsollaAuthUserTests.cs.meta b/Assets/Tests/Auth/SignInTests.cs.meta similarity index 100% rename from Assets/Tests/API/XsollaAuthTests/XsollaAuthUserTests.cs.meta rename to Assets/Tests/Auth/SignInTests.cs.meta diff --git a/Assets/Tests/Auth/SocialAuthTests.cs b/Assets/Tests/Auth/SocialAuthTests.cs new file mode 100644 index 000000000..701b9b6a9 --- /dev/null +++ b/Assets/Tests/Auth/SocialAuthTests.cs @@ -0,0 +1,65 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Tests.Auth +{ + public class SocialAuthTests : AuthTestsBase + { + [Test] + public void GetSocialNetworkAuthUrl_Success() + { + var url = XsollaAuth.GetSocialNetworkAuthUrl(SocialProvider.Facebook); + Assert.IsFalse(string.IsNullOrEmpty(url)); + } + + [UnityTest] + public IEnumerator GetLinksForSocialAuth_NoLocale_Success() + { + yield return GetLinksForSocialAuth(); + } + + [UnityTest] + public IEnumerator GetLinksForSocialAuth_deDE_Locale_Success() + { + yield return GetLinksForSocialAuth("de_DE"); + } + + [UnityTest] + public IEnumerator GetLinksForSocialAuth_InvalidToken_SuccessAndTokenRefreshed() + { + yield return SetOldAccessToken(); + var oldToken = XsollaToken.AccessToken; + yield return GetLinksForSocialAuth(); + Assert.AreNotEqual(oldToken, XsollaToken.AccessToken); + } + + private static IEnumerator GetLinksForSocialAuth(string locale = null) + { + yield return CheckSession(); + + var isComplete = false; + XsollaAuth.GetLinksForSocialAuth( + links => + { + isComplete = true; + Assert.NotNull(links); + Assert.NotNull(links.items); + Assert.Greater(links.items.Count, 0); + Assert.IsFalse(string.IsNullOrEmpty(links.items[0].provider)); + Assert.IsFalse(string.IsNullOrEmpty(links.items[0].auth_url)); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + locale); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/API/XsollaAuthTests/XsollaAuthSocialTests.cs.meta b/Assets/Tests/Auth/SocialAuthTests.cs.meta similarity index 100% rename from Assets/Tests/API/XsollaAuthTests/XsollaAuthSocialTests.cs.meta rename to Assets/Tests/Auth/SocialAuthTests.cs.meta diff --git a/Assets/Tests/API/XsollaCartTests.meta b/Assets/Tests/Cart.meta similarity index 100% rename from Assets/Tests/API/XsollaCartTests.meta rename to Assets/Tests/Cart.meta diff --git a/Assets/Tests/Cart/CartTestsBase.cs b/Assets/Tests/Cart/CartTestsBase.cs new file mode 100644 index 000000000..842562533 --- /dev/null +++ b/Assets/Tests/Cart/CartTestsBase.cs @@ -0,0 +1,44 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class CartTestsBase : TestBase + { + [OneTimeSetUp] + [OneTimeTearDown] + public void Clear() + { + ClearEnv(); + CurrentCartId = null; + } + + protected string CurrentCartId { get; private set; } + + protected IEnumerator PrepareCurrentCart() + { + yield return CheckSession(); + + if (!string.IsNullOrEmpty(CurrentCartId)) + yield break; + + var isComplete = false; + XsollaCart.GetCartItems( + cart => + { + isComplete = true; + CurrentCartId = cart.cart_id; + Assert.NotNull(cart); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/CartTestsBase.cs.meta b/Assets/Tests/Cart/CartTestsBase.cs.meta new file mode 100644 index 000000000..07c88a83f --- /dev/null +++ b/Assets/Tests/Cart/CartTestsBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 68a4b9be58a44600a26687b71b6fe2b1 +timeCreated: 1683640999 \ No newline at end of file diff --git a/Assets/Tests/Cart/ClearCartTests.cs b/Assets/Tests/Cart/ClearCartTests.cs new file mode 100644 index 000000000..8f4b31cf5 --- /dev/null +++ b/Assets/Tests/Cart/ClearCartTests.cs @@ -0,0 +1,56 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class ClearCartTests : CartTestsBase + { + [UnityTest] + public IEnumerator ClearCart_NoCartId_Success() + { + yield return ClearCart(); + } + + [UnityTest] + public IEnumerator ClearCart_NoCartId_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return ClearCart(); + } + + [UnityTest] + public IEnumerator ClearCart_CartId_Success() + { + yield return PrepareCurrentCart(); + yield return ClearCart(CurrentCartId); + } + + [UnityTest] + public IEnumerator ClearCart_CartId_InvalidToken_Success() + { + yield return PrepareCurrentCart(); + yield return SetOldAccessToken(); + yield return ClearCart(CurrentCartId); + } + + public static IEnumerator ClearCart(string cartId = null) + { + yield return CheckSession(); + + var isComplete = false; + XsollaCart.ClearCart( + () => { isComplete = true; }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + cartId); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/ClearCartTests.cs.meta b/Assets/Tests/Cart/ClearCartTests.cs.meta new file mode 100644 index 000000000..22fcdda6f --- /dev/null +++ b/Assets/Tests/Cart/ClearCartTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 68485ad11e60495bb2013464a04777c3 +timeCreated: 1683623569 \ No newline at end of file diff --git a/Assets/Tests/Cart/CreateOrderWithFreeCartTests.cs b/Assets/Tests/Cart/CreateOrderWithFreeCartTests.cs new file mode 100644 index 000000000..a848801ce --- /dev/null +++ b/Assets/Tests/Cart/CreateOrderWithFreeCartTests.cs @@ -0,0 +1,106 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class CreateOrderWithFreeCartTests : CartTestsBase + { + [UnityTest] + public IEnumerator CreateOrderWithFreeCart_Success() + { + yield return SignInAsTestUser(); + yield return ClearCartTests.ClearCart(); + yield return FillCartTests.FillCart(new List {new CartFillItem {sku = "Xsolla_free_item", quantity = 1}}); + yield return CreateOrderWithFreeCart(); + } + + [UnityTest] + public IEnumerator CreateOrderWithFreeCart_NotFreeItem_Failure() + { + yield return SignInAsTestUser(); + yield return ClearCartTests.ClearCart(); + yield return FillCartTests.FillCart(new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}); + yield return CreateOrderWithFreeCart(isSuccessExpected: false); + } + + [UnityTest] + public IEnumerator CreateOrderWithFreeCart_InvalidUser_Failure() + { + yield return SignIn(); + yield return ClearCartTests.ClearCart(); + yield return FillCartTests.FillCart(new List {new CartFillItem {sku = "Xsolla_free_item", quantity = 1}}); + yield return CreateOrderWithFreeCart(isSuccessExpected: false); + } + + [UnityTest] + public IEnumerator CreateOrderWithFreeParticularCart_Success() + { + yield return SignInAsTestUser(); + yield return PrepareCurrentCart(); + yield return ClearCartTests.ClearCart(CurrentCartId); + yield return FillCartTests.FillCart(new List {new CartFillItem {sku = "Xsolla_free_item", quantity = 1}}, CurrentCartId); + yield return CreateOrderWithFreeCart(CurrentCartId); + } + + [UnityTest] + public IEnumerator CreateOrderWithFreeParticularCart_NotFreeItem_Failure() + { + yield return SignInAsTestUser(); + yield return PrepareCurrentCart(); + yield return ClearCartTests.ClearCart(CurrentCartId); + yield return FillCartTests.FillCart(new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}, CurrentCartId); + yield return CreateOrderWithFreeCart(CurrentCartId, false); + } + + [UnityTest] + public IEnumerator CreateOrderWithFreeParticularCart_InvalidUser_Failure() + { + yield return SignIn(); + yield return PrepareCurrentCart(); + yield return ClearCartTests.ClearCart(CurrentCartId); + yield return FillCartTests.FillCart(new List {new CartFillItem {sku = "Xsolla_free_item", quantity = 1}}, CurrentCartId); + yield return CreateOrderWithFreeCart(CurrentCartId, false); + } + + private static IEnumerator CreateOrderWithFreeCart(string cartId = null, bool isSuccessExpected = true) + { + yield return CheckSession(); + + var isComplete = false; + XsollaCart.CreateOrderWithFreeCart( + orderId => + { + isComplete = true; + if (isSuccessExpected) + { + Assert.NotNull(orderId); + Assert.Greater(orderId.order_id, 0); + } + else + { + Assert.Fail("Failure expected"); + } + }, + error => + { + isComplete = true; + if (isSuccessExpected) + { + Assert.Fail(error?.errorMessage); + } + else + { + Assert.NotNull(error); + Assert.NotNull(error.errorMessage); + } + }, + cartId); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/CreateOrderWithFreeCartTests.cs.meta b/Assets/Tests/Cart/CreateOrderWithFreeCartTests.cs.meta new file mode 100644 index 000000000..8d32fdfa5 --- /dev/null +++ b/Assets/Tests/Cart/CreateOrderWithFreeCartTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5e26b416a4f043c28c0f4cf00eff6acb +timeCreated: 1683624234 \ No newline at end of file diff --git a/Assets/Tests/Cart/FillCartTests.cs b/Assets/Tests/Cart/FillCartTests.cs new file mode 100644 index 000000000..3c3a19caa --- /dev/null +++ b/Assets/Tests/Cart/FillCartTests.cs @@ -0,0 +1,58 @@ +using System.Collections; +using System.Collections.Generic; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class FillCartTests : CartTestsBase + { + [UnityTest] + public IEnumerator FillCart_NoCartId_Success() + { + yield return FillCart(new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}); + } + + [UnityTest] + public IEnumerator FillCart_NoCartId_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return FillCart(new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}); + } + + [UnityTest] + public IEnumerator FillCart_CartId_Success() + { + yield return PrepareCurrentCart(); + yield return FillCart(new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}, CurrentCartId); + } + + [UnityTest] + public IEnumerator FillCart_CartId_InvalidToken_Success() + { + yield return PrepareCurrentCart(); + yield return SetOldAccessToken(); + yield return FillCart(new List {new CartFillItem {sku = "lootbox_1", quantity = 1}}, CurrentCartId); + } + + public static IEnumerator FillCart(List fillItems, string cartId = null) + { + yield return CheckSession(); + + var isComplete = false; + XsollaCart.FillCart( + fillItems, + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + cartId); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/FillCartTests.cs.meta b/Assets/Tests/Cart/FillCartTests.cs.meta new file mode 100644 index 000000000..1675e1aa9 --- /dev/null +++ b/Assets/Tests/Cart/FillCartTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7f7f5af63dae476b97aeff8ef477c462 +timeCreated: 1683622683 \ No newline at end of file diff --git a/Assets/Tests/Cart/GetCartItemsTests.cs b/Assets/Tests/Cart/GetCartItemsTests.cs new file mode 100644 index 000000000..fc917ab25 --- /dev/null +++ b/Assets/Tests/Cart/GetCartItemsTests.cs @@ -0,0 +1,76 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class GetCartItemsTests : CartTestsBase + { + [UnityTest] + public IEnumerator GetCartItems_DefaultValues_Success() + { + yield return GetCartItems(); + } + + [UnityTest] + public IEnumerator GetCartItems_Parametrized_Success() + { + yield return GetCartItems(); + } + + [UnityTest] + public IEnumerator GetCartItems_DefaultValues_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return GetCartItems(); + } + + [UnityTest] + public IEnumerator GetCartItems_DefaultValues_CartID_Success() + { + yield return PrepareCurrentCart(); + yield return GetCartItems(CurrentCartId); + } + + [UnityTest] + public IEnumerator GetCartItems_Parametrized_CartID_Success() + { + yield return PrepareCurrentCart(); + yield return GetCartItems(CurrentCartId, "en", "USD"); + } + + [UnityTest] + public IEnumerator GetCartItems_DefaultValues_CartID_InvalidToken_Success() + { + yield return PrepareCurrentCart(); + yield return SetOldAccessToken(); + yield return GetCartItems(CurrentCartId); + } + + private static IEnumerator GetCartItems(string cartId = null, string locale = null, string currency = null) + { + yield return CheckSession(); + + var isComplete = false; + XsollaCart.GetCartItems( + cart => + { + isComplete = true; + Assert.NotNull(cart); + Assert.NotNull(cart.items); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + cartId, + locale, + currency); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/GetCartItemsTests.cs.meta b/Assets/Tests/Cart/GetCartItemsTests.cs.meta new file mode 100644 index 000000000..e7df8b264 --- /dev/null +++ b/Assets/Tests/Cart/GetCartItemsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1019537a62bf48b3b96cc91270b5fb27 +timeCreated: 1683621997 \ No newline at end of file diff --git a/Assets/Tests/Cart/PurchaseCartTests.cs b/Assets/Tests/Cart/PurchaseCartTests.cs new file mode 100644 index 000000000..2e54ed871 --- /dev/null +++ b/Assets/Tests/Cart/PurchaseCartTests.cs @@ -0,0 +1,41 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class PurchaseCartTests : CartTestsBase + { + [UnityTest] + public IEnumerator PurchaseCart_NoCartId_Success() + { + yield return PurchaseCart(); + } + + [UnityTest] + public IEnumerator PurchaseCart_CartId_Success() + { + yield return PrepareCurrentCart(); + yield return PurchaseCart(CurrentCartId); + } + + private IEnumerator PurchaseCart(string cartId = null) + { + yield return CheckSession(); + + var isComplete = false; + XsollaCart.CreateOrder( + _ => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + cartId); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/PurchaseCartTests.cs.meta b/Assets/Tests/Cart/PurchaseCartTests.cs.meta new file mode 100644 index 000000000..a7ae49386 --- /dev/null +++ b/Assets/Tests/Cart/PurchaseCartTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f3266e17674d4aeca8e9ef84d99b12b3 +timeCreated: 1683624084 \ No newline at end of file diff --git a/Assets/Tests/Cart/RedeemPromocodeTests.cs b/Assets/Tests/Cart/RedeemPromocodeTests.cs new file mode 100644 index 000000000..2bfbfe23d --- /dev/null +++ b/Assets/Tests/Cart/RedeemPromocodeTests.cs @@ -0,0 +1,49 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class RedeemPromocodeTests : CartTestsBase + { + [UnityTest] + public IEnumerator RedeemPromocode_Success() + { + yield return PrepareCurrentCart(); + yield return RedeemPromocode(); + } + + [UnityTest] + public IEnumerator RedeemPromocode_InvalidToken_Success() + { + yield return PrepareCurrentCart(); + yield return SetOldAccessToken(); + yield return RedeemPromocode(); + } + + private IEnumerator RedeemPromocode() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCart.RedeemPromocode( + "NEWGAMER2020", + CurrentCartId, + cart => + { + isComplete = true; + Assert.NotNull(cart); + Assert.NotNull(cart.items); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/RedeemPromocodeTests.cs.meta b/Assets/Tests/Cart/RedeemPromocodeTests.cs.meta new file mode 100644 index 000000000..4f1f6c386 --- /dev/null +++ b/Assets/Tests/Cart/RedeemPromocodeTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f803f8fb3ed748d4a8c6c3eab82d26b1 +timeCreated: 1683623853 \ No newline at end of file diff --git a/Assets/Tests/Cart/RemoveItemFromCartTests.cs b/Assets/Tests/Cart/RemoveItemFromCartTests.cs new file mode 100644 index 000000000..25f6a9c76 --- /dev/null +++ b/Assets/Tests/Cart/RemoveItemFromCartTests.cs @@ -0,0 +1,57 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class RemoveItemFromCartTests : CartTestsBase + { + [UnityTest] + public IEnumerator RemoveItemFromCart_NoCartId_Success() + { + yield return RemoveItemFromCart(); + } + + [UnityTest] + public IEnumerator RemoveItemFromCart_NoCartId_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return RemoveItemFromCart(); + } + + [UnityTest] + public IEnumerator RemoveItemFromCart_CartId_Success() + { + yield return PrepareCurrentCart(); + yield return RemoveItemFromCart(CurrentCartId); + } + + [UnityTest] + public IEnumerator RemoveItemFromCart_CartId_InvalidToken_Success() + { + yield return PrepareCurrentCart(); + yield return SetOldAccessToken(); + yield return RemoveItemFromCart(CurrentCartId); + } + + private static IEnumerator RemoveItemFromCart(string cartId = null) + { + yield return CheckSession(); + + var isComplete = false; + XsollaCart.RemoveItemFromCart( + "lootbox_1", + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + cartId); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/RemoveItemFromCartTests.cs.meta b/Assets/Tests/Cart/RemoveItemFromCartTests.cs.meta new file mode 100644 index 000000000..8df0b8a04 --- /dev/null +++ b/Assets/Tests/Cart/RemoveItemFromCartTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e84222583ae84d4593f785a3f1ff0035 +timeCreated: 1683623442 \ No newline at end of file diff --git a/Assets/Tests/Cart/UpdateItemInCartTests.cs b/Assets/Tests/Cart/UpdateItemInCartTests.cs new file mode 100644 index 000000000..f8e1ada2d --- /dev/null +++ b/Assets/Tests/Cart/UpdateItemInCartTests.cs @@ -0,0 +1,58 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Cart; + +namespace Xsolla.Tests.Cart +{ + public class UpdateItemInCartTests : CartTestsBase + { + [UnityTest] + public IEnumerator UpdateItemInCart_NoCartId_Success() + { + yield return UpdateItemInCart(); + } + + [UnityTest] + public IEnumerator UpdateItemInCart_NoCartId_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return UpdateItemInCart(); + } + + [UnityTest] + public IEnumerator UpdateItemInCart_CartId_Success() + { + yield return PrepareCurrentCart(); + yield return UpdateItemInCart(CurrentCartId); + } + + [UnityTest] + public IEnumerator UpdateItemInCart_CartId_InvalidToken_Success() + { + yield return PrepareCurrentCart(); + yield return SetOldAccessToken(); + yield return UpdateItemInCart(CurrentCartId); + } + + private static IEnumerator UpdateItemInCart(string cartId = null) + { + yield return CheckSession(); + + var isComplete = false; + XsollaCart.UpdateItemInCart( + "lootbox_1", + 1, + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + cartId); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Cart/UpdateItemInCartTests.cs.meta b/Assets/Tests/Cart/UpdateItemInCartTests.cs.meta new file mode 100644 index 000000000..5da96228e --- /dev/null +++ b/Assets/Tests/Cart/UpdateItemInCartTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7ac13f0432ac4447a2cd1e3895422d04 +timeCreated: 1683623227 \ No newline at end of file diff --git a/Assets/Tests/API/XsollaCatalogTests.meta b/Assets/Tests/Catalog.meta similarity index 100% rename from Assets/Tests/API/XsollaCatalogTests.meta rename to Assets/Tests/Catalog.meta diff --git a/Assets/Tests/Catalog/CatalogTestsBase.cs b/Assets/Tests/Catalog/CatalogTestsBase.cs new file mode 100644 index 000000000..603865c75 --- /dev/null +++ b/Assets/Tests/Catalog/CatalogTestsBase.cs @@ -0,0 +1,78 @@ +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Tests.Catalog +{ + public class CatalogTestsBase : TestBase + { + [OneTimeSetUp] + [OneTimeTearDown] + public void Clear() + { + ClearEnv(); + } + + private const string PERSONALIZED_ITEM_SKU = "xsollus_personalized_item"; + private const string PROMOTION_ITEM_SKU = "sdk_team_special"; + + protected static void CheckPersonalization(IEnumerable items, bool exptected) + { + var itemWithPromotion = items.FirstOrDefault(x => x.sku == "sdk_special_pack_forxsollus"); + if (exptected) + Assert.NotNull(itemWithPromotion); + else + Assert.Null(itemWithPromotion); + } + + protected static void CheckPersonalization(IEnumerable items, bool exptected) + { + var itemWithPromotion = items.FirstOrDefault(x => x.sku == "crystal_pack_specialxsollus"); + if (exptected) + Assert.NotNull(itemWithPromotion); + else + Assert.Null(itemWithPromotion); + } + + protected static void CheckPersonalization(IEnumerable items, bool exptected) + { + var itemWithPromotion = items.FirstOrDefault(x => x.sku == PERSONALIZED_ITEM_SKU); + if (exptected) + Assert.NotNull(itemWithPromotion); + else + Assert.Null(itemWithPromotion); + } + + protected static void CheckPersonalization(IEnumerable items, bool expected) + { + var itemWithPromotion = items.FirstOrDefault(x => x.sku == PERSONALIZED_ITEM_SKU); + if (expected) + Assert.NotNull(itemWithPromotion); + else + Assert.Null(itemWithPromotion); + } + + protected static void CheckPromotion(IEnumerable items, bool expected) + { + var itemWithPromotion = items.FirstOrDefault(x => x.sku == PROMOTION_ITEM_SKU); + if (!expected) + { + Assert.Null(itemWithPromotion); + return; + } + + Assert.NotNull(itemWithPromotion); + + var promotionContainer = itemWithPromotion.promotions; + Assert.NotNull(promotionContainer); + Assert.IsTrue(promotionContainer.Length > 0); + + var promotionItem = promotionContainer[0]; + Assert.NotNull(promotionItem); + Assert.IsFalse(string.IsNullOrEmpty(promotionItem.date_start)); + Assert.IsFalse(string.IsNullOrEmpty(promotionItem.date_end)); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/CatalogTestsBase.cs.meta b/Assets/Tests/Catalog/CatalogTestsBase.cs.meta new file mode 100644 index 000000000..2870353fc --- /dev/null +++ b/Assets/Tests/Catalog/CatalogTestsBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 80efedc18b8a47a181b3827942b132f0 +timeCreated: 1683626332 \ No newline at end of file diff --git a/Assets/Tests/Catalog/CreateOrderWithSpecifiedFreeItemTests.cs b/Assets/Tests/Catalog/CreateOrderWithSpecifiedFreeItemTests.cs new file mode 100644 index 000000000..8365fbe24 --- /dev/null +++ b/Assets/Tests/Catalog/CreateOrderWithSpecifiedFreeItemTests.cs @@ -0,0 +1,80 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class CreateOrderWithSpecifiedFreeItemTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator CreateOrderWithSpecifiedFreeItem_Success() + { + yield return SignInAsTestUser(); + + var isComplete = false; + XsollaCatalog.CreateOrderWithFreeItem( + "Xsolla_free_item", + orderId => + { + isComplete = true; + Assert.NotNull(orderId); + Assert.Greater(orderId.order_id, 0); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator CreateOrderWithSpecifiedFreeItem_NonExistentSku_Failure() + { + yield return SignInAsTestUser(); + + var isComplete = false; + XsollaCatalog.CreateOrderWithFreeItem( + "abcdef", + orderId => + { + isComplete = true; + Assert.Fail("Order created with invalid sku"); + }, + error => + { + isComplete = true; + Assert.NotNull(error); + Assert.NotNull(error.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator CreateOrderWithSpecifiedFreeItem_InvalidUser_Failure() + { + yield return SignIn(); + + var isComplete = false; + XsollaCatalog.CreateOrderWithFreeItem( + "Xsolla_free_item", + orderId => + { + isComplete = true; + Assert.Fail("Order created with invalid user"); + }, + error => + { + isComplete = true; + Assert.NotNull(error); + Assert.NotNull(error.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/CreateOrderWithSpecifiedFreeItemTests.cs.meta b/Assets/Tests/Catalog/CreateOrderWithSpecifiedFreeItemTests.cs.meta new file mode 100644 index 000000000..0ace30a1e --- /dev/null +++ b/Assets/Tests/Catalog/CreateOrderWithSpecifiedFreeItemTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0dc8f0d4257c451eb2e9b6162d420655 +timeCreated: 1683638016 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetBundleTests.cs b/Assets/Tests/Catalog/GetBundleTests.cs new file mode 100644 index 000000000..985e9cac2 --- /dev/null +++ b/Assets/Tests/Catalog/GetBundleTests.cs @@ -0,0 +1,59 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetBundleTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetBundle_Default_Success() + { + yield return CheckSession(); + + var isComplete = false; + + XsollaCatalog.GetBundle( + "starter_pack", + item => + { + isComplete = true; + Assert.NotNull(item); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetBundle_Parametrized_Success() + { + yield return CheckSession(); + + var isComplete = false; + + XsollaCatalog.GetBundle( + "starter_pack", + item => + { + isComplete = true; + Assert.NotNull(item); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + "de_DE", + "DE"); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetBundleTests.cs.meta b/Assets/Tests/Catalog/GetBundleTests.cs.meta new file mode 100644 index 000000000..b62325b73 --- /dev/null +++ b/Assets/Tests/Catalog/GetBundleTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 80a322366ca84372a786d2f19fb030ad +timeCreated: 1683637145 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetBundlesTests.cs b/Assets/Tests/Catalog/GetBundlesTests.cs new file mode 100644 index 000000000..7da1a395d --- /dev/null +++ b/Assets/Tests/Catalog/GetBundlesTests.cs @@ -0,0 +1,76 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetBundlesTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetBundles_Default_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetBundles(items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + CheckPersonalization(items.items, false); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetBundles_Parametrized_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetBundles( + items => + { + isComplete = true; + Assert.AreEqual(items.items.Length, 1); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + locale: "de_DE", + limit: 1, + offset: 1); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetBundles_Personalized_HasPersonalizedItem() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetBundles( + items => + { + isComplete = true; + CheckPersonalization(items.items, true); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetBundlesTests.cs.meta b/Assets/Tests/Catalog/GetBundlesTests.cs.meta new file mode 100644 index 000000000..f2d7d2fbf --- /dev/null +++ b/Assets/Tests/Catalog/GetBundlesTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7050fcb2cd46486a83aa7c0ed450a207 +timeCreated: 1683636780 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetCatalogSimplifiedTests.cs b/Assets/Tests/Catalog/GetCatalogSimplifiedTests.cs new file mode 100644 index 000000000..f9b11682f --- /dev/null +++ b/Assets/Tests/Catalog/GetCatalogSimplifiedTests.cs @@ -0,0 +1,76 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetCatalogSimplifiedTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetCatalogSimplified_Default_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetCatalogSimplified( + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + CheckPersonalization(items.items, false); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetCatalogSimplified_Parametrized_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetCatalogSimplified( + items => + { + isComplete = true; + Assert.Greater(items.items.Length, 0); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + "de_DE"); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetCatalogSimplified_HasPersonalizedItem() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetCatalogSimplified( + items => + { + isComplete = true; + CheckPersonalization(items.items, true); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetCatalogSimplifiedTests.cs.meta b/Assets/Tests/Catalog/GetCatalogSimplifiedTests.cs.meta new file mode 100644 index 000000000..1c9afbd02 --- /dev/null +++ b/Assets/Tests/Catalog/GetCatalogSimplifiedTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f201a280890143c0a08d35b7fcc47de2 +timeCreated: 1683629135 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetCatalogTests.cs b/Assets/Tests/Catalog/GetCatalogTests.cs new file mode 100644 index 000000000..3da6c3053 --- /dev/null +++ b/Assets/Tests/Catalog/GetCatalogTests.cs @@ -0,0 +1,82 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetCatalogTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetCatalog_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetCatalog( + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + CheckPersonalization(items.items, false); + CheckPromotion(items.items, false); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetCatalog_Parametrized_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetCatalog( + items => + { + isComplete = true; + Assert.AreEqual(items.items.Length, 10); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + 10, + locale: "en_US", + country: "US"); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetCatalog_HasPersonalizedItem_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetCatalog( + items => + { + isComplete = true; + CheckPersonalization(items.items, true); + CheckPromotion(items.items, true); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetCatalogTests.cs.meta b/Assets/Tests/Catalog/GetCatalogTests.cs.meta new file mode 100644 index 000000000..de7ce26b6 --- /dev/null +++ b/Assets/Tests/Catalog/GetCatalogTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b51cfc627827493a98abee82bd65747c +timeCreated: 1683626385 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetCouponRewardsTests.cs b/Assets/Tests/Catalog/GetCouponRewardsTests.cs new file mode 100644 index 000000000..770ce2b80 --- /dev/null +++ b/Assets/Tests/Catalog/GetCouponRewardsTests.cs @@ -0,0 +1,64 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetCouponRewardsTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetCouponRewards_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetCouponRewards( + "TEST2022", + reward => + { + isComplete = true; + Assert.NotNull(reward); + Assert.Greater(reward.bonus.Length, 0); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetCouponRewards_IncorrectCode_Failure() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetCouponRewards( + "SUMMER1967", + reward => + { + isComplete = true; + Assert.Fail("Coupon code is incorrect"); + }, + error => + { + isComplete = true; + Assert.NotNull(error); + Assert.NotNull(error.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetCouponRewards_TEST2022_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return GetCouponRewards_Success(); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetCouponRewardsTests.cs.meta b/Assets/Tests/Catalog/GetCouponRewardsTests.cs.meta new file mode 100644 index 000000000..4e14dd8fb --- /dev/null +++ b/Assets/Tests/Catalog/GetCouponRewardsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 948d4a67634d41b483378c071d9493f8 +timeCreated: 1683637724 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetGroupItemsTests.cs b/Assets/Tests/Catalog/GetGroupItemsTests.cs new file mode 100644 index 000000000..dab5f3dc1 --- /dev/null +++ b/Assets/Tests/Catalog/GetGroupItemsTests.cs @@ -0,0 +1,83 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetGroupItemsTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetGroupItems_Default_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetGroupItems( + "Featured", + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + CheckPromotion(items.items, false); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetGroupItems_Parametrized_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetGroupItems( + "Featured", + items => + { + isComplete = true; + Assert.AreEqual(items.items.Length, 10); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + locale: "en_US", + country: "US", + limit: 10); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetGroupItems_HasPromotionItem() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetGroupItems( + "Featured", + items => + { + isComplete = true; + CheckPromotion(items.items, true); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetGroupItemsTests.cs.meta b/Assets/Tests/Catalog/GetGroupItemsTests.cs.meta new file mode 100644 index 000000000..02b9063be --- /dev/null +++ b/Assets/Tests/Catalog/GetGroupItemsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f28302e47b1e44099a196c8312fc805c +timeCreated: 1683629555 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetItemGroupsTests.cs b/Assets/Tests/Catalog/GetItemGroupsTests.cs new file mode 100644 index 000000000..fd5fbcfac --- /dev/null +++ b/Assets/Tests/Catalog/GetItemGroupsTests.cs @@ -0,0 +1,56 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetItemGroupsTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetItemGroups_Default_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetItemGroups( + groups => + { + isComplete = true; + Assert.NotNull(groups); + Assert.NotNull(groups.groups); + Assert.Greater(groups.groups.Length, 0); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetItemGroups_Parametrized_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetItemGroups( + groups => + { + isComplete = true; + Assert.Greater(groups.groups.Length, 0); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + locale: "en_US"); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetItemGroupsTests.cs.meta b/Assets/Tests/Catalog/GetItemGroupsTests.cs.meta new file mode 100644 index 000000000..ec4e2b31d --- /dev/null +++ b/Assets/Tests/Catalog/GetItemGroupsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cb0dd20952a64226b62459948d1e5615 +timeCreated: 1683635722 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetVirtualCurrencyListTests.cs b/Assets/Tests/Catalog/GetVirtualCurrencyListTests.cs new file mode 100644 index 000000000..3501c2088 --- /dev/null +++ b/Assets/Tests/Catalog/GetVirtualCurrencyListTests.cs @@ -0,0 +1,60 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetVirtualCurrencyListTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetVirtualCurrencyList_Default_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetVirtualCurrencyList( + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetVirtualCurrencyList_Parametrized_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetVirtualCurrencyList( + items => + { + isComplete = true; + Assert.AreEqual(items.items.Length, 1); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + 1, + 1, + "en_US", + "US", + "long_description"); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetVirtualCurrencyListTests.cs.meta b/Assets/Tests/Catalog/GetVirtualCurrencyListTests.cs.meta new file mode 100644 index 000000000..bb832eff1 --- /dev/null +++ b/Assets/Tests/Catalog/GetVirtualCurrencyListTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: eb7cfa7166cd459882cc1f562087c33e +timeCreated: 1683635973 \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetVirtualCurrencyPackagesListTests.cs b/Assets/Tests/Catalog/GetVirtualCurrencyPackagesListTests.cs new file mode 100644 index 000000000..1f35c4cf3 --- /dev/null +++ b/Assets/Tests/Catalog/GetVirtualCurrencyPackagesListTests.cs @@ -0,0 +1,77 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class GetVirtualCurrencyPackagesListTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator GetVirtualCurrencyPackagesList_Default_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetVirtualCurrencyPackagesList( + packages => + { + isComplete = true; + Assert.NotNull(packages); + Assert.NotNull(packages.items); + Assert.Greater(packages.items.Length, 0); + CheckPersonalization(packages.items, false); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetVirtualCurrencyPackagesList_Parametrized_Success() + { + DeleteSavedToken(); + + var isComplete = false; + XsollaCatalog.GetVirtualCurrencyPackagesList( + packages => + { + isComplete = true; + Assert.AreEqual(packages.items.Length, 1); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + 1, + locale: "en_US", + country: "US"); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetVirtualCurrencyPackagesList_Personalized_HasPersonalizedItem() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.GetVirtualCurrencyPackagesList( + packages => + { + isComplete = true; + CheckPersonalization(packages.items, true); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/GetVirtualCurrencyPackagesListTests.cs.meta b/Assets/Tests/Catalog/GetVirtualCurrencyPackagesListTests.cs.meta new file mode 100644 index 000000000..277faac0f --- /dev/null +++ b/Assets/Tests/Catalog/GetVirtualCurrencyPackagesListTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c1398165218a4df2b9109df0eca60c9c +timeCreated: 1683636333 \ No newline at end of file diff --git a/Assets/Tests/Catalog/RedeemCouponCodeTests.cs b/Assets/Tests/Catalog/RedeemCouponCodeTests.cs new file mode 100644 index 000000000..09e46a897 --- /dev/null +++ b/Assets/Tests/Catalog/RedeemCouponCodeTests.cs @@ -0,0 +1,65 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Catalog; + +namespace Xsolla.Tests.Catalog +{ + public class RedeemCouponCodeTests : CatalogTestsBase + { + [UnityTest] + public IEnumerator RedeemCouponCode_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.RedeemCouponCode( + "TEST2022", + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator RedeemCouponCode_IncorrectCode_Failure() + { + yield return CheckSession(); + + var isComplete = false; + XsollaCatalog.RedeemCouponCode( + "SUMMER1967", + items => + { + isComplete = true; + Assert.Fail("Coupon code is incorrect"); + }, + error => + { + isComplete = true; + Assert.NotNull(error); + Assert.NotNull(error.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator RedeemCouponCode_TEST2022_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return RedeemCouponCode_Success(); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Catalog/RedeemCouponCodeTests.cs.meta b/Assets/Tests/Catalog/RedeemCouponCodeTests.cs.meta new file mode 100644 index 000000000..2c2801ab0 --- /dev/null +++ b/Assets/Tests/Catalog/RedeemCouponCodeTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2b2a46d5c9804b33afa98d4985f25bc9 +timeCreated: 1683637391 \ No newline at end of file diff --git a/Assets/Tests/API/XsollaInventoryTests.meta b/Assets/Tests/Inventory.meta similarity index 100% rename from Assets/Tests/API/XsollaInventoryTests.meta rename to Assets/Tests/Inventory.meta diff --git a/Assets/Tests/Inventory/ConsumeInventoryItemTests.cs b/Assets/Tests/Inventory/ConsumeInventoryItemTests.cs new file mode 100644 index 000000000..b3b175d85 --- /dev/null +++ b/Assets/Tests/Inventory/ConsumeInventoryItemTests.cs @@ -0,0 +1,63 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Inventory; + +namespace Xsolla.Tests.Inventory +{ + public class ConsumeInventoryItemTests : InventoryTestsBase + { + private static ConsumeItem GenerateItemForConsume() + { + return new ConsumeItem { + sku = "lootbox_1", + quantity = 1 + }; + } + + [UnityTest] + public IEnumerator ConsumeInventoryItem_DefaultValues_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaInventory.ConsumeInventoryItem( + GenerateItemForConsume(), + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator ConsumeInventoryItem_Parametrized_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaInventory.ConsumeInventoryItem( + GenerateItemForConsume(), + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + "xsolla"); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator ConsumeInventoryItem_DefaultValues_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return ConsumeInventoryItem_DefaultValues_Success(); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Inventory/ConsumeInventoryItemTests.cs.meta b/Assets/Tests/Inventory/ConsumeInventoryItemTests.cs.meta new file mode 100644 index 000000000..3607beaa2 --- /dev/null +++ b/Assets/Tests/Inventory/ConsumeInventoryItemTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 999168b1b75a4bf985852a57f1496269 +timeCreated: 1683643363 \ No newline at end of file diff --git a/Assets/Tests/Inventory/GetInventoryItemsTests.cs b/Assets/Tests/Inventory/GetInventoryItemsTests.cs new file mode 100644 index 000000000..afcf407cc --- /dev/null +++ b/Assets/Tests/Inventory/GetInventoryItemsTests.cs @@ -0,0 +1,65 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Inventory; + +namespace Xsolla.Tests.Inventory +{ + public class GetInventoryItemsTests : InventoryTestsBase + { + [UnityTest] + public IEnumerator GetInventoryItems_Default_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaInventory.GetInventoryItems( + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetInventoryItems_Parametrized_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaInventory.GetInventoryItems( + items => + { + isComplete = true; + Assert.AreEqual(items.items.Length, 5); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + 5, + 0, + "en_US", + "xsolla"); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetInventoryItems_DefaultValues_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return GetInventoryItems_Default_Success(); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Inventory/GetInventoryItemsTests.cs.meta b/Assets/Tests/Inventory/GetInventoryItemsTests.cs.meta new file mode 100644 index 000000000..181bf80c5 --- /dev/null +++ b/Assets/Tests/Inventory/GetInventoryItemsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8831e11602eb47adb02201e41ec8be64 +timeCreated: 1683643006 \ No newline at end of file diff --git a/Assets/Tests/Inventory/GetTimeLimitedItemsTests.cs b/Assets/Tests/Inventory/GetTimeLimitedItemsTests.cs new file mode 100644 index 000000000..67bdb7c98 --- /dev/null +++ b/Assets/Tests/Inventory/GetTimeLimitedItemsTests.cs @@ -0,0 +1,52 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Inventory; + +namespace Xsolla.Tests.Inventory +{ + public class GetTimeLimitedItemsTests : InventoryTestsBase + { + [UnityTest] + public IEnumerator GetTimeLimitedItems_DefaultValues_Success() + { + yield return GetTimeLimitedItems(); + } + + [UnityTest] + public IEnumerator GetTimeLimitedItems_Parametrized_Success() + { + yield return GetTimeLimitedItems("xsolla"); + } + + [UnityTest] + public IEnumerator GetTimeLimitedItems_DefaultValues_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return GetTimeLimitedItems(); + } + + private static IEnumerator GetTimeLimitedItems(string platform = null) + { + yield return CheckSession(); + + var isComplete = false; + XsollaInventory.GetTimeLimitedItems( + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + platform); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Inventory/GetTimeLimitedItemsTests.cs.meta b/Assets/Tests/Inventory/GetTimeLimitedItemsTests.cs.meta new file mode 100644 index 000000000..7e1e8d9ef --- /dev/null +++ b/Assets/Tests/Inventory/GetTimeLimitedItemsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5722a1a0ae734879843d8d5a67dafac2 +timeCreated: 1683643641 \ No newline at end of file diff --git a/Assets/Tests/Inventory/GetVirtualCurrencyBalanceTests.cs b/Assets/Tests/Inventory/GetVirtualCurrencyBalanceTests.cs new file mode 100644 index 000000000..49867be48 --- /dev/null +++ b/Assets/Tests/Inventory/GetVirtualCurrencyBalanceTests.cs @@ -0,0 +1,60 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Inventory; + +namespace Xsolla.Tests.Inventory +{ + public class GetVirtualCurrencyBalanceTests : InventoryTestsBase + { + [UnityTest] + public IEnumerator GetVirtualCurrencyBalance_Default_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaInventory.GetVirtualCurrencyBalance(balances => + { + isComplete = true; + Assert.NotNull(balances); + Assert.NotNull(balances.items); + Assert.Greater(balances.items.Length, 0); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetVirtualCurrencyBalance_Parametrized_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaInventory.GetVirtualCurrencyBalance( + balances => + { + isComplete = true; + Assert.NotNull(balances); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + "xsolla"); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetVirtualCurrencyBalance_DefaultValues_InvalidToken_Success() + { + yield return SetOldAccessToken(); + yield return GetVirtualCurrencyBalance_Default_Success(); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Inventory/GetVirtualCurrencyBalanceTests.cs.meta b/Assets/Tests/Inventory/GetVirtualCurrencyBalanceTests.cs.meta new file mode 100644 index 000000000..b84f379bf --- /dev/null +++ b/Assets/Tests/Inventory/GetVirtualCurrencyBalanceTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e65693c5003e42cb9c53a9577b3878d7 +timeCreated: 1683642631 \ No newline at end of file diff --git a/Assets/Tests/Inventory/InventoryTestsBase.cs b/Assets/Tests/Inventory/InventoryTestsBase.cs new file mode 100644 index 000000000..0ac5ba5dd --- /dev/null +++ b/Assets/Tests/Inventory/InventoryTestsBase.cs @@ -0,0 +1,14 @@ +using NUnit.Framework; + +namespace Xsolla.Tests.Inventory +{ + public class InventoryTestsBase : TestBase + { + [OneTimeSetUp] + [OneTimeTearDown] + public void Clear() + { + ClearEnv(); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Inventory/InventoryTestsBase.cs.meta b/Assets/Tests/Inventory/InventoryTestsBase.cs.meta new file mode 100644 index 000000000..50b5d9a37 --- /dev/null +++ b/Assets/Tests/Inventory/InventoryTestsBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d990a6860475447c9d6a422c4d89a3a5 +timeCreated: 1683642553 \ No newline at end of file diff --git a/Assets/Tests/API/XsollaSubscriptionsTests.meta b/Assets/Tests/Subscriptions.meta similarity index 100% rename from Assets/Tests/API/XsollaSubscriptionsTests.meta rename to Assets/Tests/Subscriptions.meta diff --git a/Assets/Tests/Subscriptions/GetPlans.cs b/Assets/Tests/Subscriptions/GetPlans.cs new file mode 100644 index 000000000..7ac555a86 --- /dev/null +++ b/Assets/Tests/Subscriptions/GetPlans.cs @@ -0,0 +1,96 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Subscriptions; + +namespace Xsolla.Tests.Subscriptions +{ + public class GetPlans : SubscriptionsTestsBase + { + [UnityTest] + public IEnumerator GetSubscriptionPlans_Default_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaSubscriptions.GetSubscriptionPlans( + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetSubscriptionPlans_FilteredByPlanId_Success() + { + yield return GetSubscriptionPlans_Filtered(268800, null, 1); + } + + [UnityTest] + public IEnumerator GetSubscriptionPlans_FilteredByNonExistentPlanId_Success() + { + yield return GetSubscriptionPlans_Filtered(123, null, 0); + } + + [UnityTest] + public IEnumerator GetSubscriptionPlans_FilteredByExternalId_Success() + { + yield return GetSubscriptionPlans_Filtered(null, "tNuy9WMo", 1); + } + + [UnityTest] + public IEnumerator GetSubscriptionPlans_FilteredByNonExistentExternalId_Success() + { + yield return GetSubscriptionPlans_Filtered(null, "123", 0); + } + + private static IEnumerator GetSubscriptionPlans_Filtered(int? planId, string planExternalId, int expectedCount) + { + yield return CheckSession(); + + int[] planIdFilter = null; + if (planId.HasValue) + { + planIdFilter = new[] { + planId.Value + }; + } + + string[] planExternalIdFilter = null; + if (!string.IsNullOrEmpty(planExternalId)) + { + planExternalIdFilter = new[] { + planExternalId + }; + } + + var isComplete = false; + XsollaSubscriptions.GetSubscriptionPlans( + plans => + { + isComplete = true; + Assert.AreEqual(plans.items.Length, expectedCount); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + planIdFilter, + planExternalIdFilter + ); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Subscriptions/GetPlans.cs.meta b/Assets/Tests/Subscriptions/GetPlans.cs.meta new file mode 100644 index 000000000..dc3b24fdd --- /dev/null +++ b/Assets/Tests/Subscriptions/GetPlans.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f62afe29697248d981b508dc1dbd6cc1 +timeCreated: 1683644902 \ No newline at end of file diff --git a/Assets/Tests/Subscriptions/GetPublicPlans.cs b/Assets/Tests/Subscriptions/GetPublicPlans.cs new file mode 100644 index 000000000..8953036c6 --- /dev/null +++ b/Assets/Tests/Subscriptions/GetPublicPlans.cs @@ -0,0 +1,99 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Subscriptions; + +namespace Xsolla.Tests.Subscriptions +{ + public class GetPublicPlans : SubscriptionsTestsBase + { + [UnityTest] + public IEnumerator GetSubscriptionPublicPlans_Default_Success() + { + yield return SignOut(); + + var isComplete = false; + XsollaSubscriptions.GetSubscriptionPublicPlans( + plans => + { + isComplete = true; + Assert.NotNull(plans); + Assert.NotNull(plans.items); + Assert.Greater(plans.items.Length, 0); + Assert.IsFalse(plans.has_more); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + } + ); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetSubscriptionPublicPlans_FilteredByPlanId_Success() + { + yield return GetSubscriptionPublicPlans_Filtered(268800, null, 1); + } + + [UnityTest] + public IEnumerator GetSubscriptionPublicPlans_FilteredByNonExistentPlanId_Success() + { + yield return GetSubscriptionPublicPlans_Filtered(123, null, 0); + } + + [UnityTest] + public IEnumerator GetSubscriptionPublicPlans_FilteredByExternalId_Success() + { + yield return GetSubscriptionPublicPlans_Filtered(null, "tNuy9WMo", 1); + } + + [UnityTest] + public IEnumerator GetSubscriptionPublicPlans_FilteredBNonExistentExternalId_Success() + { + yield return GetSubscriptionPublicPlans_Filtered(null, "123", 0); + } + + private static IEnumerator GetSubscriptionPublicPlans_Filtered(int? planId, string planExternalId, int expectedCount) + { + yield return SignOut(); + + int[] planIdFilter = null; + if (planId.HasValue) + { + planIdFilter = new[] { + planId.Value + }; + } + + string[] planExternalIdFilter = null; + if (!string.IsNullOrEmpty(planExternalId)) + { + planExternalIdFilter = new[] { + planExternalId + }; + } + + var isComplete = false; + XsollaSubscriptions.GetSubscriptionPublicPlans( + plans => + { + isComplete = true; + Assert.AreEqual(plans.items.Length, expectedCount); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }, + planIdFilter, + planExternalIdFilter + ); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Subscriptions/GetPublicPlans.cs.meta b/Assets/Tests/Subscriptions/GetPublicPlans.cs.meta new file mode 100644 index 000000000..73d1d0268 --- /dev/null +++ b/Assets/Tests/Subscriptions/GetPublicPlans.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 647f3e42da8141059c30bdb4e00c67fa +timeCreated: 1683643975 \ No newline at end of file diff --git a/Assets/Tests/Subscriptions/GetSubscriptionsTests.cs b/Assets/Tests/Subscriptions/GetSubscriptionsTests.cs new file mode 100644 index 000000000..2e76eeea3 --- /dev/null +++ b/Assets/Tests/Subscriptions/GetSubscriptionsTests.cs @@ -0,0 +1,99 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using Xsolla.Subscriptions; + +namespace Xsolla.Tests.Subscriptions +{ + public class GetSubscriptionsTests : SubscriptionsTestsBase + { + [UnityTest] + public IEnumerator GetSubscriptions_Default_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaSubscriptions.GetSubscriptions( + items => + { + isComplete = true; + Assert.NotNull(items); + Assert.NotNull(items.items); + Assert.Greater(items.items.Length, 0); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetSubscriptionDetails_Default_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaSubscriptions.GetSubscriptionDetails( + 65045530, + details => + { + isComplete = true; + Assert.NotNull(details); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetSubscriptionPurchaseUrl_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaSubscriptions.GetSubscriptionPurchaseUrl( + "tNuy9WMo", + link => + { + isComplete = true; + Assert.NotNull(link); + Assert.NotNull(link.link_to_ps); + }, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + } + ); + + yield return new WaitUntil(() => isComplete); + } + + [UnityTest] + public IEnumerator GetSubscriptionManagementUrl_Success() + { + yield return CheckSession(); + + var isComplete = false; + XsollaSubscriptions.GetSubscriptionManagementUrl( + link => + { + isComplete = true; + Assert.NotNull(link); + Assert.NotNull(link.link_to_ps); + }, error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Subscriptions/GetSubscriptionsTests.cs.meta b/Assets/Tests/Subscriptions/GetSubscriptionsTests.cs.meta new file mode 100644 index 000000000..a70ef393e --- /dev/null +++ b/Assets/Tests/Subscriptions/GetSubscriptionsTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 49573d302d5f4077916191d5d647f538 +timeCreated: 1683645345 \ No newline at end of file diff --git a/Assets/Tests/Subscriptions/SubscriptionsTestsBase.cs b/Assets/Tests/Subscriptions/SubscriptionsTestsBase.cs new file mode 100644 index 000000000..ac26c549b --- /dev/null +++ b/Assets/Tests/Subscriptions/SubscriptionsTestsBase.cs @@ -0,0 +1,14 @@ +using NUnit.Framework; + +namespace Xsolla.Tests.Subscriptions +{ + public class SubscriptionsTestsBase : TestBase + { + [OneTimeSetUp] + [OneTimeTearDown] + public void Clear() + { + ClearEnv(); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/Subscriptions/SubscriptionsTestsBase.cs.meta b/Assets/Tests/Subscriptions/SubscriptionsTestsBase.cs.meta new file mode 100644 index 000000000..3811c618c --- /dev/null +++ b/Assets/Tests/Subscriptions/SubscriptionsTestsBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 70ebf7f1518c4980bcc7a7073ca4712e +timeCreated: 1683643947 \ No newline at end of file diff --git a/Assets/Tests/TestBase.cs b/Assets/Tests/TestBase.cs new file mode 100644 index 000000000..a0535cd50 --- /dev/null +++ b/Assets/Tests/TestBase.cs @@ -0,0 +1,88 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Tests +{ + public class TestBase + { + private const string OLD_ACCESS_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOltdLCJlbWFpbCI6Inhzb2xsYXN0b3Jlc2RrLmFAZ21haWwuY29tIiwiZXhwIjoxNjQ4NDYwMzc2LCJncm91cHMiOlt7ImlkIjo2NDgxLCJuYW1lIjoiZGVmYXVsdCIsImlzX2RlZmF1bHQiOnRydWV9XSwiaWF0IjoxNjQ4MzczOTc2LCJpc19tYXN0ZXIiOnRydWUsImlzcyI6Imh0dHBzOi8vbG9naW4ueHNvbGxhLmNvbSIsImp0aSI6ImFhNzRhMTVhLWIxNWQtNGM4MS1hYzUxLTdmNGE1OTVkYWU5YyIsInByb21vX2VtYWlsX2FncmVlbWVudCI6dHJ1ZSwicHVibGlzaGVyX2lkIjoxMzY1OTMsInNjcCI6WyJvZmZsaW5lIl0sInN1YiI6IjE0ZGNiMzQzLWFkMjUtNDZhOS05YjE2LWJjZWVjNWNmN2NjZiIsInR5cGUiOiJ4c29sbGFfbG9naW4iLCJ1c2VybmFtZSI6Inhzb2xsYSIsInhzb2xsYV9sb2dpbl9hY2Nlc3Nfa2V5Ijoialpta3dObUlsZ25IZVVCSE8xRURRUFhleHJhdjJYdEk4Y1FJeF90ajliZyIsInhzb2xsYV9sb2dpbl9wcm9qZWN0X2lkIjoiMDI2MjAxZTMtN2U0MC0xMWVhLWE4NWItNDIwMTBhYTgwMDA0In0.Y4qJ0_UStkND4Xsjhy1P0EUv1DLswxybxLKW8IV6N3Y"; + private const string OLD_REFRESH_TOKEN = "W0qQwxh5rJe4wK3VREv1qsGnxUKQfZNvJkYJq7lMPCA.6HeK7wKy1cZAy2STRk8sTcplcA7TiglrT5K3kn-lClc"; + + protected static void ClearEnv() + { + DeleteSavedToken(); + Object.DestroyImmediate(WebRequestHelper.Instance.gameObject); + } + + protected static void DeleteSavedToken() + { + XsollaToken.DeleteSavedInstance(); + } + + protected static IEnumerator SetOldAccessToken() + { + yield return SignIn(); + var refreshToken = XsollaToken.RefreshToken; + XsollaToken.Create(OLD_ACCESS_TOKEN, refreshToken); + } + + protected static IEnumerator SetOldRefreshToken() + { + yield return SignIn(); + var accessToken = XsollaToken.AccessToken; + XsollaToken.Create(accessToken, OLD_REFRESH_TOKEN); + } + + protected static IEnumerator CheckSession() + { + if (!XsollaToken.Exists) + yield return SignIn(); + } + + protected static IEnumerator SignInAsTestUser() + { + yield return SignIn("sdk@xsolla.com", "1qazXSW@"); + } + + protected static IEnumerator SignIn() + { + yield return SignIn("xsolla", "xsolla"); + } + + private static IEnumerator SignIn(string username, string password) + { + var isComplete = false; + XsollaAuth.SignIn( + username, + password, + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + + protected static IEnumerator SignOut() + { + if (!XsollaToken.Exists) + yield break; + + var isComplete = false; + XsollaAuth.Logout( + () => isComplete = true, + error => + { + isComplete = true; + Assert.Fail(error?.errorMessage); + }); + + yield return new WaitUntil(() => isComplete); + } + } +} \ No newline at end of file diff --git a/Assets/Tests/TestBase.cs.meta b/Assets/Tests/TestBase.cs.meta new file mode 100644 index 000000000..f0a3e572a --- /dev/null +++ b/Assets/Tests/TestBase.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 88bc094555fc45fca7e4e43d0824a49d +timeCreated: 1683646615 \ No newline at end of file diff --git a/Assets/Tests/TestUtils/TestHelper.cs b/Assets/Tests/TestUtils/TestHelper.cs deleted file mode 100644 index 39d075c6e..000000000 --- a/Assets/Tests/TestUtils/TestHelper.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Runtime.CompilerServices; -using NUnit.Framework; -using UnityEngine; -using Xsolla.Core; -using Xsolla.Auth; -using Xsolla.Catalog; -using Xsolla.Cart; -using Xsolla.Inventory; -using Xsolla.GameKeys; -using Xsolla.Orders; -using Xsolla.Subscriptions; -using Xsolla.UserAccount; - -using Debug = UnityEngine.Debug; - -namespace Xsolla.Tests -{ - public class TestHelper - { - public static void Pass([CallerMemberName] string testName = null) - { - Debug.Log($"SUCCESS: '{testName}'"); - } - - public static void Pass(string additionalInfo, [CallerMemberName] string testName = null) - { - Debug.Log($"SUCCESS: '{testName}' info: '{additionalInfo}'"); - } - - public static void Pass(TestSignInHelper.SignInResult signInResult, [CallerMemberName] string testName = null) - { - Debug.Log($"SUCCESS: '{testName}' signInSuccess: '{signInResult?.success}' signInError: '{signInResult?.errorMessage ?? "ERROR IS NULL"}'"); - } - - public static void Fail([CallerMemberName] string testName = null) - { - var message = $"FAIL: '{testName}'"; - Debug.LogError(message); - Assert.Fail(message); - } - - public static void Fail(string additionalInfo, [CallerMemberName] string testName = null) - { - var message = $"FAIL: '{testName}' info: '{additionalInfo}'"; - Debug.LogError(message); - Assert.Fail(message); - } - - public static void Fail(TestSignInHelper.SignInResult signInResult, [CallerMemberName] string testName = null) - { - var message = $"FAIL: '{testName}' signInSuccess: '{signInResult?.success}' signInError: '{signInResult?.errorMessage ?? "ERROR IS NULL"}'"; - Debug.LogError(message); - Assert.Fail(message); - } - - public static void Fail(Error error, [CallerMemberName] string testName = null) - { - var message = $"FAIL: '{testName}' error: '{error?.errorMessage ?? "ERROR IS NULL"}'"; - Debug.LogError(message); - Assert.Fail(message); - } - - public static void CheckTokenChanged([CallerMemberName] string testName = null) - { - string oldToken = TestSignInHelper.Instance.OldToken; - CheckTokenChanged(oldToken, testName); - } - - public static void CheckTokenChanged(string oldToken, [CallerMemberName] string testName = null) - { - string newToken = Token.Instance; - - if (newToken != oldToken) - Pass("TOKEN CHANGED", testName); - else - Fail("TOKEN DID NOT CHANGE", testName); - } - - public static void Clear() - { - //Clear Token and Refresh Token - if (Token.Instance != null) - Token.Instance = null; - if (TokenRefresh.IsExist) - GameObject.DestroyImmediate(TokenRefresh.Instance.gameObject); - - PlayerPrefs.DeleteKey(Constants.LAST_SUCCESS_AUTH_TOKEN); - PlayerPrefs.DeleteKey(Constants.LAST_SUCCESS_OAUTH_REFRESH_TOKEN); - - //Delete temporary objects if any - if (XsollaAuth.IsExist) - GameObject.DestroyImmediate(XsollaAuth.Instance.gameObject); - if (XsollaCart.IsExist) - GameObject.DestroyImmediate(XsollaCart.Instance.gameObject); - if (XsollaCatalog.IsExist) - GameObject.DestroyImmediate(XsollaCatalog.Instance.gameObject); - if (XsollaGameKeys.IsExist) - GameObject.DestroyImmediate(XsollaGameKeys.Instance.gameObject); - if (XsollaInventory.IsExist) - GameObject.DestroyImmediate(XsollaInventory.Instance.gameObject); - if (XsollaOrders.IsExist) - GameObject.DestroyImmediate(XsollaOrders.Instance.gameObject); - if (XsollaSubscriptions.IsExist) - GameObject.DestroyImmediate(XsollaSubscriptions.Instance.gameObject); - if (XsollaUserAccount.IsExist) - GameObject.DestroyImmediate(XsollaUserAccount.Instance.gameObject); - - //Delete temporary util objects if any - if (TestSignInHelper.IsExist) - GameObject.DestroyImmediate(TestSignInHelper.Instance.gameObject); - if (WebRequestHelper.IsExist) - GameObject.DestroyImmediate(WebRequestHelper.Instance.gameObject); - } - } -} \ No newline at end of file diff --git a/Assets/Tests/TestUtils/XsollaTests.asmref b/Assets/Tests/TestUtils/XsollaTests.asmref deleted file mode 100644 index e13a794a1..000000000 --- a/Assets/Tests/TestUtils/XsollaTests.asmref +++ /dev/null @@ -1,3 +0,0 @@ -{ - "reference": "GUID:6cba6d6de9fada24a9cd30e8613b8746" -} \ No newline at end of file diff --git a/Assets/Tests/TestUtils/XsollaTests.asmref.meta b/Assets/Tests/TestUtils/XsollaTests.asmref.meta deleted file mode 100644 index 7406e10ee..000000000 --- a/Assets/Tests/TestUtils/XsollaTests.asmref.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: f271da1d09e009e4eaebc6eeddc0b27c -AssemblyDefinitionReferenceImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Tests/TestUtilsMonobehaviour/TestSignInHelper.cs b/Assets/Tests/TestUtilsMonobehaviour/TestSignInHelper.cs deleted file mode 100644 index 41ede90ac..000000000 --- a/Assets/Tests/TestUtilsMonobehaviour/TestSignInHelper.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections; -using UnityEngine; -using Xsolla.Auth; -using Xsolla.Core; - -namespace Xsolla.Tests -{ - public class TestSignInHelper : MonoSingleton - { - private const string OLD_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOltdLCJlbWFpbCI6Inhzb2xsYXN0b3Jlc2RrLmFAZ21haWwuY29tIiwiZXhwIjoxNjQ4NDYwMzc2LCJncm91cHMiOlt7ImlkIjo2NDgxLCJuYW1lIjoiZGVmYXVsdCIsImlzX2RlZmF1bHQiOnRydWV9XSwiaWF0IjoxNjQ4MzczOTc2LCJpc19tYXN0ZXIiOnRydWUsImlzcyI6Imh0dHBzOi8vbG9naW4ueHNvbGxhLmNvbSIsImp0aSI6ImFhNzRhMTVhLWIxNWQtNGM4MS1hYzUxLTdmNGE1OTVkYWU5YyIsInByb21vX2VtYWlsX2FncmVlbWVudCI6dHJ1ZSwicHVibGlzaGVyX2lkIjoxMzY1OTMsInNjcCI6WyJvZmZsaW5lIl0sInN1YiI6IjE0ZGNiMzQzLWFkMjUtNDZhOS05YjE2LWJjZWVjNWNmN2NjZiIsInR5cGUiOiJ4c29sbGFfbG9naW4iLCJ1c2VybmFtZSI6Inhzb2xsYSIsInhzb2xsYV9sb2dpbl9hY2Nlc3Nfa2V5Ijoialpta3dObUlsZ25IZVVCSE8xRURRUFhleHJhdjJYdEk4Y1FJeF90ajliZyIsInhzb2xsYV9sb2dpbl9wcm9qZWN0X2lkIjoiMDI2MjAxZTMtN2U0MC0xMWVhLWE4NWItNDIwMTBhYTgwMDA0In0.Y4qJ0_UStkND4Xsjhy1P0EUv1DLswxybxLKW8IV6N3Y"; - - public string OldToken => OLD_TOKEN; - - public IEnumerator SignIn(string login = "xsolla", string password = "xsolla", Action callback = null) - { - bool? success = default; - string errorMessage = default; - - Action onSuccess = _ => success = true; - Action onError = error => { errorMessage = error?.errorMessage ?? "ERROR IS NULL"; success = false; }; - - XsollaAuth.Instance.SignIn(login, password, false, null, null, onSuccess, onError); - - yield return new WaitUntil(() => success.HasValue); - - callback?.Invoke(new SignInResult(success.Value, errorMessage)); - } - - public IEnumerator SignInAsTestUser() - { - yield return SignIn("sdk@xsolla.com", "1qazXSW@"); - } - - public IEnumerator SignOut() - { - if (Token.Instance == null) - yield break; - - bool? success = default; - string errorMessage = default; - - Action onSuccess = () => success = true; - Action onError = error => - { - errorMessage = error?.errorMessage ?? "ERROR IS NULL"; - UnityEngine.Debug.LogError(errorMessage); - success = false; - }; - - XsollaAuth.Instance.OAuthLogout( - token: Token.Instance, - sessions: OAuthLogoutType.All, - onSuccess: onSuccess, - onError: onError); - - yield return new WaitUntil(() => success.HasValue); - - Token.Instance = null; - TokenRefresh.Instance.RefreshToken = string.Empty; - } - - public IEnumerator CheckSession() - { - if (Token.Instance == null || - string.IsNullOrEmpty(TokenRefresh.Instance.RefreshToken) || - !XsollaAuth.IsExist) - { - yield return GenerateNewSession(); - } - } - - public IEnumerator SetOldToken() - { - yield return GenerateNewSession(); - Token.Instance = Token.Create(OLD_TOKEN); - } - - public IEnumerator GenerateNewSession() - { - if (!XsollaAuth.IsExist) - XsollaAuth.Instance.Init(); - - if (Token.Instance != null) - yield return SignOut(); - - yield return TestSignInHelper.Instance.SignIn(); - } - - public class SignInResult - { - public readonly bool success; - public readonly string errorMessage; - - public SignInResult(bool success, string errorMessage) - { - this.success = success; - this.errorMessage = errorMessage; - } - } - } -} \ No newline at end of file diff --git a/Assets/Tests/TestUtilsMonobehaviour/TestSignInHelper.cs.meta b/Assets/Tests/TestUtilsMonobehaviour/TestSignInHelper.cs.meta deleted file mode 100644 index ddc9ec5dd..000000000 --- a/Assets/Tests/TestUtilsMonobehaviour/TestSignInHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bb2cb5726f6dc1f4d803df1140a51945 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Tests/TestUtilsMonobehaviour/Xsolla.asmref b/Assets/Tests/TestUtilsMonobehaviour/Xsolla.asmref deleted file mode 100644 index 24634ea00..000000000 --- a/Assets/Tests/TestUtilsMonobehaviour/Xsolla.asmref +++ /dev/null @@ -1,3 +0,0 @@ -{ - "reference": "GUID:ae0cf701846f0cc4bbd067c4edd4fe90" -} \ No newline at end of file diff --git a/Assets/Tests/TestUtilsMonobehaviour/Xsolla.asmref.meta b/Assets/Tests/TestUtilsMonobehaviour/Xsolla.asmref.meta deleted file mode 100644 index b470fdb64..000000000 --- a/Assets/Tests/TestUtilsMonobehaviour/Xsolla.asmref.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 9d6247bf111859f4fbace6b1abd35f10 -AssemblyDefinitionReferenceImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Tests/API/Xsolla.Tests.asmdef b/Assets/Tests/Xsolla.Tests.asmdef similarity index 100% rename from Assets/Tests/API/Xsolla.Tests.asmdef rename to Assets/Tests/Xsolla.Tests.asmdef diff --git a/Assets/Tests/API/Xsolla.Tests.asmdef.meta b/Assets/Tests/Xsolla.Tests.asmdef.meta similarity index 100% rename from Assets/Tests/API/Xsolla.Tests.asmdef.meta rename to Assets/Tests/Xsolla.Tests.asmdef.meta diff --git a/Assets/Xsolla.Demo/Common/DemoSettings/DemoSettings.cs b/Assets/Xsolla.Demo/Common/DemoSettings/DemoSettings.cs index fa38706a3..c9e971fc7 100644 --- a/Assets/Xsolla.Demo/Common/DemoSettings/DemoSettings.cs +++ b/Assets/Xsolla.Demo/Common/DemoSettings/DemoSettings.cs @@ -11,13 +11,13 @@ public class DemoSettings : ScriptableObject [SerializeField] private bool _requestNicknameOnAuth = true; [SerializeField] private string webStoreUrl = Constants.DEFAULT_WEB_STORE_URL; - [SerializeField] private bool useSteamAuth = default; + [SerializeField] private bool useSteamAuth; [SerializeField] private string steamAppId = "480"; [SerializeField] private PaymentsFlow paymentsFlow = PaymentsFlow.XsollaPayStation; [SerializeField] private PlatformType platform = PlatformType.Xsolla; - [SerializeField] private bool useConsoleAuth = default; - [SerializeField] private string usernameFromConsole = default; + [SerializeField] private bool useConsoleAuth; + [SerializeField] private string usernameFromConsole; private static DemoSettings _instance; @@ -71,30 +71,6 @@ public static bool UseSteamAuth set { Instance.useSteamAuth = value; - - var useSteamMark = Path.Combine(Application.dataPath, "Xsolla", "ThirdParty", "use_steam"); - try - { - if (value) - { - if (!File.Exists(useSteamMark)) - File.Create(useSteamMark); - } - else - { - if (File.Exists(useSteamMark)) - File.Delete(useSteamMark); - - var useSteamMarkMeta = $"{useSteamMark}.meta"; - if (File.Exists(useSteamMarkMeta)) - File.Delete(useSteamMarkMeta); - } - } - catch (Exception e) - { - Debug.LogError($"Could not create or delete {useSteamMark}. {e.Message}"); - } - MarkAssetDirty(); } } diff --git a/Assets/Xsolla.Demo/Common/DemoSettings/Editor/DemoSettingsEditor.Steam.cs b/Assets/Xsolla.Demo/Common/DemoSettings/Editor/DemoSettingsEditor.Steam.cs index 680ed29a6..0b430962b 100644 --- a/Assets/Xsolla.Demo/Common/DemoSettings/Editor/DemoSettingsEditor.Steam.cs +++ b/Assets/Xsolla.Demo/Common/DemoSettings/Editor/DemoSettingsEditor.Steam.cs @@ -67,12 +67,12 @@ private bool SteamSettings() File.WriteAllText(filePath, appId); } - Debug.Log("[Steamworks.NET] Files \"steam_appid.txt\" successfully updated. Please relaunch Unity"); + XDebug.Log("[Steamworks.NET] Files \"steam_appid.txt\" successfully updated. Please relaunch Unity", true); } catch (Exception) { var filePathsArray = string.Join("\n", steamAppIdFiles); - Debug.LogWarning($"[Steamworks.NET] Could not write SteamAppId in the files \"steam_appid.txt\". Please edit them manually and relaunch Unity. Files:\n{filePathsArray}\n"); + XDebug.LogWarning($"[Steamworks.NET] Could not write SteamAppId in the files \"steam_appid.txt\". Please edit them manually and relaunch Unity. Files:\n{filePathsArray}\n", true); } } diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Prefabs/Spinner.prefab b/Assets/Xsolla.Demo/Common/PopupFactory/Prefabs/Spinner.prefab index 4e2d11a38..734561f6a 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Prefabs/Spinner.prefab +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Prefabs/Spinner.prefab @@ -57,7 +57,7 @@ GameObject: - component: {fileID: 620541066977609436} - component: {fileID: 4435311804647170800} - component: {fileID: 2643959569520279956} - - component: {fileID: 846456202573169675} + - component: {fileID: 2352473327319313129} - component: {fileID: 3692129685461708294} - component: {fileID: 2240658691072249059} m_Layer: 5 @@ -123,7 +123,7 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 ---- !u!114 &846456202573169675 +--- !u!114 &2352473327319313129 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -132,7 +132,7 @@ MonoBehaviour: m_GameObject: {fileID: 3306535587679975081} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ace5b50f1146743be9dd1382d9335217, type: 3} + m_Script: {fileID: 11500000, guid: 5bafa849b07c41e8b52d1a84d2914d3c, type: 3} m_Name: m_EditorClassIdentifier: Speed: -60 @@ -149,6 +149,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: _propertyId: 31700e90-bef4-4a9a-b375-9382dccb76c6 + _comp: {fileID: 2643959569520279956} _pointerOverrider: _pointerEvents: {fileID: 0} _transitionMode: 0 @@ -156,7 +157,6 @@ MonoBehaviour: _hoverPropertyId: f59ef3aa-9cf9-4946-8de2-f203b773a004 _isOverridePress: 0 _pressPropertyId: f59ef3aa-9cf9-4946-8de2-f203b773a004 - _comp: {fileID: 2643959569520279956} --- !u!114 &2240658691072249059 MonoBehaviour: m_ObjectHideFlags: 0 @@ -170,6 +170,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: _propertyId: caa8855f-2d88-42fe-944c-50d1249c7773 + _comp: {fileID: 2643959569520279956} _pointerOverrider: _pointerEvents: {fileID: 0} _transitionMode: 0 @@ -177,7 +178,6 @@ MonoBehaviour: _hoverPropertyId: 2a5a816b-0b34-4462-a11c-94ae69041b5d _isOverridePress: 0 _pressPropertyId: 2a5a816b-0b34-4462-a11c-94ae69041b5d - _comp: {fileID: 2643959569520279956} --- !u!1 &6127526354144100117 GameObject: m_ObjectHideFlags: 0 @@ -189,7 +189,7 @@ GameObject: - component: {fileID: 8713406927727411941} - component: {fileID: 8741013707174570828} - component: {fileID: 4173637803486398794} - - component: {fileID: 2466396695753803322} + - component: {fileID: 276502302624583760} - component: {fileID: 5762624579560056345} - component: {fileID: 7938628756746902689} m_Layer: 5 @@ -255,7 +255,7 @@ MonoBehaviour: m_FillOrigin: 0 m_UseSpriteMesh: 0 m_PixelsPerUnitMultiplier: 1 ---- !u!114 &2466396695753803322 +--- !u!114 &276502302624583760 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -264,7 +264,7 @@ MonoBehaviour: m_GameObject: {fileID: 6127526354144100117} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ace5b50f1146743be9dd1382d9335217, type: 3} + m_Script: {fileID: 11500000, guid: 5bafa849b07c41e8b52d1a84d2914d3c, type: 3} m_Name: m_EditorClassIdentifier: Speed: 60 @@ -281,6 +281,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: _propertyId: 31700e90-bef4-4a9a-b375-9382dccb76c6 + _comp: {fileID: 4173637803486398794} _pointerOverrider: _pointerEvents: {fileID: 0} _transitionMode: 0 @@ -288,7 +289,6 @@ MonoBehaviour: _hoverPropertyId: f59ef3aa-9cf9-4946-8de2-f203b773a004 _isOverridePress: 0 _pressPropertyId: f59ef3aa-9cf9-4946-8de2-f203b773a004 - _comp: {fileID: 4173637803486398794} --- !u!114 &7938628756746902689 MonoBehaviour: m_ObjectHideFlags: 0 @@ -302,6 +302,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: _propertyId: da7247b4-fdc3-4b8e-9dc5-2764cc1c5f78 + _comp: {fileID: 4173637803486398794} _pointerOverrider: _pointerEvents: {fileID: 0} _transitionMode: 0 @@ -309,4 +310,3 @@ MonoBehaviour: _hoverPropertyId: 2a5a816b-0b34-4462-a11c-94ae69041b5d _isOverridePress: 0 _pressPropertyId: 2a5a816b-0b34-4462-a11c-94ae69041b5d - _comp: {fileID: 4173637803486398794} diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ConfirmationCodePopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ConfirmationCodePopup.cs index c3b4c65f4..eb263cae9 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ConfirmationCodePopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ConfirmationCodePopup.cs @@ -3,7 +3,7 @@ using UnityEngine.UI; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { [AddComponentMenu("Scripts/Xsolla.Core/Popup/ConfirmationCodePopup")] public class ConfirmationCodePopup : MonoBehaviour, IConfirmationCodePopup diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ConfirmationPopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ConfirmationPopup.cs index aecf0526f..843271322 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ConfirmationPopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ConfirmationPopup.cs @@ -3,7 +3,7 @@ using UnityEngine.UI; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { [AddComponentMenu("Scripts/Xsolla.Core/Popup/ConfirmationPopup")] public class ConfirmationPopup : MonoBehaviour, IConfirmationPopup diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ErrorPopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ErrorPopup.cs index 9bbadc54e..085e56baa 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ErrorPopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ErrorPopup.cs @@ -3,7 +3,7 @@ using UnityEngine.UI; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { [AddComponentMenu("Scripts/Xsolla.Core/Popup/ErrorPopup")] public class ErrorPopup : MonoBehaviour, IErrorPopup diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IConfirmationCodePopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IConfirmationCodePopup.cs index a69c83084..bb41f97a5 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IConfirmationCodePopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IConfirmationCodePopup.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface IConfirmationCodePopup { diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IConfirmationPopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IConfirmationPopup.cs index 8b47b9314..9c4210b3b 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IConfirmationPopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IConfirmationPopup.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface IConfirmationPopup { diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IErrorPopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IErrorPopup.cs index 15a9888d1..a71a44fad 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IErrorPopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IErrorPopup.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface IErrorPopup { diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ISuccessPopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ISuccessPopup.cs index 3d90fa82f..3c5d048b6 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ISuccessPopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/ISuccessPopup.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface ISuccessPopup { diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IWaitingPopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IWaitingPopup.cs index 8150f20bc..de4875935 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IWaitingPopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/IWaitingPopup.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface IWaitingPopup { diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/PopupFactory.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/PopupFactory.cs index 0620896e3..b62d36f61 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/PopupFactory.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/PopupFactory.cs @@ -2,7 +2,7 @@ using UnityEngine; using Object = UnityEngine.Object; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { internal static class GameObjectPopupExtensions { @@ -51,7 +51,7 @@ public override void Init() } else { - Debug.LogError("You try use 2D popup component, but Canvas object is missing!"); + XDebug.LogError("You try use 2D popup component, but Canvas object is missing!"); } } @@ -59,7 +59,7 @@ private GameObject CreateDefaultPopup(GameObject prefab, GameObject parent) { if (prefab == null) { - Debug.LogError( + XDebug.LogError( "You try create object, but prefab for it is null. " + Environment.NewLine + "Check `PopupFactory` script for missing prefabs."); return null; diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/PopupOverlay.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/PopupOverlay.cs index 9aa5359a1..aca1b45c0 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/PopupOverlay.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/PopupOverlay.cs @@ -1,7 +1,7 @@ using System.Collections; using UnityEngine; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public class PopupOverlay : MonoBehaviour { diff --git a/Assets/Xsolla/Core/Utils/RotateCircle.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/RotateCircle.cs similarity index 59% rename from Assets/Xsolla/Core/Utils/RotateCircle.cs rename to Assets/Xsolla.Demo/Common/PopupFactory/Scripts/RotateCircle.cs index e014e9983..dd04f93fa 100644 --- a/Assets/Xsolla/Core/Utils/RotateCircle.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/RotateCircle.cs @@ -1,6 +1,6 @@ using UnityEngine; -namespace Xsolla.Core +namespace Xsolla.Demo.Popup { public class RotateCircle : MonoBehaviour { @@ -10,13 +10,13 @@ public class RotateCircle : MonoBehaviour private void Awake() { - _circle = (RectTransform)transform; + _circle = (RectTransform) transform; } - void Update() + private void Update() { - Vector3 delta = Vector3.forward * Speed * Time.deltaTime; + var delta = Vector3.forward * Speed * Time.deltaTime; _circle.Rotate(delta); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/RotateCircle.cs.meta b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/RotateCircle.cs.meta new file mode 100644 index 000000000..faad4edc1 --- /dev/null +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/RotateCircle.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5bafa849b07c41e8b52d1a84d2914d3c +timeCreated: 1683276015 \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/SuccessPopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/SuccessPopup.cs index 516b8858a..1bf0b8123 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/SuccessPopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/SuccessPopup.cs @@ -4,7 +4,7 @@ using UnityEngine.UI; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { [AddComponentMenu("Scripts/Xsolla.Core/Popup/SuccessPopup")] public class SuccessPopup : MonoBehaviour, ISuccessPopup diff --git a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/WaitingPopup.cs b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/WaitingPopup.cs index 3076acdf4..f52d8e7e6 100644 --- a/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/WaitingPopup.cs +++ b/Assets/Xsolla.Demo/Common/PopupFactory/Scripts/WaitingPopup.cs @@ -2,7 +2,7 @@ using System.Collections; using UnityEngine; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { [AddComponentMenu("Scripts/Xsolla.Core/Popup/SuccessPopup")] public class WaitingPopup : MonoBehaviour, IWaitingPopup diff --git a/Assets/Xsolla.Demo/Common/Prefabs/Primitives/Buttons/ConsumeButton/ConsumeButton.cs b/Assets/Xsolla.Demo/Common/Prefabs/Primitives/Buttons/ConsumeButton/ConsumeButton.cs index 3540c48b1..70d0873da 100644 --- a/Assets/Xsolla.Demo/Common/Prefabs/Primitives/Buttons/ConsumeButton/ConsumeButton.cs +++ b/Assets/Xsolla.Demo/Common/Prefabs/Primitives/Buttons/ConsumeButton/ConsumeButton.cs @@ -1,5 +1,6 @@ using System; using UnityEngine; +using Xsolla.Core; namespace Xsolla.Demo { @@ -19,7 +20,7 @@ void Start() } else { - Debug.Log("You try consume item with quantity = 0!"); + XDebug.Log("You try consume item with quantity = 0!"); } }; } diff --git a/Assets/Xsolla.Demo/Common/Scripts/Browser/BrowserDialogHandler.cs b/Assets/Xsolla.Demo/Common/Scripts/Browser/BrowserDialogHandler.cs index 52c6b3141..e66f46b8d 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/Browser/BrowserDialogHandler.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/Browser/BrowserDialogHandler.cs @@ -1,6 +1,6 @@ using UnityEngine; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { @@ -8,7 +8,7 @@ public class BrowserDialogHandler : MonoBehaviour { private void Awake() { - var browser = BrowserHelper.Instance.InAppBrowser; + var browser = XsollaWebBrowser.InAppBrowser; if (browser == null) return; diff --git a/Assets/Xsolla/Core/Entities/MonoSingleton.cs b/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/MonoSingleton.cs similarity index 76% rename from Assets/Xsolla/Core/Entities/MonoSingleton.cs rename to Assets/Xsolla.Demo/Common/Scripts/CommonUtils/MonoSingleton.cs index 3a3f0ba5f..9a15c0dba 100644 --- a/Assets/Xsolla/Core/Entities/MonoSingleton.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/MonoSingleton.cs @@ -1,12 +1,12 @@ using UnityEngine; -namespace Xsolla.Core +namespace Xsolla.Demo { public abstract class MonoSingleton : MonoBehaviour where T : MonoSingleton { private const string PATH_TO_PREFABS = ""; private static T _instance; - private bool _isInitialized = false; + private bool _isInitialized; public static T Instance { @@ -40,16 +40,12 @@ private void Awake() private static T InstantiateThis() { - string componentName = typeof(T).Name; - Debug.Log($"No instance of {componentName}"); + var componentName = typeof(T).Name; //Try finding pre-existing object on the scene T result = FindObjectOfType(typeof(T)) as T; if (result != null) - { - Debug.Log($"{componentName} found in the scene."); return result; - } //Try loading from resources var prefab = Resources.Load($"{PATH_TO_PREFABS}{typeof(T).Name}"); @@ -60,31 +56,24 @@ private static T InstantiateThis() instance.name = typeof(T).Name; result = instance?.GetComponent(); } + if (result != null) - { - Debug.Log($"{componentName} loaded from resources."); return result; - } //Create new object var newInstance = new GameObject($"Temp Instance of {typeof(T)}"); result = newInstance.AddComponent(); if (result != null) - { - Debug.Log($"{componentName} a temporary one is created."); return result; - } - //else - Debug.LogError($"Could not instantiate {componentName}"); + XDebug.LogError($"Could not instantiate {componentName}"); return result; } - public virtual void Init() {} + public virtual void Init() { } protected virtual void OnDestroy() { - Debug.Log($"{typeof(T)} is destroyed."); _instance = null; } @@ -102,4 +91,4 @@ private void OnApplicationQuit() Destroy(gameObject); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Entities/MonoSingleton.cs.meta b/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/MonoSingleton.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Entities/MonoSingleton.cs.meta rename to Assets/Xsolla.Demo/Common/Scripts/CommonUtils/MonoSingleton.cs.meta diff --git a/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/OpenUrlOnClick.cs b/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/OpenUrlOnClick.cs index d99844f29..ab5c83aa7 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/OpenUrlOnClick.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/OpenUrlOnClick.cs @@ -24,7 +24,7 @@ private void Awake() private void OpenUrl() { - BrowserHelper.Instance.Open(URL, true); + XsollaWebBrowser.Open(URL, true); } } } diff --git a/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/UrlContainer.cs b/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/UrlContainer.cs index 0161238d4..ebe2a62e4 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/UrlContainer.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/CommonUtils/UrlContainer.cs @@ -1,5 +1,6 @@ using System; using UnityEngine; +using Xsolla.Core; namespace Xsolla.Demo { @@ -25,12 +26,12 @@ private void CheckConsistency() var urlsArrayLength = Urls.Length; if (urlsArrayLength != numberOfElementsInEnum) - Debug.LogError($"URLs length is {urlsArrayLength} while there are {numberOfElementsInEnum} UrlTypes defined. Expect the IndexOutOfRangeException."); + XDebug.LogError($"URLs length is {urlsArrayLength} while there are {numberOfElementsInEnum} UrlTypes defined. Expect the IndexOutOfRangeException."); for (int i = 0; i < urlsArrayLength; i++) { if (string.IsNullOrEmpty(Urls[i])) - Debug.Log($"URL value for '{typeNames[i]}' is null or empty."); + XDebug.Log($"URL value for '{typeNames[i]}' is null or empty."); } } } diff --git a/Assets/Xsolla.Demo/Common/Scripts/DemoController/DemoController.cs b/Assets/Xsolla.Demo/Common/Scripts/DemoController/DemoController.cs index 3973e0760..c4265b7dd 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/DemoController/DemoController.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/DemoController/DemoController.cs @@ -1,14 +1,14 @@ using UnityEngine; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { public partial class DemoController : MonoSingleton { - [SerializeField]private MenuStateMachine stateMachine = default; - [SerializeField]private UrlContainer urlContainer = default; - [SerializeField]private XsollaSettingsValidator settingsValidator = default; + [SerializeField] private MenuStateMachine stateMachine = default; + [SerializeField] private UrlContainer urlContainer = default; + [SerializeField] private XsollaSettingsValidator settingsValidator = default; public UrlContainer UrlContainer => urlContainer; public bool IsTutorialAvailable { get; private set; } = false; @@ -34,7 +34,7 @@ protected override void OnDestroy() { DestroyInstances(); - if(PopupFactory.IsExist) + if (PopupFactory.IsExist) Destroy(PopupFactory.Instance.gameObject); base.OnDestroy(); @@ -69,7 +69,7 @@ public bool IsStateAvailable(MenuState state) public string GetWebStoreUrl() { - return $"{DemoSettings.WebStoreUrl}?token={Token.Instance}&remember_me=false"; + return $"{DemoSettings.WebStoreUrl}?token={XsollaToken.AccessToken}&remember_me=false"; } public void ShowTutorial(bool showWelcomeMessage) => ManualStartTutorial(showWelcomeMessage); @@ -79,7 +79,7 @@ private void OnStateChanged(MenuState lastState, MenuState newState) if (lastState.IsPostAuthState() && newState.IsAuthState()) { DestroyInstances(); - Token.Instance = null; + XsollaToken.DeleteSavedInstance(); } if (lastState.IsAuthState() && newState == MenuState.Main) @@ -112,4 +112,4 @@ private void DestroyInstances() partial void DestroyInventory(); partial void DestroyStore(); } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Common/Scripts/DemoPopup/StoreDemoPopup.cs b/Assets/Xsolla.Demo/Common/Scripts/DemoPopup/StoreDemoPopup.cs index 3f615efc0..02dd0a213 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/DemoPopup/StoreDemoPopup.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/DemoPopup/StoreDemoPopup.cs @@ -1,6 +1,7 @@ using System; +using UnityEngine; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { @@ -15,14 +16,14 @@ public static void ShowSuccess(string message = "Everything happened as it shoul public static void ShowError(Error error) { - Debug.LogError(error); + XDebug.LogError(error); var popup = PopupFactory.Instance.CreateError(); popup.SetMessage(error.ToString()); } public static void ShowError(Error error, Action buttonCallback) { - Debug.LogError(error); + XDebug.LogError(error); var popup = PopupFactory.Instance.CreateError(); popup.SetMessage(error.ToString()); popup.SetCallback(buttonCallback); @@ -30,7 +31,7 @@ public static void ShowError(Error error, Action buttonCallback) public static void ShowWarning(Error error, Action buttonCallback = null) { - Debug.LogWarning(error); + XDebug.LogWarning(error); var popup = PopupFactory.Instance.CreateError(); popup.SetMessage(error.ToString()); diff --git a/Assets/Xsolla.Demo/Common/Scripts/Disablers/OnInAppBrowserAbsenceDisabler.cs b/Assets/Xsolla.Demo/Common/Scripts/Disablers/OnInAppBrowserAbsenceDisabler.cs index bfc29aaa4..2a87f1d74 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/Disablers/OnInAppBrowserAbsenceDisabler.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/Disablers/OnInAppBrowserAbsenceDisabler.cs @@ -7,7 +7,7 @@ public class OnInAppBrowserAbsenceDisabler : MonoBehaviour { private void Awake() { - if (BrowserHelper.Instance.InAppBrowser == null) + if (XsollaWebBrowser.InAppBrowser == null) gameObject.SetActive(false); } } diff --git a/Assets/Xsolla.Demo/Common/Scripts/Marker.meta b/Assets/Xsolla.Demo/Common/Scripts/Internal.meta similarity index 100% rename from Assets/Xsolla.Demo/Common/Scripts/Marker.meta rename to Assets/Xsolla.Demo/Common/Scripts/Internal.meta diff --git a/Assets/Xsolla.Demo/Common/Scripts/Internal/XDebug.cs b/Assets/Xsolla.Demo/Common/Scripts/Internal/XDebug.cs new file mode 100644 index 000000000..9e730c11b --- /dev/null +++ b/Assets/Xsolla.Demo/Common/Scripts/Internal/XDebug.cs @@ -0,0 +1,27 @@ +using UnityEngine; +using Xsolla.Core; + +namespace Xsolla.Demo +{ + public static class XDebug + { + private const string LOG_PREFIX = "[Xsolla DEMO]"; + + public static void Log(object message, bool ignoreLogLevel = false) + { + if (XsollaSettings.LogLevel == LogLevel.InfoWarningsErrors || ignoreLogLevel) + Debug.Log($"{LOG_PREFIX} {message}"); + } + + public static void LogWarning(object message, bool ignoreLogLevel = false) + { + if (XsollaSettings.LogLevel <= LogLevel.WarningsErrors || ignoreLogLevel) + Debug.LogWarning($"{LOG_PREFIX} {message}"); + } + + public static void LogError(object message) + { + Debug.LogError($"{LOG_PREFIX} {message}"); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Common/Scripts/Internal/XDebug.cs.meta b/Assets/Xsolla.Demo/Common/Scripts/Internal/XDebug.cs.meta new file mode 100644 index 000000000..d00e1b2ff --- /dev/null +++ b/Assets/Xsolla.Demo/Common/Scripts/Internal/XDebug.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 90fa0595cb1b45538d7f024ba68ed216 +timeCreated: 1683690989 \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Common/Scripts/Marker/XsollaMarker.cs b/Assets/Xsolla.Demo/Common/Scripts/Internal/XsollaMarker.cs similarity index 100% rename from Assets/Xsolla.Demo/Common/Scripts/Marker/XsollaMarker.cs rename to Assets/Xsolla.Demo/Common/Scripts/Internal/XsollaMarker.cs diff --git a/Assets/Xsolla.Demo/Common/Scripts/Marker/XsollaMarker.cs.meta b/Assets/Xsolla.Demo/Common/Scripts/Internal/XsollaMarker.cs.meta similarity index 100% rename from Assets/Xsolla.Demo/Common/Scripts/Marker/XsollaMarker.cs.meta rename to Assets/Xsolla.Demo/Common/Scripts/Internal/XsollaMarker.cs.meta diff --git a/Assets/Xsolla.Demo/Common/Scripts/Item/ItemUI.cs b/Assets/Xsolla.Demo/Common/Scripts/Item/ItemUI.cs index 5533b0af8..4c5c5bbea 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/Item/ItemUI.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/Item/ItemUI.cs @@ -25,12 +25,12 @@ public void Initialize(ItemModel itemModel, int quantity = 1) private void SetImage(string imageUrl, string itemSku) { if (!string.IsNullOrEmpty(imageUrl)) - ImageLoader.Instance.GetImageAsync(imageUrl, LoadImageCallback); + ImageLoader.LoadSprite(imageUrl, LoadImageCallback); else - Debug.LogError($"Item with sku: '{itemSku}' has no image url"); + XDebug.LogError($"Item with sku: '{itemSku}' has no image url"); } - private void LoadImageCallback(string url, Sprite image) + private void LoadImageCallback(Sprite image) { if (ItemImage) { diff --git a/Assets/Xsolla.Demo/Common/Scripts/LoginUtils/ConfirmationLinkResender.cs b/Assets/Xsolla.Demo/Common/Scripts/LoginUtils/ConfirmationLinkResender.cs index 68cebe8ba..7d7a1438d 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/LoginUtils/ConfirmationLinkResender.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/LoginUtils/ConfirmationLinkResender.cs @@ -1,12 +1,14 @@ using UnityEngine; using UnityEngine.UI; +using Xsolla.Auth; +using Xsolla.Core; namespace Xsolla.Demo { public class ConfirmationLinkResender : MonoBehaviour { - [SerializeField] SimpleButton resendButton = default; - [SerializeField] Text emailText = default; + [SerializeField] private SimpleButton resendButton; + [SerializeField] private Text emailText; void Awake() { @@ -21,19 +23,19 @@ void Awake() ReplaceEmailText(LoginPageChangePasswordController.LastEmail); break; default: - Debug.LogWarning($"Unexpected state"); + XDebug.LogWarning("Unexpected state"); break; } } - public void ResendRegistrationConfirmationEmail() + private void ResendRegistrationConfirmationEmail() { - SdkAuthLogic.Instance.ResendConfirmationLink(LoginPageCreateController.LastEmail); + XsollaAuth.ResendConfirmationLink(LoginPageCreateController.LastEmail, null, null); } - public void ResendPasswordResetEmail() + private void ResendPasswordResetEmail() { - SdkAuthLogic.Instance.ResetPassword(LoginPageChangePasswordController.LastEmail); + XsollaAuth.ResetPassword(LoginPageChangePasswordController.LastEmail, null, null); } private void ReplaceEmailText(string email) diff --git a/Assets/Xsolla.Demo/Common/Scripts/LoginUtils/LoginPageCommonButtonsProvider.cs b/Assets/Xsolla.Demo/Common/Scripts/LoginUtils/LoginPageCommonButtonsProvider.cs index c5fec66e9..77e75a1af 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/LoginUtils/LoginPageCommonButtonsProvider.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/LoginUtils/LoginPageCommonButtonsProvider.cs @@ -9,27 +9,13 @@ public class LoginPageCommonButtonsProvider : MonoBehaviour public SimpleButton DemoUserButton; public SimpleButton LogInButton; - private void OnEnable() - { - XsollaSettings.Changed += OnXsollaSettingsChanged; - } - - private void OnDisable() - { - XsollaSettings.Changed -= OnXsollaSettingsChanged; - } - private void Start() - { - OnXsollaSettingsChanged(); - } - - private void OnXsollaSettingsChanged() { if (DemoUserButton) { - var isDefaultProject = XsollaSettings.LoginId == Constants.DEFAULT_LOGIN_ID && - XsollaSettings.StoreProjectId == Constants.DEFAULT_PROJECT_ID; + var isDefaultProject = XsollaSettings.LoginId == Constants.DEFAULT_LOGIN_ID + && XsollaSettings.StoreProjectId == Constants.DEFAULT_PROJECT_ID; + DemoUserButton.gameObject.SetActive(isDefaultProject); } } diff --git a/Assets/Xsolla.Demo/Common/Scripts/Marker/Xsolla.asmref b/Assets/Xsolla.Demo/Common/Scripts/Marker/Xsolla.asmref deleted file mode 100644 index 24634ea00..000000000 --- a/Assets/Xsolla.Demo/Common/Scripts/Marker/Xsolla.asmref +++ /dev/null @@ -1,3 +0,0 @@ -{ - "reference": "GUID:ae0cf701846f0cc4bbd067c4edd4fe90" -} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Common/Scripts/Marker/Xsolla.asmref.meta b/Assets/Xsolla.Demo/Common/Scripts/Marker/Xsolla.asmref.meta deleted file mode 100644 index b8f0ae0b7..000000000 --- a/Assets/Xsolla.Demo/Common/Scripts/Marker/Xsolla.asmref.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: f9822718486b34c96872b4f45cf33104 -AssemblyDefinitionReferenceImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Common/Scripts/MenuStateMachine/MenuStateMachine.cs b/Assets/Xsolla.Demo/Common/Scripts/MenuStateMachine/MenuStateMachine.cs index 6aa152070..7a673f4ef 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/MenuStateMachine/MenuStateMachine.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/MenuStateMachine/MenuStateMachine.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { @@ -115,7 +115,7 @@ private GameObject SetState(MenuState state, bool addToTrace) } else { - Debug.LogError($"Prefab object is null for state = {state.ToString()}. Changing state to initial."); + XDebug.LogError($"Prefab object is null for state = {state.ToString()}. Changing state to initial."); SetInitialState(); } diff --git a/Assets/Xsolla.Demo/Common/Scripts/PageControllers/BaseMenuController.cs b/Assets/Xsolla.Demo/Common/Scripts/PageControllers/BaseMenuController.cs index d5e0ea283..de0c849a6 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/PageControllers/BaseMenuController.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/PageControllers/BaseMenuController.cs @@ -1,7 +1,7 @@ using System; using UnityEngine; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { @@ -20,7 +20,7 @@ public static void AttachUrlToButton(SimpleButton button, string url) { if (!string.IsNullOrEmpty(url)) { - AttachButtonCallback(button, () => BrowserHelper.Instance.Open(url, true)); + AttachButtonCallback(button, () => XsollaWebBrowser.Open(url, true)); } } diff --git a/Assets/Xsolla.Demo/Common/Scripts/PageControllers/MainMenuController.cs b/Assets/Xsolla.Demo/Common/Scripts/PageControllers/MainMenuController.cs index 1dc47db90..582f5cf87 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/PageControllers/MainMenuController.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/PageControllers/MainMenuController.cs @@ -1,6 +1,6 @@ using UnityEngine; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { diff --git a/Assets/Xsolla.Demo/Common/Scripts/UIUtils/CountdownTimer.cs b/Assets/Xsolla.Demo/Common/Scripts/UIUtils/CountdownTimer.cs index c9392fffe..a7fb49e93 100644 --- a/Assets/Xsolla.Demo/Common/Scripts/UIUtils/CountdownTimer.cs +++ b/Assets/Xsolla.Demo/Common/Scripts/UIUtils/CountdownTimer.cs @@ -2,6 +2,7 @@ using System.Collections; using UnityEngine; using UnityEngine.UI; +using Xsolla.Core; namespace Xsolla.Demo { @@ -31,10 +32,10 @@ private void Awake() _timerTemplateFormat = GenerateTemplateFormat(TimerTemplate); if (string.IsNullOrEmpty(TimerTemplate)) - Debug.LogWarning("TimerTemplate is not set"); + XDebug.LogWarning("TimerTemplate is not set"); if (!string.IsNullOrEmpty(OutputTemplate) && !OutputTemplate.Contains(TIMER_MARK)) - Debug.LogWarning("Incorrect OutputTemplate, check that %TIMER% is included"); + XDebug.LogWarning("Incorrect OutputTemplate, check that %TIMER% is included"); } public void StartTimer() diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/BundleItemUI.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/BundleItemUI.cs index 61234fdfb..b1578806b 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/BundleItemUI.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/BundleItemUI.cs @@ -19,18 +19,18 @@ public void Initialize(BundleContentItem item) if (!string.IsNullOrEmpty(item.ImageUrl)) { - ImageLoader.Instance.GetImageAsync(item.ImageUrl, LoadImageCallback); + ImageLoader.LoadSprite(item.ImageUrl, LoadImageCallback); } else { - Debug.LogError($"Bundle content item with sku = '{item.Sku}' without image!"); + XDebug.LogError($"Bundle content item with sku = '{item.Sku}' without image!"); } } - void LoadImageCallback(string url, Sprite image) + void LoadImageCallback(Sprite sprite) { if (itemImage) - itemImage.sprite = image; + itemImage.sprite = sprite; } } } diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/CatalogBundleItemModel.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/CatalogBundleItemModel.cs index f1e2bda2f..959791581 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/CatalogBundleItemModel.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/CatalogBundleItemModel.cs @@ -11,8 +11,8 @@ public class CatalogBundleItemModel : CatalogItemModel public KeyValuePair? ContentRealPrice { get; set; } public KeyValuePair? ContentRealPriceWithoutDiscount { get; set; } - public KeyValuePair? ContentVirtualPrice { get; set; } - public KeyValuePair? ContentVirtualPriceWithoutDiscount { get; set; } + public KeyValuePair? ContentVirtualPrice { get; set; } + public KeyValuePair? ContentVirtualPriceWithoutDiscount { get; set; } public List Content { get; set; } } diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/CatalogItemModel.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/CatalogItemModel.cs index 6552443ae..2ebe69b64 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/CatalogItemModel.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/CatalogItemModel.cs @@ -6,8 +6,8 @@ public abstract class CatalogItemModel : ItemModel { public KeyValuePair? RealPrice { get; set; } public KeyValuePair? RealPriceWithoutDiscount { get; set; } - public KeyValuePair? VirtualPrice { get; set; } - public KeyValuePair? VirtualPriceWithoutDiscount { get; set; } + public KeyValuePair? VirtualPrice { get; set; } + public KeyValuePair? VirtualPriceWithoutDiscount { get; set; } public KeyValuePair? Price => VirtualPrice.HasValue ? new KeyValuePair(VirtualPrice.Value.Key, VirtualPrice.Value.Value) diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/UserCatalog.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/UserCatalog.cs index de193c1aa..800c15a13 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/UserCatalog.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Catalog/UserCatalog.cs @@ -70,7 +70,7 @@ private IEnumerator UpdateSomeItemsCoroutine(Action>, Action { busy = false; @@ -92,7 +92,7 @@ private void AddUniqueItemsFrom(List items) where T : CatalogItemModel private IEnumerator UpdateVirtualCurrenciesCoroutine(Action onError = null) { var busy = true; - SdkCatalogLogic.Instance.GetVirtualCurrencies(items => + CatalogLogic.Instance.GetVirtualCurrencies(items => { VirtualCurrencies = items; UpdateVirtualCurrenciesEvent?.Invoke(items); @@ -104,7 +104,7 @@ private IEnumerator UpdateVirtualCurrenciesCoroutine(Action onError = nul private IEnumerator UpdateVirtualItemsCoroutine(Action onError = null) { yield return StartCoroutine(UpdateSomeItemsCoroutine( - SdkCatalogLogic.Instance.GetCatalogVirtualItems, items => + CatalogLogic.Instance.GetCatalogVirtualItems, items => { VirtualItems = items; UpdateItemsEvent?.Invoke(items); @@ -114,7 +114,7 @@ private IEnumerator UpdateVirtualItemsCoroutine(Action onError = null) private IEnumerator UpdateVirtualCurrencyPackagesCoroutine(Action onError = null) { yield return StartCoroutine(UpdateSomeItemsCoroutine( - SdkCatalogLogic.Instance.GetCatalogVirtualCurrencyPackages, items => + CatalogLogic.Instance.GetCatalogVirtualCurrencyPackages, items => { CurrencyPackages = items; UpdateVirtualCurrencyPackagesEvent?.Invoke(items); @@ -124,7 +124,7 @@ private IEnumerator UpdateVirtualCurrencyPackagesCoroutine(Action onError private IEnumerator UpdateBundlesCoroutine(Action onError = null) { yield return StartCoroutine(UpdateSomeItemsCoroutine( - SdkCatalogLogic.Instance.GetCatalogBundles, items => + CatalogLogic.Instance.GetCatalogBundles, items => { Bundles = items; UpdateBundlesEvent?.Invoke(items); @@ -134,7 +134,7 @@ private IEnumerator UpdateBundlesCoroutine(Action onError = null) private IEnumerator UpdateSubscriptionsCoroutine(Action onError = null) { yield return StartCoroutine(UpdateSomeItemsCoroutine( - SdkCatalogLogic.Instance.GetCatalogSubscriptions, items => + CatalogLogic.Instance.GetCatalogSubscriptions, items => { Subscriptions = items; UpdateSubscriptionsEvent?.Invoke(items); diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/DemoController/DemoController.Inventory.cs b/Assets/Xsolla.Demo/Inventory/Scripts/DemoController/DemoController.Inventory.cs index 80120ba0d..9e5907e40 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/DemoController/DemoController.Inventory.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/DemoController/DemoController.Inventory.cs @@ -1,3 +1,4 @@ +using UnityEngine; using Xsolla.Core; namespace Xsolla.Demo @@ -21,11 +22,7 @@ partial void AutoStartTutorial() { if (!_tutorialManager.IsTutorialCompleted()) _tutorialManager.ShowTutorial(); - else - Debug.Log("Skipping tutorial since it was already completed."); } - else - Debug.Log("Tutorial is not available for this demo."); } partial void ManualStartTutorial(bool showWelcomeMessage) @@ -41,7 +38,7 @@ partial void UpdateInventory() onSuccess: () => UserInventory.Instance.Refresh(onError: StoreDemoPopup.ShowError), onError: error => { - Debug.LogError($"InventorySDK init failure: {error}"); + XDebug.LogError($"InventorySDK init failure: {error}"); StoreDemoPopup.ShowError(error); }); } diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Coupons/CouponRewardItemUI.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Coupons/CouponRewardItemUI.cs index b7c26903d..361a6936c 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Coupons/CouponRewardItemUI.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Coupons/CouponRewardItemUI.cs @@ -21,19 +21,17 @@ public void Initialize(CouponRedeemedItemModel rewardItem) { if (!string.IsNullOrEmpty(rewardItem.ImageUrl)) { - ImageLoader.Instance.GetImageAsync(rewardItem.ImageUrl, LoadImageCallback); + ImageLoader.LoadSprite(rewardItem.ImageUrl, image => + { + if (itemImage) + itemImage.sprite = image; + }); } else { - Debug.LogError($"Coupon reward item item with sku = '{rewardItem.Sku}' without image!"); + XDebug.LogError($"Coupon reward item item with sku = '{rewardItem.Sku}' without image!"); } } } - - void LoadImageCallback(string url, Sprite image) - { - if (itemImage) - itemImage.sprite = image; - } } } diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Coupons/CouponsManager.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Coupons/CouponsManager.cs index 3ef868d0b..a38644bd3 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Coupons/CouponsManager.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Coupons/CouponsManager.cs @@ -1,5 +1,5 @@ using UnityEngine; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/InventoryItemUI.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/InventoryItemUI.cs index 13ace1729..47786065c 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/InventoryItemUI.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/InventoryItemUI.cs @@ -59,15 +59,15 @@ public void Initialize(ItemModel itemInformation) private void LoadImage(string url) { if (!string.IsNullOrEmpty(url)) - ImageLoader.Instance.GetImageAsync(url, LoadImageCallback); + ImageLoader.LoadSprite(url, LoadImageCallback); else { - Debug.LogError($"Inventory item with sku = '{_itemInformation.Sku}' has no image!"); - LoadImageCallback(string.Empty, null); + XDebug.LogWarning($"Inventory item with sku = '{_itemInformation.Sku}' has no image!"); + LoadImageCallback(null); } } - private void LoadImageCallback(string url, Sprite image) + private void LoadImageCallback(Sprite image) { if (!itemImage) return; @@ -271,11 +271,11 @@ private void ConsumeHandler() { DisableConsumeButton(); DemoInventory.Instance.ConsumeInventoryItem(model, consumeButton.counter.GetValue(), - _ => - { - UserInventory.Instance.Refresh(onError: StoreDemoPopup.ShowError); - consumeButton.counter.ResetValue(); - }, _ => EnableConsumeButton()); + _ => + { + UserInventory.Instance.Refresh(onError: StoreDemoPopup.ShowError); + consumeButton.counter.ResetValue(); + }, _ => EnableConsumeButton()); } } @@ -309,15 +309,15 @@ private bool TryDowncastTo(ItemModel itemModel, out T result) where T : ItemM { if (itemModel is T) { - result = (T)itemModel; + result = (T) itemModel; return true; } else { - Debug.LogError($"Item model incorrect for item with SKU '{itemModel.Sku}', expected type is '{typeof (T)}'"); + XDebug.LogError($"Item model incorrect for item with SKU '{itemModel.Sku}', expected type is '{typeof(T)}'"); result = null; return false; } } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Mobile/InventoryItemInfoMobile.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Mobile/InventoryItemInfoMobile.cs index 0ead437b6..610b67b28 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Mobile/InventoryItemInfoMobile.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/Mobile/InventoryItemInfoMobile.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using Xsolla.Core; namespace Xsolla.Demo { @@ -18,7 +19,7 @@ public static void ShowItem(ItemModel itemModel) { if (_instance == null) { - Debug.LogError("Instance not set"); + XDebug.LogError("Instance not set"); return; } diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/UserInventory.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/UserInventory.cs index 137fe3388..aea35ac11 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/UserInventory.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/UserInventory.cs @@ -45,33 +45,33 @@ private IEnumerator WaitItemUpdatingCoroutine(Action onSuccess = null, Action + InventoryLogic.Instance.GetVirtualCurrencyBalance(balance => { Balance = balance; balanceUpdated = true; }, onError); - if (Token.Instance == null) + if (!XsollaToken.Exists) yield break; - SdkInventoryLogic.Instance.GetInventoryItems(items => + InventoryLogic.Instance.GetInventoryItems(items => { VirtualItems = items.Where(i => !i.IsVirtualCurrency() && !i.IsSubscription()).ToList(); itemsUpdated = true; }, onError); - if (Token.Instance == null) + if (!XsollaToken.Exists) yield break; - SdkInventoryLogic.Instance.GetUserSubscriptions(items => + InventoryLogic.Instance.GetUserSubscriptions(items => { Subscriptions = items; subscriptionsUpdated = true; }, onError); - + yield return new WaitUntil(() => balanceUpdated && itemsUpdated && subscriptionsUpdated); IsUpdated = true; @@ -91,4 +91,4 @@ private void HandleInventoryUpdate(Action callback) callback?.Invoke(); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/VirtualCurrencyBalanceModel.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/VirtualCurrencyBalanceModel.cs index b57d0dce9..90097ff77 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/VirtualCurrencyBalanceModel.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Inventory/VirtualCurrencyBalanceModel.cs @@ -9,6 +9,6 @@ public class VirtualCurrencyBalanceModel : ItemModel public override bool IsSubscription() => false; public override bool IsBundle() => false; - public uint Amount { get; set; } + public int Amount { get; set; } } } \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Items/ItemsController.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Items/ItemsController.cs index 13eb75450..ea9b5d0d1 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Items/ItemsController.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Items/ItemsController.cs @@ -2,7 +2,6 @@ using System.Linq; using UnityEngine; using Xsolla.Core; -using Xsolla.Store; namespace Xsolla.Demo { diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Items/SubscriptionItemUI.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Items/SubscriptionItemUI.cs index 2b2e9efd4..54439654f 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Items/SubscriptionItemUI.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Items/SubscriptionItemUI.cs @@ -57,24 +57,22 @@ public void Initialize(TimeLimitedItem itemInformation) private void ChangeImageUrl(TimeLimitedItem itemInformation) { if (!string.IsNullOrEmpty(_itemInformation.image_url)) - ImageLoader.Instance.GetImageAsync(_itemInformation.image_url, LoadImageCallback); + ImageLoader.LoadSprite(_itemInformation.image_url, image => + { + if (!itemImage) + return; + + loadingCircle.SetActive(false); + itemImage.sprite = image; + }); else { - Debug.LogError($"Subscription item with sku = '{itemInformation.sku}' without image!"); + XDebug.LogError($"Subscription item with sku = '{itemInformation.sku}' without image!"); loadingCircle.SetActive(false); itemImage.sprite = null; } } - void LoadImageCallback(string url, Sprite image) - { - if (!itemImage) - return; - - loadingCircle.SetActive(false); - itemImage.sprite = image; - } - private DateTime UnixTimeToDateTime(long unixTime) { DateTime dtDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/ItemsTabControl/ItemsTabControl.cs b/Assets/Xsolla.Demo/Inventory/Scripts/ItemsTabControl/ItemsTabControl.cs index 78dc58156..fb8313c7f 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/ItemsTabControl/ItemsTabControl.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/ItemsTabControl/ItemsTabControl.cs @@ -1,6 +1,5 @@ using UnityEngine; using Xsolla.Core; -using Xsolla.Store; namespace Xsolla.Demo { diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/PageControllers/InventoryPageStoreItemsController.cs b/Assets/Xsolla.Demo/Inventory/Scripts/PageControllers/InventoryPageStoreItemsController.cs index c7fe53647..63e1ce7f1 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/PageControllers/InventoryPageStoreItemsController.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/PageControllers/InventoryPageStoreItemsController.cs @@ -1,8 +1,7 @@ using System.Collections.Generic; -using System; using System.Linq; using UnityEngine; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/CouponRedeemPopup.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/CouponRedeemPopup.cs index c05eca994..b3ef08b27 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/CouponRedeemPopup.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/CouponRedeemPopup.cs @@ -3,7 +3,7 @@ using UnityEngine.UI; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { [AddComponentMenu("Scripts/Xsolla.Core/Popup/RedeemCouponPopup")] public class CouponRedeemPopup : MonoBehaviour, ICouponRedeemPopup diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/CouponRewardsPopup.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/CouponRewardsPopup.cs index 55684b758..da14a3973 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/CouponRewardsPopup.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/CouponRewardsPopup.cs @@ -2,7 +2,7 @@ using UnityEngine; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { [AddComponentMenu("Scripts/Xsolla.Core/Popup/CouponRewardsPopup")] public class CouponRewardsPopup : MonoBehaviour, ICouponRewardsPopup diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ICouponRedeemPopup.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ICouponRedeemPopup.cs index e52fc8a4f..a6ace9a9d 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ICouponRedeemPopup.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ICouponRedeemPopup.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface ICouponRedeemPopup { diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ICouponRewardsPopup.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ICouponRewardsPopup.cs index dbbc7154f..a9490561b 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ICouponRewardsPopup.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ICouponRewardsPopup.cs @@ -1,7 +1,7 @@ using System.Collections.Generic; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface ICouponRewardsPopup { diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ITutorialPopup.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ITutorialPopup.cs index eaadb16a6..da19b4f32 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ITutorialPopup.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/ITutorialPopup.cs @@ -1,7 +1,7 @@ using System; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface ITutorialPopup { diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/PopupFactory.Inventory.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/PopupFactory.Inventory.cs index ffb8e278c..0d7b3b691 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/PopupFactory.Inventory.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/PopupFactory.Inventory.cs @@ -1,4 +1,4 @@ -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public partial class PopupFactory : MonoSingleton { diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/TutorialPopup.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/TutorialPopup.cs index 1c161b00a..5605eccac 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Popups/TutorialPopup.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Popups/TutorialPopup.cs @@ -3,9 +3,10 @@ using System.Linq; using UnityEngine; using UnityEngine.UI; +using Xsolla.Core; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public class TutorialPopup : MonoBehaviour, ITutorialPopup { @@ -112,10 +113,9 @@ private IEnumerator RefreshElementHighlight() yield return new WaitForSeconds(0.1f); - if (!string.IsNullOrEmpty(CurrentStepInfo.highlightElementId)) { - var highlightableObjects = GameObject.FindGameObjectsWithTag(Constants.INVENTORY_TUTORIAL_HIGHLIGHT_TAG); + var highlightableObjects = GameObject.FindGameObjectsWithTag("Highlight"); var highlightObject = highlightableObjects.FirstOrDefault( obj => obj.activeSelf && obj.GetComponent()?.ID == CurrentStepInfo.highlightElementId); @@ -163,7 +163,7 @@ private void RefreshDocumentationButton() if (!string.IsNullOrEmpty(CurrentStepInfo.associatedDocumentation)) { documentationButton.gameObject.SetActive(true); - documentationButton.onClick = () => { BrowserHelper.Instance.Open(CurrentStepInfo.associatedDocumentation, true); }; + documentationButton.onClick = () => { XsollaWebBrowser.Open(CurrentStepInfo.associatedDocumentation, true); }; } else { @@ -188,7 +188,7 @@ private void MoveToNextStep() { if (!IsTutorialInfoValid) { - Debug.LogError("Tutorial popup info is invalid or missing!"); + XDebug.LogError("Tutorial popup info is invalid or missing!"); Destroy(gameObject, 0.001F); return; } @@ -209,7 +209,7 @@ private void MoveToPreviousStep() { if (!IsTutorialInfoValid) { - Debug.LogError("Tutorial popup info is invalid or missing!"); + XDebug.LogError("Tutorial popup info is invalid or missing!"); Destroy(gameObject, 0.001F); return; } @@ -219,4 +219,4 @@ private void MoveToPreviousStep() RefreshTutorial(); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/SdkCatalogLogic.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/CatalogLogic.cs similarity index 79% rename from Assets/Xsolla.Demo/Inventory/Scripts/Sdk/SdkCatalogLogic.cs rename to Assets/Xsolla.Demo/Inventory/Scripts/Sdk/CatalogLogic.cs index 736f261e3..98a6308ef 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/SdkCatalogLogic.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/CatalogLogic.cs @@ -8,7 +8,7 @@ namespace Xsolla.Demo { - public class SdkCatalogLogic : MonoSingleton + public class CatalogLogic : MonoSingleton { private const uint CATALOG_CACHE_TIMEOUT = 500; @@ -22,7 +22,7 @@ public class SdkCatalogLogic : MonoSingleton public void GetVirtualCurrencies(Action> onSuccess, Action onError = null) { - XsollaCatalog.Instance.GetVirtualCurrencyList(XsollaSettings.StoreProjectId, items => + XsollaCatalog.GetVirtualCurrencyList(items => { var currencies = items.items.ToList(); if (currencies.Any()) @@ -44,11 +44,11 @@ public void GetCatalogVirtualItems(Action> onSucce RequestStoreItems(items => { var virtualItems = new List(); - items.Where(i => !i.IsSubscription()).ToList().ForEach(i => + + items.Where(i => i.VirtualItemType != VirtualItemType.NonRenewingSubscription).ToList().ForEach(i => { - virtualItems.Add(new CatalogVirtualItemModel - { - IsConsumable = i.IsConsumable() + virtualItems.Add(new CatalogVirtualItemModel { + IsConsumable = i.VirtualItemType == VirtualItemType.Consumable }); FillCatalogItem(virtualItems.Last(), i); }); @@ -58,19 +58,20 @@ public void GetCatalogVirtualItems(Action> onSucce public void GetCatalogVirtualCurrencyPackages(Action> onSuccess, Action onError = null) { - XsollaCatalog.Instance.GetVirtualCurrencyPackagesList(XsollaSettings.StoreProjectId, packages => + XsollaCatalog.GetVirtualCurrencyPackagesList(packages => { var currencies = new List(); - packages.items.ForEach(p => + foreach (var package in packages.items) { - currencies.Add(new CatalogVirtualCurrencyModel - { - IsConsumable = p.IsConsumable(), - Amount = (uint)p.content.First().quantity, - CurrencySku = p.content.First().sku - }); - FillCatalogItem(currencies.Last(), p); - }); + var currency = new CatalogVirtualCurrencyModel { + IsConsumable = package.VirtualItemType == VirtualItemType.Consumable, + Amount = (uint) package.content.First().quantity, + CurrencySku = package.content.First().sku + }; + FillCatalogItem(currency, package); + currencies.Add(currency); + } + onSuccess?.Invoke(currencies); }, onError); } @@ -80,10 +81,9 @@ public void GetCatalogSubscriptions(Action> o RequestStoreItems(items => { var subscriptionItems = new List(); - items.Where(i => i.IsSubscription()).ToList().ForEach(i => + items.Where(i => i.VirtualItemType == VirtualItemType.NonRenewingSubscription).ToList().ForEach(i => { - subscriptionItems.Add(new CatalogSubscriptionItemModel - { + subscriptionItems.Add(new CatalogSubscriptionItemModel { IsConsumable = false, ExpirationPeriod = i.inventory_options.expiration_period.ToTimeSpan(), ExpirationPeriodText = i.inventory_options.expiration_period.ToString() @@ -100,13 +100,12 @@ public void GetCatalogBundles(Action> onSuccess, Ac { if (!_refreshBundlesInProgress) { - XsollaCatalog.Instance.GetBundles(XsollaSettings.StoreProjectId, bundles => + XsollaCatalog.GetBundles(bundles => { var bundleItems = new List(); bundles.items.ToList().ForEach(b => { - bundleItems.Add(new CatalogBundleItemModel - { + bundleItems.Add(new CatalogBundleItemModel { Sku = b.sku, Name = b.name, Description = b.description, @@ -125,9 +124,8 @@ public void GetCatalogBundles(Action> onSuccess, Ac if (_itemsCache.Any(i => i.sku.Equals(c.sku))) { var item = _itemsCache.First(i => i.sku.Equals(c.sku)); - var catalogItem = new CatalogVirtualItemModel - { - IsConsumable = item.IsConsumable() + var catalogItem = new CatalogVirtualItemModel { + IsConsumable = item.VirtualItemType == VirtualItemType.Consumable }; model.Content.Add(new BundleContentItem(catalogItem, c.quantity)); FillCatalogItem(model.Content.Last().Item, item); @@ -149,12 +147,6 @@ public void GetCatalogBundles(Action> onSuccess, Ac } else onSuccess?.Invoke(_bundlesCache); } - - [Obsolete("Use item.Groups instead")] - public List GetCatalogGroupsByItem(ItemModel item) - { - return item.Groups; - } private void RequestStoreItems(Action> onSuccess, Action onError = null) { @@ -163,7 +155,7 @@ private void RequestStoreItems(Action> onSuccess, Action if (!_refreshItemsInProgress) { _refreshItemsInProgress = true; - XsollaCatalog.Instance.GetCatalog(XsollaSettings.StoreProjectId, items => + XsollaCatalog.GetCatalog(items => { _refreshItemsInProgress = false; _itemsCacheTime = DateTime.Now; @@ -246,7 +238,7 @@ private void FillBundleItem(CatalogBundleItemModel model, BundleItem item) return new KeyValuePair(item.price.currency, item.price.GetAmount()); } - private KeyValuePair? GetVirtualPrice(StoreItem item, out KeyValuePair? priceWithoutDiscount) + private KeyValuePair? GetVirtualPrice(StoreItem item, out KeyValuePair? priceWithoutDiscount) { var virtualPrices = item.virtual_prices.ToList(); @@ -260,8 +252,8 @@ private void FillBundleItem(CatalogBundleItemModel model, BundleItem item) ? virtualPrices.First() : virtualPrices.First(v => v.is_default); - priceWithoutDiscount = new KeyValuePair(virtualPrice.sku, virtualPrice.GetAmountWithoutDiscount()); - return new KeyValuePair(virtualPrice.sku, virtualPrice.GetAmount()); + priceWithoutDiscount = new KeyValuePair(virtualPrice.sku, virtualPrice.GetAmountWithoutDiscount()); + return new KeyValuePair(virtualPrice.sku, virtualPrice.GetAmount()); } private KeyValuePair? GetBundleRealPrice(BundleItem item, out KeyValuePair? priceWithoutDiscount) @@ -276,7 +268,7 @@ private void FillBundleItem(CatalogBundleItemModel model, BundleItem item) return new KeyValuePair(item.price.currency, item.price.GetAmount()); } - private KeyValuePair? GetBundleVirtualPrice(BundleItem item, out KeyValuePair? priceWithoutDiscount) + private KeyValuePair? GetBundleVirtualPrice(BundleItem item, out KeyValuePair? priceWithoutDiscount) { var virtualPrices = item.virtual_prices.ToList(); @@ -290,8 +282,8 @@ private void FillBundleItem(CatalogBundleItemModel model, BundleItem item) ? virtualPrices.First() : virtualPrices.First(v => v.is_default); - priceWithoutDiscount = new KeyValuePair(virtualPrice.sku, virtualPrice.GetAmountWithoutDiscount()); - return new KeyValuePair(virtualPrice.sku, virtualPrice.GetAmount()); + priceWithoutDiscount = new KeyValuePair(virtualPrice.sku, virtualPrice.GetAmountWithoutDiscount()); + return new KeyValuePair(virtualPrice.sku, virtualPrice.GetAmount()); } private KeyValuePair? GetBundleContentRealPrice(BundleItem bundle, out KeyValuePair? priceWithoutDiscount) @@ -306,7 +298,7 @@ private void FillBundleItem(CatalogBundleItemModel model, BundleItem item) return new KeyValuePair(bundle.total_content_price.currency, bundle.total_content_price.GetAmount()); } - private KeyValuePair? GetBundleContentVirtualPrice(BundleItem bundle, out KeyValuePair? priceWithoutDiscount) + private KeyValuePair? GetBundleContentVirtualPrice(BundleItem bundle, out KeyValuePair? priceWithoutDiscount) { var bundleContent = bundle.content.ToList(); @@ -316,9 +308,9 @@ private void FillBundleItem(CatalogBundleItemModel model, BundleItem item) return null; } - uint contentVirtualPrice = 0; - uint contentVirtualPriceWithoutDiscount = 0; - string virtualCurrency = ""; + var contentVirtualPrice = 0; + var contentVirtualPriceWithoutDiscount = 0; + var virtualCurrency = ""; foreach (var bundleContentItem in bundleContent) { @@ -349,8 +341,8 @@ private void FillBundleItem(CatalogBundleItemModel model, BundleItem item) contentVirtualPriceWithoutDiscount += virtualPrice.GetAmountWithoutDiscount(); } - priceWithoutDiscount = new KeyValuePair(virtualCurrency, contentVirtualPriceWithoutDiscount); - return new KeyValuePair(virtualCurrency, contentVirtualPrice); + priceWithoutDiscount = new KeyValuePair(virtualCurrency, contentVirtualPriceWithoutDiscount); + return new KeyValuePair(virtualCurrency, contentVirtualPrice); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/SdkCatalogLogic.cs.meta b/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/CatalogLogic.cs.meta similarity index 100% rename from Assets/Xsolla.Demo/Inventory/Scripts/Sdk/SdkCatalogLogic.cs.meta rename to Assets/Xsolla.Demo/Inventory/Scripts/Sdk/CatalogLogic.cs.meta diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/DemoInventory.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/DemoInventory.cs index 4f7558c3c..2927bf220 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/DemoInventory.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/DemoInventory.cs @@ -1,27 +1,12 @@ using System; using System.Collections.Generic; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { public class DemoInventory : MonoSingleton { - public void GetInventoryItems(Action> onSuccess, Action onError = null) - { - SdkInventoryLogic.Instance.GetInventoryItems(onSuccess, OnInventoryError(onError)); - } - - public void GetVirtualCurrencyBalance(Action> onSuccess, Action onError = null) - { - SdkInventoryLogic.Instance.GetVirtualCurrencyBalance(onSuccess, OnInventoryError(onError)); - } - - public void GetUserSubscriptions(Action> onSuccess, Action onError = null) - { - SdkInventoryLogic.Instance.GetUserSubscriptions(onSuccess, OnInventoryError(onError)); - } - public void ConsumeInventoryItem(InventoryItemModel item, int count = 1, Action onSuccess = null, Action onError = null, bool isConfirmationRequired = true) { @@ -30,7 +15,7 @@ public void ConsumeInventoryItem(InventoryItemModel item, int count = 1, Action< var isFinished = false; PopupFactory.Instance.CreateWaiting().SetCloseCondition(() => isFinished); - SdkInventoryLogic.Instance.ConsumeInventoryItem(item, count, + InventoryLogic.Instance.ConsumeInventoryItem(item, count, onSuccess: consumedItem => { isFinished = true; @@ -45,9 +30,9 @@ public void ConsumeInventoryItem(InventoryItemModel item, int count = 1, Action< }); if (isConfirmationRequired) - StoreDemoPopup.ShowConsumeConfirmation(item.Name, (uint)count, onConfirmation, () => onError?.Invoke(null)); + StoreDemoPopup.ShowConsumeConfirmation(item.Name, (uint) count, onConfirmation, () => onError?.Invoke(null)); else - onConfirmation?.Invoke(); + onConfirmation.Invoke(); } public void RedeemCouponCode(string couponCode, Action> onSuccess, Action onError) @@ -55,30 +40,21 @@ public void RedeemCouponCode(string couponCode, Action isFinished); - SdkInventoryLogic.Instance.RedeemCouponCode(couponCode, - onSuccess: redeemedItems => - { - isFinished = true; - onSuccess?.Invoke(redeemedItems); - }, - onError: error => - { - isFinished = true; - - if (error.ErrorType != ErrorType.InvalidCoupon) - StoreDemoPopup.ShowError(error); - - onError?.Invoke(error); - }); - } + InventoryLogic.Instance.RedeemCouponCode(couponCode, + onSuccess: redeemedItems => + { + isFinished = true; + onSuccess?.Invoke(redeemedItems); + }, + onError: error => + { + isFinished = true; + + if (error.ErrorType != ErrorType.InvalidCoupon) + StoreDemoPopup.ShowError(error); - private Action OnInventoryError(Action onError) - { - return error => - { - StoreDemoPopup.ShowError(error); - onError?.Invoke(error); - }; + onError?.Invoke(error); + }); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/SdkInventoryLogic.cs b/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/InventoryLogic.cs similarity index 81% rename from Assets/Xsolla.Demo/Inventory/Scripts/Sdk/SdkInventoryLogic.cs rename to Assets/Xsolla.Demo/Inventory/Scripts/Sdk/InventoryLogic.cs index 8837785d7..c844773a5 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/SdkInventoryLogic.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/Sdk/InventoryLogic.cs @@ -7,20 +7,20 @@ namespace Xsolla.Demo { - public class SdkInventoryLogic : MonoSingleton + public class InventoryLogic : MonoSingleton { public void GetInventoryItems(Action> onSuccess, Action onError = null) { - XsollaInventory.Instance.GetInventoryItems(XsollaSettings.StoreProjectId, items => + XsollaInventory.GetInventoryItems(items => { - var inventoryItems = items.items.Where(i => !i.IsVirtualCurrency() && !i.IsSubscription()).Select( + var inventoryItems = items.items.Where(i => !i.type.Equals("virtual_currency") && i.VirtualItemType != VirtualItemType.NonRenewingSubscription).Select( i => new InventoryItemModel { Sku = i.sku, Description = i.description, Name = i.name, ImageUrl = i.image_url, - IsConsumable = i.IsConsumable(), + IsConsumable = i.VirtualItemType == VirtualItemType.Consumable, InstanceId = i.instance_id, RemainingUses = (uint?)i.quantity, Attributes = ItemInfoConverter.ConvertAttributes(i.attributes), @@ -32,7 +32,7 @@ public void GetInventoryItems(Action> onSuccess, Action public void GetVirtualCurrencyBalance(Action> onSuccess, Action onError = null) { - XsollaInventory.Instance.GetVirtualCurrencyBalance(XsollaSettings.StoreProjectId, balances => + XsollaInventory.GetVirtualCurrencyBalance(balances => { var result = balances.items.ToList().Select(b => new VirtualCurrencyBalanceModel { @@ -49,7 +49,7 @@ public void GetVirtualCurrencyBalance(Action> public void GetUserSubscriptions(Action> onSuccess, Action onError = null) { - XsollaInventory.Instance.GetTimeLimitedItems(XsollaSettings.StoreProjectId, items => + XsollaInventory.GetTimeLimitedItems(items => { var subscriptionItems = items.items.Select(i => new UserSubscriptionModel { @@ -75,14 +75,15 @@ public void ConsumeInventoryItem(InventoryItemModel item, int? count = 1, Action quantity = count }; - XsollaInventory.Instance.ConsumeInventoryItem(XsollaSettings.StoreProjectId, consumeItem, + XsollaInventory.ConsumeInventoryItem(consumeItem, onSuccess: () => onSuccess?.Invoke(item), - onError); + onError: onError); } public void RedeemCouponCode(string couponCode, Action> onSuccess, Action onError) { - XsollaCatalog.Instance.RedeemCouponCode(XsollaSettings.StoreProjectId, new CouponCode { coupon_code = couponCode }, + XsollaCatalog.RedeemCouponCode( + couponCode, onSuccess: redeemedItems => { var redeemedItemModels = redeemedItems.items.Select( @@ -96,7 +97,7 @@ public void RedeemCouponCode(string couponCode, Action PlayerPrefs.SetInt(Constants.INVENTORY_TUTORIAL_COMPLETED, 0); - #endif + public void DropTutorial() => PlayerPrefs.SetInt(INVENTORY_TUTORIAL_COMPLETED, 0); +#endif public void ShowTutorial(bool showWelcomeMessage = true) { @@ -23,12 +23,12 @@ public void ShowTutorial(bool showWelcomeMessage = true) public bool IsTutorialCompleted() { - return PlayerPrefs.GetInt(Constants.INVENTORY_TUTORIAL_COMPLETED, 0) > 0; + return PlayerPrefs.GetInt(INVENTORY_TUTORIAL_COMPLETED, 0) > 0; } void MarkTutorialAsCompleted() { - PlayerPrefs.SetInt(Constants.INVENTORY_TUTORIAL_COMPLETED, 1); + PlayerPrefs.SetInt(INVENTORY_TUTORIAL_COMPLETED, 1); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/UserSubscriptions.cs b/Assets/Xsolla.Demo/Inventory/Scripts/UserSubscriptions.cs index 1d8c99a38..424cfa4b2 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/UserSubscriptions.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/UserSubscriptions.cs @@ -24,7 +24,7 @@ public bool IsSubscription(string sku) public void UpdateSupscriptions(Action> onSuccess = null, Action onError = null) { - XsollaInventory.Instance.GetTimeLimitedItems(XsollaSettings.StoreProjectId, items => + XsollaInventory.GetTimeLimitedItems(items => { _items = items.items.ToList(); onSuccess?.Invoke(GetItems()); diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyBalance/VirtualCurrencyBalanceUI.cs b/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyBalance/VirtualCurrencyBalanceUI.cs index 2d083a948..0491cbf81 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyBalance/VirtualCurrencyBalanceUI.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyBalance/VirtualCurrencyBalanceUI.cs @@ -15,27 +15,27 @@ public void Initialize(ItemModel item) { if (!string.IsNullOrEmpty(item.ImageUrl)) { - ImageLoader.Instance.GetImageAsync(item.ImageUrl, (_, sprite) => + ImageLoader.LoadSprite(item.ImageUrl, sprite => { - if (Image/*still*/!= null) + if (Image /*still*/ != null) Image.sprite = sprite; }); } else { - Debug.LogError($"Item with sku = '{item.Sku}' without image!"); + XDebug.LogError($"Item with sku = '{item.Sku}' without image!"); } } else { - Debug.LogWarning($"Your Virtual Currency with sku = `{item.Sku}` created without Image component!"); + XDebug.LogWarning($"Your Virtual Currency with sku = `{item.Sku}` created without Image component!"); } } - public void SetBalance(uint balance) + public void SetBalance(int balance) { if (Text) Text.text = balance.ToString(); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyBalance/VirtualCurrencyContainer.cs b/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyBalance/VirtualCurrencyContainer.cs index 31d1419bf..45dadb52f 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyBalance/VirtualCurrencyContainer.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyBalance/VirtualCurrencyContainer.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; +using Xsolla.Core; using Xsolla.UIBuilder; namespace Xsolla.Demo @@ -15,7 +16,7 @@ public class VirtualCurrencyContainer : MonoBehaviour private void Awake() { if (virtualCurrencyBalanceProvider.GetValue() != null) return; - Debug.LogAssertion("VirtualCurrencyBalancePrefab is missing!"); + XDebug.LogWarning("VirtualCurrencyBalancePrefab is missing!"); Destroy(gameObject); } diff --git a/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyConsume/CharacterLevelManager.cs b/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyConsume/CharacterLevelManager.cs index 5787c1371..b965acc49 100644 --- a/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyConsume/CharacterLevelManager.cs +++ b/Assets/Xsolla.Demo/Inventory/Scripts/VirtualCurrencyConsume/CharacterLevelManager.cs @@ -2,8 +2,8 @@ using UnityEditor; using UnityEngine; using UnityEngine.UI; +using Xsolla.Auth; using Xsolla.Core; -using Xsolla.Login; namespace Xsolla.Demo { @@ -11,7 +11,7 @@ public class CharacterLevelManager : MonoBehaviour { [SerializeField] private string CurrencySkuOrName = default; [SerializeField] private bool TryUseDefaultCurrencyOnFailure = default; - [SerializeField] private uint LevelUpPrice = default; + [SerializeField] private int LevelUpPrice = default; [SerializeField] private VirtualCurrencyBalanceUI VirtualCurrencyPrefab = default; [SerializeField] private Transform PriceTagPlacement = default; [SerializeField] private SimpleButton LevelUpButton = default; @@ -28,7 +28,6 @@ private void Awake() private void Start() { - var token = Token.Instance; Action successCallback = info => { @@ -39,11 +38,11 @@ private void Start() Action errorCallback = error => { - Debug.LogError("Could not get info for character level save/load"); + XDebug.LogError("Could not get info for character level save/load"); InitializeUI(); }; - SdkAuthLogic.Instance.GetUserInfo(token, successCallback, errorCallback); + XsollaAuth.GetUserInfo(successCallback, errorCallback); } private void InitializeUI() @@ -52,7 +51,7 @@ private void InitializeUI() if(_targetCurrency == null) { - Debug.Log("Could not obtain target currency"); + XDebug.Log("Could not obtain target currency"); LevelUpButton.onClick -= TryUpTheLevel; return; } @@ -75,7 +74,7 @@ private void TryUpTheLevel() var userCurrency = UserInventory.Instance.Balance?.Find(currency => _targetCurrency.Sku == currency.Sku); if (userCurrency == null) { - Debug.Log("UserInventory does not contain required currency"); + XDebug.Log("UserInventory does not contain required currency"); return; } @@ -103,17 +102,17 @@ private void TryUpTheLevel() levelUpPayment, (int)LevelUpPrice, onSuccess: _ => onSuccessConsume.Invoke(), - onError: _ => Debug.Log("Could not consume virtual currency")); + onError: _ => XDebug.Log("Could not consume virtual currency")); } else { - Debug.LogError("Character level up supposed to be hidden in case InventoryDemo was not provided"); + XDebug.LogError("Character level up supposed to be hidden in case InventoryDemo was not provided"); } } else { var errorMessage = "Not enough currency amount to up the level"; - Debug.Log(errorMessage); + XDebug.Log(errorMessage); StoreDemoPopup.ShowWarning(new Error(errorMessage: errorMessage)); } } @@ -123,7 +122,7 @@ private VirtualCurrencyModel GetTargetCurrency() var allCurrencies = UserCatalog.Instance.VirtualCurrencies; if (allCurrencies == null) { - Debug.LogWarning("UserCatalog returned null as VirtualCurrencies"); + XDebug.LogWarning("UserCatalog returned null as VirtualCurrencies"); return null; } @@ -135,11 +134,11 @@ private VirtualCurrencyModel GetTargetCurrency() if (/*still*/targetCurrency == null) { - Debug.LogWarning($"Could not find specified virtual currency: {CurrencySkuOrName}"); + XDebug.LogWarning($"Could not find specified virtual currency: {CurrencySkuOrName}"); if (TryUseDefaultCurrencyOnFailure) { - Debug.Log("Will try to get default project's currency"); + XDebug.Log("Will try to get default project's currency"); targetCurrency = allCurrencies.Count > 0 ? allCurrencies[0] : null; } } @@ -148,12 +147,12 @@ private VirtualCurrencyModel GetTargetCurrency() targetCurrency = allCurrencies.Count > 0 ? allCurrencies[0] : null; if (targetCurrency == null) - Debug.LogWarning("Could not find virtual currency"); + XDebug.LogWarning("Could not find virtual currency"); return targetCurrency; } - private void DrawPrice(VirtualCurrencyModel priceCurrency, uint price) + private void DrawPrice(VirtualCurrencyModel priceCurrency, int price) { var currencyObject = Instantiate(VirtualCurrencyPrefab.gameObject, PriceTagPlacement); var currencyUI = currencyObject.GetComponent(); @@ -167,7 +166,7 @@ private int LoadLevel(string levelEntry) return PlayerPrefs.GetInt(levelEntry, 1); else { - Debug.LogError("Could not load level. Level entry is null or empty"); + XDebug.LogError("Could not load level. Level entry is null or empty"); return 1; } } @@ -177,7 +176,7 @@ private void SaveLevel(string levelEntry, int characterLevel) if (!string.IsNullOrEmpty(levelEntry)) PlayerPrefs.SetInt(levelEntry, characterLevel); else - Debug.LogError("Could not save level. Level entry is null or empty"); + XDebug.LogError("Could not save level. Level entry is null or empty"); } private void ShowLevel(int characterLevel) diff --git a/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial.meta b/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial.meta deleted file mode 100644 index c6027da20..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 22d09360c66c14150ab303ac97c25cb4 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial/AndroidSDKSocialAuthListener.cs b/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial/AndroidSDKSocialAuthListener.cs deleted file mode 100644 index f6b85e936..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial/AndroidSDKSocialAuthListener.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using UnityEngine; - -namespace Xsolla.Demo -{ - /// - /// This component MUST be attached to an object called 'SocialNetworks' because its method is called by using Unity.SendMessage - /// - public class AndroidSDKSocialAuthListener : MonoBehaviour - { - public event Action OnSocialAuthResult; - - /// - /// This method is called from within AndroidSDK by using Unity.SendMessage - /// - /// - public void ReceiveSocialAuthResult(string authResult) - { - Debug.Log("AndroidSDKListener.ReceiveSocialAuthResult: auth result arrived"); - OnSocialAuthResult?.Invoke(authResult); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial/AndroidSDKSocialAuthListener.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial/AndroidSDKSocialAuthListener.cs.meta deleted file mode 100644 index ca126bfd0..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Auth/AndroidSocial/AndroidSDKSocialAuthListener.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: cb5000bdae754c341a04031ed7ba626f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher.meta b/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher.meta deleted file mode 100644 index 385112c22..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e957aeb1e7c8347a2ac836f8e158a29e -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher/LauncherArguments.cs b/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher/LauncherArguments.cs deleted file mode 100644 index 145dbdb1e..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher/LauncherArguments.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Linq; -using Newtonsoft.Json.Utilities; -using Xsolla.Core; - -namespace Xsolla.Demo -{ - public class LauncherArguments : MonoSingleton - { - const string LAUNCHER_TOKEN = "xsolla-login-token"; - - private bool invalidated = false; - - public string GetToken() - { - var commandLineArgs = Environment.GetCommandLineArgs(); - - if (invalidated || commandLineArgs.Count(a => a.Contains(LAUNCHER_TOKEN)) == 0) - { - return string.Empty; - } - - var tokenParamValueIndex = default(int); - for (int i = 0; i < commandLineArgs.Length; i++) - { - if (commandLineArgs[i].Contains(LAUNCHER_TOKEN)) - tokenParamValueIndex = i + 1; - } - - if (tokenParamValueIndex < commandLineArgs.Length) - { - return commandLineArgs[tokenParamValueIndex]; - } - - return string.Empty; - } - - public void InvalidateTokenArguments() - { - invalidated = true; - } - } -} diff --git a/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher/LauncherArguments.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher/LauncherArguments.cs.meta deleted file mode 100644 index 5c675d7cf..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Auth/Launcher/LauncherArguments.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7a9d35caa841a4fd3bac5d09c7a044fb -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Login/Scripts/DemoTypeMarker.meta b/Assets/Xsolla.Demo/Login/Scripts/DemoTypeMarker.meta deleted file mode 100644 index 127b45c25..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/DemoTypeMarker.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 323e43164566adc4aa25dbf07f0f0384 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendActionsButton.cs b/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendActionsButton.cs index 8fdb28e44..24dc0ff7c 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendActionsButton.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendActionsButton.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using UnityEngine; +using Xsolla.Core; namespace Xsolla.Demo { @@ -71,7 +72,7 @@ public void AddAction(string actionName, Action callback) } else { - Debug.LogError("In FriendActionsButton script `actionPrefab` or `actionContainer` = null!"); + XDebug.LogError("In FriendActionsButton script `actionPrefab` or `actionContainer` = null!"); } } diff --git a/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendSystemSocialNetwork.cs b/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendSystemSocialNetwork.cs index 682fc6f3d..d7be9d987 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendSystemSocialNetwork.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendSystemSocialNetwork.cs @@ -37,10 +37,10 @@ public void RefreshState() if (provider == SocialProvider.None) return; - SdkUserAccountLogic.Instance.GetLinkedSocialProviders( + UserAccountLogic.Instance.GetLinkedSocialProviders( onSuccess: networks => { - if (networks.Any(n => n.provider.Equals(provider.GetParameter()))) + if (networks.Any(n => n.provider.Equals(provider.ToString().ToLowerInvariant()))) SetState(State.Linked); else SetState(State.Unlinked); @@ -89,7 +89,7 @@ private void SetState(State state) } default: { - Debug.LogWarning($"Unexpected state: '{state}'"); + XDebug.LogWarning($"Unexpected state: '{state}'"); return; } } @@ -99,7 +99,7 @@ private void SetState(State state) private void UnlinkSocialProvider() { - Debug.Log("We can not unlink social provider yet. So do nothing."); + XDebug.Log("We can not unlink social provider yet. So do nothing."); } private void LinkSocialProvider() @@ -128,10 +128,10 @@ private void LinkSocialProvider() { Action onSuccessLink = _ => { - SdkUserAccountLogic.Instance.PurgeSocialProvidersCache(); + UserAccountLogic.Instance.PurgeSocialProvidersCache(); UserFriends.Instance.UpdateFriends(RefreshState,StoreDemoPopup.ShowError); }; - SdkUserAccountLogic.Instance.LinkSocialProvider(provider, onSuccess: onSuccessLink, onError: StoreDemoPopup.ShowError); + UserAccountLogic.Instance.LinkSocialProvider(provider, onSuccess: onSuccessLink, onError: StoreDemoPopup.ShowError); } else { diff --git a/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendUI.cs b/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendUI.cs index 836013b1c..eed9ead4a 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendUI.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Friends/FriendUI.cs @@ -18,10 +18,10 @@ public class FriendUI : MonoBehaviour [SerializeField] private SocialProviderContainer[] SocialFriendshipMarkers = default; public FriendModel FriendModel { get; private set; } - + public void Initialize(FriendModel friend) { - if(friend == null) return; + if (friend == null) return; FriendModel = friend; InitAvatar(FriendModel); @@ -35,14 +35,14 @@ private void InitAvatar(FriendModel friend) { if (!string.IsNullOrEmpty(friend.AvatarUrl)) { - ImageLoader.Instance.GetImageAsync(friend.AvatarUrl, (url, sprite) => + ImageLoader.LoadSprite(friend.AvatarUrl, sprite => { if (avatarImage) { avatarImage.gameObject.SetActive(true); avatarImage.sprite = sprite; } - }); + }); } else avatarImage.gameObject.SetActive(true); @@ -74,10 +74,10 @@ private void InitStatus(FriendModel friend) private void InitNickname(FriendModel friend) { var text = string.IsNullOrEmpty(friend.Nickname) ? string.Empty : friend.Nickname; - - if(!string.IsNullOrEmpty(text)) + + if (!string.IsNullOrEmpty(text)) gameObject.name = text; - + nicknameText.text = text; tagText.text = string.IsNullOrEmpty(friend.Tag) ? string.Empty : $"#{friend.Tag}"; @@ -121,10 +121,11 @@ public void SetUserState(UserState state) } default: { - Debug.LogWarning($"Set up handle of user state = '{state.ToString()}' in FriendUI.cs"); + XDebug.LogWarning($"Set up handle of user state = '{state.ToString()}' in FriendUI.cs"); return; } } + userState.Init(this, userButtons, userStatusLine, actionsButton); } @@ -164,8 +165,7 @@ public void SetUserRelationship(UserRelationship relationship) } default: { - Debug.LogException(new ArgumentOutOfRangeException(nameof(relationship), relationship, null)); - break; + throw new ArgumentOutOfRangeException(nameof(relationship), relationship, null); } } } @@ -190,4 +190,4 @@ private void SetSocialFriendship(SocialProvider provider) AddSocialFriendshipMark(provider); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Friends/UserFriends.cs b/Assets/Xsolla.Demo/Login/Scripts/Friends/UserFriends.cs index 8f1bcdbce..d1546753a 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Friends/UserFriends.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Friends/UserFriends.cs @@ -4,7 +4,9 @@ using System.Linq; using JetBrains.Annotations; using UnityEngine; +using Xsolla.Auth; using Xsolla.Core; +using Xsolla.UserAccount; namespace Xsolla.Demo { @@ -58,6 +60,30 @@ public void UpdateFriends([CanBeNull] Action onSuccess = null, [CanBeNull] Actio StartCoroutine(UpdateFriendsCoroutine(onSuccess, onError)); } + private void ValidateToken(Action onSuccess, Action onError) + { + void handleError(Error error) + { + if (error.ErrorType == ErrorType.InvalidToken) + { + XDebug.Log("SavedTokenAuth: Trying to refresh OAuth token"); + XsollaAuth.RefreshToken( + onSuccess, + refreshError => + { + XDebug.LogError(error.errorMessage); + onError?.Invoke(null); + }); + } + else + { + onError?.Invoke(null); + } + } + + XsollaAuth.GetUserInfo(_ => { onSuccess?.Invoke(); }, handleError); + } + private IEnumerator UpdateFriendsCoroutine(Action onSuccess, Action onError) { bool? isTokenValid = null; @@ -67,9 +93,8 @@ private IEnumerator UpdateFriendsCoroutine(Action onSuccess, Action onErr bool pendingBusy = true; bool requestedBusy = true; - SdkAuthLogic.Instance.ValidateToken( - Token.Instance, - onSuccess: _ => isTokenValid = true, + ValidateToken( + onSuccess: () => isTokenValid = true, onError: _ => isTokenValid = false ); @@ -91,18 +116,18 @@ private IEnumerator UpdateFriendsCoroutine(Action onSuccess, Action onErr } else { - onError?.Invoke(new Error(ErrorType.InvalidToken, errorMessage:"Your token is not valid")); + onError?.Invoke(new Error(ErrorType.InvalidToken, errorMessage: "Your token is not valid")); } } private void UpdateUserSocialFriends(Action onSuccess = null, Action onError = null) { - SdkFriendsLogic.Instance.ForceUpdateFriendsFromSocialNetworks(onSuccess, onError); + FriendsLogic.Instance.ForceUpdateFriendsFromSocialNetworks(onSuccess, onError); } private void UpdateUserFriends(Action onSuccess = null, Action onError = null) { - SdkFriendsLogic.Instance.GetUserFriends(friends => + FriendsLogic.Instance.GetUserFriends(friends => { Friends = friends; UserFriendsUpdatedEvent?.Invoke(); @@ -112,7 +137,7 @@ private void UpdateUserFriends(Action onSuccess = null, Action onError = private void UpdateBlockedUsers(Action onSuccess = null, Action onError = null) { - SdkFriendsLogic.Instance.GetBlockedUsers(users => + FriendsLogic.Instance.GetBlockedUsers(users => { Blocked = users; BlockedUsersUpdatedEvent?.Invoke(); @@ -122,7 +147,7 @@ private void UpdateBlockedUsers(Action onSuccess = null, Action onError = private void UpdatePendingUsers(Action onSuccess = null, Action onError = null) { - SdkFriendsLogic.Instance.GetPendingUsers(users => + FriendsLogic.Instance.GetPendingUsers(users => { Pending = users; PendingUsersUpdatedEvent?.Invoke(); @@ -132,7 +157,7 @@ private void UpdatePendingUsers(Action onSuccess = null, Action onError = private void UpdateRequestedUsers(Action onSuccess = null, Action onError = null) { - SdkFriendsLogic.Instance.GetRequestedUsers(users => + FriendsLogic.Instance.GetRequestedUsers(users => { Requested = users; RequestedUsersUpdatedEvent?.Invoke(); @@ -142,7 +167,7 @@ private void UpdateRequestedUsers(Action onSuccess = null, Action onError private void UpdateSocialFriends(Action onSuccess = null, Action onError = null) { - SdkFriendsLogic.Instance.GetFriendsFromSocialNetworks(users => + FriendsLogic.Instance.GetFriendsFromSocialNetworks(users => { SocialFriends = users; SocialFriendsUpdatedEvent?.Invoke(); @@ -152,7 +177,7 @@ private void UpdateSocialFriends(Action onSuccess = null, Action onError private void RaiseOnError(string message, Action onError = null) { - Debug.LogError(message); + XDebug.LogError(message); var error = new Error(ErrorType.IncorrectFriendState, errorMessage: message); onError?.Invoke(error); } @@ -164,16 +189,19 @@ private void RemoveUserFromMemory(FriendModel user) Friends.Remove(user); UserFriendsUpdatedEvent?.Invoke(); } + if (Pending.Contains(user)) { Pending.Remove(user); PendingUsersUpdatedEvent?.Invoke(); } + if (Requested.Contains(user)) { Requested.Remove(user); RequestedUsersUpdatedEvent?.Invoke(); } + if (Blocked.Contains(user)) { Blocked.Remove(user); @@ -187,7 +215,7 @@ public void BlockUser(FriendModel user, [CanBeNull] Action onSucces RaiseOnError($"Can not block user with this nickname = {user.Nickname}. They are already blocked.", onError); else { - SdkFriendsLogic.Instance.BlockUser(user, blockedUser => + FriendsLogic.Instance.BlockUser(user, blockedUser => { RemoveUserFromMemory(user); UpdateBlockedUsers(onError: onError); @@ -201,7 +229,7 @@ public void UnblockUser(FriendModel user, [CanBeNull] Action onSucc if (!Blocked.Contains(user)) RaiseOnError($"Can not unblock user with this nickname = {user.Nickname}. This user is not in the list of blocked friends.", onError); else - SdkFriendsLogic.Instance.UnblockUser(user, u => + FriendsLogic.Instance.UnblockUser(user, u => { RemoveUserFromMemory(user); onSuccess?.Invoke(u); @@ -213,7 +241,7 @@ public void AddFriend(FriendModel user, [CanBeNull] Action onSucces if (Friends.Contains(user) || Blocked.Contains(user) || Pending.Contains(user) || Requested.Contains(user)) RaiseOnError($"Can not add friend with this nickname = {user.Nickname}. This friend is not in the 'initial' state.", onError); else - SdkFriendsLogic.Instance.SendFriendshipInvite(user, u => + FriendsLogic.Instance.SendFriendshipInvite(user, u => { RemoveUserFromMemory(user); UpdateRequestedUsers(onError: onError); @@ -227,7 +255,7 @@ public void RemoveFriend(FriendModel user, [CanBeNull] Action onSuc RaiseOnError($"Can not remove friend with this nickname = {user.Nickname}. This user is not in the friend list.", onError); else { - SdkFriendsLogic.Instance.RemoveFriend(user, u => + FriendsLogic.Instance.RemoveFriend(user, u => { RemoveUserFromMemory(user); onSuccess?.Invoke(u); @@ -240,7 +268,7 @@ public void AcceptFriendship(FriendModel user, [CanBeNull] Action o if (!Pending.Contains(user)) RaiseOnError($"Can not accept friendship from the user = {user.Nickname}. They are not a pending user.", onError); else - SdkFriendsLogic.Instance.AcceptFriendship(user, u => + FriendsLogic.Instance.AcceptFriendship(user, u => { RemoveUserFromMemory(user); UpdateUserFriends(); @@ -253,7 +281,7 @@ public void DeclineFriendship(FriendModel user, [CanBeNull] Action if (!Pending.Contains(user)) RaiseOnError($"Can not accept friendship from the user = {user.Nickname}. They are not a pending user.", onError); else - SdkFriendsLogic.Instance.DeclineFriendship(user, u => + FriendsLogic.Instance.DeclineFriendship(user, u => { RemoveUserFromMemory(user); onSuccess?.Invoke(u); @@ -265,17 +293,38 @@ public void CancelFriendshipRequest(FriendModel user, [CanBeNull] Action + FriendsLogic.Instance.CancelFriendshipRequest(user, u => { RemoveUserFromMemory(user); onSuccess?.Invoke(u); }, onError); } - public void SearchUsersByNickname(string nickname, [CanBeNull] Action> onSuccess = null, - [CanBeNull] Action onError = null) + public void SearchUsersByNickname(string nickname, Action> onSuccess = null, Action onError = null) { - SdkUserAccountLogic.Instance.SearchUsersByNickname(nickname, onSuccess, onError); + nickname = Uri.EscapeDataString(nickname); + + XsollaUserAccount.SearchUsers( + nickname, + 0, + 20, + users => + { + onSuccess?.Invoke(users.users.Where(u => !u.is_me).Select(u => + { + var result = new FriendModel { + Id = u.user_id, + AvatarUrl = u.avatar, + Nickname = u.nickname, + Tag = u.tag + }; + var user = UserFriends.Instance.GetUserById(result.Id); + result.Status = user?.Status ?? UserOnlineStatus.Unknown; + result.Relationship = user?.Relationship ?? UserRelationship.Unknown; + return result; + }).ToList()); + }, + onError); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Friends/UserStatesUI/BaseUserStateUI.cs b/Assets/Xsolla.Demo/Login/Scripts/Friends/UserStatesUI/BaseUserStateUI.cs index a4929c2ab..3a0442f70 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Friends/UserStatesUI/BaseUserStateUI.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Friends/UserStatesUI/BaseUserStateUI.cs @@ -1,6 +1,6 @@ using System; using UnityEngine; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { diff --git a/Assets/Xsolla.Demo/Login/Scripts/Internal.meta b/Assets/Xsolla.Demo/Login/Scripts/Internal.meta new file mode 100644 index 000000000..48b38a0e9 --- /dev/null +++ b/Assets/Xsolla.Demo/Login/Scripts/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 53874787641048159afffa5b2615e9c8 +timeCreated: 1683275630 \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/DemoTypeMarker/DemoMarker.Login.cs b/Assets/Xsolla.Demo/Login/Scripts/Internal/DemoMarker.Login.cs similarity index 100% rename from Assets/Xsolla.Demo/Login/Scripts/DemoTypeMarker/DemoMarker.Login.cs rename to Assets/Xsolla.Demo/Login/Scripts/Internal/DemoMarker.Login.cs diff --git a/Assets/Xsolla.Demo/Login/Scripts/DemoTypeMarker/DemoMarker.Login.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Internal/DemoMarker.Login.cs.meta similarity index 100% rename from Assets/Xsolla.Demo/Login/Scripts/DemoTypeMarker/DemoMarker.Login.cs.meta rename to Assets/Xsolla.Demo/Login/Scripts/Internal/DemoMarker.Login.cs.meta diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/AndroidSocialAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/AndroidSocialAuth.cs deleted file mode 100644 index 75474ffd9..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/AndroidSocialAuth.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Demo -{ - public class AndroidSocialAuth : LoginAuthorization - { - public override void TryAuth(params object[] args) - { - if (TryExtractProvider(args, out SocialProvider socialProvider)) - { - try - { - using (var sdkHelper = new AndroidSDKSocialAuthHelper()) - { - sdkHelper.PerformSocialAuth(socialProvider, - onSuccess: token => OnSocialAuthResult(socialProvider, SocialAuthResult.SUCCESS, token: token), - onCancelled: () => OnSocialAuthResult(socialProvider, SocialAuthResult.CANCELLED), - onError: error => OnSocialAuthResult(socialProvider, SocialAuthResult.ERROR, error: error)); - } - - Debug.Log("AndroidSocialAuth.SocialNetworkAuth: auth request was sent"); - } - catch (Exception ex) - { - Debug.LogError($"AndroidSocialAuth.SocialNetworkAuth: {ex.Message}"); - base.OnError?.Invoke(new Error(errorMessage: "Social auth failed")); - } - } - else - { - Debug.LogWarning("AndroidSocialAuth.TryAuth: Could not extract argument"); - base.OnError?.Invoke(new Error(errorMessage: "Social auth failed")); - } - } - - private bool TryExtractProvider(object[] args, out SocialProvider provider) - { - provider = default(SocialProvider); - - if (args == null) - { - Debug.LogError("AndroidSocialAuth.TryExtractProvider: 'object[] args' was null"); - return false; - } - - if (args.Length != 1) - { - Debug.LogError($"AndroidSocialAuth.TryExtractProvider: args.Length expected 1, was {args.Length}"); - return false; - } - - try - { - provider = (SocialProvider)args[0]; - } - catch (Exception ex) - { - Debug.LogError($"AndroidSocialAuth.TryExtractProvider: Error during argument extraction: {ex.Message}"); - return false; - } - - return true; - } - - - private void OnSocialAuthResult(SocialProvider socialProvider, SocialAuthResult authResult, string token = null, Error error = null) - { - Debug.Log($"AndroidSocialAuth.OnSocialAuthResult: processing auth result for {socialProvider}"); - - var logHeader = $"AndroidSocialAuth.OnSocialAuthResult: authResult for {socialProvider} returned"; - - switch (authResult) - { - case SocialAuthResult.SUCCESS: - Debug.Log($"{logHeader} SUCCESS. Token: {token}"); - base.OnSuccess?.Invoke(token); - break; - case SocialAuthResult.CANCELLED: - Debug.Log($"{logHeader} CANCELLED."); - base.OnError?.Invoke(null); - break; - case SocialAuthResult.ERROR: - Debug.LogError($"{logHeader} ERROR. Error message: {error.errorMessage}"); - base.OnError?.Invoke(error); - break; - default: - Debug.LogError($"{logHeader} unexpected authResult."); - base.OnError?.Invoke(new Error(errorMessage: "Social auth failed")); - break; - } - } - - private enum SocialAuthResult - { - SUCCESS, CANCELLED, ERROR - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/AndroidSocialAuth.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/AndroidSocialAuth.cs.meta deleted file mode 100644 index b4eb39a8c..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/AndroidSocialAuth.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5c6bba1da82e0204f8b25a153b370443 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/BasicAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/BasicAuth.cs index d44ac99fe..a5ccd32a1 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/BasicAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/BasicAuth.cs @@ -1,4 +1,5 @@ using System; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo @@ -9,77 +10,76 @@ public class BasicAuth : LoginAuthorization private bool _isDemoUser; private bool _isJwtInvalidationEnabled; - public override void TryAuth(params object[] args) + public override void TryAuth(object[] args, Action onSuccess, Action onError) { - if (TryExtractArgs(args, out string username, out string password, out bool rememberMe)) + if (!TryExtractArgs(args, out var username, out var password)) { - _isDemoUser = (username.ToUpper() == DEMO_USER_NAME && password.ToUpper() == DEMO_USER_NAME); - _isJwtInvalidationEnabled = XsollaSettings.InvalidateExistingSessions; + onError?.Invoke(new Error(errorMessage: "Basic auth failed. Can't extract username and password")); + return; + } - if(_isDemoUser && _isJwtInvalidationEnabled) - XsollaSettings.InvalidateExistingSessions = false; + ChangeJwtInvalidationIfNeeded(username, password); - SdkAuthLogic.Instance.SignIn(username, password, rememberMe, BasicAuthSuccess, BasicAuthFailed); - } - else - { - Debug.LogError("BasicAuth.TryAuth: Could not extract arguments for SignIn"); - base.OnError?.Invoke(new Error(errorMessage: "Basic auth failed")); - } + XsollaAuth.SignIn( + username, + password, + () => + { + RestoreJwtInvalidationIfNeeded(); + onSuccess?.Invoke(); + }, + error => + { + RestoreJwtInvalidationIfNeeded(); + onError?.Invoke(error); + }); } - private bool TryExtractArgs(object[] args, out string username, out string password, out bool rememberMe) + private static bool TryExtractArgs(object[] args, out string username, out string password) { - username = default(string); - password = default(string); - rememberMe = default(bool); + username = default; + password = default; if (args == null) { - Debug.LogError("BasicAuth.TryExtractArgs: 'object[] args' was null"); + XDebug.LogError("BasicAuth.TryExtractArgs: 'object[] args' was null"); return false; } - if (args.Length != 3) + if (args.Length != 2) { - Debug.LogError($"BasicAuth.TryExtractArgs: args.Length expected 3, was {args.Length}"); + XDebug.LogError($"BasicAuth.TryExtractArgs: args.Length expected 2, was {args.Length}"); return false; } try { - username = (string)args[0]; - password = (string)args[1]; - rememberMe = (bool)args[2]; - + username = (string) args[0]; + password = (string) args[1]; LoginPageEnterController.LastUsername = username; } catch (Exception ex) { - Debug.LogError($"BasicAuth.TryExtractArgs: Error during argument extraction: {ex.Message}"); + XDebug.LogError($"BasicAuth.TryExtractArgs: Error during argument extraction: {ex.Message}"); return false; } return true; } - private void BasicAuthSuccess(string token) + private void ChangeJwtInvalidationIfNeeded(string username, string password) { - RestoreJwtInvalidationIfNeeded(); - base.OnSuccess?.Invoke(Token.Instance); - } + _isDemoUser = username.ToUpper() == DEMO_USER_NAME && password.ToUpper() == DEMO_USER_NAME; + _isJwtInvalidationEnabled = XsollaSettings.InvalidateExistingSessions; - private void BasicAuthFailed(Error error) - { - RestoreJwtInvalidationIfNeeded(); - Debug.LogWarning($"BasicAuth: auth failed. Error: {error.errorMessage}"); - base.OnError?.Invoke(error); + if (_isDemoUser && _isJwtInvalidationEnabled) + XsollaSettings.InvalidateExistingSessions = false; } private void RestoreJwtInvalidationIfNeeded() { - if(_isDemoUser && _isJwtInvalidationEnabled) + if (_isDemoUser && _isJwtInvalidationEnabled) XsollaSettings.InvalidateExistingSessions = true; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/ConsolePlatformAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/ConsolePlatformAuth.cs index a34485cbc..69e92d11b 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/ConsolePlatformAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/ConsolePlatformAuth.cs @@ -1,42 +1,24 @@ -using Xsolla.Core; +using System; +using Xsolla.Auth; +using Xsolla.Core; namespace Xsolla.Demo { public class ConsolePlatformAuth : LoginAuthorization { - public override void TryAuth(params object[] args) + public override void TryAuth(object[] _, Action onSuccess, Action onError) { - if (DemoSettings.UseConsoleAuth) + if (!DemoSettings.UseConsoleAuth) { - Debug.Log("ConsolePlatformAuth.TryAuth: Console auth enabled, trying to get token"); - RequestToken(); + onError?.Invoke(null); + return; } - else - { - Debug.Log("ConsolePlatformAuth.TryAuth: Console auth disabled"); - base.OnError?.Invoke(null); - } - } - - private void RequestToken() - { - SdkAuthLogic.Instance.SignInConsoleAccount( - userId: DemoSettings.UsernameFromConsolePlatform, - platform: DemoSettings.Platform.GetString(), - SuccessHandler, - FailHandler); - } - private void SuccessHandler(string token) - { - Debug.Log("ConsolePlatformAuth.SuccessHandler: Token loaded"); - base.OnSuccess?.Invoke(token); - } - - private void FailHandler(Error error) - { - Debug.LogError($"Failed request token by console account with user = `{DemoSettings.UsernameFromConsolePlatform}` and platform = `{DemoSettings.Platform.GetString()}`. Error:{error.ToString()}"); - base.OnError?.Invoke(error); + XsollaAuth.SignInConsoleAccount( + DemoSettings.UsernameFromConsolePlatform, + DemoSettings.Platform.GetString(), + onSuccess, + onError); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/DeviceIdAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/DeviceIdAuth.cs index 4549f7285..d6f1b9a7d 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/DeviceIdAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/DeviceIdAuth.cs @@ -1,50 +1,19 @@ +using System; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo { public class DeviceIdAuth : LoginAuthorization { - public override void TryAuth(params object[] args) + public override void TryAuth(object[] _, Action onSuccess, Action onError) { - var supported = true; -#if !(UNITY_ANDROID || UNITY_IOS) || UNITY_EDITOR - var message = "Device ID auth is not supported for this platform"; - base.OnError?.Invoke(new Error(ErrorType.MethodIsNotAllowed, errorMessage: message)); - supported = false; -#endif - if (!supported) - return; - -#if UNITY_IOS - var deviceType = DeviceType.iOS; +#if !(UNITY_ANDROID || UNITY_IOS) + onError?.Invoke(new Error(ErrorType.MethodIsNotAllowed, errorMessage: "Device ID auth is not supported for this platform")); + return; #else - var deviceType = DeviceType.Android; + XsollaAuth.AuthViaDeviceID(onSuccess, onError); #endif - var possibleException = DeviceIdUtil.GetDeviceInfo(deviceType, out string deviceId, out string deviceName, out string deviceModel); - if (possibleException != null) - { - FailHandler(new Error(errorMessage: possibleException.Message)); - return; - } - - var deviceInfo = $"{deviceName}:{deviceModel}"; - Debug.Log($"Trying device_type:'{deviceType}', device_id:'{deviceId}', device:'{deviceInfo}'"); - - SdkAuthLogic.Instance.AuthViaDeviceID(deviceType, deviceInfo, deviceId, - onSuccess: SuccessHandler, - onError: FailHandler); - } - - private void SuccessHandler(string token) - { - Debug.Log($"DeviceID Auth: Token obtained '{token}'"); - base.OnSuccess?.Invoke(token); - } - - private void FailHandler(Error error) - { - Debug.LogError($"DeviceID Auth: Failed with error '{error.ToString()}'"); - base.OnError?.Invoke(error); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/ICodeRequester.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/ICodeRequester.cs index b89205794..e5829300d 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/ICodeRequester.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/ICodeRequester.cs @@ -3,9 +3,10 @@ namespace Xsolla.Demo { - public interface ICodeRequester - { + public interface ICodeRequester + { void RequestCode(Action onCode); + void RaiseOnError(Error error); - } -} + } +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/IosSocialAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/IosSocialAuth.cs deleted file mode 100644 index 93bd03e3a..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/IosSocialAuth.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using Xsolla.Auth; -using Xsolla.Core; - -namespace Xsolla.Demo -{ - public class IosSocialAuth : LoginAuthorization - { - public override void TryAuth(params object[] args) - { - -#if UNITY_IOS - if (TryExtractProvider(args, out SocialProvider provider)) - { - try - { - new IosSDKSocialAuthHelper().PerformSocialAuth(provider, SuccessHandler, CancelHandler, FailHandler); - Debug.Log("IosSocialAuth.SocialNetworkAuth: auth request was sent"); - } - catch (Exception ex) - { - Debug.LogError($"IosSocialAuth.SocialNetworkAuth: {ex.Message}"); - base.OnError?.Invoke(new Error(errorMessage: "Social auth failed")); - } - } - else - { - Debug.LogError("IosSocialAuth.TryAuth: Could not extract argument"); - base.OnError?.Invoke(new Error(errorMessage: "Social auth failed")); - } -#else - Debug.Log("iOS social network auth is not supported for this platform"); -#endif - } - - private bool TryExtractProvider(object[] args, out SocialProvider provider) - { - provider = default(SocialProvider); - - if (args == null) - { - Debug.LogError("IosSocialAuth.TryExtractProvider: 'object[] args' was null"); - return false; - } - - if (args.Length != 1) - { - Debug.LogError($"IosSocialAuth.TryExtractProvider: args.Length expected 1, was {args.Length}"); - return false; - } - - try - { - provider = (SocialProvider) args[0]; - } - catch (Exception ex) - { - Debug.LogError($"IosSocialAuth.TryExtractProvider: Error during argument extraction: {ex.Message}"); - return false; - } - - return true; - } - - private void SuccessHandler(LoginOAuthJsonResponse response) - { - Debug.Log($"IosSocialAuth.SuccessHandler: Token received: {response.access_token}"); - base.OnSuccess?.Invoke(response.access_token); - } - - private void FailHandler(Error error) - { - Debug.Log("IosSocialAuth.SuccessHandler: Social auth failed"); - base.OnError?.Invoke(error); - } - - private void CancelHandler() - { - Debug.Log("IosSocialAuth.SuccessHandler: Social auth cancelled"); - base.OnError?.Invoke(null); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/IosSocialAuth.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/IosSocialAuth.cs.meta deleted file mode 100644 index 1db498193..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/IosSocialAuth.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: d9be5c605f0043319d57738e09a337fb -timeCreated: 1635843493 \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LauncherAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LauncherAuth.cs index 5a14fbf40..d8ff71cbf 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LauncherAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LauncherAuth.cs @@ -1,21 +1,17 @@ +using System; +using System.Linq; +using Xsolla.Auth; +using Xsolla.Core; + namespace Xsolla.Demo { public class LauncherAuth : LoginAuthorization { - public override void TryAuth(params object[] args) + public override void TryAuth(object[] _, Action onSuccess, Action onError) { - string launcherToken = LauncherArguments.Instance.GetToken(); - - if (!string.IsNullOrEmpty(launcherToken)) - { - Debug.Log("LauncherAuth.TryAuth: Token loaded"); - base.OnSuccess?.Invoke(launcherToken); - } - else - { - Debug.Log("LauncherAuth.TryAuth: No token"); - base.OnError?.Invoke(null); - } + XsollaAuth.AuthViaXsollaLauncher( + onSuccess, + error => onError?.Invoke(null)); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LoginAuthorization.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LoginAuthorization.cs index 24377daae..43bffc1e9 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LoginAuthorization.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LoginAuthorization.cs @@ -6,9 +6,6 @@ namespace Xsolla.Demo { public abstract class LoginAuthorization : MonoBehaviour { - public Action OnSuccess { get; set; } - public Action OnError { get; set; } - - public abstract void TryAuth(params object[] args); + public abstract void TryAuth(object[] args, Action onSuccess, Action onError); } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LoginWidgetAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LoginWidgetAuth.cs index 5bbd9b68f..66fe17ac4 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LoginWidgetAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/LoginWidgetAuth.cs @@ -1,3 +1,4 @@ +using System; using Xsolla.Auth; using Xsolla.Core; @@ -5,12 +6,13 @@ namespace Xsolla.Demo { internal class LoginWidgetAuth : LoginAuthorization { - public override void TryAuth(params object[] args) + public override void TryAuth(object[] _, Action onSuccess, Action onError) { - XsollaAuth.Instance.AuthWithXsollaWidget( - onSuccess: token => { base.OnSuccess?.Invoke(token); }); + XsollaAuth.AuthWithXsollaWidget( + onSuccess, + () => onError?.Invoke(null)); - BrowserHelper.Instance.InAppBrowser.UpdateSize(820, 840); + XsollaWebBrowser.InAppBrowser.UpdateSize(820, 840); } } } \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/PasswordlessEmailAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/PasswordlessEmailAuth.cs index 0c48d0237..007f96aba 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/PasswordlessEmailAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/PasswordlessEmailAuth.cs @@ -1,3 +1,5 @@ +using System; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo @@ -5,77 +7,75 @@ namespace Xsolla.Demo public class PasswordlessEmailAuth : LoginAuthorization { private string _currentEmail; - private string _currentOperationID; + private string _currentOperationId; private ICodeRequester _currentRequester; - public override void TryAuth(params object[] args) + public override void TryAuth(object[] args, Action onSuccess, Action onError) { - if (TryExtractArgs(args, out var requester, out var email)) + if (!TryExtractArgs(args, out var requester, out var email)) { - if (IsEmailValid(email)) - { - SdkAuthLogic.Instance.StartAuthByEmail( - email:email, - linkUrl: null, - sendLink:false, - onSuccess: id => OnStartAuth(email, id, requester), - onError: error => OnPasswordlessError(error,requester)); - } - else - OnPasswordlessError(new Error(ErrorType.InvalidData, errorMessage:$"Email not valid '{email}'"), requester); + XDebug.LogError("PasswordlessEmailAuth.TryAuth: Could not extract arguments"); + onError?.Invoke(new Error(errorMessage: "Passwordless auth failed")); + return; } - else + + if (!IsEmailValid(email)) { - Debug.LogError("PasswordlessEmailAuth.TryAuth: Could not extract arguments"); - base.OnError?.Invoke(new Error(errorMessage: "Passwordless auth failed")); + var error = new Error(ErrorType.InvalidData, errorMessage: $"Email not valid '{email}'"); + requester?.RaiseOnError(error); + onError?.Invoke(error); + return; } + + _currentEmail = email; + _currentRequester = requester; + + XsollaAuth.StartAuthByEmail( + email, + data => OnStartAuth(data.operation_id, onSuccess), + error => + { + requester?.RaiseOnError(error); + onError?.Invoke(error); + }); } - private bool TryExtractArgs(object[] args, out ICodeRequester requester, out string email) + private static bool TryExtractArgs(object[] args, out ICodeRequester requester, out string email) { requester = null; email = null; if (args.Length >= 2 && args[0] is ICodeRequester && args[1] is string) { - requester = (ICodeRequester)args[0]; - email = (string)args[1]; + requester = (ICodeRequester) args[0]; + email = (string) args[1]; return true; } - else - { - Debug.LogError("PasswordlessEmailAuth: Could not extract arguments"); - return false; - } - } - private bool IsEmailValid(string email) - { - return (email.Length > 1 && email.Length < 255); + XDebug.LogError("PasswordlessEmailAuth: Could not extract arguments"); + return false; } - private void OnStartAuth(string email, string operationID, ICodeRequester requester) + private static bool IsEmailValid(string email) { - _currentEmail = email; - _currentOperationID = operationID; - _currentRequester = requester; - requester.RequestCode(OnCode); + return email.Length > 1 && email.Length < 255; } - private void OnCode(string code) + private void OnStartAuth(string operationId, Action onSuccess) { - SdkAuthLogic.Instance.CompleteAuthByEmail( - email: _currentEmail, - confirmationCode: code, - operationId: _currentOperationID, - onSuccess: token => base.OnSuccess?.Invoke(token), - onError: OnCodeError); + _currentOperationId = operationId; + _currentRequester.RequestCode(code => OnCodeReceived(code, onSuccess)); } - private void OnPasswordlessError(Error error, ICodeRequester requester) + private void OnCodeReceived(string code, Action onSuccess) { - requester.RaiseOnError(error); - base.OnError?.Invoke(error); + XsollaAuth.CompleteAuthByEmail( + _currentEmail, + code, + _currentOperationId, + onSuccess, + OnCodeError + ); } private void OnCodeError(Error error) @@ -83,4 +83,4 @@ private void OnCodeError(Error error) _currentRequester.RaiseOnError(error); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/PasswordlessPhoneAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/PasswordlessPhoneAuth.cs index c08dc7009..797a9504e 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/PasswordlessPhoneAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/PasswordlessPhoneAuth.cs @@ -1,4 +1,6 @@ -using System.Text.RegularExpressions; +using System; +using System.Text.RegularExpressions; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo @@ -6,83 +8,81 @@ namespace Xsolla.Demo public class PasswordlessPhoneAuth : LoginAuthorization { private string _currentPhone; - private string _currentOperationID; + private string _currentOperationId; private ICodeRequester _currentRequester; - public override void TryAuth(params object[] args) + public override void TryAuth(object[] args, Action onSuccess, Action onError) { - if (TryExtractArgs(args, out var requester, out var phone)) + if (!TryExtractArgs(args, out var requester, out var phone)) { - if (IsPhoneValid(phone)) - { - SdkAuthLogic.Instance.StartAuthByPhoneNumber( - phoneNumber:phone, - linkUrl: null, - sendLink:false, - onSuccess: id => OnStartAuth(phone, id, requester), - onError: error => OnPasswordlessError(error,requester)); - } - else - OnPasswordlessError(new Error(ErrorType.InvalidData, errorMessage:$"Phone not valid '{phone}'"), requester); + XDebug.LogError("PasswordlessPhoneAuth.TryAuth: Could not extract arguments"); + onError?.Invoke(new Error(errorMessage: "Passwordless auth failed")); + return; } - else + + if (!IsPhoneValid(phone)) { - Debug.LogError("PasswordlessPhoneAuth.TryAuth: Could not extract arguments"); - base.OnError?.Invoke(new Error(errorMessage: "Passwordless auth failed")); + var error = new Error(ErrorType.InvalidData, errorMessage: $"Phone not valid '{phone}'"); + requester?.RaiseOnError(error); + onError?.Invoke(error); + return; } + + _currentPhone = phone; + _currentRequester = requester; + + XsollaAuth.StartAuthByPhoneNumber( + phone, + data => OnStartAuth(data.operation_id, onSuccess), + error => + { + requester?.RaiseOnError(error); + onError?.Invoke(error); + }); } - private bool TryExtractArgs(object[] args, out ICodeRequester requester, out string phone) + private static bool TryExtractArgs(object[] args, out ICodeRequester requester, out string phone) { requester = null; phone = null; if (args.Length >= 2 && args[0] is ICodeRequester && args[1] is string) { - requester = (ICodeRequester)args[0]; - phone = (string)args[1]; + requester = (ICodeRequester) args[0]; + phone = (string) args[1]; return true; } - else - { - Debug.LogError("PasswordlessPhoneAuth: Could not extract arguments"); - return false; - } + + XDebug.LogError("PasswordlessPhoneAuth: Could not extract arguments"); + return false; } - private bool IsPhoneValid(string phone) + private static bool IsPhoneValid(string phone) { var regex = new Regex("^\\+(\\d){5,25}$"); var valid = regex.IsMatch(phone); if (!valid) - Debug.LogError($"Phone not valid: '{phone}'"); + XDebug.LogError($"Phone not valid: '{phone}'"); return valid; } - private void OnStartAuth(string phone, string operationID, ICodeRequester requester) - { - _currentPhone = phone; - _currentOperationID = operationID; - _currentRequester = requester; - requester.RequestCode(OnCode); - } - - private void OnCode(string code) + private void OnStartAuth(string operationId, Action onSuccess) { - SdkAuthLogic.Instance.CompleteAuthByPhoneNumber( - phoneNumber: _currentPhone, - confirmationCode: code, - operationId: _currentOperationID, - onSuccess: token => base.OnSuccess?.Invoke(token), - onError: OnCodeError); + _currentOperationId = operationId; + _currentRequester.RequestCode(code => OnCodeReceived(code, onSuccess)); } - private void OnPasswordlessError(Error error, ICodeRequester requester) + private void OnCodeReceived(string code, Action onSuccess) { - requester.RaiseOnError(error); - base.OnError?.Invoke(error); + XsollaAuth.CompleteAuthByPhoneNumber( + _currentPhone, + code, + _currentOperationId, + onSuccess, + OnCodeError + ); } private void OnCodeError(Error error) @@ -90,4 +90,4 @@ private void OnCodeError(Error error) _currentRequester.RaiseOnError(error); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SavedTokenAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SavedTokenAuth.cs index 0c2deec05..3a2ad4191 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SavedTokenAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SavedTokenAuth.cs @@ -1,5 +1,4 @@ -using System.Collections; -using UnityEngine; +using System; using Xsolla.Auth; using Xsolla.Core; @@ -7,40 +6,13 @@ namespace Xsolla.Demo { public class SavedTokenAuth : LoginAuthorization { - public override void TryAuth(params object[] args) + public override void TryAuth(object[] _, Action onSuccess, Action onError) { - if (Token.Load()) - { - Debug.Log("SavedTokenAuth.TryAuth: Token loaded, validating"); - SdkAuthLogic.Instance.ValidateToken( - token: Token.Instance, - onSuccess: _ => base.OnSuccess?.Invoke(Token.Instance), - onError: HandleError); - } + var success = XsollaAuth.AuthViaSavedToken(); + if (success) + onSuccess?.Invoke(); else - { - Debug.Log("SavedTokenAuth.TryAuth: No token"); - base.OnError?.Invoke(null); - } - } - - private void HandleError(Error error) - { - Debug.Log($"SavedTokenAuth.TryAuth: Error occured while validating: {error.ErrorType}"); - - if (error.ErrorType == ErrorType.InvalidToken) - { - Debug.Log($"SavedTokenAuth.TryAuth: Trying to refresh OAuth token"); - SdkAuthLogic.Instance.RefreshOAuthToken( - onSuccess: newToken => base.OnSuccess?.Invoke(newToken), - onError: refreshError => - { - Debug.LogError(error.errorMessage); - base.OnError?.Invoke(null); - }); - } - else - base.OnError?.Invoke(null); + onError?.Invoke(null); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SocialAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SocialAuth.cs index 14fa3977a..3cb49a519 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SocialAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SocialAuth.cs @@ -1,101 +1,53 @@ -using System; -using System.Collections; -using UnityEngine; +using System; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo { public class SocialAuth : LoginAuthorization { - public override void TryAuth(params object[] args) + public override void TryAuth(object[] args, Action onSuccess, Action onError) { - #if UNITY_EDITOR || UNITY_STANDALONE - if (HotkeyCoroutine.IsLocked()) + if (!TryExtractProvider(args, out var socialProvider)) { - base.OnError?.Invoke(null); + onError?.Invoke(new Error(errorMessage: $"{GetType().Name}. Auth failed. Can't extract provider")); return; } - if (TryExtractProvider(args, out SocialProvider provider)) - { - HotkeyCoroutine.Lock(); - - string url = SdkAuthLogic.Instance.GetSocialNetworkAuthUrl(provider); - Debug.Log($"Social url: {url}"); - - var browser = BrowserHelper.Instance.InAppBrowser; - browser.Open(url); - browser.AddCloseHandler(BrowserCloseHandler); - browser.AddUrlChangeHandler(UrlChangedHandler); - } - else - { - Debug.LogError("SocialAuth.TryAuth: Could not extract argument"); - base.OnError?.Invoke(new Error(errorMessage: "Social auth failed")); - } - #endif + XsollaAuth.AuthViaSocialNetwork( + socialProvider, + onSuccess, + onError, + () => onError?.Invoke(null)); } - private bool TryExtractProvider(object[] args, out SocialProvider provider) + private static bool TryExtractProvider(object[] args, out SocialProvider provider) { - provider = default(SocialProvider); + provider = default; if (args == null) { - Debug.LogError("SocialAuth.TryExtractProvider: 'object[] args' was null"); + XDebug.LogError("AndroidSocialAuth.TryExtractProvider: 'object[] args' was null"); return false; } if (args.Length != 1) { - Debug.LogError($"SocialAuth.TryExtractProvider: args.Length expected 1, was {args.Length}"); + XDebug.LogError($"AndroidSocialAuth.TryExtractProvider: args.Length expected 1, was {args.Length}"); return false; } try { - provider = (SocialProvider)args[0]; + provider = (SocialProvider) args[0]; } catch (Exception ex) { - Debug.LogError($"SocialAuth.TryExtractProvider: Error during argument extraction: {ex.Message}"); + XDebug.LogError($"AndroidSocialAuth.TryExtractProvider: Error during argument extraction: {ex.Message}"); return false; } return true; } - - - private void BrowserCloseHandler() - { - HotkeyCoroutine.Unlock(); - base.OnError?.Invoke(null); - } - - private void UrlChangedHandler(string newUrl) - { - if (ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.code, out var code)) - { - Debug.Log($"We take{Environment.NewLine}from URL:{newUrl}{Environment.NewLine}code = {code}"); - SdkAuthLogic.Instance.ExchangeCodeToToken( - code, - onSuccessExchange: socialToken => StartCoroutine(SuccessAuthCoroutine(socialToken)), - onError: error => { Debug.LogError(error.errorMessage); base.OnError?.Invoke(error); } - ); - } - } - - private IEnumerator SuccessAuthCoroutine(string token) - { - yield return new WaitForEndOfFrame(); - - if (EnvironmentDefiner.IsStandaloneOrEditor) - { - BrowserHelper.Instance.Close(); - HotkeyCoroutine.Unlock(); - } - - base.OnSuccess?.Invoke(token); - } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SocialAuth.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SocialAuth.cs.meta index 248c51c91..b4eb39a8c 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SocialAuth.cs.meta +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SocialAuth.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 5d4e58a5c404d4f4da5c6716d60a2a03 +guid: 5c6bba1da82e0204f8b25a153b370443 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SteamAuth.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SteamAuth.cs index 3d12486f4..a352237be 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SteamAuth.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/Auth/SteamAuth.cs @@ -1,55 +1,43 @@ -using Xsolla.Core; +using System; +using Xsolla.Auth; +using Xsolla.Core; namespace Xsolla.Demo { public class SteamAuth : LoginAuthorization { - private string _steamSessionTicket = default; - - public override void TryAuth(params object[] args) + public override void TryAuth(object[] args, Action onSuccess, Action onError) { +#if !(UNITY_EDITOR || UNITY_STANDALONE) + onError?.Invoke(null); +#else if (!DemoSettings.UseSteamAuth) { - Debug.Log("SteamAuth.TryAuth: Steam auth disabled"); - base.OnError?.Invoke(null); - } - else - { - Debug.Log("SteamAuth.TryAuth: Steam auth enabled, trying to get token"); - - #if UNITY_STANDALONE || UNITY_EDITOR - _steamSessionTicket = new SteamSessionTicket().ToString(); - #endif - if (!string.IsNullOrEmpty(_steamSessionTicket)) - RequestTokenBy(_steamSessionTicket); - else - base.OnError?.Invoke(new Error(errorMessage: "Steam auth failed")); + onError?.Invoke(null); + return; } - } - private void RequestTokenBy(string ticket) - { - if (int.TryParse(DemoSettings.SteamAppId, out _)) + var appId = DemoSettings.SteamAppId; + if (!int.TryParse(appId, out _)) { - SdkAuthLogic.Instance.SilentAuth("steam", DemoSettings.SteamAppId, ticket, onSuccess:SuccessHandler, onError:FailHandler); + onError?.Invoke(new Error(errorMessage: "Steam auth failed. Can't parse SteamAppId")); + return; } - else + + var sessionTicket = SteamUtils.GetSteamSessionTicket(); + if (string.IsNullOrEmpty(sessionTicket)) { - Debug.LogError($"Can't parse SteamAppId = {DemoSettings.SteamAppId}"); - base.OnError?.Invoke(new Error(errorMessage: "Steam auth failed")); + onError?.Invoke(new Error(errorMessage: "Steam auth failed. Can't get session ticket")); + return; } - } - - private void SuccessHandler(string token) - { - Debug.Log("SteamAuth.SuccessHandler: Token loaded"); - base.OnSuccess?.Invoke(token); - } - private void FailHandler(Error error) - { - Debug.LogError($"Token request by steam session ticket failed. Ticket: {_steamSessionTicket} Error: {error.ToString()}"); - base.OnError?.Invoke(error); + XsollaAuth.SilentAuth( + "steam", + appId, + sessionTicket, + onSuccess, + onError); +#endif } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/DemoUserLoginResponse.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/DemoUserLoginResponse.cs new file mode 100644 index 000000000..ddb446f6c --- /dev/null +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/DemoUserLoginResponse.cs @@ -0,0 +1,11 @@ +using System; + +namespace Xsolla.Demo +{ + [Serializable] + public class DemoUserLoginResponse + { + public string access_token; + public string refresh_token; + } +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/DemoUserLoginResponse.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Login/DemoUserLoginResponse.cs.meta new file mode 100644 index 000000000..1b2160980 --- /dev/null +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/DemoUserLoginResponse.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 7ea8b31c345a43d09a24ba0ec31bafd7 +timeCreated: 1683275715 \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageChangePasswordController.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageChangePasswordController.cs index a415bd630..ff210c939 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageChangePasswordController.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageChangePasswordController.cs @@ -2,6 +2,7 @@ using Xsolla.Core; using UnityEngine; using UnityEngine.UI; +using Xsolla.Auth; namespace Xsolla.Demo { @@ -18,9 +19,9 @@ private bool IsPasswordChangeInProgress set { if (value) - Debug.Log("LoginPageChangePasswordController: Password reset started"); + XDebug.Log("LoginPageChangePasswordController: Password reset started"); else - Debug.Log("LoginPageChangePasswordController: Password reset ended"); + XDebug.Log("LoginPageChangePasswordController: Password reset ended"); base.IsInProgress = value; } @@ -48,18 +49,18 @@ public void RunPasswordChange(string email) Action onSuccessfulPasswordChange = () => { - Debug.Log("LoginPageChangePasswordController: Password change success"); - base.OnSuccess?.Invoke(); + XDebug.Log("LoginPageChangePasswordController: Password change success"); + OnSuccess?.Invoke(); }; Action onFailedPasswordChange = error => { - Debug.LogError($"LoginPageChangePasswordController: Password change error: {error.ToString()}"); - base.OnError?.Invoke(error); + XDebug.LogError($"LoginPageChangePasswordController: Password change error: {error.ToString()}"); + OnError?.Invoke(error); }; - SdkAuthLogic.Instance.ResetPassword(email, onSuccessfulPasswordChange, onFailedPasswordChange); + XsollaAuth.ResetPassword(email, onSuccessfulPasswordChange, onFailedPasswordChange); IsPasswordChangeInProgress = false; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageCreateController.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageCreateController.cs index d527726b0..2f97d3ffd 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageCreateController.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageCreateController.cs @@ -1,6 +1,7 @@ using System; using UnityEngine; using UnityEngine.UI; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo @@ -27,9 +28,9 @@ private bool IsCreateInProgress set { if (value) - Debug.Log("LoginPageCreateController: Create started"); + XDebug.Log("LoginPageCreateController: Create started"); else - Debug.Log("LoginPageCreateController: Create ended"); + XDebug.Log("LoginPageCreateController: Create ended"); base.IsInProgress = value; } @@ -70,38 +71,45 @@ public void RunCreate(string username, string email, string password) if (isFieldsFilled && isEmailValid) { - Action onSuccessfulCreate = webRequestResponseCode => + Action onSuccessfulCreate = loginLink => { - Debug.Log("LoginPageCreateController: Create success"); - - if (webRequestResponseCode == 200) + XDebug.Log("LoginPageCreateController: Create success"); + + if (loginLink.login_url != null) { FindObjectOfType().SetState(MenuState.Authorization); FindObjectOfType().RunBasicAuth(username, password, true); } else { - base.OnSuccess?.Invoke(); + OnSuccess?.Invoke(); } }; Action onFailedCreate = error => { - Debug.LogError($"LoginPageCreateController: Create error: {error}"); - base.OnError?.Invoke(error); + XDebug.LogError($"LoginPageCreateController: Create error: {error}"); + OnError?.Invoke(error); }; - SdkAuthLogic.Instance.Register(username, password, email, onSuccess:onSuccessfulCreate, onError:onFailedCreate); + XsollaAuth.Register( + username, + password, + email, + onSuccessfulCreate, + onFailedCreate, + acceptConsent: true, + promoEmailAgreement: true); } else if (!isEmailValid) { - Debug.Log($"Invalid email: {email}"); + XDebug.Log($"Invalid email: {email}"); Error error = new Error(errorType: ErrorType.RegistrationNotAllowedException, errorMessage: "Invalid email"); - base.OnError?.Invoke(error); + OnError?.Invoke(error); } else { - Debug.LogError($"Fields are not filled. Username: '{username}' Password: '{password}'"); + XDebug.LogError($"Fields are not filled. Username: '{username}' Password: '{password}'"); Error error = new Error(errorType: ErrorType.RegistrationNotAllowedException, errorMessage: $"Not all fields are filled"); base.OnError?.Invoke(error); } @@ -109,4 +117,4 @@ public void RunCreate(string username, string email, string password) IsCreateInProgress = false; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.AutomaticAuths.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.AutomaticAuths.cs index 4e1c976a1..413440d77 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.AutomaticAuths.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.AutomaticAuths.cs @@ -1,13 +1,13 @@ using System; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { - public partial class LoginPageEnterController : LoginPageController + public partial class LoginPageEnterController { private static bool _isFirstLaunch = true; - private int _autoAuthState = 0; + private int _autoAuthCounter; private void Start() { @@ -20,13 +20,13 @@ private void Start() } else { - Token.DeleteSave(); + XsollaToken.DeleteSavedInstance(); } } private void RunAutomaticAuths() { - Action onFailedAutomaticAuth = error => + Action handleErrorOrSkip = error => { if (error != null) { @@ -34,27 +34,24 @@ private void RunAutomaticAuths() } else { - _autoAuthState++; + _autoAuthCounter++; RunAutomaticAuths(); } }; - Action onSuccessfulAutomaticAuth = token => - SdkAuthLogic.Instance.ValidateToken(token, onSuccess: validToken => CompleteSuccessfulAuth(validToken), onError: _ => onFailedAutomaticAuth.Invoke(null)); - - switch (_autoAuthState) + switch (_autoAuthCounter) { case 0: - TryAuthBy(args: null, onSuccess: validToken => CompleteSuccessfulAuth(validToken), onFailed: onFailedAutomaticAuth); + TryAuthBy(null, SuperComplete, handleErrorOrSkip); break; case 1: - TryAuthBy(args: null, onSuccess: onSuccessfulAutomaticAuth, onFailed: onFailedAutomaticAuth); + TryAuthBy(null, SuperComplete, handleErrorOrSkip); break; case 2: - TryAuthBy(args: null, onSuccess: onSuccessfulAutomaticAuth, onFailed: onFailedAutomaticAuth); + TryAuthBy(null, SuperComplete, handleErrorOrSkip); break; case 3: - TryAuthBy(args: null, onSuccess: onSuccessfulAutomaticAuth, onFailed: onFailedAutomaticAuth); + TryAuthBy(null, SuperComplete, handleErrorOrSkip); break; default: IsAuthInProgress = false; @@ -62,4 +59,4 @@ private void RunAutomaticAuths() } } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.ButtonAuths.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.ButtonAuths.cs index 702fe60fc..960b02f9a 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.ButtonAuths.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.ButtonAuths.cs @@ -1,30 +1,29 @@ using System; using UnityEngine; using UnityEngine.UI; -using Xsolla.Auth; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { - public partial class LoginPageEnterController : LoginPageController + public partial class LoginPageEnterController { - [SerializeField] InputField EmailInputField = default; - [SerializeField] InputField PasswordInputField = default; - [SerializeField] Toggle RememberMeCheckbox = default; - [SerializeField] SimpleButton LoginButton = default; + [SerializeField] private InputField EmailInputField; + [SerializeField] private InputField PasswordInputField; + [SerializeField] private Toggle RememberMeCheckbox; + [SerializeField] private SimpleButton LoginButton; [Space] - [SerializeField] private SimpleSocialButton[] MainSocialLoginButtons = default; - [SerializeField] private SimpleButton OtherSocialNetworksButton = default; - [SerializeField] private SocialNetworksWidget SocialNetworksWidget = default; + [SerializeField] private SimpleSocialButton[] MainSocialLoginButtons; + [SerializeField] private SimpleButton OtherSocialNetworksButton; + [SerializeField] private SocialNetworksWidget SocialNetworksWidget; [Space] - [SerializeField] private SimpleButton PasswordlessButton = default; - [SerializeField] private PasswordlessWidget PasswordlessWidget = default; + [SerializeField] private SimpleButton PasswordlessButton; + [SerializeField] private PasswordlessWidget PasswordlessWidget; [Space] - [SerializeField] SimpleButton DeviceIDAuthButton = default; + [SerializeField] private SimpleButton DeviceIDAuthButton; private void Awake() { @@ -36,8 +35,8 @@ private void Awake() if (PasswordlessWidget) { PasswordlessButton.onClick += () => PasswordlessWidget.gameObject.SetActive(true); - PasswordlessWidget.OnPhoneAccessRequest += phone => RunPasswordlessAuth(phone); - PasswordlessWidget.OnEmailAccessRequest += email => RunPasswordlessAuth(email); + PasswordlessWidget.OnPhoneAccessRequest += RunPasswordlessAuth; + PasswordlessWidget.OnEmailAccessRequest += RunPasswordlessAuth; } foreach (var button in MainSocialLoginButtons) @@ -57,30 +56,17 @@ public void RunBasicAuth(string username, string password, bool rememberMe) IsAuthInProgress = true; PopupFactory.Instance.CreateWaiting().SetCloseCondition(() => IsAuthInProgress == false); - object[] args = {username, password, rememberMe}; - - Action onSuccessfulBasicAuth = token => - { - SdkAuthLogic.Instance.ValidateToken( - token, - t => CompleteSuccessfulAuth(token, true, isSaveToken: rememberMe), - ProcessError); + object[] args = { + username, + password }; - TryAuthBy(args, onSuccessfulBasicAuth, ProcessError); + TryAuthBy(args, SuperComplete, ProcessError); } public void RunWidgetAuth() { - Action onSuccessfulWidgetAuth = token => - { - SdkAuthLogic.Instance.ValidateToken( - token: token, - onSuccess: t => CompleteSuccessfulAuth(token, isSaveToken: true), - onError: ProcessError); - }; - - TryAuthBy(null, onSuccessfulWidgetAuth, ProcessError); + TryAuthBy(null, SuperComplete, ProcessError); } public void RunSocialAuth(SocialProvider socialProvider) @@ -89,19 +75,9 @@ public void RunSocialAuth(SocialProvider socialProvider) return; IsAuthInProgress = true; - object[] args = { socialProvider }; - - Action onSuccessfulSocialAuth = token => SdkAuthLogic.Instance - .ValidateToken(token, t => CompleteSuccessfulAuth(token, isSaveToken: true), ProcessError); - Action onFailedSocialAuth = ProcessError; - - #if UNITY_EDITOR || UNITY_STANDALONE - TryAuthBy(args, onSuccessfulSocialAuth, onFailedSocialAuth); - #elif UNITY_ANDROID - TryAuthBy(args, onSuccessfulSocialAuth, onFailedSocialAuth); - #elif UNITY_IOS - TryAuthBy(args, onSuccessfulSocialAuth, onFailedSocialAuth); - #endif + object[] args = {socialProvider}; + + TryAuthBy(args, SuperComplete, ProcessError); } public void RunManualSteamAuth() @@ -112,14 +88,10 @@ public void RunManualSteamAuth() IsAuthInProgress = true; PopupFactory.Instance.CreateWaiting().SetCloseCondition(() => IsAuthInProgress == false); - Action onSuccessfulSteamAuth = token => SdkAuthLogic.Instance - .ValidateToken(token, t => CompleteSuccessfulAuth(token, isSaveToken: true), ProcessError); - Action onFailedSteamAuth = ProcessError; - - TryAuthBy(args: null, onSuccess: onSuccessfulSteamAuth, onFailed: onFailedSteamAuth); + TryAuthBy(null, SuperComplete, ProcessError); } - public void RunDeviceIDAuth() + private void RunDeviceIDAuth() { if (IsAuthInProgress) return; @@ -127,47 +99,42 @@ public void RunDeviceIDAuth() IsAuthInProgress = true; PopupFactory.Instance.CreateWaiting().SetCloseCondition(() => IsAuthInProgress == false); - Action onSuccessfulDeviecIDAuth = token => SdkAuthLogic.Instance - .ValidateToken(token, t => CompleteSuccessfulAuth(token, isSaveToken: true), ProcessError); - Action onFailedDeviecIDAuth = ProcessError; - - TryAuthBy(args: null, onSuccess: onSuccessfulDeviecIDAuth, onFailed: onFailedDeviecIDAuth); + TryAuthBy(null, SuperComplete, ProcessError); } - public void RunPasswordlessAuth(string value) where T : LoginAuthorization + private void RunPasswordlessAuth(string value) where T : LoginAuthorization { + var args = new object[] { + PasswordlessWidget, + value + }; + var passwordlessAuth = GetComponent(); if (passwordlessAuth != null) { - passwordlessAuth.TryAuth(PasswordlessWidget, value); + passwordlessAuth.TryAuth(args, SuperComplete, ProcessError); return; } - Action onSuccessfulPasswordlessAuth = token => SdkAuthLogic.Instance - .ValidateToken(token, t => CompleteSuccessfulAuth(token, isSaveToken: true), ProcessError); - Action onFailedPasswordlessAuth = ProcessError; - - TryAuthBy(args: new object[] { PasswordlessWidget, value }, onSuccess: onSuccessfulPasswordlessAuth, onFailed: onFailedPasswordlessAuth); + TryAuthBy(args, SuperComplete, ProcessError); } public void RunDemoUserAuth() { - if(IsAuthInProgress) + if (IsAuthInProgress) return; - + IsAuthInProgress = true; PopupFactory.Instance.CreateWaiting().SetCloseCondition(() => IsAuthInProgress == false); - Debug.LogWarning("!PLEASE WAIT! Process of creating new demo user can take up to 30 seconds"); - - Action onDemoUserSuccess = response => + XDebug.LogWarning("!PLEASE WAIT! Process of creating new demo user can take up to 30 seconds"); + + Action onDemoUserSuccess = response => { - Token.Instance = Token.Create(response.access_token); - PlayerPrefs.SetString(Constants.LAST_SUCCESS_AUTH_TOKEN, response.access_token); - TokenRefresh.Instance.RefreshToken = response.refresh_token; - SdkAuthLogic.Instance.ValidateToken(response.access_token, t => CompleteSuccessfulAuth(t, isSaveToken: true), ProcessError); + XsollaToken.Create(response.access_token, response.refresh_token); + SuperComplete(); }; - - WebRequestHelper.Instance.GetRequest( + + WebRequestHelper.Instance.GetRequest( sdkType: SdkType.Login, url: "https://us-central1-xsolla-sdk-demo.cloudfunctions.net/generateDemoUserToken", onComplete: onDemoUserSuccess, @@ -179,11 +146,11 @@ private void DisableCommonButtons() var buttonsProvider = GetComponent(); if (buttonsProvider != null) { - if(buttonsProvider.DemoUserButton != null) + if (buttonsProvider.DemoUserButton != null) buttonsProvider.DemoUserButton.gameObject.SetActive(false); - if(buttonsProvider.LogInButton != null) + if (buttonsProvider.LogInButton != null) buttonsProvider.LogInButton.gameObject.SetActive(false); } } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.cs index bab65924d..76d00d5c3 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageEnterController.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo @@ -7,60 +8,85 @@ namespace Xsolla.Demo public partial class LoginPageEnterController : LoginPageController { public static string LastUsername { get; set; } - + public bool IsAuthInProgress { - get => base.IsInProgress; + get => IsInProgress; + private set + { + XDebug.Log(value + ? "LoginPageEnterController: Authentication process started" + : "LoginPageEnterController: Authentication process ended"); + + IsInProgress = value; + } + } + + private void TryAuthBy(object[] args, Action onSuccess, Action onError) where T : LoginAuthorization + { + var auth = gameObject.AddComponent(); + XDebug.Log($"Trying auth via: {auth.GetType().Name}"); - set + void handleSuccess() { - if (value) - Debug.Log("LoginPageEnterController: Authentication process started"); - else - Debug.Log("LoginPageEnterController: Authentication process ended"); + Destroy(auth); + onSuccess?.Invoke(); + } - base.IsInProgress = value; + void handleError(Error error) + { + Destroy(auth); + onError?.Invoke(error); } + + auth.TryAuth(args, handleSuccess, handleError); } - private void TryAuthBy(object[] args, Action onSuccess = null, Action onFailed = null) where T : LoginAuthorization + private void SuperComplete() { - T auth = base.gameObject.AddComponent(); - Debug.Log($"Trying {auth.GetType().Name}"); - auth.OnSuccess = token => { Destroy(auth); onSuccess?.Invoke(token); }; - auth.OnError = error => { Destroy(auth); onFailed?.Invoke(error); }; - auth.TryAuth(args); + ValidateToken( + () => + { + XDebug.Log($"Successful auth with access token = {XsollaToken.AccessToken}"); + MainMenuNicknameChecker.ResetFlag(); + IsAuthInProgress = false; + OnSuccess?.Invoke(); + }, + ProcessError); } - - private void CompleteSuccessfulAuth(string encodedToken, bool isBasicAuth = false, bool isSaveToken = false) + + private static void ValidateToken(Action onSuccess, Action onError) { - if (!isBasicAuth) + void handleError(Error error) { - encodedToken = encodedToken.Split('&').First(); - Token.Instance = Token.Create(encodedToken); + if (error.ErrorType == ErrorType.InvalidToken) + { + XDebug.Log("SavedTokenAuth: Trying to refresh OAuth token"); + XsollaAuth.RefreshToken( + onSuccess, + refreshError => + { + XDebug.LogError(error.errorMessage); + onError?.Invoke(null); + }); + } + else + { + onError?.Invoke(null); + } } - if(isSaveToken) - Token.Save(); - - Debug.Log($"Successful auth with token = {encodedToken}"); - MainMenuNicknameChecker.ResetFlag(); - IsAuthInProgress = false; - base.OnSuccess?.Invoke(); + XsollaAuth.GetUserInfo(_ => { onSuccess?.Invoke(); }, handleError); } private void ProcessError(Error error) { IsAuthInProgress = false; - if (error == null) - { - //Do nothing, it means that chosen auth was not completed, but ended without any errors (example: cancelled SocialAuth) - } - else - { - base.OnError?.Invoke(error); - } + if (error != null) + OnError?.Invoke(error); + + //Do nothing, it means that chosen auth was not completed, but ended without any errors (example: cancelled SocialAuth) } public void RunLoginProxyAction(Action action, object arg = null) @@ -68,4 +94,4 @@ public void RunLoginProxyAction(Action action, action.Invoke(this, arg); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageErrorShower.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageErrorShower.cs index f91ec9c60..f2a99d9b4 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageErrorShower.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/LoginPageErrorShower.cs @@ -1,19 +1,20 @@ using UnityEngine; using UnityEngine.UI; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo { public class LoginPageErrorShower : MonoBehaviour { - [SerializeField] Text ErrorText = default; - [SerializeField] private SimpleTextButton ResendEmailButton = default; + [SerializeField] private Text ErrorText; + [SerializeField] private SimpleTextButton ResendEmailButton; private void Awake() { if (ResendEmailButton) { - ResendEmailButton.onClick += () => SdkAuthLogic.Instance.ResendConfirmationLink(LoginPageEnterController.LastUsername); + ResendEmailButton.onClick += () => XsollaAuth.ResendConfirmationLink(LoginPageEnterController.LastUsername, null, null); ResendEmailButton.gameObject.SetActive(false); } } @@ -48,4 +49,4 @@ public void ShowError(Error error) ShowError(error.ErrorType.ToString()); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/PasswordlessWidget.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/PasswordlessWidget.cs index 336d136ee..fe9d4fb43 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/PasswordlessWidget.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/PasswordlessWidget.cs @@ -102,7 +102,7 @@ private bool IsPhoneValid(string phone) private void OnPhoneRequest() { var phone = PhoneConverter.ConvertBack(PhoneInputField.text); - Debug.Log($"PasswordlessWidget: phone is '{phone}'"); + XDebug.Log($"PasswordlessWidget: phone is '{phone}'"); _currentAuthType = AuthType.Phone; OnPhoneAccessRequest?.Invoke(phone); } @@ -124,7 +124,7 @@ private void OnEmailInput(string text) private void OnEmailRequest() { var email = EmailInputField.text; - Debug.Log($"PasswordlessWidget: email is '{email}'"); + XDebug.Log($"PasswordlessWidget: email is '{email}'"); _currentAuthType = AuthType.Email; OnEmailAccessRequest?.Invoke(email); } @@ -148,7 +148,7 @@ private void OnResendButton() OnEmailRequest(); break; default: - Debug.LogError($"PasswordlessWidget.OnResendButton: Unexpected auth type '{_currentAuthType}'"); + XDebug.LogError($"PasswordlessWidget.OnResendButton: Unexpected auth type '{_currentAuthType}'"); break; } diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/SocialNetworksWidget.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/SocialNetworksWidget.cs index 1b61e9796..966e0ff71 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/SocialNetworksWidget.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/SocialNetworksWidget.cs @@ -40,7 +40,7 @@ private void OnFilterChanged(string filterText) foreach (var button in SocialNetworkButtons) { - button.gameObject.SetActive(button.SocialProvider.GetParameter().StartsWith(filterText)); + button.gameObject.SetActive(button.SocialProvider.ToString().ToLowerInvariant().StartsWith(filterText)); } } } diff --git a/Assets/Xsolla.Demo/Login/Scripts/Login/UI/PasswordFieldToggler.cs b/Assets/Xsolla.Demo/Login/Scripts/Login/UI/PasswordFieldToggler.cs index dc88cd0f1..17cdab296 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Login/UI/PasswordFieldToggler.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Login/UI/PasswordFieldToggler.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEngine.UI; +using Xsolla.Core; namespace Xsolla.Demo { @@ -18,7 +19,7 @@ void Start() if (_showPasswordToggle != null) _showPasswordToggle.onValueChanged.AddListener(ToggleShowPassword); else - Debug.LogError("Show password toggle is missing"); + XDebug.LogError("Show password toggle is missing"); } void ToggleShowPassword(bool show) diff --git a/Assets/Xsolla.Demo/Login/Scripts/PageControllers/FriendsMenuController.cs b/Assets/Xsolla.Demo/Login/Scripts/PageControllers/FriendsMenuController.cs index 13ab07d4b..25d38cab4 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/PageControllers/FriendsMenuController.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/PageControllers/FriendsMenuController.cs @@ -2,6 +2,7 @@ using System.Linq; using UnityEngine; using UnityEngine.UI; +using Xsolla.Core; using Xsolla.UIBuilder; namespace Xsolla.Demo @@ -136,7 +137,7 @@ private void EnableEmptyGroupMessage(string groupID) emptySubMessage = "All blocked players appear here"; break; default: - Debug.LogError($"Unknown groupID: {groupID}"); + XDebug.LogError($"Unknown groupID: {groupID}"); return; } diff --git a/Assets/Xsolla.Demo/Login/Scripts/PageControllers/SocialFriendsMenuController.cs b/Assets/Xsolla.Demo/Login/Scripts/PageControllers/SocialFriendsMenuController.cs index b5c69d85c..76b73c662 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/PageControllers/SocialFriendsMenuController.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/PageControllers/SocialFriendsMenuController.cs @@ -29,7 +29,7 @@ private void NetworkOnStateChanged(SocialProvider socialProvider, FriendSystemSo switch (state) { case FriendSystemSocialNetwork.State.Linked: - SdkFriendsLogic.Instance.GetFriendsFromSocialNetworks( + FriendsLogic.Instance.GetFriendsFromSocialNetworks( onSuccess: newFriends => { _socialFriends[socialProvider] = newFriends; @@ -91,7 +91,7 @@ private void RefreshSocialNetworks() network.RefreshState(); }; - SdkUserAccountLogic.Instance.PurgeSocialProvidersCache(); + UserAccountLogic.Instance.PurgeSocialProvidersCache(); UserFriends.Instance.UpdateFriends(onFriendsUpdate, StoreDemoPopup.ShowError); } } diff --git a/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/INicknamePopup.cs b/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/INicknamePopup.cs index fcce8fac8..6cb982126 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/INicknamePopup.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/INicknamePopup.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface INicknamePopup { diff --git a/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/NicknamePopup.cs b/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/NicknamePopup.cs index d6890c1f3..a48d80f3a 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/NicknamePopup.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/NicknamePopup.cs @@ -2,7 +2,7 @@ using UnityEngine; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { [AddComponentMenu("Scripts/Xsolla.Core/Popup/NicknamePopup")] public class NicknamePopup : MonoBehaviour, INicknamePopup diff --git a/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/PopupFactory.Login.cs b/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/PopupFactory.Login.cs index 9aae4feb1..4abc08de6 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/PopupFactory.Login.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/PopupFactory/PopupFactory.Login.cs @@ -1,4 +1,4 @@ -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public partial class PopupFactory : MonoSingleton { diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Attributes/UserAttributes.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Attributes/UserAttributes.cs index a1afde7e3..63077dc93 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Attributes/UserAttributes.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Attributes/UserAttributes.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.Text.RegularExpressions; +using UnityEngine; using Xsolla.Core; using Xsolla.UserAccount; namespace Xsolla.Demo { - public class UserAttributes : MonoSingleton + public class UserAttributes : MonoSingleton { private List _readOnlyAttributes; private List _customAttributesOriginal; @@ -26,7 +27,7 @@ public int ChangesCount { if (_modifiedAttributes == null || _removedAttributes == null) { - Debug.LogError($"UserAttributes: Get or update attributes before use"); + XDebug.LogError($"UserAttributes: Get or update attributes before use"); return -1; } @@ -43,9 +44,9 @@ public void UpdateAttributes(Action onSuccess = null, Action onError = nu { _isUpdateInProgress = true; - List attributeKeys = null;//Get all existing attributes without filter - string userId = null;//Get current user attributes - string token = Token.Instance; + List attributeKeys = null; //Get all existing attributes without filter + string userId = null; //Get current user attributes + string token = XsollaToken.AccessToken; string projectId = XsollaSettings.StoreProjectId; void FinalizeUpdate(List readOnlyAttributes, List customAttributes, Error error) @@ -82,18 +83,24 @@ void FinalizeUpdate(List readOnlyAttributes, List _isUpdateInProgress = false; } - Action onErrorGet = error => - { - FinalizeUpdate(null, null, error); - }; + Action onErrorGet = error => { FinalizeUpdate(null, null, error); }; - Action> onSuccessGetReadonly = readOnlyAttributes => + Action onSuccessGetReadonly = readOnlyAttributes => { - Action> onSuccessGetCustom = customAttributes => FinalizeUpdate(readOnlyAttributes, customAttributes, error: null); - SdkUserAccountLogic.Instance.GetUserAttributes(token, projectId, UserAttributeType.CUSTOM, attributeKeys, userId, onSuccessGetCustom, onErrorGet); + Action onSuccessGetCustom = customAttributes => FinalizeUpdate(readOnlyAttributes.items, customAttributes.items, error: null); + + XsollaUserAccount.GetUserAttributes(UserAttributeType.CUSTOM, + attributeKeys, + userId, + onSuccessGetCustom, + onErrorGet); }; - SdkUserAccountLogic.Instance.GetUserAttributes(token, projectId, UserAttributeType.READONLY, attributeKeys, userId, onSuccessGetReadonly, onErrorGet); + XsollaUserAccount.GetUserAttributes(UserAttributeType.READONLY, + attributeKeys, + userId, + onSuccessGetReadonly, + onErrorGet); } /// @@ -109,7 +116,7 @@ public void GetReadonlyAttributes(Action> onSuccess, Action< return; } - _updateQueue.Enqueue(new UpdateQueueItem() {OnGetReadonly=onSuccess, OnError=onError}); + _updateQueue.Enqueue(new UpdateQueueItem() {OnGetReadonly = onSuccess, OnError = onError}); if (!_isUpdateInProgress) UpdateAttributes(); @@ -128,7 +135,7 @@ public void GetCustomAttributes(Action> onSuccess, Action 256 || !Regex.IsMatch(newKey, "^[A-Za-z0-9_]+$")) { - Debug.LogError($"UserAttributes.ChangeKey: New key does not follow rules MaxLength:256 Pattern:[A-Za-z0-9_]+. OldKey:{oldKey} NewKey:{newKey}"); + XDebug.LogError($"UserAttributes.ChangeKey: New key does not follow rules MaxLength:256 Pattern:[A-Za-z0-9_]+. OldKey:{oldKey} NewKey:{newKey}"); error = AttributesError.IncorrectKey; return false; } if (!IsNewKey(newKey)) { - Debug.LogError($"UserAttributes.ChangeKey: This key already exists. OldKey:{oldKey} NewKey:{newKey}"); + XDebug.LogError($"UserAttributes.ChangeKey: This key already exists. OldKey:{oldKey} NewKey:{newKey}"); error = AttributesError.IncorrectKey; return false; } @@ -191,14 +198,14 @@ public bool ChangeValue(string key, string newValue, out AttributesError error) if (string.IsNullOrEmpty(newValue)) { - Debug.LogError($"UserAttributes.ChangeValue: Value can not be null or empty"); + XDebug.LogError($"UserAttributes.ChangeValue: Value can not be null or empty"); error = AttributesError.IncorrectValue; return false; } if (newValue.Length > 256) { - Debug.LogError($"UserAttributes.ChangeValue: New value does not follow rule MaxLength:256 Key:{key} NewValue:{newValue}"); + XDebug.LogError($"UserAttributes.ChangeValue: New value does not follow rule MaxLength:256 Key:{key} NewValue:{newValue}"); error = AttributesError.IncorrectValue; return false; } @@ -243,42 +250,42 @@ public UserAttribute AddNewAttribute(string newKey, string newValue, out Attribu { if (_customAttributes == null) { - Debug.LogError($"UserAttributes: Get or update attributes before use"); + XDebug.LogError($"UserAttributes: Get or update attributes before use"); error = AttributesError.NotInitialized; return null; } if (string.IsNullOrEmpty(newKey)) { - Debug.LogError($"UserAttributes.AddNewAttribute: Key can not be null or empty"); + XDebug.LogError($"UserAttributes.AddNewAttribute: Key can not be null or empty"); error = AttributesError.IncorrectKey; return null; } if (newKey.Length > 256 || !Regex.IsMatch(newKey, "^[A-Za-z0-9_]+$")) { - Debug.LogError($"UserAttributes.AddNewAttribute: New key does not follow rules MaxLength:256 Pattern:[A-Za-z0-9_]+. NewKey:{newKey}"); + XDebug.LogError($"UserAttributes.AddNewAttribute: New key does not follow rules MaxLength:256 Pattern:[A-Za-z0-9_]+. NewKey:{newKey}"); error = AttributesError.IncorrectKey; return null; } if (string.IsNullOrEmpty(newValue)) { - Debug.LogError($"UserAttributes.AddNewAttribute: Value can not be null or empty"); + XDebug.LogError($"UserAttributes.AddNewAttribute: Value can not be null or empty"); error = AttributesError.IncorrectValue; return null; } if (newValue.Length > 256) { - Debug.LogError($"UserAttributes.AddNewAttribute: New value does not follow rule MaxLength:256 Key:{newKey} NewValue:{newValue}"); + XDebug.LogError($"UserAttributes.AddNewAttribute: New value does not follow rule MaxLength:256 Key:{newKey} NewValue:{newValue}"); error = AttributesError.IncorrectValue; return null; } if (!IsNewKey(newKey)) { - Debug.LogError($"UserAttributes.AddNewAttribute: This key already exists. NewKey:{newKey} NewValue:{newValue}"); + XDebug.LogError($"UserAttributes.AddNewAttribute: This key already exists. NewKey:{newKey} NewValue:{newValue}"); error = AttributesError.IncorrectKey; return null; } @@ -306,7 +313,7 @@ public void PushChanges(Action onSuccess = null, Action onCancelled = null, Acti var changesCount = ChangesCount; if (changesCount < 1) { - Debug.Log($"UserAttributes.PushChanges: Push cancelled. Changes count:'{changesCount}'"); + XDebug.Log($"UserAttributes.PushChanges: Push cancelled. Changes count:'{changesCount}'"); onCancelled?.Invoke(); return; } @@ -329,7 +336,7 @@ public void PushChanges(Action onSuccess = null, Action onCancelled = null, Acti else if (_modifiedAttributes.Count > 0) { Action onSuccessUpdate = () => FinalizePush(onSuccess); - PushModifiedChanges(onSuccessUpdate,onError); + PushModifiedChanges(onSuccessUpdate, onError); } else if (_removedAttributes.Count > 0) { @@ -357,14 +364,14 @@ private UserAttribute GetAttribute(string key, out AttributesError error) { if (_customAttributes == null) { - Debug.LogError($"UserAttributes: Get or update attributes before use"); + XDebug.LogError($"UserAttributes: Get or update attributes before use"); error = AttributesError.NotInitialized; return null; } if (string.IsNullOrEmpty(key)) { - Debug.LogError($"UserAttributes: Key can not be null or empty"); + XDebug.LogError($"UserAttributes: Key can not be null or empty"); error = AttributesError.IncorrectKey; return null; } @@ -381,7 +388,7 @@ private UserAttribute GetAttribute(string key, out AttributesError error) if (attributeToReturn == null) { - Debug.LogError($"UserAttributes: Could not find attribute. Key:{key}"); + XDebug.LogError($"UserAttributes: Could not find attribute. Key:{key}"); error = AttributesError.KeyNotFound; return null; } @@ -401,33 +408,30 @@ private bool IsNewKey(string key) break; } } + return isNew; } private void PushRemoveChanges(Action onSuccess, Action onError) { - Action onSuccessRemove = () => - { - _removedAttributes.Clear(); - onSuccess?.Invoke(); - }; - - string token = Token.Instance; - string projectId = XsollaSettings.StoreProjectId; - SdkUserAccountLogic.Instance.RemoveUserAttributes(token, projectId, _removedAttributes, onSuccessRemove, onError); + XsollaUserAccount.RemoveUserAttributes(_removedAttributes, + () => + { + _removedAttributes.Clear(); + onSuccess?.Invoke(); + }, + onError); } private void PushModifiedChanges(Action onSuccess, Action onError) { - Action onSuccessUpdate = () => - { - _modifiedAttributes.Clear(); - onSuccess?.Invoke(); - }; - - string token = Token.Instance; - string projectId = XsollaSettings.StoreProjectId; - SdkUserAccountLogic.Instance.UpdateUserAttributes(token, projectId, _modifiedAttributes, onSuccessUpdate, onError); + XsollaUserAccount.UpdateUserAttributes(_modifiedAttributes, + () => + { + _modifiedAttributes.Clear(); + onSuccess?.Invoke(); + }, + onError); } private void FinalizePush(Action onSuccess) @@ -457,4 +461,4 @@ private class UpdateQueueItem public Action OnError; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Attributes/UserAttributesUI.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Attributes/UserAttributesUI.cs index a67536fb1..93c7be1c9 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Attributes/UserAttributesUI.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Attributes/UserAttributesUI.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; +using Xsolla.Core; using Xsolla.UIBuilder; using Xsolla.UserAccount; @@ -127,7 +128,7 @@ private void HandleKeyChanged(AttributeItemUI attributeItem, string oldKey, stri { if (attributeItem.IsReadOnly) { - Debug.LogError($"UserAttributesUI.HandleKeyChanged: Attempt to change key of read-only attribute. OldKey:'{oldKey}' NewKey:'{newKey}'"); + XDebug.LogError($"UserAttributesUI.HandleKeyChanged: Attempt to change key of read-only attribute. OldKey:'{oldKey}' NewKey:'{newKey}'"); attributeItem.Key = oldKey; return; } @@ -135,7 +136,7 @@ private void HandleKeyChanged(AttributeItemUI attributeItem, string oldKey, stri var successChange = UserAttributes.Instance.ChangeKey(oldKey, newKey, out var error); if (!successChange) { - Debug.LogWarning($"UserAttributesUI.HandleKeyChanged: Failed attempt to change key. OldKey:'{oldKey}' NewKey:'{newKey}' Error:{error}"); + XDebug.LogWarning($"UserAttributesUI.HandleKeyChanged: Failed attempt to change key. OldKey:'{oldKey}' NewKey:'{newKey}' Error:{error}"); attributeItem.Key = oldKey; } } @@ -144,7 +145,7 @@ private void HandleValueChanged(AttributeItemUI attributeItem, string oldValue, { if (attributeItem.IsReadOnly) { - Debug.LogError($"UserAttributesUI.HandleValueChanged: Attempt to change value of read-only attribute. Key:{attributeItem.Key} OldValue:{oldValue} NewValue:{newValue}"); + XDebug.LogError($"UserAttributesUI.HandleValueChanged: Attempt to change value of read-only attribute. Key:{attributeItem.Key} OldValue:{oldValue} NewValue:{newValue}"); attributeItem.Value = oldValue; return; } @@ -152,7 +153,7 @@ private void HandleValueChanged(AttributeItemUI attributeItem, string oldValue, var successChange = UserAttributes.Instance.ChangeValue(attributeItem.Key, newValue, out var error); if (!successChange) { - Debug.LogWarning($"UserAttributesUI.HandleValueChanged: Failed attempt to change value. Key:'{attributeItem.Key}' OldValue:'{oldValue}' NewValue:'{newValue}' Error:{error}"); + XDebug.LogWarning($"UserAttributesUI.HandleValueChanged: Failed attempt to change value. Key:'{attributeItem.Key}' OldValue:'{oldValue}' NewValue:'{newValue}' Error:{error}"); attributeItem.Value = oldValue; } } @@ -161,14 +162,14 @@ private void HandleRemoveRequest(AttributeItemUI attributeItem) { if (attributeItem.IsReadOnly) { - Debug.LogError($"UserAttributesUI.HandleRemoveRequest: Attempt to remove read-only attribute. Key:{attributeItem.Key}"); + XDebug.LogError($"UserAttributesUI.HandleRemoveRequest: Attempt to remove read-only attribute. Key:{attributeItem.Key}"); return; } var successRemove = UserAttributes.Instance.RemoveAttribute(attributeItem.Key, out var error); if (!successRemove) { - Debug.LogWarning($"UserAttributesUI.HandleRemoveRequest: Failed attempt to remove attribute. Key:'{attributeItem.Key}' Error:{error}"); + XDebug.LogWarning($"UserAttributesUI.HandleRemoveRequest: Failed attempt to remove attribute. Key:'{attributeItem.Key}' Error:{error}"); return; } @@ -208,7 +209,7 @@ void CreateNewAttribute(List userAttributes) if (newAttribute != null) InstantiateAttributes(new List() { newAttribute }, readOnly: false); else - Debug.LogWarning($"UserAttributesUI.AddNewAttribute: Failed attempt to add new attribute. Error:{error}"); + XDebug.LogWarning($"UserAttributesUI.AddNewAttribute: Failed attempt to add new attribute. Error:{error}"); } UserAttributes.Instance.GetCustomAttributes(CreateNewAttribute,StoreDemoPopup.ShowError); diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/MainMenuNicknameChecker.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/MainMenuNicknameChecker.cs index 6096ea908..f2225ee4a 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/MainMenuNicknameChecker.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/MainMenuNicknameChecker.cs @@ -1,8 +1,8 @@ using System; using UnityEngine; -using Xsolla.Core; -using Xsolla.Core.Popup; -using Xsolla.Login; +using Xsolla.Auth; +using Xsolla.Demo.Popup; +using Xsolla.UserAccount; namespace Xsolla.Demo { @@ -26,19 +26,20 @@ private void Start() private void CheckNicknamePresence() { - var token = Token.Instance; - SdkAuthLogic.Instance.GetUserInfo(token, info => - { - if (string.IsNullOrEmpty(info.nickname)) + XsollaAuth.GetUserInfo( + info => { - var isUserEmailRegistration = !string.IsNullOrEmpty(info.email) && !string.IsNullOrEmpty(info.username); + if (string.IsNullOrEmpty(info.nickname)) + { + var isUserEmailRegistration = !string.IsNullOrEmpty(info.email) && !string.IsNullOrEmpty(info.username); - if (isUserEmailRegistration) - SetNickname(info.username); - else if (DemoSettings.RequestNicknameOnAuth) - RequestNickname(); - } - }); + if (isUserEmailRegistration) + SetNickname(info.username); + else if (DemoSettings.RequestNicknameOnAuth) + RequestNickname(); + } + }, + error => XDebug.LogError("Could not get user info")); } private void RequestNickname() @@ -51,14 +52,16 @@ private void SetNickname(string newNickname) var isNicknameUpdateInProgress = true; ShowWaiting(() => isNicknameUpdateInProgress); - var token = Token.Instance; - var updatePack = new UserInfoUpdate() { nickname = newNickname }; + var updateInfo = new UserInfoUpdate { + nickname = newNickname + }; - SdkAuthLogic.Instance.UpdateUserInfo(token, updatePack, - onSuccess: _ => isNicknameUpdateInProgress = false, - onError: error => + XsollaUserAccount.UpdateUserInfo( + updateInfo, + _ => isNicknameUpdateInProgress = false, + error => { - Debug.LogError("Could not update user info"); + XDebug.LogError("Could not update user info"); isNicknameUpdateInProgress = false; StoreDemoPopup.ShowError(error); }); @@ -69,4 +72,4 @@ private void ShowWaiting(Func waitWhile) PopupFactory.Instance.CreateWaiting().SetCloseCondition(() => !waitWhile.Invoke()); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/AndroidProfileEntryDisabler.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/AndroidProfileEntryDisabler.cs index 7ab8f662b..6ac8b0584 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/AndroidProfileEntryDisabler.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/AndroidProfileEntryDisabler.cs @@ -1,4 +1,5 @@ using UnityEngine; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo @@ -6,19 +7,17 @@ namespace Xsolla.Demo [RequireComponent(typeof(UserProfileEntryUI))] public class AndroidProfileEntryDisabler : MonoBehaviour { - #if UNITY_ANDROID +#if UNITY_ANDROID private void Start() { - SdkAuthLogic.Instance.GetUserInfo(Token.Instance, - onSuccess: info => + XsollaAuth.GetUserInfo( + info => { if (string.IsNullOrEmpty(info.email)) - { - this.gameObject.SetActive(false); - } + gameObject.SetActive(false); }, - onError: error => Debug.Log("Could not get user info")); + null); } - #endif +#endif } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/AvatarChoiceButton.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/AvatarChoiceButton.cs index ea46dd5c6..6df03168c 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/AvatarChoiceButton.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/AvatarChoiceButton.cs @@ -7,7 +7,7 @@ namespace Xsolla.Demo [RequireComponent(typeof(SimpleButton))] public class AvatarChoiceButton : MonoBehaviour { - [SerializeField] Image AvatarImage = default; + [SerializeField] private Image AvatarImage; public static event Action AvatarPicked; @@ -21,4 +21,4 @@ private void RaiseAvatarPicked() AvatarPicked?.Invoke(AvatarImage.sprite); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/Editors/UserProfileEntryGenderEditor.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/Editors/UserProfileEntryGenderEditor.cs index ae2bace94..09457e35f 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/Editors/UserProfileEntryGenderEditor.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/Editors/UserProfileEntryGenderEditor.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEngine.UI; +using Xsolla.Core; namespace Xsolla.Demo { @@ -49,7 +50,7 @@ public override void SetInitial(string value) checkboxTypeToActivate = CheckboxType.PreferNot; break; default: - Debug.LogWarning($"Could not set initial value: {value}"); + XDebug.LogWarning($"Could not set initial value: {value}"); return; } @@ -81,7 +82,7 @@ private void ProcessValueChange(CheckboxType checkboxType, bool newValue) result = UserProfileGender.PREFER_NOT; break; default: - Debug.LogError($"Unexpected checkboxType: {checkboxType.ToString()}"); + XDebug.LogError($"Unexpected checkboxType: {checkboxType.ToString()}"); break; } diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/PasswordProfileEntryDisabler.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/PasswordProfileEntryDisabler.cs index b1bd35c6b..22137e0d1 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/PasswordProfileEntryDisabler.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/PasswordProfileEntryDisabler.cs @@ -1,4 +1,6 @@ using UnityEngine; +using Xsolla.Auth; +using Xsolla.Core; namespace Xsolla.Demo { @@ -6,20 +8,15 @@ public class PasswordProfileEntryDisabler : MonoBehaviour { private void Start() { - var token = Core.Token.Instance; - - SdkAuthLogic.Instance.GetUserInfo(token, - onSuccess: info => + XsollaAuth.GetUserInfo( + info => { var isEmailPresented = !string.IsNullOrEmpty(info.email); var isUsernamePresented = !string.IsNullOrEmpty(info.username); - if (!isEmailPresented && !isUsernamePresented) - { - this.gameObject.SetActive(false); - } + gameObject.SetActive(false); }, - onError: error => Debug.Log("Could not get user info")); + error => XDebug.Log("Could not get user info")); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileAvatarManager.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileAvatarManager.cs index 85aaf0b72..ca111f0e2 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileAvatarManager.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileAvatarManager.cs @@ -3,21 +3,21 @@ using System.Text; using System.Collections.Generic; using UnityEngine; +using Xsolla.Auth; using Xsolla.Core; -using Xsolla.Core.Popup; -using Xsolla.Login; +using Xsolla.Demo.Popup; using Xsolla.UserAccount; namespace Xsolla.Demo { public class UserProfileAvatarManager : MonoBehaviour { - [SerializeField] GameObject SetBlock = default; - [SerializeField] GameObject UnsetBlock = default; - [SerializeField] GameObject EditBlock = default; + [SerializeField] private GameObject SetBlock; + [SerializeField] private GameObject UnsetBlock; + [SerializeField] private GameObject EditBlock; - [SerializeField] SimpleButton[] EditButtons = default; - [SerializeField] SimpleButton DeleteButton = default; + [SerializeField] private SimpleButton[] EditButtons; + [SerializeField] private SimpleButton DeleteButton; private void Awake() { @@ -39,14 +39,13 @@ private IEnumerator Start() string pictureUrl = null; bool? isUserPictureUrlObtained = null; - var token = Token.Instance; - SdkAuthLogic.Instance.GetUserInfo(token, - onSuccess: info => + XsollaAuth.GetUserInfo( + info => { pictureUrl = info.picture; isUserPictureUrlObtained = true; }, - onError: error => + error => { StoreDemoPopup.ShowError(error); isUserPictureUrlObtained = false; @@ -91,9 +90,10 @@ private void UploadPicture(Sprite sprite) byte[] data = ConvertToData(sprite, out string boundary); - var token = Token.Instance; - SdkUserAccountLogic.Instance.UploadUserPicture(token, data, boundary, - onSuccess: imageInfo => + XsollaUserAccount.UploadUserPicture( + data, + boundary, + imageInfo => { var packedInfo = ParseUtils.FromJson(imageInfo); @@ -103,16 +103,15 @@ private void UploadPicture(Sprite sprite) SetPictureUrlToInfo(pictureUrl, onSuccess: () => { - ImageLoader.Instance.AddImage(pictureUrl, sprite); RefreshImageLoaders(); isImageUploaded = true; }, onError: () => isImageUploaded = false); } else - Debug.LogError($"Could not parse server response: {imageInfo}"); + XDebug.LogError($"Could not parse server response: {imageInfo}"); }, - onError: error => + error => { isImageUploaded = false; StoreDemoPopup.ShowError(error); @@ -124,9 +123,8 @@ private void DeletePicture() bool? isPictureDeleted = null; ShowWaiting(() => isPictureDeleted == null); - var token = Token.Instance; - SdkUserAccountLogic.Instance.DeleteUserPicture(token, - onSuccess: () => + XsollaUserAccount.DeleteUserPicture( + () => { SetPictureUrlToInfo(null, onSuccess: () => @@ -136,7 +134,7 @@ private void DeletePicture() }, onError: () => isPictureDeleted = false); }, - onError: error => + error => { isPictureDeleted = false; StoreDemoPopup.ShowError(error); @@ -150,14 +148,13 @@ private void ShowWaiting(Func waitWhile) private void SetPictureUrlToInfo(string pictureUrl, Action onSuccess = null, Action onError = null) { - var token = Token.Instance; - SdkAuthLogic.Instance.GetUserInfo(token, - onSuccess: info => + XsollaAuth.GetUserInfo( + info => { info.picture = pictureUrl; onSuccess?.Invoke(); }, - onError: error => + error => { StoreDemoPopup.ShowError(error); onError?.Invoke(); @@ -198,7 +195,9 @@ private void RefreshImageLoaders() private enum AvatarState { - Set, Unset, Edit + Set, + Unset, + Edit } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileEntryType.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileEntryType.cs index a752b2df8..8efea5cc6 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileEntryType.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileEntryType.cs @@ -2,6 +2,14 @@ { public enum UserProfileEntryType { - Email, Password, Username, Nickname, PhoneNumber, FirstName, LastName, DateOfBirth, Gender + Email, + Password, + Username, + Nickname, + PhoneNumber, + FirstName, + LastName, + DateOfBirth, + Gender } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileEntryUI.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileEntryUI.cs index db9c6747c..349c6b6ee 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileEntryUI.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfileEntryUI.cs @@ -6,19 +6,19 @@ namespace Xsolla.Demo { public class UserProfileEntryUI : MonoBehaviour { - [SerializeField] GameObject SetStateObjects = default; - [SerializeField] GameObject UnsetStateObjects = default; - [SerializeField] GameObject EditStateObjects = default; + [SerializeField] private GameObject SetStateObjects; + [SerializeField] private GameObject UnsetStateObjects; + [SerializeField] private GameObject EditStateObjects; - [SerializeField] Text CurrentValueText = default; + [SerializeField] private Text CurrentValueText; - [SerializeField] SimpleButton[] EditButtons = default; - [SerializeField] UserProfileEntryEditor EntryEditor = default; - [SerializeField] BaseUserProfileValueConverter ValueConverter = default; + [SerializeField] private SimpleButton[] EditButtons; + [SerializeField] private UserProfileEntryEditor EntryEditor; + [SerializeField] private BaseUserProfileValueConverter ValueConverter; private UserProfileEntryType _entryType; private EntryState _currentState; - + private string CurrentValue { get => CurrentValueText.text; @@ -132,7 +132,9 @@ private void OnEntryEdited(string newValue) private enum EntryState { - Set, Unset, Edit + Set, + Unset, + Edit } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfilePageManager.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfilePageManager.cs index 65eb37548..90bd0d3fe 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfilePageManager.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfilePageManager.cs @@ -2,10 +2,10 @@ using System.Collections; using System.Text.RegularExpressions; using UnityEngine; -using UnityEngine.EventSystems; +using Xsolla.Auth; using Xsolla.Core; -using Xsolla.Core.Popup; -using Xsolla.Login; +using Xsolla.Demo.Popup; +using Xsolla.UserAccount; namespace Xsolla.Demo { @@ -15,7 +15,7 @@ public class UserProfilePageManager : MonoBehaviour private bool? _isProfileUpdated; private Action _commonErrorCallback; - private Func _commonWaitCondition; + private Func _commonWaitCondition; private bool _isUpdateInProgress; private const int POPUP_VALUE_LIMIT = 20; @@ -27,7 +27,7 @@ private void Awake() _commonErrorCallback = error => { _isProfileUpdated = false; - Debug.LogError(error.errorMessage); + XDebug.LogError(error.errorMessage); StoreDemoPopup.ShowError(error); }; @@ -42,17 +42,16 @@ private void OnDestroy() private IEnumerator Start() { UserInfo userInfo = null; - var token = Token.Instance; - SdkAuthLogic.Instance.GetUserInfo(token, - onSuccess: info => + XsollaAuth.GetUserInfo( + info => { userInfo = info; _isProfileUpdated = true; }, - onError: _commonErrorCallback); + _commonErrorCallback); - ShowWaiting(waitWhile: _commonWaitCondition); + ShowWaiting(_commonWaitCondition); yield return new WaitWhile(_commonWaitCondition); if (userInfo == null) @@ -66,9 +65,9 @@ private IEnumerator Start() private void InitializeEntries(UserInfo userInfo) { - for (int index = 0; index < UserProfileEntries.Length; index++) + for (var index = 0; index < UserProfileEntries.Length; index++) { - var entryType = (UserProfileEntryType)index; + var entryType = (UserProfileEntryType) index; string entryValue = null; switch (entryType) @@ -110,21 +109,21 @@ private void OnUserEntryEdited(UserProfileEntryUI sender, UserProfileEntryType e { if (newValue == null) { - Debug.LogError($"New value of entryType {entryType} is null. Can not update"); + XDebug.LogError($"New value of entryType {entryType} is null. Can not update"); sender.InitializeEntry(entryType, oldValue); return; } if (_isUpdateInProgress) { - Debug.LogWarning("Can not update new entry while another update is in progress"); + XDebug.LogWarning("Can not update new entry while another update is in progress"); sender.InitializeEntry(entryType, oldValue); return; } _isUpdateInProgress = true; _isProfileUpdated = null; - ShowWaiting(waitWhile: _commonWaitCondition); + ShowWaiting(_commonWaitCondition); StartCoroutine(UnsetIsInProgressOnCompletion()); StartCoroutine(RevertValueOnError(sender, entryType, oldValue)); @@ -144,7 +143,7 @@ private void OnUserEntryEdited(UserProfileEntryUI sender, UserProfileEntryType e StartCoroutine(DeleteUserPhoneNumber()); break; default: - Debug.LogWarning($"Update of {entryType} is not supported"); + XDebug.LogWarning($"Update of {entryType} is not supported"); _isProfileUpdated = false; return; } @@ -161,7 +160,7 @@ private IEnumerator RevertValueOnError(UserProfileEntryUI sender, UserProfileEnt { yield return new WaitWhile(_commonWaitCondition); - if(_isProfileUpdated == false) + if (_isProfileUpdated == false) sender.InitializeEntry(entryType, oldValue); } @@ -173,7 +172,7 @@ private void UpdateCommonEntries(UserProfileEntryType entryType, string newValue switch (entryType) { case UserProfileEntryType.DateOfBirth: - if (DateTime.TryParse(newValue, out DateTime birthday)) + if (DateTime.TryParse(newValue, out var birthday)) infoUpdatePack.birthday = newValue; else isValueValid = false; @@ -183,9 +182,9 @@ private void UpdateCommonEntries(UserProfileEntryType entryType, string newValue break; case UserProfileEntryType.Gender: if (newValue == UserProfileGender.MALE_SHORT || - newValue == UserProfileGender.FEMALE_SHORT || - newValue == UserProfileGender.OTHER_LOWERCASE || - newValue == UserProfileGender.PREFER_NOT_LOWERCASE) + newValue == UserProfileGender.FEMALE_SHORT || + newValue == UserProfileGender.OTHER_LOWERCASE || + newValue == UserProfileGender.PREFER_NOT_LOWERCASE) infoUpdatePack.gender = newValue; else isValueValid = false; @@ -206,15 +205,14 @@ private void UpdateCommonEntries(UserProfileEntryType entryType, string newValue return; } - - var token = Token.Instance; - SdkAuthLogic.Instance.UpdateUserInfo(token, infoUpdatePack, - onSuccess: newInfo => + XsollaUserAccount.UpdateUserInfo( + infoUpdatePack, + newInfo => { InitializeEntries(newInfo); _isProfileUpdated = true; }, - onError: _commonErrorCallback); + _commonErrorCallback); } private IEnumerator UpdateUpperRightCornerInfoOnCompletion() @@ -223,38 +221,29 @@ private IEnumerator UpdateUpperRightCornerInfoOnCompletion() FindObjectOfType()?.Refresh(); } - private void UpdateUserPhoneNumber(string newValue) + private void UpdateUserPhoneNumber(string newPhone) { - var isValid = Regex.IsMatch(newValue, @"^\+(\d){5,25}$"); - + var isValid = Regex.IsMatch(newPhone, @"^\+(\d){5,25}$"); if (!isValid) { - ShowInvalidValue(UserProfileEntryType.PhoneNumber, newValue); + ShowInvalidValue(UserProfileEntryType.PhoneNumber, newPhone); _isProfileUpdated = false; return; } - var token = Token.Instance; - - SdkAuthLogic.Instance.GetUserInfo(token, - onSuccess: info => info.phone = newValue); - - SdkUserAccountLogic.Instance.UpdateUserPhoneNumber(token, newValue, - onSuccess: () => _isProfileUpdated = true, - onError: _commonErrorCallback); + XsollaUserAccount.UpdateUserPhoneNumber( + newPhone, + () => _isProfileUpdated = true, + _commonErrorCallback); } private IEnumerator DeleteUserPhoneNumber() { - var token = Token.Instance; UserInfo userInfo = null; - SdkAuthLogic.Instance.GetUserInfo(token, - onSuccess: info => - { - userInfo = info; - }, - onError: _commonErrorCallback); + XsollaAuth.GetUserInfo( + info => { userInfo = info; }, + _commonErrorCallback); yield return new WaitWhile(() => _isProfileUpdated == null && userInfo == null); @@ -263,9 +252,10 @@ private IEnumerator DeleteUserPhoneNumber() var oldPhoneNumber = userInfo.phone; userInfo.phone = null; - SdkUserAccountLogic.Instance.DeleteUserPhoneNumber(token, oldPhoneNumber, - onSuccess: () => _isProfileUpdated = true, - onError: _commonErrorCallback); + XsollaUserAccount.DeleteUserPhoneNumber( + oldPhoneNumber, + () => _isProfileUpdated = true, + _commonErrorCallback); } } @@ -284,4 +274,4 @@ private void ShowInvalidValue(UserProfileEntryType entryType, string value) StoreDemoPopup.ShowError(error); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfilePasswordReset.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfilePasswordReset.cs index a699386d5..9344ee33d 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfilePasswordReset.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/Profile/UserProfilePasswordReset.cs @@ -1,14 +1,15 @@ using System; using System.Collections; using UnityEngine; +using Xsolla.Auth; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { public class UserProfilePasswordReset : MonoBehaviour { - [SerializeField] SimpleButton PasswordEditButton = default; + [SerializeField] private SimpleButton PasswordEditButton = default; private const string MESSAGE_TEMPLATE = "Change your password using the instructions we sent to {email@domain.com}."; @@ -23,14 +24,13 @@ private IEnumerator ResetPassword() string email = null; - var token = Token.Instance; - SdkAuthLogic.Instance.GetUserInfo(token, - onSuccess: info => + XsollaAuth.GetUserInfo( + info => { email = info.email; isInfoObtained = true; }, - onError: error => + error => { StoreDemoPopup.ShowError(error); isInfoObtained = false; @@ -43,17 +43,14 @@ private IEnumerator ResetPassword() Action onSuccessfulPasswordChange = () => { - Debug.Log("Password reset request success"); + XDebug.Log("Password reset request success"); var message = MESSAGE_TEMPLATE.Replace("{email@domain.com}", email); PopupFactory.Instance.CreateSuccessPasswordReset().SetMessage(message); }; - Action onFailedPasswordChange = error => - { - StoreDemoPopup.ShowError(error); - }; + Action onFailedPasswordChange = error => { StoreDemoPopup.ShowError(error); }; - SdkAuthLogic.Instance.ResetPassword(email, onSuccessfulPasswordChange, onFailedPasswordChange); + XsollaAuth.ResetPassword(email, onSuccessfulPasswordChange, onFailedPasswordChange); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/UserAvatarLoader.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/UserAvatarLoader.cs index 0e1438937..e0dca37b9 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/UserAvatarLoader.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/UserAvatarLoader.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEngine.UI; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo @@ -9,17 +10,13 @@ public class UserAvatarLoader : MonoBehaviour [SerializeField] private Image UserAvatarHolder = default; [SerializeField] private Sprite AvatarPlaceholder = default; - private static string _expectedAvatarUrl; - public void Refresh() => Start(); private void Start() { - var token = Token.Instance; - SdkAuthLogic.Instance.GetUserInfo(token, info => - { - DrawAvatar(info.picture); - }); + XsollaAuth.GetUserInfo( + info => { DrawAvatar(info.picture); }, + XDebug.LogError); } private void DrawAvatar(string avatarUrl) @@ -28,21 +25,16 @@ private void DrawAvatar(string avatarUrl) { if (UserAvatarHolder) UserAvatarHolder.sprite = AvatarPlaceholder; - - _expectedAvatarUrl = null; } else { - if (avatarUrl != _expectedAvatarUrl) - _expectedAvatarUrl = avatarUrl; - - ImageLoader.Instance.GetImageAsync(avatarUrl, - callback: (receivedAvatarUrl, avatar) => + ImageLoader.LoadSprite(avatarUrl, + avatar => { - if (receivedAvatarUrl == _expectedAvatarUrl && UserAvatarHolder != null) + if (UserAvatarHolder) UserAvatarHolder.sprite = avatar; }); } } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserImageUpload.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/UserImageUpload.cs similarity index 75% rename from Assets/Xsolla/UserAccount/Entities/UserImageUpload.cs rename to Assets/Xsolla.Demo/Login/Scripts/Profile/UserImageUpload.cs index ac35f5006..2f9737c9f 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserImageUpload.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/UserImageUpload.cs @@ -1,10 +1,10 @@ using System; -namespace Xsolla.UserAccount +namespace Xsolla.Demo { [Serializable] public class UserImageUpload { public string picture; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserImageUpload.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Profile/UserImageUpload.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/UserImageUpload.cs.meta rename to Assets/Xsolla.Demo/Login/Scripts/Profile/UserImageUpload.cs.meta diff --git a/Assets/Xsolla.Demo/Login/Scripts/Profile/UserInfoDrawer.cs b/Assets/Xsolla.Demo/Login/Scripts/Profile/UserInfoDrawer.cs index 0989c5ee7..2e846d10b 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Profile/UserInfoDrawer.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Profile/UserInfoDrawer.cs @@ -1,6 +1,7 @@ using System.Collections; using UnityEngine; using UnityEngine.UI; +using Xsolla.Auth; using Xsolla.Core; namespace Xsolla.Demo @@ -16,15 +17,14 @@ private IEnumerator Start() { if (!UserEmailText) { - Debug.LogWarning("Can not draw user info because 'UserEmailText' field is null or empty!"); + XDebug.LogWarning("Can not draw user info because 'UserEmailText' field is null or empty!"); yield break; } - yield return new WaitWhile(() => Core.Token.Instance == null); + yield return new WaitWhile(() => !XsollaToken.Exists); var busy = true; - var token = Core.Token.Instance; - SdkAuthLogic.Instance.GetUserInfo(token, info => + XsollaAuth.GetUserInfo(info => { DrawInfo(info); busy = false; @@ -60,4 +60,4 @@ public void Refresh() StartCoroutine(Start()); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkFriendsLogic.cs b/Assets/Xsolla.Demo/Login/Scripts/Sdk/FriendsLogic.cs similarity index 68% rename from Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkFriendsLogic.cs rename to Assets/Xsolla.Demo/Login/Scripts/Sdk/FriendsLogic.cs index d0df57fb3..23dadbe99 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkFriendsLogic.cs +++ b/Assets/Xsolla.Demo/Login/Scripts/Sdk/FriendsLogic.cs @@ -8,7 +8,7 @@ namespace Xsolla.Demo { - public class SdkFriendsLogic : MonoSingleton + public class FriendsLogic : MonoSingleton { /// /// Maximum friends count to display. @@ -19,8 +19,8 @@ public class SdkFriendsLogic : MonoSingleton /// private const string DEFAULT_NAME_VALUE = "User without name"; - private const FriendsSearchResultsSortOrder FRIENDS_SORT_ORDER = FriendsSearchResultsSortOrder.Asc; - private const FriendsSearchResultsSort FRIENDS_SORT_TYPE = FriendsSearchResultsSort.ByNickname; + private const FriendsSearchOrder FRIENDS_SORT_ORDER = FriendsSearchOrder.Asc; + private const FriendsSearchSort FRIENDS_SORT_TYPE = FriendsSearchSort.ByNickname; public event Action UpdateUserFriendsEvent; public event Action UpdateUserSocialFriendsEvent; @@ -52,8 +52,8 @@ public void BlockUser(FriendModel user, Action onSuccess = null, Ac onSuccess?.Invoke(user); UpdateUserFriendsEvent?.Invoke(); }; - - XsollaUserAccount.Instance.UpdateUserFriends(Token.Instance, FriendAction.BlockFriend, user.Id, successCallback, onError); + + XsollaUserAccount.UpdateUserFriends(FriendAction.BlockFriend, user.Id, successCallback, onError); } public void UnblockUser(FriendModel user, Action onSuccess = null, Action onError = null) @@ -64,7 +64,7 @@ public void UnblockUser(FriendModel user, Action onSuccess = null, UpdateUserFriendsEvent?.Invoke(); }; - XsollaUserAccount.Instance.UpdateUserFriends(Token.Instance, FriendAction.UnblockFriend, user.Id, successCallback, onError); + XsollaUserAccount.UpdateUserFriends(FriendAction.UnblockFriend, user.Id, successCallback, onError); } public void SendFriendshipInvite(FriendModel user, Action onSuccess = null, Action onError = null) @@ -75,7 +75,7 @@ public void SendFriendshipInvite(FriendModel user, Action onSuccess UpdateUserFriendsEvent?.Invoke(); }; - XsollaUserAccount.Instance.UpdateUserFriends(Token.Instance, FriendAction.SendInviteRequest, user.Id, successCallback, onError); + XsollaUserAccount.UpdateUserFriends(FriendAction.SendInviteRequest, user.Id, successCallback, onError); } public void RemoveFriend(FriendModel user, Action onSuccess = null, Action onError = null) @@ -86,7 +86,7 @@ public void RemoveFriend(FriendModel user, Action onSuccess = null, UpdateUserFriendsEvent?.Invoke(); }; - XsollaUserAccount.Instance.UpdateUserFriends(Token.Instance, FriendAction.RemoveFriend, user.Id, successCallback, onError); + XsollaUserAccount.UpdateUserFriends(FriendAction.RemoveFriend, user.Id, successCallback, onError); } public void AcceptFriendship(FriendModel user, Action onSuccess = null, Action onError = null) @@ -97,7 +97,7 @@ public void AcceptFriendship(FriendModel user, Action onSuccess = n UpdateUserFriendsEvent?.Invoke(); }; - XsollaUserAccount.Instance.UpdateUserFriends(Token.Instance, FriendAction.AcceptInvite, user.Id, successCallback, onError); + XsollaUserAccount.UpdateUserFriends(FriendAction.AcceptInvite, user.Id, successCallback, onError); } public void DeclineFriendship(FriendModel user, Action onSuccess = null, Action onError = null) @@ -108,7 +108,7 @@ public void DeclineFriendship(FriendModel user, Action onSuccess = UpdateUserFriendsEvent?.Invoke(); }; - XsollaUserAccount.Instance.UpdateUserFriends(Token.Instance, FriendAction.DenyInvite, user.Id, successCallback, onError); + XsollaUserAccount.UpdateUserFriends(FriendAction.DenyInvite, user.Id, successCallback, onError); } public void CancelFriendshipRequest(FriendModel user, Action onSuccess = null, Action onError = null) @@ -119,7 +119,7 @@ public void CancelFriendshipRequest(FriendModel user, Action onSucc UpdateUserFriendsEvent?.Invoke(); }; - XsollaUserAccount.Instance.UpdateUserFriends(Token.Instance, FriendAction.CancelRequest, user.Id, successCallback, onError); + XsollaUserAccount.UpdateUserFriends(FriendAction.CancelRequest, user.Id, successCallback, onError); } public void ForceUpdateFriendsFromSocialNetworks(Action onSuccess = null, Action onError = null) @@ -130,14 +130,13 @@ public void ForceUpdateFriendsFromSocialNetworks(Action onSuccess = null, Action UpdateUserSocialFriendsEvent?.Invoke(); }; - XsollaUserAccount.Instance.UpdateUserSocialFriends(Token.Instance, SocialProvider.None, successCallback, onError); + XsollaUserAccount.UpdateUserSocialFriends(successCallback, onError); } public void GetFriendsFromSocialNetworks(Action> onSuccess = null, Action onError = null) { - XsollaUserAccount.Instance.GetUserSocialFriends(Token.Instance, SocialProvider.None, 0, 500, false, - onSuccess: friends => StartCoroutine(ConvertSocialFriendsToRecommended(friends.data, onSuccess, onError)), - onError); + XsollaUserAccount.GetUserSocialFriends(onSuccess: friends => StartCoroutine(ConvertSocialFriendsToRecommended(friends.data, onSuccess, onError)), + onError: onError); } private IEnumerator ConvertSocialFriendsToRecommended(List socialFriends, Action> onSuccess = null, Action onError = null) @@ -148,27 +147,27 @@ private IEnumerator ConvertSocialFriendsToRecommended(List soc { var recommendedFriend = ConvertFriendEntity(socialFriend); - if (recommendedFriend.Relationship == UserRelationship.SocialNonXsolla)//Social friend without linked Xsolla account + if (recommendedFriend.Relationship == UserRelationship.SocialNonXsolla) //Social friend without linked Xsolla account { //Proceed } - else if (recommendedFriend.Relationship != UserRelationship.Unknown)//User is already added/blocked/requested + else if (recommendedFriend.Relationship != UserRelationship.Unknown) //User is already added/blocked/requested { - continue;//Skip this user, they should not appear as recommended + continue; //Skip this user, they should not appear as recommended } - else//Social friend with linked Xsolla account, replace nickname and avatar with ones from Xsolla + else //Social friend with linked Xsolla account, replace nickname and avatar with ones from Xsolla { - var token = Token.Instance; bool? isUserinfoObtained = null; - SdkUserAccountLogic.Instance.GetPublicInfo(token, recommendedFriend.Id, - onSuccess: info => + XsollaUserAccount.GetPublicInfo( + recommendedFriend.Id, + info => { recommendedFriend.Nickname = info.nickname; recommendedFriend.AvatarUrl = info.avatar; isUserinfoObtained = true; }, - onError: error => + error => { onError?.Invoke(error); isUserinfoObtained = false; @@ -178,7 +177,7 @@ private IEnumerator ConvertSocialFriendsToRecommended(List soc if (isUserinfoObtained == false) { - Debug.LogError($"Could not get user information. UserID: {recommendedFriend.Id}"); + XDebug.LogError($"Could not get user information. UserID: {recommendedFriend.Id}"); yield break; } } @@ -187,7 +186,7 @@ private IEnumerator ConvertSocialFriendsToRecommended(List soc //Avatar preload if (!string.IsNullOrEmpty(recommendedFriend.AvatarUrl)) - ImageLoader.Instance.GetImageAsync(recommendedFriend.AvatarUrl, null); + ImageLoader.LoadSprite(recommendedFriend.AvatarUrl, null); } onSuccess?.Invoke(recommendedFriends); @@ -196,30 +195,34 @@ private IEnumerator ConvertSocialFriendsToRecommended(List soc private void GetUsersByType(FriendsSearchType searchType, UserRelationship relationship, Action> onSuccess = null, Action onError = null) { - XsollaUserAccount.Instance.GetUserFriends(Token.Instance, - searchType, FRIENDS_SORT_TYPE, FRIENDS_SORT_ORDER, null, MAX_FRIENDS_COUNT, friends => + XsollaUserAccount.GetUserFriends( + searchType, + friends => { - onSuccess?.Invoke(friends.Select(f => + onSuccess?.Invoke(friends.relationships.Select(f => { var result = ConvertFriendEntity(f, relationship); // this method used at this place for fastest image loading if (!string.IsNullOrEmpty(result.AvatarUrl)) - ImageLoader.Instance.GetImageAsync(result.AvatarUrl, null); + ImageLoader.LoadSprite(result.AvatarUrl, null); return result; }).ToList()); - }, onError); + }, + onError, + FRIENDS_SORT_TYPE, + FRIENDS_SORT_ORDER, + MAX_FRIENDS_COUNT); } private FriendModel ConvertFriendEntity(UserSocialFriend friend) { - var result = new FriendModel - { + var result = new FriendModel { Id = friend.xl_uid, Nickname = friend.name, AvatarUrl = friend.avatar }; - if (!string.IsNullOrEmpty(friend.xl_uid))//Xsolla ID not null - this is a registered Xsolla user with linked social account + if (!string.IsNullOrEmpty(friend.xl_uid)) //Xsolla ID not null - this is a registered Xsolla user with linked social account { var existingFriend = UserFriends.Instance.GetUserById(friend.xl_uid); result.Status = existingFriend?.Status ?? UserOnlineStatus.Unknown; @@ -231,16 +234,15 @@ private FriendModel ConvertFriendEntity(UserSocialFriend friend) result.Relationship = UserRelationship.SocialNonXsolla; } - if (Enum.TryParse(friend.platform, ignoreCase: true, out SocialProvider provider)) + if (Enum.TryParse(friend.platform, ignoreCase: true, out SocialProvider provider)) result.SocialProvider = provider; return result; } - private FriendModel ConvertFriendEntity(UserFriendEntity friend, UserRelationship relationship) + private FriendModel ConvertFriendEntity(UserFriend friend, UserRelationship relationship) { - return new FriendModel - { + return new FriendModel { Id = friend.user.id, Nickname = GetUserNickname(friend), Tag = friend.user.tag, @@ -250,7 +252,7 @@ private FriendModel ConvertFriendEntity(UserFriendEntity friend, UserRelationshi }; } - private string GetUserNickname(UserFriendEntity friend) + private string GetUserNickname(UserFriend friend) { var userInfo = friend.user; @@ -268,4 +270,4 @@ private string GetUserNickname(UserFriendEntity friend) return DEFAULT_NAME_VALUE; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkFriendsLogic.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Sdk/FriendsLogic.cs.meta similarity index 100% rename from Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkFriendsLogic.cs.meta rename to Assets/Xsolla.Demo/Login/Scripts/Sdk/FriendsLogic.cs.meta diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkAuthLogic.cs b/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkAuthLogic.cs deleted file mode 100644 index d45413b63..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkAuthLogic.cs +++ /dev/null @@ -1,205 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Auth; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Demo -{ - public class SdkAuthLogic : MonoSingleton - { - public event Action RegistrationEvent; - public event Action LoginEvent; - public event Action UpdateUserInfoEvent; - - #region Token - public void ValidateToken(string token, Action onSuccess = null, Action onError = null) - { - GetUserInfo(token, useCache: false, onSuccess: _ => onSuccess?.Invoke(token), onError: onError); - } - #endregion - - #region User - public void GetUserInfo(string token, Action onSuccess = null, Action onError = null) - { - GetUserInfo(token, useCache: true, onSuccess, onError); - } - - private readonly Dictionary _userCache = new Dictionary(); - public void GetUserInfo(string token, bool useCache, Action onSuccess, Action onError = null) - { - if (useCache && _userCache.ContainsKey(token)) - onSuccess?.Invoke(_userCache[token]); - else - XsollaAuth.Instance.GetUserInfo(token, info => - { - _userCache[token] = info; - onSuccess?.Invoke(info); - }, onError); - } - - public void UpdateUserInfo(string token, UserInfoUpdate info, Action onSuccess, Action onError = null) - { - Action successCallback = userInfo => - { - _userCache[token] = userInfo; - onSuccess?.Invoke(userInfo); - UpdateUserInfoEvent?.Invoke(); - }; - - XsollaUserAccount.Instance.UpdateUserInfo(token, info, successCallback, onError); - } - - public void Register(string username, string password, string email, string state = null, Action onSuccess = null, Action onError = null) - { - Action successCallback = () => - { - onSuccess?.Invoke(); - RegistrationEvent?.Invoke(); - }; - - XsollaAuth.Instance.Register(username, password, email, - oauthState:state, acceptConsent:true, promoEmailAgreement:true, onSuccess:successCallback, onError:onError); - } - - public void Register(string username, string password, string email, string state = null, Action onSuccess = null, Action onError = null) - { - Action successCallback = responseCode => - { - onSuccess?.Invoke(responseCode); - RegistrationEvent?.Invoke(); - }; - - XsollaAuth.Instance.Register(username, password, email, - oauthState:state, acceptConsent:true, promoEmailAgreement:true, onSuccess:successCallback, onError:onError); - } - - public void Register(string username, string password, string email, string state = null, Action onSuccess = null, Action onError = null) - { - Action successCallback = response => - { - onSuccess?.Invoke(response); - RegistrationEvent?.Invoke(); - }; - - XsollaAuth.Instance.Register(username, password, email, - oauthState:state, acceptConsent:true, promoEmailAgreement:true, onSuccess:successCallback, onError:onError); - } - - public void SignIn(string username, string password, bool rememberUser, Action onSuccess, Action onError = null) - { - Action successCallback = token => - { - onSuccess?.Invoke(token); - LoginEvent?.Invoke(); - }; - - XsollaAuth.Instance.SignIn(username, password, rememberUser, onSuccess:successCallback, onError:onError); - } - - public void ResetPassword(string username, Action onSuccess = null, Action onError = null) - { - XsollaAuth.Instance.ResetPassword(username, onSuccess:onSuccess, onError:onError); - } - - public void ResendConfirmationLink(string username, Action onSuccess = null, Action onError = null) - { - XsollaAuth.Instance.ResendConfirmationLink(username, onSuccess:onSuccess, onError:onError); - } - #endregion - - #region Social - public void SilentAuth(string providerName, string appId, string sessionTicket, string state = null, Action onSuccess = null, Action onError = null) - { - Action successCallback = token => - { - onSuccess?.Invoke(token); - LoginEvent?.Invoke(); - }; - - XsollaAuth.Instance.SilentAuth(providerName: providerName, appId: appId, sessionTicket: sessionTicket, oauthState: state, onSuccess: successCallback, onError: onError); - } - - public void AuthViaDeviceID(Core.DeviceType deviceType, string deviceName, string deviceId, string payload = null, string state = null, Action onSuccess = null, Action onError = null) - { - Action successCallback = token => - { - onSuccess?.Invoke(token); - LoginEvent?.Invoke(); - }; - - XsollaAuth.Instance.AuthViaDeviceID(deviceType, deviceName, deviceId, payload, state, successCallback, onError); - } - - public string GetSocialNetworkAuthUrl(SocialProvider socialProvider) - { - return XsollaAuth.Instance.GetSocialNetworkAuthUrl(socialProvider); - } - #endregion - - #region AccountLinking - public void SignInConsoleAccount(string userId, string platform, Action onSuccess, Action onError) - { - Action successCallback = token => - { - onSuccess?.Invoke(token); - LoginEvent?.Invoke(); - }; - - XsollaAuth.Instance.SignInConsoleAccount(userId, platform, successCallback, onError); - } - #endregion - - #region OAuth2.0 - public void RefreshOAuthToken(Action onSuccess, Action onError) - { - Action successCallback = token => - { - onSuccess?.Invoke(token); - LoginEvent?.Invoke(); - }; - - XsollaAuth.Instance.RefreshOAuthToken(successCallback, onError); - } - - public void ExchangeCodeToToken(string code, Action onSuccessExchange = null, Action onError = null) - { - XsollaAuth.Instance.ExchangeCodeToToken(code, onSuccessExchange, onError); - } - #endregion - - #region Passwordless - public void StartAuthByPhoneNumber(string phoneNumber, string linkUrl, bool sendLink, Action onSuccess, Action onError = null) - { - XsollaAuth.Instance.StartAuthByPhoneNumber(phoneNumber, linkUrl, sendLink, onSuccess, onError); - } - - public void CompleteAuthByPhoneNumber(string phoneNumber, string confirmationCode, string operationId, Action onSuccess, Action onError = null) - { - Action successCallback = token => - { - onSuccess?.Invoke(token); - LoginEvent?.Invoke(); - }; - - XsollaAuth.Instance.CompleteAuthByPhoneNumber(phoneNumber, confirmationCode, operationId, successCallback, onError); - } - - public void StartAuthByEmail(string email, string linkUrl, bool sendLink, Action onSuccess, Action onError = null) - { - XsollaAuth.Instance.StartAuthByEmail(email, linkUrl, sendLink, onSuccess, onError); - } - - public void CompleteAuthByEmail(string email, string confirmationCode, string operationId, Action onSuccess, Action onError = null) - { - Action successCallback = token => - { - onSuccess?.Invoke(token); - LoginEvent?.Invoke(); - }; - - XsollaAuth.Instance.CompleteAuthByEmail(email, confirmationCode, operationId, successCallback, onError); - } - #endregion - } -} diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkAuthLogic.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkAuthLogic.cs.meta deleted file mode 100644 index d9b3ff156..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkAuthLogic.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 78432eafc3b9ef44bb74a919839e5264 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkLoginLogic.cs b/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkLoginLogic.cs deleted file mode 100644 index 6f165684a..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkLoginLogic.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Auth; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Demo -{ - public class SdkLoginLogic : MonoSingleton - { - private const int NETWORKS_CACHE_TIMEOUT = 5; - - [Obsolete("Use SdkAuthLogic instead")] - public event Action RegistrationEvent - { - add => SdkAuthLogic.Instance.RegistrationEvent += value; - remove => SdkAuthLogic.Instance.RegistrationEvent -= value; - } - - [Obsolete("Use SdkAuthLogic instead")] - public event Action LoginEvent - { - add => SdkAuthLogic.Instance.LoginEvent += value; - remove => SdkAuthLogic.Instance.LoginEvent -= value; - } - - [Obsolete("Use SdkAuthLogic instead")] - public event Action UpdateUserInfoEvent - { - add => SdkAuthLogic.Instance.UpdateUserInfoEvent += value; - remove => SdkAuthLogic.Instance.UpdateUserInfoEvent -= value; - } - - [Obsolete("Use SdkUserAccountLogic instead")] - public event Action UpdateUserAttributesEvent - { - add => SdkUserAccountLogic.Instance.UpdateUserAttributesEvent += value; - remove => SdkUserAccountLogic.Instance.UpdateUserAttributesEvent -= value; - } - - [Obsolete("Use SdkUserAccountLogic instead")] - public event Action RemoveUserAttributesEvent - { - add => SdkUserAccountLogic.Instance.RemoveUserAttributesEvent += value; - remove => SdkUserAccountLogic.Instance.RemoveUserAttributesEvent -= value; - } - - #region Token - [Obsolete("Use SdkAuthLogic instead")] - public void ValidateToken(string token, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.ValidateToken(token, onSuccess, onError); - #endregion - - #region User - [Obsolete("Use SdkAuthLogic instead")] - public void GetUserInfo(string token, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.GetUserInfo(token, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void GetUserInfo(string token, bool useCache, Action onSuccess, Action onError = null) - => SdkAuthLogic.Instance.GetUserInfo(token, useCache, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void UpdateUserInfo(string token, UserInfoUpdate info, Action onSuccess, Action onError = null) - => SdkAuthLogic.Instance.UpdateUserInfo(token, info, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void GetPublicInfo(string token, string user, Action onSuccess, Action onError = null) - => SdkUserAccountLogic.Instance.GetPublicInfo(token, user, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void Registration(string username, string password, string email, string state = null, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.Register(username, password, email, state, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void Registration(string username, string password, string email, string state = null, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.Register(username, password, email, state, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void Registration(string username, string password, string email, string state = null, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.Register(username, password, email, state, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void SignIn(string username, string password, bool rememberUser, Action onSuccess, Action onError = null) - => SdkAuthLogic.Instance.SignIn(username, password, rememberUser, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void ResetPassword(string username, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.ResetPassword(username, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void ResendConfirmationLink(string username, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.ResendConfirmationLink(username, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void ChangeUserPhoneNumber(string token, string phoneNumber, Action onSuccess, Action onError) - => SdkUserAccountLogic.Instance.UpdateUserPhoneNumber(token, phoneNumber, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void DeleteUserPhoneNumber(string token, string phoneNumber, Action onSuccess, Action onError) - => SdkUserAccountLogic.Instance.DeleteUserPhoneNumber(token, phoneNumber, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void SearchUsersByNickname(string nickname, Action> onSuccess = null, Action onError = null) - => SdkUserAccountLogic.Instance.SearchUsersByNickname(nickname, onSuccess, onError); - #endregion - - #region Social - [Obsolete("Use SdkAuthLogic instead")] - public void SteamAuth(string appId, string sessionTicket, string state = null, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.SilentAuth("steam", appId, sessionTicket, state, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void AuthViaDeviceID(Core.DeviceType deviceType, string deviceName, string deviceId, string payload = null, string state = null, Action onSuccess = null, Action onError = null) - => SdkAuthLogic.Instance.AuthViaDeviceID(deviceType, deviceName, deviceId, payload, state, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public string GetSocialNetworkAuthUrl(SocialProvider socialProvider) - => SdkAuthLogic.Instance.GetSocialNetworkAuthUrl(socialProvider); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void LinkSocialProvider(SocialProvider socialProvider, Action onSuccess, Action onError = null) - => SdkUserAccountLogic.Instance.LinkSocialProvider(socialProvider, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void PurgeSocialProvidersCache() - => SdkUserAccountLogic.Instance.PurgeSocialProvidersCache(); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void GetLinkedSocialProviders(Action> onSuccess, Action onError = null) - => SdkUserAccountLogic.Instance.GetLinkedSocialProviders(onSuccess, onError); - #endregion - - #region AccountLinking - [Obsolete("Use SdkAuthLogic instead")] - public void SignInConsoleAccount(string userId, string platform, Action onSuccess, Action onError) - => SdkAuthLogic.Instance.SignInConsoleAccount(userId, platform, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void RequestLinkingCode(Action onSuccess, Action onError) - => SdkUserAccountLogic.Instance.RequestLinkingCode(onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void LinkConsoleAccount(string userId, string platform, string confirmationCode, Action onSuccess, Action onError) - => SdkUserAccountLogic.Instance.LinkConsoleAccount(userId, platform, confirmationCode, onSuccess, onError); - #endregion - - #region Attributes - [Obsolete("Use SdkUserAccountLogic instead")] - public void GetUserAttributes(string token, string projectId, UserAttributeType attributeType, - List attributeKeys, string userId, Action> onSuccess, Action onError) - => SdkUserAccountLogic.Instance.GetUserAttributes(token, projectId, attributeType, attributeKeys, userId, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void UpdateUserAttributes(string token, string projectId, List attributes, Action onSuccess, Action onError) - => SdkUserAccountLogic.Instance.UpdateUserAttributes(token, projectId, attributes, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void RemoveUserAttributes(string token, string projectId, List attributeKeys, Action onSuccess, Action onError) - => SdkUserAccountLogic.Instance.RemoveUserAttributes(token, projectId, attributeKeys, onSuccess, onError); - #endregion - - #region OAuth2.0 - [Obsolete("Obsolete and will always return false")] - public bool IsOAuthTokenRefreshInProgress - => false; - - [Obsolete("Use SdkAuthLogic instead")] - public void ExchangeCodeToToken(string code, Action onSuccessExchange = null, Action onError = null) - => SdkAuthLogic.Instance.ExchangeCodeToToken(code, onSuccessExchange, onError); - #endregion - - #region Picture - [Obsolete("Use SdkUserAccountLogic instead")] - public void UploadUserPicture(string token, byte[] pictureData, string boundary, Action onSuccess, Action onError) - => SdkUserAccountLogic.Instance.UploadUserPicture(token, pictureData, boundary, onSuccess, onError); - - [Obsolete("Use SdkUserAccountLogic instead")] - public void DeleteUserPicture(string token, Action onSuccess, Action onError) - => SdkUserAccountLogic.Instance.DeleteUserPicture(token, onSuccess, onError); - #endregion - - #region Passwordless - [Obsolete("Use SdkAuthLogic instead")] - public void StartAuthByPhoneNumber(string phoneNumber, string linkUrl, bool sendLink, Action onSuccess, Action onError = null) - => SdkAuthLogic.Instance.StartAuthByPhoneNumber(phoneNumber, linkUrl, sendLink, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void CompleteAuthByPhoneNumber(string phoneNumber, string confirmationCode, string operationId, Action onSuccess, Action onError = null) - => SdkAuthLogic.Instance.CompleteAuthByPhoneNumber(phoneNumber, confirmationCode, operationId, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void StartAuthByEmail(string email, string linkUrl, bool sendLink, Action onSuccess, Action onError = null) - => SdkAuthLogic.Instance.StartAuthByEmail(email, linkUrl, sendLink, onSuccess, onError); - - [Obsolete("Use SdkAuthLogic instead")] - public void CompleteAuthByEmail(string email, string confirmationCode, string operationId, Action onSuccess, Action onError = null) - => SdkAuthLogic.Instance.CompleteAuthByEmail(email, confirmationCode, operationId, onSuccess, onError); - #endregion - } -} diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkLoginLogic.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkLoginLogic.cs.meta deleted file mode 100644 index fadbeba05..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkLoginLogic.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d97a9acc7a3662d44931619bdef99788 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkUserAccountLogic.cs b/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkUserAccountLogic.cs deleted file mode 100644 index b7bc2db19..000000000 --- a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkUserAccountLogic.cs +++ /dev/null @@ -1,209 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Demo -{ - public class SdkUserAccountLogic : MonoSingleton - { - private const int NETWORKS_CACHE_TIMEOUT = 5; - - public event Action UpdateUserAttributesEvent; - public event Action RemoveUserAttributesEvent; - - #region User - public void GetPublicInfo(string token, string user, Action onSuccess, Action onError = null) - { - XsollaUserAccount.Instance.GetPublicInfo(token, user, onSuccess, onError = null); - } - - public void UpdateUserPhoneNumber(string token, string phoneNumber, Action onSuccess, Action onError) - { - XsollaUserAccount.Instance.UpdateUserPhoneNumber(token, phoneNumber, onSuccess, onError); - } - - public void DeleteUserPhoneNumber(string token, string phoneNumber, Action onSuccess, Action onError) - { - XsollaUserAccount.Instance.DeleteUserPhoneNumber(token, phoneNumber, onSuccess, onError); - } - - public void SearchUsersByNickname(string nickname, Action> onSuccess = null, Action onError = null) - { - nickname = Uri.EscapeDataString(nickname); - - XsollaUserAccount.Instance.SearchUsers(Token.Instance, nickname, 0, 20, - onSuccess: users => - { - onSuccess?.Invoke(users.users.Where(u => !u.is_me).Select(u => - { - var result = new FriendModel - { - Id = u.user_id, - AvatarUrl = u.avatar, - Nickname = u.nickname, - Tag = u.tag - }; - var user = UserFriends.Instance.GetUserById(result.Id); - result.Status = user?.Status ?? UserOnlineStatus.Unknown; - result.Relationship = user?.Relationship ?? UserRelationship.Unknown; - return result; - }).ToList()); - }, - onError: onError); - } - #endregion - - #region Social - public void LinkSocialProvider(SocialProvider socialProvider, Action onSuccess, Action onError = null) - { - if (!EnvironmentDefiner.IsStandaloneOrEditor) - { - var errorMessage = "LinkSocialProvider: This functionality is not supported elswere except Editor and Standalone build"; - Debug.LogError(errorMessage); - onError?.Invoke(new Error(ErrorType.MethodIsNotAllowed, errorMessage: errorMessage)); - return; - } - - Action urlCallback = url => - { - var browser = BrowserHelper.Instance.InAppBrowser; - if (browser == null) - { - var message = "LinkSocialProvider: Can not obtain in-built browser"; - Debug.LogError(message); - onError?.Invoke(new Error(ErrorType.MethodIsNotAllowed, errorMessage: message)); - return; - } - - browser.Open(url); - browser.AddInitHandler(() => - { - browser.AddUrlChangeHandler(newUrl => - { - Debug.Log($"URL = {newUrl}"); - - if (ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.token, out _)) - { - browser.Close(); - HotkeyCoroutine.Unlock(); - onSuccess?.Invoke(socialProvider); - return; - } - - if (ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.error_code, out string errorCode) && - ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.error_description, out string errorDescription)) - { - browser.Close(); - HotkeyCoroutine.Unlock(); - onError?.Invoke(new Error(statusCode: errorCode, errorMessage: errorDescription)); - } - }); - }); - }; - - XsollaUserAccount.Instance.LinkSocialProvider(socialProvider, urlCallback, onError); - } - - private List _networksCache; - private DateTime _networksCacheTime; - private bool _networksCacheInProgress; - - public void PurgeSocialProvidersCache() => _networksCache = null; - - public void GetLinkedSocialProviders(Action> onSuccess, Action onError = null) - { - if (_networksCacheInProgress) - { - StartCoroutine(WaitLinkedSocialProviders(onSuccess)); - return; - } - if ((DateTime.Now - _networksCacheTime).Seconds > NETWORKS_CACHE_TIMEOUT || _networksCache == null) - { - _networksCacheInProgress = true; - XsollaUserAccount.Instance.GetLinkedSocialProviders(networks => - { - _networksCache = networks; - _networksCacheTime = DateTime.Now; - onSuccess?.Invoke(_networksCache); - _networksCacheInProgress = false; - }, error => - { - if (_networksCache == null) - _networksCache = new List(); - onError?.Invoke(error); - _networksCacheInProgress = false; - }); - } - else - { - onSuccess?.Invoke(_networksCache); - } - } - - private IEnumerator WaitLinkedSocialProviders(Action> onSuccess) - { - yield return new WaitWhile(() => _networksCacheInProgress); - onSuccess?.Invoke(_networksCache); - } - - #endregion - - #region AccountLinking - public void RequestLinkingCode(Action onSuccess, Action onError) - { - XsollaUserAccount.Instance.RequestLinkingCode(onSuccess, onError); - } - - public void LinkConsoleAccount(string userId, string platform, string confirmationCode, Action onSuccess, Action onError) - { - XsollaUserAccount.Instance.LinkConsoleAccount(userId, platform, confirmationCode, onSuccess, onError); - } - #endregion - - #region Attributes - public void GetUserAttributes(string token, string projectId, UserAttributeType attributeType, - List attributeKeys, string userId, Action> onSuccess, Action onError) - { - XsollaUserAccount.Instance.GetUserAttributes(token, projectId, attributeType, attributeKeys, userId, onSuccess, onError); - } - - public void UpdateUserAttributes(string token, string projectId, List attributes, Action onSuccess, Action onError) - { - Action successCallback = () => - { - onSuccess?.Invoke(); - UpdateUserAttributesEvent?.Invoke(); - }; - - XsollaUserAccount.Instance.UpdateUserAttributes(token, projectId, attributes, successCallback, onError); - } - - public void RemoveUserAttributes(string token, string projectId, List attributeKeys, Action onSuccess, Action onError) - { - Action successCallback = () => - { - onSuccess?.Invoke(); - RemoveUserAttributesEvent?.Invoke(); - }; - - XsollaUserAccount.Instance.RemoveUserAttributes(token, projectId, attributeKeys, successCallback, onError); - } - #endregion - - #region Picture - public void UploadUserPicture(string token, byte[] pictureData, string boundary, Action onSuccess, Action onError) - { - XsollaUserAccount.Instance.UploadUserPicture(token, pictureData, boundary, onSuccess, onError); - } - - public void DeleteUserPicture(string token, Action onSuccess, Action onError) - { - XsollaUserAccount.Instance.DeleteUserPicture(token, onSuccess, onError); - } - #endregion - } -} diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/UserAccountLogic.cs b/Assets/Xsolla.Demo/Login/Scripts/Sdk/UserAccountLogic.cs new file mode 100644 index 000000000..1b14c35bc --- /dev/null +++ b/Assets/Xsolla.Demo/Login/Scripts/Sdk/UserAccountLogic.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Xsolla.Core; +using Xsolla.UserAccount; + +namespace Xsolla.Demo +{ + public class UserAccountLogic : MonoSingleton + { + private const int NETWORKS_CACHE_TIMEOUT = 5; + + #region Social + + private bool IsEditorOrStandalone + { + get + { + if (Application.isEditor) + return true; + + switch (Application.platform) + { + case RuntimePlatform.LinuxEditor: + case RuntimePlatform.OSXEditor: + case RuntimePlatform.WindowsEditor: + return true; + } + + return false; + } + } + + public void LinkSocialProvider(SocialProvider socialProvider, Action onSuccess, Action onError = null) + { + if (!IsEditorOrStandalone) + { + var errorMessage = "LinkSocialProvider: This functionality is not supported elswere except Editor and Standalone build"; + XDebug.LogError(errorMessage); + onError?.Invoke(new Error(ErrorType.MethodIsNotAllowed, errorMessage: errorMessage)); + return; + } + + Action urlCallback = url => + { + var browser = XsollaWebBrowser.InAppBrowser; + if (browser == null) + { + var message = "LinkSocialProvider: Can not obtain in-built browser"; + XDebug.LogError(message); + onError?.Invoke(new Error(ErrorType.MethodIsNotAllowed, errorMessage: message)); + return; + } + + browser.Open(url.url); + browser.AddInitHandler(() => + { + browser.AddUrlChangeHandler(newUrl => + { + XDebug.Log($"URL = {newUrl}"); + + if (ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.token, out _)) + { + browser.Close(); + HotkeyCoroutine.Unlock(); + onSuccess?.Invoke(socialProvider); + return; + } + + if (ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.error_code, out string errorCode) && + ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.error_description, out string errorDescription)) + { + browser.Close(); + HotkeyCoroutine.Unlock(); + onError?.Invoke(new Error(statusCode: errorCode, errorMessage: errorDescription)); + } + }); + }); + }; + + XsollaUserAccount.LinkSocialProvider(socialProvider, urlCallback, onError); + } + + private List _networksCache; + private DateTime _networksCacheTime; + private bool _networksCacheInProgress; + + public void PurgeSocialProvidersCache() => _networksCache = null; + + public void GetLinkedSocialProviders(Action> onSuccess, Action onError = null) + { + if (_networksCacheInProgress) + { + StartCoroutine(WaitLinkedSocialProviders(onSuccess)); + return; + } + + if ((DateTime.Now - _networksCacheTime).Seconds > NETWORKS_CACHE_TIMEOUT || _networksCache == null) + { + _networksCacheInProgress = true; + XsollaUserAccount.GetLinkedSocialProviders(networks => + { + _networksCache = networks.items; + _networksCacheTime = DateTime.Now; + onSuccess?.Invoke(_networksCache); + _networksCacheInProgress = false; + }, error => + { + if (_networksCache == null) + _networksCache = new List(); + onError?.Invoke(error); + _networksCacheInProgress = false; + }); + } + else + { + onSuccess?.Invoke(_networksCache); + } + } + + private IEnumerator WaitLinkedSocialProviders(Action> onSuccess) + { + yield return new WaitWhile(() => _networksCacheInProgress); + onSuccess?.Invoke(_networksCache); + } + + #endregion + } +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkUserAccountLogic.cs.meta b/Assets/Xsolla.Demo/Login/Scripts/Sdk/UserAccountLogic.cs.meta similarity index 100% rename from Assets/Xsolla.Demo/Login/Scripts/Sdk/SdkUserAccountLogic.cs.meta rename to Assets/Xsolla.Demo/Login/Scripts/Sdk/UserAccountLogic.cs.meta diff --git a/Assets/Xsolla.Demo/Store/Scripts/Cart/CartDiscountUI.cs b/Assets/Xsolla.Demo/Store/Scripts/Cart/CartDiscountUI.cs index da4c62803..196f77f70 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Cart/CartDiscountUI.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Cart/CartDiscountUI.cs @@ -1,5 +1,6 @@ using UnityEngine; using UnityEngine.UI; +using Xsolla.Core; namespace Xsolla.Demo { @@ -10,7 +11,7 @@ public class CartDiscountUI : MonoBehaviour public void Initialize(float discount) { - Debug.Log("Discount = " + discount); + XDebug.Log("Discount = " + discount); discountAmount.text = $"- {PriceFormatter.FormatPrice(discount)}"; } } diff --git a/Assets/Xsolla.Demo/Store/Scripts/Cart/CartItemUI.cs b/Assets/Xsolla.Demo/Store/Scripts/Cart/CartItemUI.cs index f58b7dc10..451fe1ef4 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Cart/CartItemUI.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Cart/CartItemUI.cs @@ -93,19 +93,17 @@ public void Initialize(UserCartItem cartItem) { if (!string.IsNullOrEmpty(_cartItem.ImageUrl)) { - ImageLoader.Instance.GetImageAsync(_cartItem.ImageUrl, LoadImageCallback); + ImageLoader.LoadSprite(_cartItem.ImageUrl, image => + { + if (itemImage) + itemImage.sprite = image; + }); } else { - Debug.LogError($"Cart item with sku = '{_cartItem.Sku}' without image!"); + XDebug.LogError($"Cart item with sku = '{_cartItem.Sku}' without image!"); } } } - - void LoadImageCallback(string url, Sprite image) - { - if (itemImage) - itemImage.sprite = image; - } } } diff --git a/Assets/Xsolla.Demo/Store/Scripts/Cart/UserCart.cs b/Assets/Xsolla.Demo/Store/Scripts/Cart/UserCart.cs index fb4fbe127..7b8156881 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Cart/UserCart.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Cart/UserCart.cs @@ -109,9 +109,9 @@ public void Purchase(Action onSuccess = null, Action onError = null) var items = GetItems(); if (items.Any(x => x.Item.RealPrice != null)) - DemoShop.Instance.PurchaseCart(items, handleSuccess, onError); + StoreLogic.PurchaseCart(items, handleSuccess, onError); else - DemoShop.Instance.PurchaseFreeCart(items, handleSuccess, onError); + StoreLogic.PurchaseFreeCart(items, handleSuccess, onError); } } } diff --git a/Assets/Xsolla.Demo/Store/Scripts/DemoController/DemoController.Store.cs b/Assets/Xsolla.Demo/Store/Scripts/DemoController/DemoController.Store.cs index b54bfbbe5..84448f067 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/DemoController/DemoController.Store.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/DemoController/DemoController.Store.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; +using UnityEngine; using Xsolla.Core; -using Xsolla.Store; namespace Xsolla.Demo { @@ -36,13 +36,9 @@ private void StartLoadItemImages(List items) items.ForEach(i => { if (!string.IsNullOrEmpty(i.ImageUrl)) - { - ImageLoader.Instance.GetImageAsync(i.ImageUrl, null); - } + ImageLoader.LoadSprite(i.ImageUrl, null); else - { - Debug.LogError($"Catalog item with sku = '{i.Sku}' without image!"); - } + XDebug.LogError($"Catalog item with sku = '{i.Sku}' without image!"); }); } } diff --git a/Assets/Xsolla.Demo/Store/Scripts/DemoTypeMarker.meta b/Assets/Xsolla.Demo/Store/Scripts/DemoTypeMarker.meta deleted file mode 100644 index a8759df8f..000000000 --- a/Assets/Xsolla.Demo/Store/Scripts/DemoTypeMarker.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: aae86cf1ff775d84c930d9c2dc31f59d -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Store/Scripts/Items/InventoryItemUI.subscriptionRenewal.cs b/Assets/Xsolla.Demo/Store/Scripts/Items/InventoryItemUI.subscriptionRenewal.cs index 1e76d74b3..605fb02c3 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Items/InventoryItemUI.subscriptionRenewal.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Items/InventoryItemUI.subscriptionRenewal.cs @@ -18,9 +18,9 @@ partial void AttachRenewSubscriptionHandler() return; if (subscriptionItem.VirtualPrice == null) - renewSubscriptionButton.onClick = () => DemoShop.Instance.PurchaseForRealMoney(subscriptionItem); + renewSubscriptionButton.onClick = () => StoreLogic.PurchaseForRealMoney(subscriptionItem, null, null); else - renewSubscriptionButton.onClick = () => DemoShop.Instance.PurchaseForVirtualCurrency(subscriptionItem); + renewSubscriptionButton.onClick = () => StoreLogic.PurchaseForVirtualCurrency(subscriptionItem, null, null); } } } \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Store/Scripts/Items/StoreItemUI.cs b/Assets/Xsolla.Demo/Store/Scripts/Items/StoreItemUI.cs index e3d7da654..195505d0f 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Items/StoreItemUI.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Items/StoreItemUI.cs @@ -4,7 +4,7 @@ using UnityEngine; using UnityEngine.UI; using Xsolla.Core; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { @@ -43,7 +43,7 @@ public void Initialize(CatalogItemModel virtualItem) itemPriceVcText.gameObject.SetActive(false); expirationTimeObject.SetActive(false); freePrice.SetActive(false); - + _itemInformation = virtualItem; if (virtualItem.VirtualPrice != null) @@ -128,13 +128,13 @@ private void InitializeVcImage(CatalogItemModel virtualItem) var currency = UserCatalog.Instance.VirtualCurrencies.First(vc => vc.Sku.Equals(currencySku)); if (!string.IsNullOrEmpty(currency.ImageUrl)) - ImageLoader.Instance.GetImageAsync(currency.ImageUrl, (_, sprite) => + ImageLoader.LoadSprite(currency.ImageUrl, sprite => { if (itemPriceVcImage) itemPriceVcImage.sprite = sprite; }); else - Debug.LogError($"Virtual currency item with sku = '{virtualItem.Sku}' without image!"); + XDebug.LogError($"Virtual currency item with sku = '{virtualItem.Sku}' without image!"); })); } @@ -164,16 +164,16 @@ private void InitializeRealPrice(CatalogItemModel virtualItem) EnableCheckout(isSelected); }; - + var realPrice = virtualItem.RealPrice; if (realPrice == null) { freePrice.SetActive(true); return; } - + EnablePrice(false); - + var valuePair = realPrice.Value; var currency = valuePair.Key; var price = valuePair.Value; @@ -186,7 +186,7 @@ private void InitializeRealPrice(CatalogItemModel virtualItem) var priceWithoutDiscount = priceWithoutDiscountContainer.Value.Value; if (priceWithoutDiscount == price) return; - + itemPriceWithoutDiscount.text = PriceFormatter.FormatPrice(currency, priceWithoutDiscount); itemPriceWithoutDiscount.gameObject.SetActive(true); } @@ -195,7 +195,7 @@ private void InitializeVirtualItem(CatalogItemModel virtualItem) { if (string.IsNullOrEmpty(virtualItem.Name)) { - Debug.LogError($"Try initialize item with sku = {virtualItem.Sku} without name!"); + XDebug.LogError($"Try initialize item with sku = {virtualItem.Sku} without name!"); virtualItem.Name = virtualItem.Sku; } @@ -204,19 +204,19 @@ private void InitializeVirtualItem(CatalogItemModel virtualItem) gameObject.name = "Item_" + virtualItem.Name.Replace(" ", ""); if (!string.IsNullOrEmpty(virtualItem.ImageUrl)) { - ImageLoader.Instance.GetImageAsync(virtualItem.ImageUrl, LoadImageCallback); + ImageLoader.LoadSprite(virtualItem.ImageUrl, LoadImageCallback); } else { - Debug.LogError($"Virtual item item with sku = '{virtualItem.Sku}' without image!"); + XDebug.LogError($"Virtual item item with sku = '{virtualItem.Sku}' without image!"); } } - private void LoadImageCallback(string url, Sprite image) + private void LoadImageCallback(Sprite image) { if (!itemImage) return; - + loadingCircle.SetActive(false); itemImage.gameObject.SetActive(true); itemImage.sprite = image; @@ -235,7 +235,7 @@ private void InitExpirationTime(CatalogItemModel virtualItem) var subscription = UserCatalog.Instance.Subscriptions.First(s => s.Sku.Equals(virtualItem.Sku)); if (subscription == null) { - Debug.LogError($"Something went wrong... Can not find subscription item with sku = '{virtualItem.Sku}'!"); + XDebug.LogError($"Something went wrong... Can not find subscription item with sku = '{virtualItem.Sku}'!"); return; } @@ -248,11 +248,11 @@ private void AttachBuyButtonHandler(CatalogItemModel virtualItem) Action onPurchased = item => { StartCoroutine(WaitInventoryUpdate(() => CheckIfItemPurchased(item))); }; if (virtualItem.VirtualPrice != null) - buyButton.onClick = () => DemoShop.Instance.PurchaseForVirtualCurrency(virtualItem, onPurchased); + buyButton.onClick = () => StoreLogic.PurchaseForVirtualCurrency(virtualItem, onPurchased, null); else if (virtualItem.Price != null) - buyButton.onClick = () => DemoShop.Instance.PurchaseForRealMoney(virtualItem, onPurchased); + buyButton.onClick = () => StoreLogic.PurchaseForRealMoney(virtualItem, onPurchased, null); else - buyButton.onClick = () => DemoShop.Instance.PurchaseFreeItem(virtualItem, onPurchased); + buyButton.onClick = () => StoreLogic.PurchaseFreeItem(virtualItem, onPurchased, null); } private void AttachPreviewButtonHandler(CatalogItemModel virtualItem) @@ -279,4 +279,4 @@ private string ShortenDescription(string input, int limit) return result; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Store/Scripts/MobileUIUtils/StoreItemFullscreenView.cs b/Assets/Xsolla.Demo/Store/Scripts/MobileUIUtils/StoreItemFullscreenView.cs index f29853e80..53fb3d259 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/MobileUIUtils/StoreItemFullscreenView.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/MobileUIUtils/StoreItemFullscreenView.cs @@ -1,4 +1,5 @@ using UnityEngine; +using Xsolla.Core; namespace Xsolla.Demo { @@ -13,7 +14,7 @@ public static void ShowItem(CatalogItemModel itemModel) { if (_instance == null) { - Debug.LogError("Instance not set"); + XDebug.LogError("Instance not set"); return; } diff --git a/Assets/Xsolla.Demo/Store/Scripts/MobileUIUtils/StoreItemToFullscreen.cs b/Assets/Xsolla.Demo/Store/Scripts/MobileUIUtils/StoreItemToFullscreen.cs index 48c72d119..d20287c3a 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/MobileUIUtils/StoreItemToFullscreen.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/MobileUIUtils/StoreItemToFullscreen.cs @@ -1,5 +1,5 @@ using UnityEngine; -using Xsolla.Core.Popup; +using Xsolla.Demo.Popup; namespace Xsolla.Demo { diff --git a/Assets/Xsolla.Demo/Store/Scripts/PageControllers/CartMenuController.cs b/Assets/Xsolla.Demo/Store/Scripts/PageControllers/CartMenuController.cs index e308155b4..6e5de2baa 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/PageControllers/CartMenuController.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/PageControllers/CartMenuController.cs @@ -1,7 +1,8 @@ using System.Collections.Generic; using System.Linq; using UnityEngine; -using Xsolla.Core.Popup; +using Xsolla.Core; +using Xsolla.Demo.Popup; using Xsolla.UIBuilder; namespace Xsolla.Demo @@ -24,7 +25,7 @@ protected virtual void Start() if (ItemPrefab == null || itemsContainer == null || cartControls == null) { var message = "Cart prefab is broken. Some fields is null."; - Debug.LogError(message); + XDebug.LogError(message); PopupFactory.Instance.CreateError() .SetMessage(message) .SetCallback(() => DemoController.Instance.SetState(MenuState.Main)); diff --git a/Assets/Xsolla.Demo/Store/Scripts/Popups/BundlePreviewPopup.cs b/Assets/Xsolla.Demo/Store/Scripts/Popups/BundlePreviewPopup.cs index 50e4fbec4..166bb9631 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Popups/BundlePreviewPopup.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Popups/BundlePreviewPopup.cs @@ -2,9 +2,10 @@ using System.Linq; using UnityEngine; using UnityEngine.UI; +using Xsolla.Core; using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public class BundlePreviewPopup : MonoBehaviour, IBundlePreviewPopup { @@ -30,18 +31,18 @@ public IBundlePreviewPopup SetBundleInfo(CatalogBundleItemModel bundle) { bundleName.text = bundle.Name; - if(bundleDescription != null) + if (bundleDescription != null) bundleDescription.text = bundle.Description; bundleInfo.text = $"This bundle includes '{bundle.Content.Count}' item{(bundle.Content.Count > 1 ? "s" : "")}:"; if (!string.IsNullOrEmpty(bundle.ImageUrl)) { - ImageLoader.Instance.GetImageAsync(bundle.ImageUrl, LoadImageCallback); + ImageLoader.LoadSprite(bundle.ImageUrl, LoadImageCallback); } else { - Debug.LogError($"Bundle with sku = '{bundle.Sku}' has no image!"); + XDebug.LogError($"Bundle with sku = '{bundle.Sku}' has no image!"); } if (bundle.VirtualPrice != null) @@ -97,7 +98,7 @@ private void InitializeRealPrice(CatalogBundleItemModel bundle) var realPrice = bundle.RealPrice; if (realPrice == null) { - Debug.LogError($"Bundle with sku = {bundle.Sku} has no price!"); + XDebug.LogError($"Bundle with sku = {bundle.Sku} has no price!"); return; } @@ -110,7 +111,7 @@ private void InitializeRealPrice(CatalogBundleItemModel bundle) var contentRealPrice = bundle.ContentRealPrice; if (contentRealPrice == null) { - Debug.LogError($"Bundle with sku = {bundle.Sku} has no content price!"); + XDebug.LogError($"Bundle with sku = {bundle.Sku} has no content price!"); return; } @@ -121,11 +122,11 @@ private void InitializeRealPrice(CatalogBundleItemModel bundle) bundlePriceWithoutDiscount.text = PriceFormatter.FormatPrice(contentCurrency, contentPrice); } - private void LoadImageCallback(string url, Sprite sprite) + private void LoadImageCallback(Sprite sprite) { if (!bundleImage) return; - + loadingCircle.SetActive(false); bundleImage.gameObject.SetActive(true); bundleImage.sprite = sprite; @@ -137,7 +138,7 @@ private void InitializeVcImages(CatalogBundleItemModel bundle) var currency = UserCatalog.Instance.VirtualCurrencies.First(vc => vc.Sku.Equals(currencySku)); if (!string.IsNullOrEmpty(currency.ImageUrl)) { - ImageLoader.Instance.GetImageAsync(currency.ImageUrl, (_, sprite) => + ImageLoader.LoadSprite(currency.ImageUrl, sprite => { if (bundlePriceVcImage) { @@ -148,7 +149,7 @@ private void InitializeVcImages(CatalogBundleItemModel bundle) } else { - Debug.LogError($"Bundle with sku = '{bundle.Sku}' virtual currency price has no image!"); + XDebug.LogError($"Bundle with sku = '{bundle.Sku}' virtual currency price has no image!"); } } @@ -164,7 +165,7 @@ private void AttachBuyButtonHandler(CatalogItemModel virtualItem) buyButton.onClick = () => { Destroy(gameObject, 0.001F); - DemoShop.Instance.PurchaseForRealMoney(virtualItem); + StoreLogic.PurchaseForRealMoney(virtualItem, null, null); }; } else @@ -172,9 +173,9 @@ private void AttachBuyButtonHandler(CatalogItemModel virtualItem) buyButton.onClick = () => { Destroy(gameObject, 0.001F); - DemoShop.Instance.PurchaseForVirtualCurrency(virtualItem); + StoreLogic.PurchaseForVirtualCurrency(virtualItem, null, null); }; } } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Store/Scripts/Popups/IBundlePreviewPopup.cs b/Assets/Xsolla.Demo/Store/Scripts/Popups/IBundlePreviewPopup.cs index 435b3bfb5..96f8e876b 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Popups/IBundlePreviewPopup.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Popups/IBundlePreviewPopup.cs @@ -1,6 +1,6 @@ using Xsolla.Demo; -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public interface IBundlePreviewPopup { diff --git a/Assets/Xsolla.Demo/Store/Scripts/Popups/PopupFactory.Store.cs b/Assets/Xsolla.Demo/Store/Scripts/Popups/PopupFactory.Store.cs index 8e0fd5360..ced1483bc 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Popups/PopupFactory.Store.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Popups/PopupFactory.Store.cs @@ -1,4 +1,4 @@ -namespace Xsolla.Core.Popup +namespace Xsolla.Demo.Popup { public partial class PopupFactory : MonoSingleton { diff --git a/Assets/Xsolla.Demo/Store/Scripts/RestrictedPaymentAllower.cs b/Assets/Xsolla.Demo/Store/Scripts/RestrictedPaymentAllower.cs deleted file mode 100644 index 941c1eb1d..000000000 --- a/Assets/Xsolla.Demo/Store/Scripts/RestrictedPaymentAllower.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Xsolla.Demo -{ - public class RestrictedPaymentAllower - { - public Action OnRestrictedPayment; - public Action OnAllowed; - } -} diff --git a/Assets/Xsolla.Demo/Store/Scripts/RestrictedPaymentAllower.cs.meta b/Assets/Xsolla.Demo/Store/Scripts/RestrictedPaymentAllower.cs.meta deleted file mode 100644 index 03346dd3b..000000000 --- a/Assets/Xsolla.Demo/Store/Scripts/RestrictedPaymentAllower.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 2b6024f0c1582734aa9da8ae47ff8f4f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Store/Scripts/DemoTypeMarker/DemoMarker.Store.cs b/Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoMarker.Store.cs similarity index 100% rename from Assets/Xsolla.Demo/Store/Scripts/DemoTypeMarker/DemoMarker.Store.cs rename to Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoMarker.Store.cs diff --git a/Assets/Xsolla.Demo/Store/Scripts/DemoTypeMarker/DemoMarker.Store.cs.meta b/Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoMarker.Store.cs.meta similarity index 100% rename from Assets/Xsolla.Demo/Store/Scripts/DemoTypeMarker/DemoMarker.Store.cs.meta rename to Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoMarker.Store.cs.meta diff --git a/Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoShop.cs b/Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoShop.cs deleted file mode 100644 index 0ebf21fd6..000000000 --- a/Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoShop.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Core; -using Xsolla.Core.Popup; - -namespace Xsolla.Demo -{ - public class DemoShop : MonoSingleton - { - public void PurchaseFreeItem(CatalogItemModel item, Action onSuccess = null, Action onError = null) - { - SdkPurchaseLogic.Instance.PurchaseFreeItem(item, - OnSuccessPurchase(onSuccess), - OnPurchaseError(onError)); - } - public void PurchaseForRealMoney(CatalogItemModel item, Action onSuccess = null, Action onError = null) - { - var restrictedPaymentAllower = GenerateAllower(); - SdkPurchaseLogic.Instance.PurchaseForRealMoney(item, - restrictedPaymentAllower, - OnSuccessPurchase(onSuccess), - OnPurchaseError(onError)); - } - - public void PurchaseForVirtualCurrency(CatalogItemModel item, Action onSuccess = null, Action onError = null, - bool isConfirmationRequired = true, bool isShowResultToUser = true) - { - var onConfirmation = new Action(() => - { - var isPurchaseComplete = false; - PopupFactory.Instance.CreateWaiting().SetCloseCondition(() => isPurchaseComplete); - - SdkPurchaseLogic.Instance.PurchaseForVirtualCurrency(item, - itemModel => - { - isPurchaseComplete = true; - OnSuccessPurchase(onSuccess, isShowResultToUser)?.Invoke(itemModel); - }, - error => - { - isPurchaseComplete = true; - OnPurchaseError(onError)?.Invoke(error); - }); - }); - - if (isConfirmationRequired) - StoreDemoPopup.ShowConfirm(onConfirmation); - else - onConfirmation.Invoke(); - } - - public void PurchaseCart(List items, Action> onSuccess, Action onError = null, bool isShowResultToUser = true) - { - var restrictedPaymentAllower = GenerateAllower(); - - Action> onSuccessPurchase = purchasedItems => - { - if (isShowResultToUser) - CompletePurchase(popupCallback: () => onSuccess?.Invoke(purchasedItems)); - else - { - UserInventory.Instance.Refresh(onError: StoreDemoPopup.ShowError); - onSuccess?.Invoke(purchasedItems); - } - }; - - SdkPurchaseLogic.Instance.PurchaseCart(items, - restrictedPaymentAllower, - onSuccessPurchase, - OnPurchaseError(onError)); - } - - public void PurchaseFreeCart(List items, Action> onSuccess, Action onError = null, bool isShowResultToUser = true) - { - Action> onSuccessPurchase = purchasedItems => - { - if (isShowResultToUser) - CompletePurchase(popupCallback: () => onSuccess?.Invoke(purchasedItems)); - else - { - UserInventory.Instance.Refresh(onError: StoreDemoPopup.ShowError); - onSuccess?.Invoke(purchasedItems); - } - }; - - SdkPurchaseLogic.Instance.PurchaseFreeCart(items, - onSuccessPurchase, - OnPurchaseError(onError)); - } - - private RestrictedPaymentAllower GenerateAllower() - { - var restrictedPaymentAllower = new RestrictedPaymentAllower(); - restrictedPaymentAllower.OnRestrictedPayment = _ => - { - PopupFactory.Instance.CreateConfirmation() - .SetMessage("This payment method is not available for in-game browser. Open browser app to continue purchase?") - .SetConfirmCallback(() => restrictedPaymentAllower.OnAllowed?.Invoke(true)) - .SetCancelCallback(() => restrictedPaymentAllower.OnAllowed?.Invoke(false)); - }; - - return restrictedPaymentAllower; - } - - private Action OnSuccessPurchase(Action onSuccess, bool isShowResult = true) - { - return purchasedItem => - { - CompletePurchase(purchasedItem, isShowResultToUser: isShowResult); - onSuccess?.Invoke(purchasedItem); - }; - } - - private Action OnPurchaseError(Action onError) - { - return error => - { - StoreDemoPopup.ShowError(error); - onError?.Invoke(error); - }; - } - - private static void CompletePurchase(CatalogItemModel item = null, bool isShowResultToUser = true, Action popupCallback = null) - { - UserInventory.Instance.Refresh(onError: StoreDemoPopup.ShowError); - - if (!isShowResultToUser) - return; - - Action callback = () => - { - if (item != null) - StoreDemoPopup.ShowSuccess($"You have purchased '{item.Name}'", popupCallback); - else - StoreDemoPopup.ShowSuccess(null, popupCallback); - }; - - var inAppBrowser = BrowserHelper.Instance.InAppBrowser; - if (inAppBrowser != null && inAppBrowser.IsOpened) - inAppBrowser.AddCloseHandler(callback); - else - callback.Invoke(); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Store/Scripts/Sdk/SdkPurchaseLogic.cs b/Assets/Xsolla.Demo/Store/Scripts/Sdk/SdkPurchaseLogic.cs deleted file mode 100644 index 59adb55cb..000000000 --- a/Assets/Xsolla.Demo/Store/Scripts/Sdk/SdkPurchaseLogic.cs +++ /dev/null @@ -1,198 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Xsolla.Cart; -using Xsolla.Catalog; -using Xsolla.Core; -using Xsolla.Orders; - -namespace Xsolla.Demo -{ - public class SdkPurchaseLogic : MonoSingleton - { - public event Action PurchaseForFreeEvent; - public event Action PurchaseForRealMoneyEvent; - public event Action PurchaseForVirtualCurrencyEvent; - public event Action> PurchaseCartEvent; - - public void PurchaseFreeItem(CatalogItemModel item, Action onSuccess = null, Action onError = null) - { - XsollaCatalog.Instance.CreateOrderWithSpecifiedFreeItem( - XsollaSettings.StoreProjectId, - item.Sku, - onSuccess: i => - { - onSuccess?.Invoke(item); - PurchaseForFreeEvent?.Invoke(item); - }, - onError); - } - - public void PurchaseForRealMoney(CatalogItemModel item, RestrictedPaymentAllower restrictedPaymentAllower = null, Action onSuccess = null, Action onError = null) - { - XsollaCatalog.Instance.PurchaseItem(XsollaSettings.StoreProjectId, item.Sku, - onSuccess: data => - { - XsollaOrders.Instance.OpenPurchaseUi(data, - forcePlatformBrowser: false, - onRestrictedPaymentMethod: methodId => - { - HandleRestrictedPaymentMethod(data, methodId, restrictedPaymentAllower, - onSuccess: () => - { - onSuccess?.Invoke(item); - }, - onError); - }); - - OrderTracking.Instance.AddOrderForTracking(XsollaSettings.StoreProjectId, data.order_id, () => - { - onSuccess?.Invoke(item); - PurchaseForRealMoneyEvent?.Invoke(item); - - if (BrowserHelper.Instance.InAppBrowser?.IsOpened ?? false) - BrowserHelper.Instance.Close(); - }, - onError); - }, - onError, customHeaders: GenerateCustomHeaders()); - } - - public void PurchaseForVirtualCurrency(CatalogItemModel item, Action onSuccess = null, Action onError = null) - { - XsollaCatalog.Instance.PurchaseItemForVirtualCurrency( - XsollaSettings.StoreProjectId, - item.Sku, - item.VirtualPrice?.Key, - data => - { - OrderTracking.Instance.AddVirtualCurrencyOrderForTracking( - XsollaSettings.StoreProjectId, - data.order_id, - () => - { - onSuccess?.Invoke(item); - PurchaseForVirtualCurrencyEvent?.Invoke(item); - }, - onError - ); - }, - onError, customHeaders: GenerateCustomHeaders()); - } - - public void PurchaseCart(List items, RestrictedPaymentAllower restrictedPaymentAllower = null, Action> onSuccess = null, Action onError = null) - { - if (!items.Any()) - { - var error = new Error(errorMessage: "Cart is empty"); - onError?.Invoke(error); - return; - } - - XsollaCart.Instance.GetCartItems(XsollaSettings.StoreProjectId, newCart => - { - XsollaCart.Instance.ClearCart(XsollaSettings.StoreProjectId, newCart.cart_id, () => - { - var cartItems = items.Select(i => new CartFillItem - { - sku = i.Sku, - quantity = i.Quantity - }).ToList(); - - XsollaCart.Instance.FillCart(XsollaSettings.StoreProjectId, cartItems, () => - { - XsollaCart.Instance.PurchaseCart(XsollaSettings.StoreProjectId, newCart.cart_id, data => - { - XsollaOrders.Instance.OpenPurchaseUi(data, false, methodId => - { - HandleRestrictedPaymentMethod(data, methodId, restrictedPaymentAllower, - onSuccess: () => - { - onSuccess?.Invoke(items); - }, - onError); - - }); - - OrderTracking.Instance.AddOrderForTracking(XsollaSettings.StoreProjectId, data.order_id, - onSuccess: () => - { - onSuccess?.Invoke(items); - PurchaseCartEvent?.Invoke(items); - - if (BrowserHelper.Instance.InAppBrowser?.IsOpened ?? false) - BrowserHelper.Instance.Close(); - }, - onError); - - }, onError, customHeaders: GenerateCustomHeaders()); - }, onError); - }, onError); - }, onError); - } - - public void PurchaseFreeCart(List items, Action> onSuccess = null, Action onError = null) - { - if (!items.Any()) - { - var error = new Error(errorMessage: "Cart is empty"); - onError?.Invoke(error); - return; - } - - XsollaCart.Instance.GetCartItems(XsollaSettings.StoreProjectId, newCart => - { - XsollaCart.Instance.ClearCart(XsollaSettings.StoreProjectId, newCart.cart_id, () => - { - var cartItems = items.Select(i => new CartFillItem - { - sku = i.Sku, - quantity = i.Quantity - }).ToList(); - - XsollaCart.Instance.FillCart(XsollaSettings.StoreProjectId, cartItems, () => - { - XsollaCart.Instance.CreateOrderWithFreeCart(XsollaSettings.StoreProjectId, orderId => onSuccess?.Invoke(items), onError); - }, onError); - }, onError); - }, onError); - } - - private void HandleRestrictedPaymentMethod(PurchaseData data, int methodId, RestrictedPaymentAllower restrictedPaymentAllower, Action onSuccess, Action onError) - { -#if UNITY_STANDALONE || UNITY_EDITOR - OrderTracking.Instance.RemoveOrderFromTracking(data.order_id); - - Action onAllowed = allowed => - { - BrowserHelper.Instance.InAppBrowser?.Close(); - - if (allowed) - { - XsollaOrders.Instance.OpenPurchaseUi(data, forcePlatformBrowser:true); - OrderTracking.Instance.AddOrderForShortPollingTracking(XsollaSettings.StoreProjectId, data.order_id, onSuccess, onError); - } - }; - - if (restrictedPaymentAllower != null) - { - restrictedPaymentAllower.OnAllowed += onAllowed; - restrictedPaymentAllower.OnRestrictedPayment.Invoke(methodId); - } - else - { - onAllowed.Invoke(true); - } -#endif - } - - private Dictionary GenerateCustomHeaders() - { -#if UNITY_STANDALONE || UNITY_EDITOR - if (DemoSettings.UseSteamAuth && DemoSettings.PaymentsFlow == PaymentsFlow.SteamGateway) - return new Dictionary{{"x-steam-userid", Token.Instance.GetSteamUserID()}}; -#endif - return null; - } - } -} diff --git a/Assets/Xsolla.Demo/Store/Scripts/Sdk/SdkPurchaseLogic.cs.meta b/Assets/Xsolla.Demo/Store/Scripts/Sdk/SdkPurchaseLogic.cs.meta deleted file mode 100644 index 9ffcc5b57..000000000 --- a/Assets/Xsolla.Demo/Store/Scripts/Sdk/SdkPurchaseLogic.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b5ea62ad98cf459438dcf4329a695b6e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla.Demo/Store/Scripts/Sdk/StoreLogic.cs b/Assets/Xsolla.Demo/Store/Scripts/Sdk/StoreLogic.cs new file mode 100644 index 000000000..f44fcac3e --- /dev/null +++ b/Assets/Xsolla.Demo/Store/Scripts/Sdk/StoreLogic.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Xsolla.Cart; +using Xsolla.Catalog; +using Xsolla.Core; +using Xsolla.Demo.Popup; + +namespace Xsolla.Demo +{ + public class StoreLogic : MonoSingleton + { + private static Dictionary GenerateCustomHeaders() + { +#if UNITY_STANDALONE || UNITY_EDITOR + if (DemoSettings.UseSteamAuth && DemoSettings.PaymentsFlow == PaymentsFlow.SteamGateway) + return SteamUtils.GetAdditionalCustomHeaders(); +#endif + return null; + } + + public static void PurchaseForRealMoney(CatalogItemModel item, Action onSuccess, Action onError) + { + XsollaCatalog.Purchase( + item.Sku, + _ => CompletePurchase(item, () => onSuccess?.Invoke(item)), + error => OnPurchaseError(error, onError), + customHeaders: GenerateCustomHeaders()); + } + + public static void PurchaseFreeItem(CatalogItemModel item, Action onSuccess, Action onError) + { + XsollaCatalog.PurchaseFreeItem(item.Sku, + _ => CompletePurchase(item, () => onSuccess?.Invoke(item)), + error => OnPurchaseError(error, onError), + customHeaders: GenerateCustomHeaders()); + } + + public static void PurchaseForVirtualCurrency(CatalogItemModel item, Action onSuccess, Action onError) + { + var onConfirmation = new Action(() => + { + var isPurchaseComplete = false; + PopupFactory.Instance.CreateWaiting().SetCloseCondition(() => isPurchaseComplete); + + XsollaCatalog.PurchaseForVirtualCurrency( + item.Sku, + item.VirtualPrice?.Key, + _ => + { + isPurchaseComplete = true; + CompletePurchase(item, () => onSuccess?.Invoke(item)); + }, + error => + { + isPurchaseComplete = true; + OnPurchaseError(error, onError); + }, + customHeaders: GenerateCustomHeaders()); + }); + + StoreDemoPopup.ShowConfirm(onConfirmation); + } + + public static void PurchaseCart(List items, Action> onSuccess, Action onError) + { + if (!items.Any()) + { + var error = new Error(errorMessage: "Cart is empty"); + onError?.Invoke(error); + return; + } + + XsollaCart.GetCartItems( + newCart => + { + XsollaCart.ClearCart( + () => + { + var cartItems = items + .Select(i => new CartFillItem { + sku = i.Sku, + quantity = i.Quantity + }).ToList(); + + XsollaCart.FillCart( + cartItems, + () => + { + XsollaCart.Purchase( + _ => CompletePurchase(null, () => onSuccess?.Invoke(items)), + error => OnPurchaseError(error, onError), + newCart.cart_id, + customHeaders: + GenerateCustomHeaders() + ); + }, + error => OnPurchaseError(error, onError), + newCart.cart_id); + }, + error => OnPurchaseError(error, onError), + newCart.cart_id); + }, + error => OnPurchaseError(error, onError), + XsollaSettings.StoreProjectId); + } + + public static void PurchaseFreeCart(List items, Action> onSuccess, Action onError) + { + if (!items.Any()) + { + var error = new Error(errorMessage: "Cart is empty"); + onError?.Invoke(error); + return; + } + + XsollaCart.GetCartItems( + newCart => + { + XsollaCart.ClearCart( + () => + { + var cartItems = items + .Select(i => new CartFillItem { + sku = i.Sku, + quantity = i.Quantity + }).ToList(); + + XsollaCart.FillCart( + cartItems, + () => + { + XsollaCart.PurchaseFreeCart( + _ => CompletePurchase(null, () => onSuccess?.Invoke(items)), + onError, + newCart.cart_id, + customHeaders: GenerateCustomHeaders() + ); + }, + error => OnPurchaseError(error, onError)); + }, + error => OnPurchaseError(error, onError), + newCart.cart_id); + }, + error => OnPurchaseError(error, onError), + XsollaSettings.StoreProjectId); + } + + private static void OnPurchaseError(Error error, Action callback) + { + StoreDemoPopup.ShowError(error); + callback?.Invoke(error); + } + + private static void CompletePurchase(ItemModel item, Action popupCallback) + { + UserInventory.Instance.Refresh(onError: StoreDemoPopup.ShowError); + + Action callback = () => + { + if (item != null) + StoreDemoPopup.ShowSuccess($"You have purchased '{item.Name}'", popupCallback); + else + StoreDemoPopup.ShowSuccess(null, popupCallback); + }; + + var inAppBrowser = XsollaWebBrowser.InAppBrowser; + if (inAppBrowser != null && inAppBrowser.IsOpened) + inAppBrowser.AddCloseHandler(callback); + else + callback.Invoke(); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoShop.cs.meta b/Assets/Xsolla.Demo/Store/Scripts/Sdk/StoreLogic.cs.meta similarity index 100% rename from Assets/Xsolla.Demo/Store/Scripts/Sdk/DemoShop.cs.meta rename to Assets/Xsolla.Demo/Store/Scripts/Sdk/StoreLogic.cs.meta diff --git a/Assets/Xsolla.Demo/Store/Scripts/Utils/CurrencyFormatUtil.cs b/Assets/Xsolla.Demo/Store/Scripts/Utils/CurrencyFormatUtil.cs index 6d331309e..8b7a843c2 100644 --- a/Assets/Xsolla.Demo/Store/Scripts/Utils/CurrencyFormatUtil.cs +++ b/Assets/Xsolla.Demo/Store/Scripts/Utils/CurrencyFormatUtil.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using Newtonsoft.Json; using UnityEngine; +using Xsolla.Demo; public static class CurrencyFormatUtil { @@ -13,7 +14,7 @@ static CurrencyFormatUtil() var currenciesFile = (TextAsset) Resources.Load(CURRENCY_FORMAT_FILE_NAME); if (currenciesFile == null) { - Debug.LogAssertion("Can not find or load currencies file"); + XDebug.LogWarning("Can not find or load currencies file"); return; } diff --git a/Assets/Xsolla/Auth/Api.meta b/Assets/Xsolla/Auth/Api.meta deleted file mode 100644 index fa8d102fa..000000000 --- a/Assets/Xsolla/Auth/Api.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: db3544d54b75353428f27768bd3a1667 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.AccountLinking.cs b/Assets/Xsolla/Auth/Api/XsollaAuth.AccountLinking.cs deleted file mode 100644 index 0414337b0..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.AccountLinking.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Auth -{ - public partial class XsollaAuth : MonoSingleton - { - private const string URL_USER_CONSOLE_AUTH = "https://livedemo.xsolla.com/sdk/sdk-shadow-account/auth"; - - #region Comment - /// - /// This method is used for authenticating users in Xsolla Login, - /// who play on the consoles and other platforms - /// where Xsolla Login isn't used. You must implement it - /// on your server side. - /// Integration flow on the server side: - /// - /// - /// Generate server JWT - /// - /// - /// - /// Connect OAuth 2.0 server client. - /// Follow the [instructions](https://developers.xsolla.com/doc/login/security/connecting-oauth2/#login_features_connecting_oauth2_connecting_client) to connect the client and cope copy the Client ID and Secret key. - /// - /// - /// - /// Implement method: - /// - /// - /// with `application/x-www-form-urlencoded` payload parameters: - /// - /// - /// client_id=YOUR_CLIENT_ID - /// - /// - /// client_secret=YOUR_CLIENT_SECRET - /// - /// - /// grant_type=client_credentials - /// - /// - /// - /// - /// - /// - /// - /// - /// Implement auth method - /// - /// - /// with: - /// - /// - /// Query parameters - /// ?publisher_project_id=XsollaSettings.StoreProjectId - /// - /// - /// Headers - /// - /// `Content-Type: application/json` and `X-SERVER-AUTHORIZATION: YourGeneratedJwt` - /// - /// - /// - /// [More information about authentication via custom ID](https://developers.xsolla.com/sdk/unity/authentication/auth-via-custom-id/). - /// - /// - /// - /// - /// - /// - /// - /// Social platform (XBox, PS4, etc) user unique identifier. - /// Platform name (XBox, PS4, etc). - /// Called after successful user authentication. Authentication data including the JWT will be received. - /// Called after the request resulted with an error. - #endregion - public void SignInConsoleAccount(string userId, string platform, Action successCase, Action failedCase) - { - var with_logout = XsollaSettings.InvalidateExistingSessions ? "1" : "0"; - var url = $"{URL_USER_CONSOLE_AUTH}?user_id={userId}&platform={platform}&with_logout={with_logout}"; - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, (TokenEntity result) => { successCase?.Invoke(result.token); }, failedCase); - } - } -} diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.AccountLinking.cs.meta b/Assets/Xsolla/Auth/Api/XsollaAuth.AccountLinking.cs.meta deleted file mode 100644 index 541da72fe..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.AccountLinking.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 7f76acd2e7cbcfc4ba736fb643be1bca -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.DeviceID.cs b/Assets/Xsolla/Auth/Api/XsollaAuth.DeviceID.cs deleted file mode 100644 index 969da4aca..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.DeviceID.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Auth -{ - public partial class XsollaAuth : MonoSingleton - { - private const string URL_DEVICE_ID_AUTH = - "https://login.xsolla.com/api/oauth2/login/device/{0}?client_id={1}&response_type=code&state={2}&redirect_uri={3}&scope=offline"; - - /// - /// Authenticates the user via a particular device ID. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). - /// Type of the device. Can be `android` and `ios`. - /// Manufacturer and model name of the device. - /// Platform specific unique device ID. - /// For Android, it is an [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID) constant.
- /// For iOS, it is an [identifierForVendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc) property. - /// - /// [OBSOLETE] Your custom data. Used only for JWT authorization type. - /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. - /// Called after successful user authentication via the device ID. - /// Called after the request resulted with an error. - public void AuthViaDeviceID(DeviceType deviceType, string device, string deviceId, string payload = null, string state = null, Action onSuccess = null, Action onError = null) - { - var deviceTypeToLower = deviceType.ToString().ToLower(); - var requestBody = new LoginDeviceIdRequest(device, deviceId); - var clientId = XsollaSettings.OAuthClientId; - var stateUrlParam = state ?? DEFAULT_OAUTH_STATE; - var redirectParam = RedirectUtils.GetRedirectUrl(); - - var url = string.Format(URL_DEVICE_ID_AUTH, deviceTypeToLower, clientId, stateUrlParam, redirectParam); - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, requestBody, - onComplete: (response) => - { - if (ParseUtils.TryGetValueFromUrl(response.login_url, ParseParameter.code, out string code)) - XsollaAuth.Instance.ExchangeCodeToToken(code, onSuccessExchange: token => onSuccess?.Invoke(token), onError: onError); - else - onError?.Invoke(Error.UnknownError); - }, - onError, ErrorCheckType.LoginErrors); - } - } -} diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.DeviceID.cs.meta b/Assets/Xsolla/Auth/Api/XsollaAuth.DeviceID.cs.meta deleted file mode 100644 index 098c8d1a8..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.DeviceID.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 718a1b2b8e575ef44889d5bd737ad2b0 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.OAuthRefreshToken.cs b/Assets/Xsolla/Auth/Api/XsollaAuth.OAuthRefreshToken.cs deleted file mode 100644 index d72d7b862..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.OAuthRefreshToken.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using UnityEngine; -using Xsolla.Core; - -namespace Xsolla.Auth -{ - public partial class XsollaAuth : MonoSingleton - { - private const string URL_OAUTH_GENERATE_JWT = "https://login.xsolla.com/api/oauth2/token"; - private bool _subscribed = false; - - /// - /// Refreshes the token in case it is expired. Works only when OAuth 2.0 is enabled. - /// - /// Called after successful token refreshing. Refresh data including the JWT will be received. - /// Called after the request resulted with an error. - public void RefreshOAuthToken(Action onSuccess, Action onError) - { - var refreshToken = TokenRefresh.Instance.RefreshToken; - RefreshOAuthToken(refreshToken, onSuccess, onError); - } - - /// - /// Refreshes the token in case it is expired. Works only when OAuth 2.0 is enabled. - /// - /// Token used to refresh the expired access token. Received when authorizing the user with username/password for the first time. - /// Called after successful token refreshing. Refresh data including the JWT will be received. - /// Called after the request resulted with an error. - public void RefreshOAuthToken(string refreshToken, Action onSuccess, Action onError) - { - if (EnvironmentDefiner.IsAndroid && Token.Instance.FromSocialNetwork()) - { - TryRefreshAndroidSocial(onSuccess, onError); - return; - } - - if (string.IsNullOrEmpty(refreshToken)) - { - var message = "Invalid refresh token"; - Debug.LogWarning(message); - onError?.Invoke(new Error(ErrorType.InvalidToken, errorMessage: message)); - return; - } - - var clientId = XsollaSettings.OAuthClientId; - var redirectUri = RedirectUtils.GetRedirectUrl(); - var requestData = new WWWForm(); - - requestData.AddField("client_id", clientId); - requestData.AddField("grant_type", "refresh_token"); - requestData.AddField("refresh_token", refreshToken); - requestData.AddField("redirect_uri", redirectUri); - - WebRequestHelper.Instance.PostRequest( - sdkType: SdkType.Login, - url: URL_OAUTH_GENERATE_JWT, - data: requestData, - onComplete: response => ProcessOAuthResponse(response, onSuccess), - onError: error => onError?.Invoke(error)); - } - - private void TryRefreshAndroidSocial(Action onSuccess, Action onError) - { - using (var helper = new AndroidSDKSocialAuthHelper()) - { - if (!helper.IsRefreshSocialTokenPossible) - { - Debug.Log("Android social token refresh is not available at the moment"); - onError?.Invoke(new Error(ErrorType.MethodIsNotAllowed)); - return; - } - - Action onSuccessRefresh = newToken => - { - var surrogateResponse = new LoginOAuthJsonResponse() - { - access_token = newToken, - refresh_token = string.Empty, - }; - - ProcessOAuthResponse(surrogateResponse, onSuccess); - }; - - helper.TryRefreshSocialToken(onSuccessRefresh, onError); - } - } - - /// - /// Exchanges the user authentication code to a valid JWT. - /// - /// Access code received from several other OAuth 2.0 requests (example: code from social network authentication). - /// Called after successful exchanging. Contains exchanged token. - /// Called after the request resulted with an error. - public void ExchangeCodeToToken(string code, Action onSuccessExchange = null, Action onError = null) - { - var clientId = XsollaSettings.OAuthClientId; - var redirectUri = RedirectUtils.GetRedirectUrl(); - - var requestData = new WWWForm(); - - requestData.AddField("grant_type", "authorization_code"); - requestData.AddField("client_id", clientId); - requestData.AddField("redirect_uri", redirectUri); - requestData.AddField("code", code); - - WebRequestHelper.Instance.PostRequest( - sdkType: SdkType.Login, - url: URL_OAUTH_GENERATE_JWT, - data: requestData, - onComplete: response => ProcessOAuthResponse(response, onSuccessExchange), - onError: error => onError?.Invoke(error)); - } - - private void ProcessOAuthResponse(LoginOAuthJsonResponse response, Action onSuccessToken) - { - Token.Instance = Token.Create(response.access_token); - SaveToken(Constants.LAST_SUCCESS_AUTH_TOKEN, response.access_token); - TokenRefresh.Instance.RefreshToken = response.refresh_token; - - onSuccessToken?.Invoke(response.access_token); - } - - private void SetupOAuthRefresh() - { - if (_subscribed) return; - - _subscribed = true; - TokenRefresh.Instance.OnInvalidToken += HandleInvalidToken; - } - - private void TeardownOAuthRefresh() - { - if (!_subscribed) return; - - _subscribed = false; - - if (TokenRefresh.IsExist) - TokenRefresh.Instance.OnInvalidToken -= HandleInvalidToken; - } - - private void HandleInvalidToken(Action repeatCall, Action onError) - { - RefreshOAuthToken( - onSuccess: _ => repeatCall?.Invoke(), - onError: onError); - } - } -} diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.OAuthRefreshToken.cs.meta b/Assets/Xsolla/Auth/Api/XsollaAuth.OAuthRefreshToken.cs.meta deleted file mode 100644 index 6e5e1195b..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.OAuthRefreshToken.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 142fbc6ae3ba9ba4daff5c7d2fa8c7cc -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.Social.cs b/Assets/Xsolla/Auth/Api/XsollaAuth.Social.cs deleted file mode 100644 index 38d7b2633..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.Social.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Core; - -namespace Xsolla.Auth -{ - public partial class XsollaAuth : MonoSingleton - { - private const string URL_SILENT_AUTH = - "https://login.xsolla.com/api/oauth2/social/{0}/cross_auth?client_id={1}&response_type=code&state={2}&redirect_uri={3}&app_id={4}&scope=offline&session_ticket={5}{6}&is_redirect=false"; - private const string URL_GET_LINK_FOR_SOCIAL_AUTH = - "https://login.xsolla.com/api/oauth2/social/{0}/login_redirect?client_id={1}&state={2}&response_type=code&redirect_uri={3}&scope=offline"; - private const string URL_GET_AVAILABLE_SOCIAL_NETWORKS = - "https://login.xsolla.com/api/users/me/login_urls?{0}"; - - /// - /// Authenticates a user by exchanging the session ticket from Steam, Xbox, or Epic Games to the JWT. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/silent-auth/). - /// Platform on which the session ticket was obtained. Can be `steam`, `xbox`, or `epicgames`. - /// Platform application identifier. - /// Session ticket received from the platform. - /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. - /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. - /// Required if there are several URIs. - /// [OBSOLETE] List of parameters which must be requested from the user or social network additionally and written to the JWT. The parameters must be separated by a comma. Used only for JWT authorization type. - /// Value used for additional user verification on backend. Must be at least 8 symbols long. Will be `xsollatest` by default. Used only for OAuth2.0 auth. - /// [OBSOLETE] Your custom data. Used only for JWT authorization type. - /// Code received from the platform. - /// Called after successful user authentication with a platform session ticket. Authentication data including a JWT will be received. - /// Called after the request resulted with an error. - public void SilentAuth(string providerName, string appId, string sessionTicket, string redirectUrl = null, List fields = null, string oauthState = null, string payload = null, string code = null, Action onSuccess = null, Action onError = null) - { - var clientIdParam = XsollaSettings.OAuthClientId; - var stateParam = (!string.IsNullOrEmpty(oauthState)) ? oauthState : DEFAULT_OAUTH_STATE; - var redirectUriParam = RedirectUtils.GetRedirectUrl(redirectUrl); - var codeParam = (!string.IsNullOrEmpty(code)) ? $"&code={code}" : ""; - - var url = string.Format(URL_SILENT_AUTH, providerName, clientIdParam, stateParam, redirectUriParam, appId, sessionTicket, codeParam); - - Action onSuccessResponse = response => - { - if (ParseUtils.TryGetValueFromUrl(response.login_url, ParseParameter.code, out string codeToExchange)) - ExchangeCodeToToken(codeToExchange, onSuccessExchange: token => onSuccess?.Invoke(token), onError: onError); - else - onError?.Invoke(Error.UnknownError); - }; - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, onSuccessResponse, onError); - } - - /// - /// Returns URL for authentication via the specified social network in a browser. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/social-auth/#sdk_how_to_set_up_web_auth_via_social_networks). - /// Name of a social network. Provider must be connected to Login in Publisher Account. - /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, or `xbox`. - /// [OBSOLETE] List of parameters which must be requested from the user or social network additionally and written to the JWT. The parameters must be separated by a comma. Used only for JWT authorization type. - /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. - /// [OBSOLETE] Your custom data. Used only for JWT authorization type. - public string GetSocialNetworkAuthUrl(SocialProvider providerName, string oauthState = null, List fields = null, string payload = null) - { - var clientIdParam = XsollaSettings.OAuthClientId; - var stateParam = (!string.IsNullOrEmpty(oauthState)) ? oauthState : DEFAULT_OAUTH_STATE; - var redirectUriParam = RedirectUtils.GetRedirectUrl(); - var result = string.Format(URL_GET_LINK_FOR_SOCIAL_AUTH, providerName.GetParameter(), clientIdParam, stateParam, redirectUriParam); - - result = WebRequestHelper.Instance.AppendAnalyticsToUrl(SdkType.Login, result); - return result; - } - - /// - /// Returns list of links for social authentication enabled in Publisher Account (your Login project > Authentication > Social login section). - /// The links are valid for 10 minutes. - /// You can get the link by this call and add it to your button for authentication via the social network. - /// - /// Called after list of links for social authentication was successfully received. - /// Called after the request resulted with an error. - /// Region in the `language code_country code` format, where: - /// - `language code` — language code in the [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) format; - /// - `country code` — country/region code in the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format.
- /// The list of the links will be sorted from most to least used social networks, according to the variable value. - /// - public void GetLinksForSocialAuth(string locale = null, Action> onSuccess = null, Action onError = null) - { - var localeParam = GetLocaleUrlParam(locale).Replace("&", string.Empty); - var url = string.Format(URL_GET_AVAILABLE_SOCIAL_NETWORKS, localeParam); - - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetLinksForSocialAuth(locale, onSuccess, onError))); - } - } -} diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.Social.cs.meta b/Assets/Xsolla/Auth/Api/XsollaAuth.Social.cs.meta deleted file mode 100644 index 37f3c8b9c..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.Social.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ce2b80c574afb714ea4109a9778322d6 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.User.cs b/Assets/Xsolla/Auth/Api/XsollaAuth.User.cs deleted file mode 100644 index 2cfd6029e..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.User.cs +++ /dev/null @@ -1,375 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Core; - -namespace Xsolla.Auth -{ - public partial class XsollaAuth : MonoSingleton - { - private const string URL_USER_REGISTRATION = "https://login.xsolla.com/api/oauth2/user?response_type=code&client_id={0}&state={1}&redirect_uri={2}{3}"; - private const string URL_USER_SIGNIN = "https://login.xsolla.com/api/oauth2/login/token?client_id={0}&scope=offline&redirect_uri={1}"; - private const string URL_USER_INFO = "https://login.xsolla.com/api/users/me"; - private const string URL_PASSWORD_RESET = "https://login.xsolla.com/api/password/reset/request?projectId={0}&login_url={1}{2}"; - private const string URL_RESEND_CONFIRMATION_LINK = "https://login.xsolla.com/api/oauth2/user/resend_confirmation_link?client_id={0}&state={1}&redirect_uri={2}{3}"; - private const string URL_USER_SOCIAL_NETWORK_TOKEN_AUTH = "https://login.xsolla.com/api/oauth2/social/{0}/login_with_token?client_id={1}&response_type=code&redirect_uri={2}&state={3}&scope=offline"; - private const string URL_GET_ACCESS_TOKEN = "{0}/login"; - private const string URL_OAUTH_LOGOUT = "https://login.xsolla.com/api/oauth2/logout?sessions={0}"; - - private const string URL_START_AUTH_BY_EMAIL = "https://login.xsolla.com/api/oauth2/login/email/request?response_type=code&client_id={0}&scope=offline&state={1}&redirect_uri={2}{3}"; - private const string URL_COMPLETE_AUTH_BY_EMAIL = "https://login.xsolla.com/api/oauth2/login/email/confirm?client_id={0}"; - private const string URL_START_AUTH_BY_PHONE_NUMBER = "https://login.xsolla.com/api/oauth2/login/phone/request?response_type=code&client_id={0}&scope=offline&state={1}&redirect_uri={2}"; - private const string URL_COMPLETE_AUTH_BY_PHONE_NUMBER = "https://login.xsolla.com/api/oauth2/login/phone/confirm?client_id={0}"; - - private const string URL_XSOLLA_LOGIN_WIDGET = "https://login-widget.xsolla.com/latest/?projectId={0}&login_url={1}"; - - /// - /// Returns user details. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User authorization token. - /// Called after successful user details were successfully received. - /// Called after the request resulted with an error. - public void GetUserInfo(string token, Action onSuccess, Action onError = null) - { - WebRequestHelper.Instance.GetRequest(SdkType.Login, URL_USER_INFO, WebRequestHeader.AuthHeader(token), onSuccess, onError); - } - - /// - /// Creates a new user account in the application and sends a sign-up confirmation email to the specified email address. To complete registration, the user must follow the link from the email. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/classic-auth/). - /// Username. - /// User password. - /// User email address. - /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. - /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. - /// Required if there are several URIs. - /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. - /// [OBSOLETE] Your custom data. Used only for JWT authorization type. - /// Whether the user gave consent to processing of their personal data. - /// Parameters used for extended registration form. To use this feature, please contact your Account Manager. - /// User consent to receive the newsletter. - /// Defines localization of the email the user receives.
- /// The following languages are supported: Arabic (`ar_AE`), Bulgarian (`bg_BG`), Czech (`cz_CZ`), German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Hebrew (`he_IL`), Italian (`it_IT`), Japanese (`ja_JP`), Korean (`ko_KR`), Polish (`pl_PL`), Portuguese (`pt_BR`), Romanian (`ro_RO`), Russian (`ru_RU`), Thai (`th_TH`), Turkish (`tr_TR`), Vietnamese (`vi_VN`), Chinese Simplified (`zh_CN`), Chinese Traditional (`zh_TW`), English (`en_XX`, default). - /// - /// Called after successful user registration. Account confirmation message will be sent to the specified email address. - /// Called after the request resulted with an error. - /// - /// - /// - public void Register(string username, string password, string email, string redirectUri = null, string oauthState = null, string payload = null, bool? acceptConsent = null, bool? promoEmailAgreement = null, List fields = null, string locale = null, Action onSuccess = null, Action onError = null) - { - var registrationData = new RegistrationJson(username, password, email, acceptConsent, fields, promoEmailAgreement); - var url = GetRegistrationUrl(oauthState, redirectUri, locale); - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, registrationData, onSuccess, onError, ErrorCheckType.RegistrationErrors); - } - - public void Register(string username, string password, string email, string redirectUri = null, string oauthState = null, string payload = null, bool? acceptConsent = null, bool? promoEmailAgreement = null, List fields = null, string locale = null, Action onSuccess = null, Action onError = null) - { - Action onSuccessRegistration = _ => onSuccess?.Invoke(); - Register(username, password, email, redirectUri, oauthState, payload, acceptConsent, promoEmailAgreement, fields, locale, onSuccessRegistration, onError); - } - - public void Register(string username, string password, string email, string redirectUri = null, string oauthState = null, string payload = null, bool? acceptConsent = null, bool? promoEmailAgreement = null, List fields = null, string locale = null, Action onSuccess = null, Action onError = null) - { - var registrationData = new RegistrationJson(username, password, email, acceptConsent, fields, promoEmailAgreement); - var url = GetRegistrationUrl(oauthState, redirectUri, locale); - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, registrationData, onSuccess, onError, ErrorCheckType.RegistrationErrors); - } - - private string GetRegistrationUrl(string oauthState = null, string redirectUri = null, string locale = null) - { - var clientIdParam = XsollaSettings.OAuthClientId; - var stateParam = (!string.IsNullOrEmpty(oauthState)) ? oauthState : DEFAULT_OAUTH_STATE; - var redirectUriParam = RedirectUtils.GetRedirectUrl(redirectUri); - var localeParam = (!string.IsNullOrEmpty(locale)) ? $"&locale={locale}" : ""; - return string.Format(URL_USER_REGISTRATION, clientIdParam, stateParam, redirectUriParam, localeParam); - } - - /// - /// Authenticates the user by the username/email and password specified via the authentication interface. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/classic-auth/). - /// Username or email address. - /// User password. - /// Whether the user agrees to save the authentication data. - /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. - /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. - /// Required if there are several URIs. - /// [OBSOLETE] Your custom data. Used only for JWT authorization type. - /// Called after successful user authentication. Authentication data including the JWT will be received. - /// Called after the request resulted with an error. - /// - /// - /// - /// - public void SignIn(string username, string password, bool rememberMe, string redirectUri = null, string payload = null, Action onSuccess = null, Action onError = null) - { - var loginData = new LoginRequest(username, password); - var redirectUriParam = RedirectUtils.GetRedirectUrl(redirectUri); - var url = string.Format(URL_USER_SIGNIN, XsollaSettings.OAuthClientId, redirectUriParam); - - Action successCallback = response => - { - ProcessOAuthResponse(response, onSuccess); - }; - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, loginData, successCallback, onError, ErrorCheckType.LoginErrors); - } - - /// - /// Starts user authentication and sends an email with a one-time code and a link to the specified email address (if login via magic link is configured for the Login project) - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/passwordless-auth/). - /// User email address. - /// URL to redirect the user to the status authentication page. - /// Shows whether a link is sent with the confirmation code in the email or not. - /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. - /// Defines localization of the email the user receives. - /// The following languages are supported: Arabic (`ar_AE`), Bulgarian (`bg_BG`), Czech (`cz_CZ`), German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Hebrew (`he_IL`), Italian (`it_IT`), Japanese (`ja_JP`), Korean (`ko_KR`), Polish (`pl_PL`), Portuguese (`pt_BR`), Romanian (`ro_RO`), Russian (`ru_RU`), Thai (`th_TH`), Turkish (`tr_TR`), Vietnamese (`vi_VN`), Chinese Simplified (`zh_CN`), Chinese Traditional (`zh_TW`), English (`en_XX`, default). - /// - /// Called after successful email authentication start. - /// Called after the request resulted with an error. - public void StartAuthByEmail(string email, string linkUrl, bool? sendLink, string oauthState = null, string locale = null, Action onSuccess = null, Action onError = null) - { - var data = new StartAuthByEmailRequest(email, linkUrl, sendLink); - var state = oauthState ?? DEFAULT_OAUTH_STATE; - var redirectParam = RedirectUtils.GetRedirectUrl(); - var localeParam = (!string.IsNullOrEmpty(locale)) ? $"&locale={locale}" : ""; - var url = string.Format(URL_START_AUTH_BY_EMAIL, XsollaSettings.OAuthClientId, state, redirectParam, localeParam); - - WebRequestHelper.Instance.PostRequest( - SdkType.Login, - url, - data, - response => onSuccess?.Invoke(response.operation_id), - onError, - ErrorCheckType.LoginErrors); - } - - public void StartAuthByEmail(string email, string linkUrl, bool? sendLink, Action onSuccess, Action onError = null) - { - StartAuthByEmail(email:email, linkUrl:linkUrl, sendLink:sendLink, oauthState:null, onSuccess:onSuccess, onError:onError); - } - - /// - /// Completes authentication after the user enters a one-time code or follows a link received in an email. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/passwordless-auth/). - /// User email address. - /// Confirmation code. - /// Identifier of the confirmation code. - /// Called after successful email authentication. - /// Called after the request resulted with an error. - public void CompleteAuthByEmail(string email, string confirmationCode, string operationId, Action onSuccess, Action onError = null) - { - var data = new CompleteAuthByEmailRequest(email, confirmationCode, operationId); - var url = string.Format(URL_COMPLETE_AUTH_BY_EMAIL, XsollaSettings.OAuthClientId); - - WebRequestHelper.Instance.PostRequest( - SdkType.Login, - url, - data, - response => - { - if (ParseUtils.TryGetValueFromUrl(response.login_url, ParseParameter.code, out var parsedCode)) - ExchangeCodeToToken(parsedCode, token => onSuccess?.Invoke(token), onError); - else - onError?.Invoke(Error.UnknownError); - }, - onError, - ErrorCheckType.LoginErrors); - } - - /// - /// Starts user authentication and sends an SMS with a one-time code and a link to the specified phone number (if login via magic link is configured for the Login project). - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/passwordless-auth/). - /// User phone number. - /// URL to redirect the user to the status authentication page. - /// Shows whether a link is sent with the confirmation code in the SMS or not. - /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. - /// Called after successful phone number authentication start. - /// Called after the request resulted with an error. - public void StartAuthByPhoneNumber(string phoneNumber, string linkUrl, bool sendLink, string oauthState, Action onSuccess, Action onError = null) - { - var data = new StartAuthByPhoneNumberRequest(phoneNumber, linkUrl, sendLink); - var state = oauthState ?? DEFAULT_OAUTH_STATE; - var redirectParam = RedirectUtils.GetRedirectUrl(); - var url = string.Format(URL_START_AUTH_BY_PHONE_NUMBER, XsollaSettings.OAuthClientId, state, redirectParam); - - WebRequestHelper.Instance.PostRequest( - SdkType.Login, - url, - data, - response => onSuccess?.Invoke(response.operation_id), - onError, - ErrorCheckType.LoginErrors); - } - - public void StartAuthByPhoneNumber(string phoneNumber, string linkUrl, bool sendLink, Action onSuccess, Action onError = null) - { - StartAuthByPhoneNumber(phoneNumber:phoneNumber, linkUrl:linkUrl, sendLink:sendLink, oauthState:null, onSuccess:onSuccess, onError:onError); - } - - /// - /// Completes authentication after the user enters a one-time code or follows a link received by SMS. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/passwordless-auth/). - /// User phone number. - /// Confirmation code. - /// Identifier of the confirmation code. - /// Called after successful phone number authentication. - /// Called after the request resulted with an error. - public void CompleteAuthByPhoneNumber(string phoneNumber, string confirmationCode, string operationId, Action onSuccess, Action onError = null) - { - var data = new CompleteAuthByPhoneNumberRequest(phoneNumber, confirmationCode, operationId); - var url = string.Format(URL_COMPLETE_AUTH_BY_PHONE_NUMBER, XsollaSettings.OAuthClientId); - - WebRequestHelper.Instance.PostRequest( - SdkType.Login, - url, - data, - response => - { - if (ParseUtils.TryGetValueFromUrl(response.login_url, ParseParameter.code, out var parsedCode)) - ExchangeCodeToToken(parsedCode, token => onSuccess?.Invoke(token), onError); - else - onError?.Invoke(Error.UnknownError); - }, - onError, - ErrorCheckType.LoginErrors); - } - - /// - /// Resets the user’s current password and sends an email to change the password to the email address specified during sign-up. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/classic-auth/). - /// Email to send the password change verification message to. - /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. - /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. - /// Required if there are several URIs. - /// Called after successful user password reset. - /// Called after the request resulted with an error. - /// Defines localization of the email the user receives. - /// The following languages are supported: Arabic (`ar_AE`), Bulgarian (`bg_BG`), Czech (`cz_CZ`), German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Hebrew (`he_IL`), Italian (`it_IT`), Japanese (`ja_JP`), Korean (`ko_KR`), Polish (`pl_PL`), Portuguese (`pt_BR`), Romanian (`ro_RO`), Russian (`ru_RU`), Thai (`th_TH`), Turkish (`tr_TR`), Vietnamese (`vi_VN`), Chinese Simplified (`zh_CN`), Chinese Traditional (`zh_TW`), English (`en_XX`, default). - /// - /// - /// - /// - public void ResetPassword(string email, string redirectUri = null, string locale = null, Action onSuccess = null, Action onError = null) - { - var projectIdParam = XsollaSettings.LoginId; - var loginUrlParam = RedirectUtils.GetRedirectUrl(redirectUri); - var localeParam = (!string.IsNullOrEmpty(locale)) ? $"&locale={locale}" : ""; - var url = string.Format(URL_PASSWORD_RESET, projectIdParam, loginUrlParam, localeParam); - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, new ResetPassword(email), onSuccess, onError, ErrorCheckType.ResetPasswordErrors); - } - - /// - /// Resends a sign-up confirmation email to the specified email address. To complete registration, the user must follow the link from the email. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/classic-auth/). - /// Username or user email address. - /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. - /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. - /// Required if there are several URIs. - /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. - /// [OBSOLETE] Your custom data. Used only for JWT authorization type. - /// Defines localization of the email user receives. - /// The following languages are supported: Arabic (`ar_AE`), Bulgarian (`bg_BG`), Czech (`cz_CZ`), German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Hebrew (`he_IL`), Italian (`it_IT`), Japanese (`ja_JP`), Korean (`ko_KR`), Polish (`pl_PL`), Portuguese (`pt_BR`), Romanian (`ro_RO`), Russian (`ru_RU`), Thai (`th_TH`), Turkish (`tr_TR`), Vietnamese (`vi_VN`), Chinese Simplified (`zh_CN`), Chinese Traditional (`zh_TW`), English (`en_XX`, default). - /// - /// Called after successful sending of the request. - /// Called after the request resulted with an error. - /// - /// - /// - public void ResendConfirmationLink(string username, string redirectUri = null, string state = null, string payload = null, string locale = null, Action onSuccess = null, Action onError = null) - { - var stateParam = state ?? DEFAULT_OAUTH_STATE; - var redirectUriParam = RedirectUtils.GetRedirectUrl(redirectUri); - var localeParam = (!string.IsNullOrEmpty(locale)) ? $"&locale={locale}" : ""; - var url = string.Format(URL_RESEND_CONFIRMATION_LINK, XsollaSettings.OAuthClientId, stateParam, redirectUriParam, localeParam); - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, new ResendConfirmationLinkRequest(username), onSuccess, onError); - } - - /// - /// Authenticates the user with the access token using social network credentials. - /// - /// Access token received from a social network. - /// Parameter `oauth_token_secret` received from the authorization request. Required for Twitter only. - /// Parameter `openid` received from the social network. Required for WeChat only. - /// Name of the social network connected to Login in Publisher Account. Can be `facebook`, `google`, `wechat`, or `qq_mobile`. - /// [OBSOLETE] Your custom data. Used only for JWT authorization type. - /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. - /// Called after successful user authentication on the specified platform. - /// Called after the request resulted with an error. - public void AuthWithSocialNetworkAccessToken(string accessToken, string accessTokenSecret, string openId, string providerName, string payload, string state = null, Action onSuccess = null, Action onError = null) - { - var oauthState = state ?? DEFAULT_OAUTH_STATE; - var redirectParam = RedirectUtils.GetRedirectUrl(); - var url = string.Format(URL_USER_SOCIAL_NETWORK_TOKEN_AUTH, providerName, XsollaSettings.OAuthClientId, redirectParam, oauthState); - - var requestData = new SocialNetworkAccessTokenRequest - { - access_token = accessToken, - access_token_secret = accessTokenSecret, - openId = openId - }; - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, requestData, onSuccess, onError, ErrorCheckType.LoginErrors); - } - - - /// - /// Authenticates the user with Xsolla Login widget. - /// - /// Called after successful authentication. - /// Called after browser closing by user. - public void AuthWithXsollaWidget(Action onSuccess, Action onCancel = null) - { - var url = string.Format(URL_XSOLLA_LOGIN_WIDGET, XsollaSettings.LoginId, RedirectUtils.GetRedirectUrl()); - BrowserHelper.Instance.Open(url); - - var browser = BrowserHelper.Instance.InAppBrowser; - - void onBrowserClose(bool isManually) - { - onCancel?.Invoke(); - browser.CloseEvent -= onBrowserClose; - browser.UrlChangeEvent -= onBrowserUrlChange; - } - - void onBrowserUrlChange(string newUrl) - { - if (ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.token, out var token)) - { - browser.CloseEvent -= onBrowserClose; - browser.UrlChangeEvent -= onBrowserUrlChange; - BrowserHelper.Instance.Close(); - onSuccess?.Invoke(token); - } - } - - browser.CloseEvent += onBrowserClose; - browser.UrlChangeEvent += onBrowserUrlChange; - } - - /// - /// Logs the user out and deletes the user session according to the value of the sessions parameter (OAuth2.0 only). - /// - /// User authorization token. - /// Shows how the user is logged out and how the user session is deleted. Can be `sso` or `all` (default). Leave empty to use the default value. - /// Called after successful user logout. - /// Called after the request resulted with an error. - public void OAuthLogout(string token, OAuthLogoutType sessions, Action onSuccess, Action onError = null) - { - var logoutTypeFlag = sessions.ToString().ToLowerInvariant(); - var url = string.Format(URL_OAUTH_LOGOUT, logoutTypeFlag); - - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(token), onSuccess, onError); - } - } -} diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.cs b/Assets/Xsolla/Auth/Api/XsollaAuth.cs deleted file mode 100644 index be130eaab..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.cs +++ /dev/null @@ -1,55 +0,0 @@ -using UnityEngine; -using Xsolla.Core; -using JetBrains.Annotations; - -namespace Xsolla.Auth -{ - [PublicAPI] - public partial class XsollaAuth : MonoSingleton - { - private const string DEFAULT_OAUTH_STATE = "xsollatest"; - - - public override void Init() - { - base.Init(); - SetupOAuthRefresh(); - } - - protected override void OnDestroy() - { - TeardownOAuthRefresh(); - base.OnDestroy(); - } - - public void DeleteToken(string key) - { - if (!string.IsNullOrEmpty(key) && PlayerPrefs.HasKey(key)) - { - PlayerPrefs.DeleteKey(key); - } - } - - public void SaveToken(string key, string token) - { - if (!string.IsNullOrEmpty(token)) - { - PlayerPrefs.SetString(key, token); - } - } - - public string LoadToken(string key) - { - return PlayerPrefs.GetString(key, string.Empty); - } - - string GetLocaleUrlParam(string locale) - { - if (string.IsNullOrEmpty(locale)) - { - return string.Empty; - } - return string.Format("&locale={0}", locale); - } - } -} diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.cs.meta b/Assets/Xsolla/Auth/Api/XsollaAuth.cs.meta deleted file mode 100644 index 18829137a..000000000 --- a/Assets/Xsolla/Auth/Api/XsollaAuth.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 66de31fbf7ebb8745b9584b5e686fa02 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Entities/CompleteAuthByEmailRequest.cs b/Assets/Xsolla/Auth/Entities/CompleteAuthByEmailRequest.cs deleted file mode 100644 index 95c0d537b..000000000 --- a/Assets/Xsolla/Auth/Entities/CompleteAuthByEmailRequest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace Xsolla.Auth -{ - [Serializable] - public class CompleteAuthByEmailRequest - { - public string email; - public string code; - public string operation_id; - - public CompleteAuthByEmailRequest(string email, string code, string operationId) - { - this.code = code; - this.email = email; - operation_id = operationId; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/CompleteAuthByPhoneNumberRequest.cs b/Assets/Xsolla/Auth/Entities/CompleteAuthByPhoneNumberRequest.cs deleted file mode 100644 index 9a20bdebb..000000000 --- a/Assets/Xsolla/Auth/Entities/CompleteAuthByPhoneNumberRequest.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace Xsolla.Auth -{ - [Serializable] - public class CompleteAuthByPhoneNumberRequest - { - public string phone_number; - public string code; - public string operation_id; - - public CompleteAuthByPhoneNumberRequest(string phoneNumber, string code, string operationId) - { - this.code = code; - phone_number = phoneNumber; - operation_id = operationId; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/DeviceInfo.cs b/Assets/Xsolla/Auth/Entities/DeviceInfo.cs new file mode 100644 index 000000000..c8c9cf937 --- /dev/null +++ b/Assets/Xsolla/Auth/Entities/DeviceInfo.cs @@ -0,0 +1,20 @@ +using Xsolla.Core; + +namespace Xsolla.Auth +{ + public class DeviceInfo + { + // Type of the device. Can be `android` and `ios`. + public DeviceType DeviceType; + + // For Android, it is an [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID) constant.
+ // For iOS, it is an [identifierForVendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc) property. + public string DeviceId; + + // Manufacturer name of the device. + public string DeviceModel; + + // Model name of the device. + public string DeviceName; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/DeviceInfo.cs.meta b/Assets/Xsolla/Auth/Entities/DeviceInfo.cs.meta new file mode 100644 index 000000000..5c6e711ad --- /dev/null +++ b/Assets/Xsolla/Auth/Entities/DeviceInfo.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: cba35c7cf95043b2a02d1c511e4c48cc +timeCreated: 1683083554 \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/LoginDeviceIdRequest.cs b/Assets/Xsolla/Auth/Entities/LoginDeviceIdRequest.cs deleted file mode 100644 index 1a04f97bb..000000000 --- a/Assets/Xsolla/Auth/Entities/LoginDeviceIdRequest.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Xsolla.Auth -{ - [Serializable] - public class LoginDeviceIdRequest - { - public string device; - public string device_id; - - public LoginDeviceIdRequest(string device, string device_id) - { - this.device = device; - this.device_id = device_id; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/LoginUrlResponse.cs b/Assets/Xsolla/Auth/Entities/LoginLink.cs similarity index 61% rename from Assets/Xsolla/Auth/Entities/LoginUrlResponse.cs rename to Assets/Xsolla/Auth/Entities/LoginLink.cs index 3d6ca13c4..bbd28198f 100644 --- a/Assets/Xsolla/Auth/Entities/LoginUrlResponse.cs +++ b/Assets/Xsolla/Auth/Entities/LoginLink.cs @@ -3,8 +3,9 @@ namespace Xsolla.Auth { [Serializable] - public class LoginUrlResponse + public class LoginLink { + // Link for authentication. public string login_url; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/LoginUrlResponse.cs.meta b/Assets/Xsolla/Auth/Entities/LoginLink.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/LoginUrlResponse.cs.meta rename to Assets/Xsolla/Auth/Entities/LoginLink.cs.meta diff --git a/Assets/Xsolla/Auth/Entities/LoginRequest.cs b/Assets/Xsolla/Auth/Entities/LoginRequest.cs deleted file mode 100644 index 5ad35711e..000000000 --- a/Assets/Xsolla/Auth/Entities/LoginRequest.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Newtonsoft.Json; -using System; - -namespace Xsolla.Auth -{ - [Serializable] - public class LoginRequest - { - public string username; - public string password; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public bool? remember_me; - - public LoginRequest(string username, string password, bool? rememberMe = null) - { - this.username = username; - this.password = password; - this.remember_me = rememberMe; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/LogoutType.cs b/Assets/Xsolla/Auth/Entities/LogoutType.cs new file mode 100644 index 000000000..33ad9fc81 --- /dev/null +++ b/Assets/Xsolla/Auth/Entities/LogoutType.cs @@ -0,0 +1,11 @@ +namespace Xsolla.Auth +{ + public enum LogoutType + { + // Is used for deleting only the SSO user session. + Sso, + + // Is used for deleting the SSO user session and invalidating all access and refresh tokens. + All + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Enum/OAuthLogoutType.cs.meta b/Assets/Xsolla/Auth/Entities/LogoutType.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Enum/OAuthLogoutType.cs.meta rename to Assets/Xsolla/Auth/Entities/LogoutType.cs.meta diff --git a/Assets/Xsolla/Auth/Entities/StartAuthByEmailResponse.cs b/Assets/Xsolla/Auth/Entities/OperationId.cs similarity index 66% rename from Assets/Xsolla/Auth/Entities/StartAuthByEmailResponse.cs rename to Assets/Xsolla/Auth/Entities/OperationId.cs index 2c719af22..19c019a03 100644 --- a/Assets/Xsolla/Auth/Entities/StartAuthByEmailResponse.cs +++ b/Assets/Xsolla/Auth/Entities/OperationId.cs @@ -3,8 +3,9 @@ namespace Xsolla.Auth { [Serializable] - public class StartAuthByEmailResponse + public class OperationId { + // Operation ID. public string operation_id; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/OperationId.cs.meta b/Assets/Xsolla/Auth/Entities/OperationId.cs.meta new file mode 100644 index 000000000..e796a6a29 --- /dev/null +++ b/Assets/Xsolla/Auth/Entities/OperationId.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ce3fad5c47f5406da1da2fa0de3c69cb +timeCreated: 1682570812 \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/RegistrationJson.cs b/Assets/Xsolla/Auth/Entities/RegistrationJson.cs deleted file mode 100644 index e1c62a503..000000000 --- a/Assets/Xsolla/Auth/Entities/RegistrationJson.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Xsolla.Auth -{ - [Serializable] - public class RegistrationJson - { - public string username; - public string password; - public string email; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public bool? accept_consent; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public List fields; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public int? promo_email_agreement; - - public RegistrationJson(string userName, string password, string email, bool? acceptConsent = null, List fields = null, bool? promoEmailAgreement = null) - { - this.username = userName; - this.password = password; - this.email = email; - this.accept_consent = acceptConsent; - this.fields = fields; - - if (promoEmailAgreement.HasValue) - this.promo_email_agreement = promoEmailAgreement.Value ? 1 : 0; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/ResendConfirmationLinkRequest.cs b/Assets/Xsolla/Auth/Entities/ResendConfirmationLinkRequest.cs deleted file mode 100644 index 82293024b..000000000 --- a/Assets/Xsolla/Auth/Entities/ResendConfirmationLinkRequest.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Xsolla.Auth -{ - [Serializable] - public class ResendConfirmationLinkRequest - { - public string username; - - public ResendConfirmationLinkRequest(string username) - { - this.username = username; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/ResetPassword.cs b/Assets/Xsolla/Auth/Entities/ResetPassword.cs deleted file mode 100644 index 7122e1919..000000000 --- a/Assets/Xsolla/Auth/Entities/ResetPassword.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Xsolla.Auth -{ - [Serializable] - public class ResetPassword - { - public string username; - - public ResetPassword(string username) - { - this.username = username; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/SocialNetworkLink.cs b/Assets/Xsolla/Auth/Entities/SocialNetworkLink.cs deleted file mode 100644 index 36c9468ab..000000000 --- a/Assets/Xsolla/Auth/Entities/SocialNetworkLink.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace Xsolla.Auth -{ - [Serializable] - public class SocialNetworkLink - { - public string auth_url; - public string provider; - } -} diff --git a/Assets/Xsolla/Auth/Entities/SocialNetworkLink.cs.meta b/Assets/Xsolla/Auth/Entities/SocialNetworkLink.cs.meta deleted file mode 100644 index e17a0f9e5..000000000 --- a/Assets/Xsolla/Auth/Entities/SocialNetworkLink.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5c2d2eda9f05cc145b483bd2eec9f28f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Entities/SocialNetworkLinks.cs b/Assets/Xsolla/Auth/Entities/SocialNetworkLinks.cs new file mode 100644 index 000000000..09fdc90d1 --- /dev/null +++ b/Assets/Xsolla/Auth/Entities/SocialNetworkLinks.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; + +namespace Xsolla.Auth +{ + [Serializable] + public class SocialNetworkLinks + { + public List items; + } + + [Serializable] + public class SocialNetworkLink + { + // Link for authentication via the social network. + public string auth_url; + + // Name of the social network. + public string provider; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/SocialNetworkLinks.cs.meta b/Assets/Xsolla/Auth/Entities/SocialNetworkLinks.cs.meta new file mode 100644 index 000000000..caa76e9e2 --- /dev/null +++ b/Assets/Xsolla/Auth/Entities/SocialNetworkLinks.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 64579ef07e88410f9cdfe20ab6a1d5b6 +timeCreated: 1683733591 \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/StartAuthByEmailRequest.cs b/Assets/Xsolla/Auth/Entities/StartAuthByEmailRequest.cs deleted file mode 100644 index bba334fc7..000000000 --- a/Assets/Xsolla/Auth/Entities/StartAuthByEmailRequest.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Xsolla.Auth -{ - [Serializable] - public class StartAuthByEmailRequest - { - public string email; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string link_url; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public bool? send_link; - - public StartAuthByEmailRequest(string email, string linkUrl = null, bool? sendLink = null) - { - this.email = email; - link_url = linkUrl; - send_link = sendLink; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/StartAuthByEmailResponse.cs.meta b/Assets/Xsolla/Auth/Entities/StartAuthByEmailResponse.cs.meta deleted file mode 100644 index 6bbc08eda..000000000 --- a/Assets/Xsolla/Auth/Entities/StartAuthByEmailResponse.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: ef83a1f85e7748e6917d6d37ab3b55da -timeCreated: 1634030798 \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberRequest.cs b/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberRequest.cs deleted file mode 100644 index 64c133f18..000000000 --- a/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberRequest.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Xsolla.Auth -{ - [Serializable] - public class StartAuthByPhoneNumberRequest - { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string link_url; - public string phone_number; - public bool send_link; - - public StartAuthByPhoneNumberRequest(string phoneNumber, string linkUrl, bool sendLink) - { - link_url = linkUrl; - phone_number = phoneNumber; - send_link = sendLink; - } - } -} diff --git a/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberResponse.cs.meta b/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberResponse.cs.meta deleted file mode 100644 index d84a1e9de..000000000 --- a/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberResponse.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 22341f61162b4de0abd307583c509e1e -timeCreated: 1634030847 \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/TokenEntity.cs.meta b/Assets/Xsolla/Auth/Entities/TokenEntity.cs.meta deleted file mode 100644 index 7fd3711da..000000000 --- a/Assets/Xsolla/Auth/Entities/TokenEntity.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 1ddcbac71254b4d5183ec9f82863d635 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Enum.meta b/Assets/Xsolla/Auth/Enum.meta deleted file mode 100644 index a843c1007..000000000 --- a/Assets/Xsolla/Auth/Enum.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4a4d5afe64cd6114b81326792bdab44f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Auth/Enum/OAuthLogoutType.cs b/Assets/Xsolla/Auth/Enum/OAuthLogoutType.cs deleted file mode 100644 index 39788d681..000000000 --- a/Assets/Xsolla/Auth/Enum/OAuthLogoutType.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace Xsolla.Auth -{ - public enum OAuthLogoutType - { - Sso, - All - } -} diff --git a/Assets/Tests/API.meta b/Assets/Xsolla/Auth/Internal.meta similarity index 77% rename from Assets/Tests/API.meta rename to Assets/Xsolla/Auth/Internal.meta index 6fcf8c2bc..929130d18 100644 --- a/Assets/Tests/API.meta +++ b/Assets/Xsolla/Auth/Internal.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: ddb35beab37d1c941bc2d0a5cc140800 +guid: 742cdd09a299c4a18bf14e915f2d4817 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Xsolla/Auth/Entities/TokenEntity.cs b/Assets/Xsolla/Auth/Internal/AccessTokenResponse.cs similarity index 69% rename from Assets/Xsolla/Auth/Entities/TokenEntity.cs rename to Assets/Xsolla/Auth/Internal/AccessTokenResponse.cs index ae91920ac..360641acd 100644 --- a/Assets/Xsolla/Auth/Entities/TokenEntity.cs +++ b/Assets/Xsolla/Auth/Internal/AccessTokenResponse.cs @@ -3,8 +3,8 @@ namespace Xsolla.Auth { [Serializable] - public class TokenEntity + internal class AccessTokenResponse { public string token; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/Entities/TokenEntity.cs.meta b/Assets/Xsolla/Auth/Internal/AccessTokenResponse.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/Entities/TokenEntity.cs.meta rename to Assets/Xsolla/Auth/Internal/AccessTokenResponse.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/AuthViaDeviceIdRequest.cs b/Assets/Xsolla/Auth/Internal/AuthViaDeviceIdRequest.cs new file mode 100644 index 000000000..bab247f37 --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/AuthViaDeviceIdRequest.cs @@ -0,0 +1,11 @@ +using System; + +namespace Xsolla.Auth +{ + [Serializable] + internal class AuthViaDeviceIdRequest + { + public string device; + public string device_id; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/LoginDeviceIdRequest.cs.meta b/Assets/Xsolla/Auth/Internal/AuthViaDeviceIdRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/LoginDeviceIdRequest.cs.meta rename to Assets/Xsolla/Auth/Internal/AuthViaDeviceIdRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Entities/SocialNetworkAccessTokenRequest.cs b/Assets/Xsolla/Auth/Internal/AuthWithSocialNetworkAccessTokenRequest.cs similarity index 72% rename from Assets/Xsolla/Auth/Entities/SocialNetworkAccessTokenRequest.cs rename to Assets/Xsolla/Auth/Internal/AuthWithSocialNetworkAccessTokenRequest.cs index f422037d8..0868da63b 100644 --- a/Assets/Xsolla/Auth/Entities/SocialNetworkAccessTokenRequest.cs +++ b/Assets/Xsolla/Auth/Internal/AuthWithSocialNetworkAccessTokenRequest.cs @@ -3,10 +3,10 @@ namespace Xsolla.Auth { [Serializable] - public class SocialNetworkAccessTokenRequest + internal class AuthWithSocialNetworkAccessTokenRequest { public string access_token; public string access_token_secret; public string openId; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/SocialNetworkAccessTokenRequest.cs.meta b/Assets/Xsolla/Auth/Internal/AuthWithSocialNetworkAccessTokenRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/SocialNetworkAccessTokenRequest.cs.meta rename to Assets/Xsolla/Auth/Internal/AuthWithSocialNetworkAccessTokenRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberResponse.cs b/Assets/Xsolla/Auth/Internal/CompleteAuthByEmailRequest.cs similarity index 50% rename from Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberResponse.cs rename to Assets/Xsolla/Auth/Internal/CompleteAuthByEmailRequest.cs index f36dde071..098749d65 100644 --- a/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberResponse.cs +++ b/Assets/Xsolla/Auth/Internal/CompleteAuthByEmailRequest.cs @@ -3,8 +3,10 @@ namespace Xsolla.Auth { [Serializable] - public class StartAuthByPhoneNumberResponse + internal class CompleteAuthByEmailRequest { + public string email; + public string code; public string operation_id; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/CompleteAuthByEmailRequest.cs.meta b/Assets/Xsolla/Auth/Internal/CompleteAuthByEmailRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/CompleteAuthByEmailRequest.cs.meta rename to Assets/Xsolla/Auth/Internal/CompleteAuthByEmailRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/CompleteAuthByPhoneNumberRequest.cs b/Assets/Xsolla/Auth/Internal/CompleteAuthByPhoneNumberRequest.cs new file mode 100644 index 000000000..9f0b821c6 --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/CompleteAuthByPhoneNumberRequest.cs @@ -0,0 +1,12 @@ +using System; + +namespace Xsolla.Auth +{ + [Serializable] + internal class CompleteAuthByPhoneNumberRequest + { + public string phone_number; + public string code; + public string operation_id; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/CompleteAuthByPhoneNumberRequest.cs.meta b/Assets/Xsolla/Auth/Internal/CompleteAuthByPhoneNumberRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/CompleteAuthByPhoneNumberRequest.cs.meta rename to Assets/Xsolla/Auth/Internal/CompleteAuthByPhoneNumberRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/RegisterRequest.cs b/Assets/Xsolla/Auth/Internal/RegisterRequest.cs new file mode 100644 index 000000000..bc87cb9ef --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/RegisterRequest.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; + +namespace Xsolla.Auth +{ + [Serializable] + internal class RegisterRequest + { + public string username; + public string password; + public string email; + public bool? accept_consent; + public List fields; + public int? promo_email_agreement; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/RegistrationJson.cs.meta b/Assets/Xsolla/Auth/Internal/RegisterRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/RegistrationJson.cs.meta rename to Assets/Xsolla/Auth/Internal/RegisterRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/ResendConfirmationLinkRequest.cs b/Assets/Xsolla/Auth/Internal/ResendConfirmationLinkRequest.cs new file mode 100644 index 000000000..1a8775040 --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/ResendConfirmationLinkRequest.cs @@ -0,0 +1,10 @@ +using System; + +namespace Xsolla.Auth +{ + [Serializable] + internal class ResendConfirmationLinkRequest + { + public string username; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/ResendConfirmationLinkRequest.cs.meta b/Assets/Xsolla/Auth/Internal/ResendConfirmationLinkRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/ResendConfirmationLinkRequest.cs.meta rename to Assets/Xsolla/Auth/Internal/ResendConfirmationLinkRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/ResetPasswordRequest.cs b/Assets/Xsolla/Auth/Internal/ResetPasswordRequest.cs new file mode 100644 index 000000000..108bdf89d --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/ResetPasswordRequest.cs @@ -0,0 +1,10 @@ +using System; + +namespace Xsolla.Auth +{ + [Serializable] + internal class ResetPasswordRequest + { + public string username; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/ResetPassword.cs.meta b/Assets/Xsolla/Auth/Internal/ResetPasswordRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/ResetPassword.cs.meta rename to Assets/Xsolla/Auth/Internal/ResetPasswordRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/SignInRequest.cs b/Assets/Xsolla/Auth/Internal/SignInRequest.cs new file mode 100644 index 000000000..56c551c2a --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/SignInRequest.cs @@ -0,0 +1,12 @@ +using System; + +namespace Xsolla.Auth +{ + [Serializable] + internal class SignInRequest + { + public string username; + public string password; + public bool? remember_me; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/LoginRequest.cs.meta b/Assets/Xsolla/Auth/Internal/SignInRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/LoginRequest.cs.meta rename to Assets/Xsolla/Auth/Internal/SignInRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/StandaloneSocialAuth.cs b/Assets/Xsolla/Auth/Internal/StandaloneSocialAuth.cs new file mode 100644 index 000000000..b0be19060 --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/StandaloneSocialAuth.cs @@ -0,0 +1,33 @@ +using System; +using Xsolla.Core; + +namespace Xsolla.Auth +{ + internal class StandaloneSocialAuth + { + public void Perform(SocialProvider provider, Action onSuccess, Action onError, Action onCancel) + { + var socialNetworkAuthUrl = XsollaAuth.GetSocialNetworkAuthUrl(provider); + var browser = XsollaWebBrowser.InAppBrowser; + browser.Open(socialNetworkAuthUrl); + + browser.AddCloseHandler(() => onCancel?.Invoke()); + browser.AddUrlChangeHandler(url => UrlChangedHandler(url, onSuccess, onError)); + } + + private static void UrlChangedHandler(string url, Action onSuccess, Action onError) + { + if (ParseUtils.TryGetValueFromUrl(url, ParseParameter.code, out var code)) + { + XsollaAuth.ExchangeCodeToToken( + code, + () => + { + XsollaWebBrowser.Close(); + onSuccess?.Invoke(); + }, + onError); + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Internal/StandaloneSocialAuth.cs.meta b/Assets/Xsolla/Auth/Internal/StandaloneSocialAuth.cs.meta new file mode 100644 index 000000000..fa1154180 --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/StandaloneSocialAuth.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 18b7d4210f854b7cb920bace09bc0d4a +timeCreated: 1683001343 \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Internal/StartAuthByEmailRequest.cs b/Assets/Xsolla/Auth/Internal/StartAuthByEmailRequest.cs new file mode 100644 index 000000000..25b029aff --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/StartAuthByEmailRequest.cs @@ -0,0 +1,12 @@ +using System; + +namespace Xsolla.Auth +{ + [Serializable] + internal class StartAuthByEmailRequest + { + public string email; + public string link_url; + public bool? send_link; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/StartAuthByEmailRequest.cs.meta b/Assets/Xsolla/Auth/Internal/StartAuthByEmailRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/StartAuthByEmailRequest.cs.meta rename to Assets/Xsolla/Auth/Internal/StartAuthByEmailRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/StartAuthByPhoneNumberRequest.cs b/Assets/Xsolla/Auth/Internal/StartAuthByPhoneNumberRequest.cs new file mode 100644 index 000000000..dba947de4 --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/StartAuthByPhoneNumberRequest.cs @@ -0,0 +1,12 @@ +using System; + +namespace Xsolla.Auth +{ + [Serializable] + internal class StartAuthByPhoneNumberRequest + { + public string link_url; + public string phone_number; + public bool? send_link; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberRequest.cs.meta b/Assets/Xsolla/Auth/Internal/StartAuthByPhoneNumberRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/StartAuthByPhoneNumberRequest.cs.meta rename to Assets/Xsolla/Auth/Internal/StartAuthByPhoneNumberRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Internal/XsollaLauncherAuth.cs b/Assets/Xsolla/Auth/Internal/XsollaLauncherAuth.cs new file mode 100644 index 000000000..9994054b0 --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/XsollaLauncherAuth.cs @@ -0,0 +1,43 @@ +using System; + +namespace Xsolla.Core +{ + internal class XsollaLauncherAuth + { + private const string LAUNCHER_TOKEN_KEY = "xsolla-login-token"; + + public void Perform(Action onSuccess, Action onError) + { + var launcherToken = GetLauncherToken(); + if (string.IsNullOrEmpty(launcherToken)) + { + onError?.Invoke(new Error(ErrorType.Undefined, "Can't get launcher token from command line arguments.")); + } + else + { + XsollaToken.Create(launcherToken); + onSuccess?.Invoke(); + } + } + + private static string GetLauncherToken() + { + var commandLineArgs = Environment.GetCommandLineArgs(); + var tokenValueIndex = -1; + + for (var i = 0; i < commandLineArgs.Length; i++) + { + if (commandLineArgs[i].Contains(LAUNCHER_TOKEN_KEY)) + { + tokenValueIndex = i + 1; + break; + } + } + + if (tokenValueIndex == -1 || tokenValueIndex >= commandLineArgs.Length) + return null; + + return commandLineArgs[tokenValueIndex]; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Internal/XsollaLauncherAuth.cs.meta b/Assets/Xsolla/Auth/Internal/XsollaLauncherAuth.cs.meta new file mode 100644 index 000000000..2da936ee5 --- /dev/null +++ b/Assets/Xsolla/Auth/Internal/XsollaLauncherAuth.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 03150433f99b4afbaa565ee66c856fc4 +timeCreated: 1684209725 \ No newline at end of file diff --git a/Assets/Xsolla/Auth/XsollaAuth.cs b/Assets/Xsolla/Auth/XsollaAuth.cs new file mode 100644 index 000000000..58dfec1a1 --- /dev/null +++ b/Assets/Xsolla/Auth/XsollaAuth.cs @@ -0,0 +1,824 @@ +using System; +using System.Collections.Generic; +using UnityEngine; +using Xsolla.Core; + +namespace Xsolla.Auth +{ + public static class XsollaAuth + { + private const string BASE_URL = "https://login.xsolla.com/api"; + + /// + /// Checks if the user is authenticated. Returns `true` if the token exists and the user is authenticated. + /// + public static bool IsUserAuthenticated() + { + return XsollaToken.Exists; + } + + /// + /// Creates a new user account in the application and sends a sign-up confirmation email to the specified email address. To complete registration, the user should follow the link from the email. To disable email confirmation, contact your Account Manager. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/classic-auth/). + /// Username. + /// User password. + /// User email address. + /// Called after successful user registration. An account confirmation message will be sent to the specified email address if not disabled. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. + /// Defines localization of the email the user receives.
+ /// The following languages are supported: Arabic (`ar_AE`), Bulgarian (`bg_BG`), Czech (`cz_CZ`), German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Hebrew (`he_IL`), Italian (`it_IT`), Japanese (`ja_JP`), Korean (`ko_KR`), Polish (`pl_PL`), Portuguese (`pt_BR`), Romanian (`ro_RO`), Russian (`ru_RU`), Thai (`th_TH`), Turkish (`tr_TR`), Vietnamese (`vi_VN`), Chinese Simplified (`zh_CN`), Chinese Traditional (`zh_TW`), English (`en_XX`, default). + /// + /// Whether the user gave consent to processing of their personal data. + /// User consent to receive the newsletter. + /// Parameters used for extended registration form. To use this feature, please contact your Account Manager. + /// + /// + /// + public static void Register(string username, string password, string email, Action onSuccess, Action onError, string redirectUri = null, string state = null, string locale = null, bool? acceptConsent = null, bool? promoEmailAgreement = null, List fields = null) + { + var url = new UrlBuilder(BASE_URL + "/oauth2/user") + .AddClientId(XsollaSettings.OAuthClientId) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddState(GetState(state)) + .AddLocale(locale) + .AddResponseType(GetResponseType()) + .Build(); + + var requestData = new RegisterRequest { + username = username, + password = password, + email = email, + accept_consent = acceptConsent, + fields = fields, + promo_email_agreement = promoEmailAgreement.HasValue && promoEmailAgreement.Value ? 1 : 0 + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + webRequest => + { + var responseJson = webRequest?.downloadHandler?.text; + if (string.IsNullOrEmpty(responseJson)) + { + onSuccess?.Invoke(new LoginLink()); + } + else + { + var loginLink = ParseUtils.FromJson(responseJson); + onSuccess?.Invoke(loginLink); + } + }, + onError, + ErrorGroup.RegistrationErrors); + } + + /// + /// Authenticates the user by the username/email and password specified via the authentication interface. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/classic-auth/). + /// Username or email address. + /// User password. + /// Called after successful user authentication. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// + /// + /// + /// + public static void SignIn(string username, string password, Action onSuccess, Action onError, string redirectUri = null) + { + var url = new UrlBuilder(BASE_URL + "/oauth2/login/token") + .AddClientId(XsollaSettings.OAuthClientId) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddScope(GetScope()) + .Build(); + + var requestData = new SignInRequest { + username = username, + password = password + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + response => + { + XsollaToken.Create(response.access_token, response.refresh_token); + onSuccess?.Invoke(); + }, + onError, + ErrorGroup.LoginErrors); + } + + /// + /// Starts user authentication and sends an email with a one-time code and a link to the specified email address (if login via magic link is configured for the Login project) + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/passwordless-auth/). + /// User email address. + /// Called after successful email authentication start. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. + /// Defines localization of the email the user receives. + /// The following languages are supported: Arabic (`ar_AE`), Bulgarian (`bg_BG`), Czech (`cz_CZ`), German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Hebrew (`he_IL`), Italian (`it_IT`), Japanese (`ja_JP`), Korean (`ko_KR`), Polish (`pl_PL`), Portuguese (`pt_BR`), Romanian (`ro_RO`), Russian (`ru_RU`), Thai (`th_TH`), Turkish (`tr_TR`), Vietnamese (`vi_VN`), Chinese Simplified (`zh_CN`), Chinese Traditional (`zh_TW`), English (`en_XX`, default). + /// + /// Shows whether a link is sent with the confirmation code in the email or not. + /// URL to redirect the user to the status authentication page. + public static void StartAuthByEmail(string email, Action onSuccess, Action onError, string redirectUri = null, string state = null, string locale = null, bool? sendLink = null, string linkUrl = null) + { + var url = new UrlBuilder(BASE_URL + "/oauth2/login/email/request") + .AddClientId(XsollaSettings.OAuthClientId) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddState(GetState(state)) + .AddLocale(locale) + .AddScope(GetScope()) + .AddResponseType(GetResponseType()) + .Build(); + + var requestData = new StartAuthByEmailRequest { + email = email, + link_url = linkUrl, + send_link = sendLink + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + onSuccess, + onError, + ErrorGroup.LoginErrors); + } + + /// + /// Completes authentication after the user enters a one-time code or follows a link received in an email. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/passwordless-auth/). + /// User email address. + /// Confirmation code. + /// Identifier of the confirmation code. + /// Called after successful email authentication. + /// Called after the request resulted with an error. + public static void CompleteAuthByEmail(string email, string confirmationCode, string operationId, Action onSuccess, Action onError) + { + var url = new UrlBuilder(BASE_URL + "/oauth2/login/email/confirm") + .AddClientId(XsollaSettings.OAuthClientId) + .Build(); + + var requestData = new CompleteAuthByEmailRequest { + email = email, + code = confirmationCode, + operation_id = operationId + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + response => ParseCodeFromUrlAndExchangeToToken(response.login_url, onSuccess, onError), + onError, + ErrorGroup.LoginErrors); + } + + /// + /// Starts user authentication and sends an SMS with a one-time code and a link to the specified phone number (if login via magic link is configured for the Login project). + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/passwordless-auth/). + /// User phone number. + /// Called after successful phone number authentication start. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. + /// Shows whether a link is sent with the confirmation code in the SMS or not. + /// URL to redirect the user to the status authentication page. + public static void StartAuthByPhoneNumber(string phoneNumber, Action onSuccess, Action onError, string redirectUri = null, string state = null, bool? sendLink = null, string linkUrl = null) + { + var url = new UrlBuilder(BASE_URL + "/oauth2/login/phone/request") + .AddClientId(XsollaSettings.OAuthClientId) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddState(GetState(state)) + .AddScope(GetScope()) + .AddResponseType(GetResponseType()) + .Build(); + + var requestData = new StartAuthByPhoneNumberRequest { + link_url = linkUrl, + phone_number = phoneNumber, + send_link = sendLink + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + onSuccess, + onError, + ErrorGroup.LoginErrors); + } + + /// + /// Completes authentication after the user enters a one-time code or follows a link received by SMS. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/passwordless-auth/). + /// User phone number. + /// Confirmation code. + /// Identifier of the confirmation code. + /// Called after successful phone number authentication. + /// Called after the request resulted with an error. + public static void CompleteAuthByPhoneNumber(string phoneNumber, string confirmationCode, string operationId, Action onSuccess, Action onError) + { + var url = new UrlBuilder(BASE_URL + "/oauth2/login/phone/confirm") + .AddClientId(XsollaSettings.OAuthClientId) + .Build(); + + var requestData = new CompleteAuthByPhoneNumberRequest { + phone_number = phoneNumber, + code = confirmationCode, + operation_id = operationId + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + response => ParseCodeFromUrlAndExchangeToToken(response.login_url, onSuccess, onError), + onError, + ErrorGroup.LoginErrors); + } + + /// + /// Resets the user’s current password and sends an email to change the password to the email address specified during sign-up. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/classic-auth/). + /// Email to send the password change verification message to. + /// Called after successful user password reset. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Defines localization of the email the user receives. + /// The following languages are supported: Arabic (`ar_AE`), Bulgarian (`bg_BG`), Czech (`cz_CZ`), German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Hebrew (`he_IL`), Italian (`it_IT`), Japanese (`ja_JP`), Korean (`ko_KR`), Polish (`pl_PL`), Portuguese (`pt_BR`), Romanian (`ro_RO`), Russian (`ru_RU`), Thai (`th_TH`), Turkish (`tr_TR`), Vietnamese (`vi_VN`), Chinese Simplified (`zh_CN`), Chinese Traditional (`zh_TW`), English (`en_XX`, default). + /// + /// + /// + /// + public static void ResetPassword(string email, Action onSuccess, Action onError, string redirectUri = null, string locale = null) + { + var url = new UrlBuilder(BASE_URL + "/password/reset/request") + .AddProjectId(XsollaSettings.LoginId) + .AddParam("login_url", RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddLocale(locale) + .Build(); + + var requestData = new ResetPasswordRequest { + username = email + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + onSuccess, + onError, + ErrorGroup.ResetPasswordErrors); + } + + /// + /// Resends a sign-up confirmation email to the specified email address. To complete registration, the user must follow the link from the email. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/classic-auth/). + /// Username or user email address. + /// Called after successful sending of the request. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. + /// Defines localization of the email user receives. + /// The following languages are supported: Arabic (`ar_AE`), Bulgarian (`bg_BG`), Czech (`cz_CZ`), German (`de_DE`), Spanish (`es_ES`), French (`fr_FR`), Hebrew (`he_IL`), Italian (`it_IT`), Japanese (`ja_JP`), Korean (`ko_KR`), Polish (`pl_PL`), Portuguese (`pt_BR`), Romanian (`ro_RO`), Russian (`ru_RU`), Thai (`th_TH`), Turkish (`tr_TR`), Vietnamese (`vi_VN`), Chinese Simplified (`zh_CN`), Chinese Traditional (`zh_TW`), English (`en_XX`, default). + /// + /// + /// + /// + public static void ResendConfirmationLink(string username, Action onSuccess, Action onError, string redirectUri = null, string state = null, string locale = null) + { + var url = new UrlBuilder(BASE_URL + "/oauth2/user/resend_confirmation_link") + .AddClientId(XsollaSettings.OAuthClientId) + .AddState(GetState(state)) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddLocale(locale) + .Build(); + + var requestData = new ResendConfirmationLinkRequest { + username = username + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + onSuccess, + onError); + } + + /// + /// Authenticates the user with the access token using social network credentials. + /// + /// Access token received from a social network. + /// Parameter `oauth_token_secret` received from the authorization request. Required for Twitter only. + /// Parameter `openid` received from the social network. Required for WeChat only. + /// Name of the social network connected to Login in Publisher Account. Can be `facebook`, `google`, `wechat`, or `qq_mobile`. + /// Called after successful user authentication on the specified platform. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. + public static void AuthWithSocialNetworkAccessToken(string accessToken, string accessTokenSecret, string openId, string provider, Action onSuccess, Action onError, string redirectUri = null, string state = null) + { + var url = new UrlBuilder(BASE_URL + $"/oauth2/social/{provider}/login_with_token") + .AddClientId(XsollaSettings.OAuthClientId) + .AddResponseType(GetResponseType()) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddState(GetState(state)) + .AddScope(GetScope()) + .Build(); + + var requestData = new AuthWithSocialNetworkAccessTokenRequest { + access_token = accessToken, + access_token_secret = accessTokenSecret, + openId = openId + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + link => ParseCodeFromUrlAndExchangeToToken(link.login_url, onSuccess, onError), + onError, + ErrorGroup.LoginErrors); + } + + /// + /// Authenticates the user by saved token. Returns `true` if the token is loaded successfully and the user is authenticated + /// + public static bool AuthViaSavedToken() + { + return XsollaToken.TryLoadInstance(); + } + + /// + /// Authenticates the user with Xsolla Login widget. + /// + /// Called after successful authentication. + /// Called after browser closing by user. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + public static void AuthWithXsollaWidget(Action onSuccess, Action onCancel, string redirectUri = null) + { + var url = new UrlBuilder("https://login-widget.xsolla.com/latest/") + .AddProjectId(XsollaSettings.LoginId) + .AddParam("login_url", RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .Build(); + + XsollaWebBrowser.Open(url); + var browser = XsollaWebBrowser.InAppBrowser; + + void onBrowserClose(BrowserCloseInfo info) + { + onCancel?.Invoke(); + browser.CloseEvent -= onBrowserClose; + browser.UrlChangeEvent -= onBrowserUrlChange; + } + + void onBrowserUrlChange(string newUrl) + { + if (!ParseUtils.TryGetValueFromUrl(newUrl, ParseParameter.token, out var parsedToken)) + return; + + XsollaToken.Create(parsedToken); + onSuccess?.Invoke(); + + browser.CloseEvent -= onBrowserClose; + browser.UrlChangeEvent -= onBrowserUrlChange; + XsollaWebBrowser.Close(); + } + + browser.CloseEvent += onBrowserClose; + browser.UrlChangeEvent += onBrowserUrlChange; + } + + /// + /// Authenticates the user via Xsolla Launcher + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-launcher/#unity_sdk_how_to_set_up_auth_via_launcher). + /// Called after successful authentication. + /// Called after the request resulted with an error. + public static void AuthViaXsollaLauncher(Action onSuccess, Action onError) + { + new XsollaLauncherAuth().Perform(onSuccess, onError); + } + + /// + /// Logs the user out and deletes the user session according to the value of the sessions parameter (OAuth2.0 only). + /// + /// Called after successful user logout. + /// Called after the request resulted with an error. + /// Shows how the user is logged out and how the user session is deleted. Can be `sso` or `all` (default). Leave empty to use the default value. + public static void Logout(Action onSuccess, Action onError, LogoutType logoutType = LogoutType.All) + { + var url = new UrlBuilder(BASE_URL + "/oauth2/logout") + .AddParam("sessions", logoutType.ToString().ToLowerInvariant()) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + onError); + + XsollaToken.DeleteSavedInstance(); + } + + /// + /// This method is used for authenticating users in Xsolla Login, + /// who play on the consoles and other platforms + /// where Xsolla Login isn't used. You must implement it + /// on your server side. + /// Integration flow on the server side: + /// + /// + /// Generate server JWT + /// + /// + /// + /// Connect OAuth 2.0 server client. + /// Follow the [instructions](https://developers.xsolla.com/doc/login/security/connecting-oauth2/#login_features_connecting_oauth2_connecting_client) to connect the client and cope copy the Client ID and Secret key. + /// + /// + /// + /// Implement method: + /// + /// + /// with `application/x-www-form-urlencoded` payload parameters: + /// + /// + /// client_id=YOUR_CLIENT_ID + /// + /// + /// client_secret=YOUR_CLIENT_SECRET + /// + /// + /// grant_type=client_credentials + /// + /// + /// + /// + /// + /// + /// + /// + /// Implement auth method + /// + /// + /// with: + /// + /// + /// Query parameters + /// ?publisher_project_id=XsollaSettings.StoreProjectId + /// + /// + /// Headers + /// + /// `Content-Type: application/json` and `X-SERVER-AUTHORIZATION: YourGeneratedJwt` + /// + /// + /// + /// [More information about authentication via custom ID](https://developers.xsolla.com/sdk/unity/authentication/auth-via-custom-id/). + /// + /// + /// + /// + /// + /// + /// + /// Social platform (XBox, PS4, etc) user unique identifier. + /// Platform name (XBox, PS4, etc). + /// Called after successful user authentication. Authentication data including the JWT will be received. + /// Called after the request resulted with an error. + public static void SignInConsoleAccount(string userId, string platform, Action onSuccess, Action onError) + { + var withLogoutValue = XsollaSettings.InvalidateExistingSessions ? "1" : "0"; + var url = new UrlBuilder("https://livedemo.xsolla.com/sdk/sdk-shadow-account/auth") + .AddParam("user_id", userId) + .AddPlatform(platform) + .AddParam("with_logout", withLogoutValue) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + response => + { + XsollaToken.Create(response.token); + onSuccess?.Invoke(); + }, + onError); + } + + /// + /// Authenticates the user via a particular device ID. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). + /// Called after successful user authentication via the device ID. + /// Called after the request resulted with an error. + /// Information about the device that is used to identify the user. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. + public static void AuthViaDeviceID(Action onSuccess, Action onError, DeviceInfo deviceInfo = null, string redirectUri = null, string state = null) + { +#if !(UNITY_ANDROID || UNITY_IOS) + onError?.Invoke(new Error(ErrorType.NotSupportedOnCurrentPlatform, "This method is only available for Android and iOS platforms")); +#else + if (deviceInfo == null) + { + deviceInfo = new DeviceInfo { + DeviceId = DeviceIdUtil.GetDeviceId(), + DeviceModel = DeviceIdUtil.GetDeviceModel(), + DeviceName = DeviceIdUtil.GetDeviceName() + }; + +#if UNITY_ANDROID + deviceInfo.DeviceType = Core.DeviceType.Android; +#elif UNITY_IOS + deviceInfo.DeviceType = Core.DeviceType.iOS; +#endif + } + + var deviceType = deviceInfo.DeviceType.ToString().ToLower(); + var url = new UrlBuilder(BASE_URL + $"/oauth2/login/device/{deviceType}") + .AddClientId(XsollaSettings.OAuthClientId) + .AddResponseType(GetResponseType()) + .AddState(GetState(state)) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddScope(GetScope()) + .Build(); + + var requestData = new AuthViaDeviceIdRequest { + device = $"{deviceInfo.DeviceModel}:{deviceInfo.DeviceName}", + device_id = deviceInfo.DeviceId + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + response => ParseCodeFromUrlAndExchangeToToken(response.login_url, onSuccess, onError), + onError, + ErrorGroup.LoginErrors); +#endif + } + + /// + /// Authenticates a user by exchanging the session ticket from Steam, Xbox, or Epic Games to the JWT. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/silent-auth/). + /// Platform on which the session ticket was obtained. Can be `steam`, `xbox`, or `epicgames`. + /// Platform application identifier. + /// Session ticket received from the platform. + /// Called after successful user authentication with a platform session ticket. Authentication data including a JWT will be received. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Value used for additional user verification on backend. Must be at least 8 symbols long. Will be `xsollatest` by default. Used only for OAuth2.0 auth. + /// Code received from the platform. + public static void SilentAuth(string providerName, string appId, string sessionTicket, Action onSuccess, Action onError, string redirectUri = null, string state = null, string code = null) + { + var url = new UrlBuilder(BASE_URL + $"/oauth2/social/{providerName}/cross_auth") + .AddClientId(XsollaSettings.OAuthClientId) + .AddResponseType(GetResponseType()) + .AddState(GetState(state)) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddScope(GetScope()) + .AddParam("app_id", appId) + .AddParam("session_ticket", sessionTicket) + .AddParam("code", code) + .AddParam("is_redirect", "false") + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + response => ParseCodeFromUrlAndExchangeToToken(response.login_url, onSuccess, onError), + onError); + } + + /// + /// Returns URL for authentication via the specified social network in a browser. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/social-auth/#sdk_how_to_set_up_web_auth_via_social_networks). + /// Name of a social network. Provider must be connected to Login in Publisher Account. + /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, or `xbox`. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Value used for additional user verification on backend. Must be at least 8 symbols long. `xsollatest` by default. Required for OAuth 2.0. + public static string GetSocialNetworkAuthUrl(SocialProvider provider, string redirectUri = null, string state = null) + { + var providerValue = provider.ToApiParameter(); + var url = new UrlBuilder(BASE_URL + $"/oauth2/social/{providerValue}/login_redirect") + .AddClientId(XsollaSettings.OAuthClientId) + .AddState(GetState(state)) + .AddResponseType(GetResponseType()) + .AddRedirectUri(RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .AddScope(GetScope()) + .Build(); + + return WebRequestHelper.Instance.AppendAnalyticsToUrl(SdkType.Login, url); + } + + /// + /// Returns list of links for social authentication enabled in Publisher Account (your Login project > Authentication > Social login section). + /// The links are valid for 10 minutes. + /// You can get the link by this call and add it to your button for authentication via the social network. + /// + /// Called after list of links for social authentication was successfully received. + /// Called after the request resulted with an error. + /// Region in the `language code_country code` format, where: + /// - `language code` — language code in the [ISO 639-1](https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes) format; + /// - `country code` — country/region code in the [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) format.
+ /// The list of the links will be sorted from most to least used social networks, according to the variable value. + /// + public static void GetLinksForSocialAuth(Action onSuccess, Action onError, string locale = null) + { + var url = new UrlBuilder(BASE_URL + "/users/me/login_urls") + .AddLocale(locale) + .Build(); + + WebRequestHelper.Instance.GetRequest>( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + list => + { + onSuccess?.Invoke(new SocialNetworkLinks { + items = list + }); + }, + error => TokenAutoRefresher.Check(error, onError, () => GetLinksForSocialAuth(onSuccess, onError, locale))); + } + + /// + /// Refreshes the token in case it is expired. Works only when OAuth 2.0 is enabled. + /// + /// Called after successful token refreshing. Refresh data including the JWT will be received. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + public static void RefreshToken(Action onSuccess, Action onError, string redirectUri = null) + { +#if UNITY_ANDROID && !UNITY_EDITOR + new AndroidRefreshToken().Perform(onSuccess, onError); +#else + var refreshToken = XsollaToken.RefreshToken; + if (string.IsNullOrEmpty(refreshToken)) + { + onError?.Invoke(new Error(ErrorType.InvalidToken, errorMessage: "Invalid refresh token")); + return; + } + + var requestData = new WWWForm(); + requestData.AddField("client_id", XsollaSettings.OAuthClientId); + requestData.AddField("redirect_uri", RedirectUrlHelper.GetRedirectUrl(redirectUri)); + requestData.AddField("grant_type", "refresh_token"); + requestData.AddField("refresh_token", refreshToken); + + const string url = BASE_URL + "/oauth2/token"; + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + response => + { + XsollaToken.Create(response.access_token, response.refresh_token); + onSuccess?.Invoke(); + }, + error => onError?.Invoke(error)); +#endif + } + + /// + /// Exchanges the user authentication code to a valid JWT. + /// + /// Access code received from several other OAuth 2.0 requests (example: code from social network authentication). + /// Called after successful exchanging. Contains exchanged token. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + public static void ExchangeCodeToToken(string code, Action onSuccess, Action onError, string redirectUri = null) + { + const string url = BASE_URL + "/oauth2/token"; + + var requestData = new WWWForm(); + requestData.AddField("client_id", XsollaSettings.OAuthClientId); + requestData.AddField("redirect_uri", RedirectUrlHelper.GetRedirectUrl(redirectUri)); + requestData.AddField("grant_type", "authorization_code"); + requestData.AddField("code", code); + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + response => + { + XsollaToken.Create(response.access_token, response.refresh_token); + onSuccess?.Invoke(); + }, + error => onError?.Invoke(error)); + } + + /// + /// Returns user details. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// Called after successful user details were successfully received. + /// Called after the request resulted with an error. + public static void GetUserInfo(Action onSuccess, Action onError) + { + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + BASE_URL + "/users/me", + WebRequestHeader.AuthHeader(), + onSuccess, + onError); + } + + /// + /// Authenticates user via an account in the specified social networks. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/social-auth/). + /// Name of a social network. Provider must be connected to Login in Publisher Account. + /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, or `xbox`. + /// Called after successful user authentication. + /// Called after the request resulted with an error. + /// Called in case user closed browser. + public static void AuthViaSocialNetwork(SocialProvider provider, Action onSuccess, Action onError, Action onCancel) + { +#if UNITY_WEBGL + onError?.Invoke(new Error(ErrorType.NotSupportedOnCurrentPlatform, errorMessage: "Social auth is not supported for WebGL")); +#elif UNITY_ANDROID + new AndroidSocialAuth().Perform(provider, onSuccess, onError, onCancel); +#elif UNITY_IOS + new IosSocialAuth().Perform(provider, onSuccess, onError, onCancel); +#else + new StandaloneSocialAuth().Perform(provider, onSuccess, onError, onCancel); +#endif + } + + private static void ParseCodeFromUrlAndExchangeToToken(string url, Action onSuccess, Action onError) + { + if (ParseUtils.TryGetValueFromUrl(url, ParseParameter.code, out var parsedCode)) + ExchangeCodeToToken(parsedCode, onSuccess, onError); + else + onError?.Invoke(Error.UnknownError); + } + + private static string GetState(string oauthState) + { + return !string.IsNullOrEmpty(oauthState) + ? oauthState + : "xsollatest"; + } + + private static string GetResponseType() + { + return "code"; + } + + private static string GetScope() + { + return "offline"; + } + } +} diff --git a/Assets/Xsolla/Auth/Api/XsollaAuth.User.cs.meta b/Assets/Xsolla/Auth/XsollaAuth.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Api/XsollaAuth.User.cs.meta rename to Assets/Xsolla/Auth/XsollaAuth.cs.meta diff --git a/Assets/Xsolla/CHANGELOG.md b/Assets/Xsolla/CHANGELOG.md index 74db167b6..d9e29ba11 100644 --- a/Assets/Xsolla/CHANGELOG.md +++ b/Assets/Xsolla/CHANGELOG.md @@ -1,4 +1,38 @@ # Changelog +## [2.0.0] - 2023-05-18 +### Added +- `XsollaAuth.AuthViaSocialNetwork` SDK method for cross-platform social network authentication. Method incapsulates web-based and native authentication methods +- `XsollaAuth.AuthViaXsollaLauncher` SDK method for authentication via Xsolla Launcher +- `XsollaAuth.AuthViaSavedToken` SDK method for authentication with a saved token which was received during previous authentication +- `XsollaAuth.IsUserAuthenticated` SDK method for checking if the user is authenticated +- `XsollaCatalog.Purchase` SDK method for purchasing virtual items for real money +- `XsollaCatalog.PurchaseForVirtualCurrency` SDK method for purchasing virtual items for virtual currency +- `XsollaCatalog.PurchaseFreeItem` SDK method for purchasing free virtual items +- `XsollaCart.Purchase` SDK method for purchasing virtual items from the cart for real money +- `XsollaCart.PurchaseFreeCart` method for purchasing free virtual items from the cart +- `SteamUtils` class which provides additional methods for authentication and purchasing via Steam + +### Changed +- All methods and classes of requests are static now. You don't have to use the singleton `Instance` property anymore +- All authorization methods in `XsollaAuth` class don't pass `token` as success callback parameter now. They save token data locally for further use. Use `XsollaToken` class to get token data if you need it +- All requests which required authorization has silent refresh token logic now +- `XsollaAuth.AuthViaDeviceID` SDK method. Device info parameters are optional now. SDK detects required parameters such as `device_id` automatically if not specified +- `XsollaAuth.Logout` SDK method. It invalidates local saved token data +- Class `Token` renamed to `XsollaToken` and made static +- SDK methods of `XsollaCart` class. Method overloads where removed. Parameter `cartId` is optional, if not specified method uses current cart ID +- `XsollaAuth.Register` SDK method. It passes `LoginLink` as success callback parameter +- `XsollaAuth.StartAuthByEmail` and `XsollaAuth.StartAuthByPhoneNumber` SDK methods. They pass `OperationId` as success callback parameter +- `BrowserUtils` renamed to `XsollaWebBrowser` +- `Canvas` component for `XsollaInAppBrowser` + +### Removed +- Class `OrderTracking` is internal now and not available for use in the client code +- All Android and iOS helper classes are internal now and not available for use in the client code + +### Fixed +- Disabling `bitcode` parameter of Xcode project for iOS builds + + ## [1.5.0] - 2023-03-27 ### Added - User login with Xsolla Login widget diff --git a/Assets/Xsolla/Cart/Api.meta b/Assets/Xsolla/Cart/Api.meta deleted file mode 100644 index d8ad48ede..000000000 --- a/Assets/Xsolla/Cart/Api.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 00381d9fad7a37c4d97ad0d51112c3eb -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Cart/Api/XsollaCart.cs b/Assets/Xsolla/Cart/Api/XsollaCart.cs deleted file mode 100644 index adad65817..000000000 --- a/Assets/Xsolla/Cart/Api/XsollaCart.cs +++ /dev/null @@ -1,351 +0,0 @@ -using System; -using System.Collections.Generic; -using JetBrains.Annotations; -using Xsolla.Core; - -namespace Xsolla.Cart -{ - public partial class XsollaCart : MonoSingleton - { - private const string URL_CART_CURRENT_GET_ITEMS = Constants.BASE_STORE_API_URL + "/cart"; - private const string URL_CART_GET_ITEMS = Constants.BASE_STORE_API_URL + "/cart/{1}"; - - private const string URL_CART_CURRENT_ITEM_UPDATE = Constants.BASE_STORE_API_URL + "/cart/item/{1}"; - private const string URL_CART_SPECIFIC_ITEM_UPDATE = Constants.BASE_STORE_API_URL + "/cart/{1}/item/{2}"; - - private const string URL_CART_CURRENT_ITEM_REMOVE = Constants.BASE_STORE_API_URL + "/cart/item/{1}"; - private const string URL_CART_SPECIFIC_ITEM_REMOVE = Constants.BASE_STORE_API_URL + "/cart/{1}/item/{2}"; - - private const string URL_CART_CURRENT_CLEAR = Constants.BASE_STORE_API_URL + "/cart/clear"; - private const string URL_CART_SPECIFIC_CLEAR = Constants.BASE_STORE_API_URL + "/cart/{1}/clear"; - - private const string URL_CART_CURRENT_FILL = Constants.BASE_STORE_API_URL + "/cart/fill"; - private const string URL_CART_SPECIFIC_FILL = Constants.BASE_STORE_API_URL + "/cart/{1}/fill"; - - private const string URL_REDEEM_PROMOCODE = Constants.BASE_STORE_API_URL + "/promocode/redeem"; - private const string URL_GET_PROMOCODE_REWARD = Constants.BASE_STORE_API_URL + "/promocode/code/{1}/rewards"; - private const string URL_REMOVE_PROMOCODE_FROM_CART = Constants.BASE_STORE_API_URL + "/promocode/remove"; - - private const string URL_BUY_CURRENT_CART = Constants.BASE_STORE_API_URL + "/payment/cart"; - private const string URL_BUY_SPECIFIC_CART = Constants.BASE_STORE_API_URL + "/payment/cart/{1}"; - - private const string URL_BUY_CURRENT_FREE_CART = Constants.BASE_STORE_API_URL + "/free/cart"; - private const string URL_BUY_SPECIFIC_FREE_CART = Constants.BASE_STORE_API_URL + "/free/cart/{1}"; - - /// - /// Returns a list of items from the cart of the current user. For each item, complete data is returned. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after local cache of cart items was successfully updated. - /// Called after the request resulted with an error. - /// Defines localization of item's text fields.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// The currency in which prices are displayed. Three-letter currency code per [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (USD by default). - public void GetCartItems(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, [CanBeNull] string currency = null) - { - var url = string.Format(URL_CART_CURRENT_GET_ITEMS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, locale: locale, currency: currency); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetCartItems(projectId, onSuccess, onError, locale, currency)), - ErrorCheckType.CreateCartErrors); - } - - /// - /// Returns a list of items from the cart with the specified ID. For each item, complete data is returned. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique cart identifier. - /// Called after local cache of cart items was successfully updated. - /// Called after the request resulted with an error. - /// Defines localization of item's text fields.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// The currency in which prices are displayed. Three-letter currency code per [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (USD by default). - public void GetCartItems(string projectId, string cartId, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, [CanBeNull] string currency = null) - { - var url = string.Format(URL_CART_GET_ITEMS, projectId, cartId); - url = UrlParameterizer.ConcatUrlAndParams(url, locale: locale, currency: currency); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetCartItems(projectId, cartId, onSuccess, onError, locale, currency)), - ErrorCheckType.GetCartItemsErrors); - } - - /// - /// Fills the cart of the current user with items. If there is already an item with the same SKU in the cart, the existing item position will be replaced by the passed value. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Item for filling the cart. If there is already an item with the same SKU in the cart, the existing item position will be replaced by the passed value. - /// Called after cart is successfully filled. - /// Called after the request resulted with an error. - public void FillCart(string projectId, List items, [NotNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_CART_CURRENT_FILL, projectId); - var entity = new CartFillEntity { items = items }; - WebRequestHelper.Instance.PutRequest(SdkType.Store, url, entity, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => FillCart(projectId, items, onSuccess, onError)), - ErrorCheckType.CreateCartErrors); - } - - /// - /// Fills the cart with the specified ID with items. If there is already an item with the same SKU in the cart, the existing item position will be replaced by the passed value. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique cart identifier. - /// Item for filling the cart. If there is already an item with the same SKU in the cart, the existing item position will be replaced by the passed value. - /// Called after cart is successfully filled. - /// Called after the request resulted with an error. - public void FillCart(string projectId, string cartId, List items, [NotNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_CART_SPECIFIC_FILL, projectId, cartId); - var entity = new CartFillEntity { items = items }; - WebRequestHelper.Instance.PutRequest(SdkType.Store, url, entity, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => FillCart(projectId, cartId, items, onSuccess, onError)), - ErrorCheckType.CreateCartErrors); - } - - /// - /// Updates the quantity of a previously added item in the current user cart. If there is no item with the specified SKU in the cart, it will be added. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// SKU of item for purchase. - /// Quantity of purchased item. - /// Called after successfully adding a new item to the cart. - /// Called after the request resulted with an error. - /// - public void UpdateItemInCart(string projectId, string itemSku, int quantity, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_CART_CURRENT_ITEM_UPDATE, projectId, itemSku); - var jsonObject = new Quantity { quantity = quantity }; - WebRequestHelper.Instance.PutRequest(SdkType.Store, url, jsonObject, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UpdateItemInCart(projectId, itemSku, quantity, onSuccess, onError)), - ErrorCheckType.AddToCartCartErrors); - } - - /// - /// Updates the quantity of a previously added item in the cart with the specified ID. If there is no item with the specified SKU in the cart, it will be added. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique cart identifier. - /// SKU of item for purchase. - /// Quantity of purchased items. - /// Called after successfully adding a new item to the cart. - /// Called after the request resulted with an error. - /// - public void UpdateItemInCart(string projectId, string cartId, string itemSku, int quantity, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_CART_SPECIFIC_ITEM_UPDATE, projectId, cartId, itemSku); - var jsonObject = new Quantity { quantity = quantity }; - WebRequestHelper.Instance.PutRequest(SdkType.Store, url, jsonObject, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UpdateItemInCart(projectId, cartId, itemSku, quantity, onSuccess, onError)), - ErrorCheckType.AddToCartCartErrors); - } - - /// - /// Removes the item from the cart of the current user. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Item SKU to delete. - /// Called after successfully removing an item from the cart. - /// Called after the request resulted with an error. - public void RemoveItemFromCart(string projectId, string itemSku, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_CART_CURRENT_ITEM_REMOVE, projectId, itemSku); - WebRequestHelper.Instance.DeleteRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => RemoveItemFromCart(projectId, itemSku, onSuccess, onError)), - ErrorCheckType.DeleteFromCartErrors); - } - - /// - /// Removes the item from the cart with the specified ID. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique cart identifier. - /// Item SKU to delete. - /// Called after successfully removing an item from the cart. - /// Called after the request resulted with an error. - public void RemoveItemFromCart(string projectId, string cartId, string itemSku, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_CART_SPECIFIC_ITEM_REMOVE, projectId, cartId, itemSku); - WebRequestHelper.Instance.DeleteRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => RemoveItemFromCart(projectId, cartId, itemSku, onSuccess, onError)), - ErrorCheckType.DeleteFromCartErrors); - } - - /// - /// Removes all items from the cart of the current user. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after successful cart clearing. - /// Called after the request resulted with an error. - public void ClearCart(string projectId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_CART_CURRENT_CLEAR, projectId); - WebRequestHelper.Instance.PutRequest(SdkType.Store, url, null, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => ClearCart(projectId, onSuccess, onError)), - ErrorCheckType.AddToCartCartErrors); - } - - /// - /// Removes all items from the cart with the specified ID. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique cart identifier. - /// Called after successful cart clearing. - /// Called after the request resulted with an error. - public void ClearCart(string projectId, string cartId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_CART_SPECIFIC_CLEAR, projectId, cartId); - WebRequestHelper.Instance.PutRequest(SdkType.Store, url, null, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => ClearCart(projectId, cartId, onSuccess, onError)), - ErrorCheckType.AddToCartCartErrors); - } - - /// - /// Redeems a promo code. After activating the promo code, the user gets free items and/or the price of the cart is reduced. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/promo-codes/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique code of promocode. Contains letters and numbers. - /// Unique cart identifier. The current user cart will be updated if empty. - /// Called after successful promocode redemption. - /// Called after the request resulted with an error. - public void RedeemPromocode(string projectId, string promocode, string cartId, [NotNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_REDEEM_PROMOCODE, projectId); - var request = new RedeemPromocodeRequest() - { - coupon_code = promocode, - cart = string.IsNullOrEmpty(cartId) ? null : new RedeemPromocodeRequest.Cart { id = cartId } - }; - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, request, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => RedeemPromocode(projectId, promocode, cartId, onSuccess, onError)), - ErrorCheckType.DeleteFromCartErrors); - } - - /// - /// Returns a list of items that can be credited to the user when the promo code is activated. Allows users to choose from several available items. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/promo-codes/#sdk_promo_codes). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique code of promocode. Contains letters and numbers. - /// Called after successfully receiving promocode rewards. - /// Called after the request resulted with an error. - public void GetPromocodeReward(string projectId, string promocode, [NotNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_GET_PROMOCODE_REWARD, projectId, promocode); - - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetPromocodeReward(projectId, promocode, onSuccess, onError)), - ErrorCheckType.DeleteFromCartErrors); - } - - /// - /// Removes a promo code from a cart. After the promo code is removed, the total price of all items in the cart will be recalculated without bonuses and discounts provided by a promo code. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/promo-codes/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Cart ID. The current user cart will be updated if empty. - /// Called after the promo code has been successful removed from cart. - /// Called after the request resulted with an error. - public void RemovePromocodeFromCart(string projectId, string cartId, Action onSuccess, Action onError = null) - { - var data = new RemovePromocodeFromCartRequest(cartId); - var url = string.Format(URL_REMOVE_PROMOCODE_FROM_CART, projectId); - - WebRequestHelper.Instance.PutRequest(SdkType.Store, url, data, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => RemovePromocodeFromCart(projectId, cartId, onSuccess, onError)), - ErrorCheckType.DeleteFromCartErrors); - } - - /// - /// Creates an order with items from the cart of the current user. Returns the payment token and order ID. The created order will get a `new` order status. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after the payment token was successfully fetched. - /// Called after the request resulted with an error. - /// Purchase parameters such as country, locale and currency. - /// Custom web request headers. - public void PurchaseCart(string projectId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) - { - var tempPurchaseParams = PurchaseParamsGenerator.GenerateTempPurchaseParams(purchaseParams); - var url = string.Format(URL_BUY_CURRENT_CART, projectId); - var paymentHeaders = PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance, customHeaders); - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, tempPurchaseParams, paymentHeaders, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => PurchaseCart(projectId, onSuccess, onError, purchaseParams, customHeaders)), - ErrorCheckType.BuyCartErrors); - } - - /// - /// Creates an order with items from the cart with the specified ID. Returns the payment token and order ID. The created order will get a `new` order status. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique cart identifier. - /// Called after the payment token was successfully fetched. - /// Called after the request resulted with an error. - /// Purchase parameters such as country, locale and currency. - /// Custom web request headers. - public void PurchaseCart(string projectId, string cartId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) - { - var tempPurchaseParams = PurchaseParamsGenerator.GenerateTempPurchaseParams(purchaseParams); - var url = string.Format(URL_BUY_SPECIFIC_CART, projectId, cartId); - var paymentHeaders = PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance, customHeaders); - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, tempPurchaseParams, paymentHeaders, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => PurchaseCart(projectId, cartId, onSuccess, onError, purchaseParams, customHeaders)), - ErrorCheckType.BuyCartErrors); - } - - /// - /// Create order with free cart. The created order will get a `done` order status. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/free-items/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after the payment was successfully completed. - /// Called after the request resulted with an error. - /// Purchase parameters such as country, locale and currency. - /// Custom web request headers. - public void CreateOrderWithFreeCart(string projectId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) - { - var tempPurchaseParams = PurchaseParamsGenerator.GenerateTempPurchaseParams(purchaseParams); - var url = string.Format(URL_BUY_CURRENT_FREE_CART, projectId); - var paymentHeaders = PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance, customHeaders); - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, tempPurchaseParams, paymentHeaders, - onComplete: purchaseData => onSuccess?.Invoke(purchaseData.order_id), - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => CreateOrderWithFreeCart(projectId, onSuccess, onError, purchaseParams, customHeaders)), - ErrorCheckType.BuyCartErrors); - } - - /// - /// Create order with particular free cart. The created order will get a `done` order status. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/free-items/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique cart identifier. - /// Called after server response. - /// Called after the request resulted with an error. - /// Purchase parameters such as country, locale and currency. - /// Custom web request headers. - public void CreateOrderWithParticularFreeCart(string projectId, string cartId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) - { - var tempPurchaseParams = PurchaseParamsGenerator.GenerateTempPurchaseParams(purchaseParams); - var url = string.Format(URL_BUY_SPECIFIC_FREE_CART, projectId, cartId); - var paymentHeaders = PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance, customHeaders); - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, tempPurchaseParams, paymentHeaders, - onComplete: purchaseData => onSuccess?.Invoke(purchaseData.order_id), - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => CreateOrderWithParticularFreeCart(projectId, cartId, onSuccess, onError, purchaseParams, customHeaders)), - ErrorCheckType.BuyCartErrors); - } - } -} diff --git a/Assets/Xsolla/Cart/Entities/Cart.cs b/Assets/Xsolla/Cart/Entities/Cart.cs index ea62e6dcf..69ddc3c99 100644 --- a/Assets/Xsolla/Cart/Entities/Cart.cs +++ b/Assets/Xsolla/Cart/Entities/Cart.cs @@ -1,9 +1,14 @@ using System; +using Xsolla.Core; namespace Xsolla.Cart { [Serializable] - public class Cart : CartItems + public class Cart { + public string cart_id; + public bool is_free; + public Price price; + public CartItem[] items; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/CartFillItem.cs b/Assets/Xsolla/Cart/Entities/CartFillItem.cs index b4ef63812..43bad4fe6 100644 --- a/Assets/Xsolla/Cart/Entities/CartFillItem.cs +++ b/Assets/Xsolla/Cart/Entities/CartFillItem.cs @@ -8,4 +8,4 @@ public class CartFillItem public string sku; public int quantity; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/CartItem.cs b/Assets/Xsolla/Cart/Entities/CartItem.cs index c3824d125..35a7866a2 100644 --- a/Assets/Xsolla/Cart/Entities/CartItem.cs +++ b/Assets/Xsolla/Cart/Entities/CartItem.cs @@ -6,23 +6,6 @@ namespace Xsolla.Cart [Serializable] public class CartItem { - [Serializable] - public class Group - { - public string external_id; - public string name; - } - [Serializable] - public class InventoryOptions - { - [Serializable] - public class ConsumableOption - { - public int? usages_count; - } - public StoreItem.InventoryOptions.ConsumableOption consumable; - } - public string sku; public string name; public string type; @@ -37,5 +20,12 @@ public class ConsumableOption public VirtualPrice[] virtual_prices; public StoreItem.InventoryOptions inventory_options; public int quantity; + + [Serializable] + public class Group + { + public string external_id; + public string name; + } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/CartItems.cs b/Assets/Xsolla/Cart/Entities/CartItems.cs deleted file mode 100644 index a75ac3a53..000000000 --- a/Assets/Xsolla/Cart/Entities/CartItems.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Cart -{ - [Serializable] - public class CartItems - { - public string cart_id; - public bool is_free; - public Price price; - public CartItem[] items; - } -} diff --git a/Assets/Xsolla/Cart/Entities/CartItems.cs.meta b/Assets/Xsolla/Cart/Entities/CartItems.cs.meta deleted file mode 100644 index b5e529018..000000000 --- a/Assets/Xsolla/Cart/Entities/CartItems.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 5b950c684599c6047a89e81e0f73c04e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Cart/Entities/PromocodeReward.cs b/Assets/Xsolla/Cart/Entities/PromocodeReward.cs index d4e91e5f1..f35e6df5d 100644 --- a/Assets/Xsolla/Cart/Entities/PromocodeReward.cs +++ b/Assets/Xsolla/Cart/Entities/PromocodeReward.cs @@ -5,26 +5,10 @@ namespace Xsolla.Cart [Serializable] public class PromocodeReward { - [Serializable] - public class UnitItem - { - public string sku; - public string type; - public string name; - public string drm_name; - public string drm_sku; - } - - [Serializable] - public class RewardItem - { - public string sku; - public string name; - public string type; - public string description; - public string image_url; - public UnitItem[] unit_items; - } + public BonusItem[] bonus; + public Discount discount; + public DiscountedItems discounted_items; + public bool is_selectable; [Serializable] public class BonusItem @@ -32,7 +16,7 @@ public class BonusItem public RewardItem item; public int quantity; } - + [Serializable] public class Discount { @@ -46,9 +30,25 @@ public class DiscountedItems public Discount discount; } - public BonusItem[] bonus; - public Discount discount; - public DiscountedItems discounted_items; - public bool is_selectable; + [Serializable] + public class RewardItem + { + public string sku; + public string name; + public string type; + public string description; + public string image_url; + public UnitItem[] unit_items; + } + + [Serializable] + public class UnitItem + { + public string sku; + public string type; + public string name; + public string drm_name; + public string drm_sku; + } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartRequest.cs b/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartRequest.cs deleted file mode 100644 index 7322e0c2a..000000000 --- a/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartRequest.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Xsolla.Cart -{ - [Serializable] - public class RemovePromocodeFromCartRequest - { - public string id; - - public RemovePromocodeFromCartRequest(string id) - { - this.id = id; - } - } -} diff --git a/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResponse.cs b/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResult.cs similarity index 89% rename from Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResponse.cs rename to Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResult.cs index fe5b4d405..877d4f9a4 100644 --- a/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResponse.cs +++ b/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResult.cs @@ -4,7 +4,7 @@ namespace Xsolla.Cart { [Serializable] - public class RemovePromocodeFromCartResponse + public class RemovePromocodeFromCartResult { public string cart_id; public Price price; @@ -24,4 +24,4 @@ public class Item public bool is_free; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResponse.cs.meta b/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResult.cs.meta similarity index 100% rename from Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResponse.cs.meta rename to Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartResult.cs.meta diff --git a/Assets/Xsolla/Cart/Internal.meta b/Assets/Xsolla/Cart/Internal.meta new file mode 100644 index 000000000..51b4d528a --- /dev/null +++ b/Assets/Xsolla/Cart/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0ee42593eabc47729a3d8aeec4e0af37 +timeCreated: 1682697708 \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/CartFillEntity.cs b/Assets/Xsolla/Cart/Internal/CartFillRequest.cs similarity index 79% rename from Assets/Xsolla/Cart/Entities/CartFillEntity.cs rename to Assets/Xsolla/Cart/Internal/CartFillRequest.cs index b82ccbae6..dfd9ea360 100644 --- a/Assets/Xsolla/Cart/Entities/CartFillEntity.cs +++ b/Assets/Xsolla/Cart/Internal/CartFillRequest.cs @@ -4,8 +4,8 @@ namespace Xsolla.Cart { [Serializable] - public class CartFillEntity + internal class CartFillRequest { public List items; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/CartFillEntity.cs.meta b/Assets/Xsolla/Cart/Internal/CartFillRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Cart/Entities/CartFillEntity.cs.meta rename to Assets/Xsolla/Cart/Internal/CartFillRequest.cs.meta diff --git a/Assets/Xsolla/Cart/Entities/Quantity.cs b/Assets/Xsolla/Cart/Internal/QuantityRequest.cs similarity index 72% rename from Assets/Xsolla/Cart/Entities/Quantity.cs rename to Assets/Xsolla/Cart/Internal/QuantityRequest.cs index c6d55f71e..ef227d69b 100644 --- a/Assets/Xsolla/Cart/Entities/Quantity.cs +++ b/Assets/Xsolla/Cart/Internal/QuantityRequest.cs @@ -3,8 +3,8 @@ namespace Xsolla.Cart { [Serializable] - public class Quantity + internal class QuantityRequest { public int quantity; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/Quantity.cs.meta b/Assets/Xsolla/Cart/Internal/QuantityRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Cart/Entities/Quantity.cs.meta rename to Assets/Xsolla/Cart/Internal/QuantityRequest.cs.meta diff --git a/Assets/Xsolla/Cart/Entities/RedeemPromocodeRequest.cs b/Assets/Xsolla/Cart/Internal/RedeemPromocodeRequest.cs similarity index 79% rename from Assets/Xsolla/Cart/Entities/RedeemPromocodeRequest.cs rename to Assets/Xsolla/Cart/Internal/RedeemPromocodeRequest.cs index 4e15c490e..b90b87d47 100644 --- a/Assets/Xsolla/Cart/Entities/RedeemPromocodeRequest.cs +++ b/Assets/Xsolla/Cart/Internal/RedeemPromocodeRequest.cs @@ -3,14 +3,14 @@ namespace Xsolla.Cart { [Serializable] - public class RedeemPromocodeRequest + internal class RedeemPromocodeRequest { + public string coupon_code; + public Cart cart; + public class Cart { public string id; } - - public string coupon_code; - public Cart cart; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/RedeemPromocodeRequest.cs.meta b/Assets/Xsolla/Cart/Internal/RedeemPromocodeRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Cart/Entities/RedeemPromocodeRequest.cs.meta rename to Assets/Xsolla/Cart/Internal/RedeemPromocodeRequest.cs.meta diff --git a/Assets/Xsolla/Cart/Internal/RemovePromocodeFromCartRequest.cs b/Assets/Xsolla/Cart/Internal/RemovePromocodeFromCartRequest.cs new file mode 100644 index 000000000..c08b73cce --- /dev/null +++ b/Assets/Xsolla/Cart/Internal/RemovePromocodeFromCartRequest.cs @@ -0,0 +1,10 @@ +using System; + +namespace Xsolla.Cart +{ + [Serializable] + internal class RemovePromocodeFromCartRequest + { + public string id; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartRequest.cs.meta b/Assets/Xsolla/Cart/Internal/RemovePromocodeFromCartRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Cart/Entities/RemovePromocodeFromCartRequest.cs.meta rename to Assets/Xsolla/Cart/Internal/RemovePromocodeFromCartRequest.cs.meta diff --git a/Assets/Xsolla/Cart/XsollaCart.cs b/Assets/Xsolla/Cart/XsollaCart.cs new file mode 100644 index 000000000..acac7bac8 --- /dev/null +++ b/Assets/Xsolla/Cart/XsollaCart.cs @@ -0,0 +1,331 @@ +using System; +using System.Collections.Generic; +using Xsolla.Core; + +namespace Xsolla.Cart +{ + public static class XsollaCart + { + private static string BaseUrl => $"https://store.xsolla.com/api/v2/project/{XsollaSettings.StoreProjectId}"; + + /// + /// Returns a list of items from the cart with the specified ID. For each item, complete data is returned. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). + /// Called after local cache of cart items was successfully updated. + /// Called after the request resulted with an error. + /// Unique cart identifier. + /// Defines localization of item's text fields.
The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// The currency in which prices are displayed. Three-letter currency code per [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (USD by default). + public static void GetCartItems(Action onSuccess, Action onError, string cartId = null, string locale = null, string currency = null) + { + var url = string.IsNullOrEmpty(cartId) + ? BaseUrl + "/cart" + : BaseUrl + $"/cart/{cartId}"; + + url = new UrlBuilder(url) + .AddLocale(locale) + .AddCurrency(currency) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetCartItems(onSuccess, onError, cartId, locale, currency)), + ErrorGroup.CartErrors); + } + + /// + /// Fills the cart with the specified ID with items. If there is already an item with the same SKU in the cart, the existing item position will be replaced by the passed value. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). + /// Item for filling the cart. If there is already an item with the same SKU in the cart, the existing item position will be replaced by the passed value. + /// Called after cart is successfully filled. + /// Called after the request resulted with an error. + /// Unique cart identifier. + public static void FillCart(List items, Action onSuccess, Action onError, string cartId = null) + { + var url = string.IsNullOrWhiteSpace(cartId) + ? $"{BaseUrl}/cart/fill" + : $"{BaseUrl}/cart/{cartId}/fill"; + + var requestData = new CartFillRequest { + items = items + }; + + WebRequestHelper.Instance.PutRequest( + SdkType.Store, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => FillCart(items, onSuccess, onError, cartId)), + ErrorGroup.CartErrors); + } + + /// + /// Updates the quantity of a previously added item in the cart with the specified ID. If there is no item with the specified SKU in the cart, it will be added. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). + /// SKU of item for purchase. + /// Quantity of purchased items. + /// Called after successfully adding a new item to the cart. + /// Called after the request resulted with an error. + /// Unique cart identifier. + public static void UpdateItemInCart(string itemSku, int quantity, Action onSuccess, Action onError, string cartId = null) + { + var url = string.IsNullOrWhiteSpace(cartId) + ? $"{BaseUrl}/cart/item/{itemSku}" + : $"{BaseUrl}/cart/{cartId}/item/{itemSku}"; + + var requestData = new QuantityRequest { + quantity = quantity + }; + + WebRequestHelper.Instance.PutRequest( + SdkType.Store, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => UpdateItemInCart(itemSku, quantity, onSuccess, onError, cartId)), + ErrorGroup.CartErrors); + } + + /// + /// Removes the item from the cart with the specified ID. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). + /// Item SKU to delete. + /// Called after successfully removing an item from the cart. + /// Called after the request resulted with an error. + /// Unique cart identifier. + public static void RemoveItemFromCart(string itemSku, Action onSuccess, Action onError, string cartId = null) + { + var url = string.IsNullOrWhiteSpace(cartId) + ? $"{BaseUrl}/cart/item/{itemSku}" + : $"{BaseUrl}/cart/{cartId}/item/{itemSku}"; + + WebRequestHelper.Instance.DeleteRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => RemoveItemFromCart(itemSku, onSuccess, onError, cartId)), + ErrorGroup.CartErrors); + } + + /// + /// Removes all items from the cart with the specified ID. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). + /// Called after successful cart clearing. + /// Called after the request resulted with an error. + /// Unique cart identifier. + public static void ClearCart(Action onSuccess, Action onError, string cartId = null) + { + var url = string.IsNullOrWhiteSpace(cartId) + ? $"{BaseUrl}/cart/clear" + : $"{BaseUrl}/cart/{cartId}/clear"; + + WebRequestHelper.Instance.PutRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => ClearCart(onSuccess, onError, cartId)), + ErrorGroup.CartErrors); + } + + /// + /// Redeems a promo code. After activating the promo code, the user gets free items and/or the price of the cart is reduced. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/promo-codes/). + /// Unique code of promocode. Contains letters and numbers. + /// Unique cart identifier. The current user cart will be updated if empty. + /// Called after successful promocode redemption. + /// Called after the request resulted with an error. + public static void RedeemPromocode(string promocode, string cartId, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/promocode/redeem"; + + var requestData = new RedeemPromocodeRequest { + coupon_code = promocode, + cart = string.IsNullOrEmpty(cartId) ? null : new RedeemPromocodeRequest.Cart {id = cartId} + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => RedeemPromocode(promocode, cartId, onSuccess, onError)), + ErrorGroup.CartErrors); + } + + /// + /// Returns a list of items that can be credited to the user when the promo code is activated. Allows users to choose from several available items. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/promo-codes/#sdk_promo_codes). + /// Unique code of promocode. Contains letters and numbers. + /// Called after successfully receiving promocode rewards. + /// Called after the request resulted with an error. + public static void GetPromocodeReward(string promocode, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/promocode/code/{promocode}/rewards"; + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetPromocodeReward(promocode, onSuccess, onError)), + ErrorGroup.CartErrors); + } + + /// + /// Removes a promo code from a cart. After the promo code is removed, the total price of all items in the cart will be recalculated without bonuses and discounts provided by a promo code. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/promo-codes/). + /// Cart ID. The current user cart will be updated if empty. + /// Called after the promo code has been successful removed from cart. + /// Called after the request resulted with an error. + public static void RemovePromocodeFromCart(string cartId, Action onSuccess, Action onError = null) + { + var url = $"{BaseUrl}/promocode/remove"; + + var requestData = new RemovePromocodeFromCartRequest { + id = cartId + }; + + WebRequestHelper.Instance.PutRequest( + SdkType.Store, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => RemovePromocodeFromCart(cartId, onSuccess, onError)), + ErrorGroup.CartErrors); + } + + /// + /// Creates an order with items from the cart with the specified ID. Returns the payment token and order ID. The created order will get a `new` order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). + /// Called after the order was successfully created. + /// Called after the request resulted with an error. + /// Unique cart identifier. + /// Purchase parameters such as country, locale, currency, and quantity. + /// Custom HTTP request headers. + public static void CreateOrder(Action onSuccess, Action onError, string cartId = null, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) + { + var url = string.IsNullOrWhiteSpace(cartId) + ? $"{BaseUrl}/payment/cart" + : $"{BaseUrl}/payment/cart/{cartId}"; + + var requestData = PurchaseParamsGenerator.GeneratePurchaseParamsRequest(purchaseParams); + var headers = PurchaseParamsGenerator.GeneratePaymentHeaders(customHeaders); + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => CreateOrder(onSuccess, onError, cartId, purchaseParams, customHeaders)), + ErrorGroup.BuyCartErrors); + } + + /// + /// Create order with particular free cart. The created order will get a `done` order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/free-items/). + /// Called after server response. + /// Called after the request resulted with an error. + /// Unique cart identifier. + /// Purchase parameters such as country, locale, currency, and quantity. + /// Custom HTTP request headers. + public static void CreateOrderWithFreeCart(Action onSuccess, Action onError, string cartId = null, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) + { + var url = string.IsNullOrWhiteSpace(cartId) + ? $"{BaseUrl}/free/cart" + : $"{BaseUrl}/free/cart/{cartId}"; + + var requestData = PurchaseParamsGenerator.GeneratePurchaseParamsRequest(purchaseParams); + var headers = PurchaseParamsGenerator.GeneratePaymentHeaders(customHeaders); + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + headers, + purchaseData => onSuccess?.Invoke(purchaseData), + error => TokenAutoRefresher.Check(error, onError, () => CreateOrderWithFreeCart(onSuccess, onError, cartId, purchaseParams, customHeaders)), + ErrorGroup.BuyCartErrors); + } + + /// + /// Launches purchase process for the cart with the specified ID or for the cart of the current user. This method encapsulates methods for creating an order, opening a payment UI, and tracking the order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/). + /// Called after the order transitions to the 'done' status. + /// Called after the request resulted with an error. + /// Unique cart identifier. + /// Called after browser closed. + /// Purchase parameters such as country, locale, and currency. + /// Custom HTTP request headers. + public static void Purchase(Action onSuccess, Action onError, string cartId = null, Action onBrowseClosed = null, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) + { + CreateOrder( + orderData => + { + XsollaWebBrowser.OpenPurchaseUI( + orderData.token, + false, + onBrowseClosed); + + OrderTrackingService.AddOrderForTracking(orderData.order_id, + true, () => + { + if (XsollaWebBrowser.InAppBrowser?.IsOpened ?? false) + XsollaWebBrowser.Close(); + + OrderStatusService.GetOrderStatus(orderData.order_id, onSuccess, onError); + }, onError); + }, + onError, + cartId, + purchaseParams, + customHeaders + ); + } + + /// + /// Launches purchase process for the free cart with the specified ID or for the free cart of the current user. This method encapsulates methods for creating an order and tracking the order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/free-items/). + /// Called after the order transitions to the 'done' status. + /// Called after the request resulted with an error. + /// Unique cart identifier. + /// Purchase parameters such as country, locale, and currency. + /// Custom HTTP request headers. + public static void PurchaseFreeCart(Action onSuccess, Action onError, string cartId = null, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) + { + CreateOrderWithFreeCart( + orderId => + { + OrderTrackingService.AddOrderForTracking( + orderId.order_id, + false, () => OrderStatusService.GetOrderStatus(orderId.order_id, onSuccess, onError), onError); + }, + onError, + cartId, + purchaseParams, + customHeaders + ); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Cart/Api/XsollaCart.cs.meta b/Assets/Xsolla/Cart/XsollaCart.cs.meta similarity index 100% rename from Assets/Xsolla/Cart/Api/XsollaCart.cs.meta rename to Assets/Xsolla/Cart/XsollaCart.cs.meta diff --git a/Assets/Xsolla/Catalog/Api.meta b/Assets/Xsolla/Catalog/Api.meta deleted file mode 100644 index 031c0af10..000000000 --- a/Assets/Xsolla/Catalog/Api.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b329646a2baed9a44a40fa9739e17fc0 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Catalog/Api/XsollaCatalog.cs b/Assets/Xsolla/Catalog/Api/XsollaCatalog.cs deleted file mode 100644 index ea6513e15..000000000 --- a/Assets/Xsolla/Catalog/Api/XsollaCatalog.cs +++ /dev/null @@ -1,311 +0,0 @@ -using System; -using System.Collections.Generic; -using JetBrains.Annotations; -using Xsolla.Core; - -namespace Xsolla.Catalog -{ - public partial class XsollaCatalog : MonoSingleton - { - private const string URL_CATALOG_GET_ALL_VIRTUAL_ITEMS = Constants.BASE_STORE_API_URL + "/items/virtual_items/all"; - private const string URL_CATALOG_GET_ITEMS = Constants.BASE_STORE_API_URL + "/items/virtual_items"; - private const string URL_CATALOG_GET_BUNDLE = Constants.BASE_STORE_API_URL + "/items/bundle/sku/{1}"; - private const string URL_CATALOG_GET_BUNDLES = Constants.BASE_STORE_API_URL + "/items/bundle"; - private const string URL_CATALOG_GET_ITEMS_IN_GROUP = Constants.BASE_STORE_API_URL + "/items/virtual_items/group/{1}"; - private const string URL_CATALOG_GET_GROUPS = Constants.BASE_STORE_API_URL + "/items/groups"; - - private const string URL_VIRTUAL_CURRENCY_LIST = Constants.BASE_STORE_API_URL + "/items/virtual_currency"; - private const string URL_VIRTUAL_CURRENCY_PACKAGES_IN_PROJECT = Constants.BASE_STORE_API_URL + "/items/virtual_currency/package"; - - private const string URL_INVENTORY_REDEEM_COUPON = Constants.BASE_STORE_API_URL + "/coupon/redeem"; - private const string URL_INVENTORY_GET_COUPON_REWARDS = Constants.BASE_STORE_API_URL + "/coupon/code/{1}/rewards"; - - private const string URL_BUY_ITEM = Constants.BASE_STORE_API_URL + "/payment/item/{1}"; - private const string URL_BUY_ITEM_FOR_VC = Constants.BASE_STORE_API_URL + "/payment/item/{1}/virtual/{2}"; - - private const string URL_CREATE_FREE_ORDER_WITH_ITEM = Constants.BASE_STORE_API_URL + "/free/item/{1}"; - - /// - /// Returns a list of virtual items according to pagination settings. - /// The list includes items for which display in the store is enabled in the settings. For each virtual item, complete data is returned. - /// If used after user authentication, the method returns items that match the personalization rules for the current user. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after virtual items were successfully received. - /// Called after the request resulted with an error. - /// Limit for the number of elements on the page. - /// Number of the element from which the list is generated (the count starts from 0). - /// Response language.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
- /// Leave empty to use the default value. - /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. - /// Country to calculate regional prices and restrictions to catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Calculated based on the user's IP address if not specified. - public void GetCatalog(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null, string additionalFields = "long_description", [CanBeNull] string country = null) - { - var url = string.Format(URL_CATALOG_GET_ITEMS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, GetPersonalizationHeader(), onSuccess, onError, ErrorCheckType.ItemsListErrors); - } - - /// - /// Returns a full list of virtual items. The list includes items for which display in the store is enabled in the settings. For each virtual item, the SKU, name, description, and data about the groups it belongs to are returned. - /// If used after user authentication, the method returns items that match the personalization rules for the current user. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Response language.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
- /// Leave empty to use the default value. - /// Called after server response. - /// Called after the request resulted with an error. - public void GetCatalogSimplified(string projectId, Action onSuccess, Action onError = null, string locale = null) - { - var url = string.Format(URL_CATALOG_GET_ALL_VIRTUAL_ITEMS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, locale: locale); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, GetPersonalizationHeader(), onSuccess, onError, ErrorCheckType.ItemsListErrors); - } - - /// - /// Returns a list of items for the specified group according to pagination settings. The list includes items for which display in the store is enabled in the settings. In the settings of the group, the display in the store must be enabled. - /// If used after user authentication, the method returns items that match the personalization rules for the current user. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Group external ID. - /// Called after server response. - /// Called after the request resulted with an error. - /// Limit for the number of elements on the page. - /// Number of the element from which the list is generated (the count starts from 0). - /// Response language.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// The list of additional fields. This fields will be in a response if you send its in a request. Available fields `media_list`, `order`, `long_description`. - /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. - public void GetGroupItems(string projectId, string groupExternalId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int? limit = null, int? offset = null, [CanBeNull] string locale = null, string additionalFields = null, string country = null) - { - var url = string.Format(URL_CATALOG_GET_ITEMS_IN_GROUP, projectId, groupExternalId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, GetPersonalizationHeader(), onSuccess, onError, ErrorCheckType.ItemsListErrors); - } - - /// - /// Returns a full list of virtual item groups. The list includes groups for which display in the store is enabled in the settings. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after virtual item groups were successfully received. - /// Called after the request resulted with an error. - /// Limit for the number of elements on the page. - /// Number of the element from which the list is generated (the count starts from 0). - /// Defines localization of the item text fields.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - public void GetItemGroups(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null) - { - var url = string.Format(URL_CATALOG_GET_GROUPS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError); - } - - /// - /// Returns a list of virtual currencies according to pagination settings. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after virtual currencies were successfully received. - /// Called after the request resulted with an error. - /// Limit for the number of elements on the page. - /// Number of the element from which the list is generated (the count starts from 0). - /// Response language.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. - /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. - public void GetVirtualCurrencyList(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null, string additionalFields = null, string country = null) - { - var url = string.Format(URL_VIRTUAL_CURRENCY_LIST, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError, ErrorCheckType.ItemsListErrors); - } - - /// - /// Returns a list of virtual currency packages according to pagination settings. The list includes packages for which display in the store is enabled in the settings. - /// If used after user authentication, the method returns packages that match the personalization rules for the current user. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after virtual currency packages were successfully received. - /// Called after the request resulted with an error. - /// Limit for the number of elements on the page. - /// Number of the element from which the list is generated (the count starts from 0). - /// Response language.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. - /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. - public void GetVirtualCurrencyPackagesList(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null, string additionalFields = null, string country = null) - { - var url = string.Format(URL_VIRTUAL_CURRENCY_PACKAGES_IN_PROJECT, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, GetPersonalizationHeader(), onSuccess, onError, ErrorCheckType.ItemsListErrors); - } - - /// - /// Returns a list of bundles according to pagination settings. The list includes bundles for which display in the store is enabled in the settings. - /// If used after user authentication, the method returns items that match the personalization rules for the current user. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/#unreal_engine_sdk_how_to_bundles). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after bundles are successfully received. - /// Called after the request resulted with an error. - /// Limit for the number of elements on the page. - /// Number of the element from which the list is generated (the count starts from 0). - /// Defines localization of the item text fields.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// The list of additional fields. This fields will be in a response if you send its in a request. Available fields `media_list`, `order`, `long_description`. - /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. - public void GetBundles(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null, string additionalFields = null, [CanBeNull] string country = null) - { - var url = string.Format(URL_CATALOG_GET_BUNDLES, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, GetPersonalizationHeader(), onSuccess, onError, ErrorCheckType.ItemsListErrors); - } - - /// - /// Returns information about the contents of the specified bundle. In the bundle settings, display in the store must be enabled. - /// If used after user authentication, the method returns items that match the personalization rules for the current user. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/#unreal_engine_sdk_how_to_bundles). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Bundle SKU. - /// Called after the cart is successfully filled. - /// Called after the request resulted with an error. - /// Defines localization of the item text fields.
- /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. - public void GetBundle(string projectId, string sku, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, [CanBeNull] string country = null) - { - var url = string.Format(URL_CATALOG_GET_BUNDLE, projectId, sku); - url = UrlParameterizer.ConcatUrlAndParams(url, locale: locale, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, GetPersonalizationHeader(), onSuccess, onError, ErrorCheckType.ItemsListErrors); - } - - /// - /// Redeems the coupon code and delivers a reward to the user in one of the following ways: - /// - to their inventory (virtual items, virtual currency packages, or bundles) - /// - via email (game keys) - /// - to the entitlement system (game keys) - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/coupons). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique case sensitive code. Contains letters and numbers. - /// Called after successful coupon redemption. - /// Called after the request resulted with an error. - public void RedeemCouponCode(string projectId, CouponCode couponCode, [NotNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_INVENTORY_REDEEM_COUPON, projectId); - - var headers = new List() { WebRequestHeader.AuthHeader(Token.Instance), WebRequestHeader.ContentTypeHeader() }; - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, couponCode, headers, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => RedeemCouponCode(projectId, couponCode, onSuccess, onError)), - ErrorCheckType.CouponErrors); - } - - /// - /// Returns a list of items that can be credited to the user when the coupon is redeemed. Can be used to let users choose one of many items as a bonus. The usual case is choosing a DRM if the coupon contains a game as a bonus. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/coupons). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique case sensitive code. Contains letters and numbers. - /// Called after receiving coupon rewards successfully. - /// Called after the request resulted with an error. - public void GetCouponRewards(string projectId, string couponCode, [NotNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_INVENTORY_GET_COUPON_REWARDS, projectId, couponCode); - - var headers = new List() { WebRequestHeader.AuthHeader(Token.Instance), WebRequestHeader.ContentTypeHeader() }; - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, headers, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetCouponRewards(projectId, couponCode, onSuccess, onError)), - ErrorCheckType.CouponErrors); - } - - /// - /// Creates an order with a specified item. The created order will get a `new` order status. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/one-click-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Item SKU to purchase. - /// Called after server response. - /// Called after the request resulted with an error. - /// Purchase parameters such as country, locale, and currency. - /// Custom web request headers - public void PurchaseItem(string projectId, string itemSku, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) - { - var tempPurchaseParams = PurchaseParamsGenerator.GenerateTempPurchaseParams(purchaseParams); - var url = string.Format(URL_BUY_ITEM, projectId, itemSku); - var paymentHeaders = PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance, customHeaders); - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, tempPurchaseParams, paymentHeaders, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => PurchaseItem(projectId, itemSku, onSuccess, onError, purchaseParams, customHeaders)), - ErrorCheckType.BuyItemErrors); - } - - /// - /// Creates an order with a specified item, returns unique identifier of the created order and the Pay Station token for the purchase of the specified product by virtual currency. The created order will get a `new` order status. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/purchase-for-vc/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Item SKU to purchase. - /// Virtual currency SKU. - /// Called after server response. - /// Called after the request resulted with an error. - /// Purchase parameters such as country, locale and currency. - /// Publishing platform the user plays on.
- /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. - /// Custom web request headers. - public void PurchaseItemForVirtualCurrency(string projectId, string itemSku, string priceSku, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null, string platform = null, Dictionary customHeaders = null) - { - TempPurchaseParams tempPurchaseParams = new TempPurchaseParams - { - sandbox = XsollaSettings.IsSandbox, - custom_parameters = purchaseParams?.custom_parameters - }; - - var url = string.Format(URL_BUY_ITEM_FOR_VC, projectId, itemSku, priceSku); - var platformParam = UrlParameterizer.GetPlatformUrlParam(platform); - url = UrlParameterizer.ConcatUrlAndParams(url, platformParam); - - var paymentHeaders = PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance, customHeaders); - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, tempPurchaseParams, paymentHeaders, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => PurchaseItemForVirtualCurrency(projectId, itemSku, priceSku, onSuccess, onError, purchaseParams, platform, customHeaders)), - ErrorCheckType.BuyItemErrors); - } - - /// - /// Create order with specified free item. The created order will get a `done` order status. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/free-items/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Desired free item SKU. - /// Called after the payment was successfully completed. - /// Called after the request resulted with an error. - /// Purchase parameters such as country, locale, and currency. - /// Custom web request headers - public void CreateOrderWithSpecifiedFreeItem(string projectId, string itemSku, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) - { - var tempPurchaseParams = PurchaseParamsGenerator.GenerateTempPurchaseParams(purchaseParams); - var url = string.Format(URL_CREATE_FREE_ORDER_WITH_ITEM, projectId, itemSku); - var paymentHeaders = PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance, customHeaders); - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, tempPurchaseParams, paymentHeaders, - onComplete: purchaseData => onSuccess?.Invoke(purchaseData.order_id), - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => CreateOrderWithSpecifiedFreeItem(projectId, itemSku, onSuccess, onError, purchaseParams, customHeaders)), - ErrorCheckType.BuyItemErrors); - } - - private WebRequestHeader GetPersonalizationHeader() => (Token.Instance != null) ? WebRequestHeader.AuthHeader(Token.Instance) : null; - } -} diff --git a/Assets/Xsolla/Catalog/Entities/BundleItem.cs b/Assets/Xsolla/Catalog/Entities/BundleItem.cs deleted file mode 100644 index c73cb34bb..000000000 --- a/Assets/Xsolla/Catalog/Entities/BundleItem.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Catalog -{ - [Serializable] - public class BundleItem - { - public string sku; - public string name; - public StoreItemGroup[] groups; - public string description; - public StoreItemAttribute[] attributes; - public string type; - public string bundle_type; - public string image_url; - public bool is_free; - public Price price; - public Price total_content_price; - public VirtualPrice[] virtual_prices; - public Content[] content; - public StoreItemPromotion[] promotions; - - [Serializable] - public class Content - { - public string sku; - public string name; - public string type; - public string description; - public string image_url; - public int quantity; - public Price price; - public VirtualPrice[] virtual_prices; - } - } -} diff --git a/Assets/Xsolla/Catalog/Entities/BundleItem.cs.meta b/Assets/Xsolla/Catalog/Entities/BundleItem.cs.meta deleted file mode 100644 index 6e9f68119..000000000 --- a/Assets/Xsolla/Catalog/Entities/BundleItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: fc6a5208910c43fea8497d512e20e347 -timeCreated: 1603342934 \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/BundleItems.cs b/Assets/Xsolla/Catalog/Entities/BundleItems.cs index 2d363ab66..b385ecf34 100644 --- a/Assets/Xsolla/Catalog/Entities/BundleItems.cs +++ b/Assets/Xsolla/Catalog/Entities/BundleItems.cs @@ -1,4 +1,5 @@ using System; +using Xsolla.Core; namespace Xsolla.Catalog { @@ -7,4 +8,37 @@ public class BundleItems { public BundleItem[] items; } -} + + [Serializable] + public class BundleItem + { + public string sku; + public string name; + public StoreItemGroup[] groups; + public string description; + public StoreItemAttribute[] attributes; + public string type; + public string bundle_type; + public string image_url; + public bool is_free; + public Price price; + public Price total_content_price; + public VirtualPrice[] virtual_prices; + public Content[] content; + public StoreItemPromotion[] promotions; + public StoreItemLimits limits; + + [Serializable] + public class Content + { + public string sku; + public string name; + public string type; + public string description; + public string image_url; + public int quantity; + public Price price; + public VirtualPrice[] virtual_prices; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/CouponRedeemedItem.cs b/Assets/Xsolla/Catalog/Entities/CouponRedeemedItem.cs deleted file mode 100644 index 17ca8def6..000000000 --- a/Assets/Xsolla/Catalog/Entities/CouponRedeemedItem.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; - -namespace Xsolla.Catalog -{ - [Serializable] - public class CouponRedeemedItem - { - [Serializable] - public class Group - { - public string external_id; - public string name; - } - - public string sku; - public Group[] groups; - public string name; - public string type; - public string description; - public string image_url; - public int quantity; - public bool is_free; - // public object attributes; Don't use it yet. - } -} diff --git a/Assets/Xsolla/Catalog/Entities/CouponRedeemedItem.cs.meta b/Assets/Xsolla/Catalog/Entities/CouponRedeemedItem.cs.meta deleted file mode 100644 index 8b9c3dc67..000000000 --- a/Assets/Xsolla/Catalog/Entities/CouponRedeemedItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0b0ddffbee074dab8271cf4a5d8fed6d -timeCreated: 1604933295 \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/CouponRedeemedItems.cs b/Assets/Xsolla/Catalog/Entities/CouponRedeemedItems.cs index 7d1bfb302..29126227f 100644 --- a/Assets/Xsolla/Catalog/Entities/CouponRedeemedItems.cs +++ b/Assets/Xsolla/Catalog/Entities/CouponRedeemedItems.cs @@ -7,4 +7,24 @@ public class CouponRedeemedItems { public CouponRedeemedItem[] items; } -} + + [Serializable] + public class CouponRedeemedItem + { + public string sku; + public Group[] groups; + public string name; + public string type; + public string description; + public string image_url; + public int quantity; + public bool is_free; + + [Serializable] + public class Group + { + public string external_id; + public string name; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/CouponReward.cs b/Assets/Xsolla/Catalog/Entities/CouponReward.cs index 8dce8003a..7567b9495 100644 --- a/Assets/Xsolla/Catalog/Entities/CouponReward.cs +++ b/Assets/Xsolla/Catalog/Entities/CouponReward.cs @@ -5,6 +5,9 @@ namespace Xsolla.Catalog [Serializable] public class CouponReward { + public BonusItem[] bonus; + public bool is_selectable; + [Serializable] public class UnitItem { @@ -32,8 +35,5 @@ public class BonusItem public RewardItem item; public int quantity; } - - public BonusItem[] bonus; - public bool is_selectable; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/Group.cs b/Assets/Xsolla/Catalog/Entities/Group.cs deleted file mode 100644 index e3f079b19..000000000 --- a/Assets/Xsolla/Catalog/Entities/Group.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Xsolla.Catalog -{ - [Serializable] - public class Group - { - public string external_id; - public string name; - public string description; - public string image_url; - public int level; - public int? order; - public List children; - public string parent_external_id; - } -} diff --git a/Assets/Xsolla/Catalog/Entities/Group.cs.meta b/Assets/Xsolla/Catalog/Entities/Group.cs.meta deleted file mode 100644 index 9b8bf04e7..000000000 --- a/Assets/Xsolla/Catalog/Entities/Group.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bd3637a3703e1f84186cc6bf3007ac83 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Catalog/Entities/Groups.cs b/Assets/Xsolla/Catalog/Entities/Groups.cs index 585a7a3c4..d7165a42a 100644 --- a/Assets/Xsolla/Catalog/Entities/Groups.cs +++ b/Assets/Xsolla/Catalog/Entities/Groups.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; namespace Xsolla.Catalog { @@ -7,4 +8,17 @@ public class Groups { public Group[] groups; } -} + + [Serializable] + public class Group + { + public string external_id; + public string name; + public string description; + public string image_url; + public int level; + public int? order; + public List children; + public string parent_external_id; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/StoreItemShort.cs.meta b/Assets/Xsolla/Catalog/Entities/StoreItemShort.cs.meta deleted file mode 100644 index 06c67db56..000000000 --- a/Assets/Xsolla/Catalog/Entities/StoreItemShort.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 3cdb18f9e6ae45ee90f198b4ced667ef -timeCreated: 1633985758 \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/StoreItemShortCollection.cs b/Assets/Xsolla/Catalog/Entities/StoreItemShortCollection.cs deleted file mode 100644 index ac784b255..000000000 --- a/Assets/Xsolla/Catalog/Entities/StoreItemShortCollection.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace Xsolla.Catalog -{ - [Serializable] - public class StoreItemShortCollection - { - public StoreItemShort[] items; - } -} diff --git a/Assets/Xsolla/Catalog/Entities/StoreItems.cs b/Assets/Xsolla/Catalog/Entities/StoreItems.cs index dac9c72db..d53f813af 100644 --- a/Assets/Xsolla/Catalog/Entities/StoreItems.cs +++ b/Assets/Xsolla/Catalog/Entities/StoreItems.cs @@ -8,4 +8,4 @@ public class StoreItems { public StoreItem[] items; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/StoreItemShort.cs b/Assets/Xsolla/Catalog/Entities/StoreShortItems.cs similarity index 66% rename from Assets/Xsolla/Catalog/Entities/StoreItemShort.cs rename to Assets/Xsolla/Catalog/Entities/StoreShortItems.cs index 25653b0b7..6cc28c2aa 100644 --- a/Assets/Xsolla/Catalog/Entities/StoreItemShort.cs +++ b/Assets/Xsolla/Catalog/Entities/StoreShortItems.cs @@ -4,7 +4,13 @@ namespace Xsolla.Catalog { [Serializable] - public class StoreItemShort + public class StoreShortItems + { + public StoreShortItem[] items; + } + + [Serializable] + public class StoreShortItem { public string sku; public string name; @@ -12,4 +18,4 @@ public class StoreItemShort public StoreItemGroup[] groups; public StoreItemPromotion[] promotions; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/StoreItemShortCollection.cs.meta b/Assets/Xsolla/Catalog/Entities/StoreShortItems.cs.meta similarity index 100% rename from Assets/Xsolla/Catalog/Entities/StoreItemShortCollection.cs.meta rename to Assets/Xsolla/Catalog/Entities/StoreShortItems.cs.meta diff --git a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItem.cs b/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItem.cs deleted file mode 100644 index 65e4e5bb3..000000000 --- a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItem.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Catalog -{ - [Serializable] - public class VirtualCurrencyItem : StoreItem - { - } -} diff --git a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItem.cs.meta b/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItem.cs.meta deleted file mode 100644 index 12a15bacd..000000000 --- a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9447830aeca764c5d97ad483dd986db9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItems.cs b/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItems.cs index 991cd401a..b8aa33b29 100644 --- a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItems.cs +++ b/Assets/Xsolla/Catalog/Entities/VirtualCurrencyItems.cs @@ -1,4 +1,5 @@ using System; +using Xsolla.Core; namespace Xsolla.Catalog { @@ -7,4 +8,7 @@ public class VirtualCurrencyItems { public VirtualCurrencyItem[] items; } -} + + [Serializable] + public class VirtualCurrencyItem : StoreItem { } +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackage.cs b/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackage.cs deleted file mode 100644 index 29e15aee3..000000000 --- a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Core; - -namespace Xsolla.Catalog -{ - [Serializable] - public class VirtualCurrencyPackage : StoreItem - { - [Serializable] - public class Content - { - public string sku; - public string name; - public string type; - public string description; - public string image_url; - public int quantity; - public InventoryOptions inventory_options; - } - - public string bundle_type; - public List content; - } -} diff --git a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackage.cs.meta b/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackage.cs.meta deleted file mode 100644 index dad39828a..000000000 --- a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackage.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: bcddd084b91d14361b9d9ab3054e1323 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackages.cs b/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackages.cs index 8385681a2..eadd5e2b7 100644 --- a/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackages.cs +++ b/Assets/Xsolla/Catalog/Entities/VirtualCurrencyPackages.cs @@ -1,11 +1,31 @@ using System; using System.Collections.Generic; +using Xsolla.Core; namespace Xsolla.Catalog { [Serializable] public class VirtualCurrencyPackages { - public List items; + public VirtualCurrencyPackage[] items; } -} + + [Serializable] + public class VirtualCurrencyPackage : StoreItem + { + public string bundle_type; + public List content; + + [Serializable] + public class Content + { + public string sku; + public string name; + public string type; + public string description; + public string image_url; + public int quantity; + public InventoryOptions inventory_options; + } + } +} \ No newline at end of file diff --git a/Assets/Tests/TestUtils.meta b/Assets/Xsolla/Catalog/Internal.meta similarity index 77% rename from Assets/Tests/TestUtils.meta rename to Assets/Xsolla/Catalog/Internal.meta index 47671321a..9247ae53f 100644 --- a/Assets/Tests/TestUtils.meta +++ b/Assets/Xsolla/Catalog/Internal.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 2dc1e7d580df27a4aafc3bfc5ef77326 +guid: 2bfb1c9389d64ccca0b51aa03fa12d5a folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Xsolla/Catalog/Entities/CouponCode.cs b/Assets/Xsolla/Catalog/Internal/CouponCodeRequest.cs similarity index 72% rename from Assets/Xsolla/Catalog/Entities/CouponCode.cs rename to Assets/Xsolla/Catalog/Internal/CouponCodeRequest.cs index 76df3f905..286f7b9f3 100644 --- a/Assets/Xsolla/Catalog/Entities/CouponCode.cs +++ b/Assets/Xsolla/Catalog/Internal/CouponCodeRequest.cs @@ -3,8 +3,8 @@ namespace Xsolla.Catalog { [Serializable] - public class CouponCode + internal class CouponCodeRequest { public string coupon_code; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Entities/CouponCode.cs.meta b/Assets/Xsolla/Catalog/Internal/CouponCodeRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Catalog/Entities/CouponCode.cs.meta rename to Assets/Xsolla/Catalog/Internal/CouponCodeRequest.cs.meta diff --git a/Assets/Xsolla/Catalog/XsollaCatalog.cs b/Assets/Xsolla/Catalog/XsollaCatalog.cs new file mode 100644 index 000000000..7b528e20d --- /dev/null +++ b/Assets/Xsolla/Catalog/XsollaCatalog.cs @@ -0,0 +1,480 @@ +using System; +using System.Collections.Generic; +using Xsolla.Core; + +namespace Xsolla.Catalog +{ + public static class XsollaCatalog + { + private static string BaseUrl => $"https://store.xsolla.com/api/v2/project/{XsollaSettings.StoreProjectId}"; + + /// + /// Returns a list of virtual items according to pagination settings. + /// The list includes items for which display in the store is enabled in the settings. For each virtual item, complete data is returned. + /// If used after user authentication, the method returns items that match the personalization rules for the current user. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). + /// Called after virtual items were successfully received. + /// Called after the request resulted with an error. + /// Limit for the number of elements on the page. + /// Number of the element from which the list is generated (the count starts from 0). + /// Response language.
+ /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
+ /// Leave empty to use the default value. + /// Country to calculate regional prices and restrictions to catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Calculated based on the user's IP address if not specified. + /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. + public static void GetCatalog(Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null, string country = null, string additionalFields = "long_description") + { + var url = new UrlBuilder($"{BaseUrl}/items/virtual_items") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetCatalog(onSuccess, onError, limit, offset, locale, country, additionalFields)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Returns a full list of virtual items. The list includes items for which display in the store is enabled in the settings. For each virtual item, the SKU, name, description, and data about the groups it belongs to are returned. + /// If used after user authentication, the method returns items that match the personalization rules for the current user. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). + /// Called after server response. + /// Called after the request resulted with an error. + /// Response language.
+ /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
+ /// Leave empty to use the default value. + public static void GetCatalogSimplified(Action onSuccess, Action onError, string locale = null) + { + var url = new UrlBuilder($"{BaseUrl}/items/virtual_items/all") + .AddLocale(locale) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetCatalogSimplified(onSuccess, onError, locale)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Returns a list of items for the specified group according to pagination settings. The list includes items for which display in the store is enabled in the settings. In the settings of the group, the display in the store must be enabled. + /// If used after user authentication, the method returns items that match the personalization rules for the current user. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). + /// Group external ID. + /// Called after server response. + /// Called after the request resulted with an error. + /// Limit for the number of elements on the page. + /// Number of the element from which the list is generated (the count starts from 0). + /// Response language.
+ /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. + /// The list of additional fields. This fields will be in a response if you send its in a request. Available fields `media_list`, `order`, `long_description`. + public static void GetGroupItems(string groupExternalId, Action onSuccess, Action onError, int? limit = null, int? offset = null, string locale = null, string country = null, string additionalFields = null) + { + var url = new UrlBuilder($"{BaseUrl}/items/virtual_items/group/{groupExternalId}") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetGroupItems(groupExternalId, onSuccess, onError, limit, offset, locale, country, additionalFields)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Returns a full list of virtual item groups. The list includes groups for which display in the store is enabled in the settings. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). + /// Called after virtual item groups were successfully received. + /// Called after the request resulted with an error. + /// Limit for the number of elements on the page. + /// Number of the element from which the list is generated (the count starts from 0). + /// Defines localization of the item text fields.
+ /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + public static void GetItemGroups(Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null) + { + var url = new UrlBuilder($"{BaseUrl}/items/groups") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetItemGroups(onSuccess, onError, limit, offset, locale))); + } + + /// + /// Returns a list of virtual currencies according to pagination settings. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). + /// Called after virtual currencies were successfully received. + /// Called after the request resulted with an error. + /// Limit for the number of elements on the page. + /// Number of the element from which the list is generated (the count starts from 0). + /// Response language.
+ /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. + /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. + public static void GetVirtualCurrencyList(Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null, string country = null, string additionalFields = null) + { + var url = new UrlBuilder($"{BaseUrl}/items/virtual_currency") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetVirtualCurrencyList(onSuccess, onError, limit, offset, locale, country, additionalFields)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Returns a list of virtual currency packages according to pagination settings. The list includes packages for which display in the store is enabled in the settings. + /// If used after user authentication, the method returns packages that match the personalization rules for the current user. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/). + /// Called after virtual currency packages were successfully received. + /// Called after the request resulted with an error. + /// Limit for the number of elements on the page. + /// Number of the element from which the list is generated (the count starts from 0). + /// Response language.
+ /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. + /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. + public static void GetVirtualCurrencyPackagesList(Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null, string country = null, string additionalFields = null) + { + var url = new UrlBuilder($"{BaseUrl}/items/virtual_currency/package") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetVirtualCurrencyPackagesList(onSuccess, onError, limit, offset, locale, country, additionalFields)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Returns a list of bundles according to pagination settings. The list includes bundles for which display in the store is enabled in the settings. + /// If used after user authentication, the method returns items that match the personalization rules for the current user. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/#unreal_engine_sdk_how_to_bundles). + /// Called after bundles are successfully received. + /// Called after the request resulted with an error. + /// Limit for the number of elements on the page. + /// Number of the element from which the list is generated (the count starts from 0). + /// Defines localization of the item text fields.
+ /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. + /// The list of additional fields. This fields will be in a response if you send its in a request. Available fields `media_list`, `order`, `long_description`. + public static void GetBundles(Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null, string country = null, string additionalFields = null) + { + var url = new UrlBuilder($"{BaseUrl}/items/bundle") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetBundles(onSuccess, onError, limit, offset, locale, country, additionalFields)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Returns information about the contents of the specified bundle. In the bundle settings, display in the store must be enabled. + /// If used after user authentication, the method returns items that match the personalization rules for the current user. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/catalog/catalog-display/#unreal_engine_sdk_how_to_bundles). + /// Bundle SKU. + /// Called after the cart is successfully filled. + /// Called after the request resulted with an error. + /// Defines localization of the item text fields.
+ /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. + public static void GetBundle(string sku, Action onSuccess, Action onError, string locale = null, string country = null) + { + var url = new UrlBuilder($"{BaseUrl}/items/bundle/sku/{sku}") + .AddLocale(locale) + .AddCountry(country) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetBundle(sku, onSuccess, onError, locale, country)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Redeems the coupon code and delivers a reward to the user in one of the following ways: + /// - to their inventory (virtual items, virtual currency packages, or bundles) + /// - via email (game keys) + /// - to the entitlement system (game keys) + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/coupons). + /// Unique case sensitive code. Contains letters and numbers. + /// Called after successful coupon redemption. + /// Called after the request resulted with an error. + public static void RedeemCouponCode(string couponCode, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/coupon/redeem"; + + var headers = new List { + WebRequestHeader.AuthHeader(), + WebRequestHeader.JsonContentTypeHeader() + }; + + var requestData = new CouponCodeRequest { + coupon_code = couponCode + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => RedeemCouponCode(couponCode, onSuccess, onError)), + ErrorGroup.CouponErrors); + } + + /// + /// Returns a list of items that can be credited to the user when the coupon is redeemed. Can be used to let users choose one of many items as a bonus. The usual case is choosing a DRM if the coupon contains a game as a bonus. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/coupons). + /// Unique case sensitive code. Contains letters and numbers. + /// Called after receiving coupon rewards successfully. + /// Called after the request resulted with an error. + public static void GetCouponRewards(string couponCode, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/coupon/code/{couponCode}/rewards"; + + var headers = new List { + WebRequestHeader.AuthHeader(), + WebRequestHeader.JsonContentTypeHeader() + }; + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetCouponRewards(couponCode, onSuccess, onError)), + ErrorGroup.CouponErrors); + } + + /// + /// Creates an order with a specified item. The created order will get a `new` order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/one-click-purchase/). + /// Item SKU to purchase. + /// Called after server response. + /// Called after the request resulted with an error. + /// Purchase parameters such as country, locale, and currency. + /// Custom web request headers + public static void CreateOrder(string itemSku, Action onSuccess, Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) + { + var url = $"{BaseUrl}/payment/item/{itemSku}"; + var requestData = PurchaseParamsGenerator.GeneratePurchaseParamsRequest(purchaseParams); + var headers = PurchaseParamsGenerator.GeneratePaymentHeaders(customHeaders); + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => CreateOrder(itemSku, onSuccess, onError, purchaseParams, customHeaders)), + ErrorGroup.BuyItemErrors); + } + + /// + /// Creates an order with a specified item, returns unique identifier of the created order and the Pay Station token for the purchase of the specified product by virtual currency. The created order will get a `new` order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/purchase-for-vc/). + /// Item SKU to purchase. + /// Virtual currency SKU. + /// Called after server response. + /// Called after the request resulted with an error. + /// Purchase parameters such as country, locale, currency, and quantity. + /// Publishing platform the user plays on.
+ /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. + /// Custom HTTP request headers. + public static void CreateOrderByVirtualCurrency(string itemSku, string priceSku, Action onSuccess, Action onError, PurchaseParams purchaseParams = null, string platform = null, Dictionary customHeaders = null) + { + var url = new UrlBuilder($"{BaseUrl}/payment/item/{itemSku}/virtual/{priceSku}") + .AddPlatform(platform) + .Build(); + + var requestData = new PurchaseParamsRequest { + sandbox = XsollaSettings.IsSandbox, + custom_parameters = purchaseParams?.custom_parameters + }; + + var headers = PurchaseParamsGenerator.GeneratePaymentHeaders(customHeaders); + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => CreateOrderByVirtualCurrency(itemSku, priceSku, onSuccess, onError, purchaseParams, platform, customHeaders)), + ErrorGroup.BuyItemErrors); + } + + /// + /// Create order with specified free item. The created order will get a `done` order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/free-items/). + /// Desired free item SKU. + /// Called after the order was successfully created. + /// Called after the request resulted with an error. + /// Purchase parameters such as country, locale, and currency. + /// Custom web request headers + public static void CreateOrderWithFreeItem(string itemSku, Action onSuccess, Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) + { + var url = $"{BaseUrl}/free/item/{itemSku}"; + var requestData = PurchaseParamsGenerator.GeneratePurchaseParamsRequest(purchaseParams); + var headers = PurchaseParamsGenerator.GeneratePaymentHeaders(customHeaders); + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + headers, + purchaseData => onSuccess?.Invoke(purchaseData), + error => TokenAutoRefresher.Check(error, onError, () => CreateOrderWithFreeItem(itemSku, onSuccess, onError, purchaseParams, customHeaders)), + ErrorGroup.BuyItemErrors); + } + + /// + /// Launches purchase process for a specified item. This method encapsulates methods for creating an order, opening a payment UI, and tracking the order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/one-click-purchase/). + /// Desired free item SKU. + /// Called after the order transitions to the 'done' status. + /// Called after the request resulted with an error. + /// Called after browser closed. + /// Purchase parameters such as country, locale, and currency. + /// Custom web request headers + public static void Purchase(string itemSku, Action onSuccess, Action onError, Action onBrowseClosed = null, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) + { + CreateOrder( + itemSku, + orderData => + { + XsollaWebBrowser.OpenPurchaseUI( + orderData.token, + false, + onBrowseClosed); + + OrderTrackingService.AddOrderForTracking(orderData.order_id, + true, () => + { + if (XsollaWebBrowser.InAppBrowser?.IsOpened ?? false) + XsollaWebBrowser.Close(); + + OrderStatusService.GetOrderStatus(orderData.order_id, onSuccess, onError); + }, onError); + }, + onError, + purchaseParams, + customHeaders); + } + + /// + /// Launch purchase process for a specified item by virtual currency. This method encapsulates methods for creating an order and tracking the order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/purchase-for-vc/). + /// Desired free item SKU. + /// Virtual currency SKU. + /// Called after the order transitions to the 'done' status. + /// Called after the request resulted with an error. + /// Purchase parameters such as country, locale, and currency. + /// Publishing platform the user plays on.
+ /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. + /// Custom HTTP request headers. + public static void PurchaseForVirtualCurrency(string itemSku, string priceSku, Action onSuccess, Action onError, PurchaseParams purchaseParams = null, string platform = null, Dictionary customHeaders = null) + { + CreateOrderByVirtualCurrency( + itemSku, + priceSku, + orderId => + { + OrderTrackingService.AddOrderForTracking( + orderId.order_id, + false, () => OrderStatusService.GetOrderStatus(orderId.order_id, onSuccess, onError), onError); + }, + onError, + purchaseParams, + platform, + customHeaders); + } + + /// + /// Launches purchase process for a specified free item. This method encapsulates methods for creating an order and tracking the order status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/promo/free-items/). + /// Desired free item SKU. + /// Called after the order transitions to the 'done' status. + /// Called after the request resulted with an error. + /// Purchase parameters such as country, locale, and currency. + /// Custom HTTP request headers. + public static void PurchaseFreeItem(string itemSku, Action onSuccess, Action onError, PurchaseParams purchaseParams = null, Dictionary customHeaders = null) + { + CreateOrderWithFreeItem( + itemSku, + orderId => + { + OrderTrackingService.AddOrderForTracking( + orderId.order_id, + false, () => OrderStatusService.GetOrderStatus(orderId.order_id, onSuccess, onError), onError); + }, + onError, + purchaseParams, + customHeaders); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Catalog/Api/XsollaCatalog.cs.meta b/Assets/Xsolla/Catalog/XsollaCatalog.cs.meta similarity index 100% rename from Assets/Xsolla/Catalog/Api/XsollaCatalog.cs.meta rename to Assets/Xsolla/Catalog/XsollaCatalog.cs.meta diff --git a/Assets/Xsolla/Core/Android/AndroidAuthCallback.cs b/Assets/Xsolla/Core/Android/AndroidAuthCallback.cs new file mode 100644 index 000000000..9b4573104 --- /dev/null +++ b/Assets/Xsolla/Core/Android/AndroidAuthCallback.cs @@ -0,0 +1,44 @@ +using System; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class AndroidAuthCallback : AndroidJavaProxy + { + private readonly Action OnSuccess; + private readonly Action OnError; + private readonly Action OnCancel; + + public AndroidAuthCallback(Action onSuccess, Action onError, Action onCancel) : base("com.xsolla.android.login.callback.AuthCallback") + { + OnSuccess = onSuccess; + OnError = onError; + OnCancel = onCancel; + } + + public void onSuccess() + { + try + { + var token = new AndroidHelper().Xlogin.CallStatic("getToken"); + OnSuccess?.Invoke(token); + } + catch (Exception e) + { + OnError?.Invoke(new Error(errorMessage: e.Message)); + } + } + + public void onError(AndroidJavaObject _, string errorMessage) + { + if (!string.IsNullOrEmpty(errorMessage) && errorMessage == "CANCELLED") + { + OnCancel?.Invoke(); + } + else + { + OnError?.Invoke(new Error(errorMessage: errorMessage)); + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSDKAuthCallback.cs.meta b/Assets/Xsolla/Core/Android/AndroidAuthCallback.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Android/AndroidSDKAuthCallback.cs.meta rename to Assets/Xsolla/Core/Android/AndroidAuthCallback.cs.meta diff --git a/Assets/Xsolla/Core/Android/AndroidBrowserCallback.cs b/Assets/Xsolla/Core/Android/AndroidBrowserCallback.cs new file mode 100644 index 000000000..c4e5d1612 --- /dev/null +++ b/Assets/Xsolla/Core/Android/AndroidBrowserCallback.cs @@ -0,0 +1,17 @@ +using System; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class AndroidBrowserCallback : AndroidJavaProxy + { + public Action OnBrowserClosed { get; set; } + + public AndroidBrowserCallback() : base("com.xsolla.android.payments.callback.BrowserCallback") { } + + public void onBrowserClosed(bool isManually) + { + OnBrowserClosed?.Invoke(isManually); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSDKBrowserCallback.cs.meta b/Assets/Xsolla/Core/Android/AndroidBrowserCallback.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Android/AndroidSDKBrowserCallback.cs.meta rename to Assets/Xsolla/Core/Android/AndroidBrowserCallback.cs.meta diff --git a/Assets/Xsolla/Core/Android/AndroidHelper.cs b/Assets/Xsolla/Core/Android/AndroidHelper.cs index f5a2af0ec..175c69c7c 100644 --- a/Assets/Xsolla/Core/Android/AndroidHelper.cs +++ b/Assets/Xsolla/Core/Android/AndroidHelper.cs @@ -1,23 +1,15 @@ -using System; +using System; using UnityEngine; -namespace Xsolla.Core.Android +namespace Xsolla.Core { - public class AndroidHelper : IDisposable + internal class AndroidHelper { private AndroidJavaClass _unityPlayer; private AndroidJavaObject _activity; private AndroidJavaObject _context; - - private static OnMainThreadExecutor _onMainThreadExecutorInstance; - - public AndroidHelper() - { - if (!_onMainThreadExecutorInstance) - _onMainThreadExecutorInstance = new GameObject("Android Main Thread Executor").AddComponent(); - } - - public OnMainThreadExecutor OnMainThreadExecutor => _onMainThreadExecutorInstance; + private static MainThreadExecutor _mainThreadExecutorInstance; + private static AndroidJavaClass _xlogin; private AndroidJavaClass UnityPlayer { @@ -41,7 +33,7 @@ public AndroidJavaObject CurrentActivity } } - public AndroidJavaObject ApplicationContext + private AndroidJavaObject ApplicationContext { get { @@ -52,11 +44,50 @@ public AndroidJavaObject ApplicationContext } } - public void Dispose() + public AndroidJavaClass Xlogin => _xlogin; + + public MainThreadExecutor MainThreadExecutor => _mainThreadExecutorInstance; + + public AndroidHelper() + { + CreateMainThreadExecutor(); + InitLogin(); + } + + private static void CreateMainThreadExecutor() { - _context?.Dispose(); - _activity?.Dispose(); - _unityPlayer?.Dispose(); + if (!_mainThreadExecutorInstance) + _mainThreadExecutorInstance = new GameObject("Android MainThreadExecutor").AddComponent(); + } + + private void InitLogin() + { + if (_xlogin != null) + return; + + try + { + _xlogin = new AndroidJavaClass("com.xsolla.android.login.XLogin"); + var socialConfig = new AndroidJavaObject( + "com.xsolla.android.login.XLogin$SocialConfig", + XsollaSettings.FacebookAppId, + XsollaSettings.GoogleServerId, + XsollaSettings.WeChatAppId, + XsollaSettings.QQAppId); + + var loginConfigBuilder = new AndroidJavaObject("com.xsolla.android.login.LoginConfig$OauthBuilder"); + loginConfigBuilder.Call("setSocialConfig", socialConfig); + loginConfigBuilder.Call("setProjectId", XsollaSettings.LoginId); + loginConfigBuilder.Call("setOauthClientId", XsollaSettings.OAuthClientId); + + var loginConfig = loginConfigBuilder.Call("build"); + + _xlogin.CallStatic("init", ApplicationContext, loginConfig); + } + catch (Exception e) + { + throw new AggregateException($"AndroidSDKSocialAuthHelper.Ctor: {e.Message}", e); + } } } } \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidHelper.cs.meta b/Assets/Xsolla/Core/Android/AndroidHelper.cs.meta index 3a06ed878..1bc0de66d 100644 --- a/Assets/Xsolla/Core/Android/AndroidHelper.cs.meta +++ b/Assets/Xsolla/Core/Android/AndroidHelper.cs.meta @@ -1,11 +1,3 @@ fileFormatVersion: 2 -guid: 3b444db267b0a7747b9b15815553836e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: +guid: d560a23b051d4a939918705260359226 +timeCreated: 1683002849 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidPayments.cs b/Assets/Xsolla/Core/Android/AndroidPayments.cs new file mode 100644 index 000000000..374770e16 --- /dev/null +++ b/Assets/Xsolla/Core/Android/AndroidPayments.cs @@ -0,0 +1,43 @@ +using System; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class AndroidPayments + { + public void Perform(string paymentToken, Action onBrowserClose) + { + try + { + var helper = new AndroidHelper(); + + string redirectScheme = null; + string redirectHost = null; + var redirectPolicy = XsollaSettings.AndroidRedirectPolicySettings; + if (!redirectPolicy.UseSettingsFromPublisherAccount && !string.IsNullOrEmpty(redirectPolicy.ReturnUrl)) + { + var uri = new Uri(redirectPolicy.ReturnUrl); + redirectScheme = uri.Scheme; + redirectHost = uri.Host; + } + + var browserCloseCallback = new AndroidBrowserCallback { + OnBrowserClosed = isManually => helper.MainThreadExecutor.Enqueue(() => onBrowserClose?.Invoke(isManually)) + }; + + var proxyActivity = new AndroidJavaClass($"{Application.identifier}.androidProxies.PaymentsProxyActivity"); + proxyActivity.CallStatic("perform", + helper.CurrentActivity, + paymentToken, + XsollaSettings.IsSandbox, + redirectScheme, + redirectHost, + browserCloseCallback); + } + catch (Exception e) + { + throw new AggregateException($"AndroidSDKPaymentsHelper.PerformPayment: {e.Message}", e); + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSDKPaymentsHelper.cs.meta b/Assets/Xsolla/Core/Android/AndroidPayments.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Android/AndroidSDKPaymentsHelper.cs.meta rename to Assets/Xsolla/Core/Android/AndroidPayments.cs.meta diff --git a/Assets/Xsolla/Core/Android/AndroidRefreshToken.cs b/Assets/Xsolla/Core/Android/AndroidRefreshToken.cs new file mode 100644 index 000000000..7a6559ebb --- /dev/null +++ b/Assets/Xsolla/Core/Android/AndroidRefreshToken.cs @@ -0,0 +1,30 @@ +using System; + +namespace Xsolla.Core +{ + internal class AndroidRefreshToken + { + public void Perform(Action onSuccess, Action onError) + { + var androidHelper = new AndroidHelper(); + + var canRefresh = androidHelper.Xlogin.CallStatic("canRefreshToken"); + if (!canRefresh) + { + XDebug.Log("Android social token refresh is not available at the moment"); + onError?.Invoke(new Error(ErrorType.MethodIsNotAllowed)); + return; + } + + var callback = new AndroidRefreshTokenCallback( + token => androidHelper.MainThreadExecutor.Enqueue(() => + { + XsollaToken.Create(token); + onSuccess?.Invoke(); + }), + error => androidHelper.MainThreadExecutor.Enqueue(() => onError(error))); + + androidHelper.Xlogin.CallStatic("refreshToken", callback); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidRefreshToken.cs.meta b/Assets/Xsolla/Core/Android/AndroidRefreshToken.cs.meta new file mode 100644 index 000000000..16c2dbe1c --- /dev/null +++ b/Assets/Xsolla/Core/Android/AndroidRefreshToken.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 58ff16c0933b4935a66855a32e98f708 +timeCreated: 1683005590 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidRefreshTokenCallback.cs b/Assets/Xsolla/Core/Android/AndroidRefreshTokenCallback.cs new file mode 100644 index 000000000..f2492997f --- /dev/null +++ b/Assets/Xsolla/Core/Android/AndroidRefreshTokenCallback.cs @@ -0,0 +1,37 @@ +using System; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class AndroidRefreshTokenCallback : AndroidJavaProxy + { + private readonly Action OnSuccess; + private readonly Action OnError; + + public AndroidRefreshTokenCallback(Action onSuccess, Action onError) : base("com.xsolla.android.login.callback.RefreshTokenCallback") + { + OnSuccess = onSuccess; + OnError = onError; + } + + public void onSuccess() + { + try + { + var token = new AndroidHelper().Xlogin.CallStatic("getToken"); + OnSuccess?.Invoke(token); + } + catch (Exception ex) + { + XDebug.LogError($"AndroidSDKRefreshTokenCallback.onSuccess: {ex.Message}"); + OnError?.Invoke(new Error(errorMessage: ex.Message)); + } + } + + public void onError(AndroidJavaObject _, string errorMessage) + { + var error = new Error(errorMessage: errorMessage); + OnError?.Invoke(error); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSDKRefreshTokenCallback.cs.meta b/Assets/Xsolla/Core/Android/AndroidRefreshTokenCallback.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Android/AndroidSDKRefreshTokenCallback.cs.meta rename to Assets/Xsolla/Core/Android/AndroidRefreshTokenCallback.cs.meta diff --git a/Assets/Xsolla/Core/Android/AndroidSDKAuthCallback.cs b/Assets/Xsolla/Core/Android/AndroidSDKAuthCallback.cs deleted file mode 100644 index 9220e85c0..000000000 --- a/Assets/Xsolla/Core/Android/AndroidSDKAuthCallback.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using UnityEngine; - -namespace Xsolla.Core.Android -{ - public class AndroidSDKAuthCallback : AndroidJavaProxy - { - public Action OnSuccess { get; set; } - public Action OnCancelled { get; set; } - public Action OnError { get; set; } - - public AndroidSDKAuthCallback() : base("com.xsolla.android.login.callback.AuthCallback") { } - - public void onSuccess() - { - try - { - var xlogin = new AndroidJavaClass("com.xsolla.android.login.XLogin"); - var token = xlogin.CallStatic("getToken"); - OnSuccess?.Invoke(token); - } - catch (Exception ex) - { - Debug.LogError($"AndroidSDKAuthCallback.onSuccess: ERROR {ex.Message}"); - OnError?.Invoke(new Error(errorMessage: ex.Message)); - } - } - - public void onError(AndroidJavaObject _, string errorMessage) - { - if (!string.IsNullOrEmpty(errorMessage) && errorMessage == "CANCELLED") - { - Debug.LogWarning("AndroidSDKAuthCallback: CANCELLED"); - OnCancelled?.Invoke(); - } - else - { - OnError?.Invoke(new Error(errorMessage: errorMessage)); - } - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSDKBrowserCallback.cs b/Assets/Xsolla/Core/Android/AndroidSDKBrowserCallback.cs deleted file mode 100644 index 0d6a1aa0d..000000000 --- a/Assets/Xsolla/Core/Android/AndroidSDKBrowserCallback.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using UnityEngine; - -namespace Xsolla.Core.Android -{ - internal class AndroidSDKBrowserCallback : AndroidJavaProxy - { - public Action OnBrowserClosed { get; set; } - - public AndroidSDKBrowserCallback() : base("com.xsolla.android.payments.callback.BrowserCallback") { } - - public void onBrowserClosed(bool isManually) - { - OnBrowserClosed?.Invoke(isManually); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSDKPaymentsHelper.cs b/Assets/Xsolla/Core/Android/AndroidSDKPaymentsHelper.cs deleted file mode 100644 index a873fe041..000000000 --- a/Assets/Xsolla/Core/Android/AndroidSDKPaymentsHelper.cs +++ /dev/null @@ -1,50 +0,0 @@ -using System; -using UnityEngine; -using Xsolla.Core.Android; - -namespace Xsolla.Core -{ - public class AndroidSDKPaymentsHelper : IDisposable - { - private readonly AndroidHelper androidHelper; - - public AndroidSDKPaymentsHelper() - { - androidHelper = new AndroidHelper(); - } - - public void PerformPayment(string token, bool isSandbox, Action browserClosedCallback) - { - try - { - var proxyClass = new AndroidJavaClass($"{Application.identifier}.androidProxies.AndroidPaymentsProxy"); - - string redirectScheme = null; - string redirectHost = null; - var redirectPolicy = XsollaSettings.AndroidRedirectPolicySettings; - if (!redirectPolicy.UseSettingsFromPublisherAccount && !string.IsNullOrEmpty(redirectPolicy.ReturnUrl)) - { - var uri = new Uri(redirectPolicy.ReturnUrl); - redirectScheme = uri.Scheme; - redirectHost = uri.Host; - } - - var browserCallback = new AndroidSDKBrowserCallback { - OnBrowserClosed = isManually => androidHelper.OnMainThreadExecutor.Enqueue(() => browserClosedCallback?.Invoke(isManually)) - }; - - var activity = new AndroidHelper().CurrentActivity; - proxyClass.CallStatic("performPayment", activity, token, isSandbox, redirectScheme, redirectHost, browserCallback); - } - catch (Exception e) - { - throw new AggregateException($"AndroidSDKPaymentsHelper.PerformPayment: {e.Message}", e); - } - } - - public void Dispose() - { - androidHelper.Dispose(); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSDKRefreshTokenCallback.cs b/Assets/Xsolla/Core/Android/AndroidSDKRefreshTokenCallback.cs deleted file mode 100644 index 4add53eb7..000000000 --- a/Assets/Xsolla/Core/Android/AndroidSDKRefreshTokenCallback.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using UnityEngine; - -namespace Xsolla.Core.Android -{ - public class AndroidSDKRefreshTokenCallback : AndroidJavaProxy - { - public Action OnSuccess { get; set; } - public Action OnError { get; set; } - - public AndroidSDKRefreshTokenCallback() : base("com.xsolla.android.login.callback.RefreshTokenCallback") { } - - public void onSuccess() - { - try - { - var xlogin = new AndroidJavaClass("com.xsolla.android.login.XLogin"); - var token = xlogin.CallStatic("getToken"); - OnSuccess?.Invoke(token); - } - catch (Exception ex) - { - Debug.LogError($"AndroidSDKRefreshTokenCallback.onSuccess: {ex.Message}"); - OnError?.Invoke(new Error(errorMessage: ex.Message)); - } - } - - public void onError(AndroidJavaObject _, string errorMessage) - { - var error = new Error(errorMessage: errorMessage); - OnError?.Invoke(error); - } - } -} diff --git a/Assets/Xsolla/Core/Android/AndroidSDKSocialAuthHelper.cs b/Assets/Xsolla/Core/Android/AndroidSDKSocialAuthHelper.cs deleted file mode 100644 index 6f874a61c..000000000 --- a/Assets/Xsolla/Core/Android/AndroidSDKSocialAuthHelper.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using UnityEngine; -using Xsolla.Core.Android; - -namespace Xsolla.Core -{ - public class AndroidSDKSocialAuthHelper : IDisposable - { - private readonly AndroidHelper _androidHelper; - private readonly AndroidJavaClass _xlogin; - - public AndroidSDKSocialAuthHelper() - { - GetXsollaSettings( - out string loginID, - out int OAuthClientId, - out string facebookAppId, - out string googleServerId, - out string wechatAppId, - out string qqAppId); - - _androidHelper = new AndroidHelper(); - - try - { - var xlogin = new AndroidJavaClass("com.xsolla.android.login.XLogin"); - var context = _androidHelper.ApplicationContext; - - var socialConfig = new AndroidJavaObject("com.xsolla.android.login.XLogin$SocialConfig", facebookAppId, googleServerId, wechatAppId, qqAppId); - - AndroidJavaObject loginConfig; - AndroidJavaObject loginConfigBuilder; - - loginConfigBuilder = new AndroidJavaObject("com.xsolla.android.login.LoginConfig$OauthBuilder"); - loginConfigBuilder.Call("setProjectId", loginID); - loginConfigBuilder.Call("setSocialConfig", socialConfig); - loginConfigBuilder.Call("setOauthClientId", OAuthClientId); - - loginConfig = loginConfigBuilder.Call("build"); - - xlogin.CallStatic("init", context, loginConfig); - - _xlogin = xlogin; - } - catch (Exception ex) - { - throw new AggregateException($"AndroidSDKSocialAuthHelper.Ctor: {ex.Message}", ex); - } - } - - public void PerformSocialAuth(SocialProvider socialProvider, Action onSuccess, Action onCancelled, Action onError) - { - var providerName = socialProvider.ToString().ToUpper(); - - Debug.Log($"Trying android social auth for '{providerName}'"); - - try - { - var currentActivity = _androidHelper.CurrentActivity; - var proxyActivity = new AndroidJavaObject($"{Application.identifier}.androidProxies.AndroidAuthProxy"); - var socialNetworkClass = new AndroidJavaClass("com.xsolla.android.login.social.SocialNetwork"); - var socialNetworkObject = socialNetworkClass.GetStatic(providerName); - var callback = new AndroidSDKAuthCallback - { - OnSuccess = token => _androidHelper.OnMainThreadExecutor.Enqueue(() => onSuccess(token)), - OnCancelled = () => _androidHelper.OnMainThreadExecutor.Enqueue(onCancelled), - OnError = error => _androidHelper.OnMainThreadExecutor.Enqueue(() => onError(error)) - }; - - proxyActivity.CallStatic("authSocial", currentActivity, proxyActivity, socialNetworkObject, callback); - } - catch (Exception ex) - { - throw new AggregateException($"AndroidSDKSocialAuthHelper.PerformSocialAuth: {ex.Message}", ex); - } - } - - public bool IsRefreshSocialTokenPossible - { - get - { - bool canRefresh; - - try - { - canRefresh = _xlogin.CallStatic("canRefreshToken"); - } - catch (Exception ex) - { - Debug.LogError($"AndroidSDKSocialAuthHelper.IsRefreshSocialTokenPossible: {ex.Message}"); - canRefresh = false; - } - - return canRefresh; - } - } - - public bool IsSocialTokenExpired - { - get - { - bool isTokenExpired; - - try - { - //Argument type of long is required, but is used only for JWT expiration check, which is not the case - isTokenExpired = _xlogin.CallStatic("isTokenExpired", (object) 0L); - } - catch (Exception ex) - { - Debug.LogError($"AndroidSDKSocialAuthHelper.IsSocialTokenExpired: {ex.Message}"); - isTokenExpired = false; - } - - return isTokenExpired; - } - } - - public void TryRefreshSocialToken(Action onSuccessRefresh, Action onError) - { - try - { - if (IsRefreshSocialTokenPossible) - { - var callback = new AndroidSDKRefreshTokenCallback - { - OnSuccess = token => _androidHelper.OnMainThreadExecutor.Enqueue(() => onSuccessRefresh(token)), - OnError = error => _androidHelper.OnMainThreadExecutor.Enqueue(() => onError(error)) - }; - - _xlogin.CallStatic("refreshToken", callback); - } - } - catch (Exception ex) - { - Debug.LogError($"AndroidSDKSocialAuthHelper.TryRefreshSocialToken: {ex.Message}"); - } - } - - private void GetXsollaSettings(out string loginID, out int OAuthClientId, out string facebookAppId, out string googleServerId, out string wechatAppId, out string qqAppId) - { - loginID = XsollaSettings.LoginId; - OAuthClientId = XsollaSettings.OAuthClientId; - facebookAppId = XsollaSettings.FacebookAppId; - googleServerId = XsollaSettings.GoogleServerId; - wechatAppId = XsollaSettings.WeChatAppId; - qqAppId = XsollaSettings.QQAppId; - } - - public void Dispose() - { - _androidHelper.Dispose(); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSDKSocialAuthHelper.cs.meta b/Assets/Xsolla/Core/Android/AndroidSDKSocialAuthHelper.cs.meta deleted file mode 100644 index cbf731986..000000000 --- a/Assets/Xsolla/Core/Android/AndroidSDKSocialAuthHelper.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 06e9c8c68a2fc4e40b5f3b9a6a8fc60d -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Android/AndroidSocialAuth.cs b/Assets/Xsolla/Core/Android/AndroidSocialAuth.cs new file mode 100644 index 000000000..19b09c587 --- /dev/null +++ b/Assets/Xsolla/Core/Android/AndroidSocialAuth.cs @@ -0,0 +1,40 @@ +using System; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class AndroidSocialAuth + { + public void Perform(SocialProvider provider, Action onSuccess, Action onError, Action onCancel) + { + try + { + var helper = new AndroidHelper(); + + var providerName = provider.ToString().ToUpper(); + var socialNetworkClass = new AndroidJavaClass("com.xsolla.android.login.social.SocialNetwork"); + var socialNetworkObject = socialNetworkClass.GetStatic(providerName); + + var callback = new AndroidAuthCallback( + token => helper.MainThreadExecutor.Enqueue(() => + { + XsollaToken.Create(token); + onSuccess?.Invoke(); + }), + error => helper.MainThreadExecutor.Enqueue(() => onError(error)), + () => helper.MainThreadExecutor.Enqueue(onCancel)); + + var proxyActivity = new AndroidJavaObject($"{Application.identifier}.androidProxies.SocialAuthProxyActivity"); + proxyActivity.CallStatic( + "perform", + helper.CurrentActivity, + socialNetworkObject, + callback); + } + catch (Exception e) + { + throw new AggregateException($"AndroidSocialAuth: {e.Message}", e); + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Android/AndroidSocialAuth.cs.meta b/Assets/Xsolla/Core/Android/AndroidSocialAuth.cs.meta new file mode 100644 index 000000000..403295a4e --- /dev/null +++ b/Assets/Xsolla/Core/Android/AndroidSocialAuth.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9322e93a4ac045709745de36200abb89 +timeCreated: 1683002338 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Browser/BrowserHelper.cs b/Assets/Xsolla/Core/Browser/BrowserHelper.cs deleted file mode 100644 index c89fea83b..000000000 --- a/Assets/Xsolla/Core/Browser/BrowserHelper.cs +++ /dev/null @@ -1,182 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -#if UNITY_WEBGL || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX -using System.Runtime.InteropServices; -#endif - -namespace Xsolla.Core -{ - public class BrowserHelper : MonoSingleton - { - private IInAppBrowser _inAppBrowser; - - public IInAppBrowser InAppBrowser - { - get - { -#if UNITY_EDITOR || UNITY_STANDALONE - if (_inAppBrowser != null) - return _inAppBrowser; - - if (XsollaSettings.InAppBrowserEnabled) - _inAppBrowser = GetComponent(); -#endif - - return _inAppBrowser; - } - } - - private readonly Dictionary _payStationSizes = new Dictionary{ - {PayStationUISettings.PaystationSize.Small, new Vector2(620, 630)}, - {PayStationUISettings.PaystationSize.Medium, new Vector2(740, 760)}, - {PayStationUISettings.PaystationSize.Large, new Vector2(820, 840)} - }; - - private readonly Dictionary _restrictedPaymentMethods = new Dictionary{ - {"https://secure.xsolla.com/pages/paywithgoogle", 3431}, - {"https://sandbox-secure.xsolla.com/pages/paywithgoogle", 3431}, - {"https://secure.xsolla.com/pages/vkpay", 3496}, - {"https://sandbox-secure.xsolla.com/pages/vkpay", 3496} - }; - -#if UNITY_WEBGL - [DllImport("__Internal")] - private static extern void OpenPaystationWidget(string token, bool sandbox); - - [DllImport("__Internal")] - private static extern void ClosePaystationWidget(); - - private static Action WebGLBrowserClosedCallback; - - public static void ClosePaystationWidget(bool isManually) - { - WebGLBrowserClosedCallback?.Invoke(isManually); - ClosePaystationWidget(); - } -#endif - -#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX - [DllImport("XsollaSdkNative")] - private static extern void OpenUrlInSafari(string url); -#endif - - public void OpenPurchase(string url, string token, bool forcePlatformBrowser = false, Action onRestrictedPaymentMethod = null, Action onBrowserClosed = null) - { - var isEditor = Application.isEditor; - var inAppBrowserEnabled = XsollaSettings.InAppBrowserEnabled; - var isSandbox = XsollaSettings.IsSandbox; - -#if UNITY_ANDROID - if (!isEditor && inAppBrowserEnabled) - { - using (var sdkHelper = new AndroidSDKPaymentsHelper()) - { - sdkHelper.PerformPayment(token, isSandbox, onBrowserClosed); - } - return; - } -#elif UNITY_IOS - if (!isEditor && inAppBrowserEnabled) - { - new IosSDKPaymentsHelper().PerformPayment(token, isSandbox, onBrowserClosed); - return; - } -#elif UNITY_WEBGL - if(Application.platform == RuntimePlatform.WebGLPlayer && inAppBrowserEnabled) - { - WebGLBrowserClosedCallback = onBrowserClosed; - Screen.fullScreen = false; - OpenPaystationWidget(token, isSandbox); - return; - } -#endif - - Open(url + token, forcePlatformBrowser); - -#if UNITY_STANDALONE || UNITY_EDITOR - if (InAppBrowser != null && !forcePlatformBrowser) - { - TrackRestrictedPaymentMethod(onRestrictedPaymentMethod); - UpdateBrowserSize(); - InAppBrowser.CloseEvent += onBrowserClosed; - } -#endif - } - - public void Open(string url, bool forcePlatformBrowser = false) - { - if (EnvironmentDefiner.IsStandaloneOrEditor && InAppBrowser != null && !forcePlatformBrowser) - { - OpenInAppBrowser(url); - } - else if (EnvironmentDefiner.IsWebGL) - { - OpenWebGlBrowser(url); - } - else - { - OpenPlatformBrowser(url); - } - } - - public void Close(float delay = 0) - { - InAppBrowser?.Close(delay); - } - - private void OpenInAppBrowser(string url) - { - InAppBrowser.Open(url); - } - - private void OpenWebGlBrowser(string url) - { -#pragma warning disable 0618 - Application.ExternalEval($"window.open(\"{url}\",\"_blank\")"); -#pragma warning restore 0618 - } - - private void OpenPlatformBrowser(string url) - { - Application.OpenURL(url); - } - -#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX - private void OpenSafari(string url) - { - OpenUrlInSafari(url); - } -#endif - -#if UNITY_STANDALONE || UNITY_EDITOR - private void UpdateBrowserSize() - { - InAppBrowser.AddInitHandler(() => - { - var payStationSettings = XsollaSettings.DesktopPayStationUISettings; - var payStationSize = payStationSettings.paystationSize != PayStationUISettings.PaystationSize.Auto - ? payStationSettings.paystationSize - : PayStationUISettings.PaystationSize.Medium; - - var viewportSize = _payStationSizes[payStationSize]; - InAppBrowser.UpdateSize((int) viewportSize.x, (int) viewportSize.y); - }); - } - - private void TrackRestrictedPaymentMethod(Action onRestrictedPaymentMethod) - { - InAppBrowser.AddInitHandler(() => - { - InAppBrowser.AddUrlChangeHandler(url => - { - if (_restrictedPaymentMethods.ContainsKey(url)) - { - onRestrictedPaymentMethod?.Invoke(_restrictedPaymentMethods[url]); - } - }); - }); - } -#endif - } -} diff --git a/Assets/Xsolla/Core/Browser/IInAppBrowser.cs b/Assets/Xsolla/Core/Browser/IInAppBrowser.cs index 219a89bf5..7d77fc394 100644 --- a/Assets/Xsolla/Core/Browser/IInAppBrowser.cs +++ b/Assets/Xsolla/Core/Browser/IInAppBrowser.cs @@ -6,16 +6,16 @@ public interface IInAppBrowser { event Action OpenEvent; - event Action CloseEvent; + event Action CloseEvent; event Action UrlChangeEvent; - + event Action AlertDialogEvent; - + event Action ConfirmDialogEvent; - + bool IsOpened { get; } - + void Open(string url); void Close(float delay = 0f, bool isManually = false); @@ -28,4 +28,4 @@ public interface IInAppBrowser void UpdateSize(int width, int height); } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Browser/Resources/BrowserHelper.prefab b/Assets/Xsolla/Core/Browser/Resources/XsollaWebBrowser.prefab similarity index 97% rename from Assets/Xsolla/Core/Browser/Resources/BrowserHelper.prefab rename to Assets/Xsolla/Core/Browser/Resources/XsollaWebBrowser.prefab index e1935df33..618f28c2f 100644 --- a/Assets/Xsolla/Core/Browser/Resources/BrowserHelper.prefab +++ b/Assets/Xsolla/Core/Browser/Resources/XsollaWebBrowser.prefab @@ -12,7 +12,7 @@ GameObject: - component: {fileID: 370317734354925448} - component: {fileID: 495463363682918236} m_Layer: 0 - m_Name: BrowserHelper + m_Name: XsollaWebBrowser m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -58,3 +58,4 @@ MonoBehaviour: m_EditorClassIdentifier: BrowserPrefab: {fileID: 2235249956668261828, guid: 60630ade61b56e946a1e7c4da7950f3f, type: 3} + IsDontDestroyOnLoad: 0 diff --git a/Assets/Xsolla/Core/Browser/Resources/BrowserHelper.prefab.meta b/Assets/Xsolla/Core/Browser/Resources/XsollaWebBrowser.prefab.meta similarity index 100% rename from Assets/Xsolla/Core/Browser/Resources/BrowserHelper.prefab.meta rename to Assets/Xsolla/Core/Browser/Resources/XsollaWebBrowser.prefab.meta diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPackPostprocessor.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPackPostprocessor.cs index 5404db99d..404b0691a 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPackPostprocessor.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPackPostprocessor.cs @@ -15,8 +15,8 @@ public class XsollaBrowserPackPostprocessor : IPostprocessBuildWithReport public void OnPostprocessBuild(BuildReport report) { if (report.summary.platformGroup != BuildTargetGroup.Standalone || - !XsollaSettings.InAppBrowserEnabled || - !XsollaSettings.PackInAppBrowserInBuild) + !XsollaSettings.InAppBrowserEnabled || + !XsollaSettings.PackInAppBrowserInBuild) return; var browserPlatform = string.Empty; @@ -38,14 +38,14 @@ public void OnPostprocessBuild(BuildReport report) if (string.IsNullOrEmpty(browserPlatform)) { - Debug.LogWarning($"Build target \"{report.summary.platform}\" is not supported. Packing browser in the build is skipped"); + XDebug.LogWarning($"Build target \"{report.summary.platform}\" is not supported. Packing browser in the build is skipped", true); return; } var buildBrowserDirectory = Path.GetDirectoryName(report.summary.outputPath); if (string.IsNullOrEmpty(buildBrowserDirectory)) throw new Exception(nameof(buildBrowserDirectory)); - + buildBrowserDirectory = Path.Combine(buildBrowserDirectory, ".local-chromium"); try @@ -55,7 +55,7 @@ public void OnPostprocessBuild(BuildReport report) } catch (Exception e) { - Debug.LogWarning($"Can't delete existing browser directory. Packing browser in the build is skipped. Exception: {e}"); + XDebug.LogWarning($"Can't delete existing browser directory. Packing browser in the build is skipped. Exception: {e}", true); return; } @@ -75,16 +75,16 @@ public void OnPostprocessBuild(BuildReport report) { if (Application.internetReachability == NetworkReachability.NotReachable) { - Debug.LogWarning("Internet connection is unavailable. Packing browser in the build is skipped"); + XDebug.LogWarning("Internet connection is unavailable. Packing browser in the build is skipped", true); return; } - var fetcher = new XsollaBrowserFetcher{ + var fetcher = new XsollaBrowserFetcher { Platform = browserPlatform, Path = buildBrowserDirectory, Revision = Constants.BROWSER_REVISION }; - + Task.Run(async () => await fetcher.DownloadAsync()).Wait(); } } diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserCheckPreprocessor.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPreprocessor.cs similarity index 73% rename from Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserCheckPreprocessor.cs rename to Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPreprocessor.cs index d636efb12..8f3186d84 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserCheckPreprocessor.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPreprocessor.cs @@ -4,7 +4,7 @@ namespace Xsolla.Core.Browser { - public class XsollaBrowserCheckPreprocessor : IPreprocessBuildWithReport + public class XsollaBrowserPreprocessor : IPreprocessBuildWithReport { public int callbackOrder { get; } @@ -15,8 +15,8 @@ public void OnPreprocessBuild(BuildReport report) //Check IL2CPP — browser supports only Mono. if (PlayerSettings.GetScriptingBackend(EditorUserBuildSettings.selectedBuildTargetGroup) == ScriptingImplementation.IL2CPP) - Debug.LogWarning(@"WARNING: In-App Browser does not support IL2CPP scripting backend and will result in Win32Exception upon launch. + XDebug.LogError(@"WARNING: In-App Browser does not support IL2CPP scripting backend and will result in Win32Exception upon launch. Please change scripting backend to Mono or disable In-App Browser."); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserCheckPreprocessor.cs.meta b/Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPreprocessor.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserCheckPreprocessor.cs.meta rename to Assets/Xsolla/Core/Browser/XsollaBrowser/Editor/XsollaBrowserPreprocessor.cs.meta diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/CloseButton/CloseBrowserButton.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/CloseButton/CloseBrowserButton.cs index 639cd7418..1810f6397 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/CloseButton/CloseBrowserButton.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/CloseButton/CloseBrowserButton.cs @@ -3,7 +3,7 @@ namespace Xsolla.Core.Browser { - public class CloseBrowserButton : MonoBehaviour + internal class CloseBrowserButton : MonoBehaviour { [SerializeField] private Button CloseButton; diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/InAppBrowser.prefab b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/XsollaInAppBrowser.prefab similarity index 87% rename from Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/InAppBrowser.prefab rename to Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/XsollaInAppBrowser.prefab index c59324c69..e57efdd29 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/InAppBrowser.prefab +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/XsollaInAppBrowser.prefab @@ -9,8 +9,11 @@ GameObject: serializedVersion: 6 m_Component: - component: {fileID: 7860819130398402569} + - component: {fileID: 8950912243514558821} + - component: {fileID: 5893333458352436540} + - component: {fileID: -5823321366377815275} m_Layer: 5 - m_Name: InAppBrowser + m_Name: XsollaInAppBrowser m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 @@ -37,6 +40,66 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: 0, y: 0} m_Pivot: {x: 0.5, y: 0.5} +--- !u!223 &8950912243514558821 +Canvas: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2235249956668261828} + m_Enabled: 1 + serializedVersion: 3 + m_RenderMode: 0 + m_Camera: {fileID: 0} + m_PlaneDistance: 100 + m_PixelPerfect: 1 + m_ReceivesEvents: 1 + m_OverrideSorting: 0 + m_OverridePixelPerfect: 0 + m_SortingBucketNormalizedSize: 0 + m_AdditionalShaderChannelsFlag: 0 + m_SortingLayerID: 0 + m_SortingOrder: 100 + m_TargetDisplay: 0 +--- !u!114 &5893333458352436540 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2235249956668261828} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 0cd44c1031e13a943bb63640046fad76, type: 3} + m_Name: + m_EditorClassIdentifier: + m_UiScaleMode: 1 + m_ReferencePixelsPerUnit: 100 + m_ScaleFactor: 1 + m_ReferenceResolution: {x: 1920, y: 1080} + m_ScreenMatchMode: 0 + m_MatchWidthOrHeight: 0.5 + m_PhysicalUnit: 3 + m_FallbackScreenDPI: 96 + m_DefaultSpriteDPI: 96 + m_DynamicPixelsPerUnit: 1 +--- !u!114 &-5823321366377815275 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 2235249956668261828} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: dc42784cf147c0c48a680349fa168899, type: 3} + m_Name: + m_EditorClassIdentifier: + m_IgnoreReversedGraphics: 1 + m_BlockingObjects: 0 + m_BlockingMask: + serializedVersion: 2 + m_Bits: 4294967295 --- !u!1001 &577635355487826629 PrefabInstance: m_ObjectHideFlags: 0 diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/InAppBrowser.prefab.meta b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/XsollaInAppBrowser.prefab.meta similarity index 100% rename from Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/InAppBrowser.prefab.meta rename to Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Prefabs/XsollaInAppBrowser.prefab.meta diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/Prefab/Preloader.prefab b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/Prefab/Preloader.prefab index bbad15b52..99bfaa52c 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/Prefab/Preloader.prefab +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/Prefab/Preloader.prefab @@ -11,7 +11,7 @@ GameObject: - component: {fileID: 5561199953501409930} - component: {fileID: 5561199953501409929} - component: {fileID: 5561199953501409928} - - component: {fileID: 3999812513701158159} + - component: {fileID: 1049038703679564542} m_Layer: 5 m_Name: BlackCircle m_TagString: Untagged @@ -55,17 +55,16 @@ MonoBehaviour: m_GameObject: {fileID: 5561199953501409925} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_Sprite: {fileID: 21300000, guid: 24bcef6b1d7c14fd1a5fa1351d1a6311, type: 3} m_Type: 0 m_PreserveAspect: 0 @@ -75,7 +74,8 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 ---- !u!114 &3999812513701158159 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &1049038703679564542 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -84,7 +84,7 @@ MonoBehaviour: m_GameObject: {fileID: 5561199953501409925} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ace5b50f1146743be9dd1382d9335217, type: 3} + m_Script: {fileID: 11500000, guid: 3de5891bdc874398803489ddf2813488, type: 3} m_Name: m_EditorClassIdentifier: Speed: -60 @@ -159,7 +159,7 @@ GameObject: - component: {fileID: 5561199954118118455} - component: {fileID: 5561199954118118453} - component: {fileID: 5561199954118118452} - - component: {fileID: 5561199954118118458} + - component: {fileID: 7330312468145340142} m_Layer: 5 m_Name: RedCircle m_TagString: Untagged @@ -203,17 +203,16 @@ MonoBehaviour: m_GameObject: {fileID: 5561199954118118454} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: -765806418, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_Sprite: {fileID: 21300000, guid: 369ec08421dc249768dd4d1fb3c031b0, type: 3} m_Type: 0 m_PreserveAspect: 0 @@ -223,7 +222,8 @@ MonoBehaviour: m_FillClockwise: 1 m_FillOrigin: 0 m_UseSpriteMesh: 0 ---- !u!114 &5561199954118118458 + m_PixelsPerUnitMultiplier: 1 +--- !u!114 &7330312468145340142 MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -232,7 +232,7 @@ MonoBehaviour: m_GameObject: {fileID: 5561199954118118454} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: ace5b50f1146743be9dd1382d9335217, type: 3} + m_Script: {fileID: 11500000, guid: 3de5891bdc874398803489ddf2813488, type: 3} m_Name: m_EditorClassIdentifier: Speed: 60 @@ -290,17 +290,16 @@ MonoBehaviour: m_GameObject: {fileID: 8502095929233832665} m_Enabled: 1 m_EditorHideFlags: 0 - m_Script: {fileID: 708705254, guid: f70555f144d8491a825f0804e09c671c, type: 3} + m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} m_Name: m_EditorClassIdentifier: m_Material: {fileID: 0} m_Color: {r: 1, g: 1, b: 1, a: 1} m_RaycastTarget: 1 + m_Maskable: 1 m_OnCullStateChanged: m_PersistentCalls: m_Calls: [] - m_TypeName: UnityEngine.UI.MaskableGraphic+CullStateChangedEvent, UnityEngine.UI, - Version=1.0.0.0, Culture=neutral, PublicKeyToken=null m_FontData: m_Font: {fileID: 12800000, guid: f70b0d194d863d14eaa3261671349a4b, type: 3} m_FontSize: 32 diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/PreloaderScript.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/PreloaderScript.cs index 0b953cd15..4c97f25b6 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/PreloaderScript.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/PreloaderScript.cs @@ -7,13 +7,14 @@ namespace Xsolla.Core.Browser public class PreloaderScript : MonoBehaviour { private Text text; + // Start is called before the first frame update - void Start() + private void Start() { text = transform.Find("Text").GetComponent(); } - public void SetPercent(uint value) + public void SetPercent(int value) { SetText($"Update{Environment.NewLine}{value}%"); } @@ -24,4 +25,4 @@ public void SetText(string value) text.text = value; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/RotateCircle.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/RotateCircle.cs new file mode 100644 index 000000000..1500df02d --- /dev/null +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/RotateCircle.cs @@ -0,0 +1,22 @@ +using UnityEngine; + +namespace Xsolla.Core.Browser +{ + public class RotateCircle : MonoBehaviour + { + [SerializeField] private float Speed = 60.0F; + + private RectTransform _circle; + + private void Awake() + { + _circle = (RectTransform) transform; + } + + private void Update() + { + var delta = Vector3.forward * Speed * Time.deltaTime; + _circle.Rotate(delta); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/RotateCircle.cs.meta b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/RotateCircle.cs.meta new file mode 100644 index 000000000..2aee580dc --- /dev/null +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/Preloader/RotateCircle.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3de5891bdc874398803489ddf2813488 +timeCreated: 1683276121 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/SinglePageBrowser2D.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/SinglePageBrowser2D.cs index 2b0ac63d1..ab46c1056 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/SinglePageBrowser2D.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/SinglePageBrowser2D.cs @@ -5,7 +5,7 @@ namespace Xsolla.Core.Browser { - public class SinglePageBrowser2D : MonoBehaviour + internal class SinglePageBrowser2D : MonoBehaviour { [SerializeField] private Button CloseButton; [SerializeField] private Button BackButton; @@ -19,7 +19,7 @@ public class SinglePageBrowser2D : MonoBehaviour public event Action AlertDialogEvent; public event Action ConfirmDialogEvent; #pragma warning restore CS0067 - + #if UNITY_EDITOR || UNITY_STANDALONE private XsollaBrowser xsollaBrowser; private Display2DBehaviour display; @@ -36,7 +36,7 @@ private void Awake() BackButton.gameObject.SetActive(false); xsollaBrowser = this.GetOrAddComponent(); - xsollaBrowser.LogEvent += Debug.Log; + xsollaBrowser.LogEvent += s => XDebug.Log(s); xsollaBrowser.Launch ( @@ -76,7 +76,7 @@ private IEnumerator Start() display.StartRedraw(Viewport.x, Viewport.y); display.RedrawFrameCompleteEvent += DestroyPreloader; display.RedrawFrameCompleteEvent += EnableCloseButton; - display.ViewportChangedEvent += (width, height) => UnityEngine.Debug.Log("Display viewport changed: " + width + "x" + height); + display.ViewportChangedEvent += (width, height) => XDebug.Log("Display viewport changed: " + width + "x" + height); mouse = this.GetOrAddComponent(); keyboard = this.GetOrAddComponent(); @@ -179,13 +179,13 @@ private void EnableCloseButton() private void OnCloseButtonPressed() { - Debug.Log("`Close` button pressed"); + XDebug.Log("`Close` button pressed"); BrowserCloseRequest?.Invoke(); } private void OnBackButtonPressed() { - Debug.Log("`Back` button pressed"); + XDebug.Log("`Back` button pressed"); xsollaBrowser.Navigate.Back(newUrl => { if (newUrl.Equals(urlBeforePopup)) @@ -198,8 +198,7 @@ private void OnBackButtonPressed() private void OnKeyboardEscapePressed() { - Debug.Log("`Escape` button pressed"); - Destroy(gameObject, 0.001f); + BrowserCloseRequest?.Invoke(); } private void HandleBrowserDialog(XsollaBrowserDialog dialog) @@ -236,7 +235,7 @@ private void ShowConfirmAlertPopup(XsollaBrowserDialog dialog) private void CloseAlert(XsollaBrowserDialog dialog) { - Debug.Log("Browser alert was closed automatically"); + XDebug.Log("Browser alert was closed automatically"); dialog.Accept(); } #endif diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Display2DBehaviour.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Display2DBehaviour.cs index 88cf24b4a..9f1e6732d 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Display2DBehaviour.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Display2DBehaviour.cs @@ -1,12 +1,12 @@ #if (UNITY_EDITOR || UNITY_STANDALONE) -using UnityEngine; -using System.Collections; using System; +using System.Collections; +using UnityEngine; using UnityEngine.UI; namespace Xsolla.Core.Browser { - public class Display2DBehaviour : MonoBehaviour + internal class Display2DBehaviour : MonoBehaviour { private IXsollaBrowserRender xsollaRender; private RawImage renderImage; @@ -20,7 +20,7 @@ private IEnumerator Start() { if (!GetComponentInParent()) { - Debug.LogError("Canvas not found. This browser for 2D project."); + XDebug.LogError("Canvas not found. This browser for 2D project."); Destroy(gameObject); yield break; } diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Keyboard2DBehaviour.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Keyboard2DBehaviour.cs index a03a43aa6..1ff080391 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Keyboard2DBehaviour.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Keyboard2DBehaviour.cs @@ -1,18 +1,18 @@ #if (UNITY_EDITOR || UNITY_STANDALONE) -using UnityEngine; -using System.Collections.Generic; using System; +using System.Collections.Generic; using System.Linq; +using UnityEngine; namespace Xsolla.Core.Browser { - public class Keyboard2DBehaviour : MonoBehaviour + internal class Keyboard2DBehaviour : MonoBehaviour { private IXsollaBrowserKeyboardInput keyboardInput; public event Action EscapePressed; - private static readonly List SystemKeys = new List{ + private static readonly List SystemKeys = new List { KeyCode.Escape }; diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Mouse2DBehaviour.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Mouse2DBehaviour.cs index 157ee2950..5cea6473b 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Mouse2DBehaviour.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Mouse2DBehaviour.cs @@ -1,12 +1,12 @@ #if (UNITY_EDITOR || UNITY_STANDALONE) -using UnityEngine; +using System; using System.Collections; +using UnityEngine; using UnityEngine.EventSystems; -using System; namespace Xsolla.Core.Browser { - public class Mouse2DBehaviour : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler, IScrollHandler + internal class Mouse2DBehaviour : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler, IScrollHandler { private Canvas canvas; private RectTransform selfRectTransform; @@ -56,7 +56,7 @@ void IPointerExitHandler.OnPointerExit(PointerEventData eventData) void IPointerClickHandler.OnPointerClick(PointerEventData eventData) { var mousePosition = CalculateBrowserMousePosition(eventData.position); - browserMouse.Click(mousePosition, pos => Debug.Log("Click handled by: " + pos)); + browserMouse.Click(mousePosition, pos => XDebug.Log("Click handled by: " + pos)); } void IScrollHandler.OnScroll(PointerEventData eventData) @@ -111,7 +111,7 @@ private Vector2 CalculateBrowserMousePosition(Vector3 inputMousePosition) return point; } - Debug.LogWarning("You try get mouse position, but mouse not over canvas"); + XDebug.LogWarning("You try get mouse position, but mouse not over canvas"); return Vector2.zero; } } diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Preloader2DBehaviour.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Preloader2DBehaviour.cs index b31ece73e..f2a30e76c 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Preloader2DBehaviour.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/Examples/2D/SinglePageBrowser2D/UserDefinedBehaviours/Preloader2DBehaviour.cs @@ -1,10 +1,10 @@ #if (UNITY_EDITOR || UNITY_STANDALONE) -using UnityEngine; using System.Collections; +using UnityEngine; namespace Xsolla.Core.Browser { - public class Preloader2DBehaviour : MonoBehaviour + internal class Preloader2DBehaviour : MonoBehaviour { private int lastProgress; private object progressLocker; @@ -49,7 +49,7 @@ private void OnBrowserFetchingEvent(int progress) if (lastProgress >= progress) return; - Debug.Log($"Update[%]: {lastProgress} => {progress}"); + XDebug.Log($"Update[%]: {lastProgress} => {progress}"); lastProgress = progress; StartCoroutine(PreloaderCoroutine(progress)); @@ -64,7 +64,7 @@ private IEnumerator PreloaderCoroutine(int progress) yield break; if (progress < 99) - preloaderObject.GetComponent().SetPercent((uint) progress); + preloaderObject.GetComponent().SetPercent((int) progress); else preloaderObject.GetComponent().SetText(string.Empty); } diff --git a/Assets/Xsolla/Core/Browser/XsollaBrowser/XsollaInAppBrowser.cs b/Assets/Xsolla/Core/Browser/XsollaBrowser/XsollaInAppBrowser.cs index eabb63532..7b10295e4 100644 --- a/Assets/Xsolla/Core/Browser/XsollaBrowser/XsollaInAppBrowser.cs +++ b/Assets/Xsolla/Core/Browser/XsollaBrowser/XsollaInAppBrowser.cs @@ -3,20 +3,19 @@ namespace Xsolla.Core.Browser { -#if (UNITY_EDITOR || UNITY_STANDALONE) - public class XsollaInAppBrowser : MonoBehaviour, IInAppBrowser +#if !(UNITY_EDITOR || UNITY_STANDALONE) + internal class XsollaInAppBrowser : MonoBehaviour { } #else - public class XsollaInAppBrowser : MonoBehaviour -#endif + internal class XsollaInAppBrowser : MonoBehaviour, IInAppBrowser { -#if (UNITY_EDITOR || UNITY_STANDALONE) [SerializeField] private GameObject BrowserPrefab; + [SerializeField] private bool IsDontDestroyOnLoad; private GameObject BrowserObject; private SinglePageBrowser2D SinglePageBrowser; private XsollaBrowser XsollaBrowser; public event Action OpenEvent; - public event Action CloseEvent; + public event Action CloseEvent; public event Action UrlChangeEvent; public event Action AlertDialogEvent; @@ -39,7 +38,10 @@ public void Close(float delay = 0f, bool isManually = false) if (BrowserObject) Destroy(BrowserObject, delay); - CloseEvent?.Invoke(isManually); + var info = new BrowserCloseInfo { + isManually = isManually + }; + CloseEvent?.Invoke(info); OpenEvent = null; CloseEvent = null; @@ -83,14 +85,10 @@ public void UpdateSize(int width, int height) private void CreateBrowser() { - var canvas = FindObjectOfType(); - if (canvas == null) - { - Debug.LogError("Can not find canvas! So can not draw 2D browser!"); - return; - } - - BrowserObject = Instantiate(BrowserPrefab, canvas.transform); + BrowserObject = Instantiate(BrowserPrefab); + BrowserObject.name = "XsollaInAppBrowser"; + if (IsDontDestroyOnLoad) + DontDestroyOnLoad(BrowserObject); SinglePageBrowser = BrowserObject.GetComponentInChildren(); SinglePageBrowser.BrowserCloseRequest += OnBrowserCloseRequest; @@ -120,6 +118,6 @@ private void OnConfirmDialogEvent(string message, Action acceptAction, Action ca { ConfirmDialogEvent?.Invoke(message, acceptAction, cancelAction); } -#endif } +#endif } \ No newline at end of file diff --git a/Assets/Xsolla/Core/Browser/XsollaWebBrowser.cs b/Assets/Xsolla/Core/Browser/XsollaWebBrowser.cs new file mode 100644 index 000000000..300cf1836 --- /dev/null +++ b/Assets/Xsolla/Core/Browser/XsollaWebBrowser.cs @@ -0,0 +1,191 @@ +using System; +using UnityEngine; +#if UNITY_WEBGL || UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX +using System.Runtime.InteropServices; +#endif + +namespace Xsolla.Core +{ + public class XsollaWebBrowser : MonoBehaviour + { + private static IInAppBrowser _inAppBrowser; + + public static IInAppBrowser InAppBrowser + { + get + { +#if !(UNITY_EDITOR || UNITY_STANDALONE) + return null; +#else + if (!XsollaSettings.InAppBrowserEnabled) + return null; + + if (_inAppBrowser == null) + { + var prefab = Resources.Load(Constants.WEB_BROWSER_RESOURCE_PATH); + if (prefab == null) + { + XDebug.LogError("Prefab InAppBrowser not found in Resources folder."); + } + else + { + var go = Instantiate(prefab); + go.name = "XsollaWebBrowser"; + DontDestroyOnLoad(go); + _inAppBrowser = go.GetComponent(); + } + } + + return _inAppBrowser; +#endif + } + } + + public static void OpenPurchaseUI(string paymentToken, bool forcePlatformBrowser = false, Action onBrowserClosed = null) + { +#if UNITY_ANDROID + if (!Application.isEditor && XsollaSettings.InAppBrowserEnabled) + { + new AndroidPayments().Perform( + paymentToken, + isClosedManually => + { + var info = new BrowserCloseInfo { + isManually = isClosedManually + }; + onBrowserClosed?.Invoke(info); + }); + + return; + } + +#elif UNITY_IOS + if (!Application.isEditor && XsollaSettings.InAppBrowserEnabled) + { + new IosPayments().Perform( + paymentToken, + isClosedManually => + { + var info = new BrowserCloseInfo { + isManually = isClosedManually + }; + onBrowserClosed?.Invoke(info); + }); + + return; + } + +#elif UNITY_WEBGL && !UNITY_EDITOR + if (XsollaSettings.InAppBrowserEnabled) + { + WebGLBrowserClosedCallback = isManually => + { + var info = new BrowserCloseInfo { + isManually = isManually + }; + onBrowserClosed?.Invoke(info); + }; + + Screen.fullScreen = false; + OpenPaystationWidget(paymentToken, XsollaSettings.IsSandbox); + return; + } +#endif + + var url = XsollaSettings.IsSandbox + ? Constants.PAYSTATION_SANDBOX_URL + : Constants.PAYSTATION_URL; + + url = new UrlBuilder(url) + .AddParam("access_token", paymentToken) + .Build(); + + Open(url, forcePlatformBrowser); + +#if UNITY_STANDALONE || UNITY_EDITOR + if (InAppBrowser != null && !forcePlatformBrowser) + { + UpdateBrowserSize(); + InAppBrowser.CloseEvent += onBrowserClosed; + } +#endif + } + + public static void Open(string url, bool forcePlatformBrowser = false) + { + XDebug.Log($"WebBrowser. Open url: {url}"); +#if UNITY_EDITOR || UNITY_STANDALONE + if (InAppBrowser != null && !forcePlatformBrowser) + InAppBrowser.Open(url); + else + Application.OpenURL(url); +#elif UNITY_WEBGL +#pragma warning disable 0618 + Application.ExternalEval($"window.open(\"{url}\",\"_blank\")"); +#pragma warning restore 0618 + return; +#else + Application.OpenURL(url); +#endif + } + + public static void Close(float delay = 0) + { + InAppBrowser?.Close(delay); + } + +#if UNITY_WEBGL + [DllImport("__Internal")] + private static extern void OpenPaystationWidget(string token, bool sandbox); + + [DllImport("__Internal")] + private static extern void ClosePaystationWidget(); + + private static Action WebGLBrowserClosedCallback; + + public static void ClosePaystationWidget(bool isManually) + { + WebGLBrowserClosedCallback?.Invoke(isManually); + ClosePaystationWidget(); + } +#endif + +#if UNITY_EDITOR_OSX || UNITY_STANDALONE_OSX + [DllImport("XsollaSdkNative")] + private static extern void OpenUrlInSafari(string url); + + public static void OpenSafari(string url) + { + OpenUrlInSafari(url); + } +#endif + +#if UNITY_STANDALONE || UNITY_EDITOR + private static void UpdateBrowserSize() + { + InAppBrowser.AddInitHandler(() => + { + var payStationSettings = XsollaSettings.DesktopPayStationUISettings; + var payStationSize = payStationSettings.paystationSize != PayStationUISettings.PaystationSize.Auto + ? payStationSettings.paystationSize + : PayStationUISettings.PaystationSize.Medium; + + var viewportSize = GetBrowserSize(payStationSize); + InAppBrowser.UpdateSize((int) viewportSize.x, (int) viewportSize.y); + }); + } + + private static Vector2 GetBrowserSize(PayStationUISettings.PaystationSize paystationSize) + { + switch (paystationSize) + { + case PayStationUISettings.PaystationSize.Small: return new Vector2(620, 630); + case PayStationUISettings.PaystationSize.Medium: return new Vector2(740, 760); + case PayStationUISettings.PaystationSize.Large: return new Vector2(820, 840); + default: + throw new ArgumentOutOfRangeException(nameof(paystationSize), paystationSize, null); + } + } +#endif + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Browser/BrowserHelper.cs.meta b/Assets/Xsolla/Core/Browser/XsollaWebBrowser.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Browser/BrowserHelper.cs.meta rename to Assets/Xsolla/Core/Browser/XsollaWebBrowser.cs.meta diff --git a/Assets/Xsolla/Core/Device.meta b/Assets/Xsolla/Core/Device.meta new file mode 100644 index 000000000..85951ab10 --- /dev/null +++ b/Assets/Xsolla/Core/Device.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 65778e024cc7427bbcbff4d2eb82029a +timeCreated: 1683528135 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Device/DeviceIdUtil.cs b/Assets/Xsolla/Core/Device/DeviceIdUtil.cs new file mode 100644 index 000000000..714381f3e --- /dev/null +++ b/Assets/Xsolla/Core/Device/DeviceIdUtil.cs @@ -0,0 +1,34 @@ +using UnityEngine; + +namespace Xsolla.Core +{ + public static class DeviceIdUtil + { + /// + /// Returns a device ID for user authentication in the format required by the Xsolla API. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). + public static string GetDeviceId() + { +#if UNITY_ANDROID + var contentResolver = new AndroidHelper().CurrentActivity.Call("getContentResolver"); + var secureSettings = new AndroidJavaClass("android.provider.Settings$Secure"); + return secureSettings.CallStatic("getString", contentResolver, "android_id"); +#elif UNITY_IOS + return SystemInfo.deviceUniqueIdentifier; +#else + throw new System.Exception($"Device id is not supported on this platform: {Application.platform}"); +#endif + } + + public static string GetDeviceName() + { + return SystemInfo.deviceName; + } + + public static string GetDeviceModel() + { + return SystemInfo.deviceModel; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/DeviceIdUtil.cs.meta b/Assets/Xsolla/Core/Device/DeviceIdUtil.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Utils/DeviceIdUtil.cs.meta rename to Assets/Xsolla/Core/Device/DeviceIdUtil.cs.meta diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestPreproces.cs b/Assets/Xsolla/Core/Editor/AndroidManifestPreproces.cs new file mode 100644 index 000000000..e5e839b7f --- /dev/null +++ b/Assets/Xsolla/Core/Editor/AndroidManifestPreproces.cs @@ -0,0 +1,107 @@ +using System.IO; +using UnityEditor; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; +using UnityEngine; + +namespace Xsolla.Core.Editor +{ + public class AndroidManifestPreproces : IPreprocessBuildWithReport + { + public int callbackOrder => 2000; + + public void OnPreprocessBuild(BuildReport report) + { + if (report.summary.platform != BuildTarget.Android) + return; + + XDebug.Log("Xsolla SDK is now processing AndroidManifest", true); + SetupWeChat(); + SetupProxyActivity("PaymentsProxyActivity"); + SetupProxyActivity("SocialAuthProxyActivity"); + } + + private static void SetupWeChat() + { + var androidPackageName = Application.identifier; + var wechatActivityName = $"{androidPackageName}.wxapi.WXEntryActivity"; + var wechatActivity = new ActivityNode(wechatActivityName); + wechatActivity.AddAttribute(AndroidManifestConstants.ExportedAttribute, "true"); + + var manifest = LoadManifestWrapper(); + var manifestChanged = false; + + // cleanup manifest in case WeChat activity was added previously + if (manifest.ContainsNode(new FindByTag(AndroidManifestConstants.ApplicationTag), new FindByName(wechatActivity))) + { + manifest.RemoveNode(new FindByTag(AndroidManifestConstants.ApplicationTag), new FindByName(wechatActivity)); + manifestChanged = true; + } + + if (!string.IsNullOrEmpty(XsollaSettings.WeChatAppId)) + { + manifest.AddNode(wechatActivity, new FindByTag(AndroidManifestConstants.ApplicationTag)); + manifestChanged = true; + } + + if (manifestChanged) + manifest.SaveManifest(); + } + + private static void SetupProxyActivity(string activityName) + { + var fullActivityName = $"{Application.identifier}.androidProxies.{activityName}"; + var activityNode = new ActivityNode(fullActivityName); + activityNode.AddAttribute(AndroidManifestConstants.ExportedAttribute, "true"); + activityNode.AddAttribute(AndroidManifestConstants.ConfigChanges, "orientation|screenSize|keyboardHidden"); + + var manifest = LoadManifestWrapper(); + + // cleanup manifest in case activity node was added previously + if (manifest.ContainsNode(new FindByTag(AndroidManifestConstants.ApplicationTag), new FindByName(activityNode))) + manifest.RemoveNode(new FindByTag(AndroidManifestConstants.ApplicationTag), new FindByName(activityNode)); + + manifest.AddNode(activityNode, new FindByTag(AndroidManifestConstants.ApplicationTag)); + manifest.SaveManifest(); + } + + private static AndroidManifestWrapper LoadManifestWrapper() + { + var manifestPath = Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"); + if (!File.Exists(manifestPath)) + { + var manifestDirectory = Path.GetDirectoryName(manifestPath); + if (manifestDirectory != null && !Directory.Exists(manifestDirectory)) + Directory.CreateDirectory(manifestDirectory); + + var templatePath = GetTemplateFilePath("AndroidManifest.xml"); + File.Copy(templatePath, manifestPath); + } + + return new AndroidManifestWrapper(manifestPath); + } + + private static string GetTemplateFilePath(string fileName) + { + var path = GetTemplatesDirectory(Application.dataPath); + return path != null + ? Path.Combine(path, fileName) + : null; + } + + private static string GetTemplatesDirectory(string path) + { + foreach (var dir in Directory.GetDirectories(path)) + { + if (dir.Contains("AndroidTemplateFiles")) + return dir; + + var recursiveSearchResult = GetTemplatesDirectory(dir); + if (recursiveSearchResult != null) + return recursiveSearchResult; + } + + return null; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestPreprocessor.cs.meta b/Assets/Xsolla/Core/Editor/AndroidManifestPreproces.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Editor/AndroidManifestPreprocessor.cs.meta rename to Assets/Xsolla/Core/Editor/AndroidManifestPreproces.cs.meta diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestPreprocessor.cs b/Assets/Xsolla/Core/Editor/AndroidManifestPreprocessor.cs deleted file mode 100644 index b54aa832b..000000000 --- a/Assets/Xsolla/Core/Editor/AndroidManifestPreprocessor.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System.IO; -using UnityEditor.Build; -using UnityEditor.Build.Reporting; -using UnityEngine; - -namespace Xsolla.Core.Editor -{ - public class AndroidManifestPreprocessor : IPreprocessBuildWithReport - { - const string MainManifestPath = "Plugins/Android/AndroidManifest.xml"; - - public int callbackOrder - { - get { return 2000; } - } - - public void OnPreprocessBuild(BuildReport report) - { -#if UNITY_ANDROID - Debug.Log("Xsolla SDK is now preprocessing your AndroidManifest.xml"); - SetupWeChat(); - SetupProxyActivity("AndroidPaymentsProxy"); - SetupProxyActivity("AndroidAuthProxy"); -#endif - } - - void SetupWeChat() - { - var manifestPath = Path.Combine(Application.dataPath, MainManifestPath); - var manifestExists = File.Exists(manifestPath); - - if (!manifestExists) - { - if (string.IsNullOrEmpty(XsollaSettings.WeChatAppId)) - { - return; - } - - RestoreAndroidManifest(manifestPath); - } - - var manifest = new AndroidManifestWrapper(manifestPath); - - var androidPackageName = Application.identifier; - var wechatActivityName = string.Format("{0}.wxapi.WXEntryActivity", androidPackageName); - - var wechatActivity = new ActivityNode(wechatActivityName); - wechatActivity.AddAttribute(AndroidManifestConstants.ExportedAttribute, "true"); - - var manifestChanged = false; - - // cleanup manifest in case WeChat activity was added previously - if (manifest.ContainsNode(new FindByTag(AndroidManifestConstants.ApplicationTag), new FindByName(wechatActivity))) - { - manifest.RemoveNode(new FindByTag(AndroidManifestConstants.ApplicationTag), new FindByName(wechatActivity)); - manifestChanged = true; - } - - if (!string.IsNullOrEmpty(XsollaSettings.WeChatAppId)) - { - manifest.AddNode(wechatActivity, new FindByTag(AndroidManifestConstants.ApplicationTag)); - manifestChanged = true; - } - - if (manifestChanged) - { - manifest.SaveManifest(); - } - } - - private void SetupProxyActivity(string activityName) - { - var manifestPath = Path.Combine(Application.dataPath, MainManifestPath); - var manifestExists = File.Exists(manifestPath); - - if (!manifestExists) - { - RestoreAndroidManifest(manifestPath); - } - - var manifestWrapper = new AndroidManifestWrapper(manifestPath); - var fullActivityName = $"{Application.identifier}.androidProxies.{activityName}"; - - var activityNode = new ActivityNode(fullActivityName); - activityNode.AddAttribute(AndroidManifestConstants.ExportedAttribute, "true"); - activityNode.AddAttribute(AndroidManifestConstants.ConfigChanges, "orientation|screenSize|keyboardHidden"); - - // cleanup manifest in case activity node was added previously - if (manifestWrapper.ContainsNode(new FindByTag(AndroidManifestConstants.ApplicationTag), new FindByName(activityNode))) - manifestWrapper.RemoveNode(new FindByTag(AndroidManifestConstants.ApplicationTag), new FindByName(activityNode)); - - manifestWrapper.AddNode(activityNode, new FindByTag(AndroidManifestConstants.ApplicationTag)); - manifestWrapper.SaveManifest(); - } - - static void RestoreAndroidManifest(string manifestPath) - { - var backupManifestPath = Path.Combine(FindAndroidManifestBackup(Application.dataPath).Replace("\\", "/"), "AndroidManifest.xml"); - - var manifestDirectoryPath = Path.GetDirectoryName(manifestPath); - if (!Directory.Exists(manifestDirectoryPath)) - { - Directory.CreateDirectory(manifestDirectoryPath); - } - - File.Copy(backupManifestPath, manifestPath); - } - - static string FindAndroidManifestBackup(string path) - { - foreach (var dir in Directory.GetDirectories(path)) - { - if (dir.Contains("AndroidManifestBackup")) - { - return dir; - } - - var recursiveSearchResult = FindAndroidManifestBackup(dir); - if (recursiveSearchResult != null) - { - return recursiveSearchResult; - } - } - - return null; - } - } -} diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/AndroidManifestConstants.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/AndroidManifestConstants.cs index c2c406e28..4f0fa92a1 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/AndroidManifestConstants.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/AndroidManifestConstants.cs @@ -19,4 +19,4 @@ public class AndroidManifestConstants public const string ExportedAttribute = "android:exported"; public const string ConfigChanges = "android:configChanges"; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/AndroidManifestWrapper.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/AndroidManifestWrapper.cs index 7476167cb..74c679d95 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/AndroidManifestWrapper.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/AndroidManifestWrapper.cs @@ -1,5 +1,4 @@ using System.Xml; -using UnityEngine; namespace Xsolla.Core.Editor { @@ -7,7 +6,6 @@ public class AndroidManifestWrapper { private readonly string manifestPath; private readonly XmlDocument xmlDocument; - private readonly XmlNode applicationNode; public AndroidManifestWrapper(string path) { @@ -16,11 +14,10 @@ public AndroidManifestWrapper(string path) xmlDocument = new XmlDocument(); xmlDocument.Load(path); - applicationNode = xmlDocument.FindNodeRecursive(new FindByTag(AndroidManifestConstants.ApplicationTag)); - + var applicationNode = xmlDocument.FindNodeRecursive(new FindByTag(AndroidManifestConstants.ApplicationTag)); if (applicationNode == null) { - Debug.LogError($"Failed to parse AndroidManifest.xml with path {path}"); + XDebug.LogError($"Failed to parse AndroidManifest.xml with path {path}"); } } @@ -33,7 +30,7 @@ public void AddNode(BaseManifestNode node, IFindCriteria parentNodeCrit } else { - Debug.LogError("Failed to add new node to AndroidManifest.xml since no specified parent node found"); + XDebug.LogError("Failed to add new node to AndroidManifest.xml since no specified parent node found"); } } @@ -49,7 +46,7 @@ public void RemoveNode(IFindCriteria parentNodeCriteria, IFindCriteria< } } } - + public bool ContainsNode(IFindCriteria parentNodeCriteria, IFindCriteria containsCriteria) { var parentNode = xmlDocument.FindNodeRecursive(parentNodeCriteria); @@ -64,18 +61,17 @@ public bool ContainsNode(IFindCriteria parentNodeCriteria, IFindCriteri public void SaveManifest() { - var settings = new XmlWriterSettings - { + var settings = new XmlWriterSettings { NewLineChars = "\r\n", NewLineHandling = NewLineHandling.Replace, Indent = true, IndentChars = " " }; - using (XmlWriter xmlWriter = XmlWriter.Create(manifestPath, settings)) + using (var xmlWriter = XmlWriter.Create(manifestPath, settings)) { xmlDocument.Save(xmlWriter); } } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByChildName.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByChildName.cs index 303872527..2e8db0eeb 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByChildName.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByChildName.cs @@ -22,11 +22,11 @@ public bool MatchesCriteria(XmlNode xmlNode) if (tag.Equals(xmlNode.Name)) { - var child = xmlNode.FindNodeRecursive(new FindByName(this.childNode)); + var child = xmlNode.FindNodeRecursive(new FindByName(childNode)); return child != null; } return false; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByLabel.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByLabel.cs index ca48a897b..86edea370 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByLabel.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByLabel.cs @@ -20,12 +20,12 @@ public bool MatchesCriteria(XmlNode xmlNode) { var attributeNode = xmlNode.Attributes.GetNamedItem(AndroidManifestConstants.LabelAttribute); return attributeNode != null - && node.Attributes.ContainsKey(AndroidManifestConstants.LabelAttribute) - && attributeNode.Value.Equals(node.Attributes[AndroidManifestConstants.LabelAttribute]); + && node.Attributes.ContainsKey(AndroidManifestConstants.LabelAttribute) + && attributeNode.Value.Equals(node.Attributes[AndroidManifestConstants.LabelAttribute]); } } return false; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByName.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByName.cs index 8d9fcc0e6..f183372e3 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByName.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByName.cs @@ -20,12 +20,12 @@ public bool MatchesCriteria(XmlNode xmlNode) { var attributeNode = xmlNode.Attributes.GetNamedItem(AndroidManifestConstants.NameAttribute); return attributeNode != null - && node.Attributes.ContainsKey(AndroidManifestConstants.NameAttribute) - && attributeNode.Value.Equals(node.Attributes[AndroidManifestConstants.NameAttribute]); + && node.Attributes.ContainsKey(AndroidManifestConstants.NameAttribute) + && attributeNode.Value.Equals(node.Attributes[AndroidManifestConstants.NameAttribute]); } } return false; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByTag.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByTag.cs index 36662ea58..abf5af66b 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByTag.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/FindByTag.cs @@ -21,4 +21,4 @@ public bool MatchesCriteria(XmlNode xmlNode) return tag.Equals(xmlNode.Name); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/IFindCriteria.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/IFindCriteria.cs index 71fe000a0..e6341de53 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/IFindCriteria.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/FindCriterias/IFindCriteria.cs @@ -4,4 +4,4 @@ public interface IFindCriteria { bool MatchesCriteria(T obj); } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/ActionNode.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/ActionNode.cs index 989b0c474..b7dad6844 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/ActionNode.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/ActionNode.cs @@ -5,9 +5,8 @@ namespace Xsolla.Core.Editor public class ActionNode : BaseManifestNode { public ActionNode(string name) : base( - AndroidManifestConstants.ActionTag, AndroidManifestConstants.IntentFilterTag, - new Dictionary {{AndroidManifestConstants.NameAttribute, name}}) - { - } + AndroidManifestConstants.ActionTag, + AndroidManifestConstants.IntentFilterTag, + new Dictionary {{AndroidManifestConstants.NameAttribute, name}}) { } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/ActivityNode.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/ActivityNode.cs index 1ddd4f907..5b1edc589 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/ActivityNode.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/ActivityNode.cs @@ -5,9 +5,8 @@ namespace Xsolla.Core.Editor public class ActivityNode : BaseManifestNode { public ActivityNode(string name) : base( - AndroidManifestConstants.ActivityTag, AndroidManifestConstants.ApplicationTag, - new Dictionary {{AndroidManifestConstants.NameAttribute, name}}) - { - } + AndroidManifestConstants.ActivityTag, + AndroidManifestConstants.ApplicationTag, + new Dictionary {{AndroidManifestConstants.NameAttribute, name}}) { } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/BaseManifestNode.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/BaseManifestNode.cs index 4c40f53b4..e8d877af9 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/BaseManifestNode.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/BaseManifestNode.cs @@ -6,9 +6,8 @@ public class BaseManifestNode { public string Tag { get; private set; } public string ParentTag { get; private set; } - public Dictionary Attributes { get; private set; } - public List ChildNodes { get; private set; } - + public Dictionary Attributes { get; } + public List ChildNodes { get; } public BaseManifestNode(string tag, string parentTag = "", Dictionary attributes = null, List childNodes = null) { @@ -28,4 +27,4 @@ public void AddAttribute(string key, string value) Attributes.Add(key, value); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/CategoryNode.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/CategoryNode.cs index 47cfdb1a8..0ead3bc06 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/CategoryNode.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/CategoryNode.cs @@ -5,9 +5,8 @@ namespace Xsolla.Core.Editor public class CategoryNode : BaseManifestNode { public CategoryNode(string name) : base( - AndroidManifestConstants.CategoryTag, AndroidManifestConstants.IntentFilterTag, - new Dictionary {{AndroidManifestConstants.NameAttribute, name}}) - { - } + AndroidManifestConstants.CategoryTag, + AndroidManifestConstants.IntentFilterTag, + new Dictionary {{AndroidManifestConstants.NameAttribute, name}}) { } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/DataNode.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/DataNode.cs index 58fa28b20..778c06e12 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/DataNode.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/DataNode.cs @@ -3,7 +3,8 @@ namespace Xsolla.Core.Editor public class DataNode : BaseManifestNode { public DataNode(string scheme, string host, string pathPrefix) : base( - AndroidManifestConstants.DataTag, AndroidManifestConstants.IntentFilterTag) + AndroidManifestConstants.DataTag, + AndroidManifestConstants.IntentFilterTag) { AddAttribute("android:scheme", scheme); AddAttribute("android:host", host); @@ -12,4 +13,4 @@ public DataNode(string scheme, string host, string pathPrefix) : base( AddAttribute("android:pathPrefix", pathPrefix); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/IntentFilterNode.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/IntentFilterNode.cs index 6462efedb..161e21f15 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/IntentFilterNode.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/ManifestNodes/IntentFilterNode.cs @@ -1,11 +1,9 @@ -using System.Collections.Generic; - namespace Xsolla.Core.Editor { public class IntentFilterNode : BaseManifestNode { - public IntentFilterNode(string parentTag) : base(AndroidManifestConstants.IntentFilterTag, parentTag) - { - } + public IntentFilterNode(string parentTag) : base( + AndroidManifestConstants.IntentFilterTag, + parentTag) { } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/XmlUtils/XmlNodeExtensions.cs b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/XmlUtils/XmlNodeExtensions.cs index 9a0af4431..c40e39004 100644 --- a/Assets/Xsolla/Core/Editor/AndroidManifestUtils/XmlUtils/XmlNodeExtensions.cs +++ b/Assets/Xsolla/Core/Editor/AndroidManifestUtils/XmlUtils/XmlNodeExtensions.cs @@ -11,7 +11,7 @@ public static XmlNode FindNodeRecursive(this XmlNode root, IFindCriteria criteria) { - XmlNode currentNode = root.FirstChild; + var currentNode = root.FirstChild; while (currentNode != null) { if (criteria.MatchesCriteria(currentNode)) @@ -62,7 +62,6 @@ public static void AddAndroidManifestNode(this XmlNode root, XmlDocument xmlDocu } node.ChildNodes.ForEach(childNode => xmlElement.AddAndroidManifestNode(xmlDocument, childNode)); - root.InsertAt(xmlElement, 0); } @@ -92,4 +91,4 @@ public static void InsertAt(this XmlNode node, XmlNode insertingNode, int index node.InsertBefore(insertingNode, followingNode); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidPaymentsProxy.java b/Assets/Xsolla/Core/Editor/AndroidNativeScripts/PaymentsProxyActivity.java similarity index 85% rename from Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidPaymentsProxy.java rename to Assets/Xsolla/Core/Editor/AndroidNativeScripts/PaymentsProxyActivity.java index 8094cdd46..18dba1aa3 100644 --- a/Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidPaymentsProxy.java +++ b/Assets/Xsolla/Core/Editor/AndroidNativeScripts/PaymentsProxyActivity.java @@ -1,15 +1,14 @@ -package com.XsollaInc.XsollaInGameStoreUnityAsset.androidProxies; +package com.xsolla.sdk.unity.Example.androidProxies; import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import com.unity3d.player.UnityPlayer; import com.xsolla.android.payments.XPayments; import com.xsolla.android.payments.data.AccessToken; import com.xsolla.android.payments.callback.BrowserCallback; -public class AndroidPaymentsProxy extends Activity { +public class PaymentsProxyActivity extends Activity { private static final String ARG_TOKEN = "token"; private static final String ARG_SANDBOX = "isSandbox"; @@ -19,10 +18,10 @@ public class AndroidPaymentsProxy extends Activity { private static BrowserCallback browserCallback; - public static void performPayment(Activity activity, String token, boolean isSandbox, String redirectScheme, String redirectHost, BrowserCallback callback) { + public static void perform(Activity activity, String token, boolean isSandbox, String redirectScheme, String redirectHost, BrowserCallback callback) { browserCallback = callback; - Intent intent = new Intent(activity, AndroidPaymentsProxy.class); + Intent intent = new Intent(activity, PaymentsProxyActivity.class); intent.putExtra(ARG_TOKEN, token); intent.putExtra(ARG_SANDBOX, isSandbox); intent.putExtra(ARG_REDIRECT_HOST, redirectHost); diff --git a/Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidPaymentsProxy.java.meta b/Assets/Xsolla/Core/Editor/AndroidNativeScripts/PaymentsProxyActivity.java.meta similarity index 100% rename from Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidPaymentsProxy.java.meta rename to Assets/Xsolla/Core/Editor/AndroidNativeScripts/PaymentsProxyActivity.java.meta diff --git a/Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidAuthProxy.java b/Assets/Xsolla/Core/Editor/AndroidNativeScripts/SocialAuthProxyActivity.java similarity index 86% rename from Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidAuthProxy.java rename to Assets/Xsolla/Core/Editor/AndroidNativeScripts/SocialAuthProxyActivity.java index deccc3f44..d97f8b05b 100644 --- a/Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidAuthProxy.java +++ b/Assets/Xsolla/Core/Editor/AndroidNativeScripts/SocialAuthProxyActivity.java @@ -1,29 +1,25 @@ -package com.XsollaInc.XsollaInGameStoreUnityAsset.androidProxies; - -import java.lang.reflect.*; +package com.xsolla.sdk.unity.Example.androidProxies; import android.app.Activity; import android.content.Intent; import android.os.Bundle; -import com.unity3d.player.UnityPlayer; - import com.xsolla.android.login.XLogin; import com.xsolla.android.login.social.SocialNetwork; import com.xsolla.android.login.callback.AuthCallback; import com.xsolla.android.login.callback.StartSocialCallback; import com.xsolla.android.login.callback.FinishSocialCallback; -public class AndroidAuthProxy extends Activity +public class SocialAuthProxyActivity extends Activity { private static SocialNetwork targetSocialNetwork; private static AuthCallback authCallback; - public static void authSocial(Activity currentActivity, Activity proxyActivity, SocialNetwork socialNetwork, AuthCallback callback) + public static void perform(Activity currentActivity, SocialNetwork socialNetwork, AuthCallback callback) { targetSocialNetwork = socialNetwork; authCallback = callback; - currentActivity.startActivity(new Intent(currentActivity, AndroidAuthProxy.class)); + currentActivity.startActivity(new Intent(currentActivity, SocialAuthProxyActivity.class)); } @Override diff --git a/Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidAuthProxy.java.meta b/Assets/Xsolla/Core/Editor/AndroidNativeScripts/SocialAuthProxyActivity.java.meta similarity index 100% rename from Assets/Xsolla/Core/Editor/AndroidNativeScripts/AndroidAuthProxy.java.meta rename to Assets/Xsolla/Core/Editor/AndroidNativeScripts/SocialAuthProxyActivity.java.meta diff --git a/Assets/Xsolla/Core/Editor/AndroidNativeScripts/WXEntryActivity.java b/Assets/Xsolla/Core/Editor/AndroidNativeScripts/WXEntryActivity.java index 23119c2e7..a53ddf130 100644 --- a/Assets/Xsolla/Core/Editor/AndroidNativeScripts/WXEntryActivity.java +++ b/Assets/Xsolla/Core/Editor/AndroidNativeScripts/WXEntryActivity.java @@ -1,4 +1,4 @@ -package com.XsollaInc.XsollaInGameStoreUnityAsset.wxapi; +package com.xsolla.sdk.unity.Example.wxapi; import android.app.Activity; import android.os.Bundle; diff --git a/Assets/Xsolla/Core/Editor/AndroidScriptsPreprocess.cs b/Assets/Xsolla/Core/Editor/AndroidScriptsPreprocess.cs new file mode 100644 index 000000000..967686a0e --- /dev/null +++ b/Assets/Xsolla/Core/Editor/AndroidScriptsPreprocess.cs @@ -0,0 +1,71 @@ +using System.IO; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; +using UnityEngine; + +namespace Xsolla.Core.Editor +{ + public class AndroidScriptsPreprocess : IPreprocessBuildWithReport + { + public int callbackOrder => 3000; + + public void OnPreprocessBuild(BuildReport report) + { + if (report.summary.platform != BuildTarget.Android) + return; + + SetupActivity("PaymentsProxyActivity", true, "androidProxies"); + SetupActivity("SocialAuthProxyActivity", true, "androidProxies"); + SetupActivity("WXEntryActivity", !string.IsNullOrEmpty(XsollaSettings.WeChatAppId), "wxapi"); + } + + private static void SetupActivity(string activityName, bool enableCondition, string packageSuffix) + { + var activityScriptPath = GetScriptFilePath($"{activityName}.java"); + if (!File.Exists(activityScriptPath)) + { + XDebug.LogError($"Xsolla {activityName} activity script is missing!"); + return; + } + + var assetPath = "Assets" + activityScriptPath.Substring(Application.dataPath.Length); + var activityAsset = AssetImporter.GetAtPath(assetPath) as PluginImporter; + if (activityAsset != null) + { + activityAsset.SetCompatibleWithPlatform(BuildTarget.Android, enableCondition); + activityAsset.SaveAndReimport(); + } + + var scriptContent = File.ReadAllText(activityScriptPath); + var packageLineText = $"package {Application.identifier}.{packageSuffix};"; + scriptContent = Regex.Replace(scriptContent, "package.+;", packageLineText); + + File.WriteAllText(activityScriptPath, scriptContent); + } + + private static string GetScriptFilePath(string fileName) + { + var path = GetScriptsDirectory(Application.dataPath); + return path != null + ? Path.Combine(path, fileName) + : null; + } + + private static string GetScriptsDirectory(string path) + { + foreach (var dir in Directory.GetDirectories(path)) + { + if (dir.Contains("AndroidNativeScripts")) + return dir; + + var recursiveSearchResult = GetScriptsDirectory(dir); + if (recursiveSearchResult != null) + return recursiveSearchResult; + } + + return null; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidScriptsPreprocessor.cs.meta b/Assets/Xsolla/Core/Editor/AndroidScriptsPreprocess.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Editor/AndroidScriptsPreprocessor.cs.meta rename to Assets/Xsolla/Core/Editor/AndroidScriptsPreprocess.cs.meta diff --git a/Assets/Xsolla/Core/Editor/AndroidScriptsPreprocessor.cs b/Assets/Xsolla/Core/Editor/AndroidScriptsPreprocessor.cs deleted file mode 100644 index 8ad1a9234..000000000 --- a/Assets/Xsolla/Core/Editor/AndroidScriptsPreprocessor.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System.IO; -using System.Text.RegularExpressions; -using UnityEditor; -using UnityEditor.Build; -using UnityEditor.Build.Reporting; -using UnityEngine; - -namespace Xsolla.Core.Editor -{ - public class AndroidScriptsPreprocessor : IPreprocessBuildWithReport - { - public int callbackOrder - { - get { return 3000; } - } - - public void OnPreprocessBuild(BuildReport report) - { -#if UNITY_ANDROID - Debug.Log("Xsolla SDK is now preprocessing native Android scripts."); - SetupActivity("WXEntryActivity", enableCondition:!string.IsNullOrEmpty(XsollaSettings.WeChatAppId), packageSuffix:"wxapi"); - SetupActivity("AndroidPaymentsProxy", enableCondition:true, packageSuffix:"androidProxies"); - SetupActivity("AndroidAuthProxy", enableCondition:true, packageSuffix:"androidProxies"); -#endif - } - - private void SetupActivity(string activityName, bool enableCondition, string packageSuffix) - { - var activityScriptPath = Path.Combine(FindAndroidScripts(Application.dataPath).Replace("\\", "/"), $"{activityName}.java"); - - if (!File.Exists(activityScriptPath)) - { - Debug.LogError($"{activityName} activity script is missing."); - return; - } - - var assetPath = "Assets" + activityScriptPath.Substring(Application.dataPath.Length); - var activityAsset = AssetImporter.GetAtPath(assetPath) as PluginImporter; - if (activityAsset != null) - { - activityAsset.SetCompatibleWithPlatform(BuildTarget.Android, enableCondition); - activityAsset.SaveAndReimport(); - } - - var scriptContent = File.ReadAllText(activityScriptPath); - - var androidPackageName = Application.identifier; - var editedScriptContent = Regex.Replace(scriptContent, "package.+;", $"package {androidPackageName}.{packageSuffix};"); - - File.WriteAllText(activityScriptPath, editedScriptContent); - } - - private static string FindAndroidScripts(string path) - { - foreach (var dir in Directory.GetDirectories(path)) - { - if (dir.Contains("AndroidNativeScripts")) - { - return dir; - } - - var recursiveSearchResult = FindAndroidScripts(dir); - if (recursiveSearchResult != null) - { - return recursiveSearchResult; - } - } - - return null; - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestBackup.meta b/Assets/Xsolla/Core/Editor/AndroidTemplateFiles.meta similarity index 100% rename from Assets/Xsolla/Core/Editor/AndroidManifestBackup.meta rename to Assets/Xsolla/Core/Editor/AndroidTemplateFiles.meta diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestBackup/AndroidManifest.xml b/Assets/Xsolla/Core/Editor/AndroidTemplateFiles/AndroidManifest.xml similarity index 100% rename from Assets/Xsolla/Core/Editor/AndroidManifestBackup/AndroidManifest.xml rename to Assets/Xsolla/Core/Editor/AndroidTemplateFiles/AndroidManifest.xml diff --git a/Assets/Xsolla/Core/Editor/AndroidManifestBackup/AndroidManifest.xml.meta b/Assets/Xsolla/Core/Editor/AndroidTemplateFiles/AndroidManifest.xml.meta similarity index 100% rename from Assets/Xsolla/Core/Editor/AndroidManifestBackup/AndroidManifest.xml.meta rename to Assets/Xsolla/Core/Editor/AndroidTemplateFiles/AndroidManifest.xml.meta diff --git a/Assets/Xsolla/Core/Editor/BuildPreProcess.cs b/Assets/Xsolla/Core/Editor/BuildPreProcess.cs deleted file mode 100644 index ed4c1927c..000000000 --- a/Assets/Xsolla/Core/Editor/BuildPreProcess.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System.IO; -using System.Text.RegularExpressions; -using UnityEditor; -using UnityEditor.Build; -using UnityEditor.Build.Reporting; -using UnityEngine; - -namespace Xsolla.Core.Editor -{ - public class BuildPreProcess : IPreprocessBuildWithReport - { - public int callbackOrder - { - get { return 3000; } - } - - public void OnPreprocessBuild(BuildReport report) - { - if (report.summary.platform == BuildTarget.StandaloneOSX) - { - var steamLibPath = "Assets/Xsolla/ThirdParty/Steamworks.NET-master/Plugins/steam_api.bundle"; - var steamLibAsset = AssetImporter.GetAtPath(steamLibPath) as PluginImporter; - if (steamLibAsset != null) - { - steamLibAsset.SetPlatformData(BuildTarget.StandaloneOSX,"OS", "OSX"); - steamLibAsset.SetPlatformData(BuildTarget.StandaloneOSX,"CPU", "AnyCPU"); - steamLibAsset.SaveAndReimport(); - } - } - } - } -} diff --git a/Assets/Xsolla/Core/Editor/StandaloneBuildPreprocess.cs b/Assets/Xsolla/Core/Editor/StandaloneBuildPreprocess.cs new file mode 100644 index 000000000..a8052cd13 --- /dev/null +++ b/Assets/Xsolla/Core/Editor/StandaloneBuildPreprocess.cs @@ -0,0 +1,26 @@ +using UnityEditor; +using UnityEditor.Build; +using UnityEditor.Build.Reporting; + +namespace Xsolla.Core.Editor +{ + public class StandaloneBuildPreprocess : IPreprocessBuildWithReport + { + public int callbackOrder => 3000; + + public void OnPreprocessBuild(BuildReport report) + { + if (report.summary.platform != BuildTarget.StandaloneOSX) + return; + + var steamLibPath = "Assets/Xsolla/ThirdParty/Steamworks.NET-master/Plugins/steam_api.bundle"; + var steamLibAsset = AssetImporter.GetAtPath(steamLibPath) as PluginImporter; + if (steamLibAsset != null) + { + steamLibAsset.SetPlatformData(BuildTarget.StandaloneOSX, "OS", "OSX"); + steamLibAsset.SetPlatformData(BuildTarget.StandaloneOSX, "CPU", "AnyCPU"); + steamLibAsset.SaveAndReimport(); + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/BuildPreProcess.cs.meta b/Assets/Xsolla/Core/Editor/StandaloneBuildPreprocess.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Editor/BuildPreProcess.cs.meta rename to Assets/Xsolla/Core/Editor/StandaloneBuildPreprocess.cs.meta diff --git a/Assets/Xsolla/Core/Editor/iOSBuildPostProcess.cs b/Assets/Xsolla/Core/Editor/iOSBuildPostprocess.cs similarity index 56% rename from Assets/Xsolla/Core/Editor/iOSBuildPostProcess.cs rename to Assets/Xsolla/Core/Editor/iOSBuildPostprocess.cs index 429f69b62..aa0ab3b42 100644 --- a/Assets/Xsolla/Core/Editor/iOSBuildPostProcess.cs +++ b/Assets/Xsolla/Core/Editor/iOSBuildPostprocess.cs @@ -1,71 +1,64 @@ #if UNITY_IOS - -using System; +using System.Collections.Generic; using System.IO; +using UnityEditor; using UnityEditor.Build; using UnityEditor.Build.Reporting; using UnityEditor.iOS.Xcode; namespace Xsolla.Core.Editor { - public class iOSBuildPostProcess : IPostprocessBuildWithReport + public class iOSBuildPostprocess : IPostprocessBuildWithReport { public int callbackOrder => 2000; - + public void OnPostprocessBuild(BuildReport report) { - Debug.Log("Xsolla iOSBuildPostProcess is now postprocessing iOS Project"); + if (report.summary.platform != BuildTarget.iOS) + return; + + XDebug.Log("Xsolla SDK is now processing iOS Project settings", true); SetupXcodeProject(report.summary.outputPath); SetupDeepLinking(report.summary.outputPath); } - private void SetupXcodeProject(string outputPath) + private static void SetupXcodeProject(string outputPath) { var projectPath = PBXProject.GetPBXProjectPath(outputPath); var project = new PBXProject(); project.ReadFromFile(projectPath); -#if UNITY_2019_3_OR_NEWER - var targetGuid = project.GetUnityFrameworkTargetGuid(); -#else - var targetName = PBXProject.GetUnityTargetName(); - var targetGuid = project.TargetGuidByName(targetName); -#endif - - project.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO"); + var targetGuids = new List { + project.ProjectGuid(), + project.GetUnityMainTargetGuid(), + project.GetUnityFrameworkTargetGuid() + }; - try + foreach (var targetGuid in targetGuids) { - var projectInString = File.ReadAllText(projectPath); - projectInString = projectInString.Replace("ENABLE_BITCODE = YES;",$"ENABLE_BITCODE = NO;"); - File.WriteAllText(projectPath, projectInString); - } - catch (Exception e) - { - Debug.LogException(e); + project.SetBuildProperty(targetGuid, "ENABLE_BITCODE", "NO"); } project.WriteToFile(projectPath); } - - private void SetupDeepLinking(string outputPath) + + private static void SetupDeepLinking(string outputPath) { var plistPath = Path.Combine(outputPath, "Info.plist"); var plistDoc = new PlistDocument(); plistDoc.ReadFromString(File.ReadAllText(plistPath)); - + var rootDic = plistDoc.root; var urlTypesArray = rootDic.CreateArray("CFBundleURLTypes"); - + var urlNamesDic = urlTypesArray.AddDict(); urlNamesDic.SetString("CFBundleURLName", ""); - + var urlSchemesArray = urlNamesDic.CreateArray("CFBundleURLSchemes"); urlSchemesArray.AddString("app"); - + File.WriteAllText(plistPath, plistDoc.WriteToString()); } } } - -#endif +#endif \ No newline at end of file diff --git a/Assets/Xsolla/Core/Editor/iOSBuildPostProcess.cs.meta b/Assets/Xsolla/Core/Editor/iOSBuildPostprocess.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Editor/iOSBuildPostProcess.cs.meta rename to Assets/Xsolla/Core/Editor/iOSBuildPostprocess.cs.meta diff --git a/Assets/Xsolla/Core/Entities/BrowserCloseInfo.cs b/Assets/Xsolla/Core/Entities/BrowserCloseInfo.cs new file mode 100644 index 000000000..756242731 --- /dev/null +++ b/Assets/Xsolla/Core/Entities/BrowserCloseInfo.cs @@ -0,0 +1,8 @@ +namespace Xsolla.Core +{ + public class BrowserCloseInfo + { + // Whether the browser is closed manually by a user. + public bool isManually; + } +} diff --git a/Assets/Xsolla/Core/Entities/BrowserCloseInfo.cs.meta b/Assets/Xsolla/Core/Entities/BrowserCloseInfo.cs.meta new file mode 100644 index 000000000..ff435157d --- /dev/null +++ b/Assets/Xsolla/Core/Entities/BrowserCloseInfo.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c185eb2f210443108c41059478e780b6 +timeCreated: 1683251532 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Entities/Constants.cs b/Assets/Xsolla/Core/Entities/Constants.cs deleted file mode 100644 index fdddcf824..000000000 --- a/Assets/Xsolla/Core/Entities/Constants.cs +++ /dev/null @@ -1,24 +0,0 @@ -namespace Xsolla.Core -{ - public static class Constants - { - public const string SdkVersion = "1.5.0"; - - public const string DEFAULT_PROJECT_ID = "77640"; - public const string DEFAULT_LOGIN_ID = "026201e3-7e40-11ea-a85b-42010aa80004"; - public const int DEFAULT_OAUTH_CLIENT_ID = 57; - public const string DEFAULT_REDIRECT_URL = "https://login.xsolla.com/api/blank"; - public const string DEFAULT_WEB_STORE_URL = "https://sitebuilder.xsolla.com/game/sdk-web-store/"; - - public const string LAST_SUCCESS_AUTH_TOKEN = "xsolla_login_last_success_auth_token"; - public const string LAST_SUCCESS_OAUTH_REFRESH_TOKEN = "xsolla_login_last_success_oauth_refresh_token"; - - public const string INVENTORY_TUTORIAL_COMPLETED = "xsolla_inventory_tutorial_completion_flag"; - public const string INVENTORY_TUTORIAL_HIGHLIGHT_TAG = "Highlight"; - - public const string BASE_STORE_API_URL = "https://store.xsolla.com/api/v2/project/{0}"; - - public const string BROWSER_REVISION = "1069273"; - public const string CUSTOM_BROWSER_USER_AGENT = null; - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Enum/DeviceType.cs b/Assets/Xsolla/Core/Entities/DeviceType.cs similarity index 97% rename from Assets/Xsolla/Core/Enum/DeviceType.cs rename to Assets/Xsolla/Core/Entities/DeviceType.cs index dbd7c6db6..daa5b2c37 100644 --- a/Assets/Xsolla/Core/Enum/DeviceType.cs +++ b/Assets/Xsolla/Core/Entities/DeviceType.cs @@ -5,4 +5,4 @@ public enum DeviceType Android, iOS } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Enum/DeviceType.cs.meta b/Assets/Xsolla/Core/Entities/DeviceType.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Enum/DeviceType.cs.meta rename to Assets/Xsolla/Core/Entities/DeviceType.cs.meta diff --git a/Assets/Xsolla/Core/Entities/LinkedSocialNetworks.cs b/Assets/Xsolla/Core/Entities/LinkedSocialNetworks.cs new file mode 100644 index 000000000..85759328f --- /dev/null +++ b/Assets/Xsolla/Core/Entities/LinkedSocialNetworks.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; + +namespace Xsolla.UserAccount +{ + [Serializable] + public class LinkedSocialNetworks + { + public List items; + } + + [Serializable] + public class LinkedSocialNetwork + { + public string full_name; + public string nickname; + public string picture; + public string provider; + public string social_id; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Entities/LinkedSocialNetworks.cs.meta b/Assets/Xsolla/Core/Entities/LinkedSocialNetworks.cs.meta new file mode 100644 index 000000000..921a997da --- /dev/null +++ b/Assets/Xsolla/Core/Entities/LinkedSocialNetworks.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a7e07f4ef91a452b89b7d99195dc931f +timeCreated: 1683770895 \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/MediaListItem.cs b/Assets/Xsolla/Core/Entities/MediaListItem.cs similarity index 98% rename from Assets/Xsolla/Core/EntitiesStore/MediaListItem.cs rename to Assets/Xsolla/Core/Entities/MediaListItem.cs index 9b930611e..f9f5f7c01 100644 --- a/Assets/Xsolla/Core/EntitiesStore/MediaListItem.cs +++ b/Assets/Xsolla/Core/Entities/MediaListItem.cs @@ -8,4 +8,4 @@ public class MediaListItem public string type; public string url; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/MediaListItem.cs.meta b/Assets/Xsolla/Core/Entities/MediaListItem.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/MediaListItem.cs.meta rename to Assets/Xsolla/Core/Entities/MediaListItem.cs.meta diff --git a/Assets/Xsolla/Orders/Entities/OrderContent.cs b/Assets/Xsolla/Core/Entities/OrderContent.cs similarity index 80% rename from Assets/Xsolla/Orders/Entities/OrderContent.cs rename to Assets/Xsolla/Core/Entities/OrderContent.cs index b5dc9a993..4523fd051 100644 --- a/Assets/Xsolla/Orders/Entities/OrderContent.cs +++ b/Assets/Xsolla/Core/Entities/OrderContent.cs @@ -1,7 +1,6 @@ using System; -using Xsolla.Core; -namespace Xsolla.Orders +namespace Xsolla.Core { [Serializable] public class OrderContent diff --git a/Assets/Xsolla/Orders/Entities/OrderContent.cs.meta b/Assets/Xsolla/Core/Entities/OrderContent.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/Entities/OrderContent.cs.meta rename to Assets/Xsolla/Core/Entities/OrderContent.cs.meta diff --git a/Assets/Xsolla/Core/EntitiesStore/PurchaseData.cs b/Assets/Xsolla/Core/Entities/OrderData.cs similarity index 79% rename from Assets/Xsolla/Core/EntitiesStore/PurchaseData.cs rename to Assets/Xsolla/Core/Entities/OrderData.cs index eaa0efd29..1c39e5355 100644 --- a/Assets/Xsolla/Core/EntitiesStore/PurchaseData.cs +++ b/Assets/Xsolla/Core/Entities/OrderData.cs @@ -3,9 +3,9 @@ namespace Xsolla.Core { [Serializable] - public class PurchaseData + public class OrderData { public string token; public int order_id; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/PurchaseData.cs.meta b/Assets/Xsolla/Core/Entities/OrderData.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/PurchaseData.cs.meta rename to Assets/Xsolla/Core/Entities/OrderData.cs.meta diff --git a/Assets/Xsolla/Core/Entities/OrderId.cs b/Assets/Xsolla/Core/Entities/OrderId.cs new file mode 100644 index 000000000..6f7117309 --- /dev/null +++ b/Assets/Xsolla/Core/Entities/OrderId.cs @@ -0,0 +1,10 @@ +using System; + +namespace Xsolla.Core +{ + [Serializable] + public class OrderId + { + public int order_id; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Entities/OrderId.cs.meta b/Assets/Xsolla/Core/Entities/OrderId.cs.meta new file mode 100644 index 000000000..7291153cd --- /dev/null +++ b/Assets/Xsolla/Core/Entities/OrderId.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 8a183897b03d42b98d4fceb43e9403ea +timeCreated: 1682697422 \ No newline at end of file diff --git a/Assets/Xsolla/Orders/Entities/OrderItem.cs b/Assets/Xsolla/Core/Entities/OrderItem.cs similarity index 78% rename from Assets/Xsolla/Orders/Entities/OrderItem.cs rename to Assets/Xsolla/Core/Entities/OrderItem.cs index df2bc0192..c6e684d66 100644 --- a/Assets/Xsolla/Orders/Entities/OrderItem.cs +++ b/Assets/Xsolla/Core/Entities/OrderItem.cs @@ -1,7 +1,6 @@ using System; -using Xsolla.Core; -namespace Xsolla.Orders +namespace Xsolla.Core { [Serializable] public class OrderItem diff --git a/Assets/Xsolla/Orders/Entities/OrderItem.cs.meta b/Assets/Xsolla/Core/Entities/OrderItem.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/Entities/OrderItem.cs.meta rename to Assets/Xsolla/Core/Entities/OrderItem.cs.meta diff --git a/Assets/Xsolla/Orders/Entities/OrderStatus.cs b/Assets/Xsolla/Core/Entities/OrderStatus.cs similarity index 82% rename from Assets/Xsolla/Orders/Entities/OrderStatus.cs rename to Assets/Xsolla/Core/Entities/OrderStatus.cs index c3f9be935..4db45278a 100644 --- a/Assets/Xsolla/Orders/Entities/OrderStatus.cs +++ b/Assets/Xsolla/Core/Entities/OrderStatus.cs @@ -1,14 +1,12 @@ using System; -namespace Xsolla.Orders +namespace Xsolla.Core { [Serializable] public class OrderStatus { public int order_id; - public string status; - public OrderContent content; } } \ No newline at end of file diff --git a/Assets/Xsolla/Orders/Entities/OrderStatus.cs.meta b/Assets/Xsolla/Core/Entities/OrderStatus.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/Entities/OrderStatus.cs.meta rename to Assets/Xsolla/Core/Entities/OrderStatus.cs.meta diff --git a/Assets/Xsolla/Core/Entities/PayStationUI.cs b/Assets/Xsolla/Core/Entities/PayStationUI.cs new file mode 100644 index 000000000..d3a32cebc --- /dev/null +++ b/Assets/Xsolla/Core/Entities/PayStationUI.cs @@ -0,0 +1,13 @@ +using System; + +namespace Xsolla.Core +{ + [Serializable] + public class PayStationUI + { + public string size; + public string theme; + public string version; + public bool is_independent_windows; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/PayStationUI.cs.meta b/Assets/Xsolla/Core/Entities/PayStationUI.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/PayStationUI.cs.meta rename to Assets/Xsolla/Core/Entities/PayStationUI.cs.meta diff --git a/Assets/Xsolla/Core/EntitiesStore/Price.cs b/Assets/Xsolla/Core/Entities/Price.cs similarity index 89% rename from Assets/Xsolla/Core/EntitiesStore/Price.cs rename to Assets/Xsolla/Core/Entities/Price.cs index 34d231147..a1369920f 100644 --- a/Assets/Xsolla/Core/EntitiesStore/Price.cs +++ b/Assets/Xsolla/Core/Entities/Price.cs @@ -19,9 +19,9 @@ public float GetAmount() public float GetAmountWithoutDiscount() { - return string.IsNullOrEmpty(amount_without_discount) + return string.IsNullOrEmpty(amount_without_discount) ? 0F : float.Parse(amount_without_discount, CultureInfo.InvariantCulture); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/Price.cs.meta b/Assets/Xsolla/Core/Entities/Price.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/Price.cs.meta rename to Assets/Xsolla/Core/Entities/Price.cs.meta diff --git a/Assets/Xsolla/Core/EntitiesStore/PurchaseParams.cs b/Assets/Xsolla/Core/Entities/PurchaseParams.cs similarity index 91% rename from Assets/Xsolla/Core/EntitiesStore/PurchaseParams.cs rename to Assets/Xsolla/Core/Entities/PurchaseParams.cs index b5d2e8b71..3cceed437 100644 --- a/Assets/Xsolla/Core/EntitiesStore/PurchaseParams.cs +++ b/Assets/Xsolla/Core/Entities/PurchaseParams.cs @@ -7,8 +7,9 @@ public class PurchaseParams public string currency; public string locale; public int? quantity; + public string external_id; public Dictionary custom_parameters; public ShippingData shipping_data; public Dictionary shipping_method; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/PurchaseParams.cs.meta b/Assets/Xsolla/Core/Entities/PurchaseParams.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/PurchaseParams.cs.meta rename to Assets/Xsolla/Core/Entities/PurchaseParams.cs.meta diff --git a/Assets/Xsolla/Core/Entities/RedirectPolicy.cs b/Assets/Xsolla/Core/Entities/RedirectPolicy.cs index 3d936f959..e5ff183bb 100644 --- a/Assets/Xsolla/Core/Entities/RedirectPolicy.cs +++ b/Assets/Xsolla/Core/Entities/RedirectPolicy.cs @@ -6,13 +6,9 @@ namespace Xsolla.Core public class RedirectPolicy { public string return_url; - public string redirect_conditions; - public int delay; - public string status_for_manual_redirection; - public string redirect_button_caption; } } \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/ShippingData.cs b/Assets/Xsolla/Core/Entities/ShippingData.cs similarity index 99% rename from Assets/Xsolla/Core/EntitiesStore/ShippingData.cs rename to Assets/Xsolla/Core/Entities/ShippingData.cs index f1afe6084..ef86df743 100644 --- a/Assets/Xsolla/Core/EntitiesStore/ShippingData.cs +++ b/Assets/Xsolla/Core/Entities/ShippingData.cs @@ -19,4 +19,4 @@ public class ShippingData public string phone; public string email; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/ShippingData.cs.meta b/Assets/Xsolla/Core/Entities/ShippingData.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/ShippingData.cs.meta rename to Assets/Xsolla/Core/Entities/ShippingData.cs.meta diff --git a/Assets/Xsolla/Core/Entities/SocialProvider.cs b/Assets/Xsolla/Core/Entities/SocialProvider.cs new file mode 100644 index 000000000..8392b813b --- /dev/null +++ b/Assets/Xsolla/Core/Entities/SocialProvider.cs @@ -0,0 +1,43 @@ +namespace Xsolla.Core +{ + /// + /// Social providers list for Login Social Auth. + /// See full list in Login API documentation. + /// + public enum SocialProvider + { + None, + Facebook, + GitHub, + Google, + Twitch, + Twitter, + Steam, + Xbox, + Discord, + Vk, + Naver, + Kakao, + Baidu, + Battlenet, + ChinaTelecom, + Instagram, + LinkedIn, + Odnoklassniki, + PayPal, + Pinterest, + QQ, + Reddit, + Vimeo, + WeChat, + Weibo, + Yahoo, + Amazon, + Mailru, + Microsoft, + Msn, + Yandex, + YouTube, + Apple + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Enum/SocialProvider.cs.meta b/Assets/Xsolla/Core/Entities/SocialProvider.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Enum/SocialProvider.cs.meta rename to Assets/Xsolla/Core/Entities/SocialProvider.cs.meta diff --git a/Assets/Xsolla/Core/EntitiesStore/StoreItem.cs b/Assets/Xsolla/Core/Entities/StoreItem.cs similarity index 64% rename from Assets/Xsolla/Core/EntitiesStore/StoreItem.cs rename to Assets/Xsolla/Core/Entities/StoreItem.cs index f2aa8a689..b62f045bc 100644 --- a/Assets/Xsolla/Core/EntitiesStore/StoreItem.cs +++ b/Assets/Xsolla/Core/Entities/StoreItem.cs @@ -1,29 +1,57 @@ using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; namespace Xsolla.Core { [Serializable] public class StoreItem { - static readonly Dictionary VirtualItemTypes = - new Dictionary() + public string sku; + public string name; + public StoreItemGroup[] groups; + public StoreItemAttribute[] attributes; + public string type; + public string virtual_item_type; + public string description; + public string long_description; + public string image_url; + public bool is_free; + public Price price; + public VirtualPrice[] virtual_prices; + public InventoryOptions inventory_options; + public int order; + public MediaListItem[] media_list; + public StoreItemPromotion[] promotions; + public StoreItemLimits limits; + + public VirtualItemType VirtualItemType + { + get { - {"consumable", VirtualItemType.Consumable}, - {"non_consumable", VirtualItemType.NonConsumable}, - {"non_renewing_subscription", VirtualItemType.NonRenewingSubscription} - }; + if (string.IsNullOrEmpty(virtual_item_type)) + return VirtualItemType.None; + + switch (virtual_item_type) + { + case "consumable": return VirtualItemType.Consumable; + case "non_consumable": return VirtualItemType.NonConsumable; + case "non_renewing_subscription": return VirtualItemType.NonRenewingSubscription; + default: return VirtualItemType.None; + } + } + } [Serializable] public class InventoryOptions { + public ConsumableOption consumable; + public ExpirationPeriod expiration_period; + [Serializable] public class ConsumableOption { public int? usages_count; } + [Serializable] public class ExpirationPeriod { @@ -54,6 +82,7 @@ public TimeSpan ToTimeSpan() dt = dt.AddYears(value); break; } + return dt - DateTime.Now; } @@ -65,54 +94,6 @@ public override string ToString() return result; } } - public ConsumableOption consumable; - public ExpirationPeriod expiration_period; - } - - public string sku; - public string name; - public StoreItemGroup[] groups; - public StoreItemAttribute[] attributes; - public string type; - public string virtual_item_type; - public string description; - public string long_description; - public string image_url; - public bool is_free; - public Price price; - public VirtualPrice[] virtual_prices; - public InventoryOptions inventory_options; - public int order; - public MediaListItem[] media_list; - public StoreItemPromotion[] promotions; - - public StoreItem DeepClone() - { - string json = JsonConvert.SerializeObject(this); - return JsonConvert.DeserializeObject(json); - } - - public bool IsConsumable() - { - return VirtualItemType == VirtualItemType.Consumable; - } - - public bool IsSubscription() - { - return VirtualItemType == VirtualItemType.NonRenewingSubscription; - } - - public VirtualItemType VirtualItemType - { - get - { - if (virtual_item_type != null && VirtualItemTypes.Keys.Contains(virtual_item_type)) - { - return VirtualItemTypes[virtual_item_type]; - } - - return VirtualItemType.None; - } } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/StoreItem.cs.meta b/Assets/Xsolla/Core/Entities/StoreItem.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/StoreItem.cs.meta rename to Assets/Xsolla/Core/Entities/StoreItem.cs.meta diff --git a/Assets/Xsolla/Core/EntitiesStore/StoreItemAttribute.cs b/Assets/Xsolla/Core/Entities/StoreItemAttribute.cs similarity index 97% rename from Assets/Xsolla/Core/EntitiesStore/StoreItemAttribute.cs rename to Assets/Xsolla/Core/Entities/StoreItemAttribute.cs index 0945c2f7f..072c7642c 100644 --- a/Assets/Xsolla/Core/EntitiesStore/StoreItemAttribute.cs +++ b/Assets/Xsolla/Core/Entities/StoreItemAttribute.cs @@ -4,7 +4,7 @@ namespace Xsolla.Core { [Serializable] public class StoreItemAttribute - { + { public string external_id; public string name; public ValuePair[] values; @@ -16,4 +16,4 @@ public class ValuePair public string value; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/StoreItemAttribute.cs.meta b/Assets/Xsolla/Core/Entities/StoreItemAttribute.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/StoreItemAttribute.cs.meta rename to Assets/Xsolla/Core/Entities/StoreItemAttribute.cs.meta diff --git a/Assets/Xsolla/Core/EntitiesStore/StoreItemGroup.cs b/Assets/Xsolla/Core/Entities/StoreItemGroup.cs similarity index 98% rename from Assets/Xsolla/Core/EntitiesStore/StoreItemGroup.cs rename to Assets/Xsolla/Core/Entities/StoreItemGroup.cs index fc5994164..218dcda3a 100644 --- a/Assets/Xsolla/Core/EntitiesStore/StoreItemGroup.cs +++ b/Assets/Xsolla/Core/Entities/StoreItemGroup.cs @@ -8,4 +8,4 @@ public class StoreItemGroup public string external_id; public string name; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/StoreItemGroup.cs.meta b/Assets/Xsolla/Core/Entities/StoreItemGroup.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/StoreItemGroup.cs.meta rename to Assets/Xsolla/Core/Entities/StoreItemGroup.cs.meta diff --git a/Assets/Xsolla/Core/Entities/StoreItemLimits.cs b/Assets/Xsolla/Core/Entities/StoreItemLimits.cs new file mode 100644 index 000000000..ee66fdc41 --- /dev/null +++ b/Assets/Xsolla/Core/Entities/StoreItemLimits.cs @@ -0,0 +1,26 @@ +using System; + +namespace Xsolla.Core +{ + [Serializable] + public class StoreItemLimits + { + public PerUser per_user; + + [Serializable] + public class PerUser + { + public int available; + public int total; + public RecurrentSchedule recurrent_schedule; + + [Serializable] + public class RecurrentSchedule + { + public string interval_type; + public int reset_next_date; + } + + } + } +} \ No newline at end of file diff --git a/Assets/Tests/TestUtils/TestHelper.cs.meta b/Assets/Xsolla/Core/Entities/StoreItemLimits.cs.meta similarity index 83% rename from Assets/Tests/TestUtils/TestHelper.cs.meta rename to Assets/Xsolla/Core/Entities/StoreItemLimits.cs.meta index 6aeeede90..032a12c88 100644 --- a/Assets/Tests/TestUtils/TestHelper.cs.meta +++ b/Assets/Xsolla/Core/Entities/StoreItemLimits.cs.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 95f2c52780c421946ada71590f163e57 +guid: fc3140e6c8ef9054a8e58ed34543daf0 MonoImporter: externalObjects: {} serializedVersion: 2 diff --git a/Assets/Xsolla/Core/EntitiesStore/StoreItemPromotion.cs b/Assets/Xsolla/Core/Entities/StoreItemPromotion.cs similarity index 89% rename from Assets/Xsolla/Core/EntitiesStore/StoreItemPromotion.cs rename to Assets/Xsolla/Core/Entities/StoreItemPromotion.cs index a447c64e5..52767deed 100644 --- a/Assets/Xsolla/Core/EntitiesStore/StoreItemPromotion.cs +++ b/Assets/Xsolla/Core/Entities/StoreItemPromotion.cs @@ -10,7 +10,7 @@ public class StoreItemPromotion public string date_end; public Discount discount; public Bonus[] bonus; - public Limits limits; + public PromotionLimits limits; [Serializable] public class Discount @@ -27,7 +27,7 @@ public class Bonus } [Serializable] - public class Limits + public class PromotionLimits { public PerUser per_user; @@ -39,4 +39,4 @@ public class PerUser } } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/StoreItemPromotion.cs.meta b/Assets/Xsolla/Core/Entities/StoreItemPromotion.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/StoreItemPromotion.cs.meta rename to Assets/Xsolla/Core/Entities/StoreItemPromotion.cs.meta diff --git a/Assets/Xsolla/Core/Entities/Token.cs b/Assets/Xsolla/Core/Entities/Token.cs deleted file mode 100644 index c8ebd1a00..000000000 --- a/Assets/Xsolla/Core/Entities/Token.cs +++ /dev/null @@ -1,198 +0,0 @@ -using System; -using System.Linq; -using System.Text; -using UnityEngine; - -namespace Xsolla.Core -{ - public class Token - { - private static Token _instance; - - public static Token Instance - { - get => _instance; - set - { - _instance = value; - TokenChanged?.Invoke(value); - } - } - - private string EncodedToken { get; set; } - private TokenPayload Payload { get; set; } - private bool IsPaystationToken => Payload == null; - - public static event Action TokenChanged; - - private Token() {} - - public static Token Create(string encodedToken) - { - if (string.IsNullOrEmpty(encodedToken)) - throw new ArgumentNullException(nameof(encodedToken), "Encoded token argument is null or empty"); - - var tokenPartsCount = encodedToken.Split('.').Length; - return tokenPartsCount == 3 - ? CreateJwtToken(encodedToken) - : CreatePaystationToken(encodedToken); - } - - public static bool Save() - { - if (Instance != null) - { - PlayerPrefs.SetString(Constants.LAST_SUCCESS_AUTH_TOKEN, Instance.EncodedToken); - return true; - } - else - return false; - } - - public static bool Load() - { - var encodedToken = PlayerPrefs.GetString(Constants.LAST_SUCCESS_AUTH_TOKEN, null); - if (string.IsNullOrEmpty(encodedToken)) - return false; - - Instance = Create(encodedToken); - return true; - } - - public static void DeleteSave() - { - PlayerPrefs.DeleteKey(Constants.LAST_SUCCESS_AUTH_TOKEN); - } - - public bool IsMasterAccount() - { - if (IsPaystationToken) - return false; - - return Payload.is_master; - } - - public int SecondsLeft() - { - if (IsPaystationToken) - return 0; - - var now = (int)DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1)).TotalSeconds; - return Mathf.Max(Payload.exp - now, 0); - } - - public bool FromSocialNetwork() - { - if (IsPaystationToken) - return false; - - return Payload.type == "social"; - } - - public SocialProvider GetSocialProvider() - { - if (!FromSocialNetwork()) - return SocialProvider.None; - - var provider = Payload.provider; - if (string.IsNullOrEmpty(provider)) - return SocialProvider.None; - - return (SocialProvider)Enum.Parse(typeof(SocialProvider), provider); - } - - public string GetSteamUserID() - { - if (IsPaystationToken) - return string.Empty; - - if (!Payload.is_cross_auth) - return string.Empty; - - var steamUserUrl = Payload.id; - if (string.IsNullOrEmpty(steamUserUrl)) - return string.Empty; - - return steamUserUrl.Split('/').Last(); - } - - private static Token CreateJwtToken(string encodedToken) - { - if (string.IsNullOrEmpty(encodedToken)) - throw new Exception("Encoded token argument is null or empty"); - - var tokenParts = encodedToken.Split('.'); - if (tokenParts.Length < 3) - throw new Exception($"Token must contain header, payload and signature. Your token parts count was '{tokenParts.Length}'. Your token: {encodedToken}"); - - if (!TryParsePayload(tokenParts[1], out var payload)) - throw new Exception($"Could not parse token payload. Your token = {encodedToken}"); - - if (string.IsNullOrEmpty(payload.type)) - throw new Exception($"Token must have 'type' parameter. Your token = {encodedToken}"); - - return new Token - { - EncodedToken = encodedToken, - Payload = payload - }; - } - - private static Token CreatePaystationToken(string encodedToken) - { - return new Token - { - EncodedToken = encodedToken - }; - } - - private static bool TryParsePayload(string encodedPayload, out TokenPayload payloadObject) - { - //Fix FromBase64String convertion - encodedPayload = encodedPayload.Replace('-', '+').Replace('_', '/'); - - var padding = encodedPayload.Length % 4; - if (padding != 0) - { - var paddingToAdd = 4 - padding; - encodedPayload = encodedPayload + new string('=', paddingToAdd); - } - - try - { - var bytes = Convert.FromBase64String(encodedPayload); - var decodedPayload = Encoding.UTF8.GetString(bytes); - payloadObject = ParseUtils.FromJson(decodedPayload); - } - catch (Exception ex) - { - Debug.LogError($"Error decoding token payload: {ex.Message}"); - payloadObject = null; - return false; - } - - return true; - } - - public override string ToString() - { - return EncodedToken; - } - - public static implicit operator string(Token token) - { - return token != null ? token.EncodedToken : string.Empty; - } - - [Serializable] - public class TokenPayload - { - public int exp; - public string id; - public bool is_cross_auth; - public bool is_master; - public string type; - public string provider; - } - } -} diff --git a/Assets/Xsolla/Core/Entities/Token.cs.meta b/Assets/Xsolla/Core/Entities/Token.cs.meta deleted file mode 100644 index ed9ce306c..000000000 --- a/Assets/Xsolla/Core/Entities/Token.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c4efafcf9a61b47b79488dec7ffbd452 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Entities/UserInfo.cs b/Assets/Xsolla/Core/Entities/UserInfo.cs index a1d26eab8..214593149 100644 --- a/Assets/Xsolla/Core/Entities/UserInfo.cs +++ b/Assets/Xsolla/Core/Entities/UserInfo.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using JetBrains.Annotations; namespace Xsolla.Core { @@ -25,13 +24,13 @@ public class UserInfo public UserBan ban; public string country; public string tag; - [CanBeNull] public string connection_information; - [CanBeNull] public bool? is_anonymous; - [CanBeNull] public string phone_auth; + public string connection_information; + public bool? is_anonymous; + public string phone_auth; /// /// User status. Can be 'online' or 'offline'. /// - [CanBeNull] public string presence; + public string presence; [Serializable] public class UserBan @@ -40,6 +39,7 @@ public class UserBan public string date_to; public string reason; } + [Serializable] public class UserGroup { @@ -49,4 +49,4 @@ public class UserGroup public bool? is_deletable; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EnumStore/VirtualItemType.cs b/Assets/Xsolla/Core/Entities/VirtualItemType.cs similarity index 68% rename from Assets/Xsolla/Core/EnumStore/VirtualItemType.cs rename to Assets/Xsolla/Core/Entities/VirtualItemType.cs index 09f0fb763..7dd1222fc 100644 --- a/Assets/Xsolla/Core/EnumStore/VirtualItemType.cs +++ b/Assets/Xsolla/Core/Entities/VirtualItemType.cs @@ -5,6 +5,7 @@ public enum VirtualItemType None, Consumable, NonConsumable, - NonRenewingSubscription + NonRenewingSubscription, + VirtualCurrency } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EnumStore/VirtualItemType.cs.meta b/Assets/Xsolla/Core/Entities/VirtualItemType.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EnumStore/VirtualItemType.cs.meta rename to Assets/Xsolla/Core/Entities/VirtualItemType.cs.meta diff --git a/Assets/Xsolla/Core/EntitiesStore/VirtualPrice.cs b/Assets/Xsolla/Core/Entities/VirtualPrice.cs similarity index 66% rename from Assets/Xsolla/Core/EntitiesStore/VirtualPrice.cs rename to Assets/Xsolla/Core/Entities/VirtualPrice.cs index 0f616e8e4..3923ffe66 100644 --- a/Assets/Xsolla/Core/EntitiesStore/VirtualPrice.cs +++ b/Assets/Xsolla/Core/Entities/VirtualPrice.cs @@ -1,18 +1,10 @@ using System; -using Newtonsoft.Json; namespace Xsolla.Core { [Serializable] public class VirtualPrice { - [Serializable] - private class CalculatedPrice - { - public string amount = default; - public string amount_without_discount = default; - } - public string sku; public string name; public string type; @@ -20,17 +12,17 @@ private class CalculatedPrice public string image_url; public string amount; public string amount_without_discount; - [JsonProperty] private CalculatedPrice calculated_price = default; + public CalculatedPrice calculated_price; public bool is_default; - public uint GetAmount() + public int GetAmount() { - return uint.Parse(amount.ToLowerInvariant()); + return int.Parse(amount.ToLowerInvariant()); } - public uint GetAmountWithoutDiscount() + public int GetAmountWithoutDiscount() { - return uint.Parse(amount_without_discount.ToLowerInvariant()); + return int.Parse(amount_without_discount.ToLowerInvariant()); } public string GetAmountRaw() @@ -42,5 +34,12 @@ public string GetAmountWithoutDiscountRaw() { return calculated_price.amount_without_discount; } + + [Serializable] + public class CalculatedPrice + { + public string amount = default; + public string amount_without_discount = default; + } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/VirtualPrice.cs.meta b/Assets/Xsolla/Core/Entities/VirtualPrice.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/VirtualPrice.cs.meta rename to Assets/Xsolla/Core/Entities/VirtualPrice.cs.meta diff --git a/Assets/Xsolla/Core/EntitiesStore.meta b/Assets/Xsolla/Core/EntitiesStore.meta deleted file mode 100644 index 8bc1251c0..000000000 --- a/Assets/Xsolla/Core/EntitiesStore.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 4cea4165a586d0e4184a133502431737 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/EntitiesStore/PayStationUI.cs b/Assets/Xsolla/Core/EntitiesStore/PayStationUI.cs deleted file mode 100644 index 0f484d0ff..000000000 --- a/Assets/Xsolla/Core/EntitiesStore/PayStationUI.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using Newtonsoft.Json; - -namespace Xsolla.Core -{ - [Serializable] - public class PayStationUI - { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string size; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string theme; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string version; - - public bool is_independent_windows; - } -} diff --git a/Assets/Xsolla/Core/EntitiesStore/TempPurchaseParams.cs b/Assets/Xsolla/Core/EntitiesStore/TempPurchaseParams.cs deleted file mode 100644 index 9c53ee151..000000000 --- a/Assets/Xsolla/Core/EntitiesStore/TempPurchaseParams.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System; -using System.Collections.Generic; -using Newtonsoft.Json; - -namespace Xsolla.Core -{ - [Serializable] - public class TempPurchaseParams - { - public bool sandbox; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public Settings settings; - - [JsonProperty("custom_parameters", NullValueHandling = NullValueHandling.Ignore)] - public Dictionary custom_parameters; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string currency; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string locale; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public int? quantity; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public ShippingData shipping_data; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public Dictionary shipping_method; - - [Serializable] - public class Settings - { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public string return_url; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public PayStationUI ui; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] - public RedirectPolicy redirect_policy; - } - } -} diff --git a/Assets/Xsolla/Core/Enum.meta b/Assets/Xsolla/Core/Enum.meta deleted file mode 100644 index c717a4f1d..000000000 --- a/Assets/Xsolla/Core/Enum.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d72dbf03cac2bd14b87021dc4e532140 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Enum/ParseParameter.cs b/Assets/Xsolla/Core/Enum/ParseParameter.cs deleted file mode 100644 index ee75d82d0..000000000 --- a/Assets/Xsolla/Core/Enum/ParseParameter.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Xsolla.Core -{ - public enum ParseParameter - { - token, code, status, challenge_id, error_code, error_description - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Enum/SocialProvider.cs b/Assets/Xsolla/Core/Enum/SocialProvider.cs deleted file mode 100644 index 37d169242..000000000 --- a/Assets/Xsolla/Core/Enum/SocialProvider.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; - -namespace Xsolla.Core -{ - /// - /// Social providers list for Login Social Auth. - /// See full list at . - /// - public enum SocialProvider - { - None, - Facebook, - GitHub, - Google, - Twitch, - Twitter, - Steam, - Xbox, - Discord, - Vk, - Naver, - Kakao, - Baidu, - Battlenet, - ChinaTelecom, - Instagram, - LinkedIn, - Odnoklassniki, - PayPal, - Pinterest, - QQ, - Reddit, - Vimeo, - WeChat, - Weibo, - Yahoo, - Amazon, - Mailru, - Microsoft, - Msn, - Yandex, - YouTube, - Apple - } - - public static class SocialProviderConverter - { - public static string GetParameter(this SocialProvider provider) - { - switch (provider) - { - case SocialProvider.Facebook: return "facebook"; - case SocialProvider.GitHub: return "github"; - case SocialProvider.Google: return "google"; - case SocialProvider.Twitch: return "twitch"; - case SocialProvider.Twitter: return "twitter"; - case SocialProvider.Steam: return "steam"; - case SocialProvider.Xbox: return "xbox"; - case SocialProvider.Discord: return "discord"; - case SocialProvider.Vk: return "vk"; - case SocialProvider.Naver: return "naver"; - case SocialProvider.Kakao: return "kakao"; - case SocialProvider.Baidu: return "baidu"; - case SocialProvider.Battlenet: return "battlenet"; - case SocialProvider.ChinaTelecom: return "chinatelecom"; - case SocialProvider.Instagram: return "instagram"; - case SocialProvider.LinkedIn: return "linkedin"; - case SocialProvider.Odnoklassniki: return "ok"; - case SocialProvider.PayPal: return "paypal"; - case SocialProvider.Pinterest: return "pinterest"; - case SocialProvider.QQ: return "qq"; - case SocialProvider.Reddit: return "reddit"; - case SocialProvider.Vimeo: return "vimeo"; - case SocialProvider.WeChat: return "wechat"; - case SocialProvider.Weibo: return "weibo"; - case SocialProvider.Yahoo: return "yahoo"; - case SocialProvider.Amazon: return "amazon"; - case SocialProvider.Mailru: return "mailru"; - case SocialProvider.Microsoft: return "microsoft"; - case SocialProvider.Msn: return "msn"; - case SocialProvider.Yandex: return "yandex"; - case SocialProvider.YouTube: return "youtube"; - case SocialProvider.Apple: return "apple"; - default: throw new Exception(provider.ToString()); - } - } - } - - [Serializable] - public class LinkedSocialNetwork - { - public string full_name; - public string nickname; - public string picture; - public string provider; - public string social_id; - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EnumStore.meta b/Assets/Xsolla/Core/EnumStore.meta deleted file mode 100644 index fca8208b3..000000000 --- a/Assets/Xsolla/Core/EnumStore.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 8dea87de51ce2c24aa9c2e38d9ac6daa -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Errors/CodeToErrorType.cs b/Assets/Xsolla/Core/Errors/CodeToErrorType.cs deleted file mode 100644 index cba8c4ede..000000000 --- a/Assets/Xsolla/Core/Errors/CodeToErrorType.cs +++ /dev/null @@ -1,129 +0,0 @@ -namespace Xsolla.Core -{ - public static class CodeToErrorType - { - public static bool TryGetSpecificType(string code, ErrorCheckType checkType, out ErrorType errorType) - { - if (checkType == ErrorCheckType.CommonErrors) - return TryGetCommonType(code, out errorType); - - errorType = ErrorType.Undefined; - - switch (checkType) - { - case ErrorCheckType.TokenErrors: - if (string.Equals(code,"422")) - errorType = ErrorType.TokenVerificationException; - break; - - case ErrorCheckType.LoginErrors: - switch (code) - { - case "003-007": { errorType = ErrorType.UserIsNotActivated; }; break; - case "010-007": { errorType = ErrorType.CaptchaRequiredException; }; break; - case "003-039": { errorType = ErrorType.InvalidAuthorizationCode; }; break; - case "003-049": { errorType = ErrorType.ExceededAuthorizationCodeAttempts; }; break; - } - break; - - case ErrorCheckType.RegistrationErrors: - switch (code) - { - case "010-003": { errorType = ErrorType.RegistrationNotAllowedException; }; break; - case "003-003": { errorType = ErrorType.UsernameIsTaken; }; break; - case "003-004": { errorType = ErrorType.EmailIsTaken; }; break; - } - break; - - case ErrorCheckType.ResetPasswordErrors: - switch (code) - { - case "003-007": { errorType = ErrorType.PasswordResetingNotAllowedForProject; }; break; - case "003-024": { errorType = ErrorType.PasswordResetingNotAllowedForProject; }; break; - } - break; - - case ErrorCheckType.ItemsListErrors: - case ErrorCheckType.ConsumeItemErrors: - switch (code) - { - case "401": { errorType = ErrorType.InvalidToken; }; break; - case "422": { errorType = ErrorType.InvalidData; }; break; - } - break; - - case ErrorCheckType.BuyItemErrors: - if (string.Equals(code,"422")) - errorType = ErrorType.ProductDoesNotExist; - break; - - case ErrorCheckType.CreateCartErrors: - switch (code) - { - case "401": - case "403": { errorType = ErrorType.InvalidToken; }; break; - case "404": { errorType = ErrorType.UserNotFound; }; break; - case "422": { errorType = ErrorType.InvalidData; }; break; - } - break; - - case ErrorCheckType.AddToCartCartErrors: - case ErrorCheckType.GetCartItemsErrors: - case ErrorCheckType.DeleteFromCartErrors: - switch (code) - { - case "401": - case "403": { errorType = ErrorType.InvalidToken; }; break; - case "404": { errorType = ErrorType.CartNotFound; }; break; - case "422": { errorType = ErrorType.InvalidData; }; break; - } - break; - - case ErrorCheckType.BuyCartErrors: - if (string.Equals(code,"422")) - errorType = ErrorType.CartNotFound; - break; - - case ErrorCheckType.OrderStatusErrors: - switch (code) - { - case "401": { errorType = ErrorType.InvalidToken; }; break; - case "404": { errorType = ErrorType.OrderNotFound; }; break; - } - break; - - case ErrorCheckType.CouponErrors: - switch (code) - { - case "401": { errorType = ErrorType.InvalidToken; }; break; - case "403": { errorType = ErrorType.AuthorizationHeaderNotSent; }; break; - case "404": { errorType = ErrorType.InvalidCoupon; }; break; - case "422": { errorType = ErrorType.InvalidData; }; break; - } - break; - } - - return errorType != ErrorType.Undefined; - } - - public static bool TryGetCommonType(string code, out ErrorType errorType) - { - errorType = ErrorType.Undefined; - - switch (code) - { - case "403": - case "010-023": - case "010-017": { errorType = ErrorType.InvalidToken; }; break; - case "405": { errorType = ErrorType.MethodIsNotAllowed; }; break; - case "0": - case "003-061": { errorType = ErrorType.InvalidProjectSettings; }; break; - case "003-001": { errorType = ErrorType.InvalidLoginOrPassword; }; break; - case "010-011": { errorType = ErrorType.MultipleLoginUrlsException; }; break; - case "010-012": { errorType = ErrorType.SubmittedLoginUrlNotFoundException; }; break; - } - - return errorType != ErrorType.Undefined; - } - } -} diff --git a/Assets/Xsolla/Core/Errors/Error.cs b/Assets/Xsolla/Core/Errors/Error.cs index b7f3bb328..36972c0a7 100644 --- a/Assets/Xsolla/Core/Errors/Error.cs +++ b/Assets/Xsolla/Core/Errors/Error.cs @@ -10,46 +10,32 @@ public class Error public string errorCode; public string errorMessage; - public ErrorType ErrorType { get; set; } = ErrorType.UnknownError; + public ErrorType ErrorType { get; set; } public Error(ErrorType errorType = ErrorType.UnknownError, string statusCode = "", string errorCode = "", string errorMessage = "") { + ErrorType = errorType; this.statusCode = statusCode; this.errorCode = errorCode; this.errorMessage = errorMessage; - ErrorType = errorType; } - public static Error NetworkError - { - get { return new Error(ErrorType.NetworkError); } - } - - public static Error UnknownError - { - get { return new Error(ErrorType.UnknownError); } - } + public static Error UnknownError => new Error(); - public bool IsValid() - { - return (statusCode != null) || - (errorCode != null) || - (errorMessage != null) || - (ErrorType != ErrorType.Undefined); - } - public override string ToString() { var builder = new StringBuilder($"Error: {ErrorType}."); if (!string.IsNullOrEmpty(statusCode)) builder.Append($" Status code: {statusCode}."); + if (!string.IsNullOrEmpty(errorCode)) builder.Append($" Error code: {errorCode}."); + if (!string.IsNullOrEmpty(errorMessage)) - builder.Append($" {errorMessage}."); + builder.Append($" Message: {errorMessage}."); return builder.ToString(); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Errors/ErrorCheckType.cs b/Assets/Xsolla/Core/Errors/ErrorGroup.cs similarity index 66% rename from Assets/Xsolla/Core/Errors/ErrorCheckType.cs rename to Assets/Xsolla/Core/Errors/ErrorGroup.cs index 5b166878f..1d0eb3636 100644 --- a/Assets/Xsolla/Core/Errors/ErrorCheckType.cs +++ b/Assets/Xsolla/Core/Errors/ErrorGroup.cs @@ -1,6 +1,6 @@ namespace Xsolla.Core { - public enum ErrorCheckType + public enum ErrorGroup { CommonErrors, @@ -13,13 +13,10 @@ public enum ErrorCheckType ConsumeItemErrors, BuyItemErrors, - CreateCartErrors, - AddToCartCartErrors, - GetCartItemsErrors, - DeleteFromCartErrors, + CartErrors, BuyCartErrors, OrderStatusErrors, CouponErrors } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Errors/ErrorCheckType.cs.meta b/Assets/Xsolla/Core/Errors/ErrorGroup.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Errors/ErrorCheckType.cs.meta rename to Assets/Xsolla/Core/Errors/ErrorGroup.cs.meta diff --git a/Assets/Xsolla/Core/Errors/ErrorType.cs b/Assets/Xsolla/Core/Errors/ErrorType.cs index 4db0b55fb..4c39b3a5c 100644 --- a/Assets/Xsolla/Core/Errors/ErrorType.cs +++ b/Assets/Xsolla/Core/Errors/ErrorType.cs @@ -11,16 +11,19 @@ public enum ErrorType AuthorizationHeaderNotSent, MethodIsNotAllowed, + NotSupportedOnCurrentPlatform, + InvalidData, ProductDoesNotExist, + PayStationServiceException, UserNotFound, CartNotFound, OrderNotFound, InvalidCoupon, - PasswordResetingNotAllowedForProject, - TokenVerificationException, + PasswordResetNotAllowedForProject, RegistrationNotAllowedException, + TokenVerificationException, UsernameIsTaken, EmailIsTaken, UserIsNotActivated, diff --git a/Assets/Xsolla/Core/Errors/Internal.meta b/Assets/Xsolla/Core/Errors/Internal.meta new file mode 100644 index 000000000..1265318e6 --- /dev/null +++ b/Assets/Xsolla/Core/Errors/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c59c9a81af9540818cf78a08fbeaa00b +timeCreated: 1683524364 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Errors/Internal/ErrorTypeParser.cs b/Assets/Xsolla/Core/Errors/Internal/ErrorTypeParser.cs new file mode 100644 index 000000000..6ced88b50 --- /dev/null +++ b/Assets/Xsolla/Core/Errors/Internal/ErrorTypeParser.cs @@ -0,0 +1,191 @@ +using System; + +namespace Xsolla.Core +{ + internal static class ErrorTypeParser + { + public static bool TryGetSpecificType(string code, ErrorGroup errorGroup, out ErrorType errorType) + { + if (errorGroup == ErrorGroup.CommonErrors) + return TryGetCommonType(code, out errorType); + + errorType = ErrorType.Undefined; + + var typeParser = GetErrorTypeParser(errorGroup); + if (typeParser != null) + errorType = typeParser(code); + + return errorType != ErrorType.Undefined; + } + + public static bool TryGetCommonType(string code, out ErrorType errorType) + { + errorType = CommonErrors(code); + return errorType != ErrorType.Undefined; + } + + private static Func GetErrorTypeParser(ErrorGroup errorGroup) + { + switch (errorGroup) + { + case ErrorGroup.TokenErrors: return TokenErrors; + case ErrorGroup.LoginErrors: return LoginErrors; + case ErrorGroup.RegistrationErrors: return RegistrationErrors; + case ErrorGroup.ResetPasswordErrors: return ResetPasswordErrors; + case ErrorGroup.ItemsListErrors: return ItemsListErrors; + case ErrorGroup.ConsumeItemErrors: return ConsumeItemErrors; + case ErrorGroup.BuyItemErrors: return BuyItemErrors; + case ErrorGroup.CartErrors: return CartErrors; + case ErrorGroup.BuyCartErrors: return BuyCartErrors; + case ErrorGroup.OrderStatusErrors: return OrderStatusErrors; + case ErrorGroup.CouponErrors: return CouponErrors; + } + + return null; + } + + private static ErrorType TokenErrors(string code) + { + switch (code) + { + case "422": return ErrorType.TokenVerificationException; + } + + return ErrorType.Undefined; + } + + private static ErrorType LoginErrors(string code) + { + switch (code) + { + case "003-007": return ErrorType.UserIsNotActivated; + case "010-007": return ErrorType.CaptchaRequiredException; + case "003-039": return ErrorType.InvalidAuthorizationCode; + case "003-049": return ErrorType.ExceededAuthorizationCodeAttempts; + } + + return ErrorType.Undefined; + } + + private static ErrorType RegistrationErrors(string code) + { + switch (code) + { + case "010-003": return ErrorType.RegistrationNotAllowedException; + case "003-003": return ErrorType.UsernameIsTaken; + case "003-004": return ErrorType.EmailIsTaken; + } + + return ErrorType.Undefined; + } + + private static ErrorType ResetPasswordErrors(string code) + { + switch (code) + { + case "003-007": + case "003-024": return ErrorType.PasswordResetNotAllowedForProject; + } + + return ErrorType.Undefined; + } + + private static ErrorType ItemsListErrors(string code) + { + switch (code) + { + case "401": return ErrorType.InvalidToken; + case "422": return ErrorType.InvalidData; + } + + return ErrorType.Undefined; + } + + private static ErrorType ConsumeItemErrors(string code) + { + switch (code) + { + case "401": return ErrorType.InvalidToken; + case "422": return ErrorType.InvalidData; + } + + return ErrorType.Undefined; + } + + private static ErrorType BuyItemErrors(string code) + { + switch (code) + { + case "404": return ErrorType.ProductDoesNotExist; + case "422": return ErrorType.PayStationServiceException; + } + + return ErrorType.Undefined; + } + + private static ErrorType CartErrors(string code) + { + switch (code) + { + case "401": + case "403": return ErrorType.InvalidToken; + case "404": return ErrorType.UserNotFound; + case "422": return ErrorType.InvalidData; + } + + return ErrorType.Undefined; + } + + private static ErrorType BuyCartErrors(string code) + { + switch (code) + { + case "422": return ErrorType.CartNotFound; + } + + return ErrorType.Undefined; + } + + private static ErrorType OrderStatusErrors(string code) + { + switch (code) + { + case "401": return ErrorType.InvalidToken; + case "404": return ErrorType.OrderNotFound; + } + + return ErrorType.Undefined; + } + + private static ErrorType CouponErrors(string code) + { + switch (code) + { + case "401": return ErrorType.InvalidToken; + case "403": return ErrorType.AuthorizationHeaderNotSent; + case "404": return ErrorType.InvalidCoupon; + case "422": return ErrorType.InvalidData; + } + + return ErrorType.Undefined; + } + + private static ErrorType CommonErrors(string code) + { + switch (code) + { + case "403": return ErrorType.InvalidToken; + case "010-023": return ErrorType.InvalidToken; + case "010-017": return ErrorType.InvalidToken; + case "405": return ErrorType.MethodIsNotAllowed; + case "0": return ErrorType.InvalidProjectSettings; + case "003-061": return ErrorType.InvalidProjectSettings; + case "003-001": return ErrorType.InvalidLoginOrPassword; + case "010-011": return ErrorType.MultipleLoginUrlsException; + case "010-012": return ErrorType.SubmittedLoginUrlNotFoundException; + } + + return ErrorType.Undefined; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Errors/CodeToErrorType.cs.meta b/Assets/Xsolla/Core/Errors/Internal/ErrorTypeParser.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Errors/CodeToErrorType.cs.meta rename to Assets/Xsolla/Core/Errors/Internal/ErrorTypeParser.cs.meta diff --git a/Assets/Xsolla/Core/Errors/LoginError.cs b/Assets/Xsolla/Core/Errors/Internal/LoginError.cs similarity index 57% rename from Assets/Xsolla/Core/Errors/LoginError.cs rename to Assets/Xsolla/Core/Errors/Internal/LoginError.cs index 1883c0b2c..dddb890ab 100644 --- a/Assets/Xsolla/Core/Errors/LoginError.cs +++ b/Assets/Xsolla/Core/Errors/Internal/LoginError.cs @@ -3,23 +3,27 @@ namespace Xsolla.Core { [Serializable] - public class LoginError + internal class LoginError { - [Serializable] - public class Data - { - public string code; - public string description; - } - public Data error; public Error ToError() { - if (this.error == null) + if (error == null) return null; - else - return new Error() { statusCode = error.code, errorCode = error.code, errorMessage = error.description }; + + return new Error { + statusCode = error.code, + errorCode = error.code, + errorMessage = error.description + }; + } + + [Serializable] + public class Data + { + public string code; + public string description; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Errors/LoginError.cs.meta b/Assets/Xsolla/Core/Errors/Internal/LoginError.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Errors/LoginError.cs.meta rename to Assets/Xsolla/Core/Errors/Internal/LoginError.cs.meta diff --git a/Assets/Xsolla/Core/ImageLoader.meta b/Assets/Xsolla/Core/ImageLoader.meta deleted file mode 100644 index d754aa05d..000000000 --- a/Assets/Xsolla/Core/ImageLoader.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e72fe4c918c1e49b69ab1b8c745fe583 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/ImageLoader/ImageLoader.cs b/Assets/Xsolla/Core/ImageLoader/ImageLoader.cs deleted file mode 100644 index fb3d342b0..000000000 --- a/Assets/Xsolla/Core/ImageLoader/ImageLoader.cs +++ /dev/null @@ -1,60 +0,0 @@ -using UnityEngine; -using System.Collections; -using System.Collections.Generic; -using System; - -namespace Xsolla.Core -{ - public class ImageLoader : MonoSingleton - { - private Dictionary images; - - public override void Init() - { - base.Init(); - images = new Dictionary(); - } - - protected override void OnDestroy() - { - StopAllCoroutines(); - images?.Clear(); - } - - public void AddImage(string url, Sprite image) - { - images[url] = image; - } - - public void GetImageAsync(string url, Action callback) - { - if (images.ContainsKey(url) && images[url] != null) - { - callback?.Invoke(url, images[url]); - } - else if (images.ContainsKey(url)/*&& images[url] == null*/) - { - StartCoroutine(WaitImage(url, callback)); - } - else/*if (!images.ContainsKey(url))*/ - { - images[url] = null; - LoadImage(url); - StartCoroutine(WaitImage(url, callback)); - } - } - - private void LoadImage(string url) - { - WebRequestHelper.Instance.ImageRequest(url, - onComplete: sprite => images[url] = sprite, - onError: error => Debug.LogError(error.errorMessage)); - } - - IEnumerator WaitImage(string url, Action callback) - { - yield return new WaitWhile(() => images[url] == null); - callback?.Invoke(url, images[url]); - } - } -} diff --git a/Assets/Xsolla/Core/InputProxy/InputProxy.LegacySystem.cs b/Assets/Xsolla/Core/InputProxy/InputProxy.LegacySystem.cs index 01cc5f89c..b19ab2d74 100644 --- a/Assets/Xsolla/Core/InputProxy/InputProxy.LegacySystem.cs +++ b/Assets/Xsolla/Core/InputProxy/InputProxy.LegacySystem.cs @@ -15,10 +15,7 @@ public static bool GetKeyUp(KeyCode code) return Input.GetKeyUp(code); } - public static Vector3 MousePosition - { - get => Input.mousePosition; - } + public static Vector3 MousePosition => Input.mousePosition; } } diff --git a/Assets/Xsolla/Core/Internal.meta b/Assets/Xsolla/Core/Internal.meta new file mode 100644 index 000000000..5075d88fb --- /dev/null +++ b/Assets/Xsolla/Core/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 613e500b8a224f2f976ce545609deb20 +timeCreated: 1683093362 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Internal/Constants.cs b/Assets/Xsolla/Core/Internal/Constants.cs new file mode 100644 index 000000000..600b61faa --- /dev/null +++ b/Assets/Xsolla/Core/Internal/Constants.cs @@ -0,0 +1,24 @@ +namespace Xsolla.Core +{ + public static class Constants + { + public const string SDK_VERSION = "2.0.0"; + + public const string DEFAULT_PROJECT_ID = "77640"; + public const string DEFAULT_LOGIN_ID = "026201e3-7e40-11ea-a85b-42010aa80004"; + public const int DEFAULT_OAUTH_CLIENT_ID = 57; + public const string DEFAULT_REDIRECT_URL = "https://login.xsolla.com/api/blank"; + public const string DEFAULT_WEB_STORE_URL = "https://sitebuilder.xsolla.com/game/sdk-web-store/"; + + public const string PAYSTATION_URL = "https://secure.xsolla.com/paystation3/"; + public const string PAYSTATION_SANDBOX_URL = "https://sandbox-secure.xsolla.com/paystation3/"; + + public const string WEB_BROWSER_RESOURCE_PATH = "XsollaWebBrowser"; + public const string BROWSER_REVISION = "1069273"; + public const string CUSTOM_BROWSER_USER_AGENT = null; + + public const float WEB_SOCKETS_TIMEOUT = 300f; + public const float SHORT_POLLING_INTERVAL = 3f; + public const float SHORT_POLLING_LIMIT = 600f; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Entities/Constants.cs.meta b/Assets/Xsolla/Core/Internal/Constants.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Entities/Constants.cs.meta rename to Assets/Xsolla/Core/Internal/Constants.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/LogLevel.cs b/Assets/Xsolla/Core/Internal/LogLevel.cs similarity index 98% rename from Assets/Xsolla/Core/XsollaSettings/LogLevel.cs rename to Assets/Xsolla/Core/Internal/LogLevel.cs index 1f0762f56..c4c3dca14 100644 --- a/Assets/Xsolla/Core/XsollaSettings/LogLevel.cs +++ b/Assets/Xsolla/Core/Internal/LogLevel.cs @@ -6,4 +6,4 @@ public enum LogLevel WarningsErrors = 1, Errors = 2 } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/XsollaSettings/LogLevel.cs.meta b/Assets/Xsolla/Core/Internal/LogLevel.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/LogLevel.cs.meta rename to Assets/Xsolla/Core/Internal/LogLevel.cs.meta diff --git a/Assets/Xsolla/Core/Internal/ParseParameter.cs b/Assets/Xsolla/Core/Internal/ParseParameter.cs new file mode 100644 index 000000000..8a22dc98a --- /dev/null +++ b/Assets/Xsolla/Core/Internal/ParseParameter.cs @@ -0,0 +1,11 @@ +namespace Xsolla.Core +{ + public enum ParseParameter + { + token, + code, + challenge_id, + error_code, + error_description + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Enum/ParseParameter.cs.meta b/Assets/Xsolla/Core/Internal/ParseParameter.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Enum/ParseParameter.cs.meta rename to Assets/Xsolla/Core/Internal/ParseParameter.cs.meta diff --git a/Assets/Xsolla/Core/Internal/PurchaseParamsRequest.cs b/Assets/Xsolla/Core/Internal/PurchaseParamsRequest.cs new file mode 100644 index 000000000..43cc3fd2f --- /dev/null +++ b/Assets/Xsolla/Core/Internal/PurchaseParamsRequest.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; + +namespace Xsolla.Core +{ + [Serializable] + internal class PurchaseParamsRequest + { + public bool sandbox; + public Settings settings; + public Dictionary custom_parameters; + public string currency; + public string locale; + public int? quantity; + public ShippingData shipping_data; + public Dictionary shipping_method; + + [Serializable] + public class Settings + { + public string external_id; + public string return_url; + public PayStationUI ui; + public RedirectPolicy redirect_policy; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/EntitiesStore/TempPurchaseParams.cs.meta b/Assets/Xsolla/Core/Internal/PurchaseParamsRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Core/EntitiesStore/TempPurchaseParams.cs.meta rename to Assets/Xsolla/Core/Internal/PurchaseParamsRequest.cs.meta diff --git a/Assets/Xsolla/Auth/Entities/LoginOAuthJsonResponse.cs b/Assets/Xsolla/Core/Internal/TokenResponse.cs similarity index 74% rename from Assets/Xsolla/Auth/Entities/LoginOAuthJsonResponse.cs rename to Assets/Xsolla/Core/Internal/TokenResponse.cs index 49d93c7f5..bd9dc44af 100644 --- a/Assets/Xsolla/Auth/Entities/LoginOAuthJsonResponse.cs +++ b/Assets/Xsolla/Core/Internal/TokenResponse.cs @@ -1,9 +1,9 @@ using System; -namespace Xsolla.Auth +namespace Xsolla.Core { [Serializable] - public class LoginOAuthJsonResponse + internal class TokenResponse { public string access_token; public string token_type; @@ -11,4 +11,4 @@ public class LoginOAuthJsonResponse public string refresh_token; public string scope; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Auth/Entities/LoginOAuthJsonResponse.cs.meta b/Assets/Xsolla/Core/Internal/TokenResponse.cs.meta similarity index 100% rename from Assets/Xsolla/Auth/Entities/LoginOAuthJsonResponse.cs.meta rename to Assets/Xsolla/Core/Internal/TokenResponse.cs.meta diff --git a/Assets/Xsolla/Core/Internal/XDebug.cs b/Assets/Xsolla/Core/Internal/XDebug.cs new file mode 100644 index 000000000..fb331c0d2 --- /dev/null +++ b/Assets/Xsolla/Core/Internal/XDebug.cs @@ -0,0 +1,26 @@ +using UnityEngine; + +namespace Xsolla.Core +{ + public static class XDebug + { + private const string LOG_PREFIX = "[Xsolla SDK]"; + + public static void Log(object message, bool ignoreLogLevel = false) + { + if (XsollaSettings.LogLevel == LogLevel.InfoWarningsErrors || ignoreLogLevel) + Debug.Log($"{LOG_PREFIX} {message}"); + } + + public static void LogWarning(object message, bool ignoreLogLevel = false) + { + if (XsollaSettings.LogLevel <= LogLevel.WarningsErrors || ignoreLogLevel) + Debug.LogWarning($"{LOG_PREFIX} {message}"); + } + + public static void LogError(object message) + { + Debug.LogError($"{LOG_PREFIX} {message}"); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/Debug.cs.meta b/Assets/Xsolla/Core/Internal/XDebug.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Utils/Debug.cs.meta rename to Assets/Xsolla/Core/Internal/XDebug.cs.meta diff --git a/Assets/Xsolla/Core/Marker/XsollaMarker.cs b/Assets/Xsolla/Core/Internal/XsollaMarker.cs similarity index 87% rename from Assets/Xsolla/Core/Marker/XsollaMarker.cs rename to Assets/Xsolla/Core/Internal/XsollaMarker.cs index b4fcb3f4b..1eacb4de8 100644 --- a/Assets/Xsolla/Core/Marker/XsollaMarker.cs +++ b/Assets/Xsolla/Core/Internal/XsollaMarker.cs @@ -1,10 +1,11 @@ namespace Xsolla.Core { - public interface IXsollaMarkerHasDemoPart {} + public interface IXsollaMarkerHasDemoPart { } public partial class XsollaMarker { private static XsollaMarker _instance; + private static XsollaMarker Marker { get diff --git a/Assets/Xsolla/Core/Marker/XsollaMarker.cs.meta b/Assets/Xsolla/Core/Internal/XsollaMarker.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Marker/XsollaMarker.cs.meta rename to Assets/Xsolla/Core/Internal/XsollaMarker.cs.meta diff --git a/Assets/Xsolla/Core/Marker.meta b/Assets/Xsolla/Core/Marker.meta deleted file mode 100644 index f9da385c7..000000000 --- a/Assets/Xsolla/Core/Marker.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 14ac2312c03474b4a923ed9ac818aa03 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/OrderStatus.meta b/Assets/Xsolla/Core/OrderStatus.meta new file mode 100644 index 000000000..f33036032 --- /dev/null +++ b/Assets/Xsolla/Core/OrderStatus.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 150cade2c86e4f9e9aecc42722df9270 +timeCreated: 1683730003 \ No newline at end of file diff --git a/Assets/Xsolla/Core/OrderStatus/OrderStatusCache.cs b/Assets/Xsolla/Core/OrderStatus/OrderStatusCache.cs new file mode 100644 index 000000000..fcd5c2fc4 --- /dev/null +++ b/Assets/Xsolla/Core/OrderStatus/OrderStatusCache.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace Xsolla.Core +{ + internal static class OrderStatusCache + { + private static readonly Dictionary Items = new Dictionary(); + + public static bool TryPerform(int orderId, Action callback) + { + if (orderId <= 0) + throw new ArgumentException("Order id must be positive number", nameof(orderId)); + + var status = GetCompleted(orderId); + if (status == null) + return false; + + CoroutinesExecutor.Run(PerformSuccess(status, callback)); + return true; + } + + public static void UpdateStatus(OrderStatus orderStatus) + { + if (orderStatus == null) + throw new ArgumentNullException(nameof(orderStatus)); + + if (orderStatus.order_id <= 0) + throw new ArgumentException("Order id must be positive number", nameof(orderStatus.order_id)); + + Items[orderStatus.order_id] = orderStatus; + } + + private static OrderStatus GetCompleted(int orderId) + { + if (!Items.TryGetValue(orderId, out var orderStatus)) + return null; + + return orderStatus.status == "done" + ? orderStatus + : null; + } + + private static IEnumerator PerformSuccess(OrderStatus status, Action callback) + { + yield return new WaitForSeconds(0.1f); + callback?.Invoke(status); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/OrderStatus/OrderStatusCache.cs.meta b/Assets/Xsolla/Core/OrderStatus/OrderStatusCache.cs.meta new file mode 100644 index 000000000..f20afa7b4 --- /dev/null +++ b/Assets/Xsolla/Core/OrderStatus/OrderStatusCache.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 4031259af1b24a669f6e251bea56abe4 +timeCreated: 1683729864 \ No newline at end of file diff --git a/Assets/Xsolla/Core/OrderStatus/OrderStatusService.cs b/Assets/Xsolla/Core/OrderStatus/OrderStatusService.cs new file mode 100644 index 000000000..caa05f07b --- /dev/null +++ b/Assets/Xsolla/Core/OrderStatus/OrderStatusService.cs @@ -0,0 +1,35 @@ +using System; + +namespace Xsolla.Core +{ + internal static class OrderStatusService + { + public static void GetOrderStatus(int orderId, Action onSuccess, Action onError) + { + if (OrderStatusCache.TryPerform(orderId, onSuccess)) + return; + + PerformWebRequest( + orderId, + status => + { + OrderStatusCache.UpdateStatus(status); + onSuccess?.Invoke(status); + }, + onError); + } + + private static void PerformWebRequest(int orderId, Action onSuccess, Action onError) + { + var url = $"https://store.xsolla.com/api/v2/project/{XsollaSettings.StoreProjectId}/order/{orderId}"; + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => PerformWebRequest(orderId, onSuccess, onError)), + ErrorGroup.OrderStatusErrors); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/OrderStatus/OrderStatusService.cs.meta b/Assets/Xsolla/Core/OrderStatus/OrderStatusService.cs.meta new file mode 100644 index 000000000..24ad83e7b --- /dev/null +++ b/Assets/Xsolla/Core/OrderStatus/OrderStatusService.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c8b9c050ba69471487b7f4daf6d01fbe +timeCreated: 1683730882 \ No newline at end of file diff --git a/Assets/Xsolla/Orders/OrderTracking.meta b/Assets/Xsolla/Core/OrderTracking.meta similarity index 100% rename from Assets/Xsolla/Orders/OrderTracking.meta rename to Assets/Xsolla/Core/OrderTracking.meta diff --git a/Assets/Xsolla/Core/OrderTracking/OrderTracker.cs b/Assets/Xsolla/Core/OrderTracking/OrderTracker.cs new file mode 100644 index 000000000..6ef458135 --- /dev/null +++ b/Assets/Xsolla/Core/OrderTracking/OrderTracker.cs @@ -0,0 +1,67 @@ +using System; + +namespace Xsolla.Core +{ + internal abstract class OrderTracker + { + private bool _isCheckInProgress; + + public readonly OrderTrackingData TrackingData; + + public abstract void Start(); + + public abstract void Stop(); + + protected void RemoveSelfFromTracking() + { + OrderTrackingService.RemoveOrderFromTracking(TrackingData.orderId); + } + + protected void CheckOrderStatus(Action onDone = null, Action onCancel = null, Action onError = null) + { + if (!XsollaToken.Exists) + { + XDebug.LogWarning("No Token in order status check. Check cancelled"); + onCancel?.Invoke(); + return; + } + + if (_isCheckInProgress) // Prevent double check + return; + + _isCheckInProgress = true; + + OrderStatusService.GetOrderStatus( + TrackingData.orderId, + status => + { + _isCheckInProgress = false; + HandleOrderStatus(status.status, onDone, onCancel); + }, + error => + { + _isCheckInProgress = false; + onError?.Invoke(error); + } + ); + } + + protected static void HandleOrderStatus(string status, Action onDone, Action onCancel) + { + switch (status) + { + case "done": + onDone?.Invoke(); + break; + case "canceled": + onCancel?.Invoke(); + break; + } + } + + protected OrderTracker(OrderTrackingData trackingData) + { + TrackingData = trackingData; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTracker.cs.meta b/Assets/Xsolla/Core/OrderTracking/OrderTracker.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/OrderTracking/OrderTracker.cs.meta rename to Assets/Xsolla/Core/OrderTracking/OrderTracker.cs.meta diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByPaystationCallbacks.cs b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByPaystationCallbacks.cs similarity index 50% rename from Assets/Xsolla/Orders/OrderTracking/OrderTrackerByPaystationCallbacks.cs rename to Assets/Xsolla/Core/OrderTracking/OrderTrackerByPaystationCallbacks.cs index 620576685..d6439bee6 100644 --- a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByPaystationCallbacks.cs +++ b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByPaystationCallbacks.cs @@ -1,36 +1,35 @@ -namespace Xsolla.Orders +#if UNITY_WEBGL +namespace Xsolla.Core { - public class OrderTrackerByPaystationCallbacks : OrderTracker + internal class OrderTrackerByPaystationCallbacks : OrderTracker { -#if UNITY_WEBGL private bool isCancelByUser; -#endif + + public OrderTrackerByPaystationCallbacks(OrderTrackingData trackingData) : base(trackingData) { } public override void Start() { - XsollaWebCallbacks.Instance.OnPaymentStatusUpdate += HandleStatusUpdate; - XsollaWebCallbacks.Instance.OnPaymentCancel += HandlePaymentCancel; + XsollaWebCallbacks.AddPaymentStatusUpdateHandler(HandleStatusUpdate); + XsollaWebCallbacks.AddPaymentCancelHandler(HandlePaymentCancel); } public override void Stop() { - XsollaWebCallbacks.Instance.OnPaymentStatusUpdate -= HandleStatusUpdate; - XsollaWebCallbacks.Instance.OnPaymentCancel -= HandlePaymentCancel; -#if UNITY_WEBGL - Xsolla.Core.BrowserHelper.ClosePaystationWidget(isCancelByUser); -#endif + XsollaWebCallbacks.RemovePaymentStatusUpdateHandler(HandleStatusUpdate); + XsollaWebCallbacks.RemovePaymentCancelHandler(HandlePaymentCancel); + XsollaWebBrowser.ClosePaystationWidget(isCancelByUser); } private void HandleStatusUpdate() { CheckOrderStatus( - onDone: () => + () => { TrackingData?.successCallback?.Invoke(); RemoveSelfFromTracking(); }, - onCancel: RemoveSelfFromTracking, - onError: error => + RemoveSelfFromTracking, + error => { TrackingData?.errorCallback?.Invoke(error); RemoveSelfFromTracking(); @@ -40,12 +39,9 @@ private void HandleStatusUpdate() private void HandlePaymentCancel() { -#if UNITY_WEBGL isCancelByUser = true; -#endif RemoveSelfFromTracking(); } - - public OrderTrackerByPaystationCallbacks(OrderTrackingData trackingData) : base(trackingData) { } } -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByPaystationCallbacks.cs.meta b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByPaystationCallbacks.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/OrderTracking/OrderTrackerByPaystationCallbacks.cs.meta rename to Assets/Xsolla/Core/OrderTracking/OrderTrackerByPaystationCallbacks.cs.meta diff --git a/Assets/Xsolla/Core/OrderTracking/OrderTrackerByShortPolling.cs b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByShortPolling.cs new file mode 100644 index 000000000..fb7702580 --- /dev/null +++ b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByShortPolling.cs @@ -0,0 +1,51 @@ +using System.Collections; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class OrderTrackerByShortPolling : OrderTracker + { + private Coroutine checkStatusCoroutine; + + public OrderTrackerByShortPolling(OrderTrackingData trackingData) : base(trackingData) { } + + public override void Start() + { + checkStatusCoroutine = CoroutinesExecutor.Run(TrackOrderStatus()); + } + + public override void Stop() + { + CoroutinesExecutor.Stop(checkStatusCoroutine); + } + + private IEnumerator TrackOrderStatus() + { + var timeLimit = Time.realtimeSinceStartup + Constants.SHORT_POLLING_LIMIT; + + while (true) + { + yield return new WaitForSeconds(Constants.SHORT_POLLING_INTERVAL); + CheckOrderStatus(HandleOrderDone, RemoveSelfFromTracking, HandleError); + + if (Time.realtimeSinceStartup > timeLimit) + { + HandleError(new Error(ErrorType.TimeLimitReached, errorMessage: "Polling time limit reached")); + break; + } + } + } + + private void HandleOrderDone() + { + TrackingData?.successCallback?.Invoke(); + RemoveSelfFromTracking(); + } + + private void HandleError(Error error) + { + TrackingData?.errorCallback?.Invoke(error); + RemoveSelfFromTracking(); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByShortPolling.cs.meta b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByShortPolling.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/OrderTracking/OrderTrackerByShortPolling.cs.meta rename to Assets/Xsolla/Core/OrderTracking/OrderTrackerByShortPolling.cs.meta diff --git a/Assets/Xsolla/Core/OrderTracking/OrderTrackerByWebsockets.cs b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByWebsockets.cs new file mode 100644 index 000000000..e3bcd1540 --- /dev/null +++ b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByWebsockets.cs @@ -0,0 +1,127 @@ +using System; +using UnityEngine; +using WebSocketSharp; + +namespace Xsolla.Core +{ + internal class OrderTrackerByWebsockets : OrderTracker + { + private const string BASE_URL = "wss://store-ws.xsolla.com/sub/order/status"; + + private WebSocket webSocket; + private float startTime; + + private static MainThreadExecutor MainThreadExecutor; + + public OrderTrackerByWebsockets(OrderTrackingData trackingData) : base(trackingData) { } + + public override void Start() + { + if (!MainThreadExecutor) + MainThreadExecutor = new GameObject("Websockets MainThreadExecutor").AddComponent(); + + var url = new UrlBuilder(BASE_URL) + .AddParam("order_id", TrackingData.orderId) + .AddParam("project_id", XsollaSettings.StoreProjectId) + .Build(); + + webSocket = new WebSocket(url); + webSocket.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12; + + webSocket.OnMessage += OnWebSocketMessage; + webSocket.OnClose += OnWebSocketInterrupt; + webSocket.OnError += OnWebSocketInterrupt; + webSocket.Connect(); + + startTime = Time.realtimeSinceStartup; + } + + public override void Stop() + { + if (webSocket == null) + return; + + webSocket.OnMessage -= OnWebSocketMessage; + webSocket.OnClose -= OnWebSocketInterrupt; + webSocket.OnError -= OnWebSocketInterrupt; + webSocket.Close(); + webSocket = null; + } + + private void OnWebSocketMessage(object sender, MessageEventArgs args) + { + MainThreadExecutor.Enqueue(() => + { + OrderStatus status = null; + + try + { + status = ParseUtils.FromJson(args.Data); + } + catch (Exception ex) + { + XDebug.LogError($"Could not parse WebSocket message with exception: {ex.Message}"); + } + + if (status == null) + { + XDebug.LogError("WebSocket message order status is null"); + return; + } + + XDebug.Log($"WebSocket status message. OrderId:'{status.order_id}' Status:'{status.status}'"); + + HandleOrderStatus( + status.status, + () => + { + TrackingData.successCallback?.Invoke(); + RemoveSelfFromTracking(); + }, + RemoveSelfFromTracking + ); + }); + } + + private void OnWebSocketInterrupt(object sender, EventArgs args) + { + MainThreadExecutor.Enqueue(() => + { + switch (args) + { + case CloseEventArgs closeArgs: + XDebug.LogWarning($"WebSocket was closed with the code:'{closeArgs.Code}', reason:'{closeArgs.Reason}', wasClean:'{closeArgs.WasClean}'"); + break; + case ErrorEventArgs errorArgs: + XDebug.LogError($"WebSocket was closed with the exception:'{errorArgs.Exception.Message}', message:'{errorArgs.Message}'"); + break; + default: + XDebug.LogWarning($"WebSocket was closed with the unexpected argument '{args}'"); + break; + } + + var webSocketTTL = Time.realtimeSinceStartup - startTime; + if (webSocketTTL >= Constants.WEB_SOCKETS_TIMEOUT) + { + XDebug.Log($"WebSocket TTL '{webSocketTTL}' is OK, replacing an interrupted websocket with a new one"); + + var newTracker = new OrderTrackerByWebsockets(TrackingData); + if (OrderTrackingService.ReplaceTracker(this, newTracker)) + XDebug.Log($"Tracker for an order {TrackingData.orderId} is replaced with a new one"); + else + XDebug.LogError($"Failed to replace a tracker for an order {TrackingData.orderId}"); + } + else + { + XDebug.LogWarning($"WebSocket TTL '{webSocketTTL}' is lower than expected, switching to short polling"); + + var shortPollingTracker = new OrderTrackerByShortPolling(TrackingData); + if (OrderTrackingService.ReplaceTracker(this, shortPollingTracker)) + XDebug.Log($"Tracker for an order {TrackingData.orderId} is replaced with short polling"); + else + XDebug.LogError($"Failed to replace the tracker for an order {TrackingData.orderId}"); + } + }); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByWebsockets.cs.meta b/Assets/Xsolla/Core/OrderTracking/OrderTrackerByWebsockets.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/OrderTracking/OrderTrackerByWebsockets.cs.meta rename to Assets/Xsolla/Core/OrderTracking/OrderTrackerByWebsockets.cs.meta diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTrackingData.cs b/Assets/Xsolla/Core/OrderTracking/OrderTrackingData.cs similarity index 50% rename from Assets/Xsolla/Orders/OrderTracking/OrderTrackingData.cs rename to Assets/Xsolla/Core/OrderTracking/OrderTrackingData.cs index b7be120f0..787f18b81 100644 --- a/Assets/Xsolla/Orders/OrderTracking/OrderTrackingData.cs +++ b/Assets/Xsolla/Core/OrderTracking/OrderTrackingData.cs @@ -1,21 +1,18 @@ using System; -using Xsolla.Core; -namespace Xsolla.Orders +namespace Xsolla.Core { - public class OrderTrackingData + internal class OrderTrackingData { - public readonly string projectId; public readonly int orderId; public readonly Action successCallback; public readonly Action errorCallback; - - public OrderTrackingData(string projectId, int orderId, Action successCallback, Action errorCallback) + + public OrderTrackingData(int orderId, Action successCallback, Action errorCallback) { - this.projectId = projectId; this.orderId = orderId; this.successCallback = successCallback; this.errorCallback = errorCallback; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTrackingData.cs.meta b/Assets/Xsolla/Core/OrderTracking/OrderTrackingData.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/OrderTracking/OrderTrackingData.cs.meta rename to Assets/Xsolla/Core/OrderTracking/OrderTrackingData.cs.meta diff --git a/Assets/Xsolla/Core/OrderTracking/OrderTrackingService.cs b/Assets/Xsolla/Core/OrderTracking/OrderTrackingService.cs new file mode 100644 index 000000000..5715af135 --- /dev/null +++ b/Assets/Xsolla/Core/OrderTracking/OrderTrackingService.cs @@ -0,0 +1,61 @@ +using System; +using System.Collections.Generic; + +namespace Xsolla.Core +{ + internal static class OrderTrackingService + { + private static readonly Dictionary Trackers = new Dictionary(); + + public static void AddOrderForTracking(int orderId, bool isUserInvolvedToPayment, Action onSuccess, Action onError) + { + var tracker = CreateTracker(orderId, isUserInvolvedToPayment, onSuccess, onError); + if (tracker != null) + StartTracker(tracker); + } + + private static OrderTracker CreateTracker(int orderId, bool isUserInvolvedToPayment, Action onSuccess, Action onError) + { + if (Trackers.ContainsKey(orderId)) + return null; + + var trackingData = new OrderTrackingData(orderId, onSuccess, onError); +#if UNITY_WEBGL + if (!isUserInvolvedToPayment) + return new OrderTrackerByShortPolling(trackingData); + + return !UnityEngine.Application.isEditor && XsollaSettings.InAppBrowserEnabled + ? new OrderTrackerByPaystationCallbacks(trackingData) + : new OrderTrackerByShortPolling(trackingData) as OrderTracker; +#else + return new OrderTrackerByWebsockets(trackingData); +#endif + } + + public static bool RemoveOrderFromTracking(int orderId) + { + if (!Trackers.TryGetValue(orderId, out var tracker)) + return false; + + tracker.Stop(); + Trackers.Remove(orderId); + return true; + } + + public static bool ReplaceTracker(OrderTracker oldTracker, OrderTracker newTracker) + { + if (!RemoveOrderFromTracking(oldTracker.TrackingData.orderId)) + return false; + + StartTracker(newTracker); + return true; + } + + private static void StartTracker(OrderTracker tracker) + { + XDebug.Log($"Order tracker started: {tracker.GetType().Name}"); + Trackers.Add(tracker.TrackingData.orderId, tracker); + tracker.Start(); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTracking.cs.meta b/Assets/Xsolla/Core/OrderTracking/OrderTrackingService.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/OrderTracking/OrderTracking.cs.meta rename to Assets/Xsolla/Core/OrderTracking/OrderTrackingService.cs.meta diff --git a/Assets/Xsolla/Core/Plugins/iOS/Libs/XsollaSDKLoginKitObjectiveC.framework/Headers/XsollaSDKLoginKitObjectiveC-Swift.h b/Assets/Xsolla/Core/Plugins/iOS/Libs/XsollaSDKLoginKitObjectiveC.framework/Headers/XsollaSDKLoginKitObjectiveC-Swift.h index a56f33bc6..0e0fac849 100644 --- a/Assets/Xsolla/Core/Plugins/iOS/Libs/XsollaSDKLoginKitObjectiveC.framework/Headers/XsollaSDKLoginKitObjectiveC-Swift.h +++ b/Assets/Xsolla/Core/Plugins/iOS/Libs/XsollaSDKLoginKitObjectiveC.framework/Headers/XsollaSDKLoginKitObjectiveC-Swift.h @@ -213,7 +213,7 @@ typedef unsigned int swift_uint4 __attribute__((__ext_vector_type__(4))); #endif #else #if !defined(SWIFT_NOEXCEPT) -# define SWIFT_NOEXCEPT +# define SWIFT_NOEXCEPT #endif #endif #if defined(__cplusplus) @@ -278,7 +278,7 @@ SWIFT_CLASS("_TtC27XsollaSDKLoginKitObjectiveC19JWTGenerationParams") /// The type of getting the JWT. Can be: ///
    ///
  • -/// authorization_code to exchange the code received in the method to JWT +/// authorization_code to exchange the code received in the Xsolla.Auth.XsollaAuth.SignIn" to JWT /// The value of the authCode parameter must be specified. ///
  • ///
  • @@ -357,7 +357,7 @@ SWIFT_AVAILABILITY(ios,introduced=13.4) ///
  • /// providerName: Name of the social network connected to Login in Publisher Account. /// Can be: amazon, apple, baidu, battlenet, discord, facebook, github, google, kakao, linkedin, mailru, microsoft, msn, naver, ok, paypal, psn, reddit, steam, twitch, twitter, vimeo, vk, wechat, weibo, yahoo, yandex, youtube, xbox. -/// If you store user data in PlayFab, only ‘twitch’ is available. +/// If you store user data in PlayFab, only ‘twitch’ is available. ///
  • ///
  • /// oAuth2Params: Instance of OAuth2Params. @@ -409,15 +409,15 @@ SWIFT_CLASS("_TtC27XsollaSDKLoginKitObjectiveC12OAuth2Params") /// The value will be returned in the response. Must be longer than 8 characters. @property (nonatomic, readonly, strong) NSString * _Nonnull state; /// Grant type used in your project that has the enabled OAuth 2.0 protocol. Must be code to get the user authentication code in the response. -/// The received code must be exchanged to a JWT via the Generate JWT +/// The received code must be exchanged to a JWT via the Xsolla.Auth.XsollaAuth.ExchangeCodeToToken /// method to finish user authentication. @property (nonatomic, readonly, strong) NSString * _Nonnull responseType; /// Scope is a mechanism in OAuth 2.0 to limit application’s access to a user’s account. /// Can be: -/// 1. email for Auth via social network -/// or Get link for social auth +/// 1. email for Xsolla.Auth.XsollaAuth.AuthWithSocialNetworkAccessToken +/// or Xsolla.Auth.XsollaAuth.GetSocialNetworkAuthUrl /// methods to additionally request an email from the user. -/// 2. offline to use refresh_token from Generate JWT +/// 2. offline to use refresh_token from Xsolla.Auth.XsollaAuth.ExchangeCodeToToken /// method to refresh the JWT when it is expired. /// 3. playfab to write SessionTicket to the session_ticket claim of the JWT if you store user data on the PlayFab side. /// If you process your own values of the scope parameter, and the values aren’t mentioned above, you can set them when using this method. @@ -432,7 +432,7 @@ SWIFT_CLASS("_TtC27XsollaSDKLoginKitObjectiveC12OAuth2Params") /// The type of getting the JWT. typedef SWIFT_ENUM(NSInteger, TokenGrantType, open) { -/// To exchange the code received in the method +/// To exchange the code received in the Xsolla.Auth.XsollaAuth.SignIn /// for a JWT. TokenGrantTypeAuthorizationCode = 0, /// To get the refreshed JWT when the previous value is expired. diff --git a/Assets/Xsolla/Core/XsollaSettings.meta b/Assets/Xsolla/Core/Settings.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings.meta rename to Assets/Xsolla/Core/Settings.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor.meta b/Assets/Xsolla/Core/Settings/Editor.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor.meta rename to Assets/Xsolla/Core/Settings/Editor.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillRequester.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillRequester.cs similarity index 95% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillRequester.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillRequester.cs index 5b36b4e3f..64bcc6804 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillRequester.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillRequester.cs @@ -1,8 +1,9 @@ using System; using System.Collections.Generic; +using UnityEngine; using UnityEngine.Networking; -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { public class AutoFillRequester : IDisposable { @@ -24,7 +25,7 @@ public void RequestToken(string username, string password, Action onToke var webRequest = UnityWebRequest.Post(TOKEN_REQUEST_URL, UnityWebRequest.kHttpVerbPOST); #endif var requestBody = new TokenRequestBody(username, password); - var requestHeaders = WebRequestHelper.Instance.AppendAnalyticHeaders(SdkType.SettingsFillTool, WebRequestHeader.ContentTypeHeader()); + var requestHeaders = WebRequestHelper.Instance.AppendAnalyticHeaders(SdkType.SettingsFillTool, WebRequestHeader.JsonContentTypeHeader()); Action onRequestSuccess = response => { @@ -36,7 +37,7 @@ public void RequestToken(string username, string password, Action onToke onConfirmationNeeded?.Invoke(challengeID); else { - Debug.LogError($"ConfirmByCode: Could not find neither token nor challengeID in '{response}'"); + XDebug.LogError($"ConfirmByCode: Could not find neither token nor challengeID in '{response}'"); onError?.Invoke(Error.UnknownError); } }; @@ -64,7 +65,7 @@ public void ConfirmByCode(string challengeID, string code, Action onToke EnrichToken(loginUrl,onToken,onError); else { - Debug.LogError($"ConfirmByCode: Could not find token in '{response}'"); + XDebug.LogError($"ConfirmByCode: Could not find token in '{response}'"); onError?.Invoke(Error.UnknownError); } }; @@ -84,7 +85,7 @@ private bool ParseTokenResponse(string response, out string loginUrl, out string loginUrl = container?.login_url ?? container?.url; if (loginUrl == null) { - Debug.LogError($"Could not parse response. Response: '{response}'"); + XDebug.LogError($"Could not parse response. Response: '{response}'"); value = null; return false; } diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillRequester.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillRequester.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillRequester.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillRequester.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillTool.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillTool.cs similarity index 93% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillTool.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillTool.cs index 3d3651e0d..524981b02 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillTool.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillTool.cs @@ -2,8 +2,9 @@ using System; using System.Collections.Generic; using UnityEditor; +using UnityEngine; -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { using Node = SettingsTree.TreeNode; @@ -80,7 +81,7 @@ private void OnUiClosed() _oauthToRedirectMap = null; _instance = null; - Debug.Log("AutoFullTool closed"); + XDebug.Log("AutoFullTool closed"); } private void SetToolStep(ToolStep newStep) @@ -91,7 +92,7 @@ private void SetToolStep(ToolStep newStep) private void ShowError(string errorMessage) { - Debug.LogError(errorMessage); + XDebug.LogError(errorMessage); _window?.ShowMessage(errorMessage); _window?.ClearProgress(); } @@ -156,7 +157,7 @@ private void ProcessLoginRequest(string login, string password, bool rememberMe) SetToolStep(ToolStep.Auth); }; - Debug.Log("Sending auth request. Please wait..."); + XDebug.Log("Sending auth request. Please wait..."); _requester.RequestToken(login,password,onTokenGet,onConfirmationNeeded,onError); } @@ -195,7 +196,7 @@ private void ProcessConfirmationCode(string code) SetToolStep(ToolStep.Code); }; - Debug.Log("Sending confirmation code. Please wait..."); + XDebug.Log("Sending confirmation code. Please wait..."); _requester.ConfirmByCode(_currentChallengeID,code,onTokenGet,onError); } @@ -206,7 +207,7 @@ private void GenerateAndShowSettingsTree() return; } - Debug.Log("Requesting PA values. Please wait..."); + XDebug.Log("Requesting PA values. Please wait..."); var defaultSelection = new int[Enum.GetValues(typeof(SettingsType)).Length]; Action finalCallback = () => @@ -229,7 +230,7 @@ private void RecursiveAddNode(Node curNode, SettingsType curLevel, Action finalC switch (curLevel) { case SettingsType.MerchantID: - Debug.Log("Requesting MerchantIDs..."); + XDebug.Log("Requesting MerchantIDs..."); _requester.RequestMerchantIDs(_currentToken, onSuccess: containers => { @@ -242,7 +243,7 @@ private void RecursiveAddNode(Node curNode, SettingsType curLevel, Action finalC onError: ShowError); break; case SettingsType.ProjectID: - Debug.Log($"Requesting ProjectIDs for Merchant {curNode.value}..."); + XDebug.Log($"Requesting ProjectIDs for Merchant {curNode.value}..."); _requester.RequestProjectIDs(_currentToken, merchantID: (int)curNode.value, onSuccess: containers => @@ -256,7 +257,7 @@ private void RecursiveAddNode(Node curNode, SettingsType curLevel, Action finalC onError: ShowError); break; case SettingsType.LoginID: - Debug.Log($"Requesting LoginIDs for Project {curNode.value}..."); + XDebug.Log($"Requesting LoginIDs for Project {curNode.value}..."); _requester.RequestLoginIDs(_currentToken, merchantID: (int)curNode.parent.value, projectID: (int)curNode.value, @@ -271,7 +272,7 @@ private void RecursiveAddNode(Node curNode, SettingsType curLevel, Action finalC onError: ShowError); break; case SettingsType.OAuthID: - Debug.Log($"Requesting OauthIDs for Login {curNode.value}..."); + XDebug.Log($"Requesting OauthIDs for Login {curNode.value}..."); _requester.RequestOAuthIDs(_currentToken, loginID: (string)curNode.value, onSuccess: containers => @@ -285,12 +286,12 @@ private void RecursiveAddNode(Node curNode, SettingsType curLevel, Action finalC onError: ShowError); break; case SettingsType.RedirectUrl: - Debug.Log($"Assigning RedirectURIs for OAuth client {curNode.value}..."); + XDebug.Log($"Assigning RedirectURIs for OAuth client {curNode.value}..."); TryAssignRedirectUrls(OAuthID: (int)curNode.value, curNode, out Node[] _); finalCallback?.Invoke(); break; default: - Debug.LogError($"Unexpected setting type {curLevel}"); + XDebug.LogError($"Unexpected setting type {curLevel}"); return; } } @@ -438,14 +439,14 @@ private void ApplySelection(int[] selection) } #if AUTOFILLTOOL_DEBUG - Debug.Log($"Selection applied: [{string.Join(",",projectID,loginID,OAuthID,redirectURL)}]"); + XDebug.Error($"Selection applied: [{string.Join(",",projectID,loginID,OAuthID,redirectURL)}]"); #else XsollaSettings.StoreProjectId = projectID?.ToString() ?? string.Empty; XsollaSettings.LoginId = loginID ?? string.Empty; XsollaSettings.OAuthClientId = OAuthID ?? default(int); XsollaSettings.CallbackUrl = redirectURL ?? string.Empty; - Debug.Log("Settings applied"); + XDebug.Log("Settings applied"); #endif } } diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillTool.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillTool.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillTool.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillTool.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillUI.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillUI.cs similarity index 99% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillUI.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillUI.cs index 92596b068..d5f7b9f3e 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillUI.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillUI.cs @@ -3,7 +3,7 @@ using UnityEditor; using System; -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { public class AutoFillUI : EditorWindow { diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillUI.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillUI.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/AutoFillUI.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/AutoFillUI.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/EditorWebRequestHelper.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/EditorWebRequestHelper.cs similarity index 92% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/EditorWebRequestHelper.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/EditorWebRequestHelper.cs index 1f0ce2658..2c36f4cd7 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/EditorWebRequestHelper.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/EditorWebRequestHelper.cs @@ -4,7 +4,7 @@ using UnityEngine; using UnityEngine.Networking; -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { public class EditorWebRequestHelper : MonoBehaviour { @@ -15,10 +15,10 @@ public static void Request(UnityWebRequest request, Action onSuccess = null, Action onError = null) { if (requestBody != null) - WebRequestHelper.Instance.AttachBodyToRequest(request,requestBody); + WebRequestHelper.AttachBodyToRequest(request,requestBody); if (requestHeaders != null) - WebRequestHelper.Instance.AttachHeadersToRequest(request,requestHeaders); + WebRequestHelper.AttachHeadersToRequest(request,requestHeaders); var container = new RegularContainer(request, onSuccess, onError); StartAndEnqueue(container); @@ -70,7 +70,7 @@ private static void OnEditorUpdate() if (cur is RegularContainer regularContainer) { - if (WebRequestHelper.CheckNoErrors(cur.request, ErrorCheckType.CommonErrors, out Error error)) + if (WebRequestHelper.CheckNoErrors(cur.request, ErrorGroup.CommonErrors, out Error error)) regularContainer.successCallback?.Invoke(cur.request.downloadHandler.text); else regularContainer.errorCallback?.Invoke(error); diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/EditorWebRequestHelper.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/EditorWebRequestHelper.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/EditorWebRequestHelper.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/EditorWebRequestHelper.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/IntIdContainer.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/IntIdContainer.cs similarity index 70% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/IntIdContainer.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/IntIdContainer.cs index 4fa198473..afc016899 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/IntIdContainer.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/IntIdContainer.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { [Serializable] public class IntIdContainer diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/IntIdContainer.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/IntIdContainer.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/IntIdContainer.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/IntIdContainer.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/OAuthContainer.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/OAuthContainer.cs similarity index 78% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/OAuthContainer.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/OAuthContainer.cs index bda04320b..72dddbf6a 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/OAuthContainer.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/OAuthContainer.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { [Serializable] public class OAuthContainer diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/OAuthContainer.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/OAuthContainer.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/OAuthContainer.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/OAuthContainer.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsTree.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsTree.cs similarity index 97% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsTree.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsTree.cs index 2727cd1b9..8a4208981 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsTree.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsTree.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { public class SettingsTree { diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsTree.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsTree.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsTree.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsTree.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsType.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsType.cs similarity index 66% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsType.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsType.cs index b457746d4..667c24e5d 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsType.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsType.cs @@ -1,4 +1,4 @@ -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { public enum SettingsType { diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsType.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsType.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/SettingsType.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/SettingsType.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/StringIdContainer.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/StringIdContainer.cs similarity index 71% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/StringIdContainer.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/StringIdContainer.cs index 318abd7b6..b1ef471e7 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/StringIdContainer.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/StringIdContainer.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { [Serializable] public class StringIdContainer diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/StringIdContainer.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/StringIdContainer.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/StringIdContainer.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/StringIdContainer.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/ToolStep.cs b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/ToolStep.cs similarity index 59% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/ToolStep.cs rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/ToolStep.cs index 602254193..93d992f8c 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/ToolStep.cs +++ b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/ToolStep.cs @@ -1,4 +1,4 @@ -namespace Xsolla.Core.AutoFillSettings +namespace Xsolla.Core.Editor.AutoFillSettings { public enum ToolStep { diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/ToolStep.cs.meta b/Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/ToolStep.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/AutoFillTool/Entities/ToolStep.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/AutoFillTool/Entities/ToolStep.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaEditor.asmref b/Assets/Xsolla/Core/Settings/Editor/XsollaEditor.asmref similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaEditor.asmref rename to Assets/Xsolla/Core/Settings/Editor/XsollaEditor.asmref diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaEditor.asmref.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaEditor.asmref.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaEditor.asmref.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaEditor.asmref.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Android.cs b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Android.cs similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Android.cs rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Android.cs diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Android.cs.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Android.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Android.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Android.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.AutoFill.cs b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.AutoFill.cs similarity index 77% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.AutoFill.cs rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.AutoFill.cs index 6cb585aab..c89c74f32 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.AutoFill.cs +++ b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.AutoFill.cs @@ -1,6 +1,6 @@ using UnityEditor; using UnityEngine; -using Xsolla.Core.AutoFillSettings; +using Xsolla.Core.Editor.AutoFillSettings; namespace Xsolla.Core { @@ -12,7 +12,7 @@ private bool AutoFillSettings() EditorGUILayout.BeginVertical(GroupAreaStyle); EditorGUILayout.LabelField("Auto fill settings", GroupHeaderStyle); - if (GUILayout.Button("Fill settings by PA",GUILayout.Height(30))) + if (GUILayout.Button("Fill settings by PA", GUILayout.Height(30))) AutoFillTool.OpenAutoFillTool(); EditorGUILayout.EndVertical(); diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.AutoFill.cs.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.AutoFill.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.AutoFill.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.AutoFill.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Debugging.cs b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Debugging.cs similarity index 93% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Debugging.cs rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Debugging.cs index b75e46071..1b307dd8f 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Debugging.cs +++ b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Debugging.cs @@ -8,7 +8,7 @@ public partial class XsollaSettingsEditor private const string LOG_LEVEL_LABEL = "Print to Console"; private const string LOG_LEVEL_TOOLTIP = "Types of SDK messages to display in logs."; - private readonly string[] LogLevelOptions ={ + private readonly string[] LogLevelOptions = { "Info, Warnings and Errors", "Warnings and Errors", "Only Errors" diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Debugging.cs.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Debugging.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Debugging.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Debugging.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Desktop.cs b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Desktop.cs similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Desktop.cs rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Desktop.cs diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Desktop.cs.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Desktop.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Desktop.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Desktop.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.General.cs b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.General.cs similarity index 99% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.General.cs rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.General.cs index d73261cd8..c5a8f1ede 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.General.cs +++ b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.General.cs @@ -54,4 +54,4 @@ private bool GeneralSettings() return changed; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.General.cs.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.General.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.General.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.General.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Login.cs b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Login.cs similarity index 99% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Login.cs rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Login.cs index cfefc62bf..ace446223 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Login.cs +++ b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Login.cs @@ -49,4 +49,4 @@ private bool LoginSettings() return changed; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Login.cs.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Login.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.Login.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.Login.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.PayStation.cs b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.PayStation.cs similarity index 91% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.PayStation.cs rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.PayStation.cs index 04a754f25..021459726 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.PayStation.cs +++ b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.PayStation.cs @@ -17,7 +17,8 @@ public partial class XsollaSettingsEditor private const string IOS_GROUP_LABEL = "iOS"; private const string PAYSTATION_THEME_LABEL = "Pay Station Theme"; - private const string PAYSTATION_THEME_TOOLTIP = "Pay Station Theme"; + private const string PAYSTATION_THEME_TOOLTIP = "To use default themes, enter \"default\" or \"default_dark\" values." + + "Or enter the name of the custom theme you configured in Publisher Account to use it."; private const string PAYSTATION_SIZE_LABEL = "Pay Station Size"; private const string PAYSTATION_SIZE_TOOLTIP = "Small: 620 x 630 px\n" + @@ -50,28 +51,20 @@ public partial class XsollaSettingsEditor "\"None\" — do not redirect.\n" + "\"Purchase using virtual currency\" — redirect when purchase is made using virtual currency.\n" + "\"Successful payment\" — redirect when a payment is successful.\n" + - "\"Successful or canceled payment\" — redirect when a payment is successful or canceled.\n" + - "\"Any payment\" — redirect for any payment status."; + "\"Successful or canceled payment\" — redirect when a payment is successful or canceled.\n" + + "\"Any payment\" — redirect for any payment status."; private const string REDIRECT_BUTTON_LABEL = "Redirect Button Caption"; private const string REDIRECT_BUTTON_TOOLTIP = "Caption of the button that will redirect the user to the return URL."; - private readonly string[] ThemeOptions ={ - "Default", - "Dark", - "Default Dark", - "PS4 Default Light", - "PS4 Default Dark", - }; - - private readonly string[] RedirectConditionsOptions ={ + private readonly string[] RedirectConditionsOptions = { "None", "Successful payment", "Successful or canceled payment", "Any payment" }; - private readonly string[] StatusForManualRedirectionOptions ={ + private readonly string[] StatusForManualRedirectionOptions = { "None", "Purchase using virtual currency", "Successful payment", @@ -145,7 +138,7 @@ private void DrawPayStationUISettings(PayStationUISettings settings, string titl settings.isFoldout = EditorGUILayout.Foldout(settings.isFoldout, title); if (settings.isFoldout) { - settings.paystationTheme = (PayStationUISettings.PaystationTheme) EditorGUILayout.Popup(new GUIContent(PAYSTATION_THEME_LABEL, PAYSTATION_THEME_TOOLTIP), (int) settings.paystationTheme, ThemeOptions); + settings.paystationTheme = EditorGUILayout.TextField(new GUIContent(PAYSTATION_THEME_LABEL, PAYSTATION_THEME_TOOLTIP), settings.paystationTheme); settings.paystationSize = (PayStationUISettings.PaystationSize) EditorGUILayout.EnumPopup(new GUIContent(PAYSTATION_SIZE_LABEL, PAYSTATION_SIZE_TOOLTIP), settings.paystationSize); settings.paystationVersion = (PayStationUISettings.PaystationVersion) EditorGUILayout.EnumPopup(new GUIContent(PAYSTATION_VERSION_LABEL, PAYSTATION_VERSION_TOOLTIP), settings.paystationVersion); } diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.PayStation.cs.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.PayStation.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.PayStation.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.PayStation.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.cs b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.cs similarity index 88% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.cs rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.cs index 3325e86a9..d16c03749 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.cs +++ b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.cs @@ -13,7 +13,7 @@ public static void Edit() } private GUIStyle GroupAreaStyle => GUI.skin.box; - + private GUIStyle GroupHeaderStyle => EditorStyles.boldLabel; public override void OnInspectorGUI() @@ -32,8 +32,7 @@ public override void OnInspectorGUI() public static void DropSavedTokens() { - PlayerPrefs.DeleteKey(Constants.LAST_SUCCESS_AUTH_TOKEN); - PlayerPrefs.DeleteKey(Constants.LAST_SUCCESS_OAUTH_REFRESH_TOKEN); + XsollaToken.DeleteSavedInstance(); } private static void DrawErrorBox(string message) diff --git a/Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.cs.meta b/Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Editor/XsollaSettingsEditor.cs.meta rename to Assets/Xsolla/Core/Settings/Editor/XsollaSettingsEditor.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/PayStationUISettings.cs b/Assets/Xsolla/Core/Settings/PayStationUISettings.cs similarity index 56% rename from Assets/Xsolla/Core/XsollaSettings/PayStationUISettings.cs rename to Assets/Xsolla/Core/Settings/PayStationUISettings.cs index ff5a337e7..67d954dfa 100644 --- a/Assets/Xsolla/Core/XsollaSettings/PayStationUISettings.cs +++ b/Assets/Xsolla/Core/Settings/PayStationUISettings.cs @@ -6,10 +6,10 @@ namespace Xsolla.Core public class PayStationUISettings { public bool isFoldout; - public PaystationTheme paystationTheme = PaystationTheme.PS4_DefaultDark; + public string paystationTheme = "default"; public PaystationSize paystationSize = PaystationSize.Auto; public PaystationVersion paystationVersion = PaystationVersion.Auto; - + public static PayStationUI GenerateSettings() { #if UNITY_ANDROID @@ -25,8 +25,8 @@ public static PayStationUI GenerateSettings() private PayStationUI CreateSettings() { - var ui = new PayStationUI{ - theme = ConvertToString(paystationTheme) + var ui = new PayStationUI { + theme = paystationTheme }; if (paystationSize != PaystationSize.Auto) @@ -38,26 +38,13 @@ private PayStationUI CreateSettings() return ui; } - private string ConvertToString(PaystationTheme theme) - { - switch (theme) - { - case PaystationTheme.Default: return "default"; - case PaystationTheme.Dark: return "dark"; - case PaystationTheme.DefaultDark: return "default_dark"; - case PaystationTheme.PS4_DefaultLight: return "ps4-default-light"; - case PaystationTheme.PS4_DefaultDark: return "ps4-default-dark"; - default: goto case PaystationTheme.PS4_DefaultDark; - } - } - private string ConvertToString(PaystationSize size) { switch (size) { - case PaystationSize.Small: return "small"; - case PaystationSize.Medium: return "medium"; - case PaystationSize.Large: return "large"; + case PaystationSize.Small: return "small"; + case PaystationSize.Medium: return "medium"; + case PaystationSize.Large: return "large"; default: goto case PaystationSize.Medium; } } @@ -66,21 +53,12 @@ private string ConvertToString(PaystationVersion version) { switch (version) { - case PaystationVersion.Desktop: return "desktop"; - case PaystationVersion.Mobile: return "mobile"; + case PaystationVersion.Desktop: return "desktop"; + case PaystationVersion.Mobile: return "mobile"; default: goto case PaystationVersion.Desktop; } } - public enum PaystationTheme - { - Default, - Dark, - DefaultDark, - PS4_DefaultLight, - PS4_DefaultDark - } - public enum PaystationSize { Auto, @@ -95,12 +73,5 @@ public enum PaystationVersion Desktop, Mobile } - - public enum PaystationEnvironment - { - Desktop, - Android, - WebGL - } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/XsollaSettings/PayStationUISettings.cs.meta b/Assets/Xsolla/Core/Settings/PayStationUISettings.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/PayStationUISettings.cs.meta rename to Assets/Xsolla/Core/Settings/PayStationUISettings.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/RedirectPolicySettings.cs b/Assets/Xsolla/Core/Settings/RedirectPolicySettings.cs similarity index 75% rename from Assets/Xsolla/Core/XsollaSettings/RedirectPolicySettings.cs rename to Assets/Xsolla/Core/Settings/RedirectPolicySettings.cs index f78fae7b6..240113cdd 100644 --- a/Assets/Xsolla/Core/XsollaSettings/RedirectPolicySettings.cs +++ b/Assets/Xsolla/Core/Settings/RedirectPolicySettings.cs @@ -23,8 +23,8 @@ public class RedirectPolicySettings public static RedirectPolicy GeneratePolicy() { #if UNITY_ANDROID - return !XsollaSettings.AndroidRedirectPolicySettings.UseSettingsFromPublisherAccount - ? XsollaSettings.AndroidRedirectPolicySettings.CreatePolicy() + return !XsollaSettings.AndroidRedirectPolicySettings.UseSettingsFromPublisherAccount + ? XsollaSettings.AndroidRedirectPolicySettings.CreatePolicy() : CreateDefaultPaymentsPolicy(); #elif UNITY_WEBGL return !XsollaSettings.WebglRedirectPolicySettings.UseSettingsFromPublisherAccount @@ -35,16 +35,15 @@ public static RedirectPolicy GeneratePolicy() ? XsollaSettings.IosRedirectPolicySettings.CreatePolicy() : CreateDefaultPaymentsPolicy(); #else - return !XsollaSettings.DesktopRedirectPolicySettings.UseSettingsFromPublisherAccount - ? XsollaSettings.DesktopRedirectPolicySettings.CreatePolicy() + return !XsollaSettings.DesktopRedirectPolicySettings.UseSettingsFromPublisherAccount + ? XsollaSettings.DesktopRedirectPolicySettings.CreatePolicy() : null; #endif } private RedirectPolicy CreatePolicy() { - return new RedirectPolicy - { + return new RedirectPolicy { return_url = ReturnUrl, redirect_conditions = ConvertToString(RedirectConditions), delay = Delay, @@ -55,7 +54,7 @@ private RedirectPolicy CreatePolicy() private static RedirectPolicy CreateDefaultPaymentsPolicy() { - return new RedirectPolicy{ + return new RedirectPolicy { return_url = $"app://xpayment.{Application.identifier}", redirect_conditions = RedirectConditionsType.Any.ToString().ToLowerInvariant(), delay = 0, @@ -68,11 +67,11 @@ private string ConvertToString(RedirectConditionsType conditions) { switch (conditions) { - case RedirectConditionsType.None: return "none"; - case RedirectConditionsType.Successful: return "successful"; + case RedirectConditionsType.None: return "none"; + case RedirectConditionsType.Successful: return "successful"; case RedirectConditionsType.SuccessfulOrCanceled: return "successful_or_canceled"; - case RedirectConditionsType.Any: return "any"; - default: return "none"; + case RedirectConditionsType.Any: return "any"; + default: return "none"; } } @@ -80,12 +79,12 @@ private string ConvertToString(StatusForManualRedirectionType status) { switch (status) { - case StatusForManualRedirectionType.None: return "none"; - case StatusForManualRedirectionType.Vc: return "vc"; - case StatusForManualRedirectionType.Successful: return "successful"; + case StatusForManualRedirectionType.None: return "none"; + case StatusForManualRedirectionType.Vc: return "vc"; + case StatusForManualRedirectionType.Successful: return "successful"; case StatusForManualRedirectionType.SuccessfulOrCanceled: return "successful_or_canceled"; - case StatusForManualRedirectionType.Any: return "any"; - default: return "none"; + case StatusForManualRedirectionType.Any: return "any"; + default: return "none"; } } diff --git a/Assets/Xsolla/Core/XsollaSettings/RedirectPolicySettings.cs.meta b/Assets/Xsolla/Core/Settings/RedirectPolicySettings.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/RedirectPolicySettings.cs.meta rename to Assets/Xsolla/Core/Settings/RedirectPolicySettings.cs.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Resources.meta b/Assets/Xsolla/Core/Settings/Resources.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Resources.meta rename to Assets/Xsolla/Core/Settings/Resources.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/Resources/XsollaSettings.asset b/Assets/Xsolla/Core/Settings/Resources/XsollaSettings.asset similarity index 94% rename from Assets/Xsolla/Core/XsollaSettings/Resources/XsollaSettings.asset rename to Assets/Xsolla/Core/Settings/Resources/XsollaSettings.asset index 156e82fde..370f0cb4d 100644 --- a/Assets/Xsolla/Core/XsollaSettings/Resources/XsollaSettings.asset +++ b/Assets/Xsolla/Core/Settings/Resources/XsollaSettings.asset @@ -54,22 +54,22 @@ MonoBehaviour: RedirectButtonCaption: desktopPayStationUISettings: isFoldout: 0 - paystationTheme: 4 + paystationTheme: default paystationSize: 0 paystationVersion: 0 webglPayStationUISettings: isFoldout: 0 - paystationTheme: 4 + paystationTheme: default paystationSize: 0 paystationVersion: 0 androidPayStationUISettings: isFoldout: 0 - paystationTheme: 4 + paystationTheme: default paystationSize: 0 paystationVersion: 0 iosPayStationUISettings: isFoldout: 0 - paystationTheme: 4 + paystationTheme: default paystationSize: 0 paystationVersion: 0 facebookAppId: diff --git a/Assets/Xsolla/Core/XsollaSettings/Resources/XsollaSettings.asset.meta b/Assets/Xsolla/Core/Settings/Resources/XsollaSettings.asset.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/Resources/XsollaSettings.asset.meta rename to Assets/Xsolla/Core/Settings/Resources/XsollaSettings.asset.meta diff --git a/Assets/Xsolla/Core/XsollaSettings/XsollaSettings.cs b/Assets/Xsolla/Core/Settings/XsollaSettings.cs similarity index 87% rename from Assets/Xsolla/Core/XsollaSettings/XsollaSettings.cs rename to Assets/Xsolla/Core/Settings/XsollaSettings.cs index 0d5a1977e..5cb94d208 100644 --- a/Assets/Xsolla/Core/XsollaSettings/XsollaSettings.cs +++ b/Assets/Xsolla/Core/Settings/XsollaSettings.cs @@ -1,4 +1,3 @@ -using System; using System.IO; using UnityEditor; using UnityEngine; @@ -11,11 +10,9 @@ public class XsollaSettings : ScriptableObject private const string SETTINGS_ASSET_PATH = "Resources/"; private const string SETTINGS_ASSET_EXTENSION = ".asset"; - private static XsollaSettings _instance; - [SerializeField] private string loginId = Constants.DEFAULT_LOGIN_ID; - [SerializeField] private string callbackUrl = default; - [SerializeField] private bool invalidateExistingSessions = default; + [SerializeField] private string callbackUrl; + [SerializeField] private bool invalidateExistingSessions; [SerializeField] private int oauthClientId = Constants.DEFAULT_OAUTH_CLIENT_ID; [SerializeField] private string storeProjectId = Constants.DEFAULT_PROJECT_ID; @@ -33,15 +30,13 @@ public class XsollaSettings : ScriptableObject [SerializeField] private PayStationUISettings androidPayStationUISettings = new PayStationUISettings(); [SerializeField] private PayStationUISettings iosPayStationUISettings = new PayStationUISettings(); - [SerializeField] private string facebookAppId = default; - [SerializeField] private string googleServerId = default; - [SerializeField] private string wechatAppId = default; - [SerializeField] private string qqAppId = default; + [SerializeField] private string facebookAppId; + [SerializeField] private string googleServerId; + [SerializeField] private string wechatAppId; + [SerializeField] private string qqAppId; [SerializeField] private LogLevel logLevel = LogLevel.InfoWarningsErrors; - public static event Action Changed; - public static bool PayStationGroupFoldout { get; set; } public static bool RedirectPolicyGroupFoldout { get; set; } @@ -51,11 +46,7 @@ public static string LoginId set { Instance.loginId = value; - - if (!Application.isPlaying) - MarkAssetDirty(); - - Changed?.Invoke(); + MarkAssetDirty(); } } @@ -75,11 +66,7 @@ public static int OAuthClientId set { Instance.oauthClientId = value; - - if (!Application.isPlaying) - MarkAssetDirty(); - - Changed?.Invoke(); + MarkAssetDirty(); } } @@ -99,11 +86,7 @@ public static string StoreProjectId set { Instance.storeProjectId = value; - - if (!Application.isPlaying) - MarkAssetDirty(); - - Changed?.Invoke(); + MarkAssetDirty(); } } @@ -178,7 +161,7 @@ public static PayStationUISettings AndroidPayStationUISettings get => Instance.androidPayStationUISettings; set => Instance.androidPayStationUISettings = value; } - + public static PayStationUISettings IosPayStationUISettings { get => Instance.iosPayStationUISettings; @@ -219,13 +202,15 @@ public static LogLevel LogLevel } } + private static XsollaSettings _instance; + public static XsollaSettings Instance { get { if (_instance) return _instance; - + _instance = Resources.Load(SETTINGS_ASSET_NAME) as XsollaSettings; if (_instance) return _instance; @@ -233,8 +218,12 @@ public static XsollaSettings Instance _instance = CreateInstance(); #if UNITY_EDITOR var absolutePath = Path.GetDirectoryName(Path.GetDirectoryName(FindEditor(Application.dataPath))); - var sdkPath = absolutePath.Replace("\\", "/").Replace(Application.dataPath, "Assets"); - SaveAsset(Path.Combine(sdkPath, SETTINGS_ASSET_PATH), SETTINGS_ASSET_NAME); + if (absolutePath != null) + { + var sdkPath = absolutePath.Replace("\\", "/").Replace(Application.dataPath, "Assets"); + SaveAsset(Path.Combine(sdkPath, SETTINGS_ASSET_PATH), SETTINGS_ASSET_NAME); + } + #endif return _instance; } @@ -276,8 +265,9 @@ private static void SaveAsset(string directory, string name) private static void MarkAssetDirty() { #if UNITY_EDITOR - EditorUtility.SetDirty(Instance); + if (!Application.isPlaying) + EditorUtility.SetDirty(Instance); #endif } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/XsollaSettings/XsollaSettings.cs.meta b/Assets/Xsolla/Core/Settings/XsollaSettings.cs.meta similarity index 100% rename from Assets/Xsolla/Core/XsollaSettings/XsollaSettings.cs.meta rename to Assets/Xsolla/Core/Settings/XsollaSettings.cs.meta diff --git a/Assets/Xsolla/Core/Steam/SteamSessionTicket.cs b/Assets/Xsolla/Core/Steam/SteamSessionTicket.cs index 0d7e6706b..62e9cdd34 100644 --- a/Assets/Xsolla/Core/Steam/SteamSessionTicket.cs +++ b/Assets/Xsolla/Core/Steam/SteamSessionTicket.cs @@ -1,23 +1,22 @@ using System; using System.Linq; using System.Text; -using UnityEngine; - #if UNITY_STANDALONE using Steamworks; #endif namespace Xsolla.Core { - /// - /// This ticket you can change for Login JWT - /// and use it in Xsolla Store - /// - public class SteamSessionTicket + internal class SteamSessionTicket { - private string ticket = ""; + private static byte[] RefreshTicket() + { + return Initialized() + ? GetTicketData() + : Array.Empty(); + } - private bool Initialized() + private static bool Initialized() { bool result; try @@ -26,60 +25,45 @@ private bool Initialized() } catch (Exception e) { - Debug.LogWarning("Steam initialization error. " + e.Message); + XDebug.LogError("Steam initialization error. " + e.Message); result = false; } return result; } - private byte[] GetTicketData() + private static byte[] GetTicketData() { - byte[] ticket = new byte[1024]; + var ticket = new byte[1024]; try { #if UNITY_STANDALONE - SteamUser.GetAuthSessionTicket(ticket, 1024, out uint length); + SteamUser.GetAuthSessionTicket(ticket, 1024, out var length); Array.Resize(ref ticket, (int) length); #else - ticket = new byte[0]; + ticket = new byte[0]; #endif } catch (Exception e) { - Debug.Log("Get steam session ticket exception: " + e.Message); - ticket = new byte[0]; + XDebug.LogError("Get steam session ticket exception: " + e.Message); + ticket = Array.Empty(); } return ticket; } - private byte[] RefreshTicket() - { - return Initialized() ? GetTicketData() : (new byte[0]); - } - - string ConvertTicket(byte[] ticket) + private static string ConvertTicket(byte[] ticket) { - StringBuilder sb = new StringBuilder(); - ticket.ToList().ForEach(b => sb.AppendFormat("{0:x2}", b)); - return sb.ToString(); + var stringBuilder = new StringBuilder(); + ticket.ToList().ForEach(b => stringBuilder.AppendFormat("{0:x2}", b)); + return stringBuilder.ToString(); } - /// - /// Get ticket value for change with Login API - /// - /// public override string ToString() { - if (string.IsNullOrEmpty(ticket)) - { - byte[] ticketData = RefreshTicket(); - ticket = ConvertTicket(ticketData); - Debug.Log("Requested steam session ticket = " + (string.IsNullOrEmpty(ticket) ? "none" : ticket)); - } - - return ticket; + var ticketData = RefreshTicket(); + return ConvertTicket(ticketData); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Steam/SteamTokenPayload.cs b/Assets/Xsolla/Core/Steam/SteamTokenPayload.cs new file mode 100644 index 000000000..ca8e0cec5 --- /dev/null +++ b/Assets/Xsolla/Core/Steam/SteamTokenPayload.cs @@ -0,0 +1,11 @@ +using System; + +namespace Xsolla.Core +{ + [Serializable] + internal class SteamTokenPayload + { + public string id; + public bool is_cross_auth; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Steam/SteamTokenPayload.cs.meta b/Assets/Xsolla/Core/Steam/SteamTokenPayload.cs.meta new file mode 100644 index 000000000..59d2230bb --- /dev/null +++ b/Assets/Xsolla/Core/Steam/SteamTokenPayload.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2937d1376f6148d9bfdf961aafa8f8c7 +timeCreated: 1681962886 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Steam/SteamUtils.cs b/Assets/Xsolla/Core/Steam/SteamUtils.cs new file mode 100644 index 000000000..a61678f18 --- /dev/null +++ b/Assets/Xsolla/Core/Steam/SteamUtils.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +namespace Xsolla.Core +{ + public static class SteamUtils + { + /// + /// This ticket you can change for Login JWT and use it in Xsolla Store + /// + public static string GetSteamSessionTicket() + { + var ticket = new SteamSessionTicket().ToString(); + if (!string.IsNullOrEmpty(ticket)) + XDebug.Log($"Requested steam session ticket: {ticket}"); + else + XDebug.LogError("Requested steam session ticket is null. Please check your Steam settings."); + + return ticket; + } + + public static Dictionary GetAdditionalCustomHeaders() + { + return new Dictionary {{"x-steam-userid", GetSteamUserId()}}; + } + + private static string GetSteamUserId() + { + var encodedToken = XsollaToken.AccessToken; + if (string.IsNullOrEmpty(encodedToken)) + throw new Exception("Token is empty"); + + var tokenParts = encodedToken.Split('.'); + if (tokenParts.Length < 3) + throw new Exception("Token must contain header, payload and signature. " + + $"Your token parts count was '{tokenParts.Length}'. " + + $"Your token: {encodedToken}"); + + var payload = ParsePayload(tokenParts[1]); + if (!payload.is_cross_auth) + throw new Exception("Token must not be cross auth. " + + $"Your token: {encodedToken}"); + + var steamUserUrl = payload.id; + if (string.IsNullOrEmpty(steamUserUrl)) + throw new Exception("Token must have 'id' parameter. " + + $"Your token: {encodedToken}"); + + return steamUserUrl.Split('/').Last(); + } + + private static SteamTokenPayload ParsePayload(string encodedPayload) + { + //Fix FromBase64String conversion + encodedPayload = encodedPayload + .Replace('-', '+') + .Replace('_', '/'); + + var padding = encodedPayload.Length % 4; + if (padding != 0) + { + var paddingToAdd = 4 - padding; + encodedPayload += new string('=', paddingToAdd); + } + + var bytes = Convert.FromBase64String(encodedPayload); + var json = Encoding.UTF8.GetString(bytes); + return ParseUtils.FromJson(json); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Steam/SteamUtils.cs.meta b/Assets/Xsolla/Core/Steam/SteamUtils.cs.meta new file mode 100644 index 000000000..1959f0496 --- /dev/null +++ b/Assets/Xsolla/Core/Steam/SteamUtils.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a24efab7865248c5a2771930b4e1839e +timeCreated: 1683093744 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Token.meta b/Assets/Xsolla/Core/Token.meta new file mode 100644 index 000000000..c17c341a4 --- /dev/null +++ b/Assets/Xsolla/Core/Token.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1ff27dda7c454992ae927b498cebcedb +timeCreated: 1681962868 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Token/Internal.meta b/Assets/Xsolla/Core/Token/Internal.meta new file mode 100644 index 000000000..152f31457 --- /dev/null +++ b/Assets/Xsolla/Core/Token/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fc70fa8ef222447a9c294a01f8e920e1 +timeCreated: 1683264387 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Token/Internal/TokenAutoRefresher.cs b/Assets/Xsolla/Core/Token/Internal/TokenAutoRefresher.cs new file mode 100644 index 000000000..a4ebf6c17 --- /dev/null +++ b/Assets/Xsolla/Core/Token/Internal/TokenAutoRefresher.cs @@ -0,0 +1,21 @@ +using System; +using Xsolla.Auth; + +namespace Xsolla.Core +{ + internal static class TokenAutoRefresher + { + public static void Check(Error error, Action onError, Action onSuccess) + { + if (error.ErrorType != ErrorType.InvalidToken) + { + onError?.Invoke(error); + return; + } + + XsollaAuth.RefreshToken( + () => onSuccess?.Invoke(), + onError); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Token/Internal/TokenAutoRefresher.cs.meta b/Assets/Xsolla/Core/Token/Internal/TokenAutoRefresher.cs.meta new file mode 100644 index 000000000..2ff7ed23f --- /dev/null +++ b/Assets/Xsolla/Core/Token/Internal/TokenAutoRefresher.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 3776d2859e9f48538498742f2284a40e +timeCreated: 1681965517 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Token/Internal/TokenData.cs b/Assets/Xsolla/Core/Token/Internal/TokenData.cs new file mode 100644 index 000000000..514ed7de8 --- /dev/null +++ b/Assets/Xsolla/Core/Token/Internal/TokenData.cs @@ -0,0 +1,8 @@ +namespace Xsolla.Core +{ + internal class TokenData + { + public string accessToken; + public string refreshToken; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Token/Internal/TokenData.cs.meta b/Assets/Xsolla/Core/Token/Internal/TokenData.cs.meta new file mode 100644 index 000000000..cbde1dc22 --- /dev/null +++ b/Assets/Xsolla/Core/Token/Internal/TokenData.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0bec174e17de4974a2c0478305e2b9db +timeCreated: 1682587270 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Token/XsollaToken.cs b/Assets/Xsolla/Core/Token/XsollaToken.cs new file mode 100644 index 000000000..758981c1d --- /dev/null +++ b/Assets/Xsolla/Core/Token/XsollaToken.cs @@ -0,0 +1,61 @@ +using UnityEngine; + +namespace Xsolla.Core +{ + public static class XsollaToken + { + private const string SaveKey = "XsollaSuperToken"; + + public static string AccessToken => Instance?.accessToken; + + public static string RefreshToken => Instance?.refreshToken; + + public static bool Exists => Instance != null; + + private static TokenData Instance { get; set; } + + public static void Create(string accessToken) + { + Instance = new TokenData { + accessToken = accessToken + }; + + SaveInstance(); + } + + public static void Create(string accessToken, string refreshToken) + { + Instance = new TokenData { + accessToken = accessToken, + refreshToken = refreshToken + }; + + SaveInstance(); + } + + private static void SaveInstance() + { + if (Instance == null) + return; + + var json = ParseUtils.ToJson(Instance); + PlayerPrefs.SetString(SaveKey, json); + } + + public static bool TryLoadInstance() + { + if (!PlayerPrefs.HasKey(SaveKey)) + return false; + + var json = PlayerPrefs.GetString(SaveKey); + Instance = ParseUtils.FromJson(json); + return Instance != null; + } + + public static void DeleteSavedInstance() + { + Instance = null; + PlayerPrefs.DeleteKey(SaveKey); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Token/XsollaToken.cs.meta b/Assets/Xsolla/Core/Token/XsollaToken.cs.meta new file mode 100644 index 000000000..c563b332e --- /dev/null +++ b/Assets/Xsolla/Core/Token/XsollaToken.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 839d511a903347be85b7fa8c48ac6347 +timeCreated: 1682568495 \ No newline at end of file diff --git a/Assets/Xsolla/Core/TokenRefresh.meta b/Assets/Xsolla/Core/TokenRefresh.meta deleted file mode 100644 index 74949e2d8..000000000 --- a/Assets/Xsolla/Core/TokenRefresh.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 045383d9f7306014aa5f2a015af6048f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/TokenRefresh/TokenRefresh.cs b/Assets/Xsolla/Core/TokenRefresh/TokenRefresh.cs deleted file mode 100644 index 6c8b352a1..000000000 --- a/Assets/Xsolla/Core/TokenRefresh/TokenRefresh.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using UnityEngine; - -namespace Xsolla.Core -{ - public class TokenRefresh : MonoSingleton - { - private string _refreshToken; - - public string RefreshToken - { - get - { - if (string.IsNullOrEmpty(_refreshToken)) - _refreshToken = PlayerPrefs.GetString(Constants.LAST_SUCCESS_OAUTH_REFRESH_TOKEN, string.Empty); - - return _refreshToken; - } - set - { - _refreshToken = value; - PlayerPrefs.SetString(Constants.LAST_SUCCESS_OAUTH_REFRESH_TOKEN, value); - } - } - - public event Action> OnInvalidToken; - - public void CheckInvalidToken(Error error, Action onErrorCallback, Action repeatCall) - { - if (error.ErrorType == ErrorType.InvalidToken && - OnInvalidToken != null) - { - Debug.Log("TokenRefresh: Attempting to refresh the token"); - OnInvalidToken.Invoke(repeatCall, onErrorCallback); - } - else - { - onErrorCallback?.Invoke(error); - } - } - } -} diff --git a/Assets/Xsolla/Core/TokenRefresh/TokenRefresh.cs.meta b/Assets/Xsolla/Core/TokenRefresh/TokenRefresh.cs.meta deleted file mode 100644 index aa501d45b..000000000 --- a/Assets/Xsolla/Core/TokenRefresh/TokenRefresh.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dd9f3d1b1f81c5b428fb1a40db731b28 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/CoroutinesExecutor.cs b/Assets/Xsolla/Core/Utils/CoroutinesExecutor.cs new file mode 100644 index 000000000..d62e1ba46 --- /dev/null +++ b/Assets/Xsolla/Core/Utils/CoroutinesExecutor.cs @@ -0,0 +1,32 @@ +using System.Collections; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class CoroutinesExecutor : MonoBehaviour + { + private static CoroutinesExecutor _instance; + + private static CoroutinesExecutor Instance + { + get + { + if (!_instance) + _instance = new GameObject("CoroutinesExecutor").AddComponent(); + + return _instance; + } + } + + public static Coroutine Run(IEnumerator coroutine) + { + return Instance.StartCoroutine(coroutine); + } + + public static void Stop(Coroutine coroutine) + { + if (coroutine != null) + Instance.StopCoroutine(coroutine); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/CoroutinesExecutor.cs.meta b/Assets/Xsolla/Core/Utils/CoroutinesExecutor.cs.meta new file mode 100644 index 000000000..328dba0a3 --- /dev/null +++ b/Assets/Xsolla/Core/Utils/CoroutinesExecutor.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0c65b860b8a744fa9732462e15491b81 +timeCreated: 1683001641 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/DataClassExtensions.cs b/Assets/Xsolla/Core/Utils/DataClassExtensions.cs new file mode 100644 index 000000000..41ce4f6a0 --- /dev/null +++ b/Assets/Xsolla/Core/Utils/DataClassExtensions.cs @@ -0,0 +1,47 @@ +using System; + +namespace Xsolla.Core +{ + internal static class DataClassExtensions + { + public static string ToApiParameter(this SocialProvider provider) + { + switch (provider) + { + case SocialProvider.Facebook: return "facebook"; + case SocialProvider.GitHub: return "github"; + case SocialProvider.Google: return "google"; + case SocialProvider.Twitch: return "twitch"; + case SocialProvider.Twitter: return "twitter"; + case SocialProvider.Steam: return "steam"; + case SocialProvider.Xbox: return "xbox"; + case SocialProvider.Discord: return "discord"; + case SocialProvider.Vk: return "vk"; + case SocialProvider.Naver: return "naver"; + case SocialProvider.Kakao: return "kakao"; + case SocialProvider.Baidu: return "baidu"; + case SocialProvider.Battlenet: return "battlenet"; + case SocialProvider.ChinaTelecom: return "chinatelecom"; + case SocialProvider.Instagram: return "instagram"; + case SocialProvider.LinkedIn: return "linkedin"; + case SocialProvider.Odnoklassniki: return "ok"; + case SocialProvider.PayPal: return "paypal"; + case SocialProvider.Pinterest: return "pinterest"; + case SocialProvider.QQ: return "qq"; + case SocialProvider.Reddit: return "reddit"; + case SocialProvider.Vimeo: return "vimeo"; + case SocialProvider.WeChat: return "wechat"; + case SocialProvider.Weibo: return "weibo"; + case SocialProvider.Yahoo: return "yahoo"; + case SocialProvider.Amazon: return "amazon"; + case SocialProvider.Mailru: return "mailru"; + case SocialProvider.Microsoft: return "microsoft"; + case SocialProvider.Msn: return "msn"; + case SocialProvider.Yandex: return "yandex"; + case SocialProvider.YouTube: return "youtube"; + case SocialProvider.Apple: return "apple"; + default: throw new Exception(provider.ToString()); + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/DataClassExtensions.cs.meta b/Assets/Xsolla/Core/Utils/DataClassExtensions.cs.meta new file mode 100644 index 000000000..23ebf526a --- /dev/null +++ b/Assets/Xsolla/Core/Utils/DataClassExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ed06bd4d8dd74cdc92f92277342ad08e +timeCreated: 1683696275 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/Debug.Auth.cs b/Assets/Xsolla/Core/Utils/Debug.Auth.cs deleted file mode 100644 index 7b27850eb..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Auth.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.Auth -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.Auth.cs.meta b/Assets/Xsolla/Core/Utils/Debug.Auth.cs.meta deleted file mode 100644 index 8ace75fc9..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Auth.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 60d4a8c75ed0d9b4d8b25f5c8926149e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.Cart.cs b/Assets/Xsolla/Core/Utils/Debug.Cart.cs deleted file mode 100644 index f19ed7215..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Cart.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.Cart -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.Cart.cs.meta b/Assets/Xsolla/Core/Utils/Debug.Cart.cs.meta deleted file mode 100644 index 1fc605dd7..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Cart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 90fe78ba233038443ba506a2407c8de2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.Catalog.cs b/Assets/Xsolla/Core/Utils/Debug.Catalog.cs deleted file mode 100644 index f1c9cc65b..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Catalog.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.Catalog -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.Catalog.cs.meta b/Assets/Xsolla/Core/Utils/Debug.Catalog.cs.meta deleted file mode 100644 index f62c4c53f..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Catalog.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 73b3542c0dd202c40a280be25e996306 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.Demo.cs b/Assets/Xsolla/Core/Utils/Debug.Demo.cs deleted file mode 100644 index a4bf32793..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Demo.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.Demo -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.Demo.cs.meta b/Assets/Xsolla/Core/Utils/Debug.Demo.cs.meta deleted file mode 100644 index f5fe4419d..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Demo.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 76d5a6ae03e2e9d44996a47b9b8b07de -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.GameKeys.cs b/Assets/Xsolla/Core/Utils/Debug.GameKeys.cs deleted file mode 100644 index 86dea2402..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.GameKeys.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.GameKeys -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.GameKeys.cs.meta b/Assets/Xsolla/Core/Utils/Debug.GameKeys.cs.meta deleted file mode 100644 index 6cd0b1674..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.GameKeys.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f83371ad2d66c6b4db58d61d6617ba9e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.Inventory.cs b/Assets/Xsolla/Core/Utils/Debug.Inventory.cs deleted file mode 100644 index fc83cd41c..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Inventory.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.Inventory -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.Inventory.cs.meta b/Assets/Xsolla/Core/Utils/Debug.Inventory.cs.meta deleted file mode 100644 index 008b1c094..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Inventory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3052c2d7f372e224ebd16e5f16652b0e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.Orders.cs b/Assets/Xsolla/Core/Utils/Debug.Orders.cs deleted file mode 100644 index 90c01ef01..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Orders.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.Orders -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.Orders.cs.meta b/Assets/Xsolla/Core/Utils/Debug.Orders.cs.meta deleted file mode 100644 index 724964e9c..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Orders.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 77b53e6fe37598c498e98834933b3715 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.Subscriptions.cs b/Assets/Xsolla/Core/Utils/Debug.Subscriptions.cs deleted file mode 100644 index 7fcc332dc..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Subscriptions.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.Subscriptions -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.Subscriptions.cs.meta b/Assets/Xsolla/Core/Utils/Debug.Subscriptions.cs.meta deleted file mode 100644 index a2b17fb22..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.Subscriptions.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a92c6b1f47622734b959c8a27fbba79f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.UserAccount.cs b/Assets/Xsolla/Core/Utils/Debug.UserAccount.cs deleted file mode 100644 index 29f5053d1..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.UserAccount.cs +++ /dev/null @@ -1,4 +0,0 @@ -namespace Xsolla.UserAccount -{ - public class Debug : Xsolla.Core.Debug { } -} diff --git a/Assets/Xsolla/Core/Utils/Debug.UserAccount.cs.meta b/Assets/Xsolla/Core/Utils/Debug.UserAccount.cs.meta deleted file mode 100644 index e3bb6cad5..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.UserAccount.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: d1d4e9b5eabf83147abf8a79fb6fa505 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/Debug.cs b/Assets/Xsolla/Core/Utils/Debug.cs deleted file mode 100644 index 958ce8317..000000000 --- a/Assets/Xsolla/Core/Utils/Debug.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; - -namespace Xsolla.Core -{ - public class Debug - { - public static void Log(object message) - { - if (XsollaSettings.LogLevel == LogLevel.InfoWarningsErrors) - UnityEngine.Debug.Log(message); - } - - public static void LogWarning(object message) - { - if (XsollaSettings.LogLevel <= LogLevel.WarningsErrors) - UnityEngine.Debug.LogWarning(message); - } - - public static void LogError(object message) - { - UnityEngine.Debug.LogError(message); - } - - public static void LogAssertion(object message) - { - UnityEngine.Debug.LogAssertion(message); - } - - public static void LogException(Exception exception) - { - UnityEngine.Debug.LogException(exception); - } - } -} diff --git a/Assets/Xsolla/Core/Utils/DeviceIdUtil.cs b/Assets/Xsolla/Core/Utils/DeviceIdUtil.cs deleted file mode 100644 index 9a4fe3998..000000000 --- a/Assets/Xsolla/Core/Utils/DeviceIdUtil.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using UnityEngine; - -namespace Xsolla.Core -{ - public static class DeviceIdUtil - { - public static Exception GetDeviceInfo(DeviceType deviceType, out string deviceId, out string deviceName, out string deviceModel) - { - deviceName = SystemInfo.deviceName; - deviceModel = SystemInfo.deviceModel; - var exception = GetDeviceID(deviceType, out deviceId); - return exception; - } - /// - /// Returns a device ID for user authentication in the format required by the Xsolla API. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). - public static Exception GetDeviceID(DeviceType deviceType, out string deviceID) - { - deviceID = default(string); - Exception exception = null; -#if UNITY_ANDROID - try - { - AndroidJavaClass player = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); - AndroidJavaObject currentActivity = player.GetStatic("currentActivity"); - AndroidJavaObject contentResolver = currentActivity.Call("getContentResolver"); - AndroidJavaClass secure = new AndroidJavaClass("android.provider.Settings$Secure"); - deviceID = secure.CallStatic("getString", contentResolver, "android_id"); - } - catch (Exception ex) - { - Debug.LogError(ex.Message); - exception = ex; - } -#else - deviceID = SystemInfo.deviceUniqueIdentifier; -#endif - return exception; - } - } -} diff --git a/Assets/Xsolla/Core/Utils/EnvironmentDefiner.cs b/Assets/Xsolla/Core/Utils/EnvironmentDefiner.cs deleted file mode 100644 index d71ca44f2..000000000 --- a/Assets/Xsolla/Core/Utils/EnvironmentDefiner.cs +++ /dev/null @@ -1,43 +0,0 @@ -using UnityEngine; - -namespace Xsolla.Core -{ - public static class EnvironmentDefiner - { - public static bool IsEditor - { - get - { - switch (Application.platform) - { - case RuntimePlatform.LinuxEditor: - case RuntimePlatform.OSXEditor: - case RuntimePlatform.WindowsEditor: - return true; - default: - return false; - } - } - } - - public static bool IsStandalone - { - get - { - switch (Application.platform) - { - case RuntimePlatform.LinuxPlayer: - case RuntimePlatform.OSXPlayer: - case RuntimePlatform.WindowsPlayer: - return true; - default: - return false; - } - } - } - - public static bool IsStandaloneOrEditor => (IsStandalone || IsEditor); - public static bool IsAndroid => Application.platform == RuntimePlatform.Android; - public static bool IsWebGL => Application.platform == RuntimePlatform.WebGLPlayer; - } -} diff --git a/Assets/Xsolla/Core/Utils/EnvironmentDefiner.cs.meta b/Assets/Xsolla/Core/Utils/EnvironmentDefiner.cs.meta deleted file mode 100644 index 6fc83f160..000000000 --- a/Assets/Xsolla/Core/Utils/EnvironmentDefiner.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3a33480dbca943644bc9126d688665a9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/ImageLoader.cs b/Assets/Xsolla/Core/Utils/ImageLoader.cs new file mode 100644 index 000000000..375ba661e --- /dev/null +++ b/Assets/Xsolla/Core/Utils/ImageLoader.cs @@ -0,0 +1,42 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; +using System; + +namespace Xsolla.Core +{ + public static class ImageLoader + { + private static readonly Dictionary Sprites = new Dictionary(); + + public static void LoadSprite(string url, Action callback) + { + if (string.IsNullOrEmpty(url)) + throw new ArgumentNullException(nameof(url)); + + if (Sprites.ContainsKey(url) && Sprites[url] != null) + { + callback?.Invoke(Sprites[url]); + return; + } + + if (!Sprites.ContainsKey(url)) + { + Sprites[url] = null; + + WebRequestHelper.Instance.ImageRequest( + url, + sprite => Sprites[url] = sprite, + error => XDebug.LogError(error.errorMessage)); + } + + CoroutinesExecutor.Run(WaitSprite(url, callback)); + } + + private static IEnumerator WaitSprite(string url, Action callback) + { + yield return new WaitUntil(() => Sprites[url] != null); + callback?.Invoke(Sprites[url]); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/ImageLoader/ImageLoader.cs.meta b/Assets/Xsolla/Core/Utils/ImageLoader.cs.meta similarity index 100% rename from Assets/Xsolla/Core/ImageLoader/ImageLoader.cs.meta rename to Assets/Xsolla/Core/Utils/ImageLoader.cs.meta diff --git a/Assets/Xsolla/Core/Utils/OnMainThreadExecutor.cs b/Assets/Xsolla/Core/Utils/MainThreadExecutor.cs similarity index 88% rename from Assets/Xsolla/Core/Utils/OnMainThreadExecutor.cs rename to Assets/Xsolla/Core/Utils/MainThreadExecutor.cs index f1154450f..fd36aa2ef 100644 --- a/Assets/Xsolla/Core/Utils/OnMainThreadExecutor.cs +++ b/Assets/Xsolla/Core/Utils/MainThreadExecutor.cs @@ -4,7 +4,7 @@ namespace Xsolla.Core { - public class OnMainThreadExecutor : MonoBehaviour + internal class MainThreadExecutor : MonoBehaviour { private readonly ConcurrentQueue actions = new ConcurrentQueue(); diff --git a/Assets/Xsolla/Core/Utils/OnMainThreadExecutor.cs.meta b/Assets/Xsolla/Core/Utils/MainThreadExecutor.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Utils/OnMainThreadExecutor.cs.meta rename to Assets/Xsolla/Core/Utils/MainThreadExecutor.cs.meta diff --git a/Assets/Xsolla/Core/Utils/ParseUtils.cs b/Assets/Xsolla/Core/Utils/ParseUtils.cs index 70d6f7b10..064606a0d 100644 --- a/Assets/Xsolla/Core/Utils/ParseUtils.cs +++ b/Assets/Xsolla/Core/Utils/ParseUtils.cs @@ -1,32 +1,44 @@ using System; using System.Text.RegularExpressions; -using JetBrains.Annotations; using Newtonsoft.Json; +using UnityEngine; namespace Xsolla.Core { public static class ParseUtils { - [PublicAPI] - public static T FromJson(string json) where T : class + private static readonly JsonSerializerSettings serializerSettings; + + static ParseUtils() + { + serializerSettings = new JsonSerializerSettings { + NullValueHandling = NullValueHandling.Ignore + }; + } + + public static string ToJson(TData data) where TData : class { - T result = default; + return JsonConvert.SerializeObject(data, serializerSettings); + } + + public static TData FromJson(string json) where TData : class + { + TData result; try { - result = JsonConvert.DeserializeObject(json); + result = JsonConvert.DeserializeObject(json, serializerSettings); } - catch (Exception ex) + catch (Exception) { - Debug.LogWarning($"Deserialization failed for {typeof(T)}"); - Debug.LogException(ex); + XDebug.LogWarning($"Deserialization failed for {typeof(TData)}"); result = null; } - + return result; } - - public static Error ParseError(string json) + + private static Error ParseError(string json) { if (json.Contains("statusCode") && json.Contains("errorCode") && json.Contains("errorMessage")) return FromJson(json); @@ -50,9 +62,9 @@ public static bool TryParseError(string json, out Error error) error = ParseError(json); return error != null; } - catch (System.Exception ex) + catch (Exception ex) { - error = new Error(errorType: ErrorType.InvalidData, errorMessage: ex.Message); + error = new Error(ErrorType.InvalidData, errorMessage: ex.Message); return true; } } @@ -61,21 +73,24 @@ public static bool TryGetValueFromUrl(string url, ParseParameter parameter, out { var parameterName = parameter.ToString(); var regex = new Regex($"[&?]{parameterName}=[a-zA-Z0-9._+-]+"); - value = regex.Match(url)?.Value?.Replace($"{parameterName}=",string.Empty).Replace("&",string.Empty).Replace("?",string.Empty); + value = regex.Match(url) + .Value + .Replace($"{parameterName}=", string.Empty) + .Replace("&", string.Empty) + .Replace("?", string.Empty); switch (parameter) { case ParseParameter.error_code: case ParseParameter.error_description: - if (value != null) - value = value.Replace("+"," "); + value = value?.Replace("+", " "); break; default: - Debug.Log($"Trying to find {parameterName} in URL:{url}"); + XDebug.Log($"Trying to find {parameterName} in URL:{url}"); break; } return !string.IsNullOrEmpty(value); } - } -} + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/PurchaseParamsGenerator.cs b/Assets/Xsolla/Core/Utils/PurchaseParamsGenerator.cs index e13965f93..b8a9cd951 100644 --- a/Assets/Xsolla/Core/Utils/PurchaseParamsGenerator.cs +++ b/Assets/Xsolla/Core/Utils/PurchaseParamsGenerator.cs @@ -2,25 +2,24 @@ namespace Xsolla.Core { - public static class PurchaseParamsGenerator - { - public static TempPurchaseParams GenerateTempPurchaseParams(PurchaseParams purchaseParams) + internal static class PurchaseParamsGenerator + { + public static PurchaseParamsRequest GeneratePurchaseParamsRequest(PurchaseParams purchaseParams) { - var settings = new TempPurchaseParams.Settings(); + var settings = new PurchaseParamsRequest.Settings { + ui = PayStationUISettings.GenerateSettings(), + redirect_policy = RedirectPolicySettings.GeneratePolicy(), + external_id = purchaseParams?.external_id + }; - settings.ui = PayStationUISettings.GenerateSettings(); - settings.redirect_policy = RedirectPolicySettings.GeneratePolicy(); if (settings.redirect_policy != null) - { settings.return_url = settings.redirect_policy.return_url; - } //Fix 'The array value is found, but an object is required' in case of empty values. if (settings.ui == null && settings.redirect_policy == null && settings.return_url == null) settings = null; - var tempPurchaseParams = new TempPurchaseParams() - { + var requestData = new PurchaseParamsRequest { sandbox = XsollaSettings.IsSandbox, settings = settings, custom_parameters = purchaseParams?.custom_parameters, @@ -28,35 +27,28 @@ public static TempPurchaseParams GenerateTempPurchaseParams(PurchaseParams purch locale = purchaseParams?.locale, quantity = purchaseParams?.quantity, shipping_data = purchaseParams?.shipping_data, - shipping_method = purchaseParams?.shipping_method, + shipping_method = purchaseParams?.shipping_method }; - return tempPurchaseParams; + return requestData; } - /// - /// Returns headers list such as AuthHeader and SteamPaymentHeader. - /// - /// Auth token taken from Xsolla Login. - /// Custom headers for web request. - /// - public static List GetPaymentHeaders(Token token, Dictionary customHeaders = null) + public static List GeneratePaymentHeaders(Dictionary customHeaders = null) { - var headers = new List - { - WebRequestHeader.AuthHeader(token) + var headers = new List { + WebRequestHeader.AuthHeader() }; - if (customHeaders != null) + if (customHeaders == null) + return headers; + + foreach (var kvp in customHeaders) { - foreach (var kvp in customHeaders) - { - if (!string.IsNullOrEmpty(kvp.Key) && !string.IsNullOrEmpty(kvp.Value)) - headers.Add(new WebRequestHeader(kvp.Key, kvp.Value)); - } + if (!string.IsNullOrEmpty(kvp.Key) && !string.IsNullOrEmpty(kvp.Value)) + headers.Add(new WebRequestHeader(kvp.Key, kvp.Value)); } return headers; } - } -} + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/RedirectUrlHelper.cs b/Assets/Xsolla/Core/Utils/RedirectUrlHelper.cs new file mode 100644 index 000000000..dd88b881d --- /dev/null +++ b/Assets/Xsolla/Core/Utils/RedirectUrlHelper.cs @@ -0,0 +1,37 @@ +using UnityEngine; + +namespace Xsolla.Core +{ + internal static class RedirectUrlHelper + { + public static string GetRedirectUrl(string redirectUri) + { + if (!string.IsNullOrEmpty(redirectUri)) + return redirectUri; + + return !string.IsNullOrEmpty(XsollaSettings.CallbackUrl) + ? XsollaSettings.CallbackUrl + : Constants.DEFAULT_REDIRECT_URL; + } + + public static string GetAuthDeepLinkUrl() + { + return string.IsNullOrEmpty(XsollaSettings.CallbackUrl) + ? $"app://xlogin.{Application.identifier}" + : XsollaSettings.CallbackUrl; + } + + public static string GetPaymentDeepLinkUrl(RedirectPolicySettings redirectPolicy) + { + var defaultUrl = $"app://xpayment.{Application.identifier}"; + + if (redirectPolicy.UseSettingsFromPublisherAccount) + return defaultUrl; + + var customUrl = redirectPolicy.ReturnUrl; + return string.IsNullOrEmpty(customUrl) + ? defaultUrl + : customUrl; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/RedirectUtils.cs.meta b/Assets/Xsolla/Core/Utils/RedirectUrlHelper.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Utils/RedirectUtils.cs.meta rename to Assets/Xsolla/Core/Utils/RedirectUrlHelper.cs.meta diff --git a/Assets/Xsolla/Core/Utils/RedirectUtils.cs b/Assets/Xsolla/Core/Utils/RedirectUtils.cs deleted file mode 100644 index e35f73321..000000000 --- a/Assets/Xsolla/Core/Utils/RedirectUtils.cs +++ /dev/null @@ -1,21 +0,0 @@ -namespace Xsolla.Core -{ - public static class RedirectUtils - { - public static string GetRedirectUrl() - { - if (!string.IsNullOrEmpty(XsollaSettings.CallbackUrl)) - return XsollaSettings.CallbackUrl; - else - return Constants.DEFAULT_REDIRECT_URL; - } - - public static string GetRedirectUrl(string redirectArg) - { - if (!string.IsNullOrEmpty(redirectArg)) - return redirectArg; - else - return GetRedirectUrl(); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/RegionalCurrency.cs b/Assets/Xsolla/Core/Utils/RegionalCurrency.cs deleted file mode 100644 index 2539703dc..000000000 --- a/Assets/Xsolla/Core/Utils/RegionalCurrency.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using UnityEngine; - -namespace Xsolla.Core -{ - public static class RegionalCurrency - { - class CurrencyProperties - { - public string Symbol { get; set; } - public string Code { get; set; } - } - - static readonly Dictionary Currencies = - new Dictionary() - { - {SystemLanguage.Chinese, new CurrencyProperties {Symbol = "元", Code = "CNY"}}, - {SystemLanguage.English, new CurrencyProperties {Symbol = "$", Code = "USD"}}, - {SystemLanguage.French, new CurrencyProperties {Symbol = "€", Code = "EUR"}}, - {SystemLanguage.German, new CurrencyProperties {Symbol = "€", Code = "EUR"}}, - {SystemLanguage.Korean, new CurrencyProperties {Symbol = "₩", Code = "KRW"}}, - {SystemLanguage.Portuguese, new CurrencyProperties {Symbol = "R$", Code = "BRL"}}, - {SystemLanguage.Russian, new CurrencyProperties {Symbol = "₽", Code = "RUB"}}, - {SystemLanguage.Spanish, new CurrencyProperties {Symbol = "€", Code = "EUR"}}, - {SystemLanguage.Unknown, new CurrencyProperties {Symbol = "$", Code = "USD"}} - }; - - public static string CurrencyCode - { - get - { - if (Currencies.ContainsKey(Application.systemLanguage)) - { - return Currencies[Application.systemLanguage].Code; - } - - return Currencies[SystemLanguage.Unknown].Code; - } - } - - public static string CurrencySymbol - { - get - { - if (Currencies.ContainsKey(Application.systemLanguage)) - { - return Currencies[Application.systemLanguage].Symbol; - } - - return Currencies[SystemLanguage.Unknown].Symbol; - } - } - - public static string GetCurrencySymbol(string code) - { - if (Currencies.Any(c => c.Value.Code == code)) - { - return Currencies.First(c => c.Value.Code == code).Value.Symbol; - } - - return string.Empty; - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/RegionalCurrency.cs.meta b/Assets/Xsolla/Core/Utils/RegionalCurrency.cs.meta deleted file mode 100644 index 27f531f58..000000000 --- a/Assets/Xsolla/Core/Utils/RegionalCurrency.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: dc342cb81b8350442abae700be909429 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/RotateCircle.cs.meta b/Assets/Xsolla/Core/Utils/RotateCircle.cs.meta deleted file mode 100644 index fff3d101b..000000000 --- a/Assets/Xsolla/Core/Utils/RotateCircle.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ace5b50f1146743be9dd1382d9335217 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/Utils/UrlBuilder.cs b/Assets/Xsolla/Core/Utils/UrlBuilder.cs new file mode 100644 index 000000000..ba6334c7d --- /dev/null +++ b/Assets/Xsolla/Core/Utils/UrlBuilder.cs @@ -0,0 +1,138 @@ +using System.Text; + +namespace Xsolla.Core +{ + internal class UrlBuilder + { + private readonly StringBuilder builder; + private bool isFirstParamPassed; + + private string Separator + { + get + { + if (isFirstParamPassed) + return "&"; + + isFirstParamPassed = true; + return "?"; + } + } + + public UrlBuilder(string url) + { + builder = new StringBuilder(url); + isFirstParamPassed = url.Contains("?"); + } + + public string Build() + { + return builder.ToString(); + } + + public UrlBuilder AddState(string value) + { + return AddParam("state", value); + } + + public UrlBuilder AddRedirectUri(string value) + { + return AddParam("redirect_uri", value); + } + + public UrlBuilder AddClientId(int value) + { + return AddParam("client_id", value.ToString()); + } + + public UrlBuilder AddProjectId(string value) + { + return AddParam("projectId", value); + } + + public UrlBuilder AddResponseType(string value) + { + return AddParam("response_type", value); + } + + public UrlBuilder AddScope(string value) + { + return AddParam("scope", value); + } + + public UrlBuilder AddLimit(int? value) + { + return AddParam("limit", value?.ToString()); + } + + public UrlBuilder AddOffset(int? value) + { + return AddParam("offset", value?.ToString()); + } + + public UrlBuilder AddLocale(string value) + { + return AddParam("locale", value); + } + + public UrlBuilder AddCurrency(string value) + { + return AddParam("currency", value); + } + + public UrlBuilder AddPlatform(string value) + { + return AddParam("platform", value); + } + + public UrlBuilder AddCountry(string value) + { + return AddParam("country", value); + } + + public UrlBuilder AddAdditionalFields(string value) + { + return AddParamAsArray("additional_fields", value); + } + + public UrlBuilder AddArray(string name, T[] values) + { + if (string.IsNullOrEmpty(name)) + return this; + + if (values == null || values.Length == 0) + return this; + + foreach (var value in values) + { + AddParamAsArray(name, value?.ToString()); + } + + return this; + } + + public UrlBuilder AddParam(string name, string value) + { + if (string.IsNullOrWhiteSpace(value)) + return this; + + builder.Append($"{Separator}{name}={value}"); + return this; + } + + public UrlBuilder AddParam(string name, int value) + { + builder.Append($"{Separator}{name}={value}"); + return this; + } + + private UrlBuilder AddParamAsArray(string name, string value) + { + if (string.IsNullOrWhiteSpace(value)) + return this; + + builder.Append($"{Separator}{name}[]={value}"); + return this; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/UrlBuilder.cs.meta b/Assets/Xsolla/Core/Utils/UrlBuilder.cs.meta new file mode 100644 index 000000000..25b902310 --- /dev/null +++ b/Assets/Xsolla/Core/Utils/UrlBuilder.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c40574ad2fd147888569c2425dbe7404 +timeCreated: 1681898642 \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/UrlParameterizer.cs b/Assets/Xsolla/Core/Utils/UrlParameterizer.cs deleted file mode 100644 index 9cadbd93d..000000000 --- a/Assets/Xsolla/Core/Utils/UrlParameterizer.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System.Text; - -namespace Xsolla.Core -{ - public static class UrlParameterizer - { - public static string GetLimitUrlParam(int? limit) - { - if (limit.HasValue) - return $"&limit={limit.Value}"; - else - return string.Empty; - } - - public static string GetOffsetUrlParam(int? offset) - { - if (offset.HasValue) - return $"&offset={offset}"; - else - return string.Empty; - } - - public static string GetLocaleUrlParam(string locale) - { - if (!string.IsNullOrEmpty(locale)) - return $"&locale={locale}"; - else - return string.Empty; - } - - public static string GetCurrencyUrlParam(string currency) - { - if (!string.IsNullOrEmpty(currency)) - return $"¤cy={currency}"; - else - return string.Empty; - } - - public static string GetPlatformUrlParam(string platform) - { - if (string.IsNullOrEmpty(platform)) - return string.Empty; - - return $"&platform={platform}"; - } - - public static string GetAdditionalFieldsParam(string additionalFields) - { - if (!string.IsNullOrEmpty(additionalFields)) - return $"&additional_fields[]={additionalFields}"; - else - return string.Empty; - } - - public static string GetCountryUrlParam(string country) - { - if (!string.IsNullOrEmpty(country)) - return $"&country={country}"; - else - return string.Empty; - } - - public static string ConcatUrlAndParams(string url, params string[] parameters) - { - var isQuestionMarkRequired = !url.Contains("?"); - var isFirstParamPassed = false; - var builder = new StringBuilder(url); - - foreach (var param in parameters) - { - if (string.IsNullOrEmpty(param)) - continue; - - if (isQuestionMarkRequired && !isFirstParamPassed) - { - isFirstParamPassed = true; - builder.Append(param.Replace("&", "?")); - } - else - { - builder.Append(param); - } - } - - return builder.ToString(); - } - - public static string ConcatUrlAndParams(string url, string key, T[] parameters) - { - if (string.IsNullOrEmpty(key)) - return url; - - if (parameters == null || parameters.Length == 0) - return url; - - var isQuestionMarkRequired = !url.Contains("?"); - var builder = new StringBuilder(url); - - foreach (var param in parameters) - { - var stringParam = param?.ToString(); - if (string.IsNullOrEmpty(stringParam)) - continue; - - var kvp = $"{key}[]={stringParam}"; - if (isQuestionMarkRequired) - { - builder.Append($"?{kvp}"); - isQuestionMarkRequired = false; - } - else - { - builder.Append($"&{kvp}"); - } - } - - return builder.ToString(); - } - - public static string ConcatUrlAndParams - (string url, - int? limit = null, - int? offset = null, - string locale = null, - string currency = null, - string platform = null, - string additionalFields = null, - string country = null) - { - var parameters = new string[] - { - GetLimitUrlParam(limit), - GetOffsetUrlParam(offset), - GetLocaleUrlParam(locale), - GetCurrencyUrlParam(currency), - (!string.IsNullOrEmpty(platform) ? GetPlatformUrlParam(platform) : string.Empty), - GetAdditionalFieldsParam(additionalFields), - GetCountryUrlParam(country) - }; - - return ConcatUrlAndParams(url, parameters); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Utils/UrlParameterizer.cs.meta b/Assets/Xsolla/Core/Utils/UrlParameterizer.cs.meta deleted file mode 100644 index 5dbd40acd..000000000 --- a/Assets/Xsolla/Core/Utils/UrlParameterizer.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a7e89377d4183c643ba85e86d51c47d2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Core/WebGL.meta b/Assets/Xsolla/Core/WebGL.meta new file mode 100644 index 000000000..d23e20992 --- /dev/null +++ b/Assets/Xsolla/Core/WebGL.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1a996f2c54eb4a3ba9f5f5f99673bc0d +timeCreated: 1683260769 \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebGL/XsollaWebCallbacks.cs b/Assets/Xsolla/Core/WebGL/XsollaWebCallbacks.cs new file mode 100644 index 000000000..a401ba6e8 --- /dev/null +++ b/Assets/Xsolla/Core/WebGL/XsollaWebCallbacks.cs @@ -0,0 +1,56 @@ +using System; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class XsollaWebCallbacks : MonoBehaviour + { + private event Action OnPaymentStatusUpdate; + private event Action OnPaymentCancel; + + // Callback for Xsolla Pay Station (do not remove) + public void PublishPaymentStatusUpdate() + { + OnPaymentStatusUpdate?.Invoke(); + } + + // Callback for Xsolla Pay Station (do not remove) + public void PublishPaymentCancel() + { + OnPaymentCancel?.Invoke(); + } + + public static void AddPaymentStatusUpdateHandler(Action action) + { + Instance.OnPaymentStatusUpdate += action; + } + + public static void RemovePaymentStatusUpdateHandler(Action action) + { + Instance.OnPaymentStatusUpdate -= action; + } + + public static void AddPaymentCancelHandler(Action action) + { + Instance.OnPaymentCancel += action; + } + + public static void RemovePaymentCancelHandler(Action action) + { + Instance.OnPaymentCancel -= action; + } + + private static XsollaWebCallbacks _instance; + + private static XsollaWebCallbacks Instance + { + get + { + if (!_instance) + _instance = new GameObject("XsollaWebCallbacks").AddComponent(); + + return _instance; + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/WebGL/XsollaWebCallbacks.cs.meta b/Assets/Xsolla/Core/WebGL/XsollaWebCallbacks.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/WebGL/XsollaWebCallbacks.cs.meta rename to Assets/Xsolla/Core/WebGL/XsollaWebCallbacks.cs.meta diff --git a/Assets/Xsolla/Core/WebRequestHelper/SdkType.cs b/Assets/Xsolla/Core/WebRequestHelper/SdkType.cs deleted file mode 100644 index c2ba52512..000000000 --- a/Assets/Xsolla/Core/WebRequestHelper/SdkType.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Xsolla.Core -{ - public enum SdkType - { - None, Login, Store, Subscriptions, SettingsFillTool - } -} diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHeader.cs b/Assets/Xsolla/Core/WebRequestHelper/WebRequestHeader.cs deleted file mode 100644 index 140244ebf..000000000 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHeader.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace Xsolla.Core -{ - public class WebRequestHeader - { - public string Name { get; set; } - public string Value { get; set; } - - public WebRequestHeader() - {} - - public WebRequestHeader(string name, string value) - { - Name = name; - Value = value; - } - - public static WebRequestHeader AuthHeader(string bearerTokenValue) - { - return new WebRequestHeader {Name = "Authorization", Value = string.Format("Bearer {0}", bearerTokenValue)}; - } - - public static WebRequestHeader AuthBasic(string basicTokenValue) - { - return new WebRequestHeader {Name = "Authorization", Value = string.Format("Basic {0}", basicTokenValue)}; - } - - public static WebRequestHeader ContentTypeHeader() - { - return new WebRequestHeader {Name = "Content-Type", Value = "application/json"}; - } - - public static WebRequestHeader AcceptHeader() - { - return new WebRequestHeader {Name = "Accept", Value = "application/json"}; - } - } -} diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.DELETE.cs b/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.DELETE.cs deleted file mode 100644 index 56731010c..000000000 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.DELETE.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine.Networking; - -namespace Xsolla.Core -{ - public partial class WebRequestHelper : MonoSingleton - { - public void DeleteRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) - { - var requestHeaders = AppendAnalyticHeaders(sdkType, requestHeader); - StartCoroutine(DeleteRequestCor(sdkType, url, requestHeaders, onComplete, onError, errorsToCheck)); - } - - public void DeleteRequest(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) - { - requestHeaders = AppendAnalyticHeaders(sdkType, requestHeaders); - StartCoroutine(DeleteRequestCor(sdkType, url, requestHeaders, onComplete, onError, errorsToCheck)); - } - - IEnumerator DeleteRequestCor(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) - { - url = AppendAnalyticsToUrl(sdkType, url); - - var webRequest = UnityWebRequest.Delete(url); - webRequest.downloadHandler = new DownloadHandlerBuffer(); - AttachHeadersToRequest(webRequest, requestHeaders); - - yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); - } - } -} - diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.GET.cs b/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.GET.cs deleted file mode 100644 index 382d639e2..000000000 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.GET.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine.Networking; - -namespace Xsolla.Core -{ - public partial class WebRequestHelper : MonoSingleton - { - public void GetRequest(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class - { - var headers = AppendAnalyticHeaders(sdkType, requestHeaders); - StartCoroutine(GetRequestCor(sdkType, url, headers, onComplete, onError, errorsToCheck)); - } - - public void GetRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class - { - var headers = AppendAnalyticHeaders(sdkType, requestHeader); - StartCoroutine(GetRequestCor(sdkType, url, headers, onComplete, onError, errorsToCheck)); - } - - public void GetRequest(SdkType sdkType, string url, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class - { - var headers = GetAnalyticHeaders(sdkType); - StartCoroutine(GetRequestCor(sdkType, url, headers, onComplete, onError, errorsToCheck)); - } - - public void GetRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) - { - var headers = AppendAnalyticHeaders(sdkType, requestHeader); - StartCoroutine(GetRequestCor(sdkType, url, headers, onComplete, onError, errorsToCheck)); - } - - private IEnumerator GetRequestCor(SdkType sdkType, string url, List requestHeaders = null, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class - { - url = AppendAnalyticsToUrl(sdkType, url); - - var webRequest = UnityWebRequest.Get(url); - AttachHeadersToRequest(webRequest, requestHeaders); - - yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); - } - - private IEnumerator GetRequestCor(SdkType sdkType, string url, List requestHeaders = null, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) - { - url = AppendAnalyticsToUrl(sdkType, url); - - var webRequest = UnityWebRequest.Get(url); - AttachHeadersToRequest(webRequest, requestHeaders); - - yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); - } - } -} diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Image.cs b/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Image.cs deleted file mode 100644 index b1844b50b..000000000 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Image.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using System.Collections; -using UnityEngine; -using UnityEngine.Networking; - -namespace Xsolla.Core -{ - public partial class WebRequestHelper : MonoSingleton - { - public void ImageRequest(string url, Action onComplete = null, Action onError = null) - { - StartCoroutine(ImageRequestCoroutine(url, onComplete, onError)); - } - - public void ImageRequest(string url, Action onComplete = null, Action onError = null) - { - StartCoroutine(ImageRequestCoroutine(url, onComplete, onError)); - } - - private IEnumerator ImageRequestCoroutine(string url, Action onComplete = null, Action onError = null) - { - var webRequest = UnityWebRequestTexture.GetTexture(url); - yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError)); - } - - private IEnumerator ImageRequestCoroutine(string url, Action onComplete = null, Action onError = null) - { - yield return ImageRequestCoroutine(url, texture2D => - { - Rect spriteRect = new Rect(0, 0, texture2D.width, texture2D.height); - Vector2 pivot = new Vector2(0.5f, 0.5f); - Sprite sprite = Sprite.Create(texture2D, spriteRect, pivot); - onComplete?.Invoke(sprite); - }, onError); - } - } -} - diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PATCH.cs b/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PATCH.cs deleted file mode 100644 index bad0e448d..000000000 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PATCH.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine.Networking; - -namespace Xsolla.Core -{ - public partial class WebRequestHelper : MonoSingleton - { - public void PatchRequest(SdkType sdkType, string url, D jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class - { - var headers = AppendAnalyticHeaders(sdkType, requestHeaders); - StartCoroutine(PatchRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); - } - - public void PatchRequest(SdkType sdkType, string url, D jsonObject, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class - { - var headers = AppendAnalyticHeaders(sdkType, requestHeader); - StartCoroutine(PatchRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); - } - - public void PatchRequest(SdkType sdkType, string url, D jsonObject, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class - { - var headers = GetAnalyticHeaders(sdkType); - StartCoroutine(PatchRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); - } - - IEnumerator PatchRequestCor(SdkType sdkType, string url, D jsonObject, List requestHeaders = null, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class - { - url = AppendAnalyticsToUrl(sdkType, url); - - UnityWebRequest webRequest = new UnityWebRequest(url, "PATCH"); - webRequest.downloadHandler = new DownloadHandlerBuffer(); - AttachBodyToRequest(webRequest, jsonObject); - AttachHeadersToPatchRequest(webRequest, requestHeaders); - - yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); - } - - private void AttachHeadersToPatchRequest(UnityWebRequest webRequest, List requestHeaders, bool withContentType = true) - { - if (withContentType) - { - if (requestHeaders != null) - requestHeaders.Add(WebRequestHeader.ContentTypeHeader()); - else - requestHeaders = new List() {WebRequestHeader.ContentTypeHeader()}; - } - - AttachHeadersToRequest(webRequest, requestHeaders); - } - } -} diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.ProcessRequest.cs b/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.ProcessRequest.cs deleted file mode 100644 index b195fe01e..000000000 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.ProcessRequest.cs +++ /dev/null @@ -1,155 +0,0 @@ -using System; -using UnityEngine; -using UnityEngine.Networking; - -namespace Xsolla.Core -{ - public partial class WebRequestHelper : MonoSingleton - { - /// - /// Processing request and invoke no data callback on success - /// - /// - /// - /// - /// - private void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorCheckType errorsToCheck) - { - if (CheckNoErrors(webRequest, errorsToCheck, out var error)) - onComplete?.Invoke(); - else - onError?.Invoke(error); - - webRequest.Dispose(); - } - - /// - /// Processing request and invoke response code callback on success - /// - /// - /// - /// - /// - private void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorCheckType errorsToCheck) - { - if (CheckNoErrors(webRequest, errorsToCheck, out var error)) - onComplete?.Invoke((int)webRequest.responseCode); - else - onError?.Invoke(error); - - webRequest.Dispose(); - } - - /// - /// Processing request and invoke raw data (Action) callback on success - /// - /// - /// - /// - /// - private void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorCheckType errorsToCheck) - { - if (CheckNoErrors(webRequest, errorsToCheck, out var error)) - { - string data = webRequest.downloadHandler.text; - if (data != null) - onComplete?.Invoke(data); - else - onError?.Invoke(Error.UnknownError); - } - else - onError?.Invoke(error); - - webRequest.Dispose(); - } - - /// - /// Processing request and invoke Texture2D (Action) callback on success - /// - /// - /// - /// - private void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError) - { - if (CheckNoErrors(webRequest, ErrorCheckType.CommonErrors, out var error, log: false)) - { - var texture = ((DownloadHandlerTexture)webRequest.downloadHandler).texture; - if (texture != null) - onComplete?.Invoke(texture); - else - onError?.Invoke(Error.UnknownError); - } - else - onError?.Invoke(error); - - webRequest.Dispose(); - } - - /// - /// Processing request and invoke Action callback by success - /// - /// - /// - /// - /// - /// - private void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorCheckType errorsToCheck) where T : class - { - if (CheckNoErrors(webRequest, errorsToCheck, out var error)) - { - var rawData = webRequest.downloadHandler.text; - var data = (rawData != null) ? ParseUtils.FromJson(rawData) : null; - if (data != null) - onComplete?.Invoke(data); - else - onError?.Invoke(Error.UnknownError); - } - else - onError?.Invoke(error); - - webRequest.Dispose(); - } - - public static bool CheckNoErrors(UnityWebRequest webRequest, ErrorCheckType errorsToCheck, out Error error, bool log = true) - { -#if UNITY_2020_1_OR_NEWER - var isNetworkError = webRequest.result == UnityWebRequest.Result.ConnectionError; - var isHttpError = webRequest.result == UnityWebRequest.Result.ProtocolError; -#else - var isNetworkError = webRequest.isNetworkError; - var isHttpError = webRequest.isHttpError; -#endif - if (isNetworkError) - { - error = Error.NetworkError; - return false; - } - - var url = webRequest.url; - var data = webRequest.downloadHandler.text; - - if (log) - Debug.Log($"URL: {url}{Environment.NewLine}RESPONSE: {data}"); - - if (ParseUtils.TryParseError(data, out error)) - { - if (CodeToErrorType.TryGetSpecificType(error.statusCode, errorsToCheck, out var specificErrorType)) - error.ErrorType = specificErrorType; - else if (CodeToErrorType.TryGetCommonType(error.statusCode, out var commonErrorType)) - error.ErrorType = commonErrorType; - - return false; - } - else if (isHttpError) - { - error = Error.UnknownError; - return false; - } - else - { - error = null; - return true; - } - } - } -} diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.cs b/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.cs deleted file mode 100644 index 24b9d51ac..000000000 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using Newtonsoft.Json; -using UnityEngine; -using UnityEngine.Networking; - -namespace Xsolla.Core -{ - public partial class WebRequestHelper : MonoSingleton - { - private List _requests = new List(); - - public bool IsBusy() - { - return _requests.Count > 0; - } - - public void StopAll() - { - _requests.ForEach(r => r.Dispose()); - _requests.Clear(); - } - - protected override void OnDestroy() - { - StopAll(); - StopAllCoroutines(); - base.OnDestroy(); - } - - private IEnumerator InternalPerformWebRequest(UnityWebRequest webRequest, Action requestProccesAction) - { - webRequest.disposeDownloadHandlerOnDispose = true; - webRequest.disposeUploadHandlerOnDispose = true; - webRequest.disposeCertificateHandlerOnDispose = true; - _requests.Add(webRequest); - - yield return StartCoroutine(SendWebRequest(webRequest)); - requestProccesAction?.Invoke(); - - _requests.Remove(webRequest); - } - - private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorCheckType errorsToCheck) - { - yield return InternalPerformWebRequest(webRequest, - () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); - } - - private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorCheckType errorsToCheck) - { - yield return InternalPerformWebRequest(webRequest, - () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); - } - - private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorCheckType errorsToCheck) - { - yield return InternalPerformWebRequest(webRequest, - () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); - } - - private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorCheckType errorsToCheck) where T : class - { - yield return InternalPerformWebRequest(webRequest, - () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); - } - - private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError) - { - yield return InternalPerformWebRequest(webRequest, - () => ProcessRequest(webRequest, onComplete, onError)); - } - - private IEnumerator SendWebRequest(UnityWebRequest webRequest) - { -#if UNITY_2018_1_OR_NEWER - yield return webRequest.SendWebRequest(); -#else - yield return webRequest.Send(); -#endif - } - - public void AttachHeadersToRequest(UnityWebRequest webRequest, List requestHeaders) - { - if (requestHeaders != null) - foreach (var header in requestHeaders) - if (header != null) - webRequest.SetRequestHeader(header.Name, header.Value); - } - - public void AttachBodyToRequest(UnityWebRequest webRequest, object jsonObject) - { - if (jsonObject == null) - return; - - string jsonData = JsonConvert.SerializeObject(jsonObject).Replace('\n', ' '); - byte[] body = new UTF8Encoding().GetBytes(jsonData); - webRequest.uploadHandler = (UploadHandler)new UploadHandlerRaw(body); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper.meta b/Assets/Xsolla/Core/WebRequests.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper.meta rename to Assets/Xsolla/Core/WebRequests.meta diff --git a/Assets/Xsolla/Core/WebRequests/SdkType.cs b/Assets/Xsolla/Core/WebRequests/SdkType.cs new file mode 100644 index 000000000..4198328a5 --- /dev/null +++ b/Assets/Xsolla/Core/WebRequests/SdkType.cs @@ -0,0 +1,10 @@ +namespace Xsolla.Core +{ + public enum SdkType + { + Login, + Store, + Subscriptions, + SettingsFillTool + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/SdkType.cs.meta b/Assets/Xsolla/Core/WebRequests/SdkType.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/SdkType.cs.meta rename to Assets/Xsolla/Core/WebRequests/SdkType.cs.meta diff --git a/Assets/Xsolla/Core/WebRequests/WebRequestHeader.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHeader.cs new file mode 100644 index 000000000..f2da5985c --- /dev/null +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHeader.cs @@ -0,0 +1,51 @@ +namespace Xsolla.Core +{ + public class WebRequestHeader + { + public string Name { get; set; } + + public string Value { get; set; } + + public WebRequestHeader() { } + + public WebRequestHeader(string name, string value) + { + Name = name; + Value = value; + } + + public static WebRequestHeader AuthHeader() + { + var accessToken = XsollaToken.AccessToken; + return !string.IsNullOrEmpty(accessToken) + ? AuthHeader(accessToken) + : null; + } + + public static WebRequestHeader AuthHeader(string token) + { + var header = new WebRequestHeader { + Name = "Authorization", + Value = $"Bearer {token}" + }; + + return header; + } + + public static WebRequestHeader JsonContentTypeHeader() + { + return new WebRequestHeader { + Name = "Content-Type", + Value = "application/json" + }; + } + + public static WebRequestHeader FormDataContentTypeHeader(string boundary) + { + return new WebRequestHeader { + Name = "Content-type", + Value = $"multipart/form-data; boundary ={boundary}" + }; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHeader.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHeader.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHeader.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHeader.cs.meta diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Analytics.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.Analytics.cs similarity index 70% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Analytics.cs rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.Analytics.cs index 33852ca48..ae4cd9f4a 100644 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Analytics.cs +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.Analytics.cs @@ -6,12 +6,12 @@ namespace Xsolla.Core { - public partial class WebRequestHelper : MonoSingleton + public partial class WebRequestHelper { private const string ANALYTICS_URL_TEMPLATE = "engine=unity&engine_v={0}&sdk={1}&sdk_v={2}&build_platform={3}{4}"; //Uncomment and fill the values if you want to hardcode referral info - private KeyValuePair? _referralAnalytics/* = new KeyValuePair("MyReferralPlugin", "0.0.1")*/; + private KeyValuePair? _referralAnalytics /* = new KeyValuePair("MyReferralPlugin", "0.0.1")*/; public void SetReferralAnalytics(string referralPlugin, string referralVersion) { @@ -20,19 +20,13 @@ public void SetReferralAnalytics(string referralPlugin, string referralVersion) public string AppendAnalyticsToUrl(SdkType analyticsType, string url) { - if (analyticsType == SdkType.None) - { - Debug.LogWarning("Attempt to add analytics without providing analyticsType parameter"); - return url; - } - var dividingSymbol = url.Contains("?") ? "&" : "?"; GetUnityParameters(toUpper: false, out string engineVersion, out string buildPlatform); GetXsollaSdkParameters(analyticsType, toUpper: false, out string sdkType, out string sdkVersion); var referralAnalytics = default(string); - if (_referralAnalytics.HasValue)//if (_referralAnalytics != null) + if (_referralAnalytics.HasValue) //if (_referralAnalytics != null) { string referralPlugin = _referralAnalytics.Value.Key; string referralVersion = _referralAnalytics.Value.Value; @@ -41,18 +35,12 @@ public string AppendAnalyticsToUrl(SdkType analyticsType, string url) var analyticsAddition = string.Format(ANALYTICS_URL_TEMPLATE, engineVersion, sdkType, sdkVersion, buildPlatform, referralAnalytics); - var result = $"{url}{dividingSymbol}{analyticsAddition}"; + var result = $"{url}{dividingSymbol}{analyticsAddition}"; return result; } public List AppendAnalyticHeaders(SdkType analyticsType, List headers) { - if (analyticsType == SdkType.None) - { - Debug.LogWarning("Attempt to add analytics without providing analyticsType parameter"); - return headers; - } - var analyticHeaders = GetAnalyticHeaders(analyticsType); var result = default(List); @@ -71,18 +59,12 @@ public List AppendAnalyticHeaders(SdkType analyticsType, List< public List AppendAnalyticHeaders(SdkType analyticsType, WebRequestHeader header) { - if (analyticsType == SdkType.None) - { - Debug.LogWarning("Attempt to add analytics without providing analyticsType parameter"); - return new List(){header}; - } - var analyticHeaders = GetAnalyticHeaders(analyticsType); var result = default(List); if (header != null) { - result = new List(){header}; + result = new List() {header}; result.AddRange(analyticHeaders); } else @@ -104,22 +86,21 @@ private List GetAnalyticHeaders(SdkType analyticsType) GetXsollaSdkParameters(analyticsType, toUpper: true, out string sdkType, out string sdkVersion); var resultCapacity = _referralAnalytics.HasValue ? 6 : 4; - var result = new List(capacity: resultCapacity) - { - new WebRequestHeader() { Name = "X-ENGINE", Value = "UNITY" }, - new WebRequestHeader() { Name = "X-ENGINE-V", Value = engineVersion }, - new WebRequestHeader() { Name = "X-SDK", Value = sdkType }, - new WebRequestHeader() { Name = "X-SDK-V", Value = sdkVersion }, - new WebRequestHeader() { Name = "X-BUILD-PLATFORM", Value = buildPlatform } + var result = new List(capacity: resultCapacity) { + new WebRequestHeader() {Name = "X-ENGINE", Value = "UNITY"}, + new WebRequestHeader() {Name = "X-ENGINE-V", Value = engineVersion}, + new WebRequestHeader() {Name = "X-SDK", Value = sdkType}, + new WebRequestHeader() {Name = "X-SDK-V", Value = sdkVersion}, + new WebRequestHeader() {Name = "X-BUILD-PLATFORM", Value = buildPlatform} }; - if (_referralAnalytics.HasValue)//if (_referralAnalytics != null) + if (_referralAnalytics.HasValue) //if (_referralAnalytics != null) { string referralPlugin = _referralAnalytics.Value.Key; string referralVersion = _referralAnalytics.Value.Value; - result.Add( new WebRequestHeader() { Name = "X-REF", Value = referralPlugin.ToUpper() } ); - result.Add( new WebRequestHeader() { Name = "X-REF-V", Value = referralVersion.ToUpper() }); + result.Add(new WebRequestHeader() {Name = "X-REF", Value = referralPlugin.ToUpper()}); + result.Add(new WebRequestHeader() {Name = "X-REF-V", Value = referralVersion.ToUpper()}); } return result; @@ -142,15 +123,15 @@ private void GetXsollaSdkParameters(SdkType analyticsType, bool toUpper, out str sdkType = toUpper ? "SETTINGS-FILL-TOOL" : "settings-fill-tool"; break; default: - Debug.LogError($"Unexpected analyticsType: '{analyticsType}'"); + XDebug.LogError($"Unexpected analyticsType: '{analyticsType}'"); sdkType = string.Empty; break; } if (XsollaMarker.HasDemoPart) - sdkVersion = $"{Constants.SdkVersion}{(toUpper ? "_DEMO" : "_demo")}"; + sdkVersion = $"{Constants.SDK_VERSION}{(toUpper ? "_DEMO" : "_demo")}"; else - sdkVersion = Constants.SdkVersion; + sdkVersion = Constants.SDK_VERSION; } private void GetUnityParameters(bool toUpper, out string engineVersion, out string buildPlatform) diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Analytics.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.Analytics.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Analytics.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.Analytics.cs.meta diff --git a/Assets/Xsolla/Core/WebRequests/WebRequestHelper.DELETE.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.DELETE.cs new file mode 100644 index 000000000..f532db698 --- /dev/null +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.DELETE.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine.Networking; + +namespace Xsolla.Core +{ + public partial class WebRequestHelper + { + public void DeleteRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete, Action onError, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) + { + var requestHeaders = AppendAnalyticHeaders(sdkType, requestHeader); + StartCoroutine(PerformDelete(sdkType, url, requestHeaders, onComplete, onError, errorsToCheck)); + } + + private IEnumerator PerformDelete(SdkType sdkType, string url, List requestHeaders, Action onComplete, Action onError, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) + { + url = AppendAnalyticsToUrl(sdkType, url); + + var webRequest = UnityWebRequest.Delete(url); + webRequest.downloadHandler = new DownloadHandlerBuffer(); + AttachHeadersToRequest(webRequest, requestHeaders); + + yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.DELETE.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.DELETE.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.DELETE.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.DELETE.cs.meta diff --git a/Assets/Xsolla/Core/WebRequests/WebRequestHelper.GET.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.GET.cs new file mode 100644 index 000000000..7870bab34 --- /dev/null +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.GET.cs @@ -0,0 +1,54 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine.Networking; + +namespace Xsolla.Core +{ + public partial class WebRequestHelper + { + public void GetRequest(SdkType sdkType, string url, List requestHeaders, Action onComplete, Action onError, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class + { + var headers = AppendAnalyticHeaders(sdkType, requestHeaders); + StartCoroutine(PerformGet(sdkType, url, onComplete, onError, headers, errorsToCheck)); + } + + public void GetRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete, Action onError, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class + { + var headers = AppendAnalyticHeaders(sdkType, requestHeader); + StartCoroutine(PerformGet(sdkType, url, onComplete, onError, headers, errorsToCheck)); + } + + public void GetRequest(SdkType sdkType, string url, Action onComplete, Action onError, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class + { + var headers = GetAnalyticHeaders(sdkType); + StartCoroutine(PerformGet(sdkType, url, onComplete, onError, headers, errorsToCheck)); + } + + public void GetRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete, Action onError, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) + { + var headers = AppendAnalyticHeaders(sdkType, requestHeader); + StartCoroutine(PerformGet(sdkType, url, onComplete, onError, headers, errorsToCheck)); + } + + private IEnumerator PerformGet(SdkType sdkType, string url, Action onComplete, Action onError, List requestHeaders, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class + { + url = AppendAnalyticsToUrl(sdkType, url); + + var webRequest = UnityWebRequest.Get(url); + AttachHeadersToRequest(webRequest, requestHeaders); + + yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); + } + + private IEnumerator PerformGet(SdkType sdkType, string url, Action onComplete, Action onError, List requestHeaders, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) + { + url = AppendAnalyticsToUrl(sdkType, url); + + var webRequest = UnityWebRequest.Get(url); + AttachHeadersToRequest(webRequest, requestHeaders); + + yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.GET.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.GET.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.GET.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.GET.cs.meta diff --git a/Assets/Xsolla/Core/WebRequests/WebRequestHelper.Image.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.Image.cs new file mode 100644 index 000000000..b98c21bd5 --- /dev/null +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.Image.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections; +using UnityEngine; +using UnityEngine.Networking; + +namespace Xsolla.Core +{ + public partial class WebRequestHelper + { + public void ImageRequest(string url, Action onComplete, Action onError) + { + StartCoroutine(PerformImage(url, onComplete, onError)); + } + + private IEnumerator PerformImage(string url, Action onComplete, Action onError) + { + yield return PerformImage(url, texture => + { + var spriteRect = new Rect(0, 0, texture.width, texture.height); + var pivot = new Vector2(0.5f, 0.5f); + var sprite = Sprite.Create(texture, spriteRect, pivot); + onComplete?.Invoke(sprite); + }, onError); + } + + private IEnumerator PerformImage(string url, Action onComplete, Action onError) + { + var webRequest = UnityWebRequestTexture.GetTexture(url); + yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError)); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Image.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.Image.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.Image.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.Image.cs.meta diff --git a/Assets/Xsolla/Core/WebRequests/WebRequestHelper.PATCH.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.PATCH.cs new file mode 100644 index 000000000..f2c13098a --- /dev/null +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.PATCH.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using UnityEngine.Networking; + +namespace Xsolla.Core +{ + public partial class WebRequestHelper + { + public void PatchRequest(SdkType sdkType, string url, D jsonObject, WebRequestHeader requestHeader, Action onComplete, Action onError, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class + { + var headers = AppendAnalyticHeaders(sdkType, requestHeader); + StartCoroutine(PerformPatch(sdkType, url, jsonObject, onComplete, onError, headers, errorsToCheck)); + } + + private IEnumerator PerformPatch(SdkType sdkType, string url, D jsonObject, Action onComplete, Action onError, List requestHeaders = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class + { + url = AppendAnalyticsToUrl(sdkType, url); + + var webRequest = new UnityWebRequest(url, "PATCH"); + webRequest.downloadHandler = new DownloadHandlerBuffer(); + AttachBodyToRequest(webRequest, jsonObject); + AttachHeadersToPatchRequest(webRequest, requestHeaders); + + yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); + } + + private static void AttachHeadersToPatchRequest(UnityWebRequest webRequest, List requestHeaders, bool withContentType = true) + { + if (withContentType) + { + if (requestHeaders != null) + requestHeaders.Add(WebRequestHeader.JsonContentTypeHeader()); + else + requestHeaders = new List {WebRequestHeader.JsonContentTypeHeader()}; + } + + AttachHeadersToRequest(webRequest, requestHeaders); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PATCH.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.PATCH.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PATCH.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.PATCH.cs.meta diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.POST.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.POST.cs similarity index 61% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.POST.cs rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.POST.cs index eed04e85a..0933e4515 100644 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.POST.cs +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.POST.cs @@ -1,16 +1,16 @@ using System; using System.Collections; using System.Collections.Generic; -using JetBrains.Annotations; using UnityEngine; using UnityEngine.Networking; namespace Xsolla.Core { - public partial class WebRequestHelper : MonoSingleton + public partial class WebRequestHelper { #region PostRequest - public void PostRequest(SdkType sdkType, string url, D jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + + public void PostRequest(SdkType sdkType, string url, D jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class where D : class { @@ -18,7 +18,7 @@ public void PostRequest(SdkType sdkType, string url, D jsonObject, List(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, D jsonObject, [NotNull]WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, D jsonObject, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class where D : class { @@ -26,166 +26,191 @@ public void PostRequest(SdkType sdkType, string url, D jsonObject, [NotNul StartCoroutine(PostRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, D jsonObject, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, D jsonObject, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class where D : class { var headers = GetAnalyticHeaders(sdkType); StartCoroutine(PostRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } + #endregion #region PostRequest - public void PostRequest(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + + public void PostRequest(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { var headers = AppendAnalyticHeaders(sdkType, requestHeaders); StartCoroutine(PostRequestCor(sdkType, url, jsonObject: null, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { var headers = AppendAnalyticHeaders(sdkType, requestHeader); StartCoroutine(PostRequestCor(sdkType, url, jsonObject: null, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { var headers = GetAnalyticHeaders(sdkType); StartCoroutine(PostRequestCor(sdkType, url, jsonObject: null, headers, onComplete, onError, errorsToCheck)); } + #endregion #region PostRequest with jsonObject - public void PostRequest(SdkType sdkType, string url, D jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + + public void PostRequest(SdkType sdkType, string url, D jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where D : class { var headers = AppendAnalyticHeaders(sdkType, requestHeaders); StartCoroutine(PostRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, D jsonObject, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, D jsonObject, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where D : class { var headers = AppendAnalyticHeaders(sdkType, requestHeader); StartCoroutine(PostRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, D jsonObject = null, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, D jsonObject = null, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where D : class { var headers = GetAnalyticHeaders(sdkType); StartCoroutine(PostRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, D jsonObject = null, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, D jsonObject = null, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where D : class { var headers = GetAnalyticHeaders(sdkType); StartCoroutine(PostRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } + + public void PostRequest(SdkType sdkType, string url, D jsonObject = null, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) + where D : class + { + var headers = GetAnalyticHeaders(sdkType); + StartCoroutine(PostRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); + } + #endregion #region PostRequest - public void PostRequest(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + + public void PostRequest(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { var headers = AppendAnalyticHeaders(sdkType, requestHeaders); - StartCoroutine(PostRequestCor(sdkType, url, jsonObject: null, headers, onComplete, onError, errorsToCheck)); + StartCoroutine(PostRequestCor(sdkType, url, null, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { var headers = AppendAnalyticHeaders(sdkType, requestHeader); - StartCoroutine(PostRequestCor(sdkType, url, jsonObject: null, headers, onComplete, onError, errorsToCheck)); + StartCoroutine(PostRequestCor(sdkType, url, null, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { var headers = GetAnalyticHeaders(sdkType); - StartCoroutine(PostRequestCor(sdkType, url, jsonObject: null, headers, onComplete, onError, errorsToCheck)); + StartCoroutine(PostRequestCor(sdkType, url, null, headers, onComplete, onError, errorsToCheck)); } + #endregion #region PostRquest with WWWForm - public void PostRequest(SdkType sdkType, string url, WWWForm data, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + + public void PostRequest(SdkType sdkType, string url, WWWForm data, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { var headers = AppendAnalyticHeaders(sdkType, requestHeaders); StartCoroutine(PostRequestCor(sdkType, url, data, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, WWWForm data, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, WWWForm data, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { var headers = AppendAnalyticHeaders(sdkType, requestHeader); StartCoroutine(PostRequestCor(sdkType, url, data, headers, onComplete, onError, errorsToCheck)); } - public void PostRequest(SdkType sdkType, string url, WWWForm data, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostRequest(SdkType sdkType, string url, WWWForm data, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { var headers = GetAnalyticHeaders(sdkType); StartCoroutine(PostRequestCor(sdkType, url, data, headers, onComplete, onError, errorsToCheck)); } + #endregion #region PostUploadRequest - public void PostUploadRequest(SdkType sdkType, string url, string pathToFile, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) - where T: class + + public void PostUploadRequest(SdkType sdkType, string url, string pathToFile, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) + where T : class { var headers = AppendAnalyticHeaders(sdkType, requestHeaders); StartCoroutine(PostUploadRequestCor(sdkType, url, pathToFile, headers, onComplete, onError, errorsToCheck)); } - public void PostUploadRequest(SdkType sdkType, string url, byte[] fileData, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PostUploadRequest(SdkType sdkType, string url, byte[] fileData, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { var headers = AppendAnalyticHeaders(sdkType, requestHeaders); StartCoroutine(PostUploadRequestCor(sdkType, url, fileData, headers, onComplete, onError, errorsToCheck)); } + #endregion + private IEnumerator PostRequestCor(SdkType sdkType, string url, object jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) + { + url = AppendAnalyticsToUrl(sdkType, url); + var webRequest = PreparePostWebRequest(url, jsonObject, requestHeaders); + + yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); + } - IEnumerator PostRequestCor(SdkType sdkType, string url, object jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + private IEnumerator PostRequestCor(SdkType sdkType, string url, object jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { url = AppendAnalyticsToUrl(sdkType, url); - UnityWebRequest webRequest = PreparePostWebRequest(url, jsonObject, requestHeaders); + var webRequest = PreparePostWebRequest(url, jsonObject, requestHeaders); yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); } - IEnumerator PostRequestCor(SdkType sdkType, string url, object jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + private IEnumerator PostRequestCor(SdkType sdkType, string url, object jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { url = AppendAnalyticsToUrl(sdkType, url); - UnityWebRequest webRequest = PreparePostWebRequest(url, jsonObject, requestHeaders); + var webRequest = PreparePostWebRequest(url, jsonObject, requestHeaders); yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); } - IEnumerator PostRequestCor(SdkType sdkType, string url, object jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class + private IEnumerator PostRequestCor(SdkType sdkType, string url, object jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { url = AppendAnalyticsToUrl(sdkType, url); - UnityWebRequest webRequest = PreparePostWebRequest(url, jsonObject, requestHeaders); + var webRequest = PreparePostWebRequest(url, jsonObject, requestHeaders); yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); } - IEnumerator PostUploadRequestCor(SdkType sdkType, string url, string pathToFile, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class + private IEnumerator PostUploadRequestCor(SdkType sdkType, string url, string pathToFile, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { url = AppendAnalyticsToUrl(sdkType, url); - UnityWebRequest webRequest = PreparePostUploadRequest(url, pathToFile, requestHeaders); + var webRequest = PreparePostUploadRequest(url, pathToFile, requestHeaders); yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); } - IEnumerator PostUploadRequestCor(SdkType sdkType, string url, byte[] fileData, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + private IEnumerator PostUploadRequestCor(SdkType sdkType, string url, byte[] fileData, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { url = AppendAnalyticsToUrl(sdkType, url); #if UNITY_2022_2_OR_NEWER UnityWebRequest webRequest = UnityWebRequest.PostWwwForm(url, UnityWebRequest.kHttpVerbPOST); #else - UnityWebRequest webRequest = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST); + var webRequest = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST); #endif //Timeout was set to 10 seconds for the unknown reason. I've changed it to 30 because of one specific request that can take up to 10-30 seconds. @@ -193,18 +218,18 @@ IEnumerator PostUploadRequestCor(SdkType sdkType, string url, byte[] fileData, L //https://forum.unity.com/threads/sendwebrequest-curl-timeout-error.854812/ webRequest.timeout = 30; - webRequest.uploadHandler = (UploadHandler)new UploadHandlerRaw(fileData); - AttachHeadersToPostRequest(webRequest, requestHeaders, withContentType: false); + webRequest.uploadHandler = (UploadHandler) new UploadHandlerRaw(fileData); + AttachHeadersToPostRequest(webRequest, requestHeaders, false); yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); } - IEnumerator PostRequestCor(SdkType sdkType, string url, WWWForm data, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class + private IEnumerator PostRequestCor(SdkType sdkType, string url, WWWForm data, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { url = AppendAnalyticsToUrl(sdkType, url); - UnityWebRequest webRequest = UnityWebRequest.Post(url, data); + var webRequest = UnityWebRequest.Post(url, data); - AttachHeadersToPostRequest(webRequest, requestHeaders, withContentType: false); + AttachHeadersToPostRequest(webRequest, requestHeaders, false); yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); } @@ -214,7 +239,7 @@ private UnityWebRequest PreparePostWebRequest(string url, object jsonObject, Lis #if UNITY_2022_2_OR_NEWER UnityWebRequest webRequest = UnityWebRequest.PostWwwForm(url, UnityWebRequest.kHttpVerbPOST); #else - UnityWebRequest webRequest = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST); + var webRequest = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST); #endif webRequest.timeout = 30; @@ -229,7 +254,7 @@ private UnityWebRequest PreparePostUploadRequest(string url, string pathToFile, #if UNITY_2022_2_OR_NEWER UnityWebRequest webRequest = UnityWebRequest.PostWwwForm(url, UnityWebRequest.kHttpVerbPOST); #else - UnityWebRequest webRequest = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST); + var webRequest = UnityWebRequest.Post(url, UnityWebRequest.kHttpVerbPOST); #endif webRequest.timeout = 30; @@ -241,7 +266,8 @@ private UnityWebRequest PreparePostUploadRequest(string url, string pathToFile, private void AttachFileToUploadRequest(UnityWebRequest webRequest, string pathToFile) { - if (!string.IsNullOrEmpty(pathToFile)) { + if (!string.IsNullOrEmpty(pathToFile)) + { webRequest.uploadHandler = new UploadHandlerFile(pathToFile); } } @@ -251,12 +277,12 @@ private void AttachHeadersToPostRequest(UnityWebRequest webRequest, List() { WebRequestHeader.ContentTypeHeader() }; + requestHeaders = new List() {WebRequestHeader.JsonContentTypeHeader()}; } AttachHeadersToRequest(webRequest, requestHeaders); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.POST.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.POST.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.POST.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.POST.cs.meta diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PUT.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.PUT.cs similarity index 69% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PUT.cs rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.PUT.cs index 7b772ab21..6b44814fb 100644 --- a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PUT.cs +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.PUT.cs @@ -5,67 +5,67 @@ namespace Xsolla.Core { - public partial class WebRequestHelper : MonoSingleton + public partial class WebRequestHelper { - public void PutRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + public void PutRequest(SdkType sdkType, string url, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { var headers = AppendAnalyticHeaders(sdkType, requestHeader); StartCoroutine(PutRequestCor(sdkType, url, headers, onComplete, onError, errorsToCheck)); } - - public void PutRequest(SdkType sdkType, string url, T jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class + + public void PutRequest(SdkType sdkType, string url, T jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { var headers = AppendAnalyticHeaders(sdkType, requestHeaders); StartCoroutine(PutRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } - public void PutRequest(SdkType sdkType, string url, T jsonObject, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class + public void PutRequest(SdkType sdkType, string url, T jsonObject, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { var headers = AppendAnalyticHeaders(sdkType, requestHeader); StartCoroutine(PutRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } - - public void PutRequest(SdkType sdkType, string url, D jsonObject, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where D : class where T : class + + public void PutRequest(SdkType sdkType, string url, D jsonObject, WebRequestHeader requestHeader, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where D : class where T : class { var headers = AppendAnalyticHeaders(sdkType, requestHeader); StartCoroutine(PutRequestCor(sdkType, url, jsonObject, headers, onComplete, onError, errorsToCheck)); } - - private IEnumerator PutRequestCor(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) + + private IEnumerator PutRequestCor(SdkType sdkType, string url, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) { url = AppendAnalyticsToUrl(sdkType, url); - UnityWebRequest webRequest = new UnityWebRequest(url, "PUT") { + var webRequest = new UnityWebRequest(url, "PUT") { downloadHandler = new DownloadHandlerBuffer() }; - + AttachHeadersToPutRequest(webRequest, requestHeaders); yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); } - private IEnumerator PutRequestCor(SdkType sdkType, string url, T jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class + private IEnumerator PutRequestCor(SdkType sdkType, string url, T jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class { url = AppendAnalyticsToUrl(sdkType, url); - UnityWebRequest webRequest = new UnityWebRequest(url, "PUT") { + var webRequest = new UnityWebRequest(url, "PUT") { downloadHandler = new DownloadHandlerBuffer() }; - + AttachBodyToRequest(webRequest, jsonObject); AttachHeadersToPutRequest(webRequest, requestHeaders); yield return StartCoroutine(PerformWebRequest(webRequest, onComplete, onError, errorsToCheck)); } - - private IEnumerator PutRequestCor(SdkType sdkType, string url, D jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorCheckType errorsToCheck = ErrorCheckType.CommonErrors) where T : class where D : class + + private IEnumerator PutRequestCor(SdkType sdkType, string url, D jsonObject, List requestHeaders, Action onComplete = null, Action onError = null, ErrorGroup errorsToCheck = ErrorGroup.CommonErrors) where T : class where D : class { url = AppendAnalyticsToUrl(sdkType, url); - UnityWebRequest webRequest = new UnityWebRequest(url, "PUT") { + var webRequest = new UnityWebRequest(url, "PUT") { downloadHandler = new DownloadHandlerBuffer() }; - + AttachBodyToRequest(webRequest, jsonObject); AttachHeadersToPutRequest(webRequest, requestHeaders); @@ -75,12 +75,11 @@ private IEnumerator PutRequestCor(SdkType sdkType, string url, D jsonObjec private void AttachHeadersToPutRequest(UnityWebRequest webRequest, List requestHeaders) { if (requestHeaders != null) - requestHeaders.Add(WebRequestHeader.ContentTypeHeader()); + requestHeaders.Add(WebRequestHeader.JsonContentTypeHeader()); else - requestHeaders = new List() { WebRequestHeader.ContentTypeHeader() }; + requestHeaders = new List() {WebRequestHeader.JsonContentTypeHeader()}; AttachHeadersToRequest(webRequest, requestHeaders); } } -} - +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PUT.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.PUT.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.PUT.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.PUT.cs.meta diff --git a/Assets/Xsolla/Core/WebRequests/WebRequestHelper.ProcessRequest.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.ProcessRequest.cs new file mode 100644 index 000000000..94466c63c --- /dev/null +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.ProcessRequest.cs @@ -0,0 +1,149 @@ +using System; +using System.Text; +using UnityEngine; +using UnityEngine.Networking; + +namespace Xsolla.Core +{ + public partial class WebRequestHelper + { + private static void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) + { + if (CheckNoErrors(webRequest, errorsToCheck, out var error)) + onComplete?.Invoke(); + else + onError?.Invoke(error); + + webRequest.Dispose(); + } + + private static void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) + { + if (CheckNoErrors(webRequest, errorsToCheck, out var error)) + onComplete?.Invoke((int) webRequest.responseCode); + else + onError?.Invoke(error); + + webRequest.Dispose(); + } + + private static void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) + { + if (CheckNoErrors(webRequest, errorsToCheck, out var error)) + onComplete?.Invoke(webRequest); + else + onError?.Invoke(error); + + webRequest.Dispose(); + } + + private static void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) + { + if (CheckNoErrors(webRequest, errorsToCheck, out var error)) + { + var data = webRequest.downloadHandler.text; + if (data != null) + onComplete?.Invoke(data); + else + onError?.Invoke(Error.UnknownError); + } + else + onError?.Invoke(error); + + webRequest.Dispose(); + } + + private static void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError) + { + if (CheckNoErrors(webRequest, ErrorGroup.CommonErrors, out var error, false)) + { + var texture = ((DownloadHandlerTexture) webRequest.downloadHandler).texture; + if (texture != null) + onComplete?.Invoke(texture); + else + onError?.Invoke(Error.UnknownError); + } + else + onError?.Invoke(error); + + webRequest.Dispose(); + } + + private static void ProcessRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) where T : class + { + if (CheckNoErrors(webRequest, errorsToCheck, out var error)) + { + var rawData = webRequest.downloadHandler.text; + var data = rawData != null ? ParseUtils.FromJson(rawData) : null; + if (data != null) + onComplete?.Invoke(data); + else + onError?.Invoke(Error.UnknownError); + } + else + onError?.Invoke(error); + + webRequest.Dispose(); + } + + public static bool CheckNoErrors(UnityWebRequest webRequest, ErrorGroup errorsToCheck, out Error error, bool log = true) + { +#if UNITY_2020_1_OR_NEWER + var isNetworkError = webRequest.result == UnityWebRequest.Result.ConnectionError; + var isHttpError = webRequest.result == UnityWebRequest.Result.ProtocolError; +#else + var isNetworkError = webRequest.isNetworkError; + var isHttpError = webRequest.isHttpError; +#endif + if (isNetworkError) + { + error = new Error(ErrorType.NetworkError); + return false; + } + + var data = webRequest.downloadHandler.text; + + if (log) + { + var logMessage = $"WebRequest: {webRequest.url}"; + + var header = webRequest.GetResponseHeader("Authorization"); + if (!string.IsNullOrEmpty(header)) + logMessage += $"\n\nAuthorization: {header}"; + + var uploadBytes = webRequest.uploadHandler?.data; + if (uploadBytes != null) + { + var dataJson = Encoding.UTF8.GetString(uploadBytes); + logMessage += $"\n\nRequest: {dataJson}"; + } + + if (!string.IsNullOrEmpty(data)) + { + logMessage += $"\n\nResponse: {data}"; + } + + XDebug.Log($"{logMessage}\n"); + } + + if (ParseUtils.TryParseError(data, out error)) + { + if (ErrorTypeParser.TryGetSpecificType(error.statusCode, errorsToCheck, out var specificErrorType)) + error.ErrorType = specificErrorType; + else if (ErrorTypeParser.TryGetCommonType(error.statusCode, out var commonErrorType)) + error.ErrorType = commonErrorType; + + return false; + } + + if (isHttpError) + { + error = Error.UnknownError; + return false; + } + + error = null; + return true; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.ProcessRequest.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.ProcessRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.ProcessRequest.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.ProcessRequest.cs.meta diff --git a/Assets/Xsolla/Core/WebRequests/WebRequestHelper.cs b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.cs new file mode 100644 index 000000000..58de21d02 --- /dev/null +++ b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.cs @@ -0,0 +1,126 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using UnityEngine.Networking; + +namespace Xsolla.Core +{ + public partial class WebRequestHelper : MonoBehaviour + { + private static WebRequestHelper _instance; + + public static WebRequestHelper Instance + { + get + { + if (_instance == null) + _instance = new GameObject("WebRequestHelper").AddComponent(); + + return _instance; + } + } + + private readonly List Requests = new List(); + + public bool IsBusy() + { + return Requests.Count > 0; + } + + private void OnDestroy() + { + Requests.ForEach(r => r.Dispose()); + Requests.Clear(); + + StopAllCoroutines(); + } + + private IEnumerator InternalPerformWebRequest(UnityWebRequest webRequest, Action onComplete) + { + webRequest.disposeDownloadHandlerOnDispose = true; + webRequest.disposeUploadHandlerOnDispose = true; + webRequest.disposeCertificateHandlerOnDispose = true; + Requests.Add(webRequest); + + yield return StartCoroutine(SendWebRequest(webRequest)); + onComplete?.Invoke(); + + Requests.Remove(webRequest); + } + + private static IEnumerator SendWebRequest(UnityWebRequest webRequest) + { +#if UNITY_2018_1_OR_NEWER + yield return webRequest.SendWebRequest(); +#else + yield return webRequest.Send(); +#endif + } + + private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) + { + yield return InternalPerformWebRequest( + webRequest, + () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); + } + + private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) + { + yield return InternalPerformWebRequest( + webRequest, + () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); + } + + private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) + { + yield return InternalPerformWebRequest( + webRequest, + () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); + } + + private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) + { + yield return InternalPerformWebRequest( + webRequest, + () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); + } + + private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError, ErrorGroup errorsToCheck) where T : class + { + yield return InternalPerformWebRequest( + webRequest, + () => ProcessRequest(webRequest, onComplete, onError, errorsToCheck)); + } + + private IEnumerator PerformWebRequest(UnityWebRequest webRequest, Action onComplete, Action onError) + { + yield return InternalPerformWebRequest( + webRequest, + () => ProcessRequest(webRequest, onComplete, onError)); + } + + public static void AttachHeadersToRequest(UnityWebRequest webRequest, List requestHeaders) + { + if (requestHeaders == null) + return; + + foreach (var header in requestHeaders.Where(header => header != null)) + { + webRequest.SetRequestHeader(header.Name, header.Value); + } + } + + public static void AttachBodyToRequest(UnityWebRequest webRequest, object data) + { + if (data == null) + return; + + var json = ParseUtils.ToJson(data).Replace('\n', ' '); + var body = new UTF8Encoding().GetBytes(json); + webRequest.uploadHandler = new UploadHandlerRaw(body); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.cs.meta b/Assets/Xsolla/Core/WebRequests/WebRequestHelper.cs.meta similarity index 100% rename from Assets/Xsolla/Core/WebRequestHelper/WebRequestHelper.cs.meta rename to Assets/Xsolla/Core/WebRequests/WebRequestHelper.cs.meta diff --git a/Assets/Xsolla/Core/iOS/IosCallbacks.cs b/Assets/Xsolla/Core/iOS/IosCallbacks.cs index 361aa99ad..e8e372581 100644 --- a/Assets/Xsolla/Core/iOS/IosCallbacks.cs +++ b/Assets/Xsolla/Core/iOS/IosCallbacks.cs @@ -4,12 +4,12 @@ namespace Xsolla.Core { - public static class IosCallbacks + internal static class IosCallbacks { public delegate void ActionVoidCallbackDelegate(IntPtr actionPtr); public delegate void ActionStringCallbackDelegate(IntPtr actionPtr, string value); - + public delegate void ActionBoolCallbackDelegate(IntPtr actionPtr, bool value); [MonoPInvokeCallback(typeof(ActionVoidCallbackDelegate))] @@ -18,7 +18,7 @@ public static void ActionVoidCallback(IntPtr actionPtr) if (actionPtr != IntPtr.Zero) { var action = actionPtr.Cast(); - action(); + action?.Invoke(); } } @@ -28,17 +28,17 @@ public static void ActionStringCallback(IntPtr actionPtr, string value) if (actionPtr != IntPtr.Zero) { var action = actionPtr.Cast>(); - action(value); + action?.Invoke(value); } } - + [MonoPInvokeCallback(typeof(ActionBoolCallbackDelegate))] public static void ActionBoolCallback(IntPtr actionPtr, bool value) { if (actionPtr != IntPtr.Zero) { var action = actionPtr.Cast>(); - action(value); + action?.Invoke(value); } } } diff --git a/Assets/Xsolla/Core/iOS/IosPayments.cs b/Assets/Xsolla/Core/iOS/IosPayments.cs new file mode 100644 index 000000000..6a8bed5d7 --- /dev/null +++ b/Assets/Xsolla/Core/iOS/IosPayments.cs @@ -0,0 +1,46 @@ +#if UNITY_IOS +using System; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace Xsolla.Core +{ + internal class IosPayments + { + [DllImport("__Internal")] + private static extern void _performPayment( + string token, + bool isSandbox, + string redirectUrl, + IosCallbacks.ActionStringCallbackDelegate onErrorCallback, IntPtr onErrorActionPtr, + IosCallbacks.ActionBoolCallbackDelegate browserCallback, IntPtr browserCallbackActionPtr); + + private Action OnBrowserClose { get; set; } + + public void Perform(string paymentToken, Action onBrowserClose) + { + OnBrowserClose = onBrowserClose; + + Action onErrorNative = HandleError; + Action onBrowserClosedNative = HandleBrowserClose; + + _performPayment( + paymentToken, + XsollaSettings.IsSandbox, + RedirectUrlHelper.GetPaymentDeepLinkUrl(XsollaSettings.IosRedirectPolicySettings), + IosCallbacks.ActionStringCallback, onErrorNative.GetPointer(), + IosCallbacks.ActionBoolCallback, onBrowserClosedNative.GetPointer()); + } + + private static void HandleError(string error) + { + XDebug.LogError($"IosPayments. Error: {error}"); + } + + private void HandleBrowserClose(bool isManually) + { + OnBrowserClose?.Invoke(isManually); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Xsolla/Core/iOS/IosSDKPaymentsHelper.cs.meta b/Assets/Xsolla/Core/iOS/IosPayments.cs.meta similarity index 100% rename from Assets/Xsolla/Core/iOS/IosSDKPaymentsHelper.cs.meta rename to Assets/Xsolla/Core/iOS/IosPayments.cs.meta diff --git a/Assets/Xsolla/Core/iOS/IosSDKPaymentsHelper.cs b/Assets/Xsolla/Core/iOS/IosSDKPaymentsHelper.cs deleted file mode 100644 index f5e11f0e5..000000000 --- a/Assets/Xsolla/Core/iOS/IosSDKPaymentsHelper.cs +++ /dev/null @@ -1,42 +0,0 @@ -#if UNITY_IOS -using System; -using System.Runtime.InteropServices; -using UnityEngine; - -namespace Xsolla.Core -{ - public class IosSDKPaymentsHelper - { - [DllImport("__Internal")] - private static extern void _performPayment(string token, bool isSandbox, string redirectUrl, - IosCallbacks.ActionStringCallbackDelegate onErrorCallback, IntPtr onErrorActionPtr, - IosCallbacks.ActionBoolCallbackDelegate browserCallback, IntPtr browserCallbackActionPtr); - - private Action OnBrowserClosed { get; set; } - - public void PerformPayment(string token, bool isSandbox, Action onBrowserClosed = null) - { - OnBrowserClosed = onBrowserClosed; - - var redirectPolicy = XsollaSettings.IosRedirectPolicySettings; - var redirectUrl = redirectPolicy.UseSettingsFromPublisherAccount - ? $"app://xpayment.{Application.identifier}" - : redirectPolicy.ReturnUrl; - - Action onErrorNative = FailHandler; - Action onBrowserClosedNative = HandleBrowserClosed; - _performPayment(token, isSandbox, redirectUrl, IosCallbacks.ActionStringCallback, onErrorNative.GetPointer(), IosCallbacks.ActionBoolCallback, onBrowserClosedNative.GetPointer()); - } - - private static void FailHandler(string error) - { - Debug.LogError($"Payments failed. Error: {error}"); - } - - private void HandleBrowserClosed(bool isManually) - { - OnBrowserClosed?.Invoke(isManually); - } - } -} -#endif \ No newline at end of file diff --git a/Assets/Xsolla/Core/iOS/IosSDKSocialAuthHelper.cs b/Assets/Xsolla/Core/iOS/IosSDKSocialAuthHelper.cs deleted file mode 100644 index 8c2f09eaf..000000000 --- a/Assets/Xsolla/Core/iOS/IosSDKSocialAuthHelper.cs +++ /dev/null @@ -1,62 +0,0 @@ -#if UNITY_IOS -using System; -using System.Runtime.InteropServices; -using UnityEngine; -using Xsolla.Auth; - -namespace Xsolla.Core -{ - public class IosSDKSocialAuthHelper - { - [DllImport("__Internal")] - private static extern void _authBySocialNetwork(string platform, int clientID, string state, string redirectUri, - IosCallbacks.ActionStringCallbackDelegate successCallback, IntPtr successActionPtr, - IosCallbacks.ActionStringCallbackDelegate errorCallback, IntPtr errorActionPtr, - IosCallbacks.ActionVoidCallbackDelegate cancelCallback, IntPtr cancelActionPtr); - - private Action successCallback; - private Action cancelCallback; - private Action errorCallback; - - public void PerformSocialAuth(SocialProvider socialProvider, Action onSuccess, Action onCancelled, Action onError) - { - successCallback = onSuccess; - cancelCallback = onCancelled; - errorCallback = onError; - - var providerName = socialProvider.ToString().ToUpper(); - const string authState = "xsollatest"; - var clientId = XsollaSettings.OAuthClientId; - - var callbackUrl = XsollaSettings.CallbackUrl; - if (string.IsNullOrEmpty(callbackUrl)) - callbackUrl = $"app://xlogin.{Application.identifier}"; - - Action onSuccessNative = SuccessHandler; - Action onErrorNative = FailHandler; - Action onCancelNative = CancelHandler; - - _authBySocialNetwork(providerName, clientId, authState, callbackUrl, - IosCallbacks.ActionStringCallback, onSuccessNative.GetPointer(), - IosCallbacks.ActionStringCallback, onErrorNative.GetPointer(), - IosCallbacks.ActionVoidCallback, onCancelNative.GetPointer()); - } - - private void SuccessHandler(string tokenInfo) - { - var response = ParseUtils.FromJson(tokenInfo); - successCallback?.Invoke(response); - } - - private void FailHandler(string error) - { - errorCallback?.Invoke(new Error(errorMessage: $"Social auth failed: {error}")); - } - - private void CancelHandler() - { - cancelCallback?.Invoke(); - } - } -} -#endif \ No newline at end of file diff --git a/Assets/Xsolla/Core/iOS/IosSocialAuth.cs b/Assets/Xsolla/Core/iOS/IosSocialAuth.cs new file mode 100644 index 000000000..0415b2ae7 --- /dev/null +++ b/Assets/Xsolla/Core/iOS/IosSocialAuth.cs @@ -0,0 +1,57 @@ +#if UNITY_IOS +using System; +using System.Runtime.InteropServices; + +namespace Xsolla.Core +{ + internal class IosSocialAuth + { + [DllImport("__Internal")] + private static extern void _authBySocialNetwork(string platform, int clientID, string state, string redirectUri, + IosCallbacks.ActionStringCallbackDelegate successCallback, IntPtr successActionPtr, + IosCallbacks.ActionStringCallbackDelegate errorCallback, IntPtr errorActionPtr, + IosCallbacks.ActionVoidCallbackDelegate cancelCallback, IntPtr cancelActionPtr); + + private Action OnSuccess; + private Action OnError; + private Action OnCancel; + + public void Perform(SocialProvider socialProvider, Action onSuccess, Action onError, Action onCancel) + { + OnSuccess = onSuccess; + OnError = onError; + OnCancel = onCancel; + + Action onSuccessNative = HandleSuccess; + Action onErrorNative = HandleError; + Action onCancelNative = HandleCancel; + + _authBySocialNetwork( + socialProvider.ToString().ToUpper(), + XsollaSettings.OAuthClientId, + "xsollatest", + RedirectUrlHelper.GetAuthDeepLinkUrl(), + IosCallbacks.ActionStringCallback, onSuccessNative.GetPointer(), + IosCallbacks.ActionStringCallback, onErrorNative.GetPointer(), + IosCallbacks.ActionVoidCallback, onCancelNative.GetPointer()); + } + + private void HandleSuccess(string tokenJson) + { + var response = ParseUtils.FromJson(tokenJson); + XsollaToken.Create(response.access_token, response.refresh_token); + OnSuccess?.Invoke(); + } + + private void HandleError(string error) + { + OnError?.Invoke(new Error(errorMessage: $"IosSocialAuth: {error}")); + } + + private void HandleCancel() + { + OnCancel?.Invoke(); + } + } +} +#endif \ No newline at end of file diff --git a/Assets/Xsolla/Core/iOS/IosSDKSocialAuthHelper.cs.meta b/Assets/Xsolla/Core/iOS/IosSocialAuth.cs.meta similarity index 100% rename from Assets/Xsolla/Core/iOS/IosSDKSocialAuthHelper.cs.meta rename to Assets/Xsolla/Core/iOS/IosSocialAuth.cs.meta diff --git a/Assets/Xsolla/GameKeys/Api.meta b/Assets/Xsolla/GameKeys/Api.meta deleted file mode 100644 index 808df423e..000000000 --- a/Assets/Xsolla/GameKeys/Api.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 6c84b4dd0b12cf0429a9d5388c149cae -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/GameKeys/Entities/DrmItem.cs b/Assets/Xsolla/GameKeys/Entities/DrmItem.cs deleted file mode 100644 index aa8998a58..000000000 --- a/Assets/Xsolla/GameKeys/Entities/DrmItem.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Xsolla.GameKeys -{ - [Serializable] - public class DrmItem - { - public string sku; - public string name; - public string image; - public string link; - public string redeem_instruction_link; - public int drm_id; - } -} diff --git a/Assets/Xsolla/GameKeys/Entities/DrmItem.cs.meta b/Assets/Xsolla/GameKeys/Entities/DrmItem.cs.meta deleted file mode 100644 index f853e908b..000000000 --- a/Assets/Xsolla/GameKeys/Entities/DrmItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 6e18beb8c362438abafcf43e6eefb287 -timeCreated: 1634106633 \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Entities/DrmItems.cs b/Assets/Xsolla/GameKeys/Entities/DrmItems.cs index 626a7fd35..80ed90109 100644 --- a/Assets/Xsolla/GameKeys/Entities/DrmItems.cs +++ b/Assets/Xsolla/GameKeys/Entities/DrmItems.cs @@ -7,4 +7,15 @@ public class DrmItems { public DrmItem[] items; } -} + + [Serializable] + public class DrmItem + { + public string sku; + public string name; + public string image; + public string link; + public string redeem_instruction_link; + public int drm_id; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Entities/GameItem.cs b/Assets/Xsolla/GameKeys/Entities/GameItem.cs deleted file mode 100644 index 73abc4c40..000000000 --- a/Assets/Xsolla/GameKeys/Entities/GameItem.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.GameKeys -{ - [Serializable] - public class GameItem - { - public string sku; - public string name; - public string type; - public string unit_type; - public string description; - public string image_url; - public StoreItemGroup[] groups; - public StoreItemAttribute[] attributes; - public Unit[] unit_items; - - [Serializable] - public class Unit - { - public string sku; - public string type; - public bool is_free; - public Price price; - public VirtualPrice[] virtual_prices; - public string drm_name; - public string drm_sku; - public bool has_keys; - public bool is_pre_order; - public string release_date; - } - } -} diff --git a/Assets/Xsolla/GameKeys/Entities/GameItem.cs.meta b/Assets/Xsolla/GameKeys/Entities/GameItem.cs.meta deleted file mode 100644 index 12ddfe72a..000000000 --- a/Assets/Xsolla/GameKeys/Entities/GameItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 0a7c45befa9a49f1b2ce8acc6783b4aa -timeCreated: 1634026362 \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Entities/GameItems.cs b/Assets/Xsolla/GameKeys/Entities/GameItems.cs index f88c78f48..7b25fcffa 100644 --- a/Assets/Xsolla/GameKeys/Entities/GameItems.cs +++ b/Assets/Xsolla/GameKeys/Entities/GameItems.cs @@ -1,4 +1,5 @@ using System; +using Xsolla.Core; namespace Xsolla.GameKeys { @@ -7,4 +8,33 @@ public class GameItems { public GameItem[] items; } -} + + [Serializable] + public class GameItem + { + public string sku; + public string name; + public string type; + public string unit_type; + public string description; + public string image_url; + public StoreItemGroup[] groups; + public StoreItemAttribute[] attributes; + public Unit[] unit_items; + + [Serializable] + public class Unit + { + public string sku; + public string type; + public bool is_free; + public Price price; + public VirtualPrice[] virtual_prices; + public string drm_name; + public string drm_sku; + public bool has_keys; + public bool is_pre_order; + public string release_date; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Entities/GameKeyItem.cs b/Assets/Xsolla/GameKeys/Entities/GameKeyItem.cs deleted file mode 100644 index d98efc445..000000000 --- a/Assets/Xsolla/GameKeys/Entities/GameKeyItem.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.GameKeys -{ - [Serializable] - public class GameKeyItem - { - public string sku; - public string name; - public string type; - public string description; - public string image_url; - public bool is_free; - public Price price; - public VirtualPrice[] virtual_prices; - public string drm_name; - public string drm_sku; - public bool has_keys; - public bool is_pre_order; - public string release_date; - public StoreItemGroup[] groups; - public StoreItemAttribute[] attributes; - } -} diff --git a/Assets/Xsolla/GameKeys/Entities/GameKeyItem.cs.meta b/Assets/Xsolla/GameKeys/Entities/GameKeyItem.cs.meta deleted file mode 100644 index 02659a011..000000000 --- a/Assets/Xsolla/GameKeys/Entities/GameKeyItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: e010311c0ed34b2e878d3d882367fad7 -timeCreated: 1634105440 \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Entities/GameKeyItems.cs b/Assets/Xsolla/GameKeys/Entities/GameKeyItems.cs index 660f8d2e8..794467566 100644 --- a/Assets/Xsolla/GameKeys/Entities/GameKeyItems.cs +++ b/Assets/Xsolla/GameKeys/Entities/GameKeyItems.cs @@ -1,4 +1,5 @@ using System; +using Xsolla.Core; namespace Xsolla.GameKeys { @@ -6,5 +7,25 @@ namespace Xsolla.GameKeys public class GameKeyItems { public GameKeyItem[] items; + + [Serializable] + public class GameKeyItem + { + public string sku; + public string name; + public string type; + public string description; + public string image_url; + public bool is_free; + public Price price; + public VirtualPrice[] virtual_prices; + public string drm_name; + public string drm_sku; + public bool has_keys; + public bool is_pre_order; + public string release_date; + public StoreItemGroup[] groups; + public StoreItemAttribute[] attributes; + } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Entities/GameOwnership.cs b/Assets/Xsolla/GameKeys/Entities/GameOwnership.cs index 60cd92759..8f64ac47e 100644 --- a/Assets/Xsolla/GameKeys/Entities/GameOwnership.cs +++ b/Assets/Xsolla/GameKeys/Entities/GameOwnership.cs @@ -23,4 +23,4 @@ public class Item public StoreItemAttribute[] attributes; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Entities/RedeemGameCodeRequest.cs b/Assets/Xsolla/GameKeys/Entities/RedeemGameCodeRequest.cs deleted file mode 100644 index 1e6ccd189..000000000 --- a/Assets/Xsolla/GameKeys/Entities/RedeemGameCodeRequest.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Xsolla.GameKeys -{ - [Serializable] - public class RedeemGameCodeRequest - { - public string code; - public bool sandbox; - - public RedeemGameCodeRequest(string code, bool sandbox) - { - this.code = code; - this.sandbox = sandbox; - } - } -} diff --git a/Assets/Xsolla/GameKeys/Internal.meta b/Assets/Xsolla/GameKeys/Internal.meta new file mode 100644 index 000000000..b12f5f758 --- /dev/null +++ b/Assets/Xsolla/GameKeys/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 602fb62b2ef94f00aeb633f5c61968b6 +timeCreated: 1682698290 \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Internal/RedeemGameCodeRequest.cs b/Assets/Xsolla/GameKeys/Internal/RedeemGameCodeRequest.cs new file mode 100644 index 000000000..b9f3f94cc --- /dev/null +++ b/Assets/Xsolla/GameKeys/Internal/RedeemGameCodeRequest.cs @@ -0,0 +1,11 @@ +using System; + +namespace Xsolla.GameKeys +{ + [Serializable] + internal class RedeemGameCodeRequest + { + public string code; + public bool sandbox; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Entities/RedeemGameCodeRequest.cs.meta b/Assets/Xsolla/GameKeys/Internal/RedeemGameCodeRequest.cs.meta similarity index 100% rename from Assets/Xsolla/GameKeys/Entities/RedeemGameCodeRequest.cs.meta rename to Assets/Xsolla/GameKeys/Internal/RedeemGameCodeRequest.cs.meta diff --git a/Assets/Xsolla/GameKeys/Api/XsollaGameKeys.cs b/Assets/Xsolla/GameKeys/XsollaGameKeys.cs similarity index 53% rename from Assets/Xsolla/GameKeys/Api/XsollaGameKeys.cs rename to Assets/Xsolla/GameKeys/XsollaGameKeys.cs index e290c5eac..8cca2361d 100644 --- a/Assets/Xsolla/GameKeys/Api/XsollaGameKeys.cs +++ b/Assets/Xsolla/GameKeys/XsollaGameKeys.cs @@ -3,159 +3,212 @@ namespace Xsolla.GameKeys { - public partial class XsollaGameKeys : MonoSingleton + public static class XsollaGameKeys { - private const string URL_GET_GAMES_LIST = Constants.BASE_STORE_API_URL + "/items/game"; - private const string URL_GET_GAMES_BY_GROUP = Constants.BASE_STORE_API_URL + "/items/game/group/{1}"; - private const string URL_GET_GAME_FOR_CATALOG = Constants.BASE_STORE_API_URL + "/items/game/sku/{1}"; - private const string URL_GET_GAME_KEY_CATALOG = Constants.BASE_STORE_API_URL + "/items/game/key/sku/{1}"; - private const string URL_GET_GAME_KEYS_BY_GROUP = Constants.BASE_STORE_API_URL + "/items/game/key/group/{1}"; - private const string URL_GET_USER_OWNED_GAMES = Constants.BASE_STORE_API_URL + "/entitlement?sandbox={1}"; - private const string URL_GET_DRM_LIST = Constants.BASE_STORE_API_URL + "/items/game/drm"; - private const string URL_REDEEM_GAME_CODE = Constants.BASE_STORE_API_URL + "/entitlement/redeem"; + private static string BaseUrl => $"https://store.xsolla.com/api/v2/project/{XsollaSettings.StoreProjectId}"; /// /// Gets a games list for building a catalog. /// - /// Project ID, can be found in Publisher Account next to the name of the project. /// Called after server response. /// Called after the request resulted with an error. /// Limit for the number of elements on the page. /// Number of the element from which the list is generated (the count starts from 0). /// Response language. Two-letter lowercase language code per ISO 639-1. - /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). If you do not specify the country explicitly, it will be defined by the user IP address. - public void GetGamesList(string projectId, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string locale = null, string additionalFields = "long_description", string country = null) + /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. + public static void GetGamesList(Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null, string country = null, string additionalFields = "long_description") { - var url = string.Format(URL_GET_GAMES_LIST, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError, ErrorCheckType.ItemsListErrors); + var url = new UrlBuilder($"{BaseUrl}/items/game") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + onSuccess, + onError, + ErrorGroup.ItemsListErrors); } /// /// Gets a game for the catalog. /// - /// Project ID, can be found in Publisher Account next to the name of the project. /// Item SKU. /// Called after server response. /// Called after the request resulted with an error. /// Response language. Two-letter lowercase language code per ISO 639-1. - /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). If you do not specify the country explicitly, it will be defined by the user IP address. - public void GetGameForCatalog(string projectId, string itemSku, Action onSuccess, Action onError = null, string locale = null, string additionalFields = "long_description", string country = null) + /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. + public static void GetGameForCatalog(string itemSku, Action onSuccess, Action onError, string locale = null, string country = null, string additionalFields = "long_description") { - var url = string.Format(URL_GET_GAME_FOR_CATALOG, projectId, itemSku); - url = UrlParameterizer.ConcatUrlAndParams(url, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError, ErrorCheckType.ItemsListErrors); + var url = new UrlBuilder($"{BaseUrl}/items/game/sku/{itemSku}") + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + onSuccess, + onError, + ErrorGroup.ItemsListErrors); } /// /// Gets a game key for the catalog. /// - /// Project ID, can be found in Publisher Account next to the name of the project. /// Item SKU. /// Called after server response. /// Called after the request resulted with an error. /// Response language. Two-letter lowercase language code per ISO 639-1. - /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). If you do not specify the country explicitly, it will be defined by the user IP address. - public void GetGameKeyForCatalog(string projectId, string itemSku, Action onSuccess, Action onError = null, string locale = null, string additionalFields = "long_description", string country = null) + /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. + public static void GetGameKeyForCatalog(string itemSku, Action onSuccess, Action onError, string locale = null, string country = null, string additionalFields = "long_description") { - var url = string.Format(URL_GET_GAME_KEY_CATALOG, projectId, itemSku); - url = UrlParameterizer.ConcatUrlAndParams(url, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError, ErrorCheckType.ItemsListErrors); + var url = new UrlBuilder($"{BaseUrl}/items/game/key/sku/{itemSku}") + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + onSuccess, + onError, + ErrorGroup.ItemsListErrors); } /// /// Gets a games list from the specified group for building a catalog. /// - /// Project ID, can be found in Publisher Account next to the name of the project. /// Group external ID. /// Called after server response. /// Called after the request resulted with an error. /// Limit for the number of elements on the page. /// Number of the element from which the list is generated (the count starts from 0). /// Response language. Two-letter lowercase language code per ISO 639-1. - /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). If you do not specify the country explicitly, it will be defined by the user IP address. - public void GetGamesListBySpecifiedGroup(string projectId, string groupId, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string locale = null, string additionalFields = "long_description", string country = null) + /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. + public static void GetGamesListBySpecifiedGroup(string groupId, Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null, string country = null, string additionalFields = "long_description") { - var url = string.Format(URL_GET_GAMES_BY_GROUP, projectId, groupId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError, ErrorCheckType.ItemsListErrors); + var url = new UrlBuilder($"{BaseUrl}/items/game/group/{groupId}") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + onSuccess, + onError, + ErrorGroup.ItemsListErrors); } /// /// Gets a game key list from the specified group for building a catalog. /// - /// Project ID, can be found in Publisher Account next to the name of the project. /// Group external ID. /// Called after server response. /// Called after the request resulted with an error. /// Limit for the number of elements on the page. /// Number of the element from which the list is generated (the count starts from 0). /// Response language. Two-letter lowercase language code per ISO 639-1. - /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. /// Country used to calculate regional prices and restrictions for the catalog. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). If you do not specify the country explicitly, it will be defined by the user IP address. - public void GetGameKeysListBySpecifiedGroup(string projectId, string groupId, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string locale = null, string additionalFields = "long_description", string country = null) + /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. + public static void GetGameKeysListBySpecifiedGroup(string groupId, Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null, string country = null, string additionalFields = "long_description") { - var url = string.Format(URL_GET_GAME_KEYS_BY_GROUP, projectId, groupId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, additionalFields: additionalFields, country: country); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError, ErrorCheckType.ItemsListErrors); + var url = new UrlBuilder($"{BaseUrl}/items/game/key/group/{groupId}") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + onSuccess, + onError, + ErrorGroup.ItemsListErrors); } /// /// Grants entitlement by a provided game code. /// - /// Project ID, can be found in Publisher Account next to the name of the project. /// Called after server response. /// Called after the request resulted with an error. - public void GetDrmList(string projectId, Action onSuccess, Action onError = null) + public static void GetDrmList(Action onSuccess, Action onError) { - var url = string.Format(URL_GET_DRM_LIST, projectId); - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError, ErrorCheckType.ItemsListErrors); + var url = $"{BaseUrl}/items/game/drm"; + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, onSuccess, + onError, + ErrorGroup.ItemsListErrors); } /// /// Get the list of games owned by the user. The response will contain an array of games owned by a particular user. /// - /// Project ID, can be found in Publisher Account next to the name of the project. /// What type of entitlements should be returned. If the parameter is set to true, the entitlements received by the user in the sandbox mode only are returned. If the parameter isn't passed or is set to false, the entitlements received by the user in the live mode only are returned. /// Called after server response. /// Called after the request resulted with an error. /// Limit for the number of elements on the page. /// Number of the element from which the list is generated (the count starts from 0). /// The list of additional fields. These fields will be in a response if you send them in a request. Available fields `media_list`, `order`, and `long_description`. - public void GetOwnedGames(string projectId, bool sandbox, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string additionalFields = "long_description") + public static void GetOwnedGames(bool sandbox, Action onSuccess, Action onError, int limit = 50, int offset = 0, string additionalFields = "long_description") { - var sandboxFlag = sandbox ? "1" : "0"; - var url = string.Format(URL_GET_USER_OWNED_GAMES, projectId, sandboxFlag); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, additionalFields: additionalFields); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, onSuccess, onError, ErrorCheckType.ItemsListErrors); + var sandboxValue = sandbox ? "1" : "0"; + var url = new UrlBuilder($"{BaseUrl}/entitlement") + .AddParam("sandbox", sandboxValue) + .AddLimit(limit) + .AddOffset(offset) + .AddAdditionalFields(additionalFields) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + onSuccess, + onError, + ErrorGroup.ItemsListErrors); } /// /// Grants entitlement by a provided game code. /// - /// Project ID, can be found in Publisher Account next to the name of the project. /// Game code. /// Redeem game code in the sandbox mode. The option is available for those users who are specified in the list of company users. /// Called after server response. /// Called after the request resulted with an error. - public void RedeemGameCode(string projectId, string gameCode, bool sandbox, Action onSuccess, Action onError = null) + public static void RedeemGameCode(string gameCode, bool sandbox, Action onSuccess, Action onError) { - var url = string.Format(URL_REDEEM_GAME_CODE, projectId); - var data = new RedeemGameCodeRequest(gameCode, sandbox); - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, data, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => RedeemGameCode(projectId, gameCode, sandbox, onSuccess, onError)), - ErrorCheckType.LoginErrors); + var url = $"{BaseUrl}/entitlement/redeem"; + + var requestData = new RedeemGameCodeRequest { + code = gameCode, + sandbox = sandbox + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => RedeemGameCode(gameCode, sandbox, onSuccess, onError)), + ErrorGroup.LoginErrors); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/GameKeys/Api/XsollaGameKeys.cs.meta b/Assets/Xsolla/GameKeys/XsollaGameKeys.cs.meta similarity index 100% rename from Assets/Xsolla/GameKeys/Api/XsollaGameKeys.cs.meta rename to Assets/Xsolla/GameKeys/XsollaGameKeys.cs.meta diff --git a/Assets/Xsolla/Inventory/Api.meta b/Assets/Xsolla/Inventory/Api.meta deleted file mode 100644 index 33c5a2f36..000000000 --- a/Assets/Xsolla/Inventory/Api.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: b62569f895a1b3e46a5808df7d48a50c -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Inventory/Api/XsollaInventory.cs b/Assets/Xsolla/Inventory/Api/XsollaInventory.cs deleted file mode 100644 index 23b4f7799..000000000 --- a/Assets/Xsolla/Inventory/Api/XsollaInventory.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Collections.Generic; -using JetBrains.Annotations; -using Xsolla.Core; - -namespace Xsolla.Inventory -{ - public class XsollaInventory : MonoSingleton - { - private const string URL_VIRTUAL_CURRENCY_BALANCE = Constants.BASE_STORE_API_URL + "/user/virtual_currency_balance"; - private const string URL_INVENTORY_GET_ITEMS = Constants.BASE_STORE_API_URL + "/user/inventory/items"; - private const string URL_INVENTORY_ITEM_CONSUME = Constants.BASE_STORE_API_URL + "/user/inventory/item/consume"; - private const string URL_GET_TIME_LIMITED_ITEMS = Constants.BASE_STORE_API_URL + "/user/time_limited_items"; - - /// - /// Returns the current user’s balance of virtual currency. For each virtual currency, complete data is returned. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/player-inventory/display-inventory/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after server response. - /// Called after virtual currency balance was successfully received. - /// Publishing platform the user plays on.
    - /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. - public void GetVirtualCurrencyBalance(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, string platform = null) - { - var url = string.Format(URL_VIRTUAL_CURRENCY_BALANCE, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, platform: platform); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetVirtualCurrencyBalance(projectId, onSuccess, onError, platform)), - ErrorCheckType.ItemsListErrors); - } - - /// - /// Returns a list of virtual items from the user’s inventory according to pagination settings. For each virtual item, complete data is returned. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/player-inventory/display-inventory/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after purchased virtual items were successfully received. - /// Called after the request resulted with an error. - /// Limit for the number of elements on the page. - /// Number of the element from which the list is generated (the count starts from 0). - /// Defines localization of item's text fields.
    - /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// Publishing platform the user plays on.
    - /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. - public void GetInventoryItems(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null, string platform = null) - { - var url = string.Format(URL_INVENTORY_GET_ITEMS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, platform: platform); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetInventoryItems(projectId, onSuccess, onError, limit, offset, locale, platform)), - ErrorCheckType.ItemsListErrors); - } - - /// - /// Consumes an inventory item. Use for only for consumable virtual items. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/player-inventory/consume-item/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Contains consume parameters. - /// Called after successful inventory item consumption. - /// Called after the request resulted with an error. - /// Publishing platform the user plays on.
    - /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. - public void ConsumeInventoryItem(string projectId, ConsumeItem item, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, string platform = null) - { - var url = string.Format(URL_INVENTORY_ITEM_CONSUME, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, platform: platform); - - var headers = new List() { WebRequestHeader.AuthHeader(Token.Instance), WebRequestHeader.ContentTypeHeader() }; - - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, item, headers, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => ConsumeInventoryItem(projectId, item, onSuccess, onError, platform)), - ErrorCheckType.ConsumeItemErrors); - } - - /// - /// Returns a list of time-limited items from the user’s inventory. For each item, complete data is returned. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/player-inventory/display-inventory/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after list of user time limited items was successfully received. - /// Called after the request resulted with an error. - /// Publishing platform the user plays on.
    - /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. - public void GetTimeLimitedItems(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, string platform = null) - { - var url = string.Format(URL_GET_TIME_LIMITED_ITEMS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, platform: platform); - - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetTimeLimitedItems(projectId, onSuccess, onError, platform)), - ErrorCheckType.ItemsListErrors); - } - } -} diff --git a/Assets/Xsolla/Inventory/Entities/ConsumeItem.cs b/Assets/Xsolla/Inventory/Entities/ConsumeItem.cs index e680d805b..2eb6e59bb 100644 --- a/Assets/Xsolla/Inventory/Entities/ConsumeItem.cs +++ b/Assets/Xsolla/Inventory/Entities/ConsumeItem.cs @@ -9,4 +9,4 @@ public class ConsumeItem public int? quantity; public string instance_id; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Inventory/Entities/InventoryItem.cs b/Assets/Xsolla/Inventory/Entities/InventoryItem.cs deleted file mode 100644 index a7fde8e9e..000000000 --- a/Assets/Xsolla/Inventory/Entities/InventoryItem.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Xsolla.Core; - -namespace Xsolla.Inventory -{ - [Serializable] - public class InventoryItem - { - static readonly Dictionary VirtualItemTypes = - new Dictionary() - { - {"consumable", VirtualItemType.Consumable}, - {"non_consumable", VirtualItemType.NonConsumable}, - {"non_renewing_subscription", VirtualItemType.NonRenewingSubscription} - }; - private const string VIRTUAL_CURRENCY_TYPE = "virtual_currency"; - - public string sku; - public string name; - public string description; - //Public object attributes; Don't use it yet. - public string type; - public string virtual_item_type; - public StoreItemAttribute[] attributes; - public StoreItemGroup[] groups; - public string image_url; - public uint? quantity; - public uint? remaining_uses; - public string instance_id; - - public bool IsConsumable() - { - return VirtualItemType == VirtualItemType.Consumable; - } - - public bool IsVirtualCurrency() - { - return !string.IsNullOrEmpty(type) && type.Equals(VIRTUAL_CURRENCY_TYPE); - } - - public bool IsSubscription() - { - return VirtualItemType == VirtualItemType.NonRenewingSubscription; - } - - public VirtualItemType VirtualItemType - { - get - { - if (!string.IsNullOrEmpty(virtual_item_type) && VirtualItemTypes.Keys.Contains(virtual_item_type)) - { - return VirtualItemTypes[virtual_item_type]; - } - - return VirtualItemType.None; - } - } - } -} - diff --git a/Assets/Xsolla/Inventory/Entities/InventoryItem.cs.meta b/Assets/Xsolla/Inventory/Entities/InventoryItem.cs.meta deleted file mode 100644 index 087e5c99e..000000000 --- a/Assets/Xsolla/Inventory/Entities/InventoryItem.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 281bcfc3f4e101141bcc861256b82fe2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Inventory/Entities/InventoryItems.cs b/Assets/Xsolla/Inventory/Entities/InventoryItems.cs index 99dd5a855..a7bc4099e 100644 --- a/Assets/Xsolla/Inventory/Entities/InventoryItems.cs +++ b/Assets/Xsolla/Inventory/Entities/InventoryItems.cs @@ -1,4 +1,5 @@ using System; +using Xsolla.Core; namespace Xsolla.Inventory { @@ -7,4 +8,41 @@ public class InventoryItems { public InventoryItem[] items; } -} + + [Serializable] + public class InventoryItem + { + public string sku; + public string name; + public string description; + //Public object attributes; Don't use it yet. + public string type; + public string virtual_item_type; + public StoreItemAttribute[] attributes; + public StoreItemGroup[] groups; + public string image_url; + public int? quantity; + public int? remaining_uses; + public string instance_id; + + public VirtualItemType VirtualItemType + { + get + { + if (!string.IsNullOrEmpty(type) && type.Equals("virtual_currency")) + return VirtualItemType.VirtualCurrency; + + if (string.IsNullOrEmpty(virtual_item_type)) + return VirtualItemType.None; + + switch (virtual_item_type) + { + case "consumable": return VirtualItemType.Consumable; + case "non_consumable": return VirtualItemType.NonConsumable; + case "non_renewing_subscription": return VirtualItemType.NonRenewingSubscription; + default: return VirtualItemType.None; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Inventory/Enum/SubscriptionStatusType.cs b/Assets/Xsolla/Inventory/Entities/SubscriptionStatusType.cs similarity index 98% rename from Assets/Xsolla/Inventory/Enum/SubscriptionStatusType.cs rename to Assets/Xsolla/Inventory/Entities/SubscriptionStatusType.cs index f9db26101..e4d16d773 100644 --- a/Assets/Xsolla/Inventory/Enum/SubscriptionStatusType.cs +++ b/Assets/Xsolla/Inventory/Entities/SubscriptionStatusType.cs @@ -6,4 +6,4 @@ public enum SubscriptionStatusType Active, Expired } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Inventory/Enum/SubscriptionStatusType.cs.meta b/Assets/Xsolla/Inventory/Entities/SubscriptionStatusType.cs.meta similarity index 100% rename from Assets/Xsolla/Inventory/Enum/SubscriptionStatusType.cs.meta rename to Assets/Xsolla/Inventory/Entities/SubscriptionStatusType.cs.meta diff --git a/Assets/Xsolla/Inventory/Entities/TimeLimitedItem.cs b/Assets/Xsolla/Inventory/Entities/TimeLimitedItem.cs deleted file mode 100644 index 2a47fc246..000000000 --- a/Assets/Xsolla/Inventory/Entities/TimeLimitedItem.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; - -namespace Xsolla.Inventory -{ - [Serializable] - public class TimeLimitedItem - { - static readonly Dictionary StatusTypes = - new Dictionary() - { - {"none", SubscriptionStatusType.None}, - {"active", SubscriptionStatusType.Active}, - {"expired", SubscriptionStatusType.Expired} - }; - - public string sku; - public string name; - public string type; - public string description; - public string image_url; - public string status; - public long? expired_at; - public string virtual_item_type; - - [JsonProperty("class")] - public string subscription_class; - - public SubscriptionStatusType Status - { - get - { - if (StatusTypes.Keys.Contains(status)) - { - return StatusTypes[status]; - } - - return SubscriptionStatusType.None; - } - } - } -} diff --git a/Assets/Xsolla/Inventory/Entities/TimeLimitedItem.cs.meta b/Assets/Xsolla/Inventory/Entities/TimeLimitedItem.cs.meta deleted file mode 100644 index 528d03813..000000000 --- a/Assets/Xsolla/Inventory/Entities/TimeLimitedItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: bf799dad174f400ea52dffcd9ed4fd2e -timeCreated: 1589529307 \ No newline at end of file diff --git a/Assets/Xsolla/Inventory/Entities/TimeLimitedItems.cs b/Assets/Xsolla/Inventory/Entities/TimeLimitedItems.cs index 16fc12c28..272bc6f46 100644 --- a/Assets/Xsolla/Inventory/Entities/TimeLimitedItems.cs +++ b/Assets/Xsolla/Inventory/Entities/TimeLimitedItems.cs @@ -1,4 +1,5 @@ using System; +using Newtonsoft.Json; namespace Xsolla.Inventory { @@ -7,4 +8,36 @@ public class TimeLimitedItems { public TimeLimitedItem[] items; } -} + + [Serializable] + public class TimeLimitedItem + { + public string sku; + public string name; + public string type; + public string description; + public string image_url; + public string status; + public long? expired_at; + public string virtual_item_type; + [JsonProperty("class")] + public string subscription_class; + + public SubscriptionStatusType Status + { + get + { + if (string.IsNullOrEmpty(status)) + return SubscriptionStatusType.None; + + switch (status) + { + case "none": return SubscriptionStatusType.None; + case "active": return SubscriptionStatusType.Active; + case "expired": return SubscriptionStatusType.Expired; + default: return SubscriptionStatusType.None; + } + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalance.cs b/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalance.cs deleted file mode 100644 index 8bdacac30..000000000 --- a/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalance.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Xsolla.Inventory -{ - [Serializable] - public class VirtualCurrencyBalance - { - public string sku; - public string type; - public string name; - public uint amount; - public string description; - public string image_url; - } -} diff --git a/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalance.cs.meta b/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalance.cs.meta deleted file mode 100644 index aba2c4ed2..000000000 --- a/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalance.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b23e05c27bccc470d961d9d29f9c798e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalances.cs b/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalances.cs index 719350594..d6cb70c64 100644 --- a/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalances.cs +++ b/Assets/Xsolla/Inventory/Entities/VirtualCurrencyBalances.cs @@ -5,6 +5,17 @@ namespace Xsolla.Inventory [Serializable] public class VirtualCurrencyBalances { - public VirtualCurrencyBalance[] items; + public VirtualCurrencyBalance[] items; } -} + + [Serializable] + public class VirtualCurrencyBalance + { + public string sku; + public string type; + public string name; + public int amount; + public string description; + public string image_url; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Inventory/Enum.meta b/Assets/Xsolla/Inventory/Enum.meta deleted file mode 100644 index 55c079c40..000000000 --- a/Assets/Xsolla/Inventory/Enum.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f427a2c2a72a50e428e7f9ca16c599e6 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Inventory/XsollaInventory.cs b/Assets/Xsolla/Inventory/XsollaInventory.cs new file mode 100644 index 000000000..a30ff2c4e --- /dev/null +++ b/Assets/Xsolla/Inventory/XsollaInventory.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using Xsolla.Core; + +namespace Xsolla.Inventory +{ + public static class XsollaInventory + { + private static string BaseUrl => $"https://store.xsolla.com/api/v2/project/{XsollaSettings.StoreProjectId}"; + + /// + /// Returns the current user’s balance of virtual currency. For each virtual currency, complete data is returned. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/player-inventory/display-inventory/). + /// Called after server response. + /// Called after virtual currency balance was successfully received. + /// Publishing platform the user plays on.
    + /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. + public static void GetVirtualCurrencyBalance(Action onSuccess, Action onError, string platform = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/virtual_currency_balance") + .AddPlatform(platform) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetVirtualCurrencyBalance(onSuccess, onError, platform)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Returns a list of virtual items from the user’s inventory according to pagination settings. For each virtual item, complete data is returned. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/player-inventory/display-inventory/). + /// Called after purchased virtual items were successfully received. + /// Called after the request resulted with an error. + /// Limit for the number of elements on the page. + /// Number of the element from which the list is generated (the count starts from 0). + /// Defines localization of item's text fields.
    + /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// Publishing platform the user plays on.
    + /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. + public static void GetInventoryItems(Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null, string platform = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/inventory/items") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddPlatform(platform) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetInventoryItems(onSuccess, onError, limit, offset, locale, platform)), + ErrorGroup.ItemsListErrors); + } + + /// + /// Consumes an inventory item. Use for only for consumable virtual items. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/player-inventory/consume-item/). + /// Contains consume parameters. + /// Called after successful inventory item consumption. + /// Called after the request resulted with an error. + /// Publishing platform the user plays on.
    + /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. + public static void ConsumeInventoryItem(ConsumeItem item, Action onSuccess, Action onError, string platform = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/inventory/item/consume") + .AddPlatform(platform) + .Build(); + + var headers = new List { + WebRequestHeader.AuthHeader(), + WebRequestHeader.JsonContentTypeHeader() + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + item, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => ConsumeInventoryItem(item, onSuccess, onError, platform)), + ErrorGroup.ConsumeItemErrors); + } + + /// + /// Returns a list of time-limited items from the user’s inventory. For each item, complete data is returned. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/player-inventory/display-inventory/). + /// Called after list of user time limited items was successfully received. + /// Called after the request resulted with an error. + /// Publishing platform the user plays on.
    + /// Can be `xsolla` (default), `playstation_network`, `xbox_live`, `pc_standalone`, `nintendo_shop`, `google_play`, `app_store_ios`, `android_standalone`, `ios_standalone`, `android_other`, `ios_other`, or `pc_other`. + public static void GetTimeLimitedItems(Action onSuccess, Action onError, string platform = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/time_limited_items") + .AddPlatform(platform) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Store, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetTimeLimitedItems(onSuccess, onError, platform)), + ErrorGroup.ItemsListErrors); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Inventory/Api/XsollaInventory.cs.meta b/Assets/Xsolla/Inventory/XsollaInventory.cs.meta similarity index 100% rename from Assets/Xsolla/Inventory/Api/XsollaInventory.cs.meta rename to Assets/Xsolla/Inventory/XsollaInventory.cs.meta diff --git a/Assets/Xsolla/Obsolete.meta b/Assets/Xsolla/Obsolete.meta deleted file mode 100644 index 3d513e392..000000000 --- a/Assets/Xsolla/Obsolete.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: dc2019de18dcde5429acbaa1a73478f0 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Inventory.meta b/Assets/Xsolla/Obsolete/Inventory.meta deleted file mode 100644 index a795ac79d..000000000 --- a/Assets/Xsolla/Obsolete/Inventory.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: e05cf3ec7e2774f44ba657fe16289490 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Catalog.cs b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Catalog.cs deleted file mode 100644 index 7b0e49161..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Catalog.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using JetBrains.Annotations; -using Xsolla.Catalog; -using Xsolla.Core; - -namespace Xsolla.Store -{ - public partial class XsollaStore : MonoSingleton - { - [Obsolete("Use XsollaCatalog instead")] - public void GetCatalogShort(string projectId, Action onSuccess, Action onError = null, string locale = null) - => XsollaCatalog.Instance.GetCatalogSimplified(projectId, onSuccess, onError, locale); - - [Obsolete("Use XsollaCatalog instead")] - public void GetCatalog(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null, string additionalFields = "long_description", [CanBeNull] string country = null) - => XsollaCatalog.Instance.GetCatalog(projectId, onSuccess, onError, limit, offset, locale, additionalFields, country); - - [Obsolete("Use XsollaCatalog instead")] - public void GetBundle(string projectId, string sku, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, [CanBeNull] string country = null) - => XsollaCatalog.Instance.GetBundle(projectId, sku, onSuccess, onError, locale, country); - - [Obsolete("Use XsollaCatalog instead")] - public void GetBundles(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, int limit = 50, int offset = 0, string additionalFields = null, [CanBeNull] string country = null) - => XsollaCatalog.Instance.GetBundles(projectId, onSuccess, onError, limit, offset, locale, additionalFields, country); - - [Obsolete("Use XsollaCatalog instead")] - public void GetGroupItems(string projectId, string groupExternalId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int? limit = null, int? offset = null, [CanBeNull] string locale = null, string additionalFields = null, string country = null) - => XsollaCatalog.Instance.GetGroupItems(projectId, groupExternalId, onSuccess, onError, limit, offset, locale, additionalFields, country); - - [Obsolete("Use XsollaCatalog instead")] - public void GetItemGroups(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, int offset = 0, int limit = 50) - => XsollaCatalog.Instance.GetItemGroups(projectId, onSuccess, onError, limit, offset, locale); - } -} diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Catalog.cs.meta b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Catalog.cs.meta deleted file mode 100644 index 87b8ba466..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Catalog.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9a2e901c9885646c58cd67ba58110216 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.GameKeys.cs b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.GameKeys.cs deleted file mode 100644 index 121527e58..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.GameKeys.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using Xsolla.Core; -using Xsolla.GameKeys; - -namespace Xsolla.Store -{ - public partial class XsollaStore : MonoSingleton - { - [Obsolete("Use XsollaGameKeys instead")] - public void GetGamesList(string projectId, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string locale = null, string additionalFields = "long_description", string country = null) - => XsollaGameKeys.Instance.GetGamesList(projectId, onSuccess, onError, limit, offset, locale, additionalFields, country); - - [Obsolete("Use XsollaGameKeys instead")] - public void GetGamesListBySpecifiedGroup(string projectId, string groupId, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string locale = null, string additionalFields = "long_description", string country = null) - => XsollaGameKeys.Instance.GetGamesListBySpecifiedGroup(projectId, groupId, onSuccess, onError, limit, offset, locale, additionalFields, country); - - [Obsolete("Use XsollaGameKeys instead")] - public void GetGameForCatalog(string projectId, string itemSku, Action onSuccess, Action onError = null, string locale = null, string additionalFields = "long_description", string country = null) - => XsollaGameKeys.Instance.GetGameForCatalog(projectId, itemSku, onSuccess, onError, locale, additionalFields, country); - - [Obsolete("Use XsollaGameKeys instead")] - public void GetGameKeyForCatalog(string projectId, string itemSku, Action onSuccess, Action onError = null, string locale = null, string additionalFields = "long_description", string country = null) - => XsollaGameKeys.Instance.GetGameKeyForCatalog(projectId, itemSku, onSuccess, onError, locale, additionalFields, country); - - [Obsolete("Use XsollaGameKeys instead")] - public void GetGameKeysListBySpecifiedGroup(string projectId, string groupId, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string locale = null, string additionalFields = "long_description", string country = null) - => XsollaGameKeys.Instance.GetGameKeysListBySpecifiedGroup(projectId, groupId, onSuccess, onError, limit, offset, locale, additionalFields, country); - - [Obsolete("Use XsollaGameKeys instead")] - public void GetOwnedGames(string projectId, bool sandbox, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string additionalFields = "long_description") - => XsollaGameKeys.Instance.GetOwnedGames(projectId, sandbox, onSuccess, onError, limit, offset, additionalFields); - - [Obsolete("Use XsollaGameKeys instead")] - public void GetDrmList(string projectId, Action onSuccess, Action onError = null) - => XsollaGameKeys.Instance.GetDrmList(projectId, onSuccess, onError); - - [Obsolete("Use XsollaGameKeys instead")] - public void RedeemGameCode(string projectId, string gameCode, bool sandbox, Action onSuccess, Action onError = null) - => XsollaGameKeys.Instance.RedeemGameCode(projectId, gameCode, sandbox, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.GameKeys.cs.meta b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.GameKeys.cs.meta deleted file mode 100644 index 2da8112de..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.GameKeys.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 55530db9f619496dba22c32ef3d05d5a -timeCreated: 1634025952 \ No newline at end of file diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Inventory.cs b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Inventory.cs deleted file mode 100644 index e2e090d3e..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Inventory.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using JetBrains.Annotations; -using Xsolla.Catalog; -using Xsolla.Core; -using Xsolla.Inventory; - -namespace Xsolla.Store -{ - public partial class XsollaStore : MonoSingleton - { - [Obsolete("Use XsollaInventory instead")] - public void GetInventoryItems(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, int limit = 50, int offset = 0) - => XsollaInventory.Instance.GetInventoryItems(projectId, onSuccess, onError, limit, offset, locale); - - [Obsolete("Use XsollaInventory instead")] - public void ConsumeInventoryItem(string projectId, ConsumeItem item, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaInventory.Instance.ConsumeInventoryItem(projectId, item, onSuccess, onError); - - [Obsolete("Use XsollaCatalog instead")] - public void RedeemCouponCode(string projectId, CouponCode couponCode, [NotNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCatalog.Instance.RedeemCouponCode(projectId, couponCode, onSuccess, onError); - - [Obsolete("Use XsollaCatalog instead")] - public void GetCouponRewards(string projectId, string couponCode, [NotNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCatalog.Instance.GetCouponRewards(projectId, couponCode, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Inventory.cs.meta b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Inventory.cs.meta deleted file mode 100644 index 7d90d5989..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Inventory.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 3436d0a60e8170c45a701c732e38cee2 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Obsolete.cs b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Obsolete.cs deleted file mode 100644 index 72476fc6e..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Obsolete.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Store -{ - public partial class XsollaStore - { - [Obsolete] - public Token Token { get; set; } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Obsolete.cs.meta b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Obsolete.cs.meta deleted file mode 100644 index 73a394832..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.Obsolete.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: a93920eeed404a4aaf577a6f68f11486 -timeCreated: 1627976126 \ No newline at end of file diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.VirtualCurrency.cs b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.VirtualCurrency.cs deleted file mode 100644 index 8f8dd47fe..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.VirtualCurrency.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using JetBrains.Annotations; -using Xsolla.Catalog; -using Xsolla.Core; -using Xsolla.Inventory; - -namespace Xsolla.Store -{ - public partial class XsollaStore : MonoSingleton - { - [Obsolete("Use XsollaInventory instead")] - public void GetVirtualCurrencyBalance(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaInventory.Instance.GetVirtualCurrencyBalance(projectId, onSuccess, onError); - - [Obsolete("Use XsollaCatalog instead")] - public void GetVirtualCurrencyList(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null, string additionalFields = null, string country = null) - => XsollaCatalog.Instance.GetVirtualCurrencyList(projectId, onSuccess, onError, limit, offset, locale, additionalFields, country); - - [Obsolete("Use XsollaCatalog instead")] - public void GetVirtualCurrencyPackagesList(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, int limit = 50, int offset = 0, [CanBeNull] string locale = null, string additionalFields = null, string country = null) - => XsollaCatalog.Instance.GetVirtualCurrencyPackagesList(projectId, onSuccess, onError, limit, offset, locale, additionalFields, country); - } -} diff --git a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.VirtualCurrency.cs.meta b/Assets/Xsolla/Obsolete/Inventory/XsollaStore.VirtualCurrency.cs.meta deleted file mode 100644 index 1eac15b46..000000000 --- a/Assets/Xsolla/Obsolete/Inventory/XsollaStore.VirtualCurrency.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b9765ac9c0be03a48bad23e4117ef85c -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Login.meta b/Assets/Xsolla/Obsolete/Login.meta deleted file mode 100644 index d49847ee8..000000000 --- a/Assets/Xsolla/Obsolete/Login.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: fe26b020209a1d64db7f7782268c14af -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.AccountLinking.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.AccountLinking.cs deleted file mode 100644 index 1c81cd5ea..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.AccountLinking.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using Xsolla.Auth; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Login -{ - public partial class XsollaLogin : MonoSingleton - { - [Obsolete("Use XsollaAuth instead")] - public void SignInConsoleAccount(string userId, string platform, Action successCase, Action failedCase) - => XsollaAuth.Instance.SignInConsoleAccount(userId, platform, successCase, failedCase); - - [Obsolete("Use XsollaUserAccount instead")] - public void RequestLinkingCode(Action onSuccess, Action onError) - => XsollaUserAccount.Instance.RequestLinkingCode(onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void LinkConsoleAccount(string userId, string platform, string confirmationCode, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.LinkConsoleAccount(userId, platform, confirmationCode, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.AccountLinking.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.AccountLinking.cs.meta deleted file mode 100644 index 3fc73962f..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.AccountLinking.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 9af11d3a1554d4b4698f71d66f03a0a3 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Attributes.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.Attributes.cs deleted file mode 100644 index 0fda7805b..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Attributes.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using System.Collections.Generic; -using JetBrains.Annotations; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Login -{ - public partial class XsollaLogin : MonoSingleton - { - [Obsolete("Use XsollaUserAccount instead")] - public void GetUserAttributes(string token, string publisherProjectId, UserAttributeType attributeType, [CanBeNull] List keys, [CanBeNull] string userId, [NotNull] Action> onSuccess, [CanBeNull] Action onError) - => XsollaUserAccount.Instance.GetUserAttributes(token, publisherProjectId, attributeType, keys, userId, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void UpdateUserAttributes(string token, string publisherProjectId, List attributes, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.UpdateUserAttributes(token, publisherProjectId, attributes, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void RemoveUserAttributes(string token, string publisherProjectId, List removingKeys, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.RemoveUserAttributes(token, publisherProjectId, removingKeys, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Attributes.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.Attributes.cs.meta deleted file mode 100644 index 11f633038..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Attributes.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 850b7af503f484d4b99cd71af935b902 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.DeviceID.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.DeviceID.cs deleted file mode 100644 index 579a549ba..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.DeviceID.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Auth; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Login -{ - public partial class XsollaLogin : MonoSingleton - { - [Obsolete("Use XsollaAuth instead")] - public void AuthViaDeviceID(DeviceType deviceType, string device, string deviceId, string payload = null, string state = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.AuthViaDeviceID(deviceType, device, deviceId, payload, state, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void AddUsernameEmailAuthToAccount(string username, string password, string email, int? promoEmailAgreement = null, Action onSuccess = null, Action onError = null) - => XsollaUserAccount.Instance.AddUsernameEmailAuthToAccount(username, password, email, promoEmailAgreement, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void GetUserDevices(Action> onSuccess = null, Action onError = null) - => XsollaUserAccount.Instance.GetUserDevices(onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void LinkDeviceToAccount(DeviceType deviceType, string device, string deviceId, Action onSuccess = null, Action onError = null) - => XsollaUserAccount.Instance.LinkDeviceToAccount(deviceType, device, deviceId, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void UnlinkDeviceFromAccount(int id, Action onSuccess = null, Action onError = null) - => XsollaUserAccount.Instance.UnlinkDeviceFromAccount(id, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.DeviceID.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.DeviceID.cs.meta deleted file mode 100644 index 38c9a9ef2..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.DeviceID.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 20edd249f7cd3904b8f6680ff0476ca5 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Friends.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.Friends.cs deleted file mode 100644 index 9cadd4bb5..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Friends.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Login -{ - public partial class XsollaLogin : MonoSingleton - { - - [Obsolete("Use XsollaUserAccount instead")] - public void GetUserSocialFriends(string token, SocialProvider platform = SocialProvider.None, uint offset = 0, uint limit = 500, bool withXlUid = false, Action onSuccess = null, Action onError = null) - => XsollaUserAccount.Instance.GetUserSocialFriends(token, platform, offset, limit, withXlUid, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void UpdateUserSocialFriends(string token, SocialProvider platform = SocialProvider.None, Action onSuccess = null, Action onError = null) - => XsollaUserAccount.Instance.UpdateUserSocialFriends(token, platform, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void GetUserFriends( - string token, - FriendsSearchType type, - FriendsSearchResultsSort sortBy = FriendsSearchResultsSort.ByNickname, - FriendsSearchResultsSortOrder sortOrder = FriendsSearchResultsSortOrder.Asc, - string after = null, - int? limit = null, - Action> onSuccess = null, Action onError = null) - => XsollaUserAccount.Instance.GetUserFriends(token, type, sortBy, sortOrder, after, limit, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void UpdateUserFriends(string token, FriendAction action, string user, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.UpdateUserFriends(token, action, user, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Friends.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.Friends.cs.meta deleted file mode 100644 index 512c1df86..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Friends.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 2ba73285cef245daad15b991fcc2d4bd -timeCreated: 1597114861 \ No newline at end of file diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.OAuthRefreshToken.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.OAuthRefreshToken.cs deleted file mode 100644 index 819a7a29a..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.OAuthRefreshToken.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Xsolla.Auth; -using Xsolla.Core; - -namespace Xsolla.Login -{ - public partial class XsollaLogin : MonoSingleton - { - [Obsolete("Obsolete and will always return false")] - public bool IsOAuthTokenRefreshInProgress - => false; - - [Obsolete("Use XsollaAuth instead")] - public void ExchangeCodeToToken(string code, Action onSuccessExchange = null, Action onError = null) - => XsollaAuth.Instance.ExchangeCodeToToken(code, onSuccessExchange, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.OAuthRefreshToken.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.OAuthRefreshToken.cs.meta deleted file mode 100644 index d88866b99..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.OAuthRefreshToken.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: f0fc0f722db41c743aa365325d58f714 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Obsolete.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.Obsolete.cs deleted file mode 100644 index 6e8bd9162..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Obsolete.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Login -{ - public partial class XsollaLogin - { - [Obsolete] - public Token Token - { - get => Core.Token.Instance; - set => Core.Token.Instance = value; - } - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Obsolete.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.Obsolete.cs.meta deleted file mode 100644 index f9df14ada..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Obsolete.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: c5e0a4079fe3448ebd8d7589eb89ede2 -timeCreated: 1627975775 \ No newline at end of file diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Social.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.Social.cs deleted file mode 100644 index 4abd3b055..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Social.cs +++ /dev/null @@ -1,31 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Auth; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Login -{ - public partial class XsollaLogin : MonoSingleton - { - [Obsolete("Use XsollaAuth instead")] - public void SteamAuth(string appId, string sessionTicket, string redirect_uri = null, List fields = null, string oauthState = null, string payload = null, string code = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.SilentAuth("steam", appId, sessionTicket, redirect_uri, fields, oauthState, payload, code, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public string GetSocialNetworkAuthUrl(SocialProvider providerName, string oauthState = null, List fields = null, string payload = null) - => XsollaAuth.Instance.GetSocialNetworkAuthUrl(providerName, oauthState, fields, payload); - - [Obsolete("Use XsollaUserAccount instead")] - public void LinkSocialProvider(SocialProvider providerName, Action urlCallback, Action onError = null) - => XsollaUserAccount.Instance.LinkSocialProvider(providerName, urlCallback, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void GetLinkedSocialProviders(Action> onSuccess, Action onError = null) - => XsollaUserAccount.Instance.GetLinkedSocialProviders(onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void GetLinksForSocialAuth(string locale = null, Action> onSuccess = null, Action onError = null) - => XsollaAuth.Instance.GetLinksForSocialAuth(locale, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Social.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.Social.cs.meta deleted file mode 100644 index ddacf888f..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.Social.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 8494336deb6154ea58ff668baefa4d48 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.User.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.User.cs deleted file mode 100644 index f7d249488..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.User.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Auth; -using Xsolla.Core; -using Xsolla.UserAccount; - -namespace Xsolla.Login -{ - public partial class XsollaLogin : MonoSingleton - { - [Obsolete("Use XsollaAuth instead")] - public void GetUserInfo(string token, Action onSuccess, Action onError = null) => XsollaAuth.Instance.GetUserInfo(token, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void UpdateUserInfo(string token, UserInfoUpdate info, Action onSuccess, Action onError = null) - => XsollaUserAccount.Instance.UpdateUserInfo(token, info, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void Registration(string username, string password, string email, string redirectUri = null, string state = null, string payload = null, bool? acceptConsent = null, bool? promoEmailAgreement = null, List fields = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.Register(username, password, email, redirectUri, state, payload, acceptConsent, promoEmailAgreement, fields, onSuccess:onSuccess, onError:onError); - - [Obsolete("Use XsollaAuth instead")] - public void Registration(string username, string password, string email, string redirectUri = null, string oauthState = null, string payload = null, bool? acceptConsent = null, bool? promoEmailAgreement = null, List fields = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.Register(username, password, email, redirectUri, oauthState, payload, acceptConsent, promoEmailAgreement, fields, onSuccess:onSuccess, onError:onError); - - [Obsolete("Use XsollaAuth instead")] - public void Registration(string username, string password, string email, string redirectUri = null, string oauthState = null, string payload = null, bool? acceptConsent = null, bool? promoEmailAgreement = null, List fields = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.Register(username, password, email, redirectUri, oauthState, payload, acceptConsent, promoEmailAgreement, fields, onSuccess:onSuccess, onError:onError); - - [Obsolete("Use XsollaAuth instead")] - public void SignIn(string username, string password, bool rememberMe, string redirectUri = null, string payload = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.SignIn(username, password, rememberMe, redirectUri, payload, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void StartAuthByEmail(string email, string linkUrl, bool? sendLink, Action onSuccess, Action onError = null) - => XsollaAuth.Instance.StartAuthByEmail(email, linkUrl, sendLink, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void CompleteAuthByEmail(string email, string confirmationCode, string operationId, Action onSuccess, Action onError = null) - => XsollaAuth.Instance.CompleteAuthByEmail(email, confirmationCode, operationId, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void StartAuthByPhoneNumber(string phoneNumber, string linkUrl, bool sendLink, Action onSuccess, Action onError = null) - => XsollaAuth.Instance.StartAuthByPhoneNumber(phoneNumber, linkUrl, sendLink, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void CompleteAuthByPhoneNumber(string phoneNumber, string confirmationCode, string operationId, Action onSuccess, Action onError = null) - => XsollaAuth.Instance.CompleteAuthByPhoneNumber(phoneNumber, confirmationCode, operationId, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void ResetPassword(string email, string redirectUri = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.ResetPassword(email, redirectUri, onSuccess:onSuccess, onError:onError); - - [Obsolete("Use XsollaAuth instead")] - public void ResendConfirmationLink(string username, string redirectUri = null, string state = null, string payload = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.ResendConfirmationLink(username, redirectUri, state, payload, onSuccess:onSuccess, onError:onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void SearchUsers(string token, string nickname, uint offset, uint limit, Action onSuccess, Action onError = null) - => XsollaUserAccount.Instance.SearchUsers(token, nickname, offset, limit, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void GetPublicInfo(string token, string userId, Action onSuccess, Action onError = null) - => XsollaUserAccount.Instance.GetPublicInfo(token, userId, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void GetUserPhoneNumber(string token, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.GetUserPhoneNumber(token, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void ChangeUserPhoneNumber(string token, string phoneNumber, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.UpdateUserPhoneNumber(token, phoneNumber, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void DeleteUserPhoneNumber(string token, string phoneNumber, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.DeleteUserPhoneNumber(token, phoneNumber, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void UploadUserPicture(string token, byte[] pictureData, string boundary, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.UploadUserPicture(token, pictureData, boundary, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void DeleteUserPicture(string token, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.DeleteUserPicture(token, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void CheckUserAge(string dateOfBirth, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.CheckUserAge(dateOfBirth, onSuccess, onError); - - [Obsolete("Use XsollaUserAccount instead")] - public void GetUserEmail(string token, Action onSuccess, Action onError) - => XsollaUserAccount.Instance.GetUserEmail(token, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void AuthWithSocialNetworkAccessToken(string accessToken, string accessTokenSecret, string openId, string providerName, string payload, string state = null, Action onSuccess = null, Action onError = null) - => XsollaAuth.Instance.AuthWithSocialNetworkAccessToken(accessToken, accessTokenSecret, openId, providerName, payload, state, onSuccess, onError); - - [Obsolete("Use XsollaAuth instead")] - public void OAuthLogout(string token, OAuthLogoutType sessions, Action onSuccess, Action onError = null) - => XsollaAuth.Instance.OAuthLogout(token, sessions, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.User.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.User.cs.meta deleted file mode 100644 index 78edd85cf..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.User.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 56687ff3c172544bca1b2d02d51b89c9 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.cs b/Assets/Xsolla/Obsolete/Login/XsollaLogin.cs deleted file mode 100644 index 25614f8a0..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Xsolla.Core; -using JetBrains.Annotations; -using Xsolla.Auth; - -namespace Xsolla.Login -{ - [PublicAPI] - public partial class XsollaLogin : MonoSingleton - { - [Obsolete("Use XsollaAuth instead")] - public void DeleteToken(string key) => XsollaAuth.Instance.DeleteToken(key); - - [Obsolete("Use XsollaAuth instead")] - public void SaveToken(string key, string token) => XsollaAuth.Instance.SaveToken(key,token); - } -} diff --git a/Assets/Xsolla/Obsolete/Login/XsollaLogin.cs.meta b/Assets/Xsolla/Obsolete/Login/XsollaLogin.cs.meta deleted file mode 100644 index 2e9c15d03..000000000 --- a/Assets/Xsolla/Obsolete/Login/XsollaLogin.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 0d78907c5a4da7c4a872f9cc11c6f53e -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Store.meta b/Assets/Xsolla/Obsolete/Store.meta deleted file mode 100644 index 6e3966389..000000000 --- a/Assets/Xsolla/Obsolete/Store.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 58a3ecdb5f9cee24088f5aa835e0454f -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Store/XsollaStore.Cart.cs b/Assets/Xsolla/Obsolete/Store/XsollaStore.Cart.cs deleted file mode 100644 index e73d7f8fd..000000000 --- a/Assets/Xsolla/Obsolete/Store/XsollaStore.Cart.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; -using System.Collections.Generic; -using JetBrains.Annotations; -using Xsolla.Cart; -using Xsolla.Core; - -namespace Xsolla.Store -{ - public partial class XsollaStore : MonoSingleton - { - [Obsolete("Use XsollaCart instead")] - public void GetCartItems(string projectId, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, [CanBeNull] string currency = null) - => XsollaCart.Instance.GetCartItems(projectId, onSuccess, onError, locale, currency); - - [Obsolete("Use XsollaCart instead")] - public void GetCartItems(string projectId, string cartId, [NotNull] Action onSuccess, [CanBeNull] Action onError, [CanBeNull] string locale = null, [CanBeNull] string currency = null) - => XsollaCart.Instance.GetCartItems(projectId, cartId, onSuccess, onError, locale, currency); - - [Obsolete("Use XsollaCart instead")] - public void FillCart(string projectId, List items, [NotNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.FillCart(projectId, items, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void FillCart(string projectId, string cartId, List items, [NotNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.FillCart(projectId, cartId, items, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void UpdateItemInCart(string projectId, string itemSku, int quantity, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.UpdateItemInCart(projectId, itemSku, quantity, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void UpdateItemInCart(string projectId, string cartId, string itemSku, int quantity, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.UpdateItemInCart(projectId, cartId, itemSku, quantity, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void ClearCart(string projectId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.ClearCart(projectId, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void ClearCart(string projectId, string cartId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.ClearCart(projectId, cartId, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void RemoveItemFromCart(string projectId, string itemSku, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.RemoveItemFromCart(projectId, itemSku, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void RemoveItemFromCart(string projectId, string cartId, string itemSku, [CanBeNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.RemoveItemFromCart(projectId, cartId, itemSku, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void RedeemPromocode(string projectId, string promocode, string cartId, [NotNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.RedeemPromocode(projectId, promocode, cartId, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void GetPromocodeReward(string projectId, string promocode, [NotNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaCart.Instance.GetPromocodeReward(projectId, promocode, onSuccess, onError); - - [Obsolete("Use XsollaCart instead")] - public void RemovePromocodeFromCart(string projectId, string cartId, Action onSuccess, Action onError = null) - => XsollaCart.Instance.RemovePromocodeFromCart(projectId, cartId, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Store/XsollaStore.Cart.cs.meta b/Assets/Xsolla/Obsolete/Store/XsollaStore.Cart.cs.meta deleted file mode 100644 index bc8947281..000000000 --- a/Assets/Xsolla/Obsolete/Store/XsollaStore.Cart.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b803396ead2e0467f834baded4e2e1d8 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Store/XsollaStore.Payments.cs b/Assets/Xsolla/Obsolete/Store/XsollaStore.Payments.cs deleted file mode 100644 index 9793ea72d..000000000 --- a/Assets/Xsolla/Obsolete/Store/XsollaStore.Payments.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using JetBrains.Annotations; -using Xsolla.Cart; -using Xsolla.Catalog; -using Xsolla.Core; -using Xsolla.Orders; - -namespace Xsolla.Store -{ - public partial class XsollaStore : MonoSingleton - { - [Obsolete("Use XsollaCatalog instead")] - public void ItemPurchase(string projectId, string itemSku, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null) - => XsollaCatalog.Instance.PurchaseItem(projectId, itemSku, onSuccess, onError, purchaseParams); - - [Obsolete("Use XsollaCatalog instead")] - public void ItemPurchaseForVirtualCurrency( - string projectId, - string itemSku, - string priceSku, - [CanBeNull] Action onSuccess, - [CanBeNull] Action onError, - PurchaseParams purchaseParams = null) - => XsollaCatalog.Instance.PurchaseItemForVirtualCurrency(projectId, itemSku, priceSku, onSuccess, onError, purchaseParams); - - [Obsolete("Use XsollaCart instead")] - public void CartPurchase(string projectId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null) - => XsollaCart.Instance.PurchaseCart(projectId, onSuccess, onError, purchaseParams); - - [Obsolete("Use XsollaCart instead")] - public void CartPurchase(string projectId, string cartId, [CanBeNull] Action onSuccess, [CanBeNull] Action onError, PurchaseParams purchaseParams = null) - => XsollaCart.Instance.PurchaseCart(projectId, cartId, onSuccess, onError, purchaseParams); - - [Obsolete("Use XsollaOrders instead")] - public void OpenPurchaseUi(PurchaseData purchaseData, bool forcePlatformBrowser = false, Action onRestrictedPaymentMethod = null) - => XsollaOrders.Instance.OpenPurchaseUi(purchaseData, forcePlatformBrowser, onRestrictedPaymentMethod); - - [Obsolete("Use XsollaOrders instead")] - public void CheckOrderStatus(string projectId, int orderId, [NotNull] Action onSuccess, [CanBeNull] Action onError) - => XsollaOrders.Instance.CheckOrderStatus(projectId, orderId, onSuccess, onError); - - [Obsolete("Use XsollaOrders instead")] - public void CreatePaymentToken( - string projectId, - float amount, - string currency, - string description, - string locale = null, - string externalID = null, - int? paymentMethod = null, - object customParameters = null, - Action onSuccess = null, - [CanBeNull] Action onError = null) - => XsollaOrders.Instance.CreatePaymentToken(projectId, amount, currency, description, locale, externalID, paymentMethod, customParameters, onSuccess, onError); - - [Obsolete("Use XsollaOrders instead")] - public void CreatePaymentToken( - string projectId, - float amount, - string currency, - PaymentTokenItem[] items, - string locale = null, - string externalID = null, - int? paymentMethod = null, - object customParameters = null, - Action onSuccess = null, - [CanBeNull] Action onError = null) - => XsollaOrders.Instance.CreatePaymentToken(projectId, amount, currency, items, locale, externalID, paymentMethod, customParameters, onSuccess, onError); - } -} diff --git a/Assets/Xsolla/Obsolete/Store/XsollaStore.Payments.cs.meta b/Assets/Xsolla/Obsolete/Store/XsollaStore.Payments.cs.meta deleted file mode 100644 index c1a86baeb..000000000 --- a/Assets/Xsolla/Obsolete/Store/XsollaStore.Payments.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b79a1a3397b34644f9d1c2763427d242 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Obsolete/Xsolla.asmref b/Assets/Xsolla/Obsolete/Xsolla.asmref deleted file mode 100644 index 24634ea00..000000000 --- a/Assets/Xsolla/Obsolete/Xsolla.asmref +++ /dev/null @@ -1,3 +0,0 @@ -{ - "reference": "GUID:ae0cf701846f0cc4bbd067c4edd4fe90" -} \ No newline at end of file diff --git a/Assets/Xsolla/Obsolete/Xsolla.asmref.meta b/Assets/Xsolla/Obsolete/Xsolla.asmref.meta deleted file mode 100644 index accd21d4e..000000000 --- a/Assets/Xsolla/Obsolete/Xsolla.asmref.meta +++ /dev/null @@ -1,7 +0,0 @@ -fileFormatVersion: 2 -guid: 602b6dab05b9d0543ade0b0ee9c6a1e5 -AssemblyDefinitionReferenceImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Orders/Api.meta b/Assets/Xsolla/Orders/Api.meta deleted file mode 100644 index 7fe8dd07e..000000000 --- a/Assets/Xsolla/Orders/Api.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f211d98cc827ed9468903865e69c1588 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Orders/Api/XsollaOrders.cs b/Assets/Xsolla/Orders/Api/XsollaOrders.cs deleted file mode 100644 index 5a1038edd..000000000 --- a/Assets/Xsolla/Orders/Api/XsollaOrders.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Collections.Generic; -using JetBrains.Annotations; -using Xsolla.Core; - -namespace Xsolla.Orders -{ - public class XsollaOrders : MonoSingleton - { - private const string URL_ORDER_GET_STATUS = Constants.BASE_STORE_API_URL + "/order/{1}"; - private const string URL_PAYSTATION_UI = "https://secure.xsolla.com/paystation3/?access_token="; - private const string URL_PAYSTATION_UI_IN_SANDBOX_MODE = "https://sandbox-secure.xsolla.com/paystation3/?access_token="; - private const string URL_CREATE_PAYMENT_TOKEN = Constants.BASE_STORE_API_URL + "/payment"; - - /// - /// Opens Pay Station in the browser with a retrieved Pay Station token. - /// - /// More about the use cases: - /// - [Cart purchase](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/) - /// - [Purchase in one click](https://developers.xsolla.com/sdk/unity/item-purchase/one-click-purchase/) - /// - [Ordering free items](https://developers.xsolla.com/sdk/unity/promo/free-items/#sdk_free_items_order_item_via_cart) - /// - /// Contains Pay Station token for the purchase. - /// Whether to force platform browser usage ignoring plug-in settings. - /// Restricted payment method was triggered in an built-in browser. - /// Called after the browser was closed. - /// - public void OpenPurchaseUi(PurchaseData purchaseData, bool forcePlatformBrowser = false, Action onRestrictedPaymentMethod = null, Action onBrowserClosed = null) - { - string url = XsollaSettings.IsSandbox ? URL_PAYSTATION_UI_IN_SANDBOX_MODE : URL_PAYSTATION_UI; - BrowserHelper.Instance.OpenPurchase( - url, - purchaseData.token, - forcePlatformBrowser, - onRestrictedPaymentMethod, - onBrowserClosed); - } - - /// - /// Returns status of the specified order. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/track-order/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Unique order identifier. - /// Called after server response. - /// Called after the request resulted with an error. - /// - /// - public void CheckOrderStatus(string projectId, int orderId, [NotNull] Action onSuccess, [CanBeNull] Action onError) - { - var url = string.Format(URL_ORDER_GET_STATUS, projectId, orderId); - WebRequestHelper.Instance.GetRequest(SdkType.Store, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => CheckOrderStatus(projectId, orderId, onSuccess, onError)), - ErrorCheckType.OrderStatusErrors); - } - - /// - /// Creates a new payment token. - /// - /// Project ID, can be found in Publisher Account next to the name of the project. - /// The total amount to be paid by the user. - /// Default purchase currency. Three-letter code per [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (USD by default). - /// Purchase description. Used to describe the purchase if there are no specific items. - /// Interface language.
    - /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// Transaction's external ID. - /// Payment method ID. - /// Your custom parameters represented as a valid JSON set of key-value pairs. - /// Called after the successful item purchase. - /// Called after the request resulted with an error. - public void CreatePaymentToken( - string projectId, - float amount, - string currency, - string description, - string locale = null, - string externalID = null, - int? paymentMethod = null, - object customParameters = null, - Action onSuccess = null, - [CanBeNull] Action onError = null) - { - var url = string.Format(URL_CREATE_PAYMENT_TOKEN, projectId); - - var checkout = new CreatePaymentTokenRequest.Purchase.Checkout(amount, currency); - var purchaseDescription = new CreatePaymentTokenRequest.Purchase.Description(description); - var purchase = new CreatePaymentTokenRequest.Purchase(checkout, purchaseDescription); - var settings = GeneratePaymentTokenSettings(currency, locale, externalID, paymentMethod); - var requestBody = new CreatePaymentTokenRequest(purchase, settings, customParameters); - - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, requestBody, PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => CreatePaymentToken(projectId, amount, currency, description, locale, externalID, paymentMethod, customParameters, onSuccess, onError)), - ErrorCheckType.BuyItemErrors); - } - - /// - /// Creates a new payment token. - /// - /// Project ID, can be found in Publisher Account next to the name of the project. - /// The total amount to be paid by the user. - /// Default purchase currency. Three-letter code per [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (USD by deafault). - /// Used to describe a purchase if it includes a list of specific items. - /// Interface language.
    - /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// Transaction's external ID. - /// Payment method ID. - /// Your custom parameters represented as a valid JSON set of key-value pairs. - /// Called after the successful item purchase. - /// Called after the request resulted with an error. - public void CreatePaymentToken( - string projectId, - float amount, - string currency, - PaymentTokenItem[] items, - string locale = null, - string externalID = null, - int? paymentMethod = null, - object customParameters = null, - Action onSuccess = null, - [CanBeNull] Action onError = null) - { - var url = string.Format(URL_CREATE_PAYMENT_TOKEN, projectId); - - var checkout = new CreatePaymentTokenRequest.Purchase.Checkout(amount, currency); - - var purchaseItems = new List(items.Length); - foreach (var item in items) - { - var price = new CreatePaymentTokenRequest.Purchase.Item.Price(item.amount, item.amountBeforeDiscount); - var purchaseItem = new CreatePaymentTokenRequest.Purchase.Item(item.name, price, item.imageUrl, item.description, item.quantity, item.isBouns); - purchaseItems.Add(purchaseItem); - } - - var purchase = new CreatePaymentTokenRequest.Purchase(checkout, purchaseItems.ToArray()); - var settings = GeneratePaymentTokenSettings(currency, locale, externalID, paymentMethod); - var requestBody = new CreatePaymentTokenRequest(purchase, settings, customParameters); - - WebRequestHelper.Instance.PostRequest(SdkType.Store, url, requestBody, PurchaseParamsGenerator.GetPaymentHeaders(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => CreatePaymentToken(projectId, amount, currency, items, locale, externalID, paymentMethod, customParameters, onSuccess, onError)), - ErrorCheckType.BuyItemErrors); - } - - private CreatePaymentTokenRequest.Settings GeneratePaymentTokenSettings(string currency, string locale, string externalID, int? paymentMethod) - { - var baseSettings = new TempPurchaseParams.Settings(); - baseSettings.ui = PayStationUISettings.GenerateSettings(); - baseSettings.redirect_policy = RedirectPolicySettings.GeneratePolicy(); - baseSettings.return_url = baseSettings.redirect_policy?.return_url; - - var settings = new CreatePaymentTokenRequest.Settings(); - settings.return_url = baseSettings.return_url; - settings.ui = baseSettings.ui; - settings.redirect_policy = baseSettings.redirect_policy; - - settings.currency = currency; - settings.locale = locale; - settings.sandbox = XsollaSettings.IsSandbox; - settings.external_id = externalID; - settings.payment_method = paymentMethod; - - return settings; - } - } -} diff --git a/Assets/Xsolla/Orders/Entities/TokenEntity.cs b/Assets/Xsolla/Orders/Entities/PaymentToken.cs similarity index 76% rename from Assets/Xsolla/Orders/Entities/TokenEntity.cs rename to Assets/Xsolla/Orders/Entities/PaymentToken.cs index b9ee8c3f7..611ca600f 100644 --- a/Assets/Xsolla/Orders/Entities/TokenEntity.cs +++ b/Assets/Xsolla/Orders/Entities/PaymentToken.cs @@ -3,7 +3,7 @@ namespace Xsolla.Orders { [Serializable] - public class TokenEntity + public class PaymentToken { public string token; } diff --git a/Assets/Xsolla/Orders/Entities/PaymentToken.cs.meta b/Assets/Xsolla/Orders/Entities/PaymentToken.cs.meta new file mode 100644 index 000000000..04c928b4d --- /dev/null +++ b/Assets/Xsolla/Orders/Entities/PaymentToken.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d65a1e2b01064447b342651f6330e704 +timeCreated: 1683082215 \ No newline at end of file diff --git a/Assets/Xsolla/Orders/Entities/PaymentTokenItem.cs b/Assets/Xsolla/Orders/Entities/PaymentTokenItem.cs index 1d01feba0..123a36987 100644 --- a/Assets/Xsolla/Orders/Entities/PaymentTokenItem.cs +++ b/Assets/Xsolla/Orders/Entities/PaymentTokenItem.cs @@ -2,24 +2,12 @@ namespace Xsolla.Orders { public class PaymentTokenItem { - public readonly string name; - public readonly string amount; - public readonly string amountBeforeDiscount; - public readonly string imageUrl; - public readonly string description; - public readonly int? quantity; - public readonly bool? isBouns; - - public PaymentTokenItem(string name, string amount, - string amountBeforeDiscount = null, string imageUrl = null, string description = null, int? quantity = null, bool? isBouns = null) - { - this.name = name; - this.amount = amount; - this.amountBeforeDiscount = amountBeforeDiscount; - this.imageUrl = imageUrl; - this.description = description; - this.quantity = quantity; - this.isBouns = isBouns; - } + public string Name; + public string Amount; + public string AmountBeforeDiscount; + public string ImageUrl; + public string Description; + public int? Quantity; + public bool? IsBonus; } } \ No newline at end of file diff --git a/Assets/Xsolla/Orders/Internal.meta b/Assets/Xsolla/Orders/Internal.meta new file mode 100644 index 000000000..e920abc69 --- /dev/null +++ b/Assets/Xsolla/Orders/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 58e02a280f19411a99831270f801c541 +timeCreated: 1683260303 \ No newline at end of file diff --git a/Assets/Xsolla/Orders/Entities/CreatePaymentTokenRequest.cs b/Assets/Xsolla/Orders/Internal/CreatePaymentTokenRequest.cs similarity index 65% rename from Assets/Xsolla/Orders/Entities/CreatePaymentTokenRequest.cs rename to Assets/Xsolla/Orders/Internal/CreatePaymentTokenRequest.cs index e00ac49f9..9f48e088a 100644 --- a/Assets/Xsolla/Orders/Entities/CreatePaymentTokenRequest.cs +++ b/Assets/Xsolla/Orders/Internal/CreatePaymentTokenRequest.cs @@ -1,63 +1,46 @@ using System; -using Newtonsoft.Json; using Xsolla.Core; namespace Xsolla.Orders { [Serializable] - public class CreatePaymentTokenRequest + internal class CreatePaymentTokenRequest { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Settings settings; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public object custom_parameters; - public Purchase purchase; - - public CreatePaymentTokenRequest(Purchase purchase, Settings settings = null, object custom_parameters = null) + public CreatePaymentTokenRequest(Purchase purchase, Settings settings, object custom_parameters) { this.settings = settings; this.custom_parameters = custom_parameters; this.purchase = purchase; } - [Serializable] - public class Settings : TempPurchaseParams.Settings + public class Settings { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] + public string return_url; + public PayStationUI ui; + public RedirectPolicy redirect_policy; public string currency; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string locale; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? sandbox; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string external_id; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public int? payment_method; } - [Serializable] public class Purchase { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Item[] items; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Description description; public Checkout checkout; public Purchase(Checkout checkout, Description description) { - this.items = null; + items = null; this.description = description; this.checkout = checkout; } @@ -65,7 +48,7 @@ public Purchase(Checkout checkout, Description description) public Purchase(Checkout checkout, Item[] items) { this.items = items; - this.description = null; + description = null; this.checkout = checkout; } @@ -73,19 +56,10 @@ public Purchase(Checkout checkout, Item[] items) public class Item { public string name; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string image_url; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string description; - public Price price; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public int? quantity; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? is_bonus; public Item(string name, Price price, string image_url = null, string description = null, int? quantity = null, bool? is_bonus = null) @@ -102,8 +76,6 @@ public Item(string name, Price price, string image_url = null, string descriptio public class Price { public string amount; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string amount_before_discount; public Price(string amount, string amount_before_discount = null) diff --git a/Assets/Xsolla/Orders/Entities/CreatePaymentTokenRequest.cs.meta b/Assets/Xsolla/Orders/Internal/CreatePaymentTokenRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/Entities/CreatePaymentTokenRequest.cs.meta rename to Assets/Xsolla/Orders/Internal/CreatePaymentTokenRequest.cs.meta diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTracker.cs b/Assets/Xsolla/Orders/OrderTracking/OrderTracker.cs deleted file mode 100644 index 396fcc7dd..000000000 --- a/Assets/Xsolla/Orders/OrderTracking/OrderTracker.cs +++ /dev/null @@ -1,83 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using UnityEngine; -using Xsolla.Core; - -namespace Xsolla.Orders -{ - public abstract class OrderTracker - { - private readonly OrderTrackingData _trackingData; - private bool _isCheckInProgress = false; - - public OrderTrackingData TrackingData => _trackingData; - - public abstract void Start(); - public abstract void Stop(); - - protected void RemoveSelfFromTracking() - { - OrderTracking.Instance.RemoveOrderFromTracking(TrackingData.orderId); - } - - protected void CheckOrderStatus(Action onDone = null, Action onCancel = null, Action onError = null) - { - if (Token.Instance == null) - { - Debug.LogWarning("No Token in order status check. Check cancelled"); - onCancel?.Invoke(); - return; - } - - if (_isCheckInProgress) // Prevent double check - return; - - _isCheckInProgress = true; - - var orderId = TrackingData.orderId; - XsollaOrders.Instance.CheckOrderStatus( - TrackingData.projectId, - TrackingData.orderId, - status => - { - _isCheckInProgress = false; - HandleOrderStatus(status.status, onDone, onCancel); - }, - error => - { - _isCheckInProgress = false; - onError?.Invoke(error); - } - ); - } - - protected void HandleOrderStatus(string status, Action onDone, Action onCancel) - { - switch (status) - { - case "done": - onDone?.Invoke(); - break; - case "canceled": - onCancel?.Invoke(); - break; - } - } - - protected Coroutine StartCoroutine(IEnumerator routine) - { - return OrderTracking.Instance.StartCoroutine(routine); - } - - protected void StopCoroutine(Coroutine routine) - { - OrderTracking.Instance.StopCoroutine(routine); - } - - protected OrderTracker(OrderTrackingData trackingData) - { - _trackingData = trackingData; - } - } -} diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByShortPolling.cs b/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByShortPolling.cs deleted file mode 100644 index d4faf8795..000000000 --- a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByShortPolling.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections; -using UnityEngine; -using Xsolla.Core; - -namespace Xsolla.Orders -{ - public class OrderTrackerByShortPolling : OrderTracker - { - public static float ShortPollingInterval {get;set;} = 3f; - public static float ShortPollingSecondsLimit {get;set;} = 600f; - - private Coroutine checkStatusCoroutine; - - public override void Start() - { - checkStatusCoroutine = base.StartCoroutine(CheckOrderStatus()); - } - - public override void Stop() - { - if (checkStatusCoroutine != null) - base.StopCoroutine(checkStatusCoroutine); - } - - private IEnumerator CheckOrderStatus() - { - var interval = new WaitForSeconds(ShortPollingInterval); - var limit = Time.time + ShortPollingSecondsLimit; - - Action onDone = () => - { - base.TrackingData?.successCallback?.Invoke(); - base.RemoveSelfFromTracking(); - }; - - Action onCancel = () => - { - base.RemoveSelfFromTracking(); - }; - - Action onError = error => - { - base.TrackingData?.errorCallback?.Invoke(error); - base.RemoveSelfFromTracking(); - }; - - while (true) - { - yield return interval; - base.CheckOrderStatus(onDone, onCancel, onError); - - if (Time.time > limit) { - onError?.Invoke(new Error(ErrorType.TimeLimitReached, errorMessage:"Polling time limit reached")); - break; - } - } - } - - public OrderTrackerByShortPolling(OrderTrackingData trackingData) : base(trackingData) - { - } - } -} diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByWebsockets.cs b/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByWebsockets.cs deleted file mode 100644 index 4c29f6708..000000000 --- a/Assets/Xsolla/Orders/OrderTracking/OrderTrackerByWebsockets.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using Newtonsoft.Json; -using WebSocketSharp; -using Xsolla.Core; -using UnityEngine; - -namespace Xsolla.Orders -{ - public class OrderTrackerByWebsockets : OrderTracker - { - private const string URL_PATTERN = "wss://store-ws.xsolla.com/sub/order/status?order_id={0}&project_id={1}"; - private const float EXPECTED_TTL = 300f; - - private WebSocket _webSocket; - private OnMainThreadExecutor _onMainThreadExecutor; - private float _startTime; - - public override void Start() - { - _onMainThreadExecutor = OrderTracking.Instance.GetComponent(); - if (!_onMainThreadExecutor) - _onMainThreadExecutor = OrderTracking.Instance.gameObject.AddComponent(); - - var url = string.Format(URL_PATTERN, base.TrackingData.orderId, base.TrackingData.projectId); - _webSocket = new WebSocket(url); - _webSocket.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.Tls12; - - _webSocket.OnMessage += OnWebSocketMessage; - _webSocket.OnClose += OnWebSocketInterrupt; - _webSocket.OnError += OnWebSocketInterrupt; - _webSocket.Connect(); - - _startTime = Time.time; - } - - public override void Stop() - { - if (_webSocket != null) - { - _webSocket.OnMessage -= OnWebSocketMessage; - _webSocket.OnClose -= OnWebSocketInterrupt; - _webSocket.OnError -= OnWebSocketInterrupt; - _webSocket.Close(); - _webSocket = null; - } - } - - private void OnWebSocketMessage(object sender, MessageEventArgs args) - { - _onMainThreadExecutor.Enqueue(() => - { - OrderStatus status = null; - - try { - status = JsonConvert.DeserializeObject(args.Data); - } catch (System.Exception ex) { - Debug.LogError($"Could not parse WebSocket message with exception: {ex.Message}"); - } - - if (status == null) { - Debug.LogError($"WebSocket message order status is null"); - return; - } - - Debug.Log($"WebSocket status message. OrderID:'{status.order_id}' Status:'{status.status}'"); - - base.HandleOrderStatus( - status.status, - onDone: () => - { - base.TrackingData.successCallback?.Invoke(); - RemoveSelfFromTracking(); - }, - onCancel: RemoveSelfFromTracking - ); - }); - } - - private void OnWebSocketInterrupt(object sender, EventArgs args) - { - _onMainThreadExecutor.Enqueue(() => - { - if (args is CloseEventArgs closeArgs) - Debug.LogWarning($"WebSocket was closed with the code:'{closeArgs.Code}', reason:'{closeArgs.Reason}', wasClean:'{closeArgs.WasClean}'"); - else if (args is ErrorEventArgs errorArgs) - Debug.LogError($"WebSocket was closed with the exception:'{errorArgs.Exception.Message}', message:'{errorArgs.Message}'"); - else - Debug.LogWarning($"WebSocket was closed with the unexpected argument '{args}'"); - - var webSocketTTL = Time.time - _startTime; - - if (webSocketTTL >= EXPECTED_TTL) - { - Debug.Log($"WebSocket TTL '{webSocketTTL}' is OK, replacing an interrupted websocket with a new one"); - - var newTracker = new OrderTrackerByWebsockets(base.TrackingData); - - if (OrderTracking.Instance.ReplaceTracker(this, newTracker)) - Debug.Log($"Traker for an order {base.TrackingData.orderId} is replaced with a new one"); - else - Debug.LogError($"Failed to relace a tracker for an order {base.TrackingData.orderId}"); - } - else - { - Debug.LogWarning($"WebSocket TTL '{webSocketTTL}' is lower than expected, switching to short polling"); - - var shortPollingTracker = new OrderTrackerByShortPolling(base.TrackingData); - - if (OrderTracking.Instance.ReplaceTracker(this, shortPollingTracker)) - Debug.Log($"Traker for an order {base.TrackingData.orderId} is replaced with short polling"); - else - Debug.LogError($"Failed to relace the tracker for an order {base.TrackingData.orderId}"); - } - }); - } - - public OrderTrackerByWebsockets(OrderTrackingData trackingData) : base(trackingData) - { - } - } -} diff --git a/Assets/Xsolla/Orders/OrderTracking/OrderTracking.cs b/Assets/Xsolla/Orders/OrderTracking/OrderTracking.cs deleted file mode 100644 index ecd4beb0f..000000000 --- a/Assets/Xsolla/Orders/OrderTracking/OrderTracking.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Collections.Generic; -using UnityEngine; -using Xsolla.Core; - -namespace Xsolla.Orders -{ - public class OrderTracking : MonoSingleton - { - private readonly Dictionary _currentTrackers = new Dictionary(); - - public bool IsTracking(int orderId) - { - return _currentTrackers.ContainsKey(orderId); - } - - public bool AddOrderForTracking(string projectId, int orderId, Action onSuccess = null, Action onError = null) - { - if (IsTracking(orderId)) - return false; - - var orderTrackingData = new OrderTrackingData(projectId,orderId,onSuccess,onError); -#if UNITY_WEBGL - var tracker = (!Application.isEditor && XsollaSettings.InAppBrowserEnabled) - ? (OrderTracker)new OrderTrackerByPaystationCallbacks(orderTrackingData) - : (OrderTracker)new OrderTrackerByShortPolling(orderTrackingData); -#else - var tracker = new OrderTrackerByWebsockets(orderTrackingData); -#endif - StartTracker(tracker); - return true; - } - - public bool AddVirtualCurrencyOrderForTracking(string projectId, int orderId, Action onSuccess = null, Action onError = null) - { - if (IsTracking(orderId)) - return false; - - var orderTrackingData = new OrderTrackingData(projectId,orderId,onSuccess,onError); -#if UNITY_WEBGL - var tracker = new OrderTrackerByShortPolling(orderTrackingData); -#else - var tracker = new OrderTrackerByWebsockets(orderTrackingData); -#endif - StartTracker(tracker); - return true; - } - - [Obsolete("Use AddOrderForShortPollingTracking instead")] - public void AddOrderForTrackingUntilDone(string projectId, int orderId, Action onSuccess = null, Action onError = null) - => AddOrderForShortPollingTracking(projectId, orderId, onSuccess, onError); - - public bool AddOrderForShortPollingTracking(string projectId, int orderId, Action onSuccess = null, Action onError = null) - { - if (IsTracking(orderId)) - return false; - - var orderTrackingData = new OrderTrackingData(projectId,orderId,onSuccess,onError); - var tracker = new OrderTrackerByShortPolling(orderTrackingData); - StartTracker(tracker); - return true; - } - - public bool RemoveOrderFromTracking(int orderId) - { - if (_currentTrackers.TryGetValue(orderId, out var tracker)) { - tracker.Stop(); - _currentTrackers.Remove(orderId); - return true; - } - - return false; - } - - public bool ReplaceTracker(OrderTracker oldTracker, OrderTracker newTracker) - { - if (RemoveOrderFromTracking(oldTracker.TrackingData.orderId)) { - StartTracker(newTracker); - return true; - } - - return false; - } - - private void StartTracker(OrderTracker tracker) - { - _currentTrackers.Add(tracker.TrackingData.orderId, tracker); - tracker.Start(); - } - } -} diff --git a/Assets/Xsolla/Orders/WebGL.meta b/Assets/Xsolla/Orders/WebGL.meta deleted file mode 100644 index 864ab88a3..000000000 --- a/Assets/Xsolla/Orders/WebGL.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: dd1517e10cc7462a8219cbeab94b63c6 -timeCreated: 1613778330 \ No newline at end of file diff --git a/Assets/Xsolla/Orders/WebGL/XsollaWebCallbacks.cs b/Assets/Xsolla/Orders/WebGL/XsollaWebCallbacks.cs deleted file mode 100644 index 88e9747e6..000000000 --- a/Assets/Xsolla/Orders/WebGL/XsollaWebCallbacks.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Orders -{ - public class XsollaWebCallbacks : MonoSingleton - { - public event Action OnPaymentStatusUpdate; - public event Action OnPaymentCancel; - - public override void Init() - { - base.Init(); - gameObject.name = "XsollaWebCallbacks"; - } - - public void PublishPaymentStatusUpdate() - { - OnPaymentStatusUpdate?.Invoke(); - } - - public void PublishPaymentCancel() - { - OnPaymentCancel?.Invoke(); - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/XsollaOrders.cs b/Assets/Xsolla/Orders/XsollaOrders.cs new file mode 100644 index 000000000..dbab05ca9 --- /dev/null +++ b/Assets/Xsolla/Orders/XsollaOrders.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Orders +{ + public static class XsollaOrders + { + private static string BaseUrl => $"https://store.xsolla.com/api/v2/project/{XsollaSettings.StoreProjectId}"; + + /// + /// Opens Pay Station in the browser with a retrieved Pay Station token. + /// + /// More about the use cases: + /// - [Cart purchase](https://developers.xsolla.com/sdk/unity/item-purchase/cart-purchase/) + /// - [Purchase in one click](https://developers.xsolla.com/sdk/unity/item-purchase/one-click-purchase/) + /// - [Ordering free items](https://developers.xsolla.com/sdk/unity/promo/free-items/#sdk_free_items_order_item_via_cart) + /// Pay Station token for the purchase. + /// Whether to force platform browser usage ignoring plug-in settings. + /// Called after the browser was closed. + /// + public static void OpenPurchaseUI(string paymentToken, bool forcePlatformBrowser = false, Action onBrowserClosed = null) + { + XsollaWebBrowser.OpenPurchaseUI( + paymentToken, + forcePlatformBrowser, + onBrowserClosed); + } + + /// + /// Returns status of the specified order. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/item-purchase/track-order/). + /// Unique order identifier. + /// Called after server response. + /// Called after the request resulted with an error. + /// + public static void CheckOrderStatus(int orderId, Action onSuccess, Action onError) + { + OrderStatusService.GetOrderStatus(orderId, onSuccess, onError); + } + + /// + /// Creates a new payment token. + /// + /// The total amount to be paid by the user. + /// Default purchase currency. Three-letter code per [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (USD by default). + /// Purchase description. Used to describe the purchase if there are no specific items. + /// Called after the successful item purchase. + /// Called after the request resulted with an error. + /// Interface language.
    + /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// Transaction's external ID. + /// Payment method ID. + /// Your custom parameters represented as a valid JSON set of key-value pairs. + public static void CreatePaymentToken( + float amount, + string currency, + string description, + Action onSuccess, + Action onError, + string locale = null, + string externalID = null, + int? paymentMethod = null, + object customParameters = null) + { + var url = $"{BaseUrl}/payment"; + var checkout = new CreatePaymentTokenRequest.Purchase.Checkout(amount, currency); + var purchaseDescription = new CreatePaymentTokenRequest.Purchase.Description(description); + var purchase = new CreatePaymentTokenRequest.Purchase(checkout, purchaseDescription); + var settings = GeneratePaymentTokenSettings(currency, locale, externalID, paymentMethod); + var requestData = new CreatePaymentTokenRequest(purchase, settings, customParameters); + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + PurchaseParamsGenerator.GeneratePaymentHeaders(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => CreatePaymentToken(amount, currency, description, onSuccess, onError, locale, externalID, paymentMethod, customParameters)), + ErrorGroup.BuyItemErrors); + } + + /// + /// Creates a new payment token. + /// + /// The total amount to be paid by the user. + /// Default purchase currency. Three-letter code per [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) (USD by deafault). + /// Used to describe a purchase if it includes a list of specific items. + /// Called after the successful item purchase. + /// Called after the request resulted with an error. + /// Interface language.
    + /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// Transaction's external ID. + /// Payment method ID. + /// Your custom parameters represented as a valid JSON set of key-value pairs. + public static void CreatePaymentToken( + float amount, + string currency, + PaymentTokenItem[] items, + Action onSuccess, + Action onError, + string locale = null, + string externalID = null, + int? paymentMethod = null, + object customParameters = null) + { + var url = $"{BaseUrl}/payment"; + var checkout = new CreatePaymentTokenRequest.Purchase.Checkout(amount, currency); + var purchaseItems = new List(items.Length); + + foreach (var item in items) + { + var price = new CreatePaymentTokenRequest.Purchase.Item.Price(item.Amount, item.AmountBeforeDiscount); + var purchaseItem = new CreatePaymentTokenRequest.Purchase.Item(item.Name, price, item.ImageUrl, item.Description, item.Quantity, item.IsBonus); + purchaseItems.Add(purchaseItem); + } + + var purchase = new CreatePaymentTokenRequest.Purchase(checkout, purchaseItems.ToArray()); + var settings = GeneratePaymentTokenSettings(currency, locale, externalID, paymentMethod); + var requestData = new CreatePaymentTokenRequest(purchase, settings, customParameters); + + WebRequestHelper.Instance.PostRequest( + SdkType.Store, + url, + requestData, + PurchaseParamsGenerator.GeneratePaymentHeaders(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => CreatePaymentToken(amount, currency, items, onSuccess, onError, locale, externalID, paymentMethod, customParameters)), + ErrorGroup.BuyItemErrors); + } + + private static CreatePaymentTokenRequest.Settings GeneratePaymentTokenSettings(string currency, string locale, string externalID, int? paymentMethod) + { + var baseSettings = new PurchaseParamsRequest.Settings { + ui = PayStationUISettings.GenerateSettings(), + redirect_policy = RedirectPolicySettings.GeneratePolicy() + }; + + baseSettings.return_url = baseSettings.redirect_policy?.return_url; + + var settings = new CreatePaymentTokenRequest.Settings { + return_url = baseSettings.return_url, + ui = baseSettings.ui, + redirect_policy = baseSettings.redirect_policy, + currency = currency, + locale = locale, + sandbox = XsollaSettings.IsSandbox, + external_id = externalID, + payment_method = paymentMethod + }; + + return settings; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Orders/Api/XsollaOrders.cs.meta b/Assets/Xsolla/Orders/XsollaOrders.cs.meta similarity index 100% rename from Assets/Xsolla/Orders/Api/XsollaOrders.cs.meta rename to Assets/Xsolla/Orders/XsollaOrders.cs.meta diff --git a/Assets/Xsolla.Demo/Login/Scripts/Auth.meta b/Assets/Xsolla/Samples.meta similarity index 77% rename from Assets/Xsolla.Demo/Login/Scripts/Auth.meta rename to Assets/Xsolla/Samples.meta index 13060f0eb..81148d713 100644 --- a/Assets/Xsolla.Demo/Login/Scripts/Auth.meta +++ b/Assets/Xsolla/Samples.meta @@ -1,5 +1,5 @@ fileFormatVersion: 2 -guid: 1d3774198db4b497fbada6cc592620e2 +guid: 6a5cd7c79c2e94597acd29fa06aae714 folderAsset: yes DefaultImporter: externalObjects: {} diff --git a/Assets/Xsolla/Samples/Authorization.meta b/Assets/Xsolla/Samples/Authorization.meta new file mode 100644 index 000000000..bf9f0341f --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 35a14621221a4518947d0fa9da8c97d0 +timeCreated: 1684201093 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Authorization/AuthorizationPage.cs b/Assets/Xsolla/Samples/Authorization/AuthorizationPage.cs new file mode 100644 index 000000000..e38cba4c1 --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/AuthorizationPage.cs @@ -0,0 +1,42 @@ +using UnityEngine; +using UnityEngine.UI; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Samples.Authorization +{ + public class AuthorizationPage : MonoBehaviour + { + // Declaration of variables for UI elements + public InputField UsernameInput; + public InputField PasswordInputField; + public Button SignInButton; + + private void Start() + { + // Handling the button click + SignInButton.onClick.AddListener(() => + { + // Get the username and password from input fields + var username = UsernameInput.text; + var password = PasswordInputField.text; + + // Call the user authorization method + // Pass credentials and callback functions for success and error cases + XsollaAuth.SignIn(username, password, OnSuccess, OnError); + }); + } + + private void OnSuccess() + { + Debug.Log("Authorization successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Authorization failed. Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/Authorization/AuthorizationPage.cs.meta b/Assets/Xsolla/Samples/Authorization/AuthorizationPage.cs.meta new file mode 100644 index 000000000..eb38eea4b --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/AuthorizationPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5668a2ba655d463a8f54239a24023e06 +timeCreated: 1684201389 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Authorization/RegistrationPage.cs b/Assets/Xsolla/Samples/Authorization/RegistrationPage.cs new file mode 100644 index 000000000..2e19633db --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/RegistrationPage.cs @@ -0,0 +1,44 @@ +using UnityEngine; +using UnityEngine.UI; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Samples.Authorization +{ + public class RegistrationPage : MonoBehaviour + { + // Declaration of variables for UI elements + public InputField UsernameInput; + public InputField EmailInputField; + public InputField PasswordInputField; + public Button RegisterButton; + + private void Start() + { + // Handling the button click + RegisterButton.onClick.AddListener(() => + { + // Get the username, email and password from input fields + var username = UsernameInput.text; + var email = EmailInputField.text; + var password = PasswordInputField.text; + + // Call the user registration method + // Pass credentials and callback functions for success and error cases + XsollaAuth.Register(username, password, email, OnSuccess, OnError); + }); + } + + private void OnSuccess(LoginLink loginLink) + { + Debug.Log("Registration successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Registration failed. Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/Authorization/RegistrationPage.cs.meta b/Assets/Xsolla/Samples/Authorization/RegistrationPage.cs.meta new file mode 100644 index 000000000..1ab00c4f4 --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/RegistrationPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ac886fd652ac43f987ff5c753e7e6990 +timeCreated: 1684201097 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Authorization/ResendConfirmationEmailPage.cs b/Assets/Xsolla/Samples/Authorization/ResendConfirmationEmailPage.cs new file mode 100644 index 000000000..5e6475a06 --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/ResendConfirmationEmailPage.cs @@ -0,0 +1,40 @@ +using UnityEngine; +using UnityEngine.UI; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Samples.Authorization +{ + public class ResendConfirmationEmailPage : MonoBehaviour + { + // Declaration of variables for UI elements + public InputField UsernameInput; + public Button ResendEmailButton; + + private void Start() + { + // Handling the button click + ResendEmailButton.onClick.AddListener(() => + { + // Get the username from the input field + var username = UsernameInput.text; + + // Call the resend confirmation email method + // Pass the username and callback functions for success and error cases + XsollaAuth.ResendConfirmationLink(username, OnSuccess, OnError); + }); + } + + private void OnSuccess() + { + Debug.Log("Resend confirmation email successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Resend confirmation email failed. Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/Authorization/ResendConfirmationEmailPage.cs.meta b/Assets/Xsolla/Samples/Authorization/ResendConfirmationEmailPage.cs.meta new file mode 100644 index 000000000..3b88999b8 --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/ResendConfirmationEmailPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9cf71542c29c435f927f8abcf80c9f76 +timeCreated: 1684201255 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Authorization/ResetPasswordPage.cs b/Assets/Xsolla/Samples/Authorization/ResetPasswordPage.cs new file mode 100644 index 000000000..518b03ee5 --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/ResetPasswordPage.cs @@ -0,0 +1,40 @@ +using UnityEngine; +using UnityEngine.UI; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Samples.Authorization +{ + public class ResetPasswordPage : MonoBehaviour + { + // Declaration of variables for UI elements + public InputField UsernameInput; + public Button ResetPasswordButton; + + private void Start() + { + // Handling the button click + ResetPasswordButton.onClick.AddListener(() => + { + // Get the username from the input field + var username = UsernameInput.text; + + // Call the password reset method + // Pass the username and callback functions for success and error cases + XsollaAuth.ResetPassword(username, OnSuccess, OnError); + }); + } + + private void OnSuccess() + { + Debug.Log("Password reset successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Password reset failed. Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/Authorization/ResetPasswordPage.cs.meta b/Assets/Xsolla/Samples/Authorization/ResetPasswordPage.cs.meta new file mode 100644 index 000000000..996047956 --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/ResetPasswordPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ce66ae50e4bd4ae4ad01e8eab15905d3 +timeCreated: 1684201546 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Authorization/SocialAuthorizationPage.cs b/Assets/Xsolla/Samples/Authorization/SocialAuthorizationPage.cs new file mode 100644 index 000000000..b3be4c90c --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/SocialAuthorizationPage.cs @@ -0,0 +1,43 @@ +using UnityEngine; +using UnityEngine.UI; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Samples.Authorization +{ + public class SocialAuthorizationPage : MonoBehaviour + { + // Declaration of variables for SocialProvider and signIn button + public SocialProvider SocialProvider = SocialProvider.Facebook; + public Button SignInButton; + + private void Start() + { + // Handling the button click + SignInButton.onClick.AddListener(() => + { + // Call the social authorization method + // Pass the social network provider and callback functions for success, error and cancel cases + XsollaAuth.AuthViaSocialNetwork(SocialProvider, OnSuccess, OnError, OnCancel); + }); + } + + private void OnSuccess() + { + Debug.Log("Social authorization successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Social authorization failed. Error: {error.errorMessage}"); + // Add actions taken in case of error + } + + private void OnCancel() + { + Debug.Log("Social authorization cancelled by user."); + // Add actions taken in case the user canceles authorization + } + } +} diff --git a/Assets/Xsolla/Samples/Authorization/SocialAuthorizationPage.cs.meta b/Assets/Xsolla/Samples/Authorization/SocialAuthorizationPage.cs.meta new file mode 100644 index 000000000..c65fae063 --- /dev/null +++ b/Assets/Xsolla/Samples/Authorization/SocialAuthorizationPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ab2d5bb6bf0f45e59a65e318f667cef8 +timeCreated: 1684201850 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog.meta b/Assets/Xsolla/Samples/DisplayCatalog.meta new file mode 100644 index 000000000..ceba83571 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 02f3c215ce4e4e4dbf42a448a0d22fcf +timeCreated: 1684204741 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/BundleWidget.cs b/Assets/Xsolla/Samples/DisplayCatalog/BundleWidget.cs new file mode 100644 index 000000000..e499e4e24 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/BundleWidget.cs @@ -0,0 +1,15 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace Xsolla.Samples.DisplayCatalog +{ + public class BundleWidget : MonoBehaviour + { + // Declaration of variables for UI elements + public Text NameText; + public Text DescriptionText; + public Text PriceText; + public Text ContentText; + public Image IconImage; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/BundleWidget.cs.meta b/Assets/Xsolla/Samples/DisplayCatalog/BundleWidget.cs.meta new file mode 100644 index 000000000..de710e003 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/BundleWidget.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1d18c794c72845d4955ce1bf2ca84cd1 +timeCreated: 1684207854 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/BundlesPage.cs b/Assets/Xsolla/Samples/DisplayCatalog/BundlesPage.cs new file mode 100644 index 000000000..c37b7b3a4 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/BundlesPage.cs @@ -0,0 +1,71 @@ +using System.Linq; +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Samples.DisplayCatalog +{ + public class BundlesPage : MonoBehaviour + { + // Declaration of variables for widget's container and prefab + public Transform WidgetsContainer; + public GameObject WidgetPrefab; + + private void Start() + { + // Starting the authentication process + // Pass the credentials and callback functions for success and error cases + // The credentials (username and password) are hard-coded for simplicity + XsollaAuth.SignIn("xsolla", "xsolla", OnAuthenticationSuccess, OnError); + } + + private void OnAuthenticationSuccess() + { + // Starting the bundle request from the store after successful authentication + // Pass the callback functions for success and error cases + XsollaCatalog.GetBundles(OnBundlesRequestSuccess, OnError); + } + + private void OnBundlesRequestSuccess(BundleItems bundleItems) + { + // Iterating the bundles collection + foreach (var bundleItem in bundleItems.items) + { + // Instantiating the widget prefab as child of the container + var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false); + var widget = widgetGo.GetComponent(); + + // Assigning the values for UI elements + widget.NameText.text = bundleItem.name; + widget.DescriptionText.text = bundleItem.description; + + // Creating the string with bundle content and assigning it to the UI element + var bundleContent = bundleItem.content.Select(x => $"{x.name} x {x.quantity}"); + widget.ContentText.text = string.Join("\n", bundleContent); + + // The bundle can be purchased for real money or virtual currency + // Checking the price type and assigning the values for appropriate UI elements + if (bundleItem.price != null) + { + var realMoneyPrice = bundleItem.price; + widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}"; + } + else if (bundleItem.virtual_prices != null) + { + var virtualCurrencyPrice = bundleItem.virtual_prices.First(x => x.is_default); + widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}"; + } + + // Loading the bundle image and assigning it to the UI element + ImageLoader.LoadSprite(bundleItem.image_url, sprite => widget.IconImage.sprite = sprite); + } + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/DisplayCatalog/BundlesPage.cs.meta b/Assets/Xsolla/Samples/DisplayCatalog/BundlesPage.cs.meta new file mode 100644 index 000000000..84176b0ff --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/BundlesPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1287c3b4be424c428df18dcbccbe0acb +timeCreated: 1684207882 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackageWidget.cs b/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackageWidget.cs new file mode 100644 index 000000000..acebc1544 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackageWidget.cs @@ -0,0 +1,14 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace Xsolla.Samples.DisplayCatalog +{ + public class VirtualCurrencyPackageWidget : MonoBehaviour + { + // Declaration of variables for UI elements + public Text NameText; + public Text DescriptionText; + public Text PriceText; + public Image IconImage; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackageWidget.cs.meta b/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackageWidget.cs.meta new file mode 100644 index 000000000..d94ed3675 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackageWidget.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: fab90a265462454ab511ac851561342e +timeCreated: 1684207948 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackagesPage.cs b/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackagesPage.cs new file mode 100644 index 000000000..4314a46c5 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackagesPage.cs @@ -0,0 +1,67 @@ +using System.Linq; +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Samples.DisplayCatalog +{ + public class VirtualCurrencyPackagesPage : MonoBehaviour + { + // Declaration of variables for widget's container and prefab + public Transform WidgetsContainer; + public GameObject WidgetPrefab; + + private void Start() + { + // Starting the authentication process + // Pass the credentials and callback functions for success and error cases + // The credentials (username and password) are hard-coded for simplicity + XsollaAuth.SignIn("xsolla", "xsolla", OnAuthenticationSuccess, OnError); + } + + private void OnAuthenticationSuccess() + { + // After successful authentication starting the request for packages from store + // Pass the callback functions for success and error cases + XsollaCatalog.GetVirtualCurrencyPackagesList(OnPackagesRequestSuccess, OnError); + } + + private void OnPackagesRequestSuccess(VirtualCurrencyPackages packageItems) + { + // Iterating the virtual currency packages collection + foreach (var packageItem in packageItems.items) + { + // Instantiating the widget prefab as child of the container + var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false); + var widget = widgetGo.GetComponent(); + + // Assigning the values for UI elements + widget.NameText.text = packageItem.name; + widget.DescriptionText.text = packageItem.description; + + // The package can be purchased for real money or virtual currency + // Checking the price type and assigning the values for appropriate UI elements + if (packageItem.price != null) + { + var realMoneyPrice = packageItem.price; + widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}"; + } + else if (packageItem.virtual_prices != null) + { + var virtualCurrencyPrice = packageItem.virtual_prices.First(x => x.is_default); + widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}"; + } + + // Loading the package image and assigning it to the UI element + ImageLoader.LoadSprite(packageItem.image_url, sprite => widget.IconImage.sprite = sprite); + } + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackagesPage.cs.meta b/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackagesPage.cs.meta new file mode 100644 index 000000000..63007ad0a --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualCurrencyPackagesPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2d4676700b3c475f9466f9ffb293b9e4 +timeCreated: 1684207975 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemGroupButton.cs b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemGroupButton.cs new file mode 100644 index 000000000..28ce4257a --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemGroupButton.cs @@ -0,0 +1,12 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace Xsolla.Samples.DisplayCatalog +{ + public class VirtualItemGroupButton : MonoBehaviour + { + // Declaration of variables for UI elements + public Text NameText; + public Button Button; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemGroupButton.cs.meta b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemGroupButton.cs.meta new file mode 100644 index 000000000..3f466ae4f --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemGroupButton.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dcad694b74ed4682b5e2327338a4ee97 +timeCreated: 1684207726 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemWidget.cs b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemWidget.cs new file mode 100644 index 000000000..13f34f326 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemWidget.cs @@ -0,0 +1,14 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace Xsolla.Samples.DisplayCatalog +{ + public class VirtualItemWidget : MonoBehaviour + { + // Declaration of variables for UI elements + public Text NameText; + public Text DescriptionText; + public Text PriceText; + public Image IconImage; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemWidget.cs.meta b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemWidget.cs.meta new file mode 100644 index 000000000..d058a50a9 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemWidget.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0ef4caaa15af457a80b370000d6b3ef3 +timeCreated: 1684204761 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsByGroupsPage.cs b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsByGroupsPage.cs new file mode 100644 index 000000000..301797962 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsByGroupsPage.cs @@ -0,0 +1,126 @@ +using System.Collections.Generic; +using System.Linq; +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Samples.DisplayCatalog +{ + public class VirtualItemsByGroupsPage : MonoBehaviour + { + // Declaration of variables for widget's container and prefab + public Transform GroupButtonsContainer; + public GameObject GroupButtonPrefab; + public Transform ItemWidgetsContainer; + public GameObject ItemWidgetPrefab; + + private void Start() + { + // Starting the authentication process + // Pass the credentials and callback functions for success and error cases + // The credentials (username and password) are hard-coded for simplicity + XsollaAuth.SignIn("xsolla", "xsolla", OnAuthenticationSuccess, OnError); + } + + private void OnAuthenticationSuccess() + { + // Starting the items request from the store after successful authentication + // Pass the callback functions for success and error cases + XsollaCatalog.GetCatalog(OnItemsRequestSuccess, OnError); + } + + private void OnItemsRequestSuccess(StoreItems storeItems) + { + // Selecting the group’s name from items and order them alphabetically + var groupNames = storeItems.items + .SelectMany(x => x.groups) + .GroupBy(x => x.name) + .Select(x => x.First()) + .OrderBy(x => x.name) + .Select(x => x.name) + .ToList(); + + // Add group name for catalog category with all items regardless of group affiliation + groupNames.Insert(0, "All"); + + // Iterating the group names collection + foreach (var groupName in groupNames) + { + // Instantiating the button prefab as child of the container + var buttonGo = Instantiate(GroupButtonPrefab, GroupButtonsContainer, false); + var groupButton = buttonGo.GetComponent(); + + // Assigning the values for UI elements + groupButton.NameText.text = groupName; + + // Adding listener for button click event + groupButton.Button.onClick.AddListener(() => OnGroupSelected(groupName, storeItems)); + } + + // Calling method for redraw page + OnGroupSelected("All", storeItems); + } + + private void OnGroupSelected(string groupName, StoreItems storeItems) + { + // Clear container + DeleteAllChildren(ItemWidgetsContainer); + + // Declaring variable for items to be displayed on the page + IEnumerable itemsForDisplay; + if (groupName == "All") + { + itemsForDisplay = storeItems.items; + } + else + { + itemsForDisplay = storeItems.items.Where(item => item.groups.Any(group => group.name == groupName)); + } + + // Iterating the items collection and assigning values for appropriate UI elements + foreach (var storeItem in itemsForDisplay) + { + // Instantiating the widget prefab as child of the container + var widgetGo = Instantiate(ItemWidgetPrefab, ItemWidgetsContainer, false); + var widget = widgetGo.GetComponent(); + + // Assigning the values for UI elements + widget.NameText.text = storeItem.name; + widget.DescriptionText.text = storeItem.description; + + // The item can be purchased for real money or virtual currency + // Checking the price type and assigning the appropriate value for price text + if (storeItem.price != null) + { + var realMoneyPrice = storeItem.price; + widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}"; + } + else if (storeItem.virtual_prices != null) + { + var virtualCurrencyPrice = storeItem.virtual_prices.First(x => x.is_default); + widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}"; + } + + // Loading the image for item icon and assigning it to the UI element + ImageLoader.LoadSprite(storeItem.image_url, sprite => widget.IconImage.sprite = sprite); + } + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + + // Utility method to delete all children of a container + private static void DeleteAllChildren(Transform parent) + { + var childList = parent.Cast().ToList(); + foreach (var childTransform in childList) + { + Destroy(childTransform.gameObject); + } + } + } +} diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsByGroupsPage.cs.meta b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsByGroupsPage.cs.meta new file mode 100644 index 000000000..84e19e28b --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsByGroupsPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1c86731e2efb42ee90443881ed851290 +timeCreated: 1684207762 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsPage.cs b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsPage.cs new file mode 100644 index 000000000..0eb280bb7 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsPage.cs @@ -0,0 +1,66 @@ +using System.Linq; +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Samples.DisplayCatalog +{ + public class VirtualItemsPage : MonoBehaviour + { + // Declaration of variables for widget's container and prefab + public Transform WidgetsContainer; + public GameObject WidgetPrefab; + + private void Start() + { + // Starting the authentication process + // Pass the credentials and callback functions for success and error cases + // The credentials (username and password) are hard-coded for simplicity + XsollaAuth.SignIn("xsolla", "xsolla", OnAuthenticationSuccess, OnError); + } + + private void OnAuthenticationSuccess() + { + // Starting the items request from the store after successful authentication + XsollaCatalog.GetCatalog(OnItemsRequestSuccess, OnError); + } + + private void OnItemsRequestSuccess(StoreItems storeItems) + { + // Iterating the items collection + foreach (var storeItem in storeItems.items) + { + // Instantiating the widget prefab as child of the container + var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false); + var widget = widgetGo.GetComponent(); + + // Assigning the values for UI elements + widget.NameText.text = storeItem.name; + widget.DescriptionText.text = storeItem.description; + + // The item can be purchased for real money or virtual currency + // Checking the price type and assigning the values for appropriate UI elements + if (storeItem.price != null) + { + var realMoneyPrice = storeItem.price; + widget.PriceText.text = $"{realMoneyPrice.amount} {realMoneyPrice.currency}"; + } + else if (storeItem.virtual_prices != null) + { + var virtualCurrencyPrice = storeItem.virtual_prices.First(x => x.is_default); + widget.PriceText.text = $"{virtualCurrencyPrice.name}: {virtualCurrencyPrice.amount}"; + } + + // Loading the item image and assigning it to the UI element + ImageLoader.LoadSprite(storeItem.image_url, sprite => widget.IconImage.sprite = sprite); + } + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsPage.cs.meta b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsPage.cs.meta new file mode 100644 index 000000000..17772c831 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayCatalog/VirtualItemsPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c9e06b50ac02436484ec23328a3cbc20 +timeCreated: 1684204818 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayItemsInInventory.meta b/Assets/Xsolla/Samples/DisplayItemsInInventory.meta new file mode 100644 index 000000000..9203b8927 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayItemsInInventory.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f765e40a180b4d17ae89c9263366276b +timeCreated: 1684208692 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemWidget.cs b/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemWidget.cs new file mode 100644 index 000000000..860acc003 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemWidget.cs @@ -0,0 +1,14 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace Xsolla.Samples.DisplayItemsInInventory +{ + public class InventoryItemWidget : MonoBehaviour + { + // Declaration of variables for UI elements + public Text NameText; + public Text DescriptionText; + public Text QuantityText; + public Image IconImage; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemWidget.cs.meta b/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemWidget.cs.meta new file mode 100644 index 000000000..68abd7c80 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemWidget.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: afe7c738e278484094e85078c2f97dce +timeCreated: 1684208698 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemsPage.cs b/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemsPage.cs new file mode 100644 index 000000000..284ec2e1b --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemsPage.cs @@ -0,0 +1,58 @@ +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Core; +using Xsolla.Inventory; + +namespace Xsolla.Samples.DisplayItemsInInventory +{ + public class InventoryItemsPage : MonoBehaviour + { + // Declaration of variables for widget's container and prefab + public Transform WidgetsContainer; + public GameObject WidgetPrefab; + + private void Start() + { + // Starting the authentication process + // Pass the credentials and callback functions for success and error cases + // The credentials (username and password) are hard-coded for simplicity + XsollaAuth.SignIn("xsolla", "xsolla", OnAuthenticationSuccess, OnError); + } + + private void OnAuthenticationSuccess() + { + // Starting the items request from the store after successful authentication + // Pass the callback functions for success and error cases + XsollaInventory.GetInventoryItems(OnItemsRequestSuccess, OnError); + } + + private void OnItemsRequestSuccess(InventoryItems inventoryItems) + { + // Iterating the items collection + foreach (var inventoryItem in inventoryItems.items) + { + // Skipping virtual currency items + if (inventoryItem.VirtualItemType == VirtualItemType.VirtualCurrency) + continue; + + // Instantiating the widget prefab as child of the container + var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false); + var widget = widgetGo.GetComponent(); + + // Assigning the values for UI elements + widget.NameText.text = inventoryItem.name; + widget.DescriptionText.text = inventoryItem.description; + widget.QuantityText.text = inventoryItem.quantity.ToString(); + + // Loading the item image and assigning it to the UI element + ImageLoader.LoadSprite(inventoryItem.image_url, sprite => widget.IconImage.sprite = sprite); + } + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemsPage.cs.meta b/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemsPage.cs.meta new file mode 100644 index 000000000..205e92cc1 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayItemsInInventory/InventoryItemsPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 35436a6a1966491d8177b69fe97547b9 +timeCreated: 1684208729 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance.meta b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance.meta new file mode 100644 index 000000000..7e8c82be7 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: e21769bc214945afa866f0a15bc70718 +timeCreated: 1684208579 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrenciesPage.cs b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrenciesPage.cs new file mode 100644 index 000000000..eb444359a --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrenciesPage.cs @@ -0,0 +1,52 @@ +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Core; +using Xsolla.Inventory; + +namespace Xsolla.Samples.DisplayVirtualCurrencyBalance +{ + public class VirtualCurrenciesPage : MonoBehaviour + { + // Declaration of variables for widget's container and prefab + public Transform WidgetsContainer; + public GameObject WidgetPrefab; + + private void Start() + { + // Starting the authentication process + // Pass the credentials and callback functions for success and error cases + // The credentials (username and password) are hard-coded for simplicity + XsollaAuth.SignIn("xsolla", "xsolla", OnAuthenticationSuccess, OnError); + } + + private void OnAuthenticationSuccess() + { + // Starting the virtual currencies request from the store after successful authentication + // Pass the callback functions for success and error cases + XsollaInventory.GetVirtualCurrencyBalance(OnBalanceRequestSuccess, OnError); + } + + private void OnBalanceRequestSuccess(VirtualCurrencyBalances balance) + { + // Iterating the virtual currency balances collection + foreach (var balanceItem in balance.items) + { + // Instantiating the widget prefab as child of the container + var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false); + var widget = widgetGo.GetComponent(); + + // Assigning the values for UI elements + widget.NameText.text = balanceItem.name; + widget.AmountText.text = balanceItem.amount.ToString(); + + ImageLoader.LoadSprite(balanceItem.image_url, sprite => widget.IconImage.sprite = sprite); + } + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrenciesPage.cs.meta b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrenciesPage.cs.meta new file mode 100644 index 000000000..2341482b6 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrenciesPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: aafcc547c9c040e3a3a589ecb2a8aa3f +timeCreated: 1684208623 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrencyWidget.cs b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrencyWidget.cs new file mode 100644 index 000000000..fe73383f6 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrencyWidget.cs @@ -0,0 +1,13 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace Xsolla.Samples.DisplayVirtualCurrencyBalance +{ + public class VirtualCurrencyWidget : MonoBehaviour + { + // Declaration of variables for UI elements + public Text NameText; + public Text AmountText; + public Image IconImage; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrencyWidget.cs.meta b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrencyWidget.cs.meta new file mode 100644 index 000000000..3dedfb169 --- /dev/null +++ b/Assets/Xsolla/Samples/DisplayVirtualCurrencyBalance/VirtualCurrencyWidget.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f3ccf38975494123a1d74b3419b1cd95 +timeCreated: 1684208594 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/SellForRealMoney.meta b/Assets/Xsolla/Samples/SellForRealMoney.meta new file mode 100644 index 000000000..9a4a2fa58 --- /dev/null +++ b/Assets/Xsolla/Samples/SellForRealMoney.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c4ef152272a84c9e92ff0f60afb98cd2 +timeCreated: 1684208069 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemWidget.cs b/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemWidget.cs new file mode 100644 index 000000000..e7b73157a --- /dev/null +++ b/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemWidget.cs @@ -0,0 +1,15 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace Xsolla.Samples.SellForRealMoney +{ + public class VirtualItemWidget : MonoBehaviour + { + // Declaration of variables for UI elements + public Text NameText; + public Text DescriptionText; + public Text PriceText; + public Image IconImage; + public Button BuyButton; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemWidget.cs.meta b/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemWidget.cs.meta new file mode 100644 index 000000000..b007945a1 --- /dev/null +++ b/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemWidget.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c004ff78c0bc41e7b15bb5e63816b117 +timeCreated: 1684208131 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemsPage.cs b/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemsPage.cs new file mode 100644 index 000000000..872be47c8 --- /dev/null +++ b/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemsPage.cs @@ -0,0 +1,75 @@ +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Samples.SellForRealMoney +{ + public class VirtualItemsPage : MonoBehaviour + { + // Declaration of variables for widget's container and prefab + public Transform WidgetsContainer; + public GameObject WidgetPrefab; + + private void Start() + { + // Starting the authentication process + // Pass the credentials and callback functions for success and error cases + // The credentials (username and password) are hard-coded for simplicity + XsollaAuth.SignIn("xsolla", "xsolla", OnAuthenticationSuccess, OnError); + } + + private void OnAuthenticationSuccess() + { + // Starting the items request from the store after successful authentication + // Pass the callback functions for success and error cases + XsollaCatalog.GetCatalog(OnItemsRequestSuccess, OnError); + } + + private void OnItemsRequestSuccess(StoreItems storeItems) + { + // Iterating the items collection + foreach (var storeItem in storeItems.items) + { + // Skipping items without prices in real money + if (storeItem.price == null) + continue; + + // Instantiating the widget prefab as child of the container + var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false); + var widget = widgetGo.GetComponent(); + + // Assigning the values for UI elements + widget.NameText.text = storeItem.name; + widget.DescriptionText.text = storeItem.description; + + // Assigning the price and currency values for UI elements + var price = storeItem.price; + widget.PriceText.text = $"{price.amount} {price.currency}"; + + // Loading the item image and assigning it to the UI element + ImageLoader.LoadSprite(storeItem.image_url, sprite => widget.IconImage.sprite = sprite); + + // Assigning the click listener for the buy button + widget.BuyButton.onClick.AddListener(() => + { + // Starting the purchase process + // Pass the item SKU and callback functions for success and error cases + XsollaCatalog.Purchase(storeItem.sku, OnPurchaseSuccess, OnError); + }); + } + } + + private void OnPurchaseSuccess(OrderStatus status) + { + Debug.Log("Purchase successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemsPage.cs.meta b/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemsPage.cs.meta new file mode 100644 index 000000000..3a0e55ed7 --- /dev/null +++ b/Assets/Xsolla/Samples/SellForRealMoney/VirtualItemsPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 41b3dbad19f944269456a39f229fbff0 +timeCreated: 1684208091 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/SellForVirtualCurrency.meta b/Assets/Xsolla/Samples/SellForVirtualCurrency.meta new file mode 100644 index 000000000..233f66cd0 --- /dev/null +++ b/Assets/Xsolla/Samples/SellForVirtualCurrency.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 2a124841bfe140fab0400c3c814487b0 +timeCreated: 1684208364 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemWidget.cs b/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemWidget.cs new file mode 100644 index 000000000..fd1075e67 --- /dev/null +++ b/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemWidget.cs @@ -0,0 +1,15 @@ +using UnityEngine; +using UnityEngine.UI; + +namespace Xsolla.Samples.SellForVirtualCurrency +{ + public class VirtualItemWidget : MonoBehaviour + { + // Declaration of variables for UI elements + public Text NameText; + public Text DescriptionText; + public Text PriceText; + public Image IconImage; + public Button BuyButton; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemWidget.cs.meta b/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemWidget.cs.meta new file mode 100644 index 000000000..d01bbe47a --- /dev/null +++ b/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemWidget.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a7878dc49e4948df8cac718ee1fb7f23 +timeCreated: 1684208371 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemsPage.cs b/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemsPage.cs new file mode 100644 index 000000000..34a991124 --- /dev/null +++ b/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemsPage.cs @@ -0,0 +1,77 @@ +using System.Linq; +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Samples.SellForVirtualCurrency +{ + public class VirtualItemsPage : MonoBehaviour + { + // Declaration of variables for containers and widget prefabs + public Transform WidgetsContainer; + public GameObject WidgetPrefab; + + private void Start() + { + // Starting the authentication process + // Pass the credentials and callback functions for success and error cases + // The credentials (username and password) are hard-coded for simplicity + XsollaAuth.SignIn("xsolla", "xsolla", OnAuthenticationSuccess, OnError); + } + + private void OnAuthenticationSuccess() + { + // After successful authentication starting the request for catalog from store + // Pass the callback functions for success and error cases + XsollaCatalog.GetCatalog(OnItemsRequestSuccess, OnError); + } + + private void OnItemsRequestSuccess(StoreItems storeItems) + { + // Iterating the items collection + foreach (var storeItem in storeItems.items) + { + // Skipping items without prices in virtual currency + if (storeItem.virtual_prices.Length == 0) + continue; + + // Instantiating the widget prefab as child of the container + var widgetGo = Instantiate(WidgetPrefab, WidgetsContainer, false); + var widget = widgetGo.GetComponent(); + + // Assigning the values for UI elements + widget.NameText.text = storeItem.name; + widget.DescriptionText.text = storeItem.description; + + // Assigning the price and currency values for UI elements + // The first price is used for the sake of simplicity + var price = storeItem.virtual_prices.First(x => x.is_default); + widget.PriceText.text = $"{price.name}: {price.amount}"; + + // Loading the item image and assigning it to the UI element + ImageLoader.LoadSprite(storeItem.image_url, sprite => widget.IconImage.sprite = sprite); + + // Assigning the click listener for the buy button + widget.BuyButton.onClick.AddListener(() => + { + // Starting the purchase process + // Pass the item SKU, the price virtual currency SKU and callback functions for success and error cases + XsollaCatalog.PurchaseForVirtualCurrency(storeItem.sku, price.sku, OnPurchaseSuccess, OnError); + }); + } + } + + private void OnPurchaseSuccess(OrderStatus status) + { + Debug.Log("Purchase successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemsPage.cs.meta b/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemsPage.cs.meta new file mode 100644 index 000000000..0b533dc63 --- /dev/null +++ b/Assets/Xsolla/Samples/SellForVirtualCurrency/VirtualItemsPage.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: b2b78454683440adb2c2e07219a019a6 +timeCreated: 1684208409 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Steam.meta b/Assets/Xsolla/Samples/Steam.meta new file mode 100644 index 000000000..ce4327cd5 --- /dev/null +++ b/Assets/Xsolla/Samples/Steam.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1a8ae91e344b49099d04e84bb196b688 +timeCreated: 1684294749 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Steam/SellViaSteamGateway.cs b/Assets/Xsolla/Samples/Steam/SellViaSteamGateway.cs new file mode 100644 index 000000000..37160c315 --- /dev/null +++ b/Assets/Xsolla/Samples/Steam/SellViaSteamGateway.cs @@ -0,0 +1,33 @@ +using UnityEngine; +using Xsolla.Catalog; +using Xsolla.Core; + +namespace Xsolla.Samples.Steam +{ + public class SellViaSteamGateway : MonoBehaviour + { + // Function for starting the purchase process via Steam Gateway + public void PurchaseItem(string itemSku) + { + // Get additional headers for the request from `SteamUtils` class + var additionalHeaders = SteamUtils.GetAdditionalCustomHeaders(); + + // Starting the purchase process + // Pass the `itemSku` parameter and callback functions for success and error cases + // Pass `additionalHeaders` variable as the optional `customHeaders` parameter + XsollaCatalog.Purchase(itemSku, OnPurchaseSuccess, OnError, customHeaders: additionalHeaders); + } + + private void OnPurchaseSuccess(OrderStatus status) + { + Debug.Log("Purchase successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/Steam/SellViaSteamGateway.cs.meta b/Assets/Xsolla/Samples/Steam/SellViaSteamGateway.cs.meta new file mode 100644 index 000000000..e10b5c48e --- /dev/null +++ b/Assets/Xsolla/Samples/Steam/SellViaSteamGateway.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1aa2190e12414d8a968489ee6f3a9b4b +timeCreated: 1684295188 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Steam/SteamNativeAuthorization.cs b/Assets/Xsolla/Samples/Steam/SteamNativeAuthorization.cs new file mode 100644 index 000000000..1698656c6 --- /dev/null +++ b/Assets/Xsolla/Samples/Steam/SteamNativeAuthorization.cs @@ -0,0 +1,34 @@ +using UnityEngine; +using Xsolla.Auth; +using Xsolla.Core; + +namespace Xsolla.Samples.Steam +{ + public class SteamNativeAuthorization : MonoBehaviour + { + private void Start() + { + // Get the steam session ticket from `SteamUtils` class + var steamSessionTicket = SteamUtils.GetSteamSessionTicket(); + + // Start silent authentication + // Pass `steam` as `providerName` parameter + // Pass your `Steam App ID` as `appId` parameter. We use `480` as an example + // Pass `steamSessionTicket` variable as the `sessionTicket` parameter + // Pass callback functions for success and error cases + XsollaAuth.SilentAuth("steam", "480", steamSessionTicket, OnSuccess, OnError); + } + + private void OnSuccess() + { + Debug.Log("Authorization successful"); + // Add actions taken in case of success + } + + private void OnError(Error error) + { + Debug.LogError($"Authorization failed. Error: {error.errorMessage}"); + // Add actions taken in case of error + } + } +} diff --git a/Assets/Xsolla/Samples/Steam/SteamNativeAuthorization.cs.meta b/Assets/Xsolla/Samples/Steam/SteamNativeAuthorization.cs.meta new file mode 100644 index 000000000..920e808fc --- /dev/null +++ b/Assets/Xsolla/Samples/Steam/SteamNativeAuthorization.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1f6000294c9f4151bc744f0f2a3a2889 +timeCreated: 1684294763 \ No newline at end of file diff --git a/Assets/Xsolla/Samples/Xsolla.Samples.asmdef b/Assets/Xsolla/Samples/Xsolla.Samples.asmdef new file mode 100644 index 000000000..3b279e4bc --- /dev/null +++ b/Assets/Xsolla/Samples/Xsolla.Samples.asmdef @@ -0,0 +1,15 @@ +{ + "name": "Xsolla.Samples", + "references": [ + "GUID:ae0cf701846f0cc4bbd067c4edd4fe90" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": false, + "precompiledReferences": [], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/Assets/Tests/TestUtilsMonobehaviour.meta b/Assets/Xsolla/Samples/Xsolla.Samples.asmdef.meta similarity index 57% rename from Assets/Tests/TestUtilsMonobehaviour.meta rename to Assets/Xsolla/Samples/Xsolla.Samples.asmdef.meta index 4a3a54aef..90becbe81 100644 --- a/Assets/Tests/TestUtilsMonobehaviour.meta +++ b/Assets/Xsolla/Samples/Xsolla.Samples.asmdef.meta @@ -1,7 +1,6 @@ fileFormatVersion: 2 -guid: 14853bd6cd3ef574caf0d64031d97671 -folderAsset: yes -DefaultImporter: +guid: 9a55a7ff9c96c45c496247b3237899e8 +AssemblyDefinitionImporter: externalObjects: {} userData: assetBundleName: diff --git a/Assets/Xsolla/Subscriptions/Api.meta b/Assets/Xsolla/Subscriptions/Api.meta deleted file mode 100644 index 5909845d3..000000000 --- a/Assets/Xsolla/Subscriptions/Api.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: d58e64ddeb657854fa18bd7862b23b27 -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/Subscriptions/Api/XsollaSubscriptions.cs b/Assets/Xsolla/Subscriptions/Api/XsollaSubscriptions.cs deleted file mode 100644 index 2677cbab7..000000000 --- a/Assets/Xsolla/Subscriptions/Api/XsollaSubscriptions.cs +++ /dev/null @@ -1,231 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.Subscriptions -{ - public class XsollaSubscriptions : MonoSingleton - { - private const string BASE_SUBSCRIPTIONS_API_URL = "https://subscriptions.xsolla.com"; - - private const string URL_GET_PUBLIC_PLANS = BASE_SUBSCRIPTIONS_API_URL + "/api/public/v1/projects/{0}/user_plans"; - - private const string URL_GET_SUBSCRIPTIONS = BASE_SUBSCRIPTIONS_API_URL + "/api/user/v1/projects/{0}/subscriptions"; - private const string URL_GET_SUBSCRIPTION_DETAILS = BASE_SUBSCRIPTIONS_API_URL + "/api/user/v1/projects/{0}/subscriptions/{1}"; - private const string URL_CANCEL_SUBSCRIPTION = BASE_SUBSCRIPTIONS_API_URL + "/api/user/v1/projects/{0}/subscriptions/{1}/cancel"; - private const string URL_GET_RENEWAL_URL = BASE_SUBSCRIPTIONS_API_URL + "/api/user/v1/projects/{0}/subscriptions/{1}/renew"; - private const string URL_GET_PURCHASE_URL = BASE_SUBSCRIPTIONS_API_URL + "/api/user/v1/projects/{0}/subscriptions/buy"; - private const string URL_GET_MANAGEMENT_URL = BASE_SUBSCRIPTIONS_API_URL + "/api/user/v1/projects/{0}/subscriptions/manage"; - - private const string URL_GET_PLANS = BASE_SUBSCRIPTIONS_API_URL + "/api/user/v1/projects/{0}/plans"; - - /// - /// Returns a list of all plans, including plans purchased by the user while promotions are active. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscriptions-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Array of subscription plan IDs. Plan ID can be found in the URL of the subscription details page in Publisher Account (https://publisher.xsolla.com/{merchant_id}/projects/{project_id}/subscriptions/plans/{merplan_id}). - /// Called after public plans have been successfully recieved. - /// Called after the request resulted with an error. - /// List of subscription plan external IDs (32 characters per ID). Plan external ID can be found in Publisher Account in the **Subscriptions > Subscription plans** section next to the plan name. - /// Limit for the number of elements on the page (15 elements are displayed by default). - /// Number of elements from which the list is generated (the count starts from 0). - /// Language of the UI.
    - /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
    - /// By default, it is determined by the user's IP address. - /// User's country. Affects the choice of locale and currency. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. - public void GetSubscriptionPublicPlans(string projectId, Action onSuccess, Action onError = null, int[] planId = null, string[] planExternalId = null, int limit = 50, int offset = 0, string locale = null, string country = null) - { - var url = string.Format(URL_GET_PUBLIC_PLANS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, "plan_id", planId); - url = UrlParameterizer.ConcatUrlAndParams(url, "plan_external_id", planExternalId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, country: country); - WebRequestHelper.Instance.GetRequest(SdkType.Subscriptions, url, onSuccess, onError); - } - - /// - /// Returns a list of active recurrent subscriptions that have the status `active`, `non renewing`, and `pause`. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after the list pf subscriptions has been successfully recieved. - /// Called after the request resulted with an error. - /// Limit for the number of elements on the page (15 elements are displayed by default). - /// Number of elements from which the list is generated (the count starts from 0). - /// Language of the UI.
    - /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
    - /// By default, it is determined by the user's IP address. - public void GetSubscriptions(string projectId, Action onSuccess, Action onError = null, int limit = 50, int offset = 0, string locale = null) - { - var url = string.Format(URL_GET_SUBSCRIPTIONS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale); - WebRequestHelper.Instance.GetRequest(SdkType.Subscriptions, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, onError); - } - - /// - /// Returns information about a subscription by its ID. Subscription can be have any status. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Subscription ID. - /// Called after subscription data have been successfully recieved. - /// Called after the request resulted with an error. - /// Language of the UI.
    - /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
    - /// By default, it is determined by the user's IP address. - public void GetSubscriptionDetails(string projectId, int subscriptionId, Action onSuccess, Action onError = null, string locale = null) - { - var url = string.Format(URL_GET_SUBSCRIPTION_DETAILS, projectId, subscriptionId); - url = UrlParameterizer.ConcatUrlAndParams(url, locale: locale); - WebRequestHelper.Instance.GetRequest(SdkType.Subscriptions, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, onError); - } - - /// - /// Changes a regular subscription status to `non_renewing` (subscription is automatically canceled after expiration). - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Subscription ID. - /// Called after successful subscription cancelling. - /// Called after the request resulted with an error. - public void CancelSubscription(string projectId, int subscriptionId, Action onSuccess, Action onError = null) - { - var url = string.Format(URL_CANCEL_SUBSCRIPTION, projectId, subscriptionId); - WebRequestHelper.Instance.PutRequest(SdkType.Subscriptions, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, onError); - } - - /// - /// Returns the URL of the renewal interface for the selected subscription. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Subscription ID. - /// Pay Station UI settings. - /// Called after the URL has been successfully recieved. - /// Called after the request resulted with an error. - public void GetSubscriptionRenewalUrl(string projectId, int subscriptionId, PaymentSettings settings, Action onSuccess, Action onError = null) - { - var url = string.Format(URL_GET_RENEWAL_URL, projectId, subscriptionId); - var data = new RenewalSubscriptionRequest(CheckAndFillPaymentSettings(settings)); - WebRequestHelper.Instance.PostRequest(SdkType.Subscriptions, url, data, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, onError); - } - - public void GetSubscriptionRenewalUrl(string projectId, int subscriptionId, Action onSuccess, Action onError = null) - { - GetSubscriptionRenewalUrl(projectId, subscriptionId, new PaymentSettings(), onSuccess, onError); - } - - /// - /// Returns Pay Station URL for the subscription purchase. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscriptions-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// List of subscription plan external IDs (32 characters per ID). Plan external ID can be found in Publisher Account in the **Subscriptions > Subscription plans** section next to the plan name. - /// Pay Station UI settings. - /// Called after the URL has been successfully recieved. - /// Called after the request resulted with an error. - /// User's country. Affects the choice of locale and currency. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. - public void GetSubscriptionPurchaseUrl(string projectId, string planExternalId, PaymentSettings settings, Action onSuccess, Action onError = null, string country = null) - { - var url = string.Format(URL_GET_PURCHASE_URL, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, country: country); - - var data = new BuySubscriptionRequest(planExternalId, CheckAndFillPaymentSettings(settings)); - WebRequestHelper.Instance.PostRequest(SdkType.Subscriptions, url, data, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, onError); - } - - public void GetSubscriptionPurchaseUrl(string projectId, string planExternalId, Action onSuccess, Action onError = null, string country = null) - { - GetSubscriptionPurchaseUrl(projectId, planExternalId, new PaymentSettings(), onSuccess, onError, country); - } - - /// - /// Returns the URL of the management interface for the selected subscription. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Settings. - /// Called after the URL jas beeb successfully revieved. - /// Called after the request resulted with an error. - /// User's country. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Affects the choice of locale and currency. By default, it is determined by the user's IP address. - public void GetSubscriptionManagementUrl(string projectId, PaymentSettings settings, Action onSuccess, Action onError = null, string country = null) - { - var url = string.Format(URL_GET_MANAGEMENT_URL, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, country: country); - - var data = new ManageSubscriptionRequest(CheckAndFillPaymentSettings(settings)); - WebRequestHelper.Instance.PostRequest(SdkType.Subscriptions, url, data, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, onError); - } - - public void GetSubscriptionManagementUrl(string projectId, Action onSuccess, Action onError = null, string country = null) - { - GetSubscriptionManagementUrl(projectId, new PaymentSettings(), onSuccess, onError, country); - } - - /// - /// Returns a list of plans available to authorized users, including plans purchased by the user while promotions are active. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscriptions-purchase/). - /// Project ID, can be found in Publisher Account next to the name of the project. - /// Called after a list of plans has been successfully recieved. - /// Called after the request resulted with an error. - /// Array of subscription plan IDs. Plan ID can be found in the URL of the subscription details page in Publisher Account (https://publisher.xsolla.com/{merchant_id}/projects/{project_id}/subscriptions/plans/{merplan_id}). - /// List of subscription plan external IDs (32 characters per ID). Plan external ID can be found in Publisher Account in the **Subscriptions > Subscription plans** section next to the plan name. - /// Limit for the number of elements on the page (15 elements are displayed by default). - /// Number of elements from which the list is generated (the count starts from 0). - /// Language of the UI.
    - /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). - /// By default, it is determined by the user's IP address. - /// User's country. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Affects the choice of locale and currency. By default, it is determined by the user's IP address. - public void GetSubscriptionPlans(string projectId, Action onSuccess, Action onError = null, int[] planId = null, string[] planExternalId = null, int limit = 50, int offset = 0, string locale = null, string country = null) - { - var url = string.Format(URL_GET_PLANS, projectId); - url = UrlParameterizer.ConcatUrlAndParams(url, "plan_id", planId); - url = UrlParameterizer.ConcatUrlAndParams(url, "plan_external_id", planExternalId); - url = UrlParameterizer.ConcatUrlAndParams(url, limit: limit, offset: offset, locale: locale, country: country); - WebRequestHelper.Instance.GetRequest(SdkType.Subscriptions, url, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, onError); - } - - private PaymentSettings CheckAndFillPaymentSettings(PaymentSettings paymentSettings) - { - if (paymentSettings == null) - paymentSettings = new PaymentSettings(); - - if (paymentSettings.sandbox == null) - paymentSettings.sandbox = XsollaSettings.IsSandbox; - - var commonUiSettings = PayStationUISettings.GenerateSettings(); - if (commonUiSettings != null) - { - if (paymentSettings.ui == null) - paymentSettings.ui = new PaymentSettings.UI(); - - if (paymentSettings.ui.size == null) - paymentSettings.ui.size = commonUiSettings.size; - if (paymentSettings.ui.theme == null) - paymentSettings.ui.theme = commonUiSettings.theme; - if (paymentSettings.ui.version == null) - paymentSettings.ui.version = commonUiSettings.version; - } - - var commonRedirectPolicy = RedirectPolicySettings.GeneratePolicy(); - if (commonRedirectPolicy != null) - { - if (paymentSettings.redirect_policy == null) - paymentSettings.redirect_policy = new PaymentSettings.RedirectPolicy(); - - if (paymentSettings.return_url == null) - paymentSettings.return_url = commonRedirectPolicy.return_url; - if (paymentSettings.redirect_policy.redirect_conditions == null) - paymentSettings.redirect_policy.redirect_conditions = commonRedirectPolicy.redirect_conditions; - if (paymentSettings.redirect_policy.delay == null) - paymentSettings.redirect_policy.delay = commonRedirectPolicy.delay; - if (paymentSettings.redirect_policy.status_for_manual_redirection == null) - paymentSettings.redirect_policy.status_for_manual_redirection = commonRedirectPolicy.status_for_manual_redirection; - if (paymentSettings.redirect_policy.redirect_button_caption == null) - paymentSettings.redirect_policy.redirect_button_caption = commonRedirectPolicy.redirect_button_caption; - } - - return paymentSettings; - } - } -} diff --git a/Assets/Xsolla/Subscriptions/Entities/BuySubscriptionRequest.cs b/Assets/Xsolla/Subscriptions/Entities/BuySubscriptionRequest.cs deleted file mode 100644 index 0d3f902c4..000000000 --- a/Assets/Xsolla/Subscriptions/Entities/BuySubscriptionRequest.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; - -namespace Xsolla.Subscriptions -{ - [Serializable] - public class BuySubscriptionRequest - { - public string plan_external_id; - public PaymentSettings settings; - - public BuySubscriptionRequest(string planExternalId, PaymentSettings settings) - { - plan_external_id = planExternalId; - this.settings = settings; - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/ManageSubscriptionRequest.cs b/Assets/Xsolla/Subscriptions/Entities/ManageSubscriptionRequest.cs deleted file mode 100644 index a0ed09f30..000000000 --- a/Assets/Xsolla/Subscriptions/Entities/ManageSubscriptionRequest.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Xsolla.Subscriptions -{ - [Serializable] - public class ManageSubscriptionRequest - { - public PaymentSettings settings; - - public ManageSubscriptionRequest(PaymentSettings settings) - { - this.settings = settings; - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/PaymentSettings.cs b/Assets/Xsolla/Subscriptions/Entities/PaymentSettings.cs index 3bcdedec2..e8d6b30c8 100644 --- a/Assets/Xsolla/Subscriptions/Entities/PaymentSettings.cs +++ b/Assets/Xsolla/Subscriptions/Entities/PaymentSettings.cs @@ -1,66 +1,43 @@ using System; -using Newtonsoft.Json; namespace Xsolla.Subscriptions { [Serializable] public class PaymentSettings { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? sandbox; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public UI ui; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string currency; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string locale; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string external_id; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public int? payment_method; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string return_url; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public RedirectPolicy redirect_policy; [Serializable] public class UI { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string size; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string theme; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string version; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Desktop desktop; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Mobile mobile; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string license_url; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string mode; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public UserAccount user_account; [Serializable] public class Desktop { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Header header; [Serializable] public class Header { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? is_visible; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? visible_logo; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? visible_name; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string type; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? close_button; } } @@ -68,23 +45,19 @@ public class Header [Serializable] public class Mobile { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string mode; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Footer footer; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public Header header; [Serializable] public class Footer { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? is_visible; } + [Serializable] public class Header { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public bool? close_button; } } @@ -92,13 +65,9 @@ public class Header [Serializable] public class UserAccount { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public EnableAndOrder history; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public EnableAndOrder payment_accounts; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public EnableAndOrder info; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public EnableAndOrder subscriptions; [Serializable] @@ -113,13 +82,9 @@ public class EnableAndOrder [Serializable] public class RedirectPolicy { - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string redirect_conditions; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public int? delay; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string status_for_manual_redirection; - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public string redirect_button_caption; } } diff --git a/Assets/Xsolla/Subscriptions/Enum/PeriodUnit.cs b/Assets/Xsolla/Subscriptions/Entities/PeriodUnit.cs similarity index 100% rename from Assets/Xsolla/Subscriptions/Enum/PeriodUnit.cs rename to Assets/Xsolla/Subscriptions/Entities/PeriodUnit.cs diff --git a/Assets/Xsolla/Subscriptions/Enum/PeriodUnit.cs.meta b/Assets/Xsolla/Subscriptions/Entities/PeriodUnit.cs.meta similarity index 100% rename from Assets/Xsolla/Subscriptions/Enum/PeriodUnit.cs.meta rename to Assets/Xsolla/Subscriptions/Entities/PeriodUnit.cs.meta diff --git a/Assets/Xsolla/Subscriptions/Entities/PlanItem.cs b/Assets/Xsolla/Subscriptions/Entities/PlanItem.cs deleted file mode 100644 index aa38738cb..000000000 --- a/Assets/Xsolla/Subscriptions/Entities/PlanItem.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; - -namespace Xsolla.Subscriptions -{ - [Serializable] - public class PlanItem - { - public int plan_id; - public string plan_external_id; - public string plan_group_id; - public string plan_type; - public string plan_name; - public string plan_description; - public DateTime? plan_start_date; - public DateTime? plan_end_date; - public int? trial_period; - public Period period; - public PlanCharge charge; - public PlanPromotion promotion; - - public PlanType PlanType - { - get - { - switch (plan_type) - { - case "all": return PlanType.All; - default: return PlanType.Unknown; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/PlanItem.cs.meta b/Assets/Xsolla/Subscriptions/Entities/PlanItem.cs.meta deleted file mode 100644 index 44ba1c159..000000000 --- a/Assets/Xsolla/Subscriptions/Entities/PlanItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 09040302988e4a4083850bdb66cf537f -timeCreated: 1652428939 \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/PlanItems.cs b/Assets/Xsolla/Subscriptions/Entities/PlanItems.cs index 2d91fdd63..0e4b8ea2b 100644 --- a/Assets/Xsolla/Subscriptions/Entities/PlanItems.cs +++ b/Assets/Xsolla/Subscriptions/Entities/PlanItems.cs @@ -8,4 +8,33 @@ public class PlanItems public PlanItem[] items; public bool has_more; } + + [Serializable] + public class PlanItem + { + public int plan_id; + public string plan_external_id; + public string plan_group_id; + public string plan_type; + public string plan_name; + public string plan_description; + public DateTime? plan_start_date; + public DateTime? plan_end_date; + public int? trial_period; + public Period period; + public PlanCharge charge; + public PlanPromotion promotion; + + public PlanType PlanType + { + get + { + switch (plan_type) + { + case "all": return PlanType.All; + default: return PlanType.Unknown; + } + } + } + } } \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Enum/PlanType.cs b/Assets/Xsolla/Subscriptions/Entities/PlanType.cs similarity index 100% rename from Assets/Xsolla/Subscriptions/Enum/PlanType.cs rename to Assets/Xsolla/Subscriptions/Entities/PlanType.cs diff --git a/Assets/Xsolla/Subscriptions/Enum/PlanType.cs.meta b/Assets/Xsolla/Subscriptions/Entities/PlanType.cs.meta similarity index 100% rename from Assets/Xsolla/Subscriptions/Enum/PlanType.cs.meta rename to Assets/Xsolla/Subscriptions/Entities/PlanType.cs.meta diff --git a/Assets/Xsolla/Subscriptions/Entities/RenewalSubscriptionRequest.cs b/Assets/Xsolla/Subscriptions/Entities/RenewalSubscriptionRequest.cs deleted file mode 100644 index e2fade9bd..000000000 --- a/Assets/Xsolla/Subscriptions/Entities/RenewalSubscriptionRequest.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace Xsolla.Subscriptions -{ - [Serializable] - public class RenewalSubscriptionRequest - { - public PaymentSettings settings; - - public RenewalSubscriptionRequest(PaymentSettings settings) - { - this.settings = settings; - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/SubscriptionItem.cs b/Assets/Xsolla/Subscriptions/Entities/SubscriptionItem.cs deleted file mode 100644 index d05dc6416..000000000 --- a/Assets/Xsolla/Subscriptions/Entities/SubscriptionItem.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; - -namespace Xsolla.Subscriptions -{ - [Serializable] - public class SubscriptionItem - { - public int id; - public int plan_id; - public string plan_external_id; - public string plan_name; - public string plan_description; - public DateTime? plan_start_date; - public DateTime? plan_end_date; - public int? product_id; - public string product_external_id; - public string product_name; - public string product_description; - public string status; - public bool is_in_trial; - public int? trial_period; - public DateTime date_create; - public DateTime? date_next_charge; - public DateTime? date_last_charge; - public SubscriptionCharge charge; - public Period period; - - public SubscriptionStatus Status - { - get - { - switch (status) - { - case "new": return SubscriptionStatus.New; - case "active": return SubscriptionStatus.Active; - case "canceled": return SubscriptionStatus.Canceled; - case "non_renewing": return SubscriptionStatus.NonRenewing; - case "pause": return SubscriptionStatus.Pause; - default: return SubscriptionStatus.Unknown; - } - } - } - } -} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/SubscriptionItem.cs.meta b/Assets/Xsolla/Subscriptions/Entities/SubscriptionItem.cs.meta deleted file mode 100644 index b51eebd16..000000000 --- a/Assets/Xsolla/Subscriptions/Entities/SubscriptionItem.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 543b3355e9b94a638d377aa8ff842b40 -timeCreated: 1652429745 \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/SubscriptionItems.cs b/Assets/Xsolla/Subscriptions/Entities/SubscriptionItems.cs index 109643862..459dce0f5 100644 --- a/Assets/Xsolla/Subscriptions/Entities/SubscriptionItems.cs +++ b/Assets/Xsolla/Subscriptions/Entities/SubscriptionItems.cs @@ -8,4 +8,44 @@ public class SubscriptionItems public SubscriptionItem[] items; public bool has_more; } + + [Serializable] + public class SubscriptionItem + { + public int id; + public int plan_id; + public string plan_external_id; + public string plan_name; + public string plan_description; + public DateTime? plan_start_date; + public DateTime? plan_end_date; + public int? product_id; + public string product_external_id; + public string product_name; + public string product_description; + public string status; + public bool is_in_trial; + public int? trial_period; + public DateTime date_create; + public DateTime? date_next_charge; + public DateTime? date_last_charge; + public SubscriptionCharge charge; + public Period period; + + public SubscriptionStatus Status + { + get + { + switch (status) + { + case "new": return SubscriptionStatus.New; + case "active": return SubscriptionStatus.Active; + case "canceled": return SubscriptionStatus.Canceled; + case "non_renewing": return SubscriptionStatus.NonRenewing; + case "pause": return SubscriptionStatus.Pause; + default: return SubscriptionStatus.Unknown; + } + } + } + } } \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Enum/SubscriptionStatus.cs b/Assets/Xsolla/Subscriptions/Entities/SubscriptionStatus.cs similarity index 100% rename from Assets/Xsolla/Subscriptions/Enum/SubscriptionStatus.cs rename to Assets/Xsolla/Subscriptions/Entities/SubscriptionStatus.cs diff --git a/Assets/Xsolla/Subscriptions/Enum/SubscriptionStatus.cs.meta b/Assets/Xsolla/Subscriptions/Entities/SubscriptionStatus.cs.meta similarity index 100% rename from Assets/Xsolla/Subscriptions/Enum/SubscriptionStatus.cs.meta rename to Assets/Xsolla/Subscriptions/Entities/SubscriptionStatus.cs.meta diff --git a/Assets/Xsolla/Subscriptions/Enum.meta b/Assets/Xsolla/Subscriptions/Enum.meta deleted file mode 100644 index 85f0d4c79..000000000 --- a/Assets/Xsolla/Subscriptions/Enum.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 58a15882705a49c0b0d716d766dda82a -timeCreated: 1652428987 \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Internal.meta b/Assets/Xsolla/Subscriptions/Internal.meta new file mode 100644 index 000000000..2d4194b2f --- /dev/null +++ b/Assets/Xsolla/Subscriptions/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: d79131fbc3534c65ab343584c4fe1432 +timeCreated: 1682699013 \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Internal/BuySubscriptionRequest.cs b/Assets/Xsolla/Subscriptions/Internal/BuySubscriptionRequest.cs new file mode 100644 index 000000000..635d1dee2 --- /dev/null +++ b/Assets/Xsolla/Subscriptions/Internal/BuySubscriptionRequest.cs @@ -0,0 +1,11 @@ +using System; + +namespace Xsolla.Subscriptions +{ + [Serializable] + internal class BuySubscriptionRequest + { + public string plan_external_id; + public PaymentSettings settings; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/BuySubscriptionRequest.cs.meta b/Assets/Xsolla/Subscriptions/Internal/BuySubscriptionRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Subscriptions/Entities/BuySubscriptionRequest.cs.meta rename to Assets/Xsolla/Subscriptions/Internal/BuySubscriptionRequest.cs.meta diff --git a/Assets/Xsolla/Subscriptions/Internal/ManageSubscriptionRequest.cs b/Assets/Xsolla/Subscriptions/Internal/ManageSubscriptionRequest.cs new file mode 100644 index 000000000..0b46bff6e --- /dev/null +++ b/Assets/Xsolla/Subscriptions/Internal/ManageSubscriptionRequest.cs @@ -0,0 +1,10 @@ +using System; + +namespace Xsolla.Subscriptions +{ + [Serializable] + internal class ManageSubscriptionRequest + { + public PaymentSettings settings; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/ManageSubscriptionRequest.cs.meta b/Assets/Xsolla/Subscriptions/Internal/ManageSubscriptionRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Subscriptions/Entities/ManageSubscriptionRequest.cs.meta rename to Assets/Xsolla/Subscriptions/Internal/ManageSubscriptionRequest.cs.meta diff --git a/Assets/Xsolla/Subscriptions/Internal/RenewalSubscriptionRequest.cs b/Assets/Xsolla/Subscriptions/Internal/RenewalSubscriptionRequest.cs new file mode 100644 index 000000000..f992fdbe8 --- /dev/null +++ b/Assets/Xsolla/Subscriptions/Internal/RenewalSubscriptionRequest.cs @@ -0,0 +1,10 @@ +using System; + +namespace Xsolla.Subscriptions +{ + [Serializable] + internal class RenewalSubscriptionRequest + { + public PaymentSettings settings; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Entities/RenewalSubscriptionRequest.cs.meta b/Assets/Xsolla/Subscriptions/Internal/RenewalSubscriptionRequest.cs.meta similarity index 100% rename from Assets/Xsolla/Subscriptions/Entities/RenewalSubscriptionRequest.cs.meta rename to Assets/Xsolla/Subscriptions/Internal/RenewalSubscriptionRequest.cs.meta diff --git a/Assets/Xsolla/Subscriptions/XsollaSubscriptions.cs b/Assets/Xsolla/Subscriptions/XsollaSubscriptions.cs new file mode 100644 index 000000000..f7bd8b99d --- /dev/null +++ b/Assets/Xsolla/Subscriptions/XsollaSubscriptions.cs @@ -0,0 +1,270 @@ +using System; +using Xsolla.Core; + +namespace Xsolla.Subscriptions +{ + public static class XsollaSubscriptions + { + private const string BaseUrl = "https://subscriptions.xsolla.com/api"; + private static string StoreProjectId => XsollaSettings.StoreProjectId; + + /// + /// Returns a list of all plans, including plans purchased by the user while promotions are active. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscriptions-purchase/). + /// Called after public plans have been successfully received. + /// Called after the request resulted with an error. + /// Array of subscription plan IDs. Plan ID can be found in the URL of the subscription details page in Publisher Account (https://publisher.xsolla.com/{merchant_id}/projects/{project_id}/subscriptions/plans/{plan_id}). + /// List of subscription plan external IDs (32 characters per ID). Plan external ID can be found in Publisher Account in the **Subscriptions > Subscription plans** section next to the plan name. + /// Limit for the number of elements on the page (15 elements are displayed by default). + /// Number of elements from which the list is generated (the count starts from 0). + /// Language of the UI.
    + /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
    + /// By default, it is determined by the user's IP address. + /// User's country. Affects the choice of locale and currency. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. + public static void GetSubscriptionPublicPlans(Action onSuccess, Action onError, int[] planId = null, string[] planExternalId = null, int limit = 50, int offset = 0, string locale = null, string country = null) + { + var url = new UrlBuilder($"{BaseUrl}/public/v1/projects/{StoreProjectId}/user_plans") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddArray("plan_id", planId) + .AddArray("plan_external_id", planExternalId) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Subscriptions, + url, + onSuccess, + onError); + } + + /// + /// Returns a list of active recurrent subscriptions that have the status `active`, `non renewing`, and `pause`. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). + /// Called after the list pf subscriptions has been successfully received. + /// Called after the request resulted with an error. + /// Limit for the number of elements on the page (15 elements are displayed by default). + /// Number of elements from which the list is generated (the count starts from 0). + /// Language of the UI.
    + /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
    + /// By default, it is determined by the user's IP address. + public static void GetSubscriptions(Action onSuccess, Action onError, int limit = 50, int offset = 0, string locale = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/v1/projects/{StoreProjectId}/subscriptions") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Subscriptions, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetSubscriptions(onSuccess, onError, limit, offset, locale))); + } + + /// + /// Returns information about a subscription by its ID. Subscription can be have any status. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). + /// Subscription ID. + /// Called after subscription data have been successfully received. + /// Called after the request resulted with an error. + /// Language of the UI.
    + /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default).
    + /// By default, it is determined by the user's IP address. + public static void GetSubscriptionDetails(int subscriptionId, Action onSuccess, Action onError, string locale = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/v1/projects/{StoreProjectId}/subscriptions/{subscriptionId}") + .AddLocale(locale) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Subscriptions, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetSubscriptionDetails(subscriptionId, onSuccess, onError, locale))); + } + + /// + /// Changes a regular subscription status to `non_renewing` (subscription is automatically canceled after expiration). + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). + /// Subscription ID. + /// Called after successful subscription cancelling. + /// Called after the request resulted with an error. + public static void CancelSubscription(int subscriptionId, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/user/v1/projects/{StoreProjectId}/subscriptions/{subscriptionId}/cancel"; + + WebRequestHelper.Instance.PutRequest( + SdkType.Subscriptions, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => CancelSubscription(subscriptionId, onSuccess, onError))); + } + + /// + /// Returns the URL of the renewal interface for the selected subscription. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). + /// Subscription ID. + /// Called after the URL has been successfully received. + /// Called after the request resulted with an error. + /// Pay Station UI settings. + public static void GetSubscriptionRenewalUrl(int subscriptionId, Action onSuccess, Action onError, PaymentSettings settings = null) + { + var url = $"{BaseUrl}/user/v1/projects/{StoreProjectId}/subscriptions/{subscriptionId}/renew"; + + var requestData = new RenewalSubscriptionRequest { + settings = CheckAndFillPaymentSettings(settings) + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Subscriptions, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetSubscriptionRenewalUrl(subscriptionId, onSuccess, onError, settings))); + } + + /// + /// Returns Pay Station URL for the subscription purchase. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscriptions-purchase/). + /// List of subscription plan external IDs (32 characters per ID). Plan external ID can be found in Publisher Account in the **Subscriptions > Subscription plans** section next to the plan name. + /// Called after the URL has been successfully received. + /// Called after the request resulted with an error. + /// Pay Station UI settings. + /// User's country. Affects the choice of locale and currency. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). By default, it is determined by the user's IP address. + public static void GetSubscriptionPurchaseUrl(string planExternalId, Action onSuccess, Action onError, PaymentSettings settings = null, string country = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/v1/projects/{StoreProjectId}/subscriptions/buy") + .AddCountry(country) + .Build(); + + var requestData = new BuySubscriptionRequest { + plan_external_id = planExternalId, + settings = CheckAndFillPaymentSettings(settings) + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Subscriptions, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetSubscriptionPurchaseUrl(planExternalId, onSuccess, onError, settings, country))); + } + + /// + /// Returns the URL of the management interface for the selected subscription. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscription-management/). + /// Called after the URL has been successfully received. + /// Called after the request resulted with an error. + /// Settings. + /// User's country. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Affects the choice of locale and currency. By default, it is determined by the user's IP address. + public static void GetSubscriptionManagementUrl(Action onSuccess, Action onError, PaymentSettings settings = null, string country = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/v1/projects/{StoreProjectId}/subscriptions/manage") + .AddCountry(country) + .Build(); + + var requestData = new ManageSubscriptionRequest { + settings = CheckAndFillPaymentSettings(settings) + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Subscriptions, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetSubscriptionManagementUrl(onSuccess, onError, settings, country))); + } + + /// + /// Returns a list of plans available to authorized users, including plans purchased by the user while promotions are active. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/subscriptions/subscriptions-purchase/). + /// Called after a list of plans has been successfully received. + /// Called after the request resulted with an error. + /// Array of subscription plan IDs. Plan ID can be found in the URL of the subscription details page in Publisher Account (https://publisher.xsolla.com/{merchant_id}/projects/{project_id}/subscriptions/plans/{plan_id}). + /// List of subscription plan external IDs (32 characters per ID). Plan external ID can be found in Publisher Account in the **Subscriptions > Subscription plans** section next to the plan name. + /// Limit for the number of elements on the page (15 elements are displayed by default). + /// Number of elements from which the list is generated (the count starts from 0). + /// Language of the UI.
    + /// The following languages are supported: Arabic (`ar`), Bulgarian (`bg`), Czech (`cs`), German (`de`), Spanish (`es`), French (`fr`), Hebrew (`he`), Italian (`it`), Japanese (`ja`), Korean (`ko`), Polish (`pl`), Portuguese (`pt`), Romanian (`ro`), Russian (`ru`), Thai (`th`), Turkish (`tr`), Vietnamese (`vi`), Chinese Simplified (`cn`), Chinese Traditional (`tw`), English (`en`, default). + /// By default, it is determined by the user's IP address. + /// User's country. Two-letter uppercase country code per [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2). Affects the choice of locale and currency. By default, it is determined by the user's IP address. + public static void GetSubscriptionPlans(Action onSuccess, Action onError, int[] planId = null, string[] planExternalId = null, int limit = 50, int offset = 0, string locale = null, string country = null) + { + var url = new UrlBuilder($"{BaseUrl}/user/v1/projects/{StoreProjectId}/plans") + .AddLimit(limit) + .AddOffset(offset) + .AddLocale(locale) + .AddCountry(country) + .AddArray("plan_id", planId) + .AddArray("plan_external_id", planExternalId) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Subscriptions, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetSubscriptionPlans(onSuccess, onError, planId, planExternalId, limit, offset, locale, country))); + } + + private static PaymentSettings CheckAndFillPaymentSettings(PaymentSettings settings) + { + if (settings == null) + settings = new PaymentSettings(); + + if (settings.sandbox == null) + settings.sandbox = XsollaSettings.IsSandbox; + + var commonUiSettings = PayStationUISettings.GenerateSettings(); + if (commonUiSettings != null) + { + if (settings.ui == null) + settings.ui = new PaymentSettings.UI(); + + if (settings.ui.size == null) + settings.ui.size = commonUiSettings.size; + if (settings.ui.theme == null) + settings.ui.theme = commonUiSettings.theme; + if (settings.ui.version == null) + settings.ui.version = commonUiSettings.version; + } + + var commonRedirectPolicy = RedirectPolicySettings.GeneratePolicy(); + if (commonRedirectPolicy != null) + { + if (settings.redirect_policy == null) + settings.redirect_policy = new PaymentSettings.RedirectPolicy(); + + if (settings.return_url == null) + settings.return_url = commonRedirectPolicy.return_url; + if (settings.redirect_policy.redirect_conditions == null) + settings.redirect_policy.redirect_conditions = commonRedirectPolicy.redirect_conditions; + if (settings.redirect_policy.delay == null) + settings.redirect_policy.delay = commonRedirectPolicy.delay; + if (settings.redirect_policy.status_for_manual_redirection == null) + settings.redirect_policy.status_for_manual_redirection = commonRedirectPolicy.status_for_manual_redirection; + if (settings.redirect_policy.redirect_button_caption == null) + settings.redirect_policy.redirect_button_caption = commonRedirectPolicy.redirect_button_caption; + } + + return settings; + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/Subscriptions/Api/XsollaSubscriptions.cs.meta b/Assets/Xsolla/Subscriptions/XsollaSubscriptions.cs.meta similarity index 100% rename from Assets/Xsolla/Subscriptions/Api/XsollaSubscriptions.cs.meta rename to Assets/Xsolla/Subscriptions/XsollaSubscriptions.cs.meta diff --git a/Assets/Xsolla/UserAccount/Api.meta b/Assets/Xsolla/UserAccount/Api.meta deleted file mode 100644 index 33ec693ce..000000000 --- a/Assets/Xsolla/UserAccount/Api.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: 26ddee34e7631ba4ca17b0bfd700d75d -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.AccountLinking.cs b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.AccountLinking.cs deleted file mode 100644 index e990bba11..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.AccountLinking.cs +++ /dev/null @@ -1,101 +0,0 @@ -using System; -using Xsolla.Core; - -namespace Xsolla.UserAccount -{ - public partial class XsollaUserAccount : MonoSingleton - { - private const string URL_LINKING_CODE_REQUEST = "https://login.xsolla.com/api/users/account/code"; - private const string URL_LINK_ACCOUNT = "https://livedemo.xsolla.com/sdk/sdk-shadow-account/link"; - - #region Comment - /// - /// Creates the code for linking the platform account to the existing main account when the user logs in to the game via a gaming console. - /// The call is used with [Link accounts by code](https://developers.xsolla.com/login-api/linking-account/linking/link-accounts-by-code/) request. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/account-linking/). - /// Called after successful linking code creation. - /// Called after the request resulted with an error. - /// - /// - #endregion - public void RequestLinkingCode(Action onSuccess, Action onError) - { - WebRequestHelper.Instance.PostRequest(SdkType.Login, URL_LINKING_CODE_REQUEST, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => RequestLinkingCode(onSuccess, onError))); - } - - #region Comment - /// - /// This method is used for authenticating users in Xsolla Login, - /// who play on the consoles and other platforms - /// where Xsolla Login isn't used. You must implement it - /// on the your server side. - /// Integration flow on the server side: - /// - /// - /// Generate server JWT - /// - /// - /// - /// Connect OAuth 2.0 server client - /// Follow the [instructions](https://developers.xsolla.com/doc/login/security/connecting-oauth2/#login_features_connecting_oauth2_connecting_client) to connect the client and cope copy the Client ID and Secret key. - /// - /// - /// - /// Implement method: - /// - /// - /// with `application/x-www-form-urlencoded` payload parameters: - /// - /// - /// client_id=YOUR_CLIENT_ID - /// - /// - /// client_secret=YOUR_CLIENT_SECRET - /// - /// - /// grant_type=client_credentials - /// - /// - /// - /// - /// - /// - /// - /// - /// Implement APIs for account linking - /// - /// - /// with: - /// - /// - /// Headers - /// - /// `Content-Type: application/json` and `X-SERVER-AUTHORIZATION: YourGeneratedJwt` - /// - /// - /// - /// Body - /// [See documentation](https://developers.xsolla.com/api/login/operation/link-accounts-by-code/). - /// - /// - /// - /// - /// - /// - /// Social platform (XBox, PS4, etc) user unique identifier. - /// Platform name (XBox, PS4, etc). - /// Code, taken from unified account. - /// Success operation callback. - /// Called after the request resulted with an error. - /// - /// - #endregion - public void LinkConsoleAccount(string userId, string platform, string confirmationCode, Action onSuccess, Action onError) - { - var url = $"{URL_LINK_ACCOUNT}?user_id={userId}&platform={platform}&code={confirmationCode}"; - WebRequestHelper.Instance.PostRequest(sdkType: SdkType.Login, url: url, onComplete: onSuccess, onError: onError); - } - } -} diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.AccountLinking.cs.meta b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.AccountLinking.cs.meta deleted file mode 100644 index 0cee726b6..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.AccountLinking.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 62e21904f6823cf478bffaafdbf48eee -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Attributes.cs b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Attributes.cs deleted file mode 100644 index d1f4158e4..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Attributes.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Generic; -using JetBrains.Annotations; -using Xsolla.Core; - -namespace Xsolla.UserAccount -{ - public partial class XsollaUserAccount : MonoSingleton - { - private const string URL_USER_GET_ATTRIBUTES = "https://login.xsolla.com/api/attributes/users/me/get"; - private const string URL_USER_GET_READONLY_ATTRIBUTES = "https://login.xsolla.com/api/attributes/users/me/get_read_only"; - private const string URL_USER_UPDATE_ATTRIBUTES = "https://login.xsolla.com/api/attributes/users/me/update"; - - /// - /// Returns a list of particular user’s attributes with their values and descriptions. Returns only user-editable attributes. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-attributes/). - /// User authorization token. - /// Project ID from Publisher Account which you want to get attributes for. If you do not specify it, it returns attributes that were created without this parameter. - /// Type of attributes to get. Can be `Readonly` or `Custom`. - /// List of attributes’ keys which you want to get. If not specified, the method returns all user’s attributes. - /// Identifier of a user whose public attributes should be requested. If not specified, the method returns attrubutes for the current user. - /// Called after user attributes were successfully received. - /// Called after the request resulted with an error. - /// - /// - public void GetUserAttributes(string token, string publisherProjectId, UserAttributeType attributeType, [CanBeNull] List keys, [CanBeNull] string userId, [NotNull] Action> onSuccess, [CanBeNull] Action onError) - { - var getAttributesRequestBody = new GetAttributesJson(keys, publisherProjectId, userId); - var headers = new List { WebRequestHeader.AuthHeader(token), WebRequestHeader.ContentTypeHeader() }; - - string url = default(string); - - switch (attributeType) - { - case UserAttributeType.CUSTOM: - url = URL_USER_GET_ATTRIBUTES; - break; - case UserAttributeType.READONLY: - url = URL_USER_GET_READONLY_ATTRIBUTES; - break; - } - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, getAttributesRequestBody, headers, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetUserAttributes(Token.Instance, publisherProjectId, attributeType, keys, userId, onSuccess, onError))); - } - - public void GetUserAttributes(string publisherProjectId, UserAttributeType attributeType, [CanBeNull] List keys, [CanBeNull] string userId, [NotNull] Action> onSuccess, [CanBeNull] Action onError) - { - GetUserAttributes(Token.Instance, publisherProjectId, attributeType, keys, userId, onSuccess, onError); - } - - /// - /// Updates the values of user attributes with the specified IDs. The method can be used to create or remove attributes. Changes are made on the user data storage side (server side). - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-attributes/). - /// User authorization token. - /// Project ID from Publisher Account which you want to update the value of specified attributes for. If you do not specify it, it updates attributes that are general to all games only. - /// List of attributes of the specified game. To add attribute which does not exist, set this attribute to the `key` parameter. To update `value` of the attribute, specify its `key` parameter and set the new `value`. You can change several attributes at a time. - /// Called after successful user attributes modification on the server side. - /// Called after the request resulted with an error. - /// - /// - public void UpdateUserAttributes(string token, string publisherProjectId, List attributes, Action onSuccess, Action onError) - { - var modifyAttributesRequestBody = new ModifyAttributesJson(attributes, publisherProjectId, null); - var headers = new List() { WebRequestHeader.AuthHeader(token), WebRequestHeader.ContentTypeHeader() }; - - WebRequestHelper.Instance.PostRequest(SdkType.Login, URL_USER_UPDATE_ATTRIBUTES, modifyAttributesRequestBody, headers, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UpdateUserAttributes(Token.Instance, publisherProjectId, attributes, onSuccess, onError))); - } - - public void UpdateUserAttributes(string publisherProjectId, List attributes, Action onSuccess, Action onError) - { - UpdateUserAttributes(Token.Instance, publisherProjectId, attributes, onSuccess, onError); - } - - /// - /// Removes user attributes with the specified IDs. Changes are made on the user data storage side (server side). - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-attributes/). - /// User authorization token. - /// Project ID from Publisher Account which you want to get attributes for. If you do not specify it, it returns attributes that were created without this parameter. - /// List of attribute keys for removal. - /// Called after successful user attributes removal on the server side. - /// Called after the request resulted with an error. - /// - /// - public void RemoveUserAttributes(string token, string publisherProjectId, List removingKeys, Action onSuccess, Action onError) - { - var removeAttributesRequestBody = new ModifyAttributesJson(null, publisherProjectId, removingKeys); - var headers = new List() { WebRequestHeader.AuthHeader(token), WebRequestHeader.ContentTypeHeader() }; - - WebRequestHelper.Instance.PostRequest(SdkType.Login, URL_USER_UPDATE_ATTRIBUTES, removeAttributesRequestBody, headers, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => RemoveUserAttributes(Token.Instance, publisherProjectId, removingKeys, onSuccess, onError))); - } - - public void RemoveUserAttributes(string publisherProjectId, List removingKeys, Action onSuccess, Action onError) - { - RemoveUserAttributes(Token.Instance, publisherProjectId, removingKeys, onSuccess, onError); - } - } -} diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Attributes.cs.meta b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Attributes.cs.meta deleted file mode 100644 index 04a2b1d92..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Attributes.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: c913eb5c092a6bc4fa53425bb720f070 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.DeviceID.cs b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.DeviceID.cs deleted file mode 100644 index c8413f9b6..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.DeviceID.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Core; - -namespace Xsolla.UserAccount -{ - public partial class XsollaUserAccount : MonoSingleton - { - private const string URL_ADD_USERNAME_EMAIL = - "https://login.xsolla.com/api/users/me/link_email_password?login_url={0}"; - - private const string URL_GET_USERS_DEVICES = - "https://login.xsolla.com/api/users/me/devices"; - - private const string URL_DEVICES_LINKING = - "https://login.xsolla.com/api/users/me/devices/{0}"; - - /// - /// Adds a username, email address, and password, that can be used for authentication, to the current account. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). - /// Username. - /// User password. - /// User email. - /// Whether the user gave consent to receive the newsletters. - /// Called after successful email and password linking. - /// Called after the request resulted with an error. - public void AddUsernameEmailAuthToAccount(string username, string password, string email, int? promoEmailAgreement = null, Action onSuccess = null, Action onError = null) - { - var requestBody = new AddUsernameAndEmailRequest(username, password, email, promoEmailAgreement); - var loginUrl = RedirectUtils.GetRedirectUrl(); - var url = string.Format(URL_ADD_USERNAME_EMAIL, loginUrl); - - Action onComplete = response => - { - onSuccess?.Invoke(response.email_confirmation_required); - }; - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, requestBody, WebRequestHeader.AuthHeader(Token.Instance), - onComplete: onComplete, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => AddUsernameEmailAuthToAccount(username, password, email, promoEmailAgreement, onSuccess, onError)), - errorsToCheck: ErrorCheckType.RegistrationErrors); - } - - /// - /// Gets a list of user's devices. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). - /// Called after users devices data was successfully received. - /// Called after the request resulted with an error. - public void GetUserDevices(Action> onSuccess = null, Action onError = null) - { - WebRequestHelper.Instance.GetRequest>(SdkType.Login, URL_GET_USERS_DEVICES, WebRequestHeader.AuthHeader(Token.Instance), - onComplete: onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetUserDevices(onSuccess, onError))); - } - - /// - /// Links the specified device to the current user account. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). - /// Type of the device. Can be `android` or `ios`. - /// Manufacturer and model name of the device. - /// Platform specific unique device ID. - /// For Android, it is an [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID) constant.
    - /// For iOS, it is an [identifierForVendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc) property.
    - /// - /// Called after successful linking of the device. - /// Called after the request resulted with an error. - public void LinkDeviceToAccount(DeviceType deviceType, string device, string deviceId, Action onSuccess = null, Action onError = null) - { - var deviceTypeAsString = deviceType.ToString().ToLower(); - var requestBody = new LinkDeviceRequest(device, deviceId); - var url = string.Format(URL_DEVICES_LINKING, deviceTypeAsString); - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, requestBody, WebRequestHeader.AuthHeader(Token.Instance), - onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => LinkDeviceToAccount(deviceType, device, deviceId, onSuccess, onError))); - } - - /// - /// Unlinks the specified device from the current user account. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). - /// Platform specific unique device ID.
    - /// For Android, it is an [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID) constant.
    - /// For iOS, it is an [identifierForVendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc) property. - /// Called after successful unlinking of the device. - /// Called after the request resulted with an error. - public void UnlinkDeviceFromAccount(int id, Action onSuccess = null, Action onError = null) - { - var url = string.Format(URL_DEVICES_LINKING, id); - - WebRequestHelper.Instance.DeleteRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(Token.Instance), - onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UnlinkDeviceFromAccount(id, onSuccess, onError))); - } - } -} diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.DeviceID.cs.meta b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.DeviceID.cs.meta deleted file mode 100644 index 2e194035e..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.DeviceID.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: ee149b84fdca0ad498fb5c51fbe34cef -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Friends.cs b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Friends.cs deleted file mode 100644 index df83dce27..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Friends.cs +++ /dev/null @@ -1,178 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using UnityEngine; -using Xsolla.Core; - -namespace Xsolla.UserAccount -{ - public partial class XsollaUserAccount : MonoSingleton - { - private const string URL_USER_GET_FRIENDS = "https://login.xsolla.com/api/users/me/relationships?type={0}&sort_by={1}&sort_order={2}{3}{4}"; - private const string URL_USER_UPDATE_FRIENDS = "https://login.xsolla.com/api/users/me/relationships"; - private const string URL_USER_SOCIAL_FRIENDS = "https://login.xsolla.com/api/users/me/social_friends?offset={0}&limit={1}&with_xl_uid={2}{3}"; - private const string URL_USER_UPDATE_SOCIAL_FRIENDS = "https://login.xsolla.com/api/users/me/social_friends/update{0}"; - private const int USER_FRIENDS_DEFAULT_PAGINATION_LIMIT = 20; - - /// - /// Gets a list of user’s friends from a social provider. - /// - /// User authorization token. - /// Name of a social network. Provider must be connected to Login in Publisher Account.
    - /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, or `xbox`. - /// Number of the elements from which the list is generated. - /// Maximum number of friends that are returned at a time. - /// Shows whether the social friends are from your game. - /// Called after user friends data was successfully received. - /// Called after the request resulted with an error. - public void GetUserSocialFriends(string token, SocialProvider platform = SocialProvider.None, uint offset = 0, uint limit = 500, bool withXlUid = false, Action onSuccess = null, Action onError = null) - { - var withUidFlag = withXlUid ? "true" : "false"; - var providerUrlAddition = platform != SocialProvider.None ? $"&platform={platform.GetParameter()}" : string.Empty; - var url = string.Format(URL_USER_SOCIAL_FRIENDS, offset, limit, withUidFlag, providerUrlAddition); - - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetUserSocialFriends(Token.Instance, platform, offset, limit, withXlUid, onSuccess, onError))); - } - - public void GetUserSocialFriends(SocialProvider platform = SocialProvider.None, uint offset = 0, uint limit = 500, bool withXlUid = false, Action onSuccess = null, Action onError = null) - { - GetUserSocialFriends(Token.Instance, platform, offset, limit, withXlUid, onSuccess, onError); - } - - /// - /// Begins data processing to update a list of user’s friends from a social provider. - /// Note that there may be a delay in data processing because of the Xsolla Login server or provider server high loads. - /// - /// User authorization token. - /// Name of a social network. Provider must be connected to Login in Publisher Account.
    - /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, or `xbox`.
    - /// If you do not specify it, the call gets friends from all social providers. - /// Called after user friends were successfully received. - /// Called after the request resulted with an error. - public void UpdateUserSocialFriends(string token, SocialProvider platform = SocialProvider.None, Action onSuccess = null, Action onError = null) - { - var providerUrlAddition = platform != SocialProvider.None ? $"?platform={platform.GetParameter()}" : string.Empty; - var url = string.Format(URL_USER_UPDATE_SOCIAL_FRIENDS, providerUrlAddition); - - WebRequestHelper.Instance.PostRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UpdateUserSocialFriends(Token.Instance, platform, onSuccess, onError))); - } - - public void UpdateUserSocialFriends(SocialProvider platform = SocialProvider.None, Action onSuccess = null, Action onError = null) - { - UpdateUserSocialFriends(Token.Instance, platform, onSuccess, onError); - } - - /// - /// Gets a list of users added as friends of the authenticated user. - /// - /// User authorization token. - /// Friends type. - /// Condition for sorting the users. - /// Condition for sorting the list of users. - /// Parameter that is used for API pagination. - /// Maximum number of users that are returned at a time. Default: 20. - /// Called after user friends data was successfully received. - /// Called after the request resulted with an error. - public void GetUserFriends( - string token, - FriendsSearchType type, - FriendsSearchResultsSort sortBy = FriendsSearchResultsSort.ByNickname, - FriendsSearchResultsSortOrder sortOrder = FriendsSearchResultsSortOrder.Asc, - string after = null, - int? limit = null, - Action> onSuccess = null, Action onError = null) - { - var afterParam = (after != null) ? $"&after={after}" : ""; - var limitParam = default(string); - - if (limit.HasValue) - { - if (limit.Value < 1 || limit.Value > 50) - { - Debug.LogError($"Limit must be 1-50. Default limit is 20. Current limit:{limit.Value}"); - return; - } - - limitParam = $"&limit={limit.Value}"; - } - else - { - limit = USER_FRIENDS_DEFAULT_PAGINATION_LIMIT; - limitParam = ""; - } - - var url = string.Format(URL_USER_GET_FRIENDS, type.GetParameter(), sortBy.GetParameter(), sortOrder.GetParameter(), afterParam, limitParam); - StartCoroutine(GetUserFriendsCoroutine(token, url, limit.Value, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetUserFriends(Token.Instance, type, sortBy, sortOrder, after, limit, onSuccess, onError)))); - } - - public void GetUserFriends( - FriendsSearchType type, - FriendsSearchResultsSort sortBy = FriendsSearchResultsSort.ByNickname, - FriendsSearchResultsSortOrder sortOrder = FriendsSearchResultsSortOrder.Asc, - string after = null, - int? limit = null, - Action> onSuccess = null, Action onError = null) - { - GetUserFriends(Token.Instance, type, sortBy, sortOrder, after, limit, onSuccess, onError); - } - - private IEnumerator GetUserFriendsCoroutine(string token, string url, int count, Action> onSuccess, Action onError) - { - var result = new List(); - while (count > 0 && !string.IsNullOrEmpty(url)) - { - var busy = true; - GetUserFriendsInternal(token, url, response => - { - var friends = response.relationships; - if (friends.Count > count) - friends = friends.Take(count).ToList(); - result.AddRange(friends); - count -= friends.Count; - url = response.next_url; - busy = false; - }, error => - { - onError?.Invoke(error); - url = string.Empty; - busy = false; - }); - yield return new WaitWhile(() => busy); - } - onSuccess?.Invoke(result); - } - - private void GetUserFriendsInternal(string token, string url, Action onSuccess = null, Action onError = null) - { - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(token), onSuccess, onError); - } - - /// - /// Modifies relationships with the specified user. - /// - /// User authorization token. - /// Type of the action. - /// Identifier of the user to change relationship with. - /// Called after successful user friends data modification. - /// Called after the request resulted with an error. - public void UpdateUserFriends(string token, FriendAction action, string user, Action onSuccess, Action onError) - { - var request = new UserFriendUpdate - { - action = action.GetParameter(), - user = user - }; - WebRequestHelper.Instance.PostRequest(SdkType.Login, URL_USER_UPDATE_FRIENDS, request, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UpdateUserFriends(Token.Instance, action, user, onSuccess, onError))); - } - - public void UpdateUserFriends(FriendAction action, string user, Action onSuccess, Action onError) - { - UpdateUserFriends(Token.Instance, action, user, onSuccess, onError); - } - } -} diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Friends.cs.meta b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Friends.cs.meta deleted file mode 100644 index b140cd267..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Friends.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: b2360458ee0af6c479f84dff6a246ee4 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Social.cs b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Social.cs deleted file mode 100644 index 9ff6d1d25..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Social.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Core; - -namespace Xsolla.UserAccount -{ - public partial class XsollaUserAccount : MonoSingleton - { - private const string URL_LINK_SOCIAL_NETWORK = - "https://login.xsolla.com/api/users/me/social_providers/{0}/login_url?login_url={1}"; - - private const string URL_GET_LINKED_SOCIAL_NETWORKS = - "https://login.xsolla.com/api/users/me/social_providers"; - - /// - /// Links a social network that can be used for authentication to the current account. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/account-linking/#sdk_account_linking_additional_account). - /// Name of a social network. Provider must be connected to Login in Publisher Account.
    - /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `instagram`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paradox`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, `xbox`, `playstation`. - /// Called after the URL for social authentication was successfully received. - /// Called after the request resulted with an error. - public void LinkSocialProvider(SocialProvider providerName, Action urlCallback, Action onError = null) - { - var redirectUrl = RedirectUtils.GetRedirectUrl(); - var url = string.Format(URL_LINK_SOCIAL_NETWORK, providerName.GetParameter(), redirectUrl); - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(Token.Instance), - onComplete: response => urlCallback?.Invoke(response?.url ?? string.Empty), - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => LinkSocialProvider(providerName, urlCallback, onError))); - } - - /// - /// Returns the list of social networks linked to the user account. - /// - /// Called after the list of linked social networks was successfully received. - /// Called after the request resulted with an error. - public void GetLinkedSocialProviders(Action> onSuccess, Action onError = null) - { - WebRequestHelper.Instance.GetRequest(SdkType.Login, URL_GET_LINKED_SOCIAL_NETWORKS, WebRequestHeader.AuthHeader(Token.Instance), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetLinkedSocialProviders(onSuccess, onError))); - } - } -} diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Social.cs.meta b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Social.cs.meta deleted file mode 100644 index a66350754..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.Social.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 62ec98dff66fbcb4aa9616086d0f718f -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.User.cs b/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.User.cs deleted file mode 100644 index d12e3183d..000000000 --- a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.User.cs +++ /dev/null @@ -1,225 +0,0 @@ -using System; -using System.Collections.Generic; -using Xsolla.Core; - -namespace Xsolla.UserAccount -{ - public partial class XsollaUserAccount : MonoSingleton - { - private const string URL_USER_INFO = "https://login.xsolla.com/api/users/me"; - private const string URL_USER_PHONE = "https://login.xsolla.com/api/users/me/phone"; - private const string URL_USER_PICTURE = "https://login.xsolla.com/api/users/me/picture"; - private const string URL_SEARCH_USER = "https://login.xsolla.com/api/users/search/by_nickname?nickname={0}&offset={1}&limit={2}"; - private const string URL_USER_PUBLIC_INFO = "https://login.xsolla.com/api/users/{0}/public"; - private const string URL_USER_CHECK_AGE = "https://login.xsolla.com/api/users/age/check"; - private const string URL_USER_GET_EMAIL = "https://login.xsolla.com/api/users/me/email"; - - /// - /// Updates the specified user’s information. Changes are made on the user data storage side. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User authorization token. - /// User information. - /// Called after successful user details modification. - /// Called after the request resulted with an error. - public void UpdateUserInfo(string token, UserInfoUpdate info, Action onSuccess, Action onError = null) - { - WebRequestHelper.Instance.PatchRequest(SdkType.Login, URL_USER_INFO, info, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UpdateUserInfo(Token.Instance, info, onSuccess, onError))); - } - - public void UpdateUserInfo(UserInfoUpdate info, Action onSuccess, Action onError = null) - { - UpdateUserInfo(Token.Instance, info, onSuccess, onError); - } - - /// - /// Searches users by the nickname parameter and gets a list of them. Search can be performed instantly when the user starts entering the search parameter. - /// NOTE: User can search only 1 time per second. - /// - /// User authorization token. - /// The search string that may contain: Nickname only, Tag only, Nickname and tag together - /// Number of the elements from which the list is generated. - /// Maximum number of users that are returned at a time. - /// Called after user search is successfully completed. - /// Called after the request resulted with an error. - public void SearchUsers(string token, string nickname, uint offset, uint limit, Action onSuccess, Action onError = null) - { - var url = string.Format(URL_SEARCH_USER, nickname, offset, limit); - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => SearchUsers(Token.Instance, nickname, offset, limit, onSuccess, onError))); - } - - public void SearchUsers(string nickname, uint offset, uint limit, Action onSuccess, Action onError = null) - { - SearchUsers(Token.Instance, nickname, offset, limit, onSuccess, onError); - } - - /// - /// Returns specified user public profile information. - /// - /// User authorization token. - /// User identifier of public profile information to be received. - /// Called after user profile data was successfully received. - /// Called after the request resulted with an error. - public void GetPublicInfo(string token, string userId, Action onSuccess, Action onError = null) - { - var url = string.Format(URL_USER_PUBLIC_INFO, userId); - WebRequestHelper.Instance.GetRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetPublicInfo(Token.Instance, userId, onSuccess, onError))); - } - - public void GetPublicInfo(string userId, Action onSuccess, Action onError = null) - { - GetPublicInfo(Token.Instance, userId, onSuccess, onError); - } - - /// - /// Returns user phone number that is used for two-factor authentication. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User authorization token. - /// Called after user phone number was successfully received. - /// Called after the request resulted with an error. - /// - /// - public void GetUserPhoneNumber(string token, Action onSuccess, Action onError) - { - WebRequestHelper.Instance.GetRequest(SdkType.Login, URL_USER_PHONE, WebRequestHeader.AuthHeader(token), - onComplete: (UserPhoneNumber number) => onSuccess?.Invoke(number.phone_number), - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetUserPhoneNumber(Token.Instance, onSuccess, onError))); - } - - public void GetUserPhoneNumber(Action onSuccess, Action onError) - { - GetUserPhoneNumber(Token.Instance, onSuccess, onError); - } - - /// - /// Changes the user’s phone number that is used for two-factor authentication. Changes are made on the user data storage side (server-side). - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User authorization token. - /// Updated user phone number according to national conventions. - /// Called after user phone number was successfully modified. - /// Called after the request resulted with an error. - /// - /// - public void UpdateUserPhoneNumber(string token, string phoneNumber, Action onSuccess, Action onError) - { - var request = new UserPhoneNumber { phone_number = phoneNumber }; - WebRequestHelper.Instance.PostRequest(SdkType.Login, URL_USER_PHONE, request, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UpdateUserPhoneNumber(Token.Instance, phoneNumber, onSuccess, onError))); - } - - public void UpdateUserPhoneNumber(string phoneNumber, Action onSuccess, Action onError) - { - UpdateUserPhoneNumber(Token.Instance, phoneNumber, onSuccess, onError); - } - - /// - /// Deletes the user’s phone number that is used for two-factor authentication. Changes are made on the user data storage side (server side). - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User authorization token. - /// User phone number for removal. - /// Called after the user phone number was successfully removed. - /// Called after the request resulted with an error. - /// - /// - public void DeleteUserPhoneNumber(string token, string phoneNumber, Action onSuccess, Action onError) - { - var url = $"{URL_USER_PHONE}/{phoneNumber}"; - WebRequestHelper.Instance.DeleteRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => DeleteUserPhoneNumber(Token.Instance, phoneNumber, onSuccess, onError))); - } - - public void DeleteUserPhoneNumber(string phoneNumber, Action onSuccess, Action onError) - { - DeleteUserPhoneNumber(Token.Instance, phoneNumber, onSuccess, onError); - } - - /// - /// Changes the user’s avatar. Changes are made on the user data storage side (server side). - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User authorization token. - /// User profile picture in the binary format. - /// Called after the user profile picture was successfully modified. - /// Called after the request resulted with an error. - /// - public void UploadUserPicture(string token, byte[] pictureData, string boundary, Action onSuccess, Action onError) - { - var headers = new List(){ - WebRequestHeader.AuthHeader(token), - new WebRequestHeader(){ - Name = "Content-type", - Value = $"multipart/form-data; boundary ={boundary}" - } - }; - WebRequestHelper.Instance.PostUploadRequest(SdkType.Login, URL_USER_PICTURE, pictureData, headers, onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => UploadUserPicture(Token.Instance, pictureData, boundary, onSuccess, onError))); - } - - public void UploadUserPicture(byte[] pictureData, string boundary, Action onSuccess, Action onError) - { - UploadUserPicture(Token.Instance, pictureData, boundary, onSuccess, onError); - } - - /// - /// Deletes the user’s avatar. Changes are made on the user data storage side (server side). - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User authorization token. - /// Called after user profile picture was successfully removed. - /// Called after the request resulted with an error. - /// - public void DeleteUserPicture(string token, Action onSuccess, Action onError) - { - var url = URL_USER_PICTURE; - WebRequestHelper.Instance.DeleteRequest(SdkType.Login, url, WebRequestHeader.AuthHeader(token), onSuccess, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => DeleteUserPicture(Token.Instance, onSuccess, onError))); - } - - public void DeleteUserPicture(Action onSuccess, Action onError) - { - DeleteUserPicture(Token.Instance, onSuccess, onError); - } - - /// - /// Checks user age for a particular region. The age requirements depend on the region. Service determines the user location by the IP address. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User's birth date in the `YYYY-MM-DD` format. - /// Called after successful check of the user age. - /// Called after the request resulted with an error. - public void CheckUserAge(string dateOfBirth, Action onSuccess, Action onError) - { - var request = new UserCheckAgeRequest - { - dob = dateOfBirth, - project_id = XsollaSettings.LoginId - }; - WebRequestHelper.Instance.PostRequest(SdkType.Login, URL_USER_CHECK_AGE, request, onSuccess, onError); - } - - /// - /// Returns the user’s email. - /// - /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). - /// User authorization token. - /// Called after user email was successfully received. - /// Called after the request resulted with an error. - public void GetUserEmail(string token, Action onSuccess, Action onError) - { - Action successCallback = response => { onSuccess?.Invoke(response.current_email); }; - WebRequestHelper.Instance.GetRequest(SdkType.Login, URL_USER_GET_EMAIL, WebRequestHeader.AuthHeader(token), successCallback, - onError: error => TokenRefresh.Instance.CheckInvalidToken(error, onError, () => GetUserEmail(Token.Instance, onSuccess, onError))); - } - - public void GetUserEmail(Action onSuccess, Action onError) - { - GetUserEmail(Token.Instance, onSuccess, onError); - } - } -} diff --git a/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResponse.cs b/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResult.cs similarity index 71% rename from Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResponse.cs rename to Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResult.cs index a6b533c4f..5dd65deb5 100644 --- a/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResponse.cs +++ b/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResult.cs @@ -3,8 +3,8 @@ namespace Xsolla.UserAccount { [Serializable] - public class AddUsernameAndEmailResponse + public class AddUsernameAndEmailResult { public bool email_confirmation_required; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResponse.cs.meta b/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResult.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResponse.cs.meta rename to Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailResult.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/UserCheckAgeResult.cs b/Assets/Xsolla/UserAccount/Entities/CheckUserAgeResult.cs similarity index 73% rename from Assets/Xsolla/UserAccount/Entities/UserCheckAgeResult.cs rename to Assets/Xsolla/UserAccount/Entities/CheckUserAgeResult.cs index 7a060daaa..38138dc35 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserCheckAgeResult.cs +++ b/Assets/Xsolla/UserAccount/Entities/CheckUserAgeResult.cs @@ -3,8 +3,8 @@ namespace Xsolla.UserAccount { [Serializable] - public class UserCheckAgeResult + public class CheckUserAgeResult { public bool accepted; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserCheckAgeResult.cs.meta b/Assets/Xsolla/UserAccount/Entities/CheckUserAgeResult.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/UserCheckAgeResult.cs.meta rename to Assets/Xsolla/UserAccount/Entities/CheckUserAgeResult.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/FoundUser.cs b/Assets/Xsolla/UserAccount/Entities/FoundUser.cs deleted file mode 100644 index b9b08621d..000000000 --- a/Assets/Xsolla/UserAccount/Entities/FoundUser.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; - -namespace Xsolla.UserAccount -{ - /// - /// Found user entity. - /// - /// - [Serializable] - public class FoundUser - { - /// - /// The Xsolla Login user ID. You can find it in Publisher Account > your Login project > Users > Username/ID. - /// - public string user_id; - /// - /// User nickname. - /// - public string nickname; - /// - /// Shows whether the user who initiated a search or not. - /// - public bool is_me; - /// - /// Date of user registration in the RFC3339 format. - /// - public string registered; - /// - /// Date of the last user login in the RFC3339 format. - /// - public string last_login; - /// - /// URL of the user avatar. - /// - public string avatar; - /// - /// User tag without "#" at the beginning. Can have no unique value. - /// - public string tag; - } -} diff --git a/Assets/Xsolla/UserAccount/Entities/FoundUser.cs.meta b/Assets/Xsolla/UserAccount/Entities/FoundUser.cs.meta deleted file mode 100644 index e002a7a3a..000000000 --- a/Assets/Xsolla/UserAccount/Entities/FoundUser.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: b310415a58a54358a6921ac1183f113b -timeCreated: 1597124700 \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/FoundUsers.cs b/Assets/Xsolla/UserAccount/Entities/FoundUsers.cs index d6944168b..36b6f8f01 100644 --- a/Assets/Xsolla/UserAccount/Entities/FoundUsers.cs +++ b/Assets/Xsolla/UserAccount/Entities/FoundUsers.cs @@ -6,7 +6,6 @@ namespace Xsolla.UserAccount /// /// Found user entity. /// - /// [Serializable] public class FoundUsers { @@ -17,10 +16,46 @@ public class FoundUsers /// /// Number of the elements from which the list is generated. /// - public uint offset; + public int offset; /// /// Total number of users that you can get. /// - public uint total_count; + public int total_count; } -} + + /// + /// Found user entity. + /// + [Serializable] + public class FoundUser + { + /// + /// The Xsolla Login user ID. You can find it in Publisher Account > your Login project > Users > Username/ID. + /// + public string user_id; + /// + /// User nickname. + /// + public string nickname; + /// + /// Shows whether the user who initiated a search or not. + /// + public bool is_me; + /// + /// Date of user registration in the RFC3339 format. + /// + public string registered; + /// + /// Date of the last user login in the RFC3339 format. + /// + public string last_login; + /// + /// URL of the user avatar. + /// + public string avatar; + /// + /// User tag without "#" at the beginning. Can have no unique value. + /// + public string tag; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/FriendAction.cs b/Assets/Xsolla/UserAccount/Entities/FriendAction.cs new file mode 100644 index 000000000..393537fc9 --- /dev/null +++ b/Assets/Xsolla/UserAccount/Entities/FriendAction.cs @@ -0,0 +1,37 @@ +namespace Xsolla.UserAccount +{ + /// + /// Type of the action. + /// + public enum FriendAction + { + /// + /// To send a friend request + /// + SendInviteRequest, + /// + /// To cancel the friend request that was sent + /// + CancelRequest, + /// + /// To confirm the friend request + /// + AcceptInvite, + /// + /// To cancel the friend request that was received + /// + DenyInvite, + /// + /// To delete the user from the friend list + /// + RemoveFriend, + /// + /// To block the user + /// + BlockFriend, + /// + /// To unblock the user + /// + UnblockFriend + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Enum/FriendAction.cs.meta b/Assets/Xsolla/UserAccount/Entities/FriendAction.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Enum/FriendAction.cs.meta rename to Assets/Xsolla/UserAccount/Entities/FriendAction.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/FriendsSearchOrder.cs b/Assets/Xsolla/UserAccount/Entities/FriendsSearchOrder.cs new file mode 100644 index 000000000..1399e47dd --- /dev/null +++ b/Assets/Xsolla/UserAccount/Entities/FriendsSearchOrder.cs @@ -0,0 +1,11 @@ +namespace Xsolla.UserAccount +{ + /// + /// Condition for sorting users + /// + public enum FriendsSearchOrder + { + Asc, + Desc + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSortOrder.cs.meta b/Assets/Xsolla/UserAccount/Entities/FriendsSearchOrder.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSortOrder.cs.meta rename to Assets/Xsolla/UserAccount/Entities/FriendsSearchOrder.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/FriendsSearchSort.cs b/Assets/Xsolla/UserAccount/Entities/FriendsSearchSort.cs new file mode 100644 index 000000000..98ca3c9b9 --- /dev/null +++ b/Assets/Xsolla/UserAccount/Entities/FriendsSearchSort.cs @@ -0,0 +1,11 @@ +namespace Xsolla.UserAccount +{ + /// + /// Condition for sorting users + /// + public enum FriendsSearchSort + { + ByNickname, + ByUpdated + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSort.cs.meta b/Assets/Xsolla/UserAccount/Entities/FriendsSearchSort.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSort.cs.meta rename to Assets/Xsolla/UserAccount/Entities/FriendsSearchSort.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/FriendsSearchType.cs b/Assets/Xsolla/UserAccount/Entities/FriendsSearchType.cs new file mode 100644 index 000000000..6c7153bdd --- /dev/null +++ b/Assets/Xsolla/UserAccount/Entities/FriendsSearchType.cs @@ -0,0 +1,14 @@ +namespace Xsolla.UserAccount +{ + /// + /// Condition for sorting users + /// + public enum FriendsSearchType + { + Added, + Requested, + Pending, + Blocked, + BlocksMe + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Enum/FriendsSearchType.cs.meta b/Assets/Xsolla/UserAccount/Entities/FriendsSearchType.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Enum/FriendsSearchType.cs.meta rename to Assets/Xsolla/UserAccount/Entities/FriendsSearchType.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/LinkSocialProviderResponse.cs b/Assets/Xsolla/UserAccount/Entities/LinkSocialProviderLink.cs similarity index 67% rename from Assets/Xsolla/UserAccount/Entities/LinkSocialProviderResponse.cs rename to Assets/Xsolla/UserAccount/Entities/LinkSocialProviderLink.cs index f7d13db91..d98a26b9b 100644 --- a/Assets/Xsolla/UserAccount/Entities/LinkSocialProviderResponse.cs +++ b/Assets/Xsolla/UserAccount/Entities/LinkSocialProviderLink.cs @@ -3,8 +3,8 @@ namespace Xsolla.UserAccount { [Serializable] - public class LinkSocialProviderResponse + public class LinkSocialProviderLink { public string url; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/LinkSocialProviderResponse.cs.meta b/Assets/Xsolla/UserAccount/Entities/LinkSocialProviderLink.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/LinkSocialProviderResponse.cs.meta rename to Assets/Xsolla/UserAccount/Entities/LinkSocialProviderLink.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/LinkingCode.cs b/Assets/Xsolla/UserAccount/Entities/LinkingCode.cs index 01a2539ac..06f4176cb 100644 --- a/Assets/Xsolla/UserAccount/Entities/LinkingCode.cs +++ b/Assets/Xsolla/UserAccount/Entities/LinkingCode.cs @@ -7,4 +7,4 @@ public class LinkingCode { public string code; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserAttribute.cs b/Assets/Xsolla/UserAccount/Entities/UserAttribute.cs deleted file mode 100644 index b6145d71c..000000000 --- a/Assets/Xsolla/UserAccount/Entities/UserAttribute.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; - -namespace Xsolla.UserAccount -{ - [Serializable] - public class UserAttribute - { - public UserAttribute() - { - key = string.Empty; - } - - public string key; - public string permission; - public string value; - - public UserAttribute GetCopy() - { - return new UserAttribute {key = this.key, permission = this.permission, value = this.value}; - } - } -} diff --git a/Assets/Xsolla/UserAccount/Entities/UserAttribute.cs.meta b/Assets/Xsolla/UserAccount/Entities/UserAttribute.cs.meta deleted file mode 100644 index d39fcc6b2..000000000 --- a/Assets/Xsolla/UserAccount/Entities/UserAttribute.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 13587b2452ba93545bcf605e1d3eb560 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/UserAccount/Enum/UserAttributeType.cs b/Assets/Xsolla/UserAccount/Entities/UserAttributeType.cs similarity index 76% rename from Assets/Xsolla/UserAccount/Enum/UserAttributeType.cs rename to Assets/Xsolla/UserAccount/Entities/UserAttributeType.cs index bcc6f01d7..1d1016693 100644 --- a/Assets/Xsolla/UserAccount/Enum/UserAttributeType.cs +++ b/Assets/Xsolla/UserAccount/Entities/UserAttributeType.cs @@ -2,6 +2,7 @@ { public enum UserAttributeType { - CUSTOM, READONLY + CUSTOM, + READONLY } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Enum/UserAttributeType.cs.meta b/Assets/Xsolla/UserAccount/Entities/UserAttributeType.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Enum/UserAttributeType.cs.meta rename to Assets/Xsolla/UserAccount/Entities/UserAttributeType.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/UserAttributes.cs b/Assets/Xsolla/UserAccount/Entities/UserAttributes.cs new file mode 100644 index 000000000..d948d427b --- /dev/null +++ b/Assets/Xsolla/UserAccount/Entities/UserAttributes.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; + +namespace Xsolla.UserAccount +{ + [Serializable] + public class UserAttributes + { + public List items; + } + + [Serializable] + public class UserAttribute + { + public string key; + public string permission; + public string value; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserAttributes.cs.meta b/Assets/Xsolla/UserAccount/Entities/UserAttributes.cs.meta new file mode 100644 index 000000000..968c069ae --- /dev/null +++ b/Assets/Xsolla/UserAccount/Entities/UserAttributes.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 72abbb5863c04f12ae30b746bac630b5 +timeCreated: 1683770646 \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserDeviceInfo.cs b/Assets/Xsolla/UserAccount/Entities/UserDevicesInfo.cs similarity index 60% rename from Assets/Xsolla/UserAccount/Entities/UserDeviceInfo.cs rename to Assets/Xsolla/UserAccount/Entities/UserDevicesInfo.cs index c01458bff..6714bca93 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserDeviceInfo.cs +++ b/Assets/Xsolla/UserAccount/Entities/UserDevicesInfo.cs @@ -1,7 +1,14 @@ using System; +using System.Collections.Generic; namespace Xsolla.UserAccount { + [Serializable] + public class UserDevicesInfo + { + public List items; + } + [Serializable] public class UserDeviceInfo { @@ -10,4 +17,4 @@ public class UserDeviceInfo public string device; public string last_used_at; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserDeviceInfo.cs.meta b/Assets/Xsolla/UserAccount/Entities/UserDevicesInfo.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/UserDeviceInfo.cs.meta rename to Assets/Xsolla/UserAccount/Entities/UserDevicesInfo.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/UserEmail.cs b/Assets/Xsolla/UserAccount/Entities/UserEmail.cs index 642e8fd49..8b353b418 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserEmail.cs +++ b/Assets/Xsolla/UserAccount/Entities/UserEmail.cs @@ -7,4 +7,4 @@ public class UserEmail { public string current_email; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserFriendEntity.cs.meta b/Assets/Xsolla/UserAccount/Entities/UserFriendEntity.cs.meta deleted file mode 100644 index d3a40cfb2..000000000 --- a/Assets/Xsolla/UserAccount/Entities/UserFriendEntity.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 6820520d672b4d79968e13c805f1df25 -timeCreated: 1597138855 \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserFriendEntity.cs b/Assets/Xsolla/UserAccount/Entities/UserFriends.cs similarity index 69% rename from Assets/Xsolla/UserAccount/Entities/UserFriendEntity.cs rename to Assets/Xsolla/UserAccount/Entities/UserFriends.cs index 4f1bc8a51..d85566e30 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserFriendEntity.cs +++ b/Assets/Xsolla/UserAccount/Entities/UserFriends.cs @@ -1,14 +1,34 @@ using System; +using System.Collections.Generic; using Xsolla.Core; namespace Xsolla.UserAccount { + /// + /// User's friends entity. + /// + [Serializable] + public class UserFriends + { + /// + /// Friends details. + /// + public List relationships; + /// + /// URL of the request for using this call for the next time. + /// + public string next_url; + /// + /// Value of the after parameter that should be passed while requesting this call for the next time. + /// + public string next_after; + } + /// /// User's friend entity. /// - /// [Serializable] - public class UserFriendEntity + public class UserFriend { /// /// Type of the requested user. Can be: @@ -40,4 +60,4 @@ public bool IsOnline() return !string.IsNullOrEmpty(user.presence) && user.presence.Equals("online"); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserFriendsEntity.cs.meta b/Assets/Xsolla/UserAccount/Entities/UserFriends.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/UserFriendsEntity.cs.meta rename to Assets/Xsolla/UserAccount/Entities/UserFriends.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/UserFriendsEntity.cs b/Assets/Xsolla/UserAccount/Entities/UserFriendsEntity.cs deleted file mode 100644 index 17610d1b2..000000000 --- a/Assets/Xsolla/UserAccount/Entities/UserFriendsEntity.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace Xsolla.UserAccount -{ - /// - /// User's friends entity. - /// - /// - [Serializable] - public class UserFriendsEntity - { - /// - /// Friends details. - /// - public List relationships; - /// - /// URL of the request for using this call for the next time. - /// - public string next_url; - /// - /// Value of the after parameter that should be passed while requesting this call for the next time. - /// - public string next_after; - } -} diff --git a/Assets/Xsolla/Core/Entities/UserInfoUpdate.cs b/Assets/Xsolla/UserAccount/Entities/UserInfoUpdate.cs similarity index 86% rename from Assets/Xsolla/Core/Entities/UserInfoUpdate.cs rename to Assets/Xsolla/UserAccount/Entities/UserInfoUpdate.cs index 88dbf84f1..efb55debc 100644 --- a/Assets/Xsolla/Core/Entities/UserInfoUpdate.cs +++ b/Assets/Xsolla/UserAccount/Entities/UserInfoUpdate.cs @@ -1,6 +1,6 @@ using System; -namespace Xsolla.Core +namespace Xsolla.UserAccount { [Serializable] public class UserInfoUpdate @@ -11,4 +11,4 @@ public class UserInfoUpdate public string last_name; public string nickname; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/Core/Entities/UserInfoUpdate.cs.meta b/Assets/Xsolla/UserAccount/Entities/UserInfoUpdate.cs.meta similarity index 100% rename from Assets/Xsolla/Core/Entities/UserInfoUpdate.cs.meta rename to Assets/Xsolla/UserAccount/Entities/UserInfoUpdate.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/UserPhoneNumber.cs b/Assets/Xsolla/UserAccount/Entities/UserPhoneNumber.cs index d5ef4a43e..15ad637cb 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserPhoneNumber.cs +++ b/Assets/Xsolla/UserAccount/Entities/UserPhoneNumber.cs @@ -8,8 +8,7 @@ public class UserPhoneNumber /// /// User phone number. /// - /// - /// + /// National conventions for writing telephone numbers public string phone_number; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserPublicInfo.cs b/Assets/Xsolla/UserAccount/Entities/UserPublicInfo.cs index 657abb8f1..55bf8ac74 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserPublicInfo.cs +++ b/Assets/Xsolla/UserAccount/Entities/UserPublicInfo.cs @@ -5,7 +5,6 @@ namespace Xsolla.UserAccount /// /// Public user info entity. /// - /// [Serializable] public class UserPublicInfo { @@ -34,4 +33,4 @@ public class UserPublicInfo /// public string tag; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserSocialFriend.cs b/Assets/Xsolla/UserAccount/Entities/UserSocialFriend.cs deleted file mode 100644 index f56e13dca..000000000 --- a/Assets/Xsolla/UserAccount/Entities/UserSocialFriend.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System; -using JetBrains.Annotations; - -namespace Xsolla.UserAccount -{ - /// - /// User's social friend entity. - /// - /// - [Serializable] - public class UserSocialFriend - { - /// - /// Friend’s name from a social provider. - /// - public string name; - /// - /// Name of a social provider. - /// - public string platform; - /// - /// User ID from a social provider. - /// - public string user_id; - /// - /// Friend's avatar from a social provider. - /// - [CanBeNull] public string avatar; - /// - /// User tag without "#" at the beginning. Can have no unique value and can be used in the Search users by nickname call. - /// - [CanBeNull] public string tag; - /// - /// The Xsolla Login user ID. You can find it in Publisher Account > your Login project > Users > Username/ID. - /// - [CanBeNull] public string xl_uid; - } -} diff --git a/Assets/Xsolla/UserAccount/Entities/UserSocialFriend.cs.meta b/Assets/Xsolla/UserAccount/Entities/UserSocialFriend.cs.meta deleted file mode 100644 index 0171f73e1..000000000 --- a/Assets/Xsolla/UserAccount/Entities/UserSocialFriend.cs.meta +++ /dev/null @@ -1,3 +0,0 @@ -fileFormatVersion: 2 -guid: 59ad10f8dd8b4580b542bab2862eac4a -timeCreated: 1597123587 \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserSocialFriends.cs b/Assets/Xsolla/UserAccount/Entities/UserSocialFriends.cs index 2bf01b8ee..44ca85639 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserSocialFriends.cs +++ b/Assets/Xsolla/UserAccount/Entities/UserSocialFriends.cs @@ -6,33 +6,74 @@ namespace Xsolla.UserAccount /// /// User's social friends entity. /// - /// [Serializable] public class UserSocialFriends { /// /// Maximum number of friends that are returned at a time. /// - public uint limit; + public int limit; + /// /// Number of the elements from which the list is generated. /// - public uint offset; + public int offset; + /// /// Total number of friends that you can get. /// - public uint total_count; + public int total_count; + /// /// List of data from social friends accounts. /// public List data; + /// /// Name of a social provider. /// public string platform; + /// /// Shows whether the social friends are from your game. /// public bool with_xl_uid; } -} + + /// + /// User's social friend entity. + /// + [Serializable] + public class UserSocialFriend + { + /// + /// Friend’s name from a social provider. + /// + public string name; + + /// + /// Name of a social provider. + /// + public string platform; + + /// + /// User ID from a social provider. + /// + public string user_id; + + /// + /// Friend's avatar from a social provider. + /// + public string avatar; + + /// + /// User tag without "#" at the beginning. Can have no unique value and can be used in the Search users by nickname call. + /// + public string tag; + + /// + /// The Xsolla Login user ID. You can find it in Publisher Account > your Login project > Users > Username/ID. + /// + public string xl_uid; + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Enum.meta b/Assets/Xsolla/UserAccount/Enum.meta deleted file mode 100644 index 5e4cfbd3c..000000000 --- a/Assets/Xsolla/UserAccount/Enum.meta +++ /dev/null @@ -1,8 +0,0 @@ -fileFormatVersion: 2 -guid: f5754f30c5f77984f9798eb0a9f33e0b -folderAsset: yes -DefaultImporter: - externalObjects: {} - userData: - assetBundleName: - assetBundleVariant: diff --git a/Assets/Xsolla/UserAccount/Enum/FriendAction.cs b/Assets/Xsolla/UserAccount/Enum/FriendAction.cs deleted file mode 100644 index 5725842d8..000000000 --- a/Assets/Xsolla/UserAccount/Enum/FriendAction.cs +++ /dev/null @@ -1,56 +0,0 @@ -namespace Xsolla.UserAccount -{ - /// - /// Type of the action. - /// - /// - public enum FriendAction - { - /// - /// To send a friend request - /// - SendInviteRequest, - /// - /// To cancel the friend request that was sent - /// - CancelRequest, - /// - /// To confirm the friend request - /// - AcceptInvite, - /// - /// To cancel the friend request that was received - /// - DenyInvite, - /// - /// To delete the user from the friend list - /// - RemoveFriend, - /// - /// To block the user - /// - BlockFriend, - /// - /// To unblock the user - /// - UnblockFriend - } - - public static class FriendActionConverter - { - public static string GetParameter(this FriendAction provider) - { - switch (provider) - { - case FriendAction.SendInviteRequest: return "friend_request_add"; - case FriendAction.CancelRequest: return "friend_request_cancel"; - case FriendAction.AcceptInvite: return "friend_request_approve"; - case FriendAction.DenyInvite: return "friend_request_deny"; - case FriendAction.RemoveFriend: return "friend_remove"; - case FriendAction.BlockFriend: return "block"; - case FriendAction.UnblockFriend: return "unblock"; - default: return string.Empty; - } - } - } -} diff --git a/Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSort.cs b/Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSort.cs deleted file mode 100644 index 2b00280f7..000000000 --- a/Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSort.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Xsolla.UserAccount -{ - /// - /// Condition for sorting users - /// - /// - public enum FriendsSearchResultsSort - { - ByNickname, - ByUpdated - } - - public static class FriendsSearchResultsSortConverter - { - public static string GetParameter(this FriendsSearchResultsSort provider) - { - switch (provider) - { - case FriendsSearchResultsSort.ByNickname: return "by_nickname"; - case FriendsSearchResultsSort.ByUpdated: return "by_updated"; - default: return string.Empty; - } - } - } -} diff --git a/Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSortOrder.cs b/Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSortOrder.cs deleted file mode 100644 index 52f42019e..000000000 --- a/Assets/Xsolla/UserAccount/Enum/FriendsSearchResultSortOrder.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace Xsolla.UserAccount -{ - /// - /// Condition for sorting users - /// - /// - public enum FriendsSearchResultsSortOrder - { - Asc, - Desc - } - - public static class FriendsSearchResultsSortOrderConverter - { - public static string GetParameter(this FriendsSearchResultsSortOrder provider) - { - switch (provider) - { - case FriendsSearchResultsSortOrder.Asc: return "asc"; - case FriendsSearchResultsSortOrder.Desc: return "desc"; - default: return string.Empty; - } - } - } -} diff --git a/Assets/Xsolla/UserAccount/Enum/FriendsSearchType.cs b/Assets/Xsolla/UserAccount/Enum/FriendsSearchType.cs deleted file mode 100644 index 4cf11ff67..000000000 --- a/Assets/Xsolla/UserAccount/Enum/FriendsSearchType.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace Xsolla.UserAccount -{ - /// - /// Condition for sorting users - /// - /// - public enum FriendsSearchType - { - Added, - Requested, - Pending, - Blocked, - BlocksMe - } - - public static class FriendsSearchTypeConverter - { - public static string GetParameter(this FriendsSearchType provider) - { - switch (provider) - { - case FriendsSearchType.Added: return "friends"; - case FriendsSearchType.Requested: return "friend_requested"; - case FriendsSearchType.Pending: return "friend_requested_by"; - case FriendsSearchType.Blocked: return "blocked"; - case FriendsSearchType.BlocksMe: return "blocked_by"; - default: return string.Empty; - } - } - } -} diff --git a/Assets/Xsolla/UserAccount/Internal.meta b/Assets/Xsolla/UserAccount/Internal.meta new file mode 100644 index 000000000..8aaace7f9 --- /dev/null +++ b/Assets/Xsolla/UserAccount/Internal.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: eb8a5d940d2544fc968481bbdac908ce +timeCreated: 1682699105 \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailRequest.cs b/Assets/Xsolla/UserAccount/Internal/AddUsernameAndEmailRequest.cs similarity index 77% rename from Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailRequest.cs rename to Assets/Xsolla/UserAccount/Internal/AddUsernameAndEmailRequest.cs index 5a2400dc3..c85162df9 100644 --- a/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailRequest.cs +++ b/Assets/Xsolla/UserAccount/Internal/AddUsernameAndEmailRequest.cs @@ -1,16 +1,13 @@ -using Newtonsoft.Json; using System; namespace Xsolla.UserAccount { [Serializable] - public class AddUsernameAndEmailRequest + internal class AddUsernameAndEmailRequest { public string username; public string password; public string email; - - [JsonProperty(NullValueHandling = NullValueHandling.Ignore)] public int? promo_email_agreement; public AddUsernameAndEmailRequest(string username, string password, string email, int? promo_email_agreement) @@ -21,4 +18,4 @@ public AddUsernameAndEmailRequest(string username, string password, string email this.promo_email_agreement = promo_email_agreement; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailRequest.cs.meta b/Assets/Xsolla/UserAccount/Internal/AddUsernameAndEmailRequest.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/AddUsernameAndEmailRequest.cs.meta rename to Assets/Xsolla/UserAccount/Internal/AddUsernameAndEmailRequest.cs.meta diff --git a/Assets/Xsolla/UserAccount/Internal/DataClassExtensions.cs b/Assets/Xsolla/UserAccount/Internal/DataClassExtensions.cs new file mode 100644 index 000000000..e59e226bf --- /dev/null +++ b/Assets/Xsolla/UserAccount/Internal/DataClassExtensions.cs @@ -0,0 +1,53 @@ +namespace Xsolla.UserAccount +{ + internal static class DataClassExtensions + { + public static string ToApiParameter(this FriendsSearchType provider) + { + switch (provider) + { + case FriendsSearchType.Added: return "friends"; + case FriendsSearchType.Requested: return "friend_requested"; + case FriendsSearchType.Pending: return "friend_requested_by"; + case FriendsSearchType.Blocked: return "blocked"; + case FriendsSearchType.BlocksMe: return "blocked_by"; + default: return string.Empty; + } + } + + public static string ToApiParameter(this FriendAction provider) + { + switch (provider) + { + case FriendAction.SendInviteRequest: return "friend_request_add"; + case FriendAction.CancelRequest: return "friend_request_cancel"; + case FriendAction.AcceptInvite: return "friend_request_approve"; + case FriendAction.DenyInvite: return "friend_request_deny"; + case FriendAction.RemoveFriend: return "friend_remove"; + case FriendAction.BlockFriend: return "block"; + case FriendAction.UnblockFriend: return "unblock"; + default: return string.Empty; + } + } + + public static string ToApiParameter(this FriendsSearchSort provider) + { + switch (provider) + { + case FriendsSearchSort.ByNickname: return "by_nickname"; + case FriendsSearchSort.ByUpdated: return "by_updated"; + default: return string.Empty; + } + } + + public static string ToApiParameter(this FriendsSearchOrder provider) + { + switch (provider) + { + case FriendsSearchOrder.Asc: return "asc"; + case FriendsSearchOrder.Desc: return "desc"; + default: return string.Empty; + } + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Internal/DataClassExtensions.cs.meta b/Assets/Xsolla/UserAccount/Internal/DataClassExtensions.cs.meta new file mode 100644 index 000000000..ab2ab9fc6 --- /dev/null +++ b/Assets/Xsolla/UserAccount/Internal/DataClassExtensions.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: ad04857b21bb4d608658d276fa0ed414 +timeCreated: 1683685297 \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/GetAttributesJson.cs b/Assets/Xsolla/UserAccount/Internal/GetAttributesRequest.cs similarity index 76% rename from Assets/Xsolla/UserAccount/Entities/GetAttributesJson.cs rename to Assets/Xsolla/UserAccount/Internal/GetAttributesRequest.cs index ff7f09bc6..37b6e31f1 100644 --- a/Assets/Xsolla/UserAccount/Entities/GetAttributesJson.cs +++ b/Assets/Xsolla/UserAccount/Internal/GetAttributesRequest.cs @@ -5,17 +5,17 @@ namespace Xsolla.UserAccount { [Serializable] - public class GetAttributesJson + internal class GetAttributesRequest { public List keys; public int publisher_project_id; public string user_id; - public GetAttributesJson(List attributeKeys, string projectId, string userId) + public GetAttributesRequest(List attributeKeys, string projectId, string userId) { keys = attributeKeys != null && attributeKeys.Any() ? attributeKeys : new List(); publisher_project_id = Convert.ToInt32(projectId); user_id = !string.IsNullOrEmpty(userId) ? userId : null; } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/GetAttributesJson.cs.meta b/Assets/Xsolla/UserAccount/Internal/GetAttributesRequest.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/GetAttributesJson.cs.meta rename to Assets/Xsolla/UserAccount/Internal/GetAttributesRequest.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/LinkDeviceRequest.cs b/Assets/Xsolla/UserAccount/Internal/LinkDeviceRequest.cs similarity index 54% rename from Assets/Xsolla/UserAccount/Entities/LinkDeviceRequest.cs rename to Assets/Xsolla/UserAccount/Internal/LinkDeviceRequest.cs index e1d0bdd59..156c6ff42 100644 --- a/Assets/Xsolla/UserAccount/Entities/LinkDeviceRequest.cs +++ b/Assets/Xsolla/UserAccount/Internal/LinkDeviceRequest.cs @@ -7,11 +7,5 @@ public class LinkDeviceRequest { public string device; public string device_id; - - public LinkDeviceRequest(string device, string device_id) - { - this.device = device; - this.device_id = device_id; - } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/LinkDeviceRequest.cs.meta b/Assets/Xsolla/UserAccount/Internal/LinkDeviceRequest.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/LinkDeviceRequest.cs.meta rename to Assets/Xsolla/UserAccount/Internal/LinkDeviceRequest.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/ModifyAttributesJson.cs b/Assets/Xsolla/UserAccount/Internal/ModifyAttributesRequest.cs similarity index 76% rename from Assets/Xsolla/UserAccount/Entities/ModifyAttributesJson.cs rename to Assets/Xsolla/UserAccount/Internal/ModifyAttributesRequest.cs index 4ebc1e4a9..ec67cb154 100644 --- a/Assets/Xsolla/UserAccount/Entities/ModifyAttributesJson.cs +++ b/Assets/Xsolla/UserAccount/Internal/ModifyAttributesRequest.cs @@ -5,17 +5,17 @@ namespace Xsolla.UserAccount { [Serializable] - public class ModifyAttributesJson + internal class ModifyAttributesRequest { public List attributes; public int publisher_project_id; public List removing_keys; - public ModifyAttributesJson(List attributes, string projectId, List removingKeys) + public ModifyAttributesRequest(List attributes, string projectId, List removingKeys) { this.attributes = attributes != null && attributes.Any() ? attributes : new List(); publisher_project_id = Convert.ToInt32(projectId); removing_keys = removingKeys != null && removingKeys.Any() ? removingKeys : new List(); } } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/ModifyAttributesJson.cs.meta b/Assets/Xsolla/UserAccount/Internal/ModifyAttributesRequest.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/ModifyAttributesJson.cs.meta rename to Assets/Xsolla/UserAccount/Internal/ModifyAttributesRequest.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/UserCheckAgeRequest.cs b/Assets/Xsolla/UserAccount/Internal/UserCheckAgeRequest.cs similarity index 76% rename from Assets/Xsolla/UserAccount/Entities/UserCheckAgeRequest.cs rename to Assets/Xsolla/UserAccount/Internal/UserCheckAgeRequest.cs index 962935d71..8ab2c146e 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserCheckAgeRequest.cs +++ b/Assets/Xsolla/UserAccount/Internal/UserCheckAgeRequest.cs @@ -3,9 +3,9 @@ namespace Xsolla.UserAccount { [Serializable] - public class UserCheckAgeRequest + internal class UserCheckAgeRequest { public string dob; public string project_id; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserCheckAgeRequest.cs.meta b/Assets/Xsolla/UserAccount/Internal/UserCheckAgeRequest.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/UserCheckAgeRequest.cs.meta rename to Assets/Xsolla/UserAccount/Internal/UserCheckAgeRequest.cs.meta diff --git a/Assets/Xsolla/UserAccount/Entities/UserFriendUpdate.cs b/Assets/Xsolla/UserAccount/Internal/UserFriendUpdateRequest.cs similarity index 70% rename from Assets/Xsolla/UserAccount/Entities/UserFriendUpdate.cs rename to Assets/Xsolla/UserAccount/Internal/UserFriendUpdateRequest.cs index 4ab3eab0d..67530f066 100644 --- a/Assets/Xsolla/UserAccount/Entities/UserFriendUpdate.cs +++ b/Assets/Xsolla/UserAccount/Internal/UserFriendUpdateRequest.cs @@ -5,9 +5,8 @@ namespace Xsolla.UserAccount /// /// User's friend entity. /// - /// [Serializable] - public class UserFriendUpdate + internal class UserFriendUpdateRequest { /// /// Type of the action. @@ -18,4 +17,4 @@ public class UserFriendUpdate /// public string user; } -} +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Entities/UserFriendUpdate.cs.meta b/Assets/Xsolla/UserAccount/Internal/UserFriendUpdateRequest.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Entities/UserFriendUpdate.cs.meta rename to Assets/Xsolla/UserAccount/Internal/UserFriendUpdateRequest.cs.meta diff --git a/Assets/Xsolla/UserAccount/XsollaUserAccount.cs b/Assets/Xsolla/UserAccount/XsollaUserAccount.cs new file mode 100644 index 000000000..50fd803c7 --- /dev/null +++ b/Assets/Xsolla/UserAccount/XsollaUserAccount.cs @@ -0,0 +1,707 @@ +using System; +using System.Collections.Generic; +using Xsolla.Core; + +namespace Xsolla.UserAccount +{ + public static class XsollaUserAccount + { + private static string BaseUrl => "https://login.xsolla.com/api"; + private static string StoreProjectId => XsollaSettings.StoreProjectId; + + /// + /// Updates the specified user’s information. Changes are made on the user data storage side. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// User information. + /// Called after successful user details modification. + /// Called after the request resulted with an error. + public static void UpdateUserInfo(UserInfoUpdate info, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me"; + + WebRequestHelper.Instance.PatchRequest( + SdkType.Login, + url, + info, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => UpdateUserInfo(info, onSuccess, onError))); + } + + /// + /// Searches users by the nickname parameter and gets a list of them. Search can be performed instantly when the user starts entering the search parameter. + /// NOTE: User can search only 1 time per second. + /// + /// The search string that may contain: Nickname only, Tag only, Nickname and tag together + /// Number of the elements from which the list is generated. + /// Maximum number of users that are returned at a time. + /// Called after user search is successfully completed. + /// Called after the request resulted with an error. + public static void SearchUsers(string nickname, int offset, int limit, Action onSuccess, Action onError) + { + var url = new UrlBuilder($"{BaseUrl}/users/search/by_nickname") + .AddParam("nickname", nickname) + .AddLimit(limit) + .AddOffset(offset) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => SearchUsers(nickname, offset, limit, onSuccess, onError))); + } + + /// + /// Returns specified user public profile information. + /// + /// User identifier of public profile information to be received. + /// Called after user profile data was successfully received. + /// Called after the request resulted with an error. + public static void GetPublicInfo(string userId, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/{userId}/public"; + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetPublicInfo(userId, onSuccess, onError))); + } + + /// + /// Returns user phone number that is used for two-factor authentication. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// Called after user phone number was successfully received. + /// Called after the request resulted with an error. + /// + /// + public static void GetUserPhoneNumber(Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/phone"; + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetUserPhoneNumber(onSuccess, onError))); + } + + /// + /// Changes the user’s phone number that is used for two-factor authentication. Changes are made on the user data storage side (server-side). + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// Updated user phone number according to national conventions. + /// Called after user phone number was successfully modified. + /// Called after the request resulted with an error. + /// + /// + public static void UpdateUserPhoneNumber(string phoneNumber, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/phone"; + + var requestData = new UserPhoneNumber { + phone_number = phoneNumber + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => UpdateUserPhoneNumber(phoneNumber, onSuccess, onError))); + } + + /// + /// Deletes the user’s phone number that is used for two-factor authentication. Changes are made on the user data storage side (server side). + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// User phone number for removal. + /// Called after the user phone number was successfully removed. + /// Called after the request resulted with an error. + /// + /// + public static void DeleteUserPhoneNumber(string phoneNumber, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/phone/{phoneNumber}"; + + WebRequestHelper.Instance.DeleteRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => DeleteUserPhoneNumber(phoneNumber, onSuccess, onError))); + } + + /// + /// Changes the user’s avatar. Changes are made on the user data storage side (server side). + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// User profile picture in the binary format. + /// + /// Called after the user profile picture was successfully modified. + /// Called after the request resulted with an error. + /// + public static void UploadUserPicture(byte[] pictureData, string boundary, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/picture"; + + var headers = new List { + WebRequestHeader.AuthHeader(), + WebRequestHeader.FormDataContentTypeHeader(boundary) + }; + + WebRequestHelper.Instance.PostUploadRequest( + SdkType.Login, + url, + pictureData, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => UploadUserPicture(pictureData, boundary, onSuccess, onError))); + } + + /// + /// Deletes the user’s avatar. Changes are made on the user data storage side (server side). + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// Called after user profile picture was successfully removed. + /// Called after the request resulted with an error. + /// + public static void DeleteUserPicture(Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/picture"; + + WebRequestHelper.Instance.DeleteRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => DeleteUserPicture(onSuccess, onError))); + } + + /// + /// Checks user age for a particular region. The age requirements depend on the region. Service determines the user location by the IP address. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// User's birth date in the `YYYY-MM-DD` format. + /// Called after successful check of the user age. + /// Called after the request resulted with an error. + public static void CheckUserAge(string dateOfBirth, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/age/check"; + + var request = new UserCheckAgeRequest { + dob = dateOfBirth, + project_id = XsollaSettings.LoginId + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + request, + onSuccess, + onError); + } + + /// + /// Returns the user’s email. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-account/). + /// Called after user email was successfully received. + /// Called after the request resulted with an error. + public static void GetUserEmail(Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/email"; + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetUserEmail(onSuccess, onError))); + } + + /// + /// Creates the code for linking the platform account to the existing main account when the user logs in to the game via a gaming console. + /// The call is used with [Link accounts by code](https://developers.xsolla.com/login-api/linking-account/linking/link-accounts-by-code/) request. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/account-linking/). + /// Called after successful linking code creation. + /// Called after the request resulted with an error. + /// + /// + public static void RequestLinkingCode(Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/account/code"; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => RequestLinkingCode(onSuccess, onError))); + } + + /// + /// This method is used for authenticating users in Xsolla Login, + /// who play on the consoles and other platforms + /// where Xsolla Login isn't used. You must implement it + /// on the your server side. + /// Integration flow on the server side: + /// + /// + /// Generate server JWT + /// + /// + /// + /// Connect OAuth 2.0 server client + /// Follow the [instructions](https://developers.xsolla.com/doc/login/security/connecting-oauth2/#login_features_connecting_oauth2_connecting_client) to connect the client and cope copy the Client ID and Secret key. + /// + /// + /// + /// Implement method: + /// + /// + /// with `application/x-www-form-urlencoded` payload parameters: + /// + /// + /// client_id=YOUR_CLIENT_ID + /// + /// + /// client_secret=YOUR_CLIENT_SECRET + /// + /// + /// grant_type=client_credentials + /// + /// + /// + /// + /// + /// + /// + /// + /// Implement APIs for account linking + /// + /// + /// with: + /// + /// + /// Headers + /// + /// `Content-Type: application/json` and `X-SERVER-AUTHORIZATION: YourGeneratedJwt` + /// + /// + /// + /// Body + /// [See documentation](https://developers.xsolla.com/api/login/operation/link-accounts-by-code/). + /// + /// + /// + /// + /// + /// + /// Social platform (XBox, PS4, etc) user unique identifier. + /// Platform name (XBox, PS4, etc). + /// Code, taken from unified account. + /// Success operation callback. + /// Called after the request resulted with an error. + /// + /// + public static void LinkConsoleAccount(string userId, string platform, string confirmationCode, Action onSuccess, Action onError) + { + var url = new UrlBuilder("https://livedemo.xsolla.com/sdk/sdk-shadow-account/link") + .AddParam("user_id", userId) + .AddParam("code", confirmationCode) + .AddPlatform(platform) + .Build(); + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + onComplete: onSuccess, + onError: onError); + } + + /// + /// Returns a list of particular user’s attributes with their values and descriptions. Returns only user-editable attributes. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-attributes/). + /// Type of attributes to get. Can be `Readonly` or `Custom`. + /// List of attributes’ keys which you want to get. If not specified, the method returns all user’s attributes. + /// Identifier of a user whose public attributes should be requested. If not specified, the method returns attributes for the current user. + /// Called after user attributes were successfully received. + /// Called after the request resulted with an error. + /// + /// + public static void GetUserAttributes(UserAttributeType attributeType, List keys, string userId, Action onSuccess, Action onError) + { + string url; + switch (attributeType) + { + case UserAttributeType.CUSTOM: + url = $"{BaseUrl}/attributes/users/me/get"; + break; + case UserAttributeType.READONLY: + url = $"{BaseUrl}/attributes/users/me/get_read_only"; + break; + default: + throw new ArgumentOutOfRangeException(nameof(attributeType), attributeType, null); + } + + var headers = new List { + WebRequestHeader.AuthHeader(), + WebRequestHeader.JsonContentTypeHeader() + }; + + var getAttributesRequestBody = new GetAttributesRequest(keys, StoreProjectId, userId); + + WebRequestHelper.Instance.PostRequest, GetAttributesRequest>( + SdkType.Login, + url, + getAttributesRequestBody, + headers, + response => + { + onSuccess?.Invoke(new UserAttributes { + items = response + }); + }, + error => TokenAutoRefresher.Check(error, onError, () => GetUserAttributes(attributeType, keys, userId, onSuccess, onError))); + } + + /// + /// Updates the values of user attributes with the specified IDs. The method can be used to create or remove attributes. Changes are made on the user data storage side (server side). + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-attributes/). + /// List of attributes of the specified game. To add attribute which does not exist, set this attribute to the `key` parameter. To update `value` of the attribute, specify its `key` parameter and set the new `value`. You can change several attributes at a time. + /// Called after successful user attributes modification on the server side. + /// Called after the request resulted with an error. + /// + /// + public static void UpdateUserAttributes(List attributes, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/attributes/users/me/update"; + + var headers = new List { + WebRequestHeader.AuthHeader(), + WebRequestHeader.JsonContentTypeHeader() + }; + + var requestData = new ModifyAttributesRequest(attributes, StoreProjectId, null); + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => UpdateUserAttributes(attributes, onSuccess, onError))); + } + + /// + /// Removes user attributes with the specified IDs. Changes are made on the user data storage side (server side). + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/user-attributes/). + /// List of attribute keys for removal. + /// Called after successful user attributes removal on the server side. + /// Called after the request resulted with an error. + /// + /// + public static void RemoveUserAttributes(List removingKeys, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/attributes/users/me/update"; + + var headers = new List { + WebRequestHeader.AuthHeader(), + WebRequestHeader.JsonContentTypeHeader() + }; + + var requestData = new ModifyAttributesRequest(null, StoreProjectId, removingKeys); + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestData, + headers, + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => RemoveUserAttributes(removingKeys, onSuccess, onError))); + } + + /// + /// Adds a username, email address, and password, that can be used for authentication, to the current account. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). + /// Username. + /// User password. + /// User email. + /// Called after successful email and password linking. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + /// Whether the user gave consent to receive the newsletters. + public static void AddUsernameEmailAuthToAccount(string username, string password, string email, Action onSuccess, Action onError, string redirectUri = null, int? promoEmailAgreement = null) + { + var url = new UrlBuilder($"{BaseUrl}/users/me/link_email_password") + .AddParam("login_url", RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .Build(); + + var requestBody = new AddUsernameAndEmailRequest(username, password, email, promoEmailAgreement); + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestBody, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => AddUsernameEmailAuthToAccount(username, password, email, onSuccess, onError, redirectUri, promoEmailAgreement)), + ErrorGroup.RegistrationErrors); + } + + /// + /// Gets a list of user's devices. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). + /// Called after users devices data was successfully received. + /// Called after the request resulted with an error. + public static void GetUserDevices(Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/devices"; + + WebRequestHelper.Instance.GetRequest>( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + response => + { + onSuccess?.Invoke(new UserDevicesInfo { + items = response + }); + }, + error => TokenAutoRefresher.Check(error, onError, () => GetUserDevices(onSuccess, onError))); + } + + /// + /// Links the specified device to the current user account. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). + /// Type of the device. Can be `android` or `ios`. + /// Manufacturer and model name of the device. + /// Platform specific unique device ID. + /// For Android, it is an [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID) constant.
    + /// For iOS, it is an [identifierForVendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc) property.
    + /// + /// Called after successful linking of the device. + /// Called after the request resulted with an error. + public static void LinkDeviceToAccount(DeviceType deviceType, string device, string deviceId, Action onSuccess, Action onError) + { + var deviceTypeValue = deviceType.ToString().ToLower(); + var url = $"{BaseUrl}/users/me/devices/{deviceTypeValue}"; + var requestBody = new LinkDeviceRequest { + device = device, + device_id = deviceId + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + requestBody, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => LinkDeviceToAccount(deviceType, device, deviceId, onSuccess, onError))); + } + + /// + /// Unlinks the specified device from the current user account. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/authentication/auth-via-device-id/). + /// Platform specific unique device ID.
    + /// For Android, it is an [ANDROID_ID](https://developer.android.com/reference/android/provider/Settings.Secure#ANDROID_ID) constant.
    + /// For iOS, it is an [identifierForVendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor?language=objc) property. + /// Called after successful unlinking of the device. + /// Called after the request resulted with an error. + public static void UnlinkDeviceFromAccount(int deviceId, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/devices/{deviceId}"; + + WebRequestHelper.Instance.DeleteRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => UnlinkDeviceFromAccount(deviceId, onSuccess, onError))); + } + + /// + /// Gets a list of user’s friends from a social provider. + /// + /// Called after user friends data was successfully received. + /// Called after the request resulted with an error. + /// Name of a social network. Provider must be connected to Login in Publisher Account.
    + /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, or `xbox`. + /// Number of the elements from which the list is generated. + /// Maximum number of friends that are returned at a time. + /// Shows whether the social friends are from your game. + public static void GetUserSocialFriends(Action onSuccess, Action onError, SocialProvider platform = SocialProvider.None, int offset = 0, int limit = 500, bool withXlUid = false) + { + var withXlUidParam = withXlUid ? "true" : "false"; + var platformValue = platform != SocialProvider.None + ? platform.ToApiParameter() + : null; + + var url = new UrlBuilder($"{BaseUrl}/users/me/social_friends") + .AddParam("offset", offset) + .AddParam("limit", limit) + .AddParam("with_xl_uid", withXlUidParam) + .AddPlatform(platformValue) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetUserSocialFriends(onSuccess, onError, platform, offset, limit, withXlUid))); + } + + /// + /// Begins data processing to update a list of user’s friends from a social provider. + /// Note that there may be a delay in data processing because of the Xsolla Login server or provider server high loads. + /// + /// Called after user friends were successfully received. + /// Called after the request resulted with an error. + /// Name of a social network. Provider must be connected to Login in Publisher Account.
    + /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, or `xbox`.
    + /// If you do not specify it, the call gets friends from all social providers. + public static void UpdateUserSocialFriends(Action onSuccess, Action onError, SocialProvider platform = SocialProvider.None) + { + var platformParam = platform != SocialProvider.None + ? platform.ToApiParameter() + : null; + + var url = new UrlBuilder($"{BaseUrl}/users/me/social_friends/update") + .AddPlatform(platformParam) + .Build(); + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => UpdateUserSocialFriends(onSuccess, onError, platform))); + } + + /// + /// Gets a list of users added as friends of the authenticated user. + /// + /// Friends type. + /// Called after user friends data was successfully received. + /// Called after the request resulted with an error. + /// Condition for sorting the users. + /// Condition for sorting the list of users. + /// Parameter that is used for API pagination. + /// Maximum number of users that are returned at a time. Default: 20. + public static void GetUserFriends(FriendsSearchType type, + Action onSuccess, + Action onError, + FriendsSearchSort sortBy = FriendsSearchSort.ByNickname, + FriendsSearchOrder sortOrder = FriendsSearchOrder.Asc, + int limit = 20, + int offset = 0) + { + var url = new UrlBuilder($"{BaseUrl}/users/me/relationships") + .AddParam("type", type.ToApiParameter()) + .AddParam("sort_by", sortBy.ToApiParameter()) + .AddParam("sort_order", sortOrder.ToApiParameter()) + .AddParam("after", offset) + .AddParam("limit", limit) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => GetUserFriends(type, onSuccess, onError, sortBy, sortOrder, offset, limit))); + } + + /// + /// Modifies relationships with the specified user. + /// + /// Type of the action. + /// Identifier of the user to change relationship with. + /// Called after successful user friends data modification. + /// Called after the request resulted with an error. + public static void UpdateUserFriends(FriendAction action, string user, Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/relationships"; + + var request = new UserFriendUpdateRequest { + action = action.ToApiParameter(), + user = user + }; + + WebRequestHelper.Instance.PostRequest( + SdkType.Login, + url, + request, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => UpdateUserFriends(action, user, onSuccess, onError))); + } + + /// + /// Links a social network that can be used for authentication to the current account. + /// + /// [More about the use cases](https://developers.xsolla.com/sdk/unity/user-account-and-attributes/account-linking/#sdk_account_linking_additional_account). + /// Name of a social network. Provider must be connected to Login in Publisher Account.
    + /// Can be `amazon`, `apple`, `baidu`, `battlenet`, `discord`, `facebook`, `github`, `google`, `instagram`, `kakao`, `linkedin`, `mailru`, `microsoft`, `msn`, `naver`, `ok`, `paradox`, `paypal`, `psn`, `qq`, `reddit`, `steam`, `twitch`, `twitter`, `vimeo`, `vk`, `wechat`, `weibo`, `yahoo`, `yandex`, `youtube`, `xbox`, `playstation`. + /// Called after the URL for social authentication was successfully received. + /// Called after the request resulted with an error. + /// URI to redirect the user to after account confirmation, successful authentication, two-factor authentication configuration, or password reset confirmation. + /// Must be identical to the OAuth 2.0 redirect URIs specified in Publisher Account. + /// Required if there are several URIs. + public static void LinkSocialProvider(SocialProvider providerName, Action onSuccess, Action onError, string redirectUri = null) + { + var providerValue = providerName.ToApiParameter(); + var url = new UrlBuilder($"{BaseUrl}/users/me/social_providers/{providerValue}/login_url") + .AddParam("login_url", RedirectUrlHelper.GetRedirectUrl(redirectUri)) + .Build(); + + WebRequestHelper.Instance.GetRequest( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + onSuccess, + error => TokenAutoRefresher.Check(error, onError, () => LinkSocialProvider(providerName, onSuccess, onError, redirectUri))); + } + + /// + /// Returns the list of social networks linked to the user account. + /// + /// Called after the list of linked social networks was successfully received. + /// Called after the request resulted with an error. + public static void GetLinkedSocialProviders(Action onSuccess, Action onError) + { + var url = $"{BaseUrl}/users/me/social_providers"; + + WebRequestHelper.Instance.GetRequest>( + SdkType.Login, + url, + WebRequestHeader.AuthHeader(), + response => + { + onSuccess?.Invoke(new LinkedSocialNetworks { + items = response + }); + }, + error => TokenAutoRefresher.Check(error, onError, () => GetLinkedSocialProviders(onSuccess, onError))); + } + } +} \ No newline at end of file diff --git a/Assets/Xsolla/UserAccount/Api/XsollaUserAccount.User.cs.meta b/Assets/Xsolla/UserAccount/XsollaUserAccount.cs.meta similarity index 100% rename from Assets/Xsolla/UserAccount/Api/XsollaUserAccount.User.cs.meta rename to Assets/Xsolla/UserAccount/XsollaUserAccount.cs.meta diff --git a/Documentation/Autogen/Doxyfile b/Documentation/Autogen/Doxyfile index 8742cf672..223c395ef 100644 --- a/Documentation/Autogen/Doxyfile +++ b/Documentation/Autogen/Doxyfile @@ -509,7 +509,7 @@ EXTRACT_PACKAGE = NO # included in the documentation. # The default value is: NO. -EXTRACT_STATIC = NO +EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, @@ -879,7 +879,8 @@ INPUT = ./Documentation/Autogen/mainpage.md \ ./Assets/Xsolla/Core/Enum/ \ ./Assets/Xsolla/Core/EnumStore/ \ ./Assets/Xsolla/Core/Errors/ \ - ./Assets/Xsolla/Core/TokenRefresh/ + ./Assets/Xsolla/Core/TokenRefresh/ \ + ./Assets/Xsolla/Core/Utils/ # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses diff --git a/ProjectSettings/ProjectSettings.asset b/ProjectSettings/ProjectSettings.asset index 6f0054bc5..c9f60c73c 100644 --- a/ProjectSettings/ProjectSettings.asset +++ b/ProjectSettings/ProjectSettings.asset @@ -124,7 +124,7 @@ PlayerSettings: 16:10: 1 16:9: 1 Others: 1 - bundleVersion: 1.5.0 + bundleVersion: 2.0.0 preloadedAssets: [] metroInputSource: 0 wsaTransparentSwapchain: 0 @@ -168,8 +168,8 @@ PlayerSettings: androidSupportedAspectRatio: 1 androidMaxAspectRatio: 2.1 applicationIdentifier: - Android: com.XsollaInc.XsollaInGameStoreUnityAsset - Standalone: com.XsollaInc.XsollaInGameStoreUnityAsset + Android: com.xsolla.sdk.unity.Example + Standalone: com.xsolla.sdk.unity.Example iPhone: com.xsolla.sdk.unity.Example buildNumber: {} AndroidBundleVersionCode: 1 diff --git a/README.md b/README.md index f561a8805..659d87360 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,8 @@ To start with the SDK, you need to install this asset and set up a project in [X Additionally, the asset supports [creating WebGL build](https://developers.xsolla.com/sdk/unity/how-tos/application-build/#unity_sdk_how_to_build_webgl) to run your application in a browser. +The SDK uses [Google Mobile Services](https://www.android.com/gms/) and doesn’t support builds for devices without Google Mobile Services, such as Huawei. + **NOTE:** We recommend you use the Mono compiler for desktop platforms as it’s compatible with the provided in-game browser. If you use other browser solutions, you can use the IL2CPP compiler instead. You can use either Mono or IL2CPP compilers to create game builds for Android.