From 2e8d91c56af0af96121096ed017507244d202850 Mon Sep 17 00:00:00 2001 From: momintlh <77355191+momintlh@users.noreply.github.com> Date: Tue, 27 May 2025 13:06:20 +0500 Subject: [PATCH 1/3] feat: sku class --- Assets/PlayroomKit/modules/Store/SKU.cs | 68 ++++++++++++++++++++ Assets/PlayroomKit/modules/Store/SKU.cs.meta | 11 ++++ 2 files changed, 79 insertions(+) create mode 100644 Assets/PlayroomKit/modules/Store/SKU.cs create mode 100644 Assets/PlayroomKit/modules/Store/SKU.cs.meta diff --git a/Assets/PlayroomKit/modules/Store/SKU.cs b/Assets/PlayroomKit/modules/Store/SKU.cs new file mode 100644 index 0000000..68c487f --- /dev/null +++ b/Assets/PlayroomKit/modules/Store/SKU.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using SimpleJSON; +using UnityEngine; + +namespace Playroom +{ + [Serializable] + public class SKU + { + public string id; + public string name; + public string description; + public string type; + public string image; + public string key; + public bool active; + public bool deleted; + public DateTime createdAt; + public DateTime updatedAt; + public TMetadata metadata; // create your own class for metadata based on your needs. + public string price; + public string productId; + + private static SKU ParseSKU(JSONNode node, Func metadataParser) + { + var rawMeta = node["metadata"]?.ToString() ?? "{}"; + + + SKU data = new() + { + id = node["id"]?.Value ?? string.Empty, + name = node["name"]?.Value ?? string.Empty, + description = node["description"]?.Value ?? string.Empty, + type = node["type"]?.Value ?? string.Empty, + image = node["image"]?.Value, + key = node["key"]?.Value ?? string.Empty, + active = node["active"] != null && node["active"].AsBool, + deleted = node["deleted"] != null && node["deleted"].AsBool, + price = node["price"]?.Value ?? string.Empty, + productId = node["productId"]?.Value ?? string.Empty, + createdAt = DateTime.TryParse(node["createdAt"]?.Value, out var cAt) ? cAt : DateTime.MinValue, + updatedAt = DateTime.TryParse(node["updatedAt"]?.Value, out var uAt) ? uAt : DateTime.MinValue, + metadata = metadataParser(rawMeta) + }; + return data; + } + + public static List> ParseSKUS(string jsonString, Func metadataParser) + { + List> skus = new(); + JSONNode root = JSON.Parse(jsonString); + + if (!root.IsArray) + Debug.LogWarning("Expected an array of SKUs"); + + skus.Clear(); + + foreach (JSONNode item in root.AsArray) + { + SKU data = ParseSKU(item, metadataParser); + skus.Add(data); + } + + return skus; + } + } +} \ No newline at end of file diff --git a/Assets/PlayroomKit/modules/Store/SKU.cs.meta b/Assets/PlayroomKit/modules/Store/SKU.cs.meta new file mode 100644 index 0000000..8a2c7e5 --- /dev/null +++ b/Assets/PlayroomKit/modules/Store/SKU.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 23a5ac1a45fbde547a9649f022223b4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From b6c5e22b129cfc4c782724a889f0f8a0ebdcee4e Mon Sep 17 00:00:00 2001 From: momintlh <77355191+momintlh@users.noreply.github.com> Date: Tue, 27 May 2025 15:51:59 +0500 Subject: [PATCH 2/3] feat: entitlement api response types --- .../modules/Store/PlayerEntitlements.cs | 64 +++++++++++++++++++ .../modules/Store/PlayerEntitlements.cs.meta | 11 ++++ Assets/PlayroomKit/modules/Store/SKU.cs | 1 - 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs create mode 100644 Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs.meta diff --git a/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs b/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs new file mode 100644 index 0000000..a06df8d --- /dev/null +++ b/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using SimpleJSON; +using UnityEngine; + +[Serializable] +public class PlayerEntitlement +{ + public string id; + public string paymentId; + public string playerId; + public string skuId; + public bool free; + public bool active; + public bool deleted; + public DateTime createdAt; + public DateTime updatedAt; + public DateTime? startDate; + public DateTime? endDate; + public string type; + public string key; + public TMetadata metadata; // create your own class for metadata based on your needs. + + private static PlayerEntitlement ParsePlayerEntitlement(JSONNode node, Func metadataParser) + { + var rawMeta = node["metadata"]?.ToString() ?? "{}"; + + PlayerEntitlement data = new() + { + id = node["id"]?.Value ?? string.Empty, + paymentId = node["paymentId"]?.Value ?? string.Empty, + playerId = node["playerId"]?.Value ?? string.Empty, + skuId = node["skuId"]?.Value ?? string.Empty, + startDate = DateTime.TryParse(node["startDate"]?.Value, out var sAt) ? sAt : null, + endDate = DateTime.TryParse(node["endDate"]?.Value, out var eAt) ? eAt : null, + free = node["free"] != null && node["free"].AsBool, + type = node["type"]?.Value ?? string.Empty, + key = node["key"]?.Value ?? string.Empty, + active = node["active"] != null && node["active"].AsBool, + deleted = node["deleted"] != null && node["deleted"].AsBool, + createdAt = DateTime.TryParse(node["createdAt"]?.Value, out var cAt) ? cAt : DateTime.MinValue, + updatedAt = DateTime.TryParse(node["updatedAt"]?.Value, out var uAt) ? uAt : DateTime.MinValue, + metadata = metadataParser(rawMeta) + }; + return data; + } + + public static List> ParsePlayerEntitlements(string jsonString, Func metadataParser) + { + List> entitlements = new(); + JSONNode root = JSON.Parse(jsonString); + + if (!root.IsArray) + Debug.LogWarning("Expected an array of of Entitlements"); + + foreach (JSONNode item in root.AsArray) + { + var data = ParsePlayerEntitlement(item, metadataParser); + entitlements.Add(data); + } + + return entitlements; + } +} \ No newline at end of file diff --git a/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs.meta b/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs.meta new file mode 100644 index 0000000..89045ff --- /dev/null +++ b/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 2e469e6879b8a3f40895f282181b6de8 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PlayroomKit/modules/Store/SKU.cs b/Assets/PlayroomKit/modules/Store/SKU.cs index 68c487f..d49f6e2 100644 --- a/Assets/PlayroomKit/modules/Store/SKU.cs +++ b/Assets/PlayroomKit/modules/Store/SKU.cs @@ -54,7 +54,6 @@ public static List> ParseSKUS(string jsonString, Func Date: Tue, 27 May 2025 17:14:44 +0500 Subject: [PATCH 3/3] feat: new types --- Assets/PlayroomKit/modules/Store.meta | 8 ++ .../modules/Store/PlayerEntitlements.cs | 101 ++++++++-------- Assets/PlayroomKit/modules/Store/SKU.cs | 7 +- Assets/Scenes/TestScene.unity | 4 + Assets/Scripts/GameManager.cs | 111 ++++++++++++++++++ 5 files changed, 178 insertions(+), 53 deletions(-) create mode 100644 Assets/PlayroomKit/modules/Store.meta diff --git a/Assets/PlayroomKit/modules/Store.meta b/Assets/PlayroomKit/modules/Store.meta new file mode 100644 index 0000000..e6faddf --- /dev/null +++ b/Assets/PlayroomKit/modules/Store.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c77b12589d7c7c14d82a006a663c2253 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs b/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs index a06df8d..681dea6 100644 --- a/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs +++ b/Assets/PlayroomKit/modules/Store/PlayerEntitlements.cs @@ -3,62 +3,65 @@ using SimpleJSON; using UnityEngine; -[Serializable] -public class PlayerEntitlement +namespace Playroom { - public string id; - public string paymentId; - public string playerId; - public string skuId; - public bool free; - public bool active; - public bool deleted; - public DateTime createdAt; - public DateTime updatedAt; - public DateTime? startDate; - public DateTime? endDate; - public string type; - public string key; - public TMetadata metadata; // create your own class for metadata based on your needs. - - private static PlayerEntitlement ParsePlayerEntitlement(JSONNode node, Func metadataParser) + [Serializable] + public class PlayerEntitlement { - var rawMeta = node["metadata"]?.ToString() ?? "{}"; + public string id; + public string paymentId; + public string playerId; + public string skuId; + public bool free; + public bool active; + public bool deleted; + public DateTime createdAt; + public DateTime updatedAt; + public DateTime? startDate; + public DateTime? endDate; + public string type; + public string key; + public TMetadata metadata; // create your own class for metadata based on your needs. - PlayerEntitlement data = new() + private static PlayerEntitlement FromJSONNode(JSONNode node, Func metadataParser) { - id = node["id"]?.Value ?? string.Empty, - paymentId = node["paymentId"]?.Value ?? string.Empty, - playerId = node["playerId"]?.Value ?? string.Empty, - skuId = node["skuId"]?.Value ?? string.Empty, - startDate = DateTime.TryParse(node["startDate"]?.Value, out var sAt) ? sAt : null, - endDate = DateTime.TryParse(node["endDate"]?.Value, out var eAt) ? eAt : null, - free = node["free"] != null && node["free"].AsBool, - type = node["type"]?.Value ?? string.Empty, - key = node["key"]?.Value ?? string.Empty, - active = node["active"] != null && node["active"].AsBool, - deleted = node["deleted"] != null && node["deleted"].AsBool, - createdAt = DateTime.TryParse(node["createdAt"]?.Value, out var cAt) ? cAt : DateTime.MinValue, - updatedAt = DateTime.TryParse(node["updatedAt"]?.Value, out var uAt) ? uAt : DateTime.MinValue, - metadata = metadataParser(rawMeta) - }; - return data; - } + var rawMeta = node["metadata"]?.ToString() ?? "{}"; - public static List> ParsePlayerEntitlements(string jsonString, Func metadataParser) - { - List> entitlements = new(); - JSONNode root = JSON.Parse(jsonString); - - if (!root.IsArray) - Debug.LogWarning("Expected an array of of Entitlements"); + PlayerEntitlement data = new() + { + id = node["id"]?.Value ?? string.Empty, + paymentId = node["paymentId"]?.Value ?? string.Empty, + playerId = node["playerId"]?.Value ?? string.Empty, + skuId = node["skuId"]?.Value ?? string.Empty, + startDate = DateTime.TryParse(node["startDate"]?.Value, out var sAt) ? sAt : null, + endDate = DateTime.TryParse(node["endDate"]?.Value, out var eAt) ? eAt : null, + free = node["free"] != null && node["free"].AsBool, + type = node["type"]?.Value ?? string.Empty, + key = node["key"]?.Value ?? string.Empty, + active = node["active"] != null && node["active"].AsBool, + deleted = node["deleted"] != null && node["deleted"].AsBool, + createdAt = DateTime.TryParse(node["createdAt"]?.Value, out var cAt) ? cAt : DateTime.MinValue, + updatedAt = DateTime.TryParse(node["updatedAt"]?.Value, out var uAt) ? uAt : DateTime.MinValue, + metadata = metadataParser(rawMeta) + }; + return data; + } - foreach (JSONNode item in root.AsArray) + public static List> FromJSON(string jsonString, Func metadataParser) { - var data = ParsePlayerEntitlement(item, metadataParser); - entitlements.Add(data); - } + List> entitlements = new(); + JSONNode root = JSON.Parse(jsonString); + + if (!root.IsArray) + Debug.LogWarning("Expected an array"); - return entitlements; + foreach (JSONNode item in root.AsArray) + { + var data = FromJSONNode(item, metadataParser); + entitlements.Add(data); + } + + return entitlements; + } } } \ No newline at end of file diff --git a/Assets/PlayroomKit/modules/Store/SKU.cs b/Assets/PlayroomKit/modules/Store/SKU.cs index d49f6e2..cabdd26 100644 --- a/Assets/PlayroomKit/modules/Store/SKU.cs +++ b/Assets/PlayroomKit/modules/Store/SKU.cs @@ -22,7 +22,7 @@ public class SKU public string price; public string productId; - private static SKU ParseSKU(JSONNode node, Func metadataParser) + private static SKU FromJSONNode(JSONNode node, Func metadataParser) { var rawMeta = node["metadata"]?.ToString() ?? "{}"; @@ -46,7 +46,7 @@ private static SKU ParseSKU(JSONNode node, Func me return data; } - public static List> ParseSKUS(string jsonString, Func metadataParser) + public static List> FromJSON(string jsonString, Func metadataParser) { List> skus = new(); JSONNode root = JSON.Parse(jsonString); @@ -54,10 +54,9 @@ public static List> ParseSKUS(string jsonString, Func data = ParseSKU(item, metadataParser); + SKU data = FromJSONNode(item, metadataParser); skus.Add(data); } diff --git a/Assets/Scenes/TestScene.unity b/Assets/Scenes/TestScene.unity index c1283b3..25bc820 100644 --- a/Assets/Scenes/TestScene.unity +++ b/Assets/Scenes/TestScene.unity @@ -286,7 +286,11 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: dc3a2b9cdc24aab40906ce4bcdee9943, type: 3} m_Name: m_EditorClassIdentifier: + baseUrl: https://ws.joinplayroom.com/api/store + gameApiKey: 510a71af-3a69-4f5d-9b9b-296a1871e624 text: {fileID: 1547749} + skus: [] + entitlements: [] --- !u!4 &1054460207 Transform: m_ObjectHideFlags: 0 diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 8283168..66b978c 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -1,11 +1,17 @@ using System; +using System.Collections; using System.Collections.Generic; using Playroom; +using SimpleJSON; using TMPro; using UnityEngine; +using UnityEngine.Networking; public class GameManager : MonoBehaviour { + [SerializeField] private string baseUrl = "https://ws.joinplayroom.com/api/store"; + [SerializeField] private string gameApiKey; + private PlayroomKit playroomKit; public TextMeshProUGUI text; @@ -14,6 +20,72 @@ public class GameManager : MonoBehaviour string skuId = "1371921246031319121"; + [Header("SKUs")] + [SerializeField] + private List> skus; + + [Header("Entitlements")] + [SerializeField] + private List> entitlements; + + [Serializable] + public class CustomMetadataClass + { + public string packId; + } + + public void FetchSKUS(Action onRequestComplete = null) + { + StartCoroutine(GetSKUS(onRequestComplete)); + } + + private IEnumerator GetSKUS(Action onRequestComplete = null) + { + var url = $"{baseUrl}/sku?gameId={UnityWebRequest.EscapeURL("FmOBeUfQO2AOLNIrJNSJ")}&platform={UnityWebRequest.EscapeURL("discord")}"; + + using (var req = UnityWebRequest.Get(url)) + { + req.SetRequestHeader("x-game-api", gameApiKey); + yield return req.SendWebRequest(); + + if (req.result == UnityWebRequest.Result.ConnectionError || req.result == UnityWebRequest.Result.ProtocolError) + { + Debug.LogError($"Error fetching SKUs: {req.error}"); + } + else + { + onRequestComplete?.Invoke(req.downloadHandler.text); + } + } + } + + public void FetchEntitlements(Action onRequestComplete) + { + StartCoroutine(GetEntitlements(onRequestComplete)); + } + + private IEnumerator GetEntitlements(Action onRequestComplete) + { + var url = $"{baseUrl}/entitlement?gameId={UnityWebRequest.EscapeURL("FmOBeUfQO2AOLNIrJNSJ")}"; + + using (var req = UnityWebRequest.Get(url)) + { + //TODO: THIS IS FOR TESTING ONLY, REMOVE LATER + string token = "eyJhbGciOiJIUzI1NiJ9.eyJkaXNjb3JkSWQiOiI0NzY3MDk1MjQwMTE2MTQyMTkiLCJyb29tSWQiOiJEQ1JEX2ktMTM3NDY3NDQ2MDUyMjcxMzE1OS1nYy0xMjczNjA3Njg2ODE4MTA3NDAyLTEyNzQ5OTUxNDcyNjc4OTk0NTYiLCJnYW1lSWQiOiJGbU9CZVVmUU8yQU9MTklySk5TSiIsImd1aWxkSWQiOiIxMjczNjA3Njg2ODE4MTA3NDAyIiwiY2hhbm5lbElkIjoiMTI3NDk5NTE0NzI2Nzg5OTQ1NiIsImFjY2Vzc1Rva2VuIjoiV2FVNFV1RjJ6UEJOTzY1QWZISlNrR2RzaVBGOWpKIiwiYXV0aCI6ImRpc2NvcmQiLCJ0IjoxNzQ3ODE4MzYzfQ.bRvWY7SMafo0iQzfdp0N53Euu58eC35AZ6ruiCdgF0M"; + req.SetRequestHeader("Authorization", $"Bearer {token}"); + yield return req.SendWebRequest(); + + if (req.result == UnityWebRequest.Result.ConnectionError || + req.result == UnityWebRequest.Result.ProtocolError) + { + Debug.LogError($"Error fetching entitlements: {req.error}"); + onRequestComplete?.Invoke(req.error); + yield break; + } + onRequestComplete?.Invoke(req.downloadHandler.text); + } + } + private void Awake() { playroomKit = new PlayroomKit(); @@ -56,11 +128,50 @@ private void Update() }); } + if (Input.GetKeyDown(KeyCode.E)) + { + FetchEntitlements((data) => + { + text.text = "Entitlements fetched successfully!"; + Debug.Log("Entitlements fetched successfully!"); + + entitlements = PlayerEntitlement.FromJSON(data, ParseMetadata); + }); + } + + if (Input.GetKeyDown(KeyCode.S)) + { + FetchSKUS((jsonString) => + { + text.text = "SKUs fetched successfully!"; + Debug.Log("SKUs fetched successfully!"); + + skus = SKU.FromJSON(jsonString, ParseMetadata); + }); + } + + CustomMetadataClass ParseMetadata(string json) + { + JSONNode node = JSON.Parse(json); + + return new CustomMetadataClass() + { + packId = node["packId"], + }; + } + + CustomMetadataClass ParseMetadataUnity(string json) + { + return JsonUtility.FromJson(json); + } + + if (Input.GetKeyDown(KeyCode.P)) { // After InsertCoin has fully invoked playroomKit.StartDiscordPurchase(skuId, (response) => { + text.text = "Purchase started successfully!"; Debug.Log($"Entitlement: {response}"); }); }