server-master/srcs/_plugins/WingsEmu.Plugins.BasicImplementation/Warehouse/AccountWarehouseManager.cs
2026-02-10 18:21:30 +01:00

170 lines
No EOL
5.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using PhoenixLib.Caching;
using PhoenixLib.Logging;
using WingsAPI.Communication;
using WingsAPI.Communication.DbServer.WarehouseService;
using WingsAPI.Data.Account;
using WingsAPI.Game.Extensions;
using WingsEmu.Core.Extensions;
using WingsEmu.DTOs.Items;
using WingsEmu.Game._enum;
using WingsEmu.Game.Warehouse;
namespace WingsEmu.Plugins.BasicImplementations.Warehouse;
public class AccountWarehouseManager : IAccountWarehouseManager
{
private static readonly TimeSpan LifeTime = TimeSpan.FromMinutes(15);
private readonly IAccountWarehouseService _accountWarehouseService;
private readonly ILongKeyCachedRepository<Dictionary<short, AccountWarehouseItemDto>> _cachedAccountItems;
public AccountWarehouseManager(ILongKeyCachedRepository<Dictionary<short, AccountWarehouseItemDto>> cachedAccountItems, IAccountWarehouseService accountWarehouseService)
{
_cachedAccountItems = cachedAccountItems;
_accountWarehouseService = accountWarehouseService;
}
public async Task<(IDictionary<short, AccountWarehouseItemDto> accountWarehouseItemDtos, ManagerResponseType?)> GetWarehouse(long accountId)
{
Dictionary<short, AccountWarehouseItemDto> retrievedItems = _cachedAccountItems.Get(accountId);
if (retrievedItems != null)
{
_cachedAccountItems.Set(accountId, retrievedItems, LifeTime);
return (retrievedItems, ManagerResponseType.Success);
}
AccountWarehouseGetItemsResponse response = null;
try
{
response = await _accountWarehouseService.GetItems(new AccountWarehouseGetItemsRequest
{
AccountId = accountId
});
}
catch (Exception ex)
{
Log.Error("[ACCOUNT_WAREHOUSE_MANAGER][GET_ITEMS] ", ex);
}
Dictionary<short, AccountWarehouseItemDto> dictionary = response?.Items?.ToDictionary(x => x.Slot) ?? new Dictionary<short, AccountWarehouseItemDto>();
if (response?.ResponseType == RpcResponseType.SUCCESS)
{
_cachedAccountItems.Set(accountId, dictionary, LifeTime);
}
return (dictionary, response?.ResponseType.ToManagerType());
}
public async Task<(AccountWarehouseItemDto, ManagerResponseType?)> GetWarehouseItem(long accountId, short slot)
{
(IDictionary<short, AccountWarehouseItemDto> familyWarehouseItemDtos, ManagerResponseType? responseType) = await GetWarehouse(accountId);
return (familyWarehouseItemDtos.GetOrDefault(slot), responseType);
}
public async Task<(AccountWarehouseItemDto, ManagerResponseType?)> AddWarehouseItem(AccountWarehouseItemDto warehouseItemDtoToAdd)
{
AccountWarehouseAddItemResponse response = null;
try
{
response = await _accountWarehouseService.AddItem(new AccountWarehouseAddItemRequest
{
Item = warehouseItemDtoToAdd
});
}
catch (Exception ex)
{
Log.Error("[ACCOUNT_WAREHOUSE_MANAGER][ADD_ITEM] ", ex);
}
if (response?.ResponseType == RpcResponseType.SUCCESS)
{
await UpdateWarehouseItem(warehouseItemDtoToAdd.AccountId, response.Item.Slot, response.Item);
}
return (response?.Item, response?.ResponseType.ToManagerType());
}
public async Task<(AccountWarehouseItemDto, ItemInstanceDTO, ManagerResponseType?)> WithdrawWarehouseItem(AccountWarehouseItemDto warehouseItemDtoToWithdraw, int amount)
{
AccountWarehouseWithdrawItemResponse response = null;
try
{
response = await _accountWarehouseService.WithdrawItem(new AccountWarehouseWithdrawItemRequest
{
ItemToWithdraw = warehouseItemDtoToWithdraw,
Amount = amount
});
}
catch (Exception ex)
{
Log.Error("[ACCOUNT_WAREHOUSE_MANAGER][WITHDRAW_ITEM] ", ex);
}
if (response?.ResponseType == RpcResponseType.SUCCESS)
{
await UpdateWarehouseItem(warehouseItemDtoToWithdraw.AccountId, warehouseItemDtoToWithdraw.Slot, response.UpdatedItem);
}
return (response?.UpdatedItem, response?.WithdrawnItem, response?.ResponseType.ToManagerType());
}
public async Task<(AccountWarehouseItemDto oldItem, AccountWarehouseItemDto newItem, ManagerResponseType?)> MoveWarehouseItem(AccountWarehouseItemDto warehouseItemDtoToMove, int amount,
short newSlot)
{
AccountWarehouseMoveItemResponse response = null;
try
{
response = await _accountWarehouseService.MoveItem(new AccountWarehouseMoveItemRequest
{
WarehouseItemDtoToMove = warehouseItemDtoToMove,
Amount = amount,
NewSlot = newSlot
});
}
catch (Exception ex)
{
Log.Error("[ACCOUNT_WAREHOUSE_MANAGER][MOVE_ITEM] ", ex);
}
if (response?.ResponseType == RpcResponseType.SUCCESS)
{
await UpdateWarehouseItem(warehouseItemDtoToMove.AccountId, warehouseItemDtoToMove.Slot, response.OldItem);
await UpdateWarehouseItem(warehouseItemDtoToMove.AccountId, newSlot, response.NewItem);
}
return (response?.OldItem, response?.NewItem, response?.ResponseType.ToManagerType());
}
public void CleanCache(long accountId)
{
_cachedAccountItems.Remove(accountId);
}
private async Task UpdateWarehouseItem(long accountId, short slot, AccountWarehouseItemDto dto)
{
(IDictionary<short, AccountWarehouseItemDto> items, ManagerResponseType? responseType) = await GetWarehouse(accountId);
if (responseType != ManagerResponseType.Success)
{
return;
}
if (dto == null)
{
items.Remove(slot);
return;
}
items[slot] = dto;
}
}