using Microsoft.EntityFrameworkCore; using Server.DB.Documents; using Wonderking.Packets.Incoming; using Wonderking.Packets.Outgoing; using Wonderking.Packets.Outgoing.Data; namespace Server.PacketHandlers; using DB; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using NetCoreServer; public class ChannelSelectionHandler : IPacketHandler { private readonly IConfiguration _configuration; private readonly ILogger _logger; private readonly WonderkingContext _wonderkingContext; public ChannelSelectionHandler(IConfiguration configuration, ILogger logger, WonderkingContext wonderkingContext) { this._configuration = configuration; this._logger = logger; this._wonderkingContext = wonderkingContext; } public async Task HandleAsync(ChannelSelectionPacket packet, TcpSession session) { var authSession = (AuthSession)session; ChannelSelectionResponsePacket responsePacket; var guildNameResponsePacket = new CharacterSelectionSetGuildNamePacket { GuildNames = Array.Empty() }; var account = await this._wonderkingContext.Accounts .FirstOrDefaultAsync(a => a.Id == authSession.AccountId).ConfigureAwait(true); if (account != null && account.Characters.Count > 0) { responsePacket = new ChannelSelectionResponsePacket { ChannelIsFullFlag = 0, Endpoint = "127.0.0.1", Port = 2000, Characters = await _wonderkingContext.Characters.AsNoTracking() .Where(c => c.Account.Id == authSession.AccountId) .Select(c => new CharacterData { Name = c.Name, Job = c.JobData, Gender = c.Gender, Level = c.Level, // TODO: Calculate instead of clamping based on max experience for level Experience = Math.Clamp(c.Experience, 0, 100), Stats = c.BaseStats, Health = c.Health, Mana = c.Mana, EquippedItems = GetItemIDsByInventoryTab(c.InventoryItems .Where(item => item.InventoryTab == InventoryTab.WornEquipment) .Select(item => new Tuple(item.ItemId, item.Slot)).ToArray()), EquippedCashItems = GetItemIDsByInventoryTab(c.InventoryItems .Where(item => item.InventoryTab == InventoryTab.WornCashEquipment) .Select(item => new Tuple(item.ItemId, item.Slot)).ToArray()), }) .ToArrayAsync().ConfigureAwait(true), }; guildNameResponsePacket.GuildNames = await _wonderkingContext.Characters .Where(c => c.Account.Id == authSession.AccountId) .Where(c => c.Guild != null) .Select(character => character.Guild.Name).ToArrayAsync().ConfigureAwait(true); } else { responsePacket = new ChannelSelectionResponsePacket { ChannelIsFullFlag = 0, Endpoint = "127.0.0.1", Port = 2000, Characters = Array.Empty() }; } await authSession.SendAsync(responsePacket).ConfigureAwait(false); if (guildNameResponsePacket.GuildNames.Length > 0 && guildNameResponsePacket.GuildNames.Select(n => n != string.Empty).Any()) { await authSession.SendAsync(guildNameResponsePacket).ConfigureAwait(false); } } private static ushort[] GetItemIDsByInventoryTab(Tuple[] items) { var ids = new ushort[20]; for (var i = 0; i < 20; i++) { ids[i] = items.FirstOrDefault(item => item.Item2 == i)?.Item1 ?? 0; } return ids; } }