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

217 lines
No EOL
7.8 KiB
C#

// WingsEmu
//
// Developed by NosWings Team
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using PhoenixLib.Events;
using WingsAPI.Communication.Families;
using WingsAPI.Data.Families;
using WingsAPI.Game.Extensions.Families;
using WingsAPI.Game.Extensions.ItemExtension.Inventory;
using WingsEmu.DTOs.Maps;
using WingsEmu.Game;
using WingsEmu.Game._i18n;
using WingsEmu.Game.Characters;
using WingsEmu.Game.Characters.Events;
using WingsEmu.Game.Extensions;
using WingsEmu.Game.Families;
using WingsEmu.Game.Families.Configuration;
using WingsEmu.Game.Families.Event;
using WingsEmu.Game.Groups;
using WingsEmu.Game.Managers;
using WingsEmu.Game.Networking;
using WingsEmu.Packets.Enums;
using WingsEmu.Packets.Enums.Families;
namespace Plugin.FamilyImpl
{
public class FamilyCreateEventHandler : IAsyncEventProcessor<FamilyCreateEvent>
{
private readonly IForbiddenNamesManager _bannedNamesConfiguration;
private readonly FamilyConfiguration _familyConfiguration;
private readonly IFamilyManager _familyManager;
private readonly IFamilyService _familyService;
private readonly IGameLanguageService _gameLanguage;
private readonly IRandomGenerator _randomGenerator;
private readonly ISessionManager _sessionManager;
public FamilyCreateEventHandler(IFamilyService familyService, IGameLanguageService gameLanguage, FamilyConfiguration familyConfiguration,
ISessionManager sessionManager, IFamilyManager familyManager, IRandomGenerator randomGenerator, IForbiddenNamesManager bannedNamesConfiguration)
{
_familyService = familyService;
_gameLanguage = gameLanguage;
_familyConfiguration = familyConfiguration;
_sessionManager = sessionManager;
_familyManager = familyManager;
_randomGenerator = randomGenerator;
_bannedNamesConfiguration = bannedNamesConfiguration;
}
public async Task HandleAsync(FamilyCreateEvent e, CancellationToken cancellation)
{
IClientSession session = e.Sender;
if (!session.CurrentMapInstance.HasMapFlag(MapFlags.IS_BASE_MAP))
{
return;
}
if (session.CantPerformActionOnAct4())
{
return;
}
if (session.PlayerEntity.IsInRaidParty)
{
return;
}
if (session.PlayerEntity.IsInFamily())
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_ALREADY_IN_FAMILY, session.UserLanguage));
return;
}
if (!session.HasEnoughGold(_familyConfiguration.CreationPrice))
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.INTERACTION_MESSAGE_NOT_ENOUGH_GOLD, session.UserLanguage));
return;
}
int nameLength = e.Name.Length;
if (nameLength < _familyConfiguration.MinimumNameLength || nameLength > _familyConfiguration.MaximumNameLength)
{
return;
}
PlayerGroup playerGroup = session.PlayerEntity.GetGroup();
if (session.PlayerEntity.IsInGroup())
{
if (playerGroup.Members.Any(x => x.IsInFamily()))
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_CREATION_SOMEONE_ALREADY_IN_FAMILY, session.UserLanguage));
return;
}
if (playerGroup.Members.Count < _familyConfiguration.CreationGroupMembersRequired)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_GROUP_NOT_FULL, session.UserLanguage));
return;
}
}
else if (_familyConfiguration.CreationIsGroupRequired)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_CREATION_GROUP_REQUIRED, session.UserLanguage));
return;
}
var regex = new Regex(@"^[a-zA-Z0-9_\-\*]*$");
if (regex.Matches(e.Name).Count != 1)
{
return;
}
string lowerName = e.Name.ToLowerInvariant();
if (_bannedNamesConfiguration.IsBanned(lowerName, out string bannedName))
{
session.SendInfo(_gameLanguage.GetLanguageFormat(GameDialogKey.FAMILY_INFO_CREATION_BANNED_NAME, session.UserLanguage, bannedName));
return;
}
var membersList = new List<FamilyMembershipDto>();
DateTime now = DateTime.UtcNow;
if (session.PlayerEntity.IsInGroup())
{
foreach (IPlayerEntity member in playerGroup.Members)
{
if (member.Id == session.PlayerEntity.Id)
{
continue;
}
membersList.Add(new FamilyMembershipDto
{
CharacterId = member.Id,
Authority = FamilyAuthority.Deputy,
DailyMessage = null,
Experience = 0,
Title = FamilyTitle.Nothing,
JoinDate = now
});
}
}
membersList.Add(new FamilyMembershipDto
{
CharacterId = session.PlayerEntity.Id,
Authority = FamilyAuthority.Head,
DailyMessage = null,
Experience = 0,
Title = FamilyTitle.Nothing,
JoinDate = now
});
FamilyCreateResponse response = await _familyService.CreateFamilyAsync(new FamilyCreateRequest
{
Name = e.Name,
Level = 1,
MembershipCapacity = _familyConfiguration.DefaultMembershipCapacity,
Faction = (byte)_randomGenerator.RandomNumber(1, 3),
Members = membersList
});
if (response.Status == FamilyCreateResponseType.NAME_ALREADY_TAKEN)
{
session.SendInfo(_gameLanguage.GetLanguage(GameDialogKey.FAMILY_INFO_NAME_ALREADY_USED, session.UserLanguage));
return;
}
FamilyDTO familyDto = response.Family;
_familyManager.AddFamily(response.Family, membersList);
IFamily family = null;
foreach (FamilyMembershipDto member in membersList)
{
member.FamilyId = familyDto.Id;
_familyManager.AddOrReplaceMember(member);
IClientSession localSession = _sessionManager.GetSessionByCharacterId(member.CharacterId);
if (localSession == null)
{
continue;
}
family ??= localSession.PlayerEntity.Family;
if (localSession.PlayerEntity.Faction != (FactionType)family.Faction)
{
await localSession.EmitEventAsync(new ChangeFactionEvent
{
NewFaction = (FactionType)familyDto.Faction
});
}
localSession.BroadcastGidx(family, _gameLanguage);
}
if (family == null)
{
return;
}
FamilyPacketExtensions.SendFamilyMembersInfoToMembers(family, _sessionManager, _familyConfiguration);
family.SendFmiPacket(_sessionManager);
session.PlayerEntity.RemoveGold(_familyConfiguration.CreationPrice);
session.EmitEvent(new FamilyCreatedEvent());
}
}
}