215 lines
No EOL
9.2 KiB
C#
215 lines
No EOL
9.2 KiB
C#
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using PhoenixLib.Events;
|
|
using PhoenixLib.Logging;
|
|
using WingsAPI.Game.Extensions.ItemExtension.Item;
|
|
using WingsAPI.Packets.Enums;
|
|
using WingsEmu.DTOs.Maps;
|
|
using WingsEmu.Game._enum;
|
|
using WingsEmu.Game._i18n;
|
|
using WingsEmu.Game.Extensions;
|
|
using WingsEmu.Game.Managers;
|
|
using WingsEmu.Game.Managers.StaticData;
|
|
using WingsEmu.Game.Networking;
|
|
using WingsEmu.Game.Raids;
|
|
using WingsEmu.Game.Raids.Enum;
|
|
using WingsEmu.Game.Raids.Events;
|
|
using WingsEmu.Game.Relations;
|
|
using WingsEmu.Packets.Enums;
|
|
using WingsEmu.Packets.Enums.Chat;
|
|
|
|
namespace Plugin.Raids;
|
|
|
|
public class RaidPartyJoinEventHandler : IAsyncEventProcessor<RaidPartyJoinEvent>
|
|
{
|
|
private static readonly SemaphoreSlim _semaphoreSlim = new(1, 1);
|
|
private readonly IGameLanguageService _gameLanguage;
|
|
private readonly IInvitationManager _invitationManager;
|
|
private readonly IItemsManager _itemsManager;
|
|
private readonly IRaidManager _raidManager;
|
|
private readonly ISessionManager _sessionManager;
|
|
|
|
public RaidPartyJoinEventHandler(IGameLanguageService gameLanguage, ISessionManager sessionManager, IInvitationManager invitationManager, IRaidManager raidManager, IItemsManager itemsManager)
|
|
{
|
|
_gameLanguage = gameLanguage;
|
|
_sessionManager = sessionManager;
|
|
_invitationManager = invitationManager;
|
|
_raidManager = raidManager;
|
|
_itemsManager = itemsManager;
|
|
}
|
|
|
|
public async Task HandleAsync(RaidPartyJoinEvent e, CancellationToken cancellation)
|
|
{
|
|
IClientSession session = e.Sender;
|
|
long raidOwnerId = e.RaidOwnerId;
|
|
bool isByRaidList = e.IsByRaidList;
|
|
|
|
await _semaphoreSlim.WaitAsync(cancellation);
|
|
try
|
|
{
|
|
if (session.PlayerEntity.Id == raidOwnerId)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (session.IsMuted())
|
|
{
|
|
session.SendMsg(session.GetLanguage(GameDialogKey.MUTE_SHOUTMESSAGE_YOU_ARE_MUTED), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
IClientSession raidOwner = _sessionManager.GetSessionByCharacterId(raidOwnerId);
|
|
if (raidOwner?.PlayerEntity.Raid == null)
|
|
{
|
|
Log.Debug($"[ERROR] Character with ID {raidOwnerId.ToString()} was not found.");
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.IsBlocking(raidOwnerId))
|
|
{
|
|
session.SendInfo(session.GetLanguage(GameDialogKey.BLACKLIST_INFO_BLOCKING));
|
|
return;
|
|
}
|
|
|
|
if (raidOwner.PlayerEntity.IsBlocking(session.PlayerEntity.Id))
|
|
{
|
|
session.SendInfo(session.GetLanguage(GameDialogKey.BLACKLIST_INFO_BLOCKED));
|
|
return;
|
|
}
|
|
|
|
if (raidOwner.PlayerEntity.HasRaidStarted)
|
|
{
|
|
session.SendChatMessage(_gameLanguage.GetLanguage(GameDialogKey.RAID_CHATMESSAGE_NO_EXIST_OR_ALREADY_STARTED, session.UserLanguage), ChatMessageColorType.Yellow);
|
|
return;
|
|
}
|
|
|
|
if (!_invitationManager.ContainsPendingInvitation(raidOwnerId, session.PlayerEntity.Id, InvitationType.Raid) && !isByRaidList)
|
|
{
|
|
Log.Debug($"[ERROR] Character with ID {session.PlayerEntity.Id.ToString()} to join a raid, but hadn't an invitation.");
|
|
return;
|
|
}
|
|
|
|
if (!isByRaidList)
|
|
{
|
|
_invitationManager.RemovePendingInvitation(raidOwnerId, session.PlayerEntity.Id, InvitationType.Raid);
|
|
}
|
|
|
|
RaidParty raidParty = raidOwner.PlayerEntity.Raid;
|
|
if (isByRaidList && !_raidManager.ContainsRaidInRaidPublishList(raidParty))
|
|
{
|
|
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.RAID_CHATMESSAGE_NO_EXIST_OR_ALREADY_STARTED, session.UserLanguage));
|
|
await session.EmitEventAsync(new RaidListOpenEvent());
|
|
return;
|
|
}
|
|
|
|
if (!session.CurrentMapInstance.HasMapFlag(MapFlags.IS_BASE_MAP))
|
|
{
|
|
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.INFORMATION_SHOUTMESSAGE_MUST_BE_IN_CLASSIC_MAP, session.UserLanguage), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
if (raidOwner.PlayerEntity.RaidTeamIsFull)
|
|
{
|
|
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.RAID_SHOUTMESSAGE_RAID_TEAM_FULL, session.UserLanguage), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.IsInRaidParty)
|
|
{
|
|
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.RAID_SHOUTMESSAGE_ALREADY_IN_RAID, session.UserLanguage), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.TimeSpaceComponent.IsInTimeSpaceParty)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.RainbowBattleComponent.IsInRainbowBattle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.HasRaidStarted || session.PlayerEntity.HasShopOpened)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.IsInGroup())
|
|
{
|
|
session.SendMsg(_gameLanguage.GetLanguage(GameDialogKey.RAID_SHOUTMESSAGE_IN_GROUP, session.UserLanguage), MsgMessageType.Middle);
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.Level < raidParty.MinimumLevel)
|
|
{
|
|
session.SendChatMessage(_gameLanguage.GetLanguageFormat(GameDialogKey.RAID_CHATMESSAGE_LOW_LEVEL, session.UserLanguage, raidParty.MinimumLevel.ToString()), ChatMessageColorType.Red);
|
|
return;
|
|
}
|
|
|
|
if (session.PlayerEntity.HeroLevel < raidParty.MinimumHeroLevel)
|
|
{
|
|
session.SendChatMessage(_gameLanguage.GetLanguageFormat(GameDialogKey.RAID_CHATMESSAGE_LOW_LEVEL, session.UserLanguage, raidParty.MinimumHeroLevel.ToString()),
|
|
ChatMessageColorType.Red);
|
|
return;
|
|
}
|
|
|
|
if (session.IsRaidTypeRestricted(raidParty.Type))
|
|
{
|
|
if (!session.IsPlayerWearingRaidAmulet(raidParty.Type))
|
|
{
|
|
string amuletName = raidParty.Type == RaidType.LordDraco
|
|
? _itemsManager.GetItem((short)ItemVnums.DRACO_AMULET)?.GetItemName(_gameLanguage, session.UserLanguage)
|
|
: _itemsManager.GetItem((short)ItemVnums.GLACERUS_AMULET)?.GetItemName(_gameLanguage, session.UserLanguage);
|
|
|
|
session.SendChatMessage(session.GetLanguageFormat(GameDialogKey.RAID_CHATMESSAGE_AMULET_NEEDED, amuletName), ChatMessageColorType.Yellow);
|
|
return;
|
|
}
|
|
|
|
string getRaidName = session.GenerateRaidName(_gameLanguage, raidParty.Type);
|
|
if (!session.CanPlayerJoinToRestrictedRaid(raidParty.Type))
|
|
{
|
|
session.SendChatMessage(session.GetLanguageFormat(GameDialogKey.RAID_CHATMESSAGE_LIMIT_REACHED, getRaidName), ChatMessageColorType.Yellow);
|
|
return;
|
|
}
|
|
|
|
switch (raidParty.Type)
|
|
{
|
|
case RaidType.LordDraco:
|
|
session.SendChatMessage(session.GetLanguageFormat(GameDialogKey.RAID_CHATMESSAGE_LIMIT_LEFT,
|
|
getRaidName, session.PlayerEntity.RaidRestrictionDto.LordDraco), ChatMessageColorType.Yellow);
|
|
break;
|
|
case RaidType.Glacerus:
|
|
session.SendChatMessage(session.GetLanguageFormat(GameDialogKey.RAID_CHATMESSAGE_LIMIT_LEFT,
|
|
getRaidName, session.PlayerEntity.RaidRestrictionDto.Glacerus), ChatMessageColorType.Yellow);
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (session.PlayerEntity.Level > raidParty.MaximumLevel || session.PlayerEntity.HeroLevel > raidParty.MaximumHeroLevel)
|
|
{
|
|
session.SendChatMessage(_gameLanguage.GetLanguage(GameDialogKey.RAID_CHATMESSAGE_LEVEL_TOO_HIGH, session.UserLanguage), ChatMessageColorType.Yellow);
|
|
}
|
|
|
|
raidParty.AddMember(session);
|
|
session.PlayerEntity.SetRaidParty(raidParty);
|
|
|
|
raidOwner.SendRaidPacket(RaidPacketType.LIST_MEMBERS);
|
|
foreach (IClientSession member in session.PlayerEntity.Raid.Members)
|
|
{
|
|
member.SendChatMessage(_gameLanguage.GetLanguageFormat(GameDialogKey.RAID_CHATMESSAGE_X_JOINED, member.UserLanguage, session.PlayerEntity.Name), ChatMessageColorType.Yellow);
|
|
member.SendMsg(_gameLanguage.GetLanguageFormat(GameDialogKey.RAID_SHOUTMESSAGE_X_JOINED, member.UserLanguage, session.PlayerEntity.Name), MsgMessageType.Middle);
|
|
member.RefreshRaidMemberList();
|
|
}
|
|
|
|
session.SendRaidPacket(RaidPacketType.LEAVE);
|
|
session.SendRaidPacket(RaidPacketType.LEADER_RELATED);
|
|
|
|
await session.EmitEventAsync(new RaidJoinedEvent { JoinType = e.IsByRaidList ? RaidJoinType.RAID_LIST : RaidJoinType.INVITATION });
|
|
}
|
|
finally
|
|
{
|
|
_semaphoreSlim.Release();
|
|
}
|
|
}
|
|
} |