150 lines
No EOL
5.1 KiB
C#
150 lines
No EOL
5.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using WingsEmu.Game._i18n;
|
|
using WingsEmu.Game.Characters.Events;
|
|
using WingsEmu.Game.Extensions;
|
|
using WingsEmu.Game.Inventory;
|
|
using WingsEmu.Game.Networking;
|
|
using WingsEmu.Game.Shops;
|
|
using WingsEmu.Game.Shops.Event;
|
|
using WingsEmu.Packets.ClientPackets;
|
|
using WingsEmu.Packets.Enums;
|
|
using WingsEmu.Packets.Enums.Chat;
|
|
|
|
namespace WingsEmu.Plugins.PacketHandling.Game.Npc;
|
|
|
|
public class MShopPacketHandler : GenericGamePacketHandlerBase<MShopPacket>
|
|
{
|
|
private readonly IGameLanguageService _language;
|
|
|
|
public MShopPacketHandler(IGameLanguageService language) => _language = language;
|
|
|
|
protected override async Task HandlePacketAsync(IClientSession session, MShopPacket packet)
|
|
{
|
|
if (session.IsActionForbidden())
|
|
{
|
|
return;
|
|
}
|
|
|
|
switch (packet.Type)
|
|
{
|
|
case MShopPacketType.CloseShop:
|
|
await session.EmitEventAsync(new ShopPlayerCloseEvent());
|
|
break;
|
|
case MShopPacketType.OpenDialog:
|
|
session.SendPacket("ishop");
|
|
break;
|
|
|
|
case MShopPacketType.OpenShop:
|
|
await ProcessPacketStructure(session, packet.PacketData);
|
|
break;
|
|
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
|
|
private async Task ProcessPacketStructure(IClientSession session, string packet)
|
|
{
|
|
string[] packetsplit = packet.Split(' ');
|
|
|
|
if (packetsplit.Length <= 80)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!session.HasCurrentMapInstance || session.PlayerEntity.HasShopOpened || session.PlayerEntity.IsInExchange())
|
|
{
|
|
return;
|
|
}
|
|
|
|
var list = new List<ShopPlayerItem>();
|
|
const int amountPersonalShopItems = 20;
|
|
int nonNullItemsCount = 0;
|
|
|
|
for (short i = 0; i < amountPersonalShopItems; i++)
|
|
{
|
|
int packetIndexGuide = i * 4;
|
|
if (!(Enum.TryParse(packetsplit[packetIndexGuide], out InventoryType inventoryType)
|
|
&& short.TryParse(packetsplit[packetIndexGuide + 1], out short inventorySlot)
|
|
&& short.TryParse(packetsplit[packetIndexGuide + 2], out short sellAmount)
|
|
&& long.TryParse(packetsplit[packetIndexGuide + 3], out long price)))
|
|
{
|
|
list.Add(null);
|
|
continue;
|
|
}
|
|
|
|
if (inventorySlot < 0 || sellAmount < 1 || price < 1)
|
|
{
|
|
list.Add(null);
|
|
continue;
|
|
}
|
|
|
|
if (inventoryType != InventoryType.Equipment && inventoryType != InventoryType.Etc && inventoryType != InventoryType.Main)
|
|
{
|
|
await session.NotifyStrangeBehavior(StrangeBehaviorSeverity.ABUSING,
|
|
$"[PLAYER_SHOP_OPEN] Tried to add an object from a non allowed InventoryType. InventoryType: '{inventoryType.ToString()}'");
|
|
return;
|
|
}
|
|
|
|
InventoryItem inv = session.PlayerEntity.GetItemBySlotAndType(inventorySlot, inventoryType);
|
|
if (inv == null || inv.ItemInstance.Amount < sellAmount)
|
|
{
|
|
await session.NotifyStrangeBehavior(StrangeBehaviorSeverity.ABUSING, "[PLAYER_SHOP_OPEN] Tried to add a nonexistent object.");
|
|
return;
|
|
}
|
|
|
|
if (!inv.ItemInstance.GameItem.IsTradable || inv.ItemInstance.IsBound)
|
|
{
|
|
session.SendChatMessage(_language.GetLanguage(GameDialogKey.SHOP_CHATMESSAGE_ONLY_TRADABLE_ITEMS, session.UserLanguage), ChatMessageColorType.Yellow);
|
|
session.SendShopEndPacket(ShopEndType.Player);
|
|
return;
|
|
}
|
|
|
|
list.Add(new ShopPlayerItem
|
|
{
|
|
ShopSlot = i,
|
|
PricePerUnit = price,
|
|
InventoryItem = inv,
|
|
SellAmount = sellAmount
|
|
});
|
|
nonNullItemsCount++;
|
|
}
|
|
|
|
if (nonNullItemsCount < 1)
|
|
{
|
|
session.SendShopEndPacket(ShopEndType.Player);
|
|
session.SendChatMessage(_language.GetLanguage(GameDialogKey.SHOP_CHATMESSAGE_EMPTY, session.UserLanguage), ChatMessageColorType.Yellow);
|
|
return;
|
|
}
|
|
|
|
var shopNameBuilder = new StringBuilder();
|
|
|
|
const int maxShopNameLength = 20;
|
|
for (int j = 80; j < packetsplit.Length; j++)
|
|
{
|
|
if (maxShopNameLength < shopNameBuilder.Length)
|
|
{
|
|
break;
|
|
}
|
|
|
|
shopNameBuilder.Append(packetsplit[j]);
|
|
shopNameBuilder.Append(' ');
|
|
}
|
|
|
|
string shopName = shopNameBuilder.ToString(0, maxShopNameLength < shopNameBuilder.Length ? maxShopNameLength : shopNameBuilder.Length);
|
|
|
|
if (string.IsNullOrWhiteSpace(shopName) || string.IsNullOrEmpty(shopName))
|
|
{
|
|
shopName = _language.GetLanguageFormat(GameDialogKey.SHOP_DEFAULT_NAME, session.UserLanguage, session.PlayerEntity.Name);
|
|
}
|
|
|
|
await session.EmitEventAsync(new ShopPlayerOpenEvent
|
|
{
|
|
Items = list,
|
|
ShopTitle = shopName
|
|
});
|
|
}
|
|
} |