using System.Collections.Immutable; using System.Reflection; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Supercell.GUT.Server.Protocol.Attributes; using Supercell.GUT.Server.Protocol.Handlers; using Supercell.GUT.Titan.Logic.Message; namespace Supercell.GUT.Server.Protocol; internal class MessageManager { private static readonly ImmutableDictionary s_handlerServiceTypes; static MessageManager() { var builder = ImmutableDictionary.CreateBuilder(); IEnumerable types = Assembly.GetExecutingAssembly().GetTypes() .Where(t => t.GetCustomAttribute() != null); foreach (Type type in types) { int serviceNodeType = type.GetCustomAttribute()!.ServiceNodeType; builder.Add(serviceNodeType, type); } s_handlerServiceTypes = builder.ToImmutable(); } private readonly ILogger _logger; private readonly IServiceProvider _serviceProvider; public MessageManager(IServiceProvider serviceProvider, ILogger logger) { _logger = logger; _serviceProvider = serviceProvider; } public async Task ReceiveMessage(PiranhaMessage message) { int serviceNodeType = message.GetServiceNodeType(); if (s_handlerServiceTypes.TryGetValue(serviceNodeType, out Type? handlerType)) { MessageHandlerBase handler = (_serviceProvider.GetRequiredService(handlerType) as MessageHandlerBase)!; if (!await handler.HandleMessage(message)) { _logger.LogWarning("Handler for message {type} not implemented in {svcName}", message.GetMessageType(), handler.GetType().Name); } } else { _logger.LogWarning("Handler for service node type {svcType} is not defined!", serviceNodeType); } } }