# 玩家背包

> Use the SDK to manage player inventory items including adding, updating, and deleting items.

使用 `PlayerInventory` 命名空间中的方法，可以检索和更新玩家的背包实例。

这些方法将从 Authentication SDK 返回当前登录玩家的背包数据。

> **Note:**
>
> 此命名空间中的所有方法都可以抛出 [EconomyException](./exceptions.md#economyexception)。

## GetInventoryAsync##getinventory

检索与当前登录玩家关联的当前背包物品实例。

此方法可采用 `GetInventoryOptions` 对象。它可用于设置每次获取的物品数量并用于筛选。

您可以使用配置物品 ID 和/或 `PlayersInventoryItem` ID 列表来筛选背包物品。如果您使用这些筛选器选项，则只会返回具有指定配置物品 ID 和 `PlayersInventoryItem` ID 的玩家物品。

以下示例代码检索当前用户的前五个物品，然后检索接下来的五个物品。

```cs title="C#"
// Optional, defaults to 20
GetInventoryOptions options = new GetInventoryOptions
{
    ItemsPerFetch = 5
};

GetInventoryResult inventoryResult = await EconomyService.Instance.PlayerInventory.GetInventoryAsync(options);
List<PlayersInventoryItem> firstFiveItems = inventoryResult.PlayersInventoryItems;
// do something with your items

if (inventoryResult.HasNext) {
    inventoryResult = await inventoryResult.GetNextAsync(5);
    List<PlayersInventoryItem> nextFiveItems = inventoryResult.PlayersInventoryItems;
    // do something with your items
}
```

下一个示例代码仅检索玩家的 `SWORD` 物品。

```cs title="C#"
GetInventoryOptions options = new GetInventoryOptions
{
    InventoryItemIds = new List<string>() { "SWORD" }
};

GetInventoryResult inventoryResult = await EconomyService.Instance.PlayerInventory.GetInventoryAsync(options);

List<PlayersInventoryItem> listOfItems = inventoryResult.PlayersInventoryItems;

// ... etc
```

这些方法将返回 `GetInventoryResult`。

### GetInventoryOptions##getinventoryoptions

`GetInventoryAsync` 调用的选项对象。它包含以下字段：

* `PlayersInventoryItemIds`：字符串列表。默认为 `null`。您要检索的玩家背包中的物品的 `PlayersInventoryItem` ID。
* `InventoryItemIds`：字符串列表。默认为 `null`。您要检索的物品的配置 ID。
* `ItemsPerFetch`：整数。默认为 20。使用此设置可将每次调用获取的最大物品数量设置为 1 到 100 之间的数（包含 1 和 100）。

### GetInventoryResult##getinventoryresult

通过 `GetInventoryResult`，可分页查看检索到的玩家背包物品列表。它有以下字段：

* `PlayersInventoryItems`：包含当前获取物品的 `List<PlayersInventoryItem>`。

它具有以下方法：

* `GetNextAsync(int itemsToFetch = 20)`：此方法可异步获取更多结果。可以通过一个可选参数来限制获取的结果数量（1 到 100，默认为 20）。这将返回新结果，`PlayersInventoryItems` 列表中同时包含原有物品和新获取的物品。如果没有更多结果可供获取，结果将为 `null`。

## AddInventoryItemAsync##addinventoryitemasync

将物品添加到玩家的背包中。

此方法可采用 `AddInventoryItemOptions` 对象。它可用于设置自定义 `PlayersInventoryItemId`（如果为 `null`，则自动生成一个），也可用于设置实例数据的字典。

返回可用于表示添加到玩家背包中的背包物品的 `PlayersInventoryItem`。

```cs title="C#"
Dictionary<string, object> instanceData = new Dictionary<string, object>
{
    { "rarity", "purple" }
};

AddInventoryItemOptions options = new AddInventoryItemOptions
{
    PlayersInventoryItemId = "customID",
    InstanceData = instanceData 
};

PlayersInventoryItem createdInventoryItem = await EconomyService.Instance.PlayerInventory.AddInventoryItemAsync("SWORD", options);
```

### AddInventoryItemOptions##addinventoryitemoptions

`AddInventoryItemAsync` 调用的选项对象。它包含以下字段：

* `PlayersInventoryItemId`：字符串。默认为 `null`。设置创建的 `PlayersInventoryItem` 的 ID。如果未提供，则会生成一个。
* `InstanceData`：一个 `Dictionary<string, object>`。用于设置[实例数据](#using-instancedata)的字典。

## DeletePlayersInventoryItemAsync##deleteplayersinventoryitemasync

从玩家的背包中删除物品。

此方法可采用一项用于设置写锁的 `DeletePlayersInventoryItemOptions` 对象。如果提供了写锁，则仅当 Economy 服务接受写锁时才会删除该物品。如果没有提供写锁，则会强制执行操作。

```cs title="C#"
DeletePlayersInventoryItemOptions options = new DeletePlayersInventoryItemOptions
{
    WriteLock = "writeLock"
};
EconomyService.Instance.PlayerInventory.DeletePlayersInventoryItemAsync("playersInventoryItemID", options);
```

### DeletePlayersInventoryItemOptions##deleteplayersinventoryitemoptions

`DeletePlayersInventoryItemAsync` 调用的选项对象。它有以下字段：

* `WriteLock`：字符串。默认为 `null`。使用它来设置写锁，以实现乐观并发。请参阅[写锁](./common-objects.md#using-the-writelock)。

## UpdatePlayersInventoryItemAsync##updateplayersinventoryitemasync

使用新实例数据更新物品。

返回更新后的玩家背包物品。

此方法可采用一项用于设置写锁的 `UpdatePlayersInventoryItemOptions` 对象。如果提供了写锁，则仅当 Economy 服务接受写锁时才会更新物品。如果没有提供写锁，则会强制执行操作。

```cs title="C#"
Dictionary<string, object> instanceData = new Dictionary<string, object>
{
    { "rarity", "purple" }
};

UpdatePlayersInventoryItemOptions options = new UpdatePlayersInventoryItemOptions
{
    WriteLock = writeLock 
};

PlayersInventoryItem playersInventoryItem = await EconomyService.Instance.PlayerInventory.UpdatePlayersInventoryItemAsync("playersInventoryItemID", instanceData, options);
```

### UpdatePlayersInventoryItemOptions##updateplayersinventoryitemoptions

`UpdatePlayersInventoryItemAsync` 调用的选项对象。它有以下字段：

* `WriteLock`：字符串。默认为 `null`。使用它来设置写锁，以实现乐观并发。请参阅[写锁](./common-objects.md#using-the-writelock)。

## PlayersInventoryItem##playersinventoryitem

`PlayersInventoryItem` 表示玩家背包中的一项唯一物品。它包含以下字段：

* `PlayersInventoryItemId`：玩家背包中具有唯一性的此背包物品的 ID。
* `InstanceItemId`：此背包物品的配置 ID。
* `InstanceData`：与此玩家背包物品关联的任何实例数据。
* `InstanceDataDeserializable`：与此玩家背包物品关联的任何实例数据，形式为 `IDeserializable`。请参阅[使用 InstanceDataDeserializable](#using-instancedata)。
* `WriteLock`：此玩家的背包物品的当前 `writelock` 字符串。
* `Created`：此玩家的背包物品的创建日期。它是一个 [EconomyDate](./common-objects.md#economydate) 对象。
* `Modified`：此玩家的背包物品的修改日期。它是一个 [EconomyDate](./common-objects.md#economydate) 对象。

它还可以使用以下辅助器方法：

### GetItemDefinitionAsync##getitemdefinitionasync

此方法获取该玩家的背包物品配置，类型为 `InventoryItemDefinition`。

```cs title="C#"
PlayersInventoryItem playersInventoryItem = // ... fetch the players inventory item
InventoryItemDefinition itemDefinition = playersInventoryItem.GetItemDefinitionAsync();
```

## PlayersInventoryItemUpdated##playersinventoryitemupdated

可以订阅此事件，以便在 SDK 更新玩家背包中的特定物品时收到通知。订阅者将收到已更新物品的 `playersInventoryItem` ID。

> **Note:**
>
> 仅针对 SDK 发起的操作（例如，更新玩家背包、进行购买）调用此事件。在因其他设备/服务端的更改而进行任何更新时，将不调用此事件。

```cs title="C#"
EconomyService.Instance.PlayerInventory.PlayersInventoryItemUpdated += playersInventoryItemID => {
    Debug.Log($"The players inventory item that was updated was {playersInventoryItemID}");
};
```

### 使用 InstanceDataDeserializable##using-instancedata

使用 `InstanceDataDeserializable` 为玩家背包中的特定物品添加自定义数据。它作为 `object` 类型传入并作为 `IDeserializable` 类型获取。这样一来，您可以将自己的自定义类作为实例数据传入。

例如，玩家的盾牌可能具有耐久度等级。它可以通过 `InstanceDataDeserializable` 进行设置和更新：

```cs title="C#"
class MyInstanceData
    {
        public int Durability;
        public string Rarity;
    }

MyInstanceData myInstanceData = new MyInstanceData() { Durability = 100, Rarity = "purple"};
PlayersInventoryItem updatedItem = await EconomyService.Instance.PlayerInventory.UpdatePlayersInventoryItemAsync("playersInventoryItemId", myInstanceData);
```

您可以反序列化实例数据，操作如下：

```cs title="C#"
MyInstanceData fetchedInstanceData = updatedItem.InstanceData.GetAs<MyInstanceData>();
int durability = fetchedInstanceData.Durability;
string rarity = fetchedInstanceData.Rarity;
```
