server-master/srcs/_plugins/WingsEmu.Plugins.PacketHandling/CharScreen/CrossServerEntryPointPacketHandler.cs
2026-02-10 18:21:30 +01:00

163 lines
No EOL
5.9 KiB
C#

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