forked from Raphael/SCHALE.GameServer
new handlers architecture
This commit is contained in:
parent
45084b0177
commit
5ca05509fc
|
@ -0,0 +1,13 @@
|
|||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace SCHALE.Common.Database.Models.Game
|
||||
{
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public class Account : AccountDB
|
||||
{
|
||||
[Key]
|
||||
[Column("_id")]
|
||||
public new uint ServerId { get; set; }
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@ using System.ComponentModel.DataAnnotations.Schema;
|
|||
namespace SCHALE.Common.Database.Models
|
||||
{
|
||||
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable.
|
||||
public class Account
|
||||
public class GuestAccount
|
||||
{
|
||||
[Key]
|
||||
[Column("_id")]
|
|
@ -3,11 +3,13 @@ using Microsoft.EntityFrameworkCore.ChangeTracking;
|
|||
using Microsoft.EntityFrameworkCore.ValueGeneration;
|
||||
using MongoDB.EntityFrameworkCore.Extensions;
|
||||
using SCHALE.Common.Database.Models;
|
||||
using SCHALE.Common.Database.Models.Game;
|
||||
|
||||
namespace SCHALE.Common.Database
|
||||
{
|
||||
public class SCHALEContext : DbContext
|
||||
{
|
||||
public DbSet<GuestAccount> GuestAccounts { get; set; }
|
||||
public DbSet<Account> Accounts { get; set; }
|
||||
public DbSet<Counter> Counters { get; set; }
|
||||
|
||||
|
@ -19,42 +21,66 @@ namespace SCHALE.Common.Database
|
|||
{
|
||||
|
||||
base.OnModelCreating(modelBuilder);
|
||||
modelBuilder.Entity<Account>().Property(x => x.Uid).HasValueGenerator<AccountAutoIncrementValueGenerator>();
|
||||
|
||||
modelBuilder.Entity<GuestAccount>().Property(x => x.Uid).HasValueGenerator<GuestAccountAutoIncrementValueGenerator>();
|
||||
modelBuilder.Entity<GuestAccount>().ToCollection("guest_accounts");
|
||||
|
||||
modelBuilder.Entity<Account>().Property(x => x.ServerId).HasValueGenerator<AccountAutoIncrementValueGenerator>();
|
||||
modelBuilder.Entity<Account>().ToCollection("accounts");
|
||||
|
||||
modelBuilder.Entity<Counter>().ToCollection("counters");
|
||||
}
|
||||
}
|
||||
|
||||
class AccountAutoIncrementValueGenerator : AutoIncrementValueGenerator
|
||||
{
|
||||
protected override string Collection => "account";
|
||||
}
|
||||
|
||||
abstract class AutoIncrementValueGenerator : ValueGenerator<uint>
|
||||
{
|
||||
protected abstract string Collection { get; }
|
||||
public override bool GeneratesTemporaryValues => false;
|
||||
|
||||
public override uint Next(EntityEntry entry)
|
||||
private class AccountAutoIncrementValueGenerator : AutoIncrementValueGenerator
|
||||
{
|
||||
if (entry.Context is not SCHALEContext)
|
||||
{
|
||||
throw new ArgumentNullException($"{nameof(AutoIncrementValueGenerator)} is only implemented for {nameof(SCHALEContext)}");
|
||||
}
|
||||
protected override string Collection => "account";
|
||||
}
|
||||
|
||||
var context = ((SCHALEContext)entry.Context);
|
||||
var counter = context.Counters.SingleOrDefault(x => x.Id == Collection);
|
||||
private class GuestAccountAutoIncrementValueGenerator : AutoIncrementValueGenerator
|
||||
{
|
||||
protected override string Collection => "guest_account";
|
||||
}
|
||||
|
||||
if (counter is null)
|
||||
private abstract class AutoIncrementValueGenerator : ValueGenerator<uint>
|
||||
{
|
||||
protected abstract string Collection { get; }
|
||||
public override bool GeneratesTemporaryValues => false;
|
||||
|
||||
public override uint Next(EntityEntry entry)
|
||||
{
|
||||
counter = new Counter() { Id = Collection, Seq = 0 };
|
||||
context.Add(counter);
|
||||
if (entry.Context is not SCHALEContext)
|
||||
{
|
||||
throw new ArgumentNullException($"{nameof(AutoIncrementValueGenerator)} is only implemented for {nameof(SCHALEContext)}");
|
||||
}
|
||||
|
||||
var context = ((SCHALEContext)entry.Context);
|
||||
var counter = context.Counters.SingleOrDefault(x => x.Id == Collection);
|
||||
|
||||
if (counter is null)
|
||||
{
|
||||
counter = new Counter() { Id = Collection, Seq = 0 };
|
||||
context.Add(counter);
|
||||
}
|
||||
|
||||
counter.Seq++;
|
||||
context.SaveChanges();
|
||||
|
||||
return counter.Seq;
|
||||
}
|
||||
}
|
||||
|
||||
counter.Seq++;
|
||||
public override void Dispose()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
SaveChanges();
|
||||
base.Dispose();
|
||||
}
|
||||
|
||||
return counter.Seq;
|
||||
public override ValueTask DisposeAsync()
|
||||
{
|
||||
GC.SuppressFinalize(this);
|
||||
SaveChanges();
|
||||
return base.DisposeAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
using SCHALE.Common.Database.Models;
|
||||
namespace SCHALE.Common.NetworkProtocol.Account
|
||||
{
|
||||
public class AccountAuthResponse : ResponsePacket
|
||||
{
|
||||
public override Protocol Protocol => Protocol.Account_Auth;
|
||||
public long CurrentVersion { get; set; }
|
||||
public long MinimumVersion { get; set; }
|
||||
public bool IsDevelopment { get; set; }
|
||||
public bool UpdateRequired { get; set; }
|
||||
public required string TTSCdnUri { get; set; }
|
||||
/*public AccountDB AccountDB { get; set; }
|
||||
public IEnumerable<AttendanceBookReward> AttendanceBookRewards { get; set; }
|
||||
public IEnumerable<AttendanceHistoryDB> AttendanceHistoryDBs { get; set; }
|
||||
public IEnumerable<OpenConditionDB> OpenConditions { get; set; }
|
||||
public IEnumerable<PurchaseCountDB> RepurchasableMonthlyProductCountDBs { get; set; }
|
||||
public IEnumerable<ParcelInfo> MonthlyProductParcel { get; set; }
|
||||
public IEnumerable<ParcelInfo> MonthlyProductMail { get; set; }
|
||||
public IEnumerable<ParcelInfo> BiweeklyProductParcel { get; set; }
|
||||
public IEnumerable<ParcelInfo> BiweeklyProductMail { get; set; }
|
||||
public IEnumerable<ParcelInfo> WeeklyProductParcel { get; set; }
|
||||
public IEnumerable<ParcelInfo> WeeklyProductMail { get; set; }*/
|
||||
public required string EncryptedUID { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class AccountAuthRequest : RequestPacket
|
||||
{
|
||||
public override Protocol Protocol => Protocol.Account_Auth;
|
||||
public long Version { get; set; }
|
||||
public string? DevId { get; set; }
|
||||
public long IMEI { get; set; }
|
||||
public string AccessIP { get; set; } = string.Empty;
|
||||
public string MarketId { get; set; } = string.Empty;
|
||||
public string? UserType { get; set; }
|
||||
public string? AdvertisementId { get; set; }
|
||||
public string OSType { get; set; } = string.Empty;
|
||||
public string OSVersion { get; set; } = string.Empty;
|
||||
public string DeviceUniqueId { get; set; } = string.Empty;
|
||||
public string DeviceModel { get; set; } = string.Empty;
|
||||
public int DeviceSystemMemorySize { get; set; }
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
namespace SCHALE.Common.NetworkProtocol.Account
|
||||
{
|
||||
public class AccountCheckYostarRequest : RequestPacket
|
||||
{
|
||||
public override Protocol Protocol => NetworkProtocol.Protocol.Account_CheckYostar;
|
||||
public long UID { get; set; }
|
||||
public string YostarToken { get; set; } = string.Empty;
|
||||
public string EnterTicket { get; set; } = string.Empty;
|
||||
public bool PassCookieResult { get; set; }
|
||||
public string Cookie { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
|
||||
public class AccountCheckYostarResponse : ResponsePacket
|
||||
{
|
||||
public override Protocol Protocol
|
||||
{
|
||||
get
|
||||
{
|
||||
return NetworkProtocol.Protocol.Account_CheckYostar;
|
||||
}
|
||||
}
|
||||
public int ResultState { get; set; }
|
||||
public string ResultMessag { get; set; } = string.Empty;
|
||||
public string Birth { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
using System.Text.Json.Serialization;
|
||||
using SCHALE.Common.Database;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace SCHALE.Common.NetworkProtocol
|
||||
{
|
||||
|
@ -36,8 +37,8 @@ namespace SCHALE.Common.NetworkProtocol
|
|||
{
|
||||
public long ServerTimeTicks { get; set; } = DateTimeOffset.Now.Ticks;
|
||||
public ServerNotificationFlag ServerNotification { get; set; }
|
||||
// public List<MissionProgressDB> MissionProgressDBs { get; set; }
|
||||
// public Dictionary<long, List<MissionProgressDB>> EventMissionProgressDBDict { get; set; }
|
||||
public List<MissionProgressDB> MissionProgressDBs { get; set; }
|
||||
public Dictionary<long, List<MissionProgressDB>> EventMissionProgressDBDict { get; set; }
|
||||
// public Dictionary<OpenConditionContent, OpenConditionLockReason> StaticOpenConditions { get; set; }
|
||||
}
|
||||
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
namespace SCHALE.Common.NetworkProtocol.Queuing
|
||||
{
|
||||
public class QueuingGetTicketRequest : RequestPacket
|
||||
{
|
||||
public override Protocol Protocol => Protocol.Queuing_GetTicket;
|
||||
public long YostarUID { get; set; }
|
||||
public required string YostarToken { get; set; }
|
||||
public bool MakeStandby { get; set; }
|
||||
public bool PassCheck { get; set; }
|
||||
public bool PassCheckYostar { get; set; }
|
||||
public string WaitingTicket { get; set; } = string.Empty;
|
||||
public string ClientVersion { get; set; } = "0.0.0";
|
||||
}
|
||||
|
||||
public class QueuingGetTicketResponse : ResponsePacket
|
||||
{
|
||||
public override Protocol Protocol => Protocol.Queuing_GetTicket;
|
||||
public string WaitingTicket { get; set; } = string.Empty;
|
||||
public string EnterTicket { get; set; } = string.Empty;
|
||||
public long TicketSequence { get; set; }
|
||||
public long AllowedSequence { get; set; }
|
||||
public double RequiredSecondsPerUser { get; set; }
|
||||
public string Birth { get; set; } = string.Empty;
|
||||
public string ServerSeed { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
|
@ -34,28 +34,28 @@ namespace SCHALE.Common.NetworkProtocol
|
|||
public string EncryptedUID { get; set; }
|
||||
}
|
||||
|
||||
//public class AccountAuthRequest : RequestPacket
|
||||
//{
|
||||
// public override Protocol Protocol
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return NetworkProtocol.Protocol.Account_Auth;
|
||||
// }
|
||||
// }
|
||||
// public long Version { get; set; }
|
||||
// public string DevId { get; set; }
|
||||
// public long IMEI { get; set; }
|
||||
// public string AccessIP { get; set; }
|
||||
// public string MarketId { get; set; }
|
||||
// public string UserType { get; set; }
|
||||
// public string AdvertisementId { get; set; }
|
||||
// public string OSType { get; set; }
|
||||
// public string OSVersion { get; set; }
|
||||
// public string DeviceUniqueId { get; set; }
|
||||
// public string DeviceModel { get; set; }
|
||||
// public int DeviceSystemMemorySize { get; set; }
|
||||
//}
|
||||
public class AccountAuthRequest : RequestPacket
|
||||
{
|
||||
public override Protocol Protocol
|
||||
{
|
||||
get
|
||||
{
|
||||
return NetworkProtocol.Protocol.Account_Auth;
|
||||
}
|
||||
}
|
||||
public long Version { get; set; }
|
||||
public string DevId { get; set; }
|
||||
public long IMEI { get; set; }
|
||||
public string AccessIP { get; set; }
|
||||
public string MarketId { get; set; }
|
||||
public string UserType { get; set; }
|
||||
public string AdvertisementId { get; set; }
|
||||
public string OSType { get; set; }
|
||||
public string OSVersion { get; set; }
|
||||
public string DeviceUniqueId { get; set; }
|
||||
public string DeviceModel { get; set; }
|
||||
public int DeviceSystemMemorySize { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class AccountCurrencySyncResponse : ResponsePacket
|
||||
|
@ -527,36 +527,36 @@ namespace SCHALE.Common.NetworkProtocol
|
|||
}
|
||||
|
||||
|
||||
//public class AccountCheckYostarRequest : RequestPacket
|
||||
//{
|
||||
// public override Protocol Protocol
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return NetworkProtocol.Protocol.Account_CheckYostar;
|
||||
// }
|
||||
// }
|
||||
// public long UID { get; set; }
|
||||
// public string YostarToken { get; set; }
|
||||
// public string EnterTicket { get; set; }
|
||||
// public bool PassCookieResult { get; set; }
|
||||
// public string Cookie { get; set; }
|
||||
//}
|
||||
public class AccountCheckYostarRequest : RequestPacket
|
||||
{
|
||||
public override Protocol Protocol
|
||||
{
|
||||
get
|
||||
{
|
||||
return NetworkProtocol.Protocol.Account_CheckYostar;
|
||||
}
|
||||
}
|
||||
public long UID { get; set; }
|
||||
public string YostarToken { get; set; }
|
||||
public string EnterTicket { get; set; }
|
||||
public bool PassCookieResult { get; set; }
|
||||
public string Cookie { get; set; }
|
||||
}
|
||||
|
||||
|
||||
//public class AccountCheckYostarResponse : ResponsePacket
|
||||
//{
|
||||
// public override Protocol Protocol
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return NetworkProtocol.Protocol.Account_CheckYostar;
|
||||
// }
|
||||
// }
|
||||
// public int ResultState { get; set; }
|
||||
// public string ResultMessag { get; set; }
|
||||
// public string Birth { get; set; }
|
||||
//}
|
||||
public class AccountCheckYostarResponse : ResponsePacket
|
||||
{
|
||||
public override Protocol Protocol
|
||||
{
|
||||
get
|
||||
{
|
||||
return NetworkProtocol.Protocol.Account_CheckYostar;
|
||||
}
|
||||
}
|
||||
public int ResultState { get; set; }
|
||||
public string ResultMessag { get; set; }
|
||||
public string Birth { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class AccountResetRequest : RequestPacket
|
||||
|
@ -9282,23 +9282,23 @@ namespace SCHALE.Common.NetworkProtocol
|
|||
}
|
||||
|
||||
|
||||
//public class QueuingGetTicketRequest : RequestPacket
|
||||
//{
|
||||
// public override Protocol Protocol
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return NetworkProtocol.Protocol.Queuing_GetTicket;
|
||||
// }
|
||||
// }
|
||||
// public long YostarUID { get; set; }
|
||||
// public string YostarToken { get; set; }
|
||||
// public bool MakeStandby { get; set; }
|
||||
// public bool PassCheck { get; set; }
|
||||
// public bool PassCheckYostar { get; set; }
|
||||
// public string WaitingTicket { get; set; }
|
||||
// public string ClientVersion { get; set; }
|
||||
//}
|
||||
public class QueuingGetTicketRequest : RequestPacket
|
||||
{
|
||||
public override Protocol Protocol
|
||||
{
|
||||
get
|
||||
{
|
||||
return NetworkProtocol.Protocol.Queuing_GetTicket;
|
||||
}
|
||||
}
|
||||
public long YostarUID { get; set; }
|
||||
public string YostarToken { get; set; }
|
||||
public bool MakeStandby { get; set; }
|
||||
public bool PassCheck { get; set; }
|
||||
public bool PassCheckYostar { get; set; }
|
||||
public string WaitingTicket { get; set; }
|
||||
public string ClientVersion { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class MultiFloorRaidEnterBattleResponse : ResponsePacket
|
||||
|
@ -9625,26 +9625,26 @@ namespace SCHALE.Common.NetworkProtocol
|
|||
}
|
||||
|
||||
|
||||
//public class QueuingGetTicketResponse : ResponsePacket
|
||||
//{
|
||||
// public override Protocol Protocol
|
||||
// {
|
||||
// get
|
||||
// {
|
||||
// return NetworkProtocol.Protocol.Queuing_GetTicket;
|
||||
// }
|
||||
// }
|
||||
// public string WaitingTicket { get; set; }
|
||||
// public string EnterTicket { get; set; }
|
||||
// public long TicketSequence { get; set; }
|
||||
// public long AllowedSequence { get; set; }
|
||||
// public double RequiredSecondsPerUser { get; set; }
|
||||
// public string Birth { get; set; }
|
||||
// public string ServerSeed { get; set; }
|
||||
// public void Reset()
|
||||
// {
|
||||
// }
|
||||
//}
|
||||
public class QueuingGetTicketResponse : ResponsePacket
|
||||
{
|
||||
public override Protocol Protocol
|
||||
{
|
||||
get
|
||||
{
|
||||
return NetworkProtocol.Protocol.Queuing_GetTicket;
|
||||
}
|
||||
}
|
||||
public string WaitingTicket { get; set; }
|
||||
public string EnterTicket { get; set; }
|
||||
public long TicketSequence { get; set; }
|
||||
public long AllowedSequence { get; set; }
|
||||
public double RequiredSecondsPerUser { get; set; }
|
||||
public string Birth { get; set; }
|
||||
public string ServerSeed { get; set; }
|
||||
public void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class ScenarioRetreatResponse : ResponsePacket
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using SCHALE.Common.Crypto;
|
||||
using SCHALE.Common.NetworkProtocol;
|
||||
using SCHALE.GameServer.Controllers.Api.ProtocolHandlers;
|
||||
using System.Buffers.Binary;
|
||||
using System.IO.Compression;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
@ -59,17 +58,16 @@ namespace SCHALE.GameServer.Controllers.Api
|
|||
}
|
||||
|
||||
var payload = (JsonSerializer.Deserialize(payloadStr, requestType) as RequestPacket)!;
|
||||
var handler = protocolHandlerFactory.GetProtocolHandler(payload.Protocol);
|
||||
if (handler is null)
|
||||
|
||||
var rsp = protocolHandlerFactory.Invoke(protocol, [payload]);
|
||||
if (rsp is null)
|
||||
{
|
||||
logger.LogDebug("{Protocol} {Payload:j}", payload.Protocol, payloadStr);
|
||||
logger.LogError("Protocol {Protocol} is unimplemented and left unhandled", payload.Protocol);
|
||||
|
||||
goto protocolErrorRet;
|
||||
}
|
||||
|
||||
var rsp = handler.Invoke(null, [payload]);
|
||||
|
||||
|
||||
return Results.Json(new
|
||||
{
|
||||
packet = JsonSerializer.Serialize(rsp),
|
||||
|
|
|
@ -1,26 +1,37 @@
|
|||
using SCHALE.Common.NetworkProtocol;
|
||||
using SCHALE.Common.NetworkProtocol.Account;
|
||||
|
||||
namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
||||
{
|
||||
public static class Account
|
||||
public class Account : ProtocolHandlerBase
|
||||
{
|
||||
public Account(IServiceScopeFactory scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) : base(scopeFactory, protocolHandlerFactory) { }
|
||||
|
||||
[ProtocolHandler(Protocol.Account_CheckYostar)]
|
||||
public static ResponsePacket CheckYostarHandler(AccountCheckYostarRequest req)
|
||||
public ResponsePacket CheckYostarHandler(AccountCheckYostarRequest req)
|
||||
{
|
||||
var account = Context.GuestAccounts.SingleOrDefault(x => x.Uid == uint.Parse(req.EnterTicket.Split(":", StringSplitOptions.None).First()) && x.Token == req.EnterTicket.Split(":", StringSplitOptions.None).Last());
|
||||
if (account is null)
|
||||
{
|
||||
return new AccountCheckYostarResponse()
|
||||
{
|
||||
ResultState = 0,
|
||||
ResultMessag = "Invalid account (EnterTicket, AccountCheckYostar)"
|
||||
};
|
||||
}
|
||||
|
||||
return new AccountCheckYostarResponse()
|
||||
{
|
||||
ResultState = 1,
|
||||
SessionKey = new()
|
||||
{
|
||||
MxToken = req.EnterTicket,
|
||||
AccountServerId = 1
|
||||
AccountServerId = account.Uid
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
[ProtocolHandler(Protocol.Account_Auth)]
|
||||
public static ResponsePacket AuthHandler(AccountAuthRequest req)
|
||||
public ResponsePacket AuthHandler(AccountAuthRequest req)
|
||||
{
|
||||
return new ErrorPacket()
|
||||
{
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using SCHALE.Common.NetworkProtocol;
|
||||
using SCHALE.Common.Database;
|
||||
using SCHALE.Common.NetworkProtocol;
|
||||
using Serilog;
|
||||
using System.Reflection;
|
||||
|
||||
|
@ -17,27 +18,20 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
|||
|
||||
public interface IProtocolHandlerFactory
|
||||
{
|
||||
public ResponsePacket? Invoke(Protocol protocol, params object?[]? args);
|
||||
public MethodInfo? GetProtocolHandler(Protocol protocol);
|
||||
public Type? GetRequestPacketTypeByProtocol(Protocol protocol);
|
||||
public void RegisterInstance(Type t, object? inst);
|
||||
}
|
||||
|
||||
public class ProtocolHandlerFactory : IProtocolHandlerFactory
|
||||
{
|
||||
private readonly Dictionary<Protocol, MethodInfo> handlers = [];
|
||||
private readonly Dictionary<Protocol, Type> requestPacketTypes = [];
|
||||
private readonly Dictionary<Type, object?> handlerInstances = [];
|
||||
|
||||
public ProtocolHandlerFactory()
|
||||
{
|
||||
foreach (var method in Assembly.GetExecutingAssembly().GetTypes().SelectMany(x => x.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).Where(x => x.GetCustomAttribute<ProtocolHandlerAttribute>() is not null)))
|
||||
{
|
||||
var attr = method.GetCustomAttribute<ProtocolHandlerAttribute>()!;
|
||||
if (handlers.ContainsKey(attr.Protocol))
|
||||
continue;
|
||||
|
||||
handlers.Add(attr.Protocol, method);
|
||||
Log.Debug($"Loaded {method.Name} for {attr.Protocol}");
|
||||
}
|
||||
|
||||
foreach (var requestPacketType in Assembly.GetAssembly(typeof(RequestPacket))!.GetTypes().Where(x => x.IsAssignableTo(typeof(RequestPacket))))
|
||||
{
|
||||
if (requestPacketType == typeof(RequestPacket))
|
||||
|
@ -53,6 +47,31 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
|||
}
|
||||
}
|
||||
|
||||
public void RegisterInstance(Type t, object? inst)
|
||||
{
|
||||
handlerInstances.Add(t, inst);
|
||||
|
||||
foreach (var method in t.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(x => x.GetCustomAttribute<ProtocolHandlerAttribute>() is not null))
|
||||
{
|
||||
var attr = method.GetCustomAttribute<ProtocolHandlerAttribute>()!;
|
||||
if (handlers.ContainsKey(attr.Protocol))
|
||||
continue;
|
||||
|
||||
handlers.Add(attr.Protocol, method);
|
||||
Log.Debug($"Loaded {method.Name} for {attr.Protocol}");
|
||||
}
|
||||
}
|
||||
|
||||
public ResponsePacket? Invoke(Protocol protocol, params object?[]? args)
|
||||
{
|
||||
var handler = GetProtocolHandler(protocol);
|
||||
if (handler is null)
|
||||
return null;
|
||||
|
||||
handlerInstances.TryGetValue(handler.DeclaringType!, out var inst);
|
||||
return (ResponsePacket?)handler.Invoke(inst, args);
|
||||
}
|
||||
|
||||
public MethodInfo? GetProtocolHandler(Protocol protocol)
|
||||
{
|
||||
handlers.TryGetValue(protocol, out var handler);
|
||||
|
@ -68,11 +87,50 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
|||
}
|
||||
}
|
||||
|
||||
public abstract class ProtocolHandlerBase : IHostedService
|
||||
{
|
||||
private readonly IServiceScopeFactory scopeFactory;
|
||||
|
||||
public ProtocolHandlerBase(IServiceScopeFactory _scopeFactory, IProtocolHandlerFactory protocolHandlerFactory)
|
||||
{
|
||||
scopeFactory = _scopeFactory;
|
||||
protocolHandlerFactory.RegisterInstance(GetType(), this);
|
||||
}
|
||||
|
||||
public SCHALEContext Context
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var scope = scopeFactory.CreateScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<SCHALEContext>();
|
||||
|
||||
return db;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class ServiceExtensions
|
||||
{
|
||||
public static void AddProtocolHandlerFactory(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<IProtocolHandlerFactory, ProtocolHandlerFactory>();
|
||||
}
|
||||
|
||||
public static void AddProtocolHandlerGroup<T>(this IServiceCollection services) where T : ProtocolHandlerBase
|
||||
{
|
||||
services.AddHostedService<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
using SCHALE.Common.NetworkProtocol;
|
||||
using SCHALE.Common.NetworkProtocol.Queuing;
|
||||
|
||||
namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
||||
{
|
||||
public static class Queuing
|
||||
public class Queuing : ProtocolHandlerBase
|
||||
{
|
||||
public Queuing(IServiceScopeFactory scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) : base(scopeFactory, protocolHandlerFactory) { }
|
||||
|
||||
[ProtocolHandler(Protocol.Queuing_GetTicket)]
|
||||
public static ResponsePacket GetTicketHandler(QueuingGetTicketRequest req)
|
||||
public ResponsePacket GetTicketHandler(QueuingGetTicketRequest req)
|
||||
{
|
||||
return new QueuingGetTicketResponse()
|
||||
{
|
||||
EnterTicket = req.YostarToken
|
||||
EnterTicket = $"{req.YostarUID}:{req.YostarToken}"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@ namespace SCHALE.GameServer.Controllers
|
|||
public IResult Create([FromForm] string deviceId)
|
||||
{
|
||||
UserCreateResponse rsp = new() { Result = 0, IsNew = 0 };
|
||||
var account = context.Accounts.SingleOrDefault(x => x.DeviceId == deviceId);
|
||||
var account = context.GuestAccounts.SingleOrDefault(x => x.DeviceId == deviceId);
|
||||
|
||||
if (account is null)
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ namespace SCHALE.GameServer.Controllers
|
|||
[HttpPost("login")]
|
||||
public IResult Login([FromForm] uint uid, [FromForm] string token, [FromForm] string storeId)
|
||||
{
|
||||
var account = context.Accounts.SingleOrDefault(x => x.Uid == uid && x.Token == token);
|
||||
var account = context.GuestAccounts.SingleOrDefault(x => x.Uid == uid && x.Token == token);
|
||||
if (account is not null)
|
||||
{
|
||||
return Results.Json(new UserLoginResponse()
|
||||
|
|
|
@ -46,6 +46,8 @@ namespace SCHALE.GameServer
|
|||
builder.Services.AddControllers();
|
||||
builder.Services.AddMongoDBProvider(config.GetConnectionString("MongoDB") ?? throw new ArgumentNullException("ConnectionStrings/MongoDB in appsettings is missing"));
|
||||
builder.Services.AddProtocolHandlerFactory();
|
||||
builder.Services.AddProtocolHandlerGroup<Account>();
|
||||
builder.Services.AddProtocolHandlerGroup<Queuing>();
|
||||
|
||||
var app = builder.Build();
|
||||
|
||||
|
|
Loading…
Reference in New Issue