server-master/srcs/Plugin.RainbowBattle/EventHandlers/RainbowBattleEndEventHandler.cs
2026-02-10 18:21:30 +01:00

274 lines
No EOL
12 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using PhoenixLib.DAL.Redis.Locks;
using PhoenixLib.Events;
using Plugin.FamilyImpl.Achievements;
using WingsAPI.Game.Extensions.ItemExtension.Inventory;
using WingsAPI.Packets.Enums;
using WingsAPI.Packets.Enums.Rainbow;
using WingsEmu.Game._enum;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Characters.Events;
using WingsEmu.Game.Configurations;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Families;
using WingsEmu.Game.Items;
using WingsEmu.Game.Networking;
using WingsEmu.Game.Raids;
using WingsEmu.Game.RainbowBattle;
using WingsEmu.Game.RainbowBattle.Event;
using WingsEmu.Packets.Enums.Chat;
namespace Plugin.RainbowBattle.EventHandlers
{
public class RainbowBattleEndEventHandler : IAsyncEventProcessor<RainbowBattleEndEvent>
{
private readonly IExpirableLockService _expirableLockService;
private readonly IFamilyAchievementManager _familyAchievementManager;
private readonly IFamilyMissionManager _familyMissionManager;
private readonly IGameItemInstanceFactory _gameItemInstanceFactory;
private readonly RainbowBattleConfiguration _rainbowBattleConfiguration;
public RainbowBattleEndEventHandler(IFamilyMissionManager familyMissionManager, RainbowBattleConfiguration rainbowBattleConfiguration,
IGameItemInstanceFactory gameItemInstanceFactory, IFamilyAchievementManager familyAchievementManager, IExpirableLockService expirableLockService)
{
_familyMissionManager = familyMissionManager;
_rainbowBattleConfiguration = rainbowBattleConfiguration;
_gameItemInstanceFactory = gameItemInstanceFactory;
_familyAchievementManager = familyAchievementManager;
_expirableLockService = expirableLockService;
}
public async Task HandleAsync(RainbowBattleEndEvent e, CancellationToken cancellation)
{
RainbowBattleParty rainbowBattleParty = e.RainbowBattleParty;
rainbowBattleParty.FinishTime = DateTime.UtcNow.AddSeconds(15);
RainbowBattleTeamType? winnerTeam = null;
if (rainbowBattleParty.BluePoints > rainbowBattleParty.RedPoints)
{
winnerTeam = RainbowBattleTeamType.Blue;
}
else if (rainbowBattleParty.RedPoints > rainbowBattleParty.BluePoints)
{
winnerTeam = RainbowBattleTeamType.Red;
}
switch (winnerTeam)
{
case RainbowBattleTeamType.Red:
await ProcessWin(rainbowBattleParty, RainbowBattleTeamType.Red);
await ProcessLose(rainbowBattleParty, RainbowBattleTeamType.Blue);
IClientSession redDummy = rainbowBattleParty.RedTeam.FirstOrDefault();
if (redDummy != null)
{
await redDummy.EmitEventAsync(new RainbowBattleWonEvent
{
Id = rainbowBattleParty.Id,
Players = rainbowBattleParty.RedTeam.Select(x => x.PlayerEntity.Id).ToArray()
});
}
IClientSession blueDummy = rainbowBattleParty.BlueTeam.FirstOrDefault();
if (blueDummy != null)
{
await blueDummy.EmitEventAsync(new RainbowBattleLoseEvent
{
Id = rainbowBattleParty.Id,
Players = rainbowBattleParty.BlueTeam.Select(x => x.PlayerEntity.Id).ToArray()
});
}
return;
case RainbowBattleTeamType.Blue:
await ProcessWin(rainbowBattleParty, RainbowBattleTeamType.Blue);
await ProcessLose(rainbowBattleParty, RainbowBattleTeamType.Red);
redDummy = rainbowBattleParty.RedTeam.FirstOrDefault();
if (redDummy != null)
{
await redDummy.EmitEventAsync(new RainbowBattleLoseEvent
{
Players = rainbowBattleParty.RedTeam.Select(x => x.PlayerEntity.Id).ToArray()
});
}
blueDummy = rainbowBattleParty.BlueTeam.FirstOrDefault();
if (blueDummy != null)
{
await blueDummy.EmitEventAsync(new RainbowBattleWonEvent
{
Players = rainbowBattleParty.BlueTeam.Select(x => x.PlayerEntity.Id).ToArray()
});
}
return;
case null:
await ProcessLose(rainbowBattleParty, RainbowBattleTeamType.Blue);
await ProcessLose(rainbowBattleParty, RainbowBattleTeamType.Red);
IClientSession dummy = rainbowBattleParty.RedTeam.FirstOrDefault();
if (dummy != null)
{
await dummy.EmitEventAsync(new RainbowBattleTieEvent
{
RedTeam = rainbowBattleParty.RedTeam.Select(x => x.PlayerEntity.Id).ToArray(),
BlueTeam = rainbowBattleParty.BlueTeam.Select(x => x.PlayerEntity.Id).ToArray()
});
}
return;
}
}
private async Task ProcessWin(RainbowBattleParty rainbowBattleParty, RainbowBattleTeamType team)
{
IReadOnlyList<IClientSession> members = team == RainbowBattleTeamType.Red ? rainbowBattleParty.RedTeam : rainbowBattleParty.BlueTeam;
string removeClock = RainbowBattleExtensions.GenerateRainbowTime(RainbowTimeType.End);
short neededPoints = _rainbowBattleConfiguration.NeededActivityPoints;
foreach (IClientSession member in members)
{
member.SendMsg(member.GetLanguage(GameDialogKey.RAINBOW_BATTLE_MESSAGE_YOU_WON), MsgMessageType.Middle);
member.SendChatMessage(member.GetLanguage(GameDialogKey.RAINBOW_BATTLE_MESSAGE_YOU_WON), ChatMessageColorType.Yellow);
member.SendEmptyRaidBoss();
member.SendPacket(removeClock);
if (member.PlayerEntity.RainbowBattleComponent.ActivityPoints < neededPoints)
{
member.SendChatMessage(member.GetLanguage(GameDialogKey.RAINBOW_BATTLE_CHATMESSAGE_NOT_ENOUGH_ACTIVITY_POINTS), ChatMessageColorType.Red);
continue;
}
if (member.PlayerEntity.RainbowBattleLeaverBusterDto is { RewardPenalty: > 0 })
{
member.PlayerEntity.RainbowBattleLeaverBusterDto.RewardPenalty -= 1;
if (member.PlayerEntity.RainbowBattleLeaverBusterDto.RewardPenalty == 0)
{
member.SendChatMessageNoPlayer(member.GetLanguage(GameDialogKey.RAINBOW_BATTLE_CHATMESSAGE_PENALTY_NEXT_REWARD), ChatMessageColorType.IntenseRed);
}
else
{
member.SendChatMessageNoPlayer(member.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_CHATMESSAGE_PENALTY_LEFT,
member.PlayerEntity.RainbowBattleLeaverBusterDto.RewardPenalty), ChatMessageColorType.IntenseRed);
}
continue;
}
await ProcessCoins(member, true);
await member.EmitEventAsync(new GenerateReputationEvent
{
Amount = _rainbowBattleConfiguration.ReputationMultiplier * member.PlayerEntity.Level,
SendMessage = true
});
ProcessFamilyWinMission(member);
await ProcessFamilyAchievement(member, true);
ProcessFamilyMission(member);
}
}
private async Task ProcessLose(RainbowBattleParty rainbowBattleParty, RainbowBattleTeamType team)
{
IReadOnlyList<IClientSession> members = team == RainbowBattleTeamType.Red ? rainbowBattleParty.RedTeam : rainbowBattleParty.BlueTeam;
string removeClock = RainbowBattleExtensions.GenerateRainbowTime(RainbowTimeType.End);
short neededPoints = _rainbowBattleConfiguration.NeededActivityPoints;
foreach (IClientSession member in members)
{
member.SendMsg(member.GetLanguage(GameDialogKey.RAINBOW_BATTLE_MESSAGE_YOU_LOSE), MsgMessageType.Middle);
member.SendChatMessage(member.GetLanguage(GameDialogKey.RAINBOW_BATTLE_MESSAGE_YOU_LOSE), ChatMessageColorType.Yellow);
member.SendRaidUiPacket(RaidType.Cuby, RaidWindowType.MISSION_FAIL);
member.SendPacket(removeClock);
if (member.PlayerEntity.RainbowBattleComponent.ActivityPoints < neededPoints)
{
member.SendChatMessage(member.GetLanguage(GameDialogKey.RAINBOW_BATTLE_CHATMESSAGE_NOT_ENOUGH_ACTIVITY_POINTS), ChatMessageColorType.Red);
continue;
}
if (member.PlayerEntity.RainbowBattleLeaverBusterDto is { RewardPenalty: > 0 })
{
member.PlayerEntity.RainbowBattleLeaverBusterDto.RewardPenalty -= 1;
if (member.PlayerEntity.RainbowBattleLeaverBusterDto.RewardPenalty == 0)
{
member.SendChatMessageNoPlayer(member.GetLanguage(GameDialogKey.RAINBOW_BATTLE_CHATMESSAGE_PENALTY_NEXT_REWARD), ChatMessageColorType.IntenseRed);
}
else
{
member.SendChatMessageNoPlayer(member.GetLanguageFormat(GameDialogKey.RAINBOW_BATTLE_CHATMESSAGE_PENALTY_LEFT,
member.PlayerEntity.RainbowBattleLeaverBusterDto.RewardPenalty), ChatMessageColorType.IntenseRed);
}
continue;
}
await ProcessCoins(member, false);
await ProcessFamilyAchievement(member, false);
ProcessFamilyMission(member);
}
}
private async Task ProcessFamilyAchievement(IClientSession session, bool isWin)
{
if (!session.PlayerEntity.IsInFamily())
{
return;
}
IFamily family = session.PlayerEntity.Family;
if (await _expirableLockService.TryAddTemporaryLockAsync($"game:locks:family:rainbowbattle:character:{session.PlayerEntity.Id}", DateTime.UtcNow.Date.AddDays(1)))
{
_familyAchievementManager.IncrementFamilyAchievement(family.Id, (short)FamilyAchievementsVnum.COMPLETE_10_RAINBOW_BATTLE);
}
if (!isWin)
{
return;
}
if (!await _expirableLockService.TryAddTemporaryLockAsync($"game:locks:family:rainbowbattle-win:character:{session.PlayerEntity.Id}", DateTime.UtcNow.Date.AddDays(1)))
{
return;
}
_familyAchievementManager.IncrementFamilyAchievement(family.Id, (short)FamilyAchievementsVnum.WIN_5_RAINBOW_BATTLE);
}
private async Task ProcessCoins(IClientSession session, bool isWinner)
{
GameItemInstance coin = _gameItemInstanceFactory.CreateItem((short)ItemVnums.RAINBOW_COIN, isWinner ? 3 : 1);
await session.AddNewItemToInventory(coin, true, sendGiftIsFull: true);
}
private void ProcessFamilyMission(IClientSession session)
{
if (!session.PlayerEntity.IsInFamily())
{
return;
}
_familyMissionManager.IncrementFamilyMission(session.PlayerEntity.Family.Id, session.PlayerEntity.Id, (int)FamilyMissionVnums.DAILY_COMPLETE_10_RAINBOW_BATTLE);
}
private void ProcessFamilyWinMission(IClientSession session)
{
if (!session.PlayerEntity.IsInFamily())
{
return;
}
_familyMissionManager.IncrementFamilyMission(session.PlayerEntity.Family.Id, session.PlayerEntity.Id, (int)FamilyMissionVnums.DAILY_WIN_5_RAINBOW_BATTLE);
}
}
}