From effe9a5a1d31d33189f62179118329635bb9fa8b Mon Sep 17 00:00:00 2001 From: Timothy Schenk Date: Sat, 25 Nov 2023 12:20:55 +0100 Subject: [PATCH] revert: back to direct linq queries. --- ...ChannelSelectionHandler.CompiledQueries.cs | 58 ------------------- .../ChannelSelectionHandler.Projections.cs | 24 ++++++++ .../PacketHandlers/ChannelSelectionHandler.cs | 38 ++++++++++-- ...haracterCreationHandler.CompiledQueries.cs | 14 ----- .../CharacterCreationHandler.cs | 6 +- .../LoginHandler.CompiledQueries.cs | 21 ------- Server/PacketHandlers/LoginHandler.cs | 11 ++-- 7 files changed, 65 insertions(+), 107 deletions(-) delete mode 100644 Server/PacketHandlers/ChannelSelectionHandler.CompiledQueries.cs create mode 100644 Server/PacketHandlers/ChannelSelectionHandler.Projections.cs delete mode 100644 Server/PacketHandlers/CharacterCreationHandler.CompiledQueries.cs delete mode 100644 Server/PacketHandlers/LoginHandler.CompiledQueries.cs diff --git a/Server/PacketHandlers/ChannelSelectionHandler.CompiledQueries.cs b/Server/PacketHandlers/ChannelSelectionHandler.CompiledQueries.cs deleted file mode 100644 index 955f6a3..0000000 --- a/Server/PacketHandlers/ChannelSelectionHandler.CompiledQueries.cs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License. - -using Microsoft.EntityFrameworkCore; -using Server.DB; -using Server.DB.Documents; -using Wonderking.Game.Data.Character; -using Wonderking.Packets.Outgoing.Data; - -namespace Server.PacketHandlers; - -public partial class ChannelSelectionHandler -{ - private static readonly Func> _accountExists = EF.CompileAsyncQuery( - (WonderkingContext context, Guid accountId) => - context.Accounts.AsNoTracking().Any(a => a.Id == accountId)); - - private static readonly Func> _getAmountOfCharacters = - EF.CompileAsyncQuery((WonderkingContext context, Guid accountId) => - context.Characters.AsNoTracking() - .Where(c => c.Account.Id == accountId).Take(3) - .Count()); - - private static readonly Func> _getGuildNames = - EF.CompileAsyncQuery((WonderkingContext context, Guid accountId) => - context.Characters.AsNoTracking() - .Where(c => c.Account.Id == accountId && c.Guild != null) - .Select(c => c.Guild.Name).Take(3)); - - private static readonly Func> - _getCharacters = - EF.CompileAsyncQuery((WonderkingContext context, Guid accountId) => - context.Characters.AsNoTracking().AsSplitQuery() - .Where(c => c.Account.Id == accountId) - .Select(c => new CharacterDataProjection( - c.Name, - c.JobData, - c.Gender, - c.Level, - c.Experience, - c.BaseStats, - c.Health, - c.Mana, - c.InventoryItems.Select(i => new InventoryItemProjection(i.ItemId, i.Slot, i.InventoryTab)) - )).Take(3)); - - private sealed record InventoryItemProjection(ushort ItemId, byte Slot, InventoryTab InventoryTab); - - private sealed record CharacterDataProjection( - string Name, - JobData JobData, - Gender Gender, - ushort Level, - long Experience, - BaseStats BaseStats, - int Health, - int Mana, - IEnumerable InventoryItems); -} diff --git a/Server/PacketHandlers/ChannelSelectionHandler.Projections.cs b/Server/PacketHandlers/ChannelSelectionHandler.Projections.cs new file mode 100644 index 0000000..7ccc5b8 --- /dev/null +++ b/Server/PacketHandlers/ChannelSelectionHandler.Projections.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License. + +using Server.DB.Documents; +using Wonderking.Game.Data.Character; +using Wonderking.Packets.Outgoing.Data; + +namespace Server.PacketHandlers; + +public partial class ChannelSelectionHandler +{ + + private sealed record InventoryItemProjection(ushort ItemId, byte Slot, InventoryTab InventoryTab); + + private sealed record CharacterDataProjection( + string Name, + JobData JobData, + Gender Gender, + ushort Level, + long Experience, + BaseStats BaseStats, + int Health, + int Mana, + IEnumerable InventoryItems); +} diff --git a/Server/PacketHandlers/ChannelSelectionHandler.cs b/Server/PacketHandlers/ChannelSelectionHandler.cs index 056f27c..10b4d3a 100644 --- a/Server/PacketHandlers/ChannelSelectionHandler.cs +++ b/Server/PacketHandlers/ChannelSelectionHandler.cs @@ -1,6 +1,7 @@ // Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License. using DotNext.Collections.Generic; +using Microsoft.EntityFrameworkCore; using NetCoreServer; using Server.DB; using Server.DB.Documents; @@ -21,13 +22,20 @@ public partial class ChannelSelectionHandler : IPacketHandler() }; - var accountExists = await _accountExists(_wonderkingContext, authSession.AccountId); + var accountExists = + await _wonderkingContext.Accounts.AsNoTracking().AnyAsync(a => a.Id == authSession.AccountId); - var amountOfCharacter = await _getAmountOfCharacters(_wonderkingContext, authSession.AccountId); + var amountOfCharacter = await _wonderkingContext.Characters.AsNoTracking().Include(c => c.Account) + .Where(c => c.Account.Id == authSession.AccountId).Take(3) + .CountAsync(); if (!accountExists) { @@ -45,7 +53,10 @@ public partial class ChannelSelectionHandler : IPacketHandler c.Account).Include(c => c.GuildMember) + .ThenInclude(gm => gm.Guild) + .Where(c => c.Account.Id == authSession.AccountId && c.GuildMember.Guild != null) + .Select(c => c.GuildMember.Guild.Name).Take(3).ToArrayAsync(); } else { @@ -86,7 +97,23 @@ public partial class ChannelSelectionHandler : IPacketHandler GetCharacterDataAsync(Guid accountId) { - await foreach (var c in _getCharacters(_wonderkingContext, accountId)) + var characterDataProjections = _wonderkingContext.Characters.AsNoTracking().AsSplitQuery() + .Include(c => c.InventoryItems).Include(c => c.Account) + .Where(c => c.Account.Id == accountId) + .Select(c => new CharacterDataProjection( + c.Name, + c.JobData, + c.Gender, + c.Level, + c.Experience, + c.BaseStats, + c.Health, + c.Mana, + c.InventoryItems.Select(i => + new InventoryItemProjection(i.ItemId, i.Slot, i.InventoryTab)) + )).Take(3); + + await foreach (var c in characterDataProjections) { yield return new CharacterData { @@ -107,5 +134,4 @@ public partial class ChannelSelectionHandler : IPacketHandler> _getAccount = - EF.CompileQuery((WonderkingContext context, Guid accountId) => - context.Accounts.FirstOrDefaultAsync(a => a.Id == accountId, default)); -} diff --git a/Server/PacketHandlers/CharacterCreationHandler.cs b/Server/PacketHandlers/CharacterCreationHandler.cs index 2d0bf8a..fd8bc94 100644 --- a/Server/PacketHandlers/CharacterCreationHandler.cs +++ b/Server/PacketHandlers/CharacterCreationHandler.cs @@ -1,5 +1,6 @@ // Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License. +using Microsoft.EntityFrameworkCore; using NetCoreServer; using Server.DB; using Server.DB.Documents; @@ -12,7 +13,7 @@ using Wonderking.Packets.Outgoing.Data; namespace Server.PacketHandlers; -public partial class CharacterCreationHandler : IPacketHandler +public class CharacterCreationHandler : IPacketHandler { private readonly CharacterStatsMappingConfiguration _characterStatsMapping; private readonly ItemObjectPoolService _itemObjectPoolService; @@ -34,8 +35,7 @@ public partial class CharacterCreationHandler : IPacketHandler a.Id == authSession.AccountId); var firstJobConfig = SelectFirstJobConfig(packet.FirstJob); var items = CreateDefaultItems(packet, firstJobConfig); diff --git a/Server/PacketHandlers/LoginHandler.CompiledQueries.cs b/Server/PacketHandlers/LoginHandler.CompiledQueries.cs deleted file mode 100644 index ff05c32..0000000 --- a/Server/PacketHandlers/LoginHandler.CompiledQueries.cs +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2023 Timothy Schenk. Subject to the GNU AGPL Version 3 License. - -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking; -using Server.DB; -using Server.DB.Documents; - -namespace Server.PacketHandlers; - -public partial class LoginHandler -{ - private static readonly Func>> _addAccount = - EF.CompileQuery((WonderkingContext context, Account account) => context.Accounts.AddAsync(account, default)); - - private static readonly Func>> _updateAccount = - EF.CompileAsyncQuery((WonderkingContext context, Account account) => context.Accounts.Update(account)); - - private static readonly Func> _getAccount = - EF.CompileAsyncQuery((WonderkingContext context, string username) => - context.Accounts.FirstOrDefault(a => a.Username == username)); -} diff --git a/Server/PacketHandlers/LoginHandler.cs b/Server/PacketHandlers/LoginHandler.cs index e395765..947036a 100644 --- a/Server/PacketHandlers/LoginHandler.cs +++ b/Server/PacketHandlers/LoginHandler.cs @@ -5,6 +5,7 @@ using System.Security.Cryptography; using System.Text; using DotNext; using Konscious.Security.Cryptography; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using NetCoreServer; @@ -17,7 +18,7 @@ using Wonderking.Packets.Outgoing.Data; namespace Server.PacketHandlers; -public partial class LoginHandler : IPacketHandler +public class LoginHandler : IPacketHandler { private readonly IConfiguration _configuration; private readonly ILogger _logger; @@ -35,14 +36,14 @@ public partial class LoginHandler : IPacketHandler { LoginResponseReason loginResponseReason; _logger.LoginData(packet.Username, packet.Password); - var account = await _getAccount(_wonderkingContext, packet.Username); + var account = await _wonderkingContext.Accounts.FirstOrDefaultAsync(a => a.Username == packet.Username); if (account == null) { if (_configuration.GetSection("Testing").GetValue("CreateAccountOnLogin")) { loginResponseReason = await CreateAccountOnLoginAsync(packet.Username, packet.Password); - account = await _getAccount(_wonderkingContext, packet.Username); + account = await _wonderkingContext.Accounts.FirstOrDefaultAsync(a => a.Username == packet.Username); } else { @@ -106,12 +107,12 @@ public partial class LoginHandler : IPacketHandler try { var salt = RandomNumberGenerator.GetBytes(16); - var finalAccount = await _addAccount(_wonderkingContext, new Account(username, + var finalAccount = await _wonderkingContext.Accounts.AddAsync(new Account(username, Array.Empty(), "", 0, salt)); await _wonderkingContext.SaveChangesAsync(); finalAccount.Entity.Password = await GetPasswordHashAsync(password, salt, finalAccount.Entity.Id); - _updateAccount(_wonderkingContext, finalAccount.Entity); + _wonderkingContext.Accounts.Update(finalAccount.Entity); loginResponseReason = LoginResponseReason.Ok; await _wonderkingContext.SaveChangesAsync();