server-master/srcs/_plugins/Plugin.FamilyImpl/FamilyChangeAuthorityEventHandler.cs
2026-02-10 18:21:30 +01:00

236 lines
No EOL
9.4 KiB
C#

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using PhoenixLib.Events;
using PhoenixLib.Logging;
using WingsAPI.Communication;
using WingsAPI.Communication.DbServer.CharacterService;
using WingsAPI.Communication.Families;
using WingsAPI.Data.Character;
using WingsAPI.Game.Extensions.Families;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Families;
using WingsEmu.Game.Families.Configuration;
using WingsEmu.Game.Families.Event;
using WingsEmu.Game.Managers;
using WingsEmu.Game.Networking;
using WingsEmu.Packets.Enums.Families;
namespace Plugin.FamilyImpl
{
public class FamilyChangeAuthorityEventHandler : IAsyncEventProcessor<FamilyChangeAuthorityEvent>
{
private readonly ICharacterService _characterService;
private readonly FamilyConfiguration _familyConfiguration;
private readonly IFamilyService _familyService;
private readonly IGameLanguageService _gameLanguage;
private readonly ISessionManager _sessionManager;
public FamilyChangeAuthorityEventHandler(IGameLanguageService gameLanguage, FamilyConfiguration familyConfiguration, IFamilyService familyService, ISessionManager sessionManager,
ICharacterService characterService)
{
_gameLanguage = gameLanguage;
_familyConfiguration = familyConfiguration;
_familyService = familyService;
_sessionManager = sessionManager;
_characterService = characterService;
}
public async Task HandleAsync(FamilyChangeAuthorityEvent e, CancellationToken cancellation)
{
IClientSession session = e.Sender;
IFamily sessionFamily = session.PlayerEntity.Family;
long memberId = e.MemberId;
if (sessionFamily == null)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_NO_FAMILY, session.UserLanguage));
return;
}
FamilyAuthority senderAuthority = session.PlayerEntity.GetFamilyAuthority();
if (senderAuthority != FamilyAuthority.Head && senderAuthority != FamilyAuthority.Deputy)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_NO_FAMILY_RIGHT, session.UserLanguage));
return;
}
if (senderAuthority > e.FamilyAuthority)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_NO_FAMILY_RIGHT, session.UserLanguage));
return;
}
string memberName = e.CharacterName;
if (!string.IsNullOrEmpty(memberName))
{
IClientSession target = _sessionManager.GetSessionByCharacterName(memberName);
if (target == null)
{
DbServerGetCharacterResponse characterResponse = null;
try
{
characterResponse = await _characterService.GetCharacterByName(new DbServerGetCharacterRequestByName
{
CharacterName = memberName
});
}
catch (Exception ex)
{
Log.Error("[FAMILY_CHANGE_AUTHORITY] Unexpected error: ", ex);
}
if (characterResponse?.RpcResponseType != RpcResponseType.SUCCESS)
{
return;
}
CharacterDTO targetCharacter = characterResponse.CharacterDto;
memberId = targetCharacter.Id;
}
else
{
memberId = target.PlayerEntity.Id;
}
}
if (senderAuthority == FamilyAuthority.Head && e.FamilyAuthority == senderAuthority)
{
if (e.Confirmed != 1)
{
e.Sender.SendQnaPacket($"fmg {((int)e.FamilyAuthority).ToString()} {memberId.ToString()} 1",
_gameLanguage.GetLanguage(GameDialogKey.FAMILY_DIALOG_CHANGE_HEAD, session.UserLanguage));
return;
}
}
bool validAction = false;
int numberOfDeputies = 0;
int numberOfAssistants = 0;
foreach (FamilyMembership member in sessionFamily.Members.ToArray())
{
switch (member.Authority)
{
case FamilyAuthority.Deputy:
numberOfDeputies++;
break;
case FamilyAuthority.Keeper:
numberOfAssistants++;
break;
}
if (member.CharacterId != memberId)
{
continue;
}
if (memberId == session.PlayerEntity.Id)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_DIALOG_CANNOT_CHANGE_YOUR_OWN_AUTHORITY, session.UserLanguage));
break;
}
if (member.Authority == e.FamilyAuthority)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_DIALOG_ALREADY_HAS_THAT_AUTHORITY, session.UserLanguage));
break;
}
if (senderAuthority > member.Authority)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_NO_FAMILY_RIGHT, session.UserLanguage));
break;
}
if (member.Authority == senderAuthority || senderAuthority == e.FamilyAuthority && senderAuthority != FamilyAuthority.Head)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_CANT_GIVE_SAME_AUTHORITY, session.UserLanguage));
break;
}
if (senderAuthority != FamilyAuthority.Head && e.FamilyAuthority < senderAuthority)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_NO_FAMILY_RIGHT, session.UserLanguage));
break;
}
if (senderAuthority == FamilyAuthority.Head && e.FamilyAuthority == senderAuthority)
{
if (member.Authority != FamilyAuthority.Deputy)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_TARGET_NEEDS_TO_BE_DEPUTY, session.UserLanguage));
break;
}
}
validAction = true;
memberName = member.Character?.Name;
}
if (!validAction)
{
return;
}
switch (e.FamilyAuthority)
{
case FamilyAuthority.Deputy when _familyConfiguration.DeputyLimit <= numberOfDeputies:
e.Sender.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_DEPUTIES_LIMIT_REACHED, e.Sender.UserLanguage));
return;
case FamilyAuthority.Keeper when _familyConfiguration.KeeperLimit <= numberOfAssistants:
e.Sender.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_KEEPER_LIMIT_REACHED, e.Sender.UserLanguage));
return;
default:
DbServerGetCharacterResponse characterResponse = null;
try
{
characterResponse = await _characterService.GetCharacterById(new DbServerGetCharacterByIdRequest
{
CharacterId = e.MemberId
});
}
catch (Exception ex)
{
Log.Error("[FAMILY_CHANGE_AUTHORITY] Unexpected error: ", ex);
}
if (characterResponse?.RpcResponseType == RpcResponseType.SUCCESS)
{
memberName ??= characterResponse.CharacterDto.Name;
}
var list = new List<FamilyChangeContainer>();
if (e.FamilyAuthority == FamilyAuthority.Head)
{
list.Add(new FamilyChangeContainer
{
CharacterId = session.PlayerEntity.Id,
RequestedFamilyAuthority = FamilyAuthority.Deputy
});
await session.FamilyAddLogAsync(FamilyLogType.AuthorityChanged, session.PlayerEntity.Name, ((byte)FamilyAuthority.Deputy).ToString(), session.PlayerEntity.Name);
}
list.Add(new FamilyChangeContainer
{
CharacterId = memberId,
RequestedFamilyAuthority = e.FamilyAuthority
});
await session.FamilyAddLogAsync(FamilyLogType.AuthorityChanged, session.PlayerEntity.Name, ((byte)e.FamilyAuthority).ToString(), memberName);
await _familyService.ChangeAuthorityByIdAsync(new FamilyChangeAuthorityRequest
{
FamilyMembers = list
});
break;
}
}
}
}