chore: adjustments

This commit is contained in:
Timothy Schenk 2024-02-05 18:12:12 +01:00
parent 63ddbd707f
commit efd261be77
Signed by: rainote
SSH key fingerprint: SHA256:pnkNSDwpAnaip00xaZlVFHKKsS7T8UtOomMzvs0yITE
10 changed files with 69 additions and 75 deletions

View file

@ -3,7 +3,6 @@
using Continuity.AuthServer.Packets; using Continuity.AuthServer.Packets;
using JetBrains.Annotations; using JetBrains.Annotations;
using MassTransit; using MassTransit;
using NetCoreServer;
using OpenTelemetry.Trace; using OpenTelemetry.Trace;
using Rai.PacketMediator; using Rai.PacketMediator;
using Wonderking.Packets; using Wonderking.Packets;
@ -13,11 +12,11 @@ namespace Continuity.AuthServer.Consumers;
[UsedImplicitly] [UsedImplicitly]
public class PacketConsumer : IConsumer<RawPacket> public class PacketConsumer : IConsumer<RawPacket>
{ {
private readonly PacketDistributorService<OperationCode, TcpSession> _distributorService; private readonly PacketDistributorService<OperationCode, AuthSession> _distributorService;
private readonly TracerProvider _tracerProvider; private readonly TracerProvider _tracerProvider;
public PacketConsumer(PacketDistributorService<OperationCode, TcpSession> distributorService, TracerProvider tracerProvider) public PacketConsumer(PacketDistributorService<OperationCode, AuthSession> distributorService, TracerProvider tracerProvider)
{ {
_distributorService = distributorService; _distributorService = distributorService;
_tracerProvider = tracerProvider; _tracerProvider = tracerProvider;

View file

@ -11,7 +11,8 @@ RUN echo "Target: $TARGETARCH" && echo "Build: $BUILDPLATFORM"
WORKDIR /src WORKDIR /src
COPY ["Continuity.AuthServer/Continuity.AuthServer.csproj", "Continuity.AuthServer/"] COPY ["Continuity.AuthServer/Continuity.AuthServer.csproj", "Continuity.AuthServer/"]
COPY ["Wonderking/Wonderking.csproj", "Wonderking/"] COPY ["Wonderking/Wonderking.csproj", "Wonderking/"]
RUN dotnet restore "Wonderking/Wonderking.csproj" -a $TARGETARCH && dotnet restore "Continuity.AuthServer/Continuity.AuthServer.csproj" -a $TARGETARCH COPY ["Rai.PacketMediator/Rai.PacketMediator.csproj", "Rai.PacketMediator/"]
RUN dotnet restore "Wonderking/Wonderking.csproj" -a $TARGETARCH && dotnet restore "Rai.PacketMediator/Rai.PacketMediator.csproj" -a $TARGETARCH && dotnet restore "Continuity.AuthServer/Continuity.AuthServer.csproj" -a $TARGETARCH
COPY . . COPY . .
FROM build AS publish FROM build AS publish

View file

@ -4,7 +4,6 @@ using Continuity.AuthServer.DB;
using Continuity.AuthServer.DB.Documents; using Continuity.AuthServer.DB.Documents;
using DotNext.Collections.Generic; using DotNext.Collections.Generic;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NetCoreServer;
using Rai.PacketMediator; using Rai.PacketMediator;
using Wonderking.Packets.Incoming; using Wonderking.Packets.Incoming;
using Wonderking.Packets.Outgoing; using Wonderking.Packets.Outgoing;
@ -12,7 +11,7 @@ using Wonderking.Packets.Outgoing.Data;
namespace Continuity.AuthServer.PacketHandlers; namespace Continuity.AuthServer.PacketHandlers;
public partial class ChannelSelectionHandler : IPacketHandler<ChannelSelectionPacket, TcpSession> public partial class ChannelSelectionHandler : IPacketHandler<ChannelSelectionPacket, AuthSession>
{ {
private readonly WonderkingContext _wonderkingContext; private readonly WonderkingContext _wonderkingContext;
@ -21,22 +20,17 @@ public partial class ChannelSelectionHandler : IPacketHandler<ChannelSelectionPa
_wonderkingContext = wonderkingContext; _wonderkingContext = wonderkingContext;
} }
public async Task HandleAsync(ChannelSelectionPacket packet, TcpSession session, public async Task HandleAsync(ChannelSelectionPacket packet, AuthSession session,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
if (session is not AuthSession authSession)
{
return;
}
ChannelSelectionResponsePacket responsePacket; ChannelSelectionResponsePacket responsePacket;
var guildNameResponsePacket = new CharacterSelectionSetGuildNamePacket { GuildNames = Array.Empty<string>() }; var guildNameResponsePacket = new CharacterSelectionSetGuildNamePacket { GuildNames = Array.Empty<string>() };
var accountExists = var accountExists =
await _wonderkingContext.Accounts.AsNoTracking().AnyAsync(a => a.Id == authSession.AccountId, cancellationToken: cancellationToken); await _wonderkingContext.Accounts.AsNoTracking().AnyAsync(a => a.Id == session.AccountId, cancellationToken: cancellationToken);
var amountOfCharacter = await _wonderkingContext.Characters.AsNoTracking().Include(c => c.Account) var amountOfCharacter = await _wonderkingContext.Characters.AsNoTracking().Include(c => c.Account)
.Where(c => c.Account.Id == authSession.AccountId).Take(3) .Where(c => c.Account.Id == session.AccountId).Take(3)
.CountAsync(cancellationToken: cancellationToken); .CountAsync(cancellationToken: cancellationToken);
if (!accountExists) if (!accountExists)
@ -51,13 +45,13 @@ public partial class ChannelSelectionHandler : IPacketHandler<ChannelSelectionPa
ChannelIsFullFlag = 0, ChannelIsFullFlag = 0,
Endpoint = "127.0.0.1", Endpoint = "127.0.0.1",
Port = 2000, Port = 2000,
Characters = await GetCharacterDataAsync(authSession.AccountId).ToArrayAsync(token: cancellationToken) Characters = await GetCharacterDataAsync(session.AccountId).ToArrayAsync(token: cancellationToken)
}; };
guildNameResponsePacket.GuildNames = guildNameResponsePacket.GuildNames =
await _wonderkingContext.Characters.AsNoTracking().Include(c => c.Account).Include(c => c.GuildMember) await _wonderkingContext.Characters.AsNoTracking().Include(c => c.Account).Include(c => c.GuildMember)
.ThenInclude(gm => gm.Guild) .ThenInclude(gm => gm.Guild)
.Where(c => c.Account.Id == authSession.AccountId && c.GuildMember.Guild != null) .Where(c => c.Account.Id == session.AccountId && c.GuildMember.Guild != null)
.Select(c => c.GuildMember.Guild.Name).Take(3).ToArrayAsync(cancellationToken: cancellationToken); .Select(c => c.GuildMember.Guild.Name).Take(3).ToArrayAsync(cancellationToken: cancellationToken);
} }
else else
@ -71,11 +65,11 @@ public partial class ChannelSelectionHandler : IPacketHandler<ChannelSelectionPa
}; };
} }
await authSession.SendAsync(responsePacket); await session.SendAsync(responsePacket);
if (guildNameResponsePacket.GuildNames.Length > 0 && if (guildNameResponsePacket.GuildNames.Length > 0 &&
guildNameResponsePacket.GuildNames.Select(n => n != string.Empty).Any()) guildNameResponsePacket.GuildNames.Select(n => n != string.Empty).Any())
{ {
await authSession.SendAsync(guildNameResponsePacket); await session.SendAsync(guildNameResponsePacket);
} }
} }

