// WingsEmu // // Developed by NosWings Team using System; using System.Threading.Tasks; using PhoenixLib.Logging; using WingsAPI.Communication; using WingsAPI.Communication.DbServer.AccountService; using WingsAPI.Communication.Sessions; using WingsAPI.Communication.Sessions.Model; using WingsAPI.Communication.Sessions.Request; using WingsAPI.Communication.Sessions.Response; using WingsAPI.Data.Account; using WingsAPI.Game.Extensions.PacketGeneration; using WingsEmu.DTOs.Account; using WingsEmu.Game; using WingsEmu.Game.Characters.Events; using WingsEmu.Game.Managers; using WingsEmu.Game.Networking; using WingsEmu.Health; using WingsEmu.Packets.ClientPackets; using WingsEmu.Packets.Enums; namespace WingsEmu.Plugins.PacketHandling.CharScreen; public class CrossServerEntryPointPacketHandler : GenericCharScreenPacketHandlerBase { private readonly IAccountService _accountService; private readonly IMaintenanceManager _maintenanceManager; private readonly IServerManager _serverManager; private readonly ISessionService _sessionService; public CrossServerEntryPointPacketHandler(IServerManager serverManager, ISessionService sessionService, IMaintenanceManager maintenanceManager, IAccountService accountService) { _sessionService = sessionService; _maintenanceManager = maintenanceManager; _accountService = accountService; _serverManager = serverManager; } protected override async Task HandlePacketAsync(IClientSession session, CrossServerEntrypointPacket packet) { if (session.Account != null) { Log.Warn("CrossServerEntryPointPacketHandler session.Account != null"); return; } SessionResponse sessionResponse = await _sessionService.GetSessionByAccountName(new GetSessionByAccountNameRequest { AccountName = packet.AccountName }); if (sessionResponse.ResponseType != RpcResponseType.SUCCESS) { Log.Info("Session response incorrect"); session.SendPacket(session.GenerateFailcPacket(LoginFailType.CantConnect)); session.ForceDisconnect(); return; } Session sharedSession = sessionResponse.Session; if (sharedSession.State != SessionState.CrossChannelAuthentication) { Log.Debug($"Incorrect session state: {sharedSession.State}"); session.SendPacket(session.GenerateFailcPacket(LoginFailType.CantConnect)); session.ForceDisconnect(); return; } AccountLoadResponse accountLoadResponse = null; try { accountLoadResponse = await _accountService.LoadAccountById(new AccountLoadByIdRequest { AccountId = sharedSession.AccountId }); } catch (Exception e) { Log.Error("[CROSS_SERVER_AUTH] Unexpected error: ", e); } if (accountLoadResponse?.ResponseType != RpcResponseType.SUCCESS) { Log.Warn($"[CROSS_SERVER_AUTH][SESSION_ID: '{session.SessionId.ToString()}'] Failed to load account for accountId: {sharedSession.AccountId}'"); session.SendPacket(session.GenerateFailcPacket(LoginFailType.UnhandledError)); session.ForceDisconnect(); return; } AccountDTO account = accountLoadResponse.AccountDto; if (_maintenanceManager.IsMaintenanceActive && account.Authority < AuthorityType.GameMaster) { session.SendPacket(session.GenerateFailcPacket(LoginFailType.Maintenance)); session.ForceDisconnect(); return; } AccountBanGetResponse banResponse = null; try { banResponse = await _accountService.GetAccountBan(new AccountBanGetRequest { AccountId = account.Id }); } catch (Exception e) { Log.Error($"[CROSS_SERVER_AUTH][SESSION_ID: '{session.SessionId.ToString()}'] Unexpected error: ", e); } if (banResponse?.ResponseType != RpcResponseType.SUCCESS) { Log.Warn($"[CROSS_SERVER_AUTH][SESSION_ID: '{session.SessionId.ToString()}'] Failed to get account ban for accountId: '{account.Id.ToString()}'"); session.SendPacket(session.GenerateFailcPacket(LoginFailType.UnhandledError)); session.ForceDisconnect(); return; } AccountBanDto characterPenalty = banResponse.AccountBanDto; if (characterPenalty != null) { session.SendPacket(session.GenerateFailcPacket(LoginFailType.Banned)); Log.Info($"[CROSS_SERVER_AUTH][SESSION_ID: '{session.SessionId.ToString()}'] {account.Name} connected from {session.IpAddress} while being banned"); session.ForceDisconnect(); return; } var accountObj = new Account { Id = account.Id, Name = account.Name, MasterAccountId = account.MasterAccountId, Password = account.Password.ToLower(), Authority = account.Authority, BankMoney = account.BankMoney, Language = account.Language }; Log.Warn($"INITIALIZE_ACCOUNT : {account.Name}"); SessionResponse response = await _sessionService.ConnectToWorldServer(new ConnectToWorldServerRequest { AccountId = account.Id, ChannelId = _serverManager.ChannelId, ServerGroup = _serverManager.ServerGroup }); if (response is not { ResponseType: RpcResponseType.SUCCESS }) { session.ForceDisconnect(); return; } if (response.Session == null) { session.ForceDisconnect(); return; } session.InitializeAccount(accountObj, sessionResponse.Session); await session.EmitEventAsync(new CharacterPreLoadEvent(packet.CharacterSlot)); } }