server-master/srcs/_plugins/WingsEmu.Plugins.PacketHandling/Game/Npc/MShopPacketHandler.cs
2026-02-10 18:21:30 +01:00

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
});
}
}