// 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 { 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(); 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()); } } }