using System; using System.Threading.Tasks; using WingsAPI.Game.Extensions.ItemExtension.Inventory; using WingsAPI.Game.Extensions.PacketGeneration; using WingsAPI.Packets.Enums; using WingsEmu.DTOs.Maps; using WingsEmu.Game._i18n; using WingsEmu.Game.Characters.Events; using WingsEmu.Game.Exchange; using WingsEmu.Game.Exchange.Event; using WingsEmu.Game.Extensions; using WingsEmu.Game.Managers; using WingsEmu.Game.Maps; using WingsEmu.Game.Networking; using WingsEmu.Game.Relations; using WingsEmu.Packets.ClientPackets; using WingsEmu.Packets.Enums; using WingsEmu.Packets.Enums.Chat; namespace WingsEmu.Plugins.PacketHandling.Game.Inventory; public class ExchangeRequestPacketHandler : GenericGamePacketHandlerBase { private readonly IInvitationManager _invitation; private readonly IGameLanguageService _language; private readonly IServerManager _serverManager; public ExchangeRequestPacketHandler(IServerManager serverManager, IGameLanguageService language, IInvitationManager invitation) { _invitation = invitation; _serverManager = serverManager; _language = language; } protected override async Task HandlePacketAsync(IClientSession session, ExchangeRequestPacket exchangeRequestPacket) { long targetId = exchangeRequestPacket.CharacterId; RequestExchangeType requestType = exchangeRequestPacket.RequestType; if (!session.HasCurrentMapInstance || !session.HasSelectedCharacter) { return; } if (session.IsActionForbidden()) { return; } if (!session.CurrentMapInstance.HasMapFlag(MapFlags.IS_BASE_MAP) && session.CurrentMapInstance.MapInstanceType != MapInstanceType.Miniland) { return; } IClientSession target; switch (requestType) { case RequestExchangeType.Requested: if (session.PlayerEntity.Id == targetId) { return; } target = session.CurrentMapInstance.GetCharacterById(targetId)?.Session; if (target == null) { return; } if (target.IsActionForbidden()) { return; } if (session.CurrentMapInstance.Id != target.CurrentMapInstance.Id) { return; } if (session.CurrentMapInstance.HasMapFlag(MapFlags.ACT_4)) { if (target.PlayerEntity.Faction != session.PlayerEntity.Faction) { return; } } if (target.PlayerEntity.HasRaidStarted) { session.SendMsg(_language.GetLanguage(GameDialogKey.TRADE_SHOUTMESSAGE_NOT_ALLOWED_IN_RAID, session.UserLanguage), MsgMessageType.Middle); return; } if (session.PlayerEntity.HasRaidStarted) { session.SendMsg(_language.GetLanguage(GameDialogKey.TRADE_SHOUTMESSAGE_NOT_ALLOWED_WITH_RAID_MEMBER, session.UserLanguage), MsgMessageType.Middle); return; } if (session.PlayerEntity.IsBlocking(targetId)) { session.SendInfo(_language.GetLanguage(GameDialogKey.BLACKLIST_INFO_BLOCKING, session.UserLanguage)); return; } if (target.PlayerEntity.IsBlocking(session.PlayerEntity.Id)) { session.SendInfo(_language.GetLanguage(GameDialogKey.BLACKLIST_INFO_BLOCKED, session.UserLanguage)); return; } if (session.PlayerEntity.IsInExchange()) { session.SendModal(_language.GetLanguage(GameDialogKey.TRADE_MODAL_ALREADY_IN_EXCHANGE, session.UserLanguage), ModalType.Cancel); return; } if (target.PlayerEntity.IsInExchange()) { session.SendModal(_language.GetLanguage(GameDialogKey.TRADE_MODAL_ALREADY_IN_EXCHANGE, session.UserLanguage), ModalType.Cancel); return; } if (target.PlayerEntity.LastSkillUse.AddSeconds(10) > DateTime.UtcNow || target.PlayerEntity.LastDefence.AddSeconds(10) > DateTime.UtcNow) { session.SendInfo(_language.GetLanguageFormat(GameDialogKey.INFORMATION_INFO_PLAYER_IN_BATTLE, session.UserLanguage, target.PlayerEntity.Name)); return; } if (session.PlayerEntity.LastSkillUse.AddSeconds(10) > DateTime.UtcNow || session.PlayerEntity.LastDefence.AddSeconds(10) > DateTime.UtcNow) { session.SendInfo(_language.GetLanguage(GameDialogKey.TRADE_INFO_PLAYER_IN_BATTLE, session.UserLanguage)); return; } if (session.PlayerEntity.HasShopOpened || target.PlayerEntity.HasShopOpened) { session.SendMsg(_language.GetLanguage(GameDialogKey.TRADE_SHOUTMESSAGE_HAS_SHOP_OPEN, session.UserLanguage), MsgMessageType.Middle); return; } if (target.PlayerEntity.ExchangeBlocked) { session.SendChatMessage(_language.GetLanguage(GameDialogKey.TRADE_CHATMESSAGE_BLOCKED, session.UserLanguage), ChatMessageColorType.Red); return; } session.SendModal(_language.GetLanguageFormat(GameDialogKey.TRADE_DIALOG_ASK_FOR_TRADE, session.UserLanguage, target.PlayerEntity.Name), ModalType.Cancel); await session.EmitEventAsync(new InvitationEvent(targetId, InvitationType.Exchange)); break; case RequestExchangeType.Confirmed: PlayerExchange exchange = session.PlayerEntity.GetExchange(); if (exchange == null) { return; } target = session.CurrentMapInstance.GetCharacterById(exchange.TargetId)?.Session; PlayerExchange targetExchange = target?.PlayerEntity.GetExchange(); if (targetExchange == null) { return; } if (session.PlayerEntity.HasRaidStarted) { session.SendMsg(_language.GetLanguage(GameDialogKey.TRADE_SHOUTMESSAGE_NOT_ALLOWED_IN_RAID, session.UserLanguage), MsgMessageType.Middle); return; } if (target.PlayerEntity.HasRaidStarted) { session.SendMsg(_language.GetLanguage(GameDialogKey.TRADE_SHOUTMESSAGE_NOT_ALLOWED_WITH_RAID_MEMBER, session.UserLanguage), MsgMessageType.Middle); return; } if (session.IsDisposing || target.IsDisposing) { await session.CloseExchange(); return; } if (!exchange.RegisteredItems || !targetExchange.RegisteredItems) { return; } if (!exchange.AcceptedTrade) { exchange.AcceptedTrade = true; } if (exchange.AcceptedTrade && !targetExchange.AcceptedTrade) { session.SendInfo(_language.GetLanguageFormat(GameDialogKey.TRADE_INFO_WAITING_FOR_TARGET, session.UserLanguage, target.PlayerEntity.Name)); return; } await session.EmitEventAsync(new ExchangeTransferItemsEvent { Target = target, SenderGold = exchange.Gold, SenderBankGold = exchange.BankGold, SenderItems = exchange.Items, TargetItems = targetExchange.Items, TargetGold = targetExchange.Gold, TargetBankGold = targetExchange.BankGold }); break; case RequestExchangeType.Cancelled: if (!session.PlayerEntity.IsInExchange()) { return; } PlayerExchange playerExchange = session.PlayerEntity.GetExchange(); if (playerExchange == null) { return; } target = session.CurrentMapInstance.GetCharacterById(playerExchange.TargetId)?.Session; if (target == null) { return; } await session.CloseExchange(); break; case RequestExchangeType.AcceptExchangeInvitation: if (session.PlayerEntity.Id == targetId) { return; } target = session.CurrentMapInstance.GetCharacterById(targetId)?.Session; if (target == null) { return; } if (session.CurrentMapInstance.Id != target.CurrentMapInstance.Id) { return; } if (!_invitation.ContainsPendingInvitation(targetId, session.PlayerEntity.Id, InvitationType.Exchange)) { return; } if (session.PlayerEntity.IsInExchange()) { return; } if (target.PlayerEntity.IsInExchange()) { session.SendModal(_language.GetLanguage(GameDialogKey.TRADE_MODAL_ALREADY_IN_EXCHANGE, session.UserLanguage), ModalType.Cancel); return; } _invitation.RemovePendingInvitation(targetId, session.PlayerEntity.Id, InvitationType.Exchange); await session.EmitEventAsync(new ExchangeJoinEvent { Target = target }); break; case RequestExchangeType.Declined: if (session.PlayerEntity.Id == targetId) { return; } target = session.CurrentMapInstance.GetCharacterById(targetId)?.Session; if (target == null) { return; } if (session.CurrentMapInstance.Id != target.CurrentMapInstance.Id) { return; } if (!_invitation.ContainsPendingInvitation(targetId, session.PlayerEntity.Id, InvitationType.Exchange)) { return; } _invitation.RemovePendingInvitation(targetId, session.PlayerEntity.Id, InvitationType.Exchange); target.SendChatMessage(_language.GetLanguageFormat(GameDialogKey.TRADE_CHATMESSAGE_REFUSED, target.UserLanguage, session.PlayerEntity.Name), ChatMessageColorType.Yellow); session.SendChatMessage(_language.GetLanguage(GameDialogKey.TRADE_CHATMESSAGE_YOU_REFUSED, session.UserLanguage), ChatMessageColorType.Yellow); break; } } }