diff --git a/Runtime/Client/LootLockerEndPoints.cs b/Runtime/Client/LootLockerEndPoints.cs index 6a5aee8f..c34f75b4 100644 --- a/Runtime/Client/LootLockerEndPoints.cs +++ b/Runtime/Client/LootLockerEndPoints.cs @@ -349,6 +349,16 @@ public class LootLockerEndPoints // Presence (WebSocket) [Header("Presence")] public static EndPointClass presenceWebSocket = new EndPointClass("presence/v1", LootLockerHTTPMethod.GET); + + // Items + [Header("Items")] + public static EndPointClass listItemTemplates = new EndPointClass("player/inventory/v1", LootLockerHTTPMethod.GET); + public static EndPointClass listPlayerItems = new EndPointClass("player/inventory/v1/my", LootLockerHTTPMethod.GET); + public static EndPointClass getPlayerItem = new EndPointClass("player/inventory/v1/{0}", LootLockerHTTPMethod.GET); + public static EndPointClass deletePlayerItem = new EndPointClass("player/inventory/v1/{0}", LootLockerHTTPMethod.DELETE); + public static EndPointClass consumePlayerItem = new EndPointClass("player/inventory/v1/{0}/consume", LootLockerHTTPMethod.POST); + public static EndPointClass splitPlayerItemStack = new EndPointClass("player/inventory/v1/{0}/split", LootLockerHTTPMethod.POST); + public static EndPointClass mergePlayerItemStacks = new EndPointClass("player/inventory/v1/merge", LootLockerHTTPMethod.POST); } [Serializable] diff --git a/Runtime/Game/LootLockerSDKManager.cs b/Runtime/Game/LootLockerSDKManager.cs index 2d104dac..2b685735 100644 --- a/Runtime/Game/LootLockerSDKManager.cs +++ b/Runtime/Game/LootLockerSDKManager.cs @@ -6626,7 +6626,142 @@ public static void DeleteAssetInstanceFromPlayerInventory(int assetInstanceID, A LootLockerAPIManager.DeleteAssetInstanceFromPlayerInventory(forPlayerWithUlid, data, onComplete); } #endregion - + + #region Items + + /// + /// Returns a paginated list of all visible item templates. + /// + /// The page of item templates to return. Defaults to 1. + /// The number of item templates to return per page. Defaults to 25. + /// Delegate for handling the server response + /// Optional : Execute the request for the specified player. If not supplied, the default player will be used. + public static void ListItemTemplates(int page, int perPage, Action onComplete, string forPlayerWithUlid = null) + { + if (!CheckInitialized(false, forPlayerWithUlid)) + { + onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError(forPlayerWithUlid)); + return; + } + + LootLockerAPIManager.ListItemTemplates(forPlayerWithUlid, page, perPage, onComplete); + } + + /// + /// Returns a paginated list of the current player's inventory items, including their item templates. + /// + /// The page of items to return. Defaults to 1. + /// The number of items to return per page. Defaults to 25. + /// (Optional) Return only items whose template name starts with the specified value. Set to null to not use this filter. + /// (Optional) Return only items of the specified type. Set to null to not use this filter. + /// (Optional) Return only items that are (or are not) consumable. Set to null to not use this filter. + /// (Optional) The field by which to sort the items. Set to null to not use this filter. + /// (Optional) The direction in which to sort the items. Set to null to not use this filter. + /// Delegate for handling the server response + /// Optional : Execute the request for the specified player. If not supplied, the default player will be used. + public static void ListPlayerItems(int page, int perPage, string name = null, LootLockerItemType? itemType = null, bool? consumable = null, LootLockerItemSortField? sort = null, LootLockerSortOrder? order = null, Action onComplete = null, string forPlayerWithUlid = null) + { + if (!CheckInitialized(false, forPlayerWithUlid)) + { + onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError(forPlayerWithUlid)); + return; + } + + LootLockerAPIManager.ListPlayerItems(forPlayerWithUlid, page, perPage, name, itemType?.ToString(), consumable, sort?.ToString(), order?.ToString(), onComplete); + } + + /// + /// Returns a single inventory item for the current player, including its item template. + /// + /// The id of the inventory item to fetch. + /// Delegate for handling the server response + /// Optional : Execute the request for the specified player. If not supplied, the default player will be used. + public static void GetPlayerItem(string inventoryId, Action onComplete, string forPlayerWithUlid = null) + { + if (!CheckInitialized(false, forPlayerWithUlid)) + { + onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError(forPlayerWithUlid)); + return; + } + + LootLockerAPIManager.GetPlayerItem(forPlayerWithUlid, inventoryId, onComplete); + } + + /// + /// Deletes an inventory item from the current player's inventory. + /// + /// The id of the inventory item to delete. + /// Delegate for handling the server response + /// Optional : Execute the request for the specified player. If not supplied, the default player will be used. + public static void DeletePlayerItem(string inventoryId, Action onComplete, string forPlayerWithUlid = null) + { + if (!CheckInitialized(false, forPlayerWithUlid)) + { + onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError(forPlayerWithUlid)); + return; + } + + LootLockerAPIManager.DeletePlayerItem(forPlayerWithUlid, inventoryId, onComplete); + } + + /// + /// Consumes one or more items from a stackable inventory item. If is null, the whole stack is consumed. + /// + /// The id of the stackable inventory item to consume. + /// (Optional) The number of items to consume. If null, the whole stack is consumed. + /// Delegate for handling the server response + /// Optional : Execute the request for the specified player. If not supplied, the default player will be used. + public static void ConsumePlayerItem(string inventoryId, int? count, Action onComplete, string forPlayerWithUlid = null) + { + if (!CheckInitialized(false, forPlayerWithUlid)) + { + onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError(forPlayerWithUlid)); + return; + } + + LootLockerConsumeItemRequest data = new LootLockerConsumeItemRequest { count = count }; + LootLockerAPIManager.ConsumePlayerItem(forPlayerWithUlid, inventoryId, data, onComplete); + } + + /// + /// Splits a stackable inventory item into two stacks, moving items into a new stack. + /// + /// The id of the stackable inventory item to split. + /// The number of items to move into the new stack. + /// Delegate for handling the server response + /// Optional : Execute the request for the specified player. If not supplied, the default player will be used. + public static void SplitPlayerItemStack(string inventoryId, int count, Action onComplete, string forPlayerWithUlid = null) + { + if (!CheckInitialized(false, forPlayerWithUlid)) + { + onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError(forPlayerWithUlid)); + return; + } + + LootLockerSplitItemStackRequest data = new LootLockerSplitItemStackRequest { count = count }; + LootLockerAPIManager.SplitPlayerItemStack(forPlayerWithUlid, inventoryId, data, onComplete); + } + + /// + /// Merges two stacks of the same item into one. + /// + /// The id of the inventory item to merge from. + /// The id of the inventory item to merge into. + /// Delegate for handling the server response + /// Optional : Execute the request for the specified player. If not supplied, the default player will be used. + public static void MergePlayerItemStacks(string sourceInventoryId, string targetInventoryId, Action onComplete, string forPlayerWithUlid = null) + { + if (!CheckInitialized(false, forPlayerWithUlid)) + { + onComplete?.Invoke(LootLockerResponseFactory.SDKNotInitializedError(forPlayerWithUlid)); + return; + } + + LootLockerMergeItemStacksRequest data = new LootLockerMergeItemStacksRequest { source_inventory_id = sourceInventoryId, target_inventory_id = targetInventoryId }; + LootLockerAPIManager.MergePlayerItemStacks(forPlayerWithUlid, data, onComplete); + } + #endregion + #region AssetInstance progressions /// @ingroup AssetInstanceProgressions diff --git a/Runtime/Game/Requests/ItemRequest.cs b/Runtime/Game/Requests/ItemRequest.cs new file mode 100644 index 00000000..1ba1a024 --- /dev/null +++ b/Runtime/Game/Requests/ItemRequest.cs @@ -0,0 +1,359 @@ +using System; +using LootLocker.Requests; +using LootLocker.Utilities.HTTP; + +namespace LootLocker.LootLockerEnums +{ + /// + /// The type of an item, determining whether the item instances are stackable or individually tracked. + /// + public enum LootLockerItemType + { + /// Each granted item is a separate, individually tracked instance. + instanced, + /// The item is stored as a single entry with a count that can be incremented or decremented. + stackable + } + + /// + /// The field by which to order a player item list response. + /// + public enum LootLockerItemSortField + { + /// Order by when the item was created. + created_at, + /// Order by when the item was last updated. + updated_at + } + + /// + /// The direction in which to order a player item list response. + /// + public enum LootLockerSortOrder + { + /// Order ascending. + ASC, + /// Order descending. + DESC + } +} + +namespace LootLocker.Requests +{ + //================================================== + // Item Template Definitions + //================================================== + + /// + /// An item template defines a type of item that can be granted to players. + /// + public class LootLockerItemTemplate + { + /// The unique id of the item template. + public string id { get; set; } + + /// The name of the item template. + public string name { get; set; } + + /// The id of the game this item template belongs to. + public int game_id { get; set; } + + /// Indicates whether this item template is limited in how many of it can exist. + public int limited { get; set; } + + /// The type of the item (instanced or stackable). + public string item_type { get; set; } + + /// True if the item can be consumed by the player. + public bool consumable { get; set; } + + /// True if the item can be deleted by the player. + public bool deletable { get; set; } + + /// The time that this item template was created. + public string created_at { get; set; } + + /// The time that this item template was last updated. + public string updated_at { get; set; } + } + + //================================================== + // Player Item Definitions + //================================================== + + /// + /// An item instance held in a player's inventory. + /// + public class LootLockerItem + { + /// The unique id of this inventory item. + public string id { get; set; } + + /// The id of the player that owns this inventory item. + public int player_id { get; set; } + + /// The id of the item template this inventory item is based on. + public string item_template_id { get; set; } + + /// The type of the item (instanced or stackable). + public string item_type { get; set; } + + /// True if the item can be consumed by the player. + public bool consumable { get; set; } + + /// True if the item can be deleted by the player. + public bool deletable { get; set; } + + /// The number of items in this stack (only relevant for stackable items). + public int count { get; set; } + + /// The name of the item template this inventory item is based on. + public string name { get; set; } + + /// The source of this inventory item, or null if not specified. + public string source { get; set; } + + /// The time that this inventory item was created. + public string created_at { get; set; } + + /// The time that this inventory item was last updated. + public string updated_at { get; set; } + + /// Arbitrary metadata attached to this inventory item. + public LootLockerMetadataEntry[] metadata { get; set; } + } + + /// + /// An item granted to a player as the result of consuming another item (or via an on-grant behaviour). + /// Matches the go-backend `GrantResult` shape returned in `granted` / `behaviour_results`. + /// + public class LootLockerGrantedItem + { + /// The source id of the granted entry (inventory id, currency id, etc.). + public string source_id { get; set; } + + /// The number of items granted. + public int count { get; set; } + + /// The type of the granted entry ("item_template", "currency", or "publisher_currency"). + public string type { get; set; } + + /// The name of the granted entry, if applicable. + public string name { get; set; } + + /// The code of the granted entry, if applicable. + public string code { get; set; } + } + + //================================================== + // Request Definitions + //================================================== + + /// + /// Request to consume a stackable item from the player's inventory. + /// + public class LootLockerConsumeItemRequest + { + /// The number of items to consume. If omitted, the whole stack is consumed. + public int? count { get; set; } + } + + /// + /// Request to split a stackable item in the player's inventory into two stacks. + /// + public class LootLockerSplitItemStackRequest + { + /// The number of items to move into the new stack. + public int count { get; set; } + } + + /// + /// Request to merge two stacks of the same item into one. + /// + public class LootLockerMergeItemStacksRequest + { + /// The id of the source inventory item to merge from. + public string source_inventory_id { get; set; } + + /// The id of the target inventory item to merge into. + public string target_inventory_id { get; set; } + } + + //================================================== + // Response Definitions + //================================================== + + /// + /// Response containing a paginated list of visible item templates. + /// + public class LootLockerListItemTemplatesResponse : LootLockerResponse + { + /// The list of visible item templates. + public LootLockerItemTemplate[] items { get; set; } + + /// Pagination details for the response. + public LootLockerExtendedPagination pagination { get; set; } + } + + /// + /// Response containing a paginated list of the player's inventory items. + /// + public class LootLockerListPlayerItemsResponse : LootLockerResponse + { + /// The list of the player's inventory items. + public LootLockerItem[] items { get; set; } + + /// Pagination details for the response. + public LootLockerExtendedPagination pagination { get; set; } + } + + /// + /// Response containing the player's inventory item, returned at the top level with its template and metadata. + /// + public class LootLockerGetPlayerItemResponse : LootLockerResponse + { + /// The unique id of this inventory item. + public string id { get; set; } + + /// The id of the player that owns this inventory item. + public int player_id { get; set; } + + /// The id of the item template this inventory item is based on. + public string item_template_id { get; set; } + + /// The type of the item (instanced or stackable). + public string item_type { get; set; } + + /// True if the item can be consumed by the player. + public bool consumable { get; set; } + + /// True if the item can be deleted by the player. + public bool deletable { get; set; } + + /// The number of items in this stack (only relevant for stackable items). + public int count { get; set; } + + /// The source of this inventory item, or null if not specified. + public string source { get; set; } + + /// The time that this inventory item was created. + public string created_at { get; set; } + + /// The time that this inventory item was last updated. + public string updated_at { get; set; } + + /// The item template this inventory item is based on. + public LootLockerItemTemplate template { get; set; } + + /// Arbitrary metadata attached to this inventory item. + public LootLockerMetadataEntry[] metadata { get; set; } + } + + /// + /// Response containing the result of consuming an item, including any items granted as a result. + /// + public class LootLockerConsumeItemResponse : LootLockerResponse + { + /// True if the item was consumed. + public bool consumed { get; set; } + + /// Any items granted as a result of consuming the item. + public LootLockerGrantedItem[] granted { get; set; } + } + + /// + /// Response containing the id of the newly created stack after splitting an item. + /// + public class LootLockerSplitItemStackResponse : LootLockerResponse + { + /// The id of the newly created item stack. + public string id { get; set; } + } +} + +namespace LootLocker +{ + //================================================== + // API Class Definition + //================================================== + + public partial class LootLockerAPIManager + { + public static void ListItemTemplates(string forPlayerWithUlid, int page, int perPage, Action onComplete) + { + EndPointClass endPoint = LootLockerEndPoints.listItemTemplates; + + var queryParams = new QueryParamaterBuilder(); + queryParams.Add("page", page); + queryParams.Add("per_page", perPage); + + LootLockerServerRequest.CallAPI(forPlayerWithUlid, endPoint.endPoint + queryParams.Build(), endPoint.httpMethod, null, onComplete: (serverResponse) => { LootLockerResponse.Deserialize(onComplete, serverResponse); }); + } + + public static void ListPlayerItems(string forPlayerWithUlid, int page, int perPage, string name, string itemType, bool? consumable, string sort, string order, Action onComplete) + { + EndPointClass endPoint = LootLockerEndPoints.listPlayerItems; + + var queryParams = new QueryParamaterBuilder(); + queryParams.Add("page", page); + queryParams.Add("per_page", perPage); + queryParams.Add("name", name); + queryParams.Add("item_type", itemType); + if (consumable.HasValue) + { + queryParams.Add("consumable", consumable.Value.ToString().ToLower()); + } + queryParams.Add("sort", sort); + queryParams.Add("order", order); + + LootLockerServerRequest.CallAPI(forPlayerWithUlid, endPoint.endPoint + queryParams.Build(), endPoint.httpMethod, null, onComplete: (serverResponse) => { LootLockerResponse.Deserialize(onComplete, serverResponse); }); + } + + public static void GetPlayerItem(string forPlayerWithUlid, string inventoryId, Action onComplete) + { + EndPointClass endPoint = LootLockerEndPoints.getPlayerItem; + + string getVariable = endPoint.WithPathParameter(inventoryId); + + LootLockerServerRequest.CallAPI(forPlayerWithUlid, getVariable, endPoint.httpMethod, null, onComplete: (serverResponse) => { LootLockerResponse.Deserialize(onComplete, serverResponse); }); + } + + public static void DeletePlayerItem(string forPlayerWithUlid, string inventoryId, Action onComplete) + { + EndPointClass endPoint = LootLockerEndPoints.deletePlayerItem; + + string getVariable = endPoint.WithPathParameter(inventoryId); + + LootLockerServerRequest.CallAPI(forPlayerWithUlid, getVariable, endPoint.httpMethod, null, onComplete: (serverResponse) => { LootLockerResponse.Deserialize(onComplete, serverResponse); }); + } + + public static void ConsumePlayerItem(string forPlayerWithUlid, string inventoryId, LootLockerConsumeItemRequest data, Action onComplete) + { + EndPointClass endPoint = LootLockerEndPoints.consumePlayerItem; + + string getVariable = endPoint.WithPathParameter(inventoryId); + string json = LootLockerJson.SerializeObject(data); + + LootLockerServerRequest.CallAPI(forPlayerWithUlid, getVariable, endPoint.httpMethod, json, onComplete: (serverResponse) => { LootLockerResponse.Deserialize(onComplete, serverResponse); }); + } + + public static void SplitPlayerItemStack(string forPlayerWithUlid, string inventoryId, LootLockerSplitItemStackRequest data, Action onComplete) + { + EndPointClass endPoint = LootLockerEndPoints.splitPlayerItemStack; + + string getVariable = endPoint.WithPathParameter(inventoryId); + string json = LootLockerJson.SerializeObject(data); + + LootLockerServerRequest.CallAPI(forPlayerWithUlid, getVariable, endPoint.httpMethod, json, onComplete: (serverResponse) => { LootLockerResponse.Deserialize(onComplete, serverResponse); }); + } + + public static void MergePlayerItemStacks(string forPlayerWithUlid, LootLockerMergeItemStacksRequest data, Action onComplete) + { + EndPointClass endPoint = LootLockerEndPoints.mergePlayerItemStacks; + + string json = LootLockerJson.SerializeObject(data); + + LootLockerServerRequest.CallAPI(forPlayerWithUlid, endPoint.endPoint, endPoint.httpMethod, json, onComplete: (serverResponse) => { LootLockerResponse.Deserialize(onComplete, serverResponse); }); + } + } +}