306 lines
No EOL
11 KiB
C#
306 lines
No EOL
11 KiB
C#
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<ExchangeRequestPacket>
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
} |