View file

@ -4,7 +4,6 @@ using Continuity.AuthServer.DB;
using Continuity.AuthServer.DB.Documents; using Continuity.AuthServer.DB.Documents;
using Continuity.AuthServer.Services; using Continuity.AuthServer.Services;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NetCoreServer;
using Rai.PacketMediator; using Rai.PacketMediator;
using Wonderking.Game.Data.Character; using Wonderking.Game.Data.Character;
using Wonderking.Game.Mapping; using Wonderking.Game.Mapping;
@ -14,7 +13,7 @@ using Wonderking.Packets.Outgoing.Data;
namespace Continuity.AuthServer.PacketHandlers; namespace Continuity.AuthServer.PacketHandlers;
public class CharacterCreationHandler : IPacketHandler<CharacterCreationPacket, TcpSession> public class CharacterCreationHandler : IPacketHandler<CharacterCreationPacket, AuthSession>
{ {
private readonly CharacterStatsMappingConfiguration _characterStatsMapping; private readonly CharacterStatsMappingConfiguration _characterStatsMapping;
private readonly ItemObjectPoolService _itemObjectPoolService; private readonly ItemObjectPoolService _itemObjectPoolService;
@ -28,15 +27,11 @@ public class CharacterCreationHandler : IPacketHandler<CharacterCreationPacket,
_characterStatsMapping = characterStatsMappingConfiguration; _characterStatsMapping = characterStatsMappingConfiguration;
} }
public async Task HandleAsync(CharacterCreationPacket packet, TcpSession session, public async Task HandleAsync(CharacterCreationPacket packet, AuthSession session,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
if (session is not AuthSession authSession)
{
return;
}
var account = await _wonderkingContext.Accounts.FirstOrDefaultAsync(a => a.Id == authSession.AccountId, cancellationToken: cancellationToken); var account = await _wonderkingContext.Accounts.FirstOrDefaultAsync(a => a.Id == session.AccountId, cancellationToken: cancellationToken);
if (account is null) if (account is null)
{ {
@ -70,7 +65,7 @@ public class CharacterCreationHandler : IPacketHandler<CharacterCreationPacket,
.Select(item => new Tuple<ushort, byte>(item.ItemId, item.Slot)).AsEnumerable()) .Select(item => new Tuple<ushort, byte>(item.ItemId, item.Slot)).AsEnumerable())
}; };
await authSession.SendAsync(new CharacterCreationResponsePacket await session.SendAsync(new CharacterCreationResponsePacket
{ {
Character = character, Character = character,
Slot = packet.Slot, Slot = packet.Slot,

View file

@ -2,14 +2,13 @@
using Continuity.AuthServer.DB; using Continuity.AuthServer.DB;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NetCoreServer;
using Rai.PacketMediator; using Rai.PacketMediator;
using Wonderking.Packets.Incoming; using Wonderking.Packets.Incoming;
using Wonderking.Packets.Outgoing; using Wonderking.Packets.Outgoing;
namespace Continuity.AuthServer.PacketHandlers; namespace Continuity.AuthServer.PacketHandlers;
public class CharacterDeletionHandler : IPacketHandler<CharacterDeletePacket, TcpSession> public class CharacterDeletionHandler : IPacketHandler<CharacterDeletePacket, AuthSession>
{ {
private readonly WonderkingContext _wonderkingContext; private readonly WonderkingContext _wonderkingContext;
@ -18,27 +17,21 @@ public class CharacterDeletionHandler : IPacketHandler<CharacterDeletePacket, Tc
_wonderkingContext = wonderkingContext; _wonderkingContext = wonderkingContext;
} }
public async Task HandleAsync(CharacterDeletePacket packet, TcpSession session, CancellationToken cancellationToken) public async Task HandleAsync(CharacterDeletePacket packet, AuthSession session, CancellationToken cancellationToken)
{ {
if (session is not AuthSession authSession)
{
session.Disconnect();
return;
}
var character = await _wonderkingContext.Characters.FirstOrDefaultAsync(x => x.Name == packet.Name && var character = await _wonderkingContext.Characters.FirstOrDefaultAsync(x => x.Name == packet.Name &&
x.Account.Id == authSession.AccountId, cancellationToken: cancellationToken); x.Account.Id == session.AccountId, cancellationToken: cancellationToken);
var response = new CharacterDeleteResponsePacket { HasToBeZero = 0 }; var response = new CharacterDeleteResponsePacket { HasToBeZero = 0 };
if (character == null) if (character == null)
{ {
await authSession.SendAsync(response); await session.SendAsync(response);
return; return;
} }
_wonderkingContext.Characters.Remove(character); _wonderkingContext.Characters.Remove(character);
await _wonderkingContext.SaveChangesAsync(cancellationToken); await _wonderkingContext.SaveChangesAsync(cancellationToken);
await authSession.SendAsync(response); await session.SendAsync(response);
} }
} }

View file

@ -2,14 +2,13 @@
using Continuity.AuthServer.DB; using Continuity.AuthServer.DB;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using NetCoreServer;
using Rai.PacketMediator; using Rai.PacketMediator;
using Wonderking.Packets.Incoming; using Wonderking.Packets.Incoming;
using Wonderking.Packets.Outgoing; using Wonderking.Packets.Outgoing;
namespace Continuity.AuthServer.PacketHandlers; namespace Continuity.AuthServer.PacketHandlers;
public class CharacterNameCheckHandler : IPacketHandler<CharacterNameCheckPacket, TcpSession> public class CharacterNameCheckHandler : IPacketHandler<CharacterNameCheckPacket, AuthSession>
{ {
private readonly WonderkingContext _wonderkingContext; private readonly WonderkingContext _wonderkingContext;
@ -18,14 +17,14 @@ public class CharacterNameCheckHandler : IPacketHandler<CharacterNameCheckPacket
_wonderkingContext = wonderkingContext; _wonderkingContext = wonderkingContext;
} }
public async Task HandleAsync(CharacterNameCheckPacket packet, TcpSession session, public async Task HandleAsync(CharacterNameCheckPacket packet, AuthSession session,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var isTaken = await _wonderkingContext.Characters.AnyAsync(c => c.Name == packet.Name, cancellationToken: cancellationToken); var isTaken =
await _wonderkingContext.Characters.AnyAsync(c => c.Name == packet.Name,
cancellationToken: cancellationToken);
var responsePacket = new CharacterNameCheckPacketResponse { IsTaken = isTaken }; var responsePacket = new CharacterNameCheckPacketResponse { IsTaken = isTaken };
if (session is AuthSession authSession)
{ await session.SendAsync(responsePacket);
await authSession.SendAsync(responsePacket);
}
} }
} }

View file

@ -10,7 +10,6 @@ using Konscious.Security.Cryptography;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NetCoreServer;
using Rai.PacketMediator; using Rai.PacketMediator;
using Wonderking.Packets.Incoming; using Wonderking.Packets.Incoming;
using Wonderking.Packets.Outgoing; using Wonderking.Packets.Outgoing;
@ -18,12 +17,12 @@ using Wonderking.Packets.Outgoing.Data;
namespace Continuity.AuthServer.PacketHandlers; namespace Continuity.AuthServer.PacketHandlers;
public class LoginHandler : IPacketHandler<LoginInfoPacket, TcpSession> public class LoginHandler : IPacketHandler<LoginInfoPacket, AuthSession>
{ {
private readonly IConfiguration _configuration; private readonly IConfiguration _configuration;
private readonly ILogger<LoginHandler> _logger; private readonly ILogger<LoginHandler> _logger;
private readonly WonderkingContext _wonderkingContext; private readonly WonderkingContext _wonderkingContext;
private static readonly ActivitySource _activitySource = new ActivitySource(nameof(Server)); private static readonly ActivitySource _activitySource = new(nameof(Server));
public LoginHandler(ILogger<LoginHandler> logger, WonderkingContext wonderkingContext, IConfiguration configuration) public LoginHandler(ILogger<LoginHandler> logger, WonderkingContext wonderkingContext, IConfiguration configuration)
{ {
@ -32,7 +31,7 @@ public class LoginHandler : IPacketHandler<LoginInfoPacket, TcpSession>
_configuration = configuration; _configuration = configuration;
} }
public async Task HandleAsync(LoginInfoPacket packet, TcpSession session, CancellationToken cancellationToken) public async Task HandleAsync(LoginInfoPacket packet, AuthSession session, CancellationToken cancellationToken)
{ {
LoginResponseReason loginResponseReason; LoginResponseReason loginResponseReason;
_logger.LoginData(packet.Username, packet.Password); _logger.LoginData(packet.Username, packet.Password);
@ -70,14 +69,13 @@ public class LoginHandler : IPacketHandler<LoginInfoPacket, TcpSession>
IsGameMaster = true IsGameMaster = true
}; };
var authSession = session as AuthSession; if (account != null)
if (account != null && authSession != null)
{ {
authSession.AccountId = account.Id; session.AccountId = account.Id;
} }
_logger.LogInformation("LoginResponsePacket: {@LoginResponsePacket}", loginResponsePacket); _logger.LogInformation("LoginResponsePacket: {@LoginResponsePacket}", loginResponsePacket);
_ = authSession?.SendAsync(loginResponsePacket); _ = session?.SendAsync(loginResponsePacket);
} }
private static async Task<byte[]> GetPasswordHashAsync(string password, byte[] salt, Guid userId) private static async Task<byte[]> GetPasswordHashAsync(string password, byte[] salt, Guid userId)

View file

@ -3,7 +3,9 @@
using System.Net; using System.Net;
using System.Reflection; using System.Reflection;
using System.Text.Json; using System.Text.Json;
using Continuity.AuthServer;
using Continuity.AuthServer.DB; using Continuity.AuthServer.DB;
using Continuity.AuthServer.PacketHandlers;
using Continuity.AuthServer.Services; using Continuity.AuthServer.Services;
using MassTransit; using MassTransit;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
@ -12,7 +14,6 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Diagnostics.HealthChecks;
using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using NetCoreServer;
using Npgsql; using Npgsql;
using OpenTelemetry.Logs; using OpenTelemetry.Logs;
using OpenTelemetry.Metrics; using OpenTelemetry.Metrics;
@ -106,24 +107,35 @@ builder.Services.AddSingleton<CharacterStatsMappingConfiguration>(
File.ReadAllText("config/character-stats.mapping.json")) ?? throw new InvalidOperationException()); File.ReadAllText("config/character-stats.mapping.json")) ?? throw new InvalidOperationException());
builder.Services.AddSingleton<ILoggerFactory>(loggerFactory); builder.Services.AddSingleton<ILoggerFactory>(loggerFactory);
builder.Services.AddSingleton<PacketDistributorService<OperationCode, TcpSession>>(); builder.Services.AddSingleton(provider =>
new PacketDistributorService<OperationCode, AuthSession>(
provider.GetRequiredService<IServiceProvider>(),
[
Assembly.GetAssembly(typeof(LoginHandler)),
Assembly.GetAssembly(typeof(OperationCode)),
]
));
builder.Services.AddSingleton<ItemObjectPoolService>(); builder.Services.AddSingleton<ItemObjectPoolService>();
builder.Services.AddHostedService(provider => new WonderkingAuthServer(IPAddress.Any, 10001,
provider.GetService<ILogger<WonderkingAuthServer>>() ?? throw new InvalidOperationException(),
provider.GetService<IServiceProvider>() ?? throw new InvalidOperationException()));
builder.Services.AddHostedService(provider => builder.Services.AddHostedService(provider =>
provider.GetService<ItemObjectPoolService>() ?? throw new InvalidOperationException()); provider.GetService<ItemObjectPoolService>() ?? throw new InvalidOperationException());
builder.Services.AddHostedService(provider => builder.Services.AddHostedService(provider =>
provider.GetService<PacketDistributorService<OperationCode, TcpSession>>() ?? provider.GetService<PacketDistributorService<OperationCode, AuthSession>>() ?? throw new InvalidOperationException());
throw new InvalidOperationException());
builder.Services.AddMassTransit(x => builder.Services.AddMassTransit(x =>
{ {
x.UsingInMemory((context, configurator) => configurator.ConfigureEndpoints(context)); x.UsingInMemory((context, configurator) => configurator.ConfigureEndpoints(context));
x.AddMediator(cfg => cfg.AddConsumers(Assembly.GetExecutingAssembly())); x.AddMediator(cfg => cfg.AddConsumers(Assembly.GetExecutingAssembly()));
}); });
builder.Services.AddHostedService(provider => new WonderkingAuthServer(IPAddress.Any, 10001,
provider.GetService<ILogger<WonderkingAuthServer>>() ?? throw new InvalidOperationException(),
provider.GetService<IServiceProvider>() ?? throw new InvalidOperationException()));
using var host = builder.Build(); using var host = builder.Build();
using (var scope = host.Services.CreateScope())
await using (var scope = host.Services.CreateAsyncScope())
{ {
var db = scope.ServiceProvider.GetRequiredService<WonderkingContext>(); var db = scope.ServiceProvider.GetRequiredService<WonderkingContext>();
await db.Database.MigrateAsync(); await db.Database.MigrateAsync();

View file

@ -4,6 +4,7 @@ using System.Collections.Concurrent;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.Reflection; using System.Reflection;
using System.Threading.Channels; using System.Threading.Channels;
using DotNext.Collections.Generic;
using DotNext.Linq.Expressions; using DotNext.Linq.Expressions;
using DotNext.Metaprogramming; using DotNext.Metaprogramming;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -48,14 +49,14 @@ public class PacketDistributor<TPacketIdEnum, TSession> where TPacketIdEnum : En
var tempDeserializationMap = var tempDeserializationMap =
new ConcurrentDictionary<TPacketIdEnum, Func<byte[], IIncomingPacket>>(); new ConcurrentDictionary<TPacketIdEnum, Func<byte[], IIncomingPacket>>();
_packetHandlersInstantiation = new ConcurrentDictionary<TPacketIdEnum, IPacketHandler<TSession>?>(); _packetHandlersInstantiation = new ConcurrentDictionary<TPacketIdEnum, IPacketHandler<TSession>?>();
Parallel.ForEach(packetHandlers, packetHandlerPair => packetHandlers.ForEach(packetHandlerPair =>
{ {
var packetHandler = var packetHandler =
ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider, ActivatorUtilities.GetServiceOrCreateInstance(serviceProvider,
packetHandlerPair.Value); packetHandlerPair.Value);
_packetHandlersInstantiation.TryAdd(packetHandlerPair.Key, packetHandler as IPacketHandler<TSession>); _packetHandlersInstantiation.TryAdd(packetHandlerPair.Key, packetHandler as IPacketHandler<TSession>);
}); });
Parallel.ForEach(packetDictionary, packetsType => packetDictionary.ForEach(packetsType =>
{ {
var lambda = CodeGenerator.Lambda<Func<byte[], IIncomingPacket>>(fun => var lambda = CodeGenerator.Lambda<Func<byte[], IIncomingPacket>>(fun =>
{ {
@ -94,19 +95,20 @@ public class PacketDistributor<TPacketIdEnum, TSession> where TPacketIdEnum : En
.Where(t => .Where(t =>
t is { IsClass: true, IsAbstract: false } && Array.Exists(t t is { IsClass: true, IsAbstract: false } && Array.Exists(t
.GetInterfaces(), i => .GetInterfaces(), i =>
i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketHandler<TSession>))) i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IPacketHandler<,>)))
.Select(type => new .Select(packetHandlerType => new
{ {
Type = type, Type = packetHandlerType,
PacketId = type PacketId = packetHandlerType
.GetInterfaces().First(t1 => .GetInterfaces().First(t1 =>
t1 is { IsGenericType: true } && t1 is { IsGenericType: true } &&
t1.GetGenericTypeDefinition() == typeof(IPacketHandler<TSession>)) t1.GetGenericTypeDefinition() == typeof(IPacketHandler<,>)).GetGenericArguments()
.GetGenericArguments().First(t => .First(genericType => genericType.GetInterfaces().Any(packetType =>
t.GetCustomAttributes<PacketIdAttribute<TPacketIdEnum>>().Any()) packetType == typeof(IPacket)))
.GetCustomAttributes<PacketIdAttribute<TPacketIdEnum>>().First().Code .GetCustomAttribute<PacketIdAttribute<TPacketIdEnum>>()
})) }))
.ToDictionary(x => x.PacketId, x => x.Type); .Where(x => x.PacketId != null)
.ToDictionary(x => x.PacketId!.Code, x => x.Type);
return packetHandlersWithId; return packetHandlersWithId;
} }

View file

@ -31,7 +31,7 @@ services:
source: config source: config
target: /app/config target: /app/config
read_only: true read_only: true
mem_limit: 100m mem_limit: 1024m
db: db:
container_name: continuity-db container_name: continuity-db
@ -52,6 +52,7 @@ services:
interval: 10s interval: 10s
timeout: 3s timeout: 3s
retries: 3 retries: 3
mem_limit: 1024m
jaeger: jaeger:
container_name: continuity-jaeger container_name: continuity-jaeger