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
|
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.
|
#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]
|
[Key]
|
||||||
[Column("_id")]
|
[Column("_id")]
|
|
@ -3,11 +3,13 @@ using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||||
using Microsoft.EntityFrameworkCore.ValueGeneration;
|
using Microsoft.EntityFrameworkCore.ValueGeneration;
|
||||||
using MongoDB.EntityFrameworkCore.Extensions;
|
using MongoDB.EntityFrameworkCore.Extensions;
|
||||||
using SCHALE.Common.Database.Models;
|
using SCHALE.Common.Database.Models;
|
||||||
|
using SCHALE.Common.Database.Models.Game;
|
||||||
|
|
||||||
namespace SCHALE.Common.Database
|
namespace SCHALE.Common.Database
|
||||||
{
|
{
|
||||||
public class SCHALEContext : DbContext
|
public class SCHALEContext : DbContext
|
||||||
{
|
{
|
||||||
|
public DbSet<GuestAccount> GuestAccounts { get; set; }
|
||||||
public DbSet<Account> Accounts { get; set; }
|
public DbSet<Account> Accounts { get; set; }
|
||||||
public DbSet<Counter> Counters { get; set; }
|
public DbSet<Counter> Counters { get; set; }
|
||||||
|
|
||||||
|
@ -19,42 +21,66 @@ namespace SCHALE.Common.Database
|
||||||
{
|
{
|
||||||
|
|
||||||
base.OnModelCreating(modelBuilder);
|
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<Account>().ToCollection("accounts");
|
||||||
|
|
||||||
modelBuilder.Entity<Counter>().ToCollection("counters");
|
modelBuilder.Entity<Counter>().ToCollection("counters");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
class AccountAutoIncrementValueGenerator : AutoIncrementValueGenerator
|
private 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)
|
|
||||||
{
|
{
|
||||||
if (entry.Context is not SCHALEContext)
|
protected override string Collection => "account";
|
||||||
{
|
}
|
||||||
throw new ArgumentNullException($"{nameof(AutoIncrementValueGenerator)} is only implemented for {nameof(SCHALEContext)}");
|
|
||||||
}
|
|
||||||
|
|
||||||
var context = ((SCHALEContext)entry.Context);
|
private class GuestAccountAutoIncrementValueGenerator : AutoIncrementValueGenerator
|
||||||
var counter = context.Counters.SingleOrDefault(x => x.Id == Collection);
|
{
|
||||||
|
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 };
|
if (entry.Context is not SCHALEContext)
|
||||||
context.Add(counter);
|
{
|
||||||
|
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();
|
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
|
namespace SCHALE.Common.NetworkProtocol
|
||||||
{
|
{
|
||||||
|
@ -36,8 +37,8 @@ namespace SCHALE.Common.NetworkProtocol
|
||||||
{
|
{
|
||||||
public long ServerTimeTicks { get; set; } = DateTimeOffset.Now.Ticks;
|
public long ServerTimeTicks { get; set; } = DateTimeOffset.Now.Ticks;
|
||||||
public ServerNotificationFlag ServerNotification { get; set; }
|
public ServerNotificationFlag ServerNotification { get; set; }
|
||||||
// public List<MissionProgressDB> MissionProgressDBs { get; set; }
|
public List<MissionProgressDB> MissionProgressDBs { get; set; }
|
||||||
// public Dictionary<long, List<MissionProgressDB>> EventMissionProgressDBDict { get; set; }
|
public Dictionary<long, List<MissionProgressDB>> EventMissionProgressDBDict { get; set; }
|
||||||
// public Dictionary<OpenConditionContent, OpenConditionLockReason> StaticOpenConditions { 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 string EncryptedUID { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
//public class AccountAuthRequest : RequestPacket
|
public class AccountAuthRequest : RequestPacket
|
||||||
//{
|
{
|
||||||
// public override Protocol Protocol
|
public override Protocol Protocol
|
||||||
// {
|
{
|
||||||
// get
|
get
|
||||||
// {
|
{
|
||||||
// return NetworkProtocol.Protocol.Account_Auth;
|
return NetworkProtocol.Protocol.Account_Auth;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// public long Version { get; set; }
|
public long Version { get; set; }
|
||||||
// public string DevId { get; set; }
|
public string DevId { get; set; }
|
||||||
// public long IMEI { get; set; }
|
public long IMEI { get; set; }
|
||||||
// public string AccessIP { get; set; }
|
public string AccessIP { get; set; }
|
||||||
// public string MarketId { get; set; }
|
public string MarketId { get; set; }
|
||||||
// public string UserType { get; set; }
|
public string UserType { get; set; }
|
||||||
// public string AdvertisementId { get; set; }
|
public string AdvertisementId { get; set; }
|
||||||
// public string OSType { get; set; }
|
public string OSType { get; set; }
|
||||||
// public string OSVersion { get; set; }
|
public string OSVersion { get; set; }
|
||||||
// public string DeviceUniqueId { get; set; }
|
public string DeviceUniqueId { get; set; }
|
||||||
// public string DeviceModel { get; set; }
|
public string DeviceModel { get; set; }
|
||||||
// public int DeviceSystemMemorySize { get; set; }
|
public int DeviceSystemMemorySize { get; set; }
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class AccountCurrencySyncResponse : ResponsePacket
|
public class AccountCurrencySyncResponse : ResponsePacket
|
||||||
|
@ -527,36 +527,36 @@ namespace SCHALE.Common.NetworkProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public class AccountCheckYostarRequest : RequestPacket
|
public class AccountCheckYostarRequest : RequestPacket
|
||||||
//{
|
{
|
||||||
// public override Protocol Protocol
|
public override Protocol Protocol
|
||||||
// {
|
{
|
||||||
// get
|
get
|
||||||
// {
|
{
|
||||||
// return NetworkProtocol.Protocol.Account_CheckYostar;
|
return NetworkProtocol.Protocol.Account_CheckYostar;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// public long UID { get; set; }
|
public long UID { get; set; }
|
||||||
// public string YostarToken { get; set; }
|
public string YostarToken { get; set; }
|
||||||
// public string EnterTicket { get; set; }
|
public string EnterTicket { get; set; }
|
||||||
// public bool PassCookieResult { get; set; }
|
public bool PassCookieResult { get; set; }
|
||||||
// public string Cookie { get; set; }
|
public string Cookie { get; set; }
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public class AccountCheckYostarResponse : ResponsePacket
|
public class AccountCheckYostarResponse : ResponsePacket
|
||||||
//{
|
{
|
||||||
// public override Protocol Protocol
|
public override Protocol Protocol
|
||||||
// {
|
{
|
||||||
// get
|
get
|
||||||
// {
|
{
|
||||||
// return NetworkProtocol.Protocol.Account_CheckYostar;
|
return NetworkProtocol.Protocol.Account_CheckYostar;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// public int ResultState { get; set; }
|
public int ResultState { get; set; }
|
||||||
// public string ResultMessag { get; set; }
|
public string ResultMessag { get; set; }
|
||||||
// public string Birth { get; set; }
|
public string Birth { get; set; }
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class AccountResetRequest : RequestPacket
|
public class AccountResetRequest : RequestPacket
|
||||||
|
@ -9282,23 +9282,23 @@ namespace SCHALE.Common.NetworkProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public class QueuingGetTicketRequest : RequestPacket
|
public class QueuingGetTicketRequest : RequestPacket
|
||||||
//{
|
{
|
||||||
// public override Protocol Protocol
|
public override Protocol Protocol
|
||||||
// {
|
{
|
||||||
// get
|
get
|
||||||
// {
|
{
|
||||||
// return NetworkProtocol.Protocol.Queuing_GetTicket;
|
return NetworkProtocol.Protocol.Queuing_GetTicket;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// public long YostarUID { get; set; }
|
public long YostarUID { get; set; }
|
||||||
// public string YostarToken { get; set; }
|
public string YostarToken { get; set; }
|
||||||
// public bool MakeStandby { get; set; }
|
public bool MakeStandby { get; set; }
|
||||||
// public bool PassCheck { get; set; }
|
public bool PassCheck { get; set; }
|
||||||
// public bool PassCheckYostar { get; set; }
|
public bool PassCheckYostar { get; set; }
|
||||||
// public string WaitingTicket { get; set; }
|
public string WaitingTicket { get; set; }
|
||||||
// public string ClientVersion { get; set; }
|
public string ClientVersion { get; set; }
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class MultiFloorRaidEnterBattleResponse : ResponsePacket
|
public class MultiFloorRaidEnterBattleResponse : ResponsePacket
|
||||||
|
@ -9625,26 +9625,26 @@ namespace SCHALE.Common.NetworkProtocol
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//public class QueuingGetTicketResponse : ResponsePacket
|
public class QueuingGetTicketResponse : ResponsePacket
|
||||||
//{
|
{
|
||||||
// public override Protocol Protocol
|
public override Protocol Protocol
|
||||||
// {
|
{
|
||||||
// get
|
get
|
||||||
// {
|
{
|
||||||
// return NetworkProtocol.Protocol.Queuing_GetTicket;
|
return NetworkProtocol.Protocol.Queuing_GetTicket;
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// public string WaitingTicket { get; set; }
|
public string WaitingTicket { get; set; }
|
||||||
// public string EnterTicket { get; set; }
|
public string EnterTicket { get; set; }
|
||||||
// public long TicketSequence { get; set; }
|
public long TicketSequence { get; set; }
|
||||||
// public long AllowedSequence { get; set; }
|
public long AllowedSequence { get; set; }
|
||||||
// public double RequiredSecondsPerUser { get; set; }
|
public double RequiredSecondsPerUser { get; set; }
|
||||||
// public string Birth { get; set; }
|
public string Birth { get; set; }
|
||||||
// public string ServerSeed { get; set; }
|
public string ServerSeed { get; set; }
|
||||||
// public void Reset()
|
public void Reset()
|
||||||
// {
|
{
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class ScenarioRetreatResponse : ResponsePacket
|
public class ScenarioRetreatResponse : ResponsePacket
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
using SCHALE.Common.Crypto;
|
using SCHALE.Common.Crypto;
|
||||||
using SCHALE.Common.NetworkProtocol;
|
using SCHALE.Common.NetworkProtocol;
|
||||||
using SCHALE.GameServer.Controllers.Api.ProtocolHandlers;
|
using SCHALE.GameServer.Controllers.Api.ProtocolHandlers;
|
||||||
using System.Buffers.Binary;
|
|
||||||
using System.IO.Compression;
|
using System.IO.Compression;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
|
@ -59,17 +58,16 @@ namespace SCHALE.GameServer.Controllers.Api
|
||||||
}
|
}
|
||||||
|
|
||||||
var payload = (JsonSerializer.Deserialize(payloadStr, requestType) as RequestPacket)!;
|
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.LogDebug("{Protocol} {Payload:j}", payload.Protocol, payloadStr);
|
||||||
logger.LogError("Protocol {Protocol} is unimplemented and left unhandled", payload.Protocol);
|
logger.LogError("Protocol {Protocol} is unimplemented and left unhandled", payload.Protocol);
|
||||||
|
|
||||||
goto protocolErrorRet;
|
goto protocolErrorRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
var rsp = handler.Invoke(null, [payload]);
|
|
||||||
|
|
||||||
return Results.Json(new
|
return Results.Json(new
|
||||||
{
|
{
|
||||||
packet = JsonSerializer.Serialize(rsp),
|
packet = JsonSerializer.Serialize(rsp),
|
||||||
|
|
|
@ -1,26 +1,37 @@
|
||||||
using SCHALE.Common.NetworkProtocol;
|
using SCHALE.Common.NetworkProtocol;
|
||||||
using SCHALE.Common.NetworkProtocol.Account;
|
|
||||||
|
|
||||||
namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
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)]
|
[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()
|
return new AccountCheckYostarResponse()
|
||||||
{
|
{
|
||||||
ResultState = 1,
|
ResultState = 1,
|
||||||
SessionKey = new()
|
SessionKey = new()
|
||||||
{
|
{
|
||||||
MxToken = req.EnterTicket,
|
MxToken = req.EnterTicket,
|
||||||
AccountServerId = 1
|
AccountServerId = account.Uid
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[ProtocolHandler(Protocol.Account_Auth)]
|
[ProtocolHandler(Protocol.Account_Auth)]
|
||||||
public static ResponsePacket AuthHandler(AccountAuthRequest req)
|
public ResponsePacket AuthHandler(AccountAuthRequest req)
|
||||||
{
|
{
|
||||||
return new ErrorPacket()
|
return new ErrorPacket()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
using SCHALE.Common.NetworkProtocol;
|
using SCHALE.Common.Database;
|
||||||
|
using SCHALE.Common.NetworkProtocol;
|
||||||
using Serilog;
|
using Serilog;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
|
@ -17,27 +18,20 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
||||||
|
|
||||||
public interface IProtocolHandlerFactory
|
public interface IProtocolHandlerFactory
|
||||||
{
|
{
|
||||||
|
public ResponsePacket? Invoke(Protocol protocol, params object?[]? args);
|
||||||
public MethodInfo? GetProtocolHandler(Protocol protocol);
|
public MethodInfo? GetProtocolHandler(Protocol protocol);
|
||||||
public Type? GetRequestPacketTypeByProtocol(Protocol protocol);
|
public Type? GetRequestPacketTypeByProtocol(Protocol protocol);
|
||||||
|
public void RegisterInstance(Type t, object? inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ProtocolHandlerFactory : IProtocolHandlerFactory
|
public class ProtocolHandlerFactory : IProtocolHandlerFactory
|
||||||
{
|
{
|
||||||
private readonly Dictionary<Protocol, MethodInfo> handlers = [];
|
private readonly Dictionary<Protocol, MethodInfo> handlers = [];
|
||||||
private readonly Dictionary<Protocol, Type> requestPacketTypes = [];
|
private readonly Dictionary<Protocol, Type> requestPacketTypes = [];
|
||||||
|
private readonly Dictionary<Type, object?> handlerInstances = [];
|
||||||
|
|
||||||
public ProtocolHandlerFactory()
|
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))))
|
foreach (var requestPacketType in Assembly.GetAssembly(typeof(RequestPacket))!.GetTypes().Where(x => x.IsAssignableTo(typeof(RequestPacket))))
|
||||||
{
|
{
|
||||||
if (requestPacketType == 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)
|
public MethodInfo? GetProtocolHandler(Protocol protocol)
|
||||||
{
|
{
|
||||||
handlers.TryGetValue(protocol, out var handler);
|
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
|
internal static class ServiceExtensions
|
||||||
{
|
{
|
||||||
public static void AddProtocolHandlerFactory(this IServiceCollection services)
|
public static void AddProtocolHandlerFactory(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddSingleton<IProtocolHandlerFactory, ProtocolHandlerFactory>();
|
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;
|
||||||
using SCHALE.Common.NetworkProtocol.Queuing;
|
|
||||||
|
|
||||||
namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
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)]
|
[ProtocolHandler(Protocol.Queuing_GetTicket)]
|
||||||
public static ResponsePacket GetTicketHandler(QueuingGetTicketRequest req)
|
public ResponsePacket GetTicketHandler(QueuingGetTicketRequest req)
|
||||||
{
|
{
|
||||||
return new QueuingGetTicketResponse()
|
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)
|
public IResult Create([FromForm] string deviceId)
|
||||||
{
|
{
|
||||||
UserCreateResponse rsp = new() { Result = 0, IsNew = 0 };
|
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)
|
if (account is null)
|
||||||
{
|
{
|
||||||
|
@ -49,7 +49,7 @@ namespace SCHALE.GameServer.Controllers
|
||||||
[HttpPost("login")]
|
[HttpPost("login")]
|
||||||
public IResult Login([FromForm] uint uid, [FromForm] string token, [FromForm] string storeId)
|
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)
|
if (account is not null)
|
||||||
{
|
{
|
||||||
return Results.Json(new UserLoginResponse()
|
return Results.Json(new UserLoginResponse()
|
||||||
|
|
|
@ -46,6 +46,8 @@ namespace SCHALE.GameServer
|
||||||
builder.Services.AddControllers();
|
builder.Services.AddControllers();
|
||||||
builder.Services.AddMongoDBProvider(config.GetConnectionString("MongoDB") ?? throw new ArgumentNullException("ConnectionStrings/MongoDB in appsettings is missing"));
|
builder.Services.AddMongoDBProvider(config.GetConnectionString("MongoDB") ?? throw new ArgumentNullException("ConnectionStrings/MongoDB in appsettings is missing"));
|
||||||
builder.Services.AddProtocolHandlerFactory();
|
builder.Services.AddProtocolHandlerFactory();
|
||||||
|
builder.Services.AddProtocolHandlerGroup<Account>();
|
||||||
|
builder.Services.AddProtocolHandlerGroup<Queuing>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue