From 7aa5b297d0d65a42bcd42383daef80f8cf2fd70a Mon Sep 17 00:00:00 2001 From: rfi Date: Sun, 28 Apr 2024 08:41:38 +0700 Subject: [PATCH] yet another new system --- SCHALE.Common/Database/Models/Counter.cs | 2 +- SCHALE.Common/Database/Models/Game/Account.cs | 39 -- SCHALE.Common/Database/Models/Game/Player.cs | 14 - SCHALE.Common/Database/Models/GuestAccount.cs | 6 +- SCHALE.Common/Database/SCHALEContext.cs | 30 +- SCHALE.Common/Database/ServicesExtesions.cs | 27 +- SCHALE.Common/Database/dbs.cs | 37 +- SCHALE.Common/NetworkProtocol/Packet.cs | 3 +- .../Controllers/Api/GatewayController.cs | 5 +- .../Api/ProtocolHandlers/Academy.cs | 18 +- .../Api/ProtocolHandlers/Account.cs | 300 +++++++-------- .../Api/ProtocolHandlers/Mission.cs | 342 +----------------- .../Api/ProtocolHandlers/ProofToken.cs | 18 +- .../ProtocolHandlerFactory.cs | 23 +- .../Api/ProtocolHandlers/Queuing.cs | 2 +- .../Api/ProtocolHandlers/Scenario.cs | 2 +- SCHALE.GameServer/GameServer.cs | 2 + SCHALE.GameServer/Models/User.cs | 2 +- .../Services/SessionKeyService.cs | 75 ++++ 19 files changed, 328 insertions(+), 619 deletions(-) delete mode 100644 SCHALE.Common/Database/Models/Game/Account.cs delete mode 100644 SCHALE.Common/Database/Models/Game/Player.cs create mode 100644 SCHALE.GameServer/Services/SessionKeyService.cs diff --git a/SCHALE.Common/Database/Models/Counter.cs b/SCHALE.Common/Database/Models/Counter.cs index 80bd046..581a94c 100644 --- a/SCHALE.Common/Database/Models/Counter.cs +++ b/SCHALE.Common/Database/Models/Counter.cs @@ -9,6 +9,6 @@ namespace SCHALE.Common.Database.Models [Key] [Column("_id")] public string Id { get; set; } - public uint Seq { get; set; } + public long Seq { get; set; } } } diff --git a/SCHALE.Common/Database/Models/Game/Account.cs b/SCHALE.Common/Database/Models/Game/Account.cs deleted file mode 100644 index 16ba73a..0000000 --- a/SCHALE.Common/Database/Models/Game/Account.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.ComponentModel.DataAnnotations.Schema; -using System.ComponentModel.DataAnnotations; -using SCHALE.Common.FlatData; -using MongoDB.Bson.Serialization.Attributes; -using MongoDB.Driver.Core.Servers; - -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 - { - [Key] - [Column("_id")] - public required uint ServerId { get; set; } - - public AccountDB AccountDB { get; set; } - - public static Account Create(uint guest_account_uid) // make sure ServerId matches GuestAccount UID - { - Account account = new() - { - ServerId = guest_account_uid, - AccountDB = new AccountDB() - { - ServerId = guest_account_uid, - State = AccountState.Normal, - Level = 0, - Exp = 0, - RepresentCharacterServerId = 1037810385, // i think this is the default - LastConnectTime = DateTime.Now, - CreateDate = DateTime.Now, - } - }; - - return account; - } - - } -} diff --git a/SCHALE.Common/Database/Models/Game/Player.cs b/SCHALE.Common/Database/Models/Game/Player.cs deleted file mode 100644 index 865f82f..0000000 --- a/SCHALE.Common/Database/Models/Game/Player.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.ComponentModel.DataAnnotations.Schema; -using System.ComponentModel.DataAnnotations; - -namespace SCHALE.Common.Database.Models.Game -{ - public class Player - { - [Key] - [Column("_id")] - public required uint ServerId { get; set; } - - public List MissionProgressDBs { get; set; } - } -} diff --git a/SCHALE.Common/Database/Models/GuestAccount.cs b/SCHALE.Common/Database/Models/GuestAccount.cs index 11e89d0..479a7c6 100644 --- a/SCHALE.Common/Database/Models/GuestAccount.cs +++ b/SCHALE.Common/Database/Models/GuestAccount.cs @@ -6,12 +6,12 @@ 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 GuestAccount { - public uint Uid { get; set; } + [Key] + [Column("_id")] + public long Uid { get; set; } public string DeviceId { get; set; } - [Key] - [Column("_id")] public string Token { get; set; } } } diff --git a/SCHALE.Common/Database/SCHALEContext.cs b/SCHALE.Common/Database/SCHALEContext.cs index 1f2dac6..0951a88 100644 --- a/SCHALE.Common/Database/SCHALEContext.cs +++ b/SCHALE.Common/Database/SCHALEContext.cs @@ -3,18 +3,16 @@ using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ValueGeneration; using MongoDB.EntityFrameworkCore.Extensions; using SCHALE.Common.Database.Models; -using SCHALE.Common.Database.Models.Game; +using System.Text.Json; namespace SCHALE.Common.Database { public class SCHALEContext : DbContext { public DbSet GuestAccounts { get; set; } - public DbSet Accounts { get; set; } + public DbSet Accounts { get; set; } + public DbSet MissionProgresses { get; set; } public DbSet Counters { get; set; } - public DbSet Players { get; set; } - - public Player CurrentPlayer { get { return Players.FirstOrDefault();} } // temp public SCHALEContext(DbContextOptions options) : base(options) { @@ -27,26 +25,36 @@ namespace SCHALE.Common.Database modelBuilder.Entity().Property(x => x.Uid).HasValueGenerator(); modelBuilder.Entity().ToCollection("guest_accounts"); - modelBuilder.Entity().ToCollection("accounts"); - modelBuilder.Entity().ToCollection("players"); + modelBuilder.Entity().Property(x => x.ServerId).HasValueGenerator(); + modelBuilder.Entity().ToCollection("accounts"); - // attempt to fix MissionProgressDB.Dictionary ProgressParameters serialization - modelBuilder.Entity().Property(e => e.MissionProgressDBs).HasJsonConversion>(); + modelBuilder.Entity().Property(x => x.ServerId).HasValueGenerator(); + modelBuilder.Entity().ToCollection("mission_progresses"); modelBuilder.Entity().ToCollection("counters"); } + private class AccountAutoIncrementValueGenerator : AutoIncrementValueGenerator + { + protected override string Collection => "account"; + } + private class GuestAccountAutoIncrementValueGenerator : AutoIncrementValueGenerator { protected override string Collection => "guest_account"; } - private abstract class AutoIncrementValueGenerator : ValueGenerator + private class MissionProgressAutoIncrementValueGenerator : AutoIncrementValueGenerator + { + protected override string Collection => "mission_progress"; + } + + private abstract class AutoIncrementValueGenerator : ValueGenerator { protected abstract string Collection { get; } public override bool GeneratesTemporaryValues => false; - public override uint Next(EntityEntry entry) + public override long Next(EntityEntry entry) { if (entry.Context is not SCHALEContext) { diff --git a/SCHALE.Common/Database/ServicesExtesions.cs b/SCHALE.Common/Database/ServicesExtesions.cs index c126540..3e7fe8f 100644 --- a/SCHALE.Common/Database/ServicesExtesions.cs +++ b/SCHALE.Common/Database/ServicesExtesions.cs @@ -14,32 +14,7 @@ namespace SCHALE.Common.Database services.AddDbContext(opt => { opt.UseMongoDB(connectionString, "SCHALE"); - }); - } - } - - public static class ValueConversionExtensions - { - public static PropertyBuilder HasJsonConversion(this PropertyBuilder propertyBuilder) where T : class, new() - { - ValueConverter converter = new ValueConverter - ( - v => JsonConvert.SerializeObject(v), - v => JsonConvert.DeserializeObject(v) ?? new T() - ); - - ValueComparer comparer = new ValueComparer - ( - (l, r) => JsonConvert.SerializeObject(l) == JsonConvert.SerializeObject(r), - v => v == null ? 0 : JsonConvert.SerializeObject(v).GetHashCode(), - v => JsonConvert.DeserializeObject(JsonConvert.SerializeObject(v)) - ); - - propertyBuilder.HasConversion(converter); - propertyBuilder.Metadata.SetValueConverter(converter); - propertyBuilder.Metadata.SetValueComparer(comparer); - - return propertyBuilder; + }, ServiceLifetime.Singleton, ServiceLifetime.Singleton); } } } diff --git a/SCHALE.Common/Database/dbs.cs b/SCHALE.Common/Database/dbs.cs index 380e379..c880230 100644 --- a/SCHALE.Common/Database/dbs.cs +++ b/SCHALE.Common/Database/dbs.cs @@ -1,10 +1,9 @@ -using MongoDB.Bson.Serialization.Attributes; -using MongoDB.Bson.Serialization.Options; +using Newtonsoft.Json; using SCHALE.Common.FlatData; using SCHALE.Common.NetworkProtocol; using SCHALE.Common.Parcel; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Text.Json.Serialization; namespace SCHALE.Common.Database { @@ -186,6 +185,19 @@ namespace SCHALE.Common.Database public class AccountDB { + public AccountDB() { } + + public AccountDB(long publisherAccountId) + { + PublisherAccountId = publisherAccountId; + State = AccountState.Normal; + Level = 1; + LastConnectTime = DateTime.Now; + CreateDate = DateTime.Now; + } + + [Key] + [Column("_id")] public long ServerId { get; set; } public string Nickname { get; set; } @@ -1526,6 +1538,8 @@ namespace SCHALE.Common.Database public class MissionProgressDB { + [Key] + [Column("_id")] [JsonIgnore] public long ServerId { get; set; } @@ -1536,8 +1550,21 @@ namespace SCHALE.Common.Database public bool Complete { get; set; } public DateTime StartTime { get; set; } - [BsonDictionaryOptions(DictionaryRepresentation.ArrayOfArrays)] - public Dictionary ProgressParameters { get; set; } + [JsonIgnore] + public string SerializedProgressParameters { get; private set; } = "{}"; + + [NotMapped] + public Dictionary ProgressParameters + { + get + { + return JsonConvert.DeserializeObject>(SerializedProgressParameters) ?? []; + } + set + { + SerializedProgressParameters = JsonConvert.SerializeObject(value); + } + } } diff --git a/SCHALE.Common/NetworkProtocol/Packet.cs b/SCHALE.Common/NetworkProtocol/Packet.cs index 36d95cd..61192c9 100644 --- a/SCHALE.Common/NetworkProtocol/Packet.cs +++ b/SCHALE.Common/NetworkProtocol/Packet.cs @@ -1,6 +1,5 @@ using SCHALE.Common.Database; using SCHALE.Common.FlatData; -using System.Text.Json.Serialization; namespace SCHALE.Common.NetworkProtocol { @@ -40,7 +39,7 @@ namespace SCHALE.Common.NetworkProtocol public ServerNotificationFlag ServerNotification { get; set; } public List MissionProgressDBs { get; set; } public Dictionary> EventMissionProgressDBDict { get; set; } - public Dictionary StaticOpenConditions { get; set; } + public Dictionary StaticOpenConditions { get; set; } } [Flags] diff --git a/SCHALE.GameServer/Controllers/Api/GatewayController.cs b/SCHALE.GameServer/Controllers/Api/GatewayController.cs index 4a7deaa..a396595 100644 --- a/SCHALE.GameServer/Controllers/Api/GatewayController.cs +++ b/SCHALE.GameServer/Controllers/Api/GatewayController.cs @@ -62,7 +62,7 @@ namespace SCHALE.GameServer.Controllers.Api goto protocolErrorRet; } - logger.LogDebug(Encoding.ASCII.GetString(payloadMs.ToArray())); + logger.LogDebug(payloadStr); var payload = (JsonSerializer.Deserialize(payloadStr, requestType) as RequestPacket)!; @@ -78,6 +78,9 @@ namespace SCHALE.GameServer.Controllers.Api goto protocolErrorRet; } + if ((rsp as BasePacket)!.SessionKey is null) + (rsp as BasePacket)!.SessionKey = payload.SessionKey; + return Results.Json(new { packet = JsonSerializer.Serialize(rsp), diff --git a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Academy.cs b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Academy.cs index b21dcb9..f077d70 100644 --- a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Academy.cs +++ b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Academy.cs @@ -5,14 +5,20 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers { public class Academy : ProtocolHandlerBase { - public Academy(IServiceScopeFactory scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) : base(scopeFactory, protocolHandlerFactory) { } + private SCHALEContext context; + + public Academy(IProtocolHandlerFactory protocolHandlerFactory, SCHALEContext _context) : base(protocolHandlerFactory) + { + context = _context; + } [ProtocolHandler(Protocol.Academy_GetInfo)] public ResponsePacket GetInfoHandler(AcademyGetInfoRequest req) { - //Context.CurrentPlayer.MissionProgressDBs - var MissionProgressDBs = new List { - new MissionProgressDB() { + // context.CurrentPlayer.MissionProgressDBs + var MissionProgressDBs = new List + { + new() { MissionUniqueId = 1700, Complete = false, StartTime = DateTime.UtcNow, @@ -27,11 +33,11 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers { AcademyDB = new() { - AccountId = Context.CurrentPlayer.ServerId, + AccountId = req.SessionKey?.AccountServerId ?? 0 }, AcademyLocationDBs = [], MissionProgressDBs = MissionProgressDBs, - //MissionProgressDBs = Context.CurrentPlayer.MissionProgressDBs, + //MissionProgressDBs = context.CurrentPlayer.MissionProgressDBs, }; } } diff --git a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Account.cs b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Account.cs index d997113..1007bbe 100644 --- a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Account.cs +++ b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Account.cs @@ -1,23 +1,28 @@ using SCHALE.Common.Database; -using SCHALE.Common.FlatData; using SCHALE.Common.NetworkProtocol; -using SCHALE.Common.Parcel; -using SCHALE.Common.Database.Models.Game; -using Serilog; +using SCHALE.GameServer.Services; +using MongoDB.Driver.Linq; namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers { public class Account : ProtocolHandlerBase { - public Account(IServiceScopeFactory scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) : base(scopeFactory, protocolHandlerFactory) { } + private ISessionKeyService sessionKeyService; + private SCHALEContext context; + + public Account(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context) : base(protocolHandlerFactory) + { + sessionKeyService = _sessionKeyService; + context = _context; + } // most handlers empty [ProtocolHandler(Protocol.Account_CheckYostar)] public ResponsePacket CheckYostarHandler(AccountCheckYostarRequest req) { - string[] uid_token = req.EnterTicket.Split(':'); + string[] uidToken = req.EnterTicket.Split(':'); - var account = Context.GuestAccounts.SingleOrDefault(x => x.Uid == uint.Parse(uid_token[0]) && x.Token == uid_token[1]); + var account = context.GuestAccounts.SingleOrDefault(x => x.Uid == long.Parse(uidToken[0]) && x.Token == uidToken[1]); if (account is null) { @@ -31,139 +36,29 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers return new AccountCheckYostarResponse() { ResultState = 1, - SessionKey = new() - { - AccountServerId = account.Uid, - MxToken = req.EnterTicket, - } + SessionKey = sessionKeyService.Create(account.Uid) ?? new SessionKey() { MxToken = req.EnterTicket } }; } [ProtocolHandler(Protocol.Account_Auth)] public ResponsePacket AuthHandler(AccountAuthRequest req) { - var account = Context.Accounts.SingleOrDefault(x => x.ServerId == req.AccountId); - - if (account == null) + if (req.SessionKey is null || req.SessionKey.AccountServerId == 0) { return new ErrorPacket() { ErrorCode = WebAPIErrorCode.AccountAuthNotCreated }; - } else + } + else { + var account = sessionKeyService.GetAccount(req.SessionKey); + return new AccountAuthResponse() { CurrentVersion = req.Version, - AccountDB = account.AccountDB, - - SessionKey = new() - { - AccountServerId = account.ServerId, - MxToken = req.SessionKey.MxToken, - }, - - MissionProgressDBs = new List - { - new MissionProgressDB - { - MissionUniqueId = 1501, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44") }, - new MissionProgressDB - { - MissionUniqueId = 1700, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1500, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44") }, - new MissionProgressDB - { - MissionUniqueId = 2200, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 }, { 1, 5 } } - }, - new MissionProgressDB - { - MissionUniqueId = 300000, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000210, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000220, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000230, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000240, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000250, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000260, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000270, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001327, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001357, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001377, - Complete = true, - StartTime = DateTime.Parse("2024-04-26T20:46:44"), - ProgressParameters = new Dictionary { { 0, 1 } } - }, - } + AccountDB = account, + MissionProgressDBs = [.. context.MissionProgresses.Where(x => x.AccountServerId == account.ServerId)] }; } @@ -172,37 +67,153 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers [ProtocolHandler(Protocol.Account_Create)] public ResponsePacket CreateHandler(AccountCreateRequest req) { - var account = Common.Database.Models.Game.Account.Create((uint)req.AccountId); + if (req.SessionKey is null) + { + return new ErrorPacket() + { + ErrorCode = WebAPIErrorCode.InvalidSession + }; + } - Context.Accounts.Add(account); - - Context.Players.Add(new Player() { ServerId = (uint)req.AccountId }); - - Context.SaveChanges(); - - Log.Information("Account Created " + Context.Accounts.Count()); + string[] uidToken = req.SessionKey.MxToken.Split(':'); + var account = new AccountDB(long.Parse(uidToken[0])); + context.Accounts.Add(account); + context.MissionProgresses.AddRange([ + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1501, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44") + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1700, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1500, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44") + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 2200, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 }, { 1, 5 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 300000, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1000210, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1000220, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1000230, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1000240, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1000250, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1000260, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1000270, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1001327, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1001357, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + }, + new MissionProgressDB + { + AccountServerId = account.ServerId, + MissionUniqueId = 1001377, + Complete = true, + StartTime = DateTime.Parse("2024-04-26T20:46:44"), + ProgressParameters = new Dictionary { { 0, 1 } } + } + ]); + context.SaveChanges(); return new AccountCreateResponse() { - SessionKey = new() - { - AccountServerId = account.ServerId, - MxToken = req.SessionKey.MxToken, - }, + SessionKey = sessionKeyService.Create(account.PublisherAccountId) }; } [ProtocolHandler(Protocol.Account_Nickname)] public ResponsePacket NicknameHandler(AccountNicknameRequest req) { - var account = Context.Accounts.SingleOrDefault(x => x.ServerId == req.AccountId); + var account = sessionKeyService.GetAccount(req.SessionKey!); - account.AccountDB.Nickname = req.Nickname; - Context.SaveChanges(); + account.Nickname = req.Nickname; + context.SaveChanges(); return new AccountNicknameResponse() { - AccountDB = account.AccountDB + AccountDB = account }; } @@ -256,8 +267,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers return new NetworkTimeSyncResponse() { ReceiveTick = received_tick, - EchoSendTick = DateTimeOffset.Now.Ticks, - ServerTimeTicks = received_tick, + EchoSendTick = DateTimeOffset.Now.Ticks }; } @@ -279,7 +289,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers { MxToken = req.SessionKey.MxToken, AccountServerId = req.SessionKey.AccountServerId, - }, + } }; } diff --git a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Mission.cs b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Mission.cs index 2e058b4..61fdeb0 100644 --- a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Mission.cs +++ b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Mission.cs @@ -1,348 +1,32 @@ -using SCHALE.Common.Database; +using MongoDB.Driver.Linq; +using SCHALE.Common.Database; using SCHALE.Common.NetworkProtocol; +using SCHALE.GameServer.Services; using Serilog; namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers { public class Mission : ProtocolHandlerBase { - public Mission(IServiceScopeFactory scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) : base(scopeFactory, protocolHandlerFactory) { } + private ISessionKeyService sessionKeyService; + private SCHALEContext context; + + public Mission(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context) : base(protocolHandlerFactory) + { + sessionKeyService = _sessionKeyService; + context = _context; + } [ProtocolHandler(Protocol.Mission_List)] public ResponsePacket ListHandler(MissionListRequest req) { - var player = Context.Players.SingleOrDefault(x => x.ServerId == req.AccountId); - Log.Information($"MissionListRequest EventContentId: {req.EventContentId}"); - Context.CurrentPlayer.MissionProgressDBs = new List - { - new MissionProgressDB - { - MissionUniqueId = 1501, - Complete = true, - StartTime = DateTime.Now }, - new MissionProgressDB - { - MissionUniqueId = 1700, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 2 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1500, - Complete = true, - StartTime = DateTime.Now }, - new MissionProgressDB - { - MissionUniqueId = 2200, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 }, { 1, 5 } } - }, - new MissionProgressDB - { - MissionUniqueId = 300000, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000210, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000220, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000230, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000240, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000250, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000260, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1000270, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001327, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001357, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001377, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001011, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001014, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001015, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 13003, 1 }, { 13010, 1 }, { 16003, 1 }, { 26000, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001016, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001019, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 4 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001020, - Complete = true, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001021, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001025, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 13003, 1 }, { 13010, 1 }, { 16003, 1 }, { 26000, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001026, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001028, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001030, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 1, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001031, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001036, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 13003, 1 }, { 13010, 1 }, { 16003, 1 }, { 26000, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001037, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001039, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001041, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001046, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 13003, 1 }, { 13010, 1 }, { 16003, 1 }, { 26000, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001050, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001051, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001055, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 1, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001056, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 13003, 1 }, { 13010, 1 }, { 16003, 1 }, { 26000, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001057, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001059, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001060, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001061, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001065, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 13003, 1 }, { 13010, 1 }, { 16003, 1 }, { 26000, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001067, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001069, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001070, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001071, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001075, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 13003, 1 }, { 13010, 1 }, { 16003, 1 }, { 26000, 1 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001079, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 7, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001080, - StartTime = DateTime.Now, - ProgressParameters = new Dictionary { { 0, 0 } } - }, - new MissionProgressDB - { - MissionUniqueId = 1001013, - StartTime = DateTime.Now }, - new MissionProgressDB - { - MissionUniqueId = 1001023, - StartTime = DateTime.Now }, - new MissionProgressDB - { - MissionUniqueId = 1001034, - StartTime = DateTime.Now }, - new MissionProgressDB - { - MissionUniqueId = 1001044, - StartTime = DateTime.Now }, - new MissionProgressDB - { - MissionUniqueId = 1001054, - StartTime = DateTime.Now }, - }; - - //Context.CurrentPlayer.MissionProgressDBs = []; - Context.SaveChanges(); + var missionProgresses = context.MissionProgresses.Where(x => x.AccountServerId == sessionKeyService.GetAccount(req.SessionKey).ServerId).ToList(); return new MissionListResponse { - //ProgressDBs = Context.CurrentPlayer.MissionProgressDBs - ProgressDBs = Context.CurrentPlayer.MissionProgressDBs + ProgressDBs = missionProgresses }; } diff --git a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/ProofToken.cs b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/ProofToken.cs index 3e12b06..659d50e 100644 --- a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/ProofToken.cs +++ b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/ProofToken.cs @@ -4,7 +4,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers { public class ProofToken : ProtocolHandlerBase { - public ProofToken(IServiceScopeFactory scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) : base(scopeFactory, protocolHandlerFactory) { } + public ProofToken(IProtocolHandlerFactory protocolHandlerFactory) : base(protocolHandlerFactory) { } [ProtocolHandler(Protocol.ProofToken_RequestQuestion)] public ResponsePacket RequestQuestionHandler(ProofTokenRequestQuestionRequest req) @@ -12,26 +12,14 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers return new ProofTokenRequestQuestionResponse() { Hint = 69, - Question = "seggs", - SessionKey = new() - { - MxToken = req.SessionKey.MxToken, - AccountServerId = req.SessionKey.AccountServerId, - }, + Question = "seggs" }; } [ProtocolHandler(Protocol.ProofToken_Submit)] public ResponsePacket SubmitHandler(ProofTokenSubmitRequest req) { - return new ProofTokenSubmitResponse() - { - SessionKey = new() - { - MxToken = req.SessionKey.MxToken, - AccountServerId = req.SessionKey.AccountServerId, - }, - }; + return new ProofTokenSubmitResponse(); } } } diff --git a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/ProtocolHandlerFactory.cs b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/ProtocolHandlerFactory.cs index d9a179e..1c897b0 100644 --- a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/ProtocolHandlerFactory.cs +++ b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/ProtocolHandlerFactory.cs @@ -89,36 +89,21 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers public abstract class ProtocolHandlerBase : IHostedService { - private readonly IServiceScopeFactory scopeFactory; - - private IServiceScope scope; + private IProtocolHandlerFactory protocolHandlerFactory; - public ProtocolHandlerBase(IServiceScopeFactory _scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) + public ProtocolHandlerBase(IProtocolHandlerFactory _protocolHandlerFactory) { - scopeFactory = _scopeFactory; - protocolHandlerFactory.RegisterInstance(GetType(), this); - } - - public SCHALEContext Context - { - get - { - var db = scope.ServiceProvider.GetRequiredService(); - - return db; - } + protocolHandlerFactory = _protocolHandlerFactory; } public Task StartAsync(CancellationToken cancellationToken) { - scope = scopeFactory.CreateScope(); + protocolHandlerFactory.RegisterInstance(GetType(), this); return Task.CompletedTask; } public Task StopAsync(CancellationToken cancellationToken) { - scope.Dispose(); - Context.Dispose(); return Task.CompletedTask; } } diff --git a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Queuing.cs b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Queuing.cs index 13d4ab2..e820c41 100644 --- a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Queuing.cs +++ b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Queuing.cs @@ -4,7 +4,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers { public class Queuing : ProtocolHandlerBase { - public Queuing(IServiceScopeFactory scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) : base(scopeFactory, protocolHandlerFactory) { } + public Queuing(IProtocolHandlerFactory protocolHandlerFactory) : base(protocolHandlerFactory) { } [ProtocolHandler(Protocol.Queuing_GetTicket)] public ResponsePacket GetTicketHandler(QueuingGetTicketRequest req) diff --git a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Scenario.cs b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Scenario.cs index ce4d2cc..1d3c20c 100644 --- a/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Scenario.cs +++ b/SCHALE.GameServer/Controllers/Api/ProtocolHandlers/Scenario.cs @@ -5,7 +5,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers { public class Scenario : ProtocolHandlerBase { - public Scenario(IServiceScopeFactory scopeFactory, IProtocolHandlerFactory protocolHandlerFactory) : base(scopeFactory, protocolHandlerFactory) { } + public Scenario(IProtocolHandlerFactory protocolHandlerFactory) : base(protocolHandlerFactory) { } [ProtocolHandler(Protocol.Scenario_Skip)] public ResponsePacket SkipHandler(ScenarioSkipRequest req) diff --git a/SCHALE.GameServer/GameServer.cs b/SCHALE.GameServer/GameServer.cs index de6a09f..9516061 100644 --- a/SCHALE.GameServer/GameServer.cs +++ b/SCHALE.GameServer/GameServer.cs @@ -4,6 +4,7 @@ using Serilog; using System.Reflection; using SCHALE.Common.Database; using SCHALE.GameServer.Controllers.Api.ProtocolHandlers; +using SCHALE.GameServer.Services; namespace SCHALE.GameServer { @@ -46,6 +47,7 @@ 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.AddMemorySessionKeyService(); builder.Services.AddProtocolHandlerGroup(); builder.Services.AddProtocolHandlerGroup(); builder.Services.AddProtocolHandlerGroup(); diff --git a/SCHALE.GameServer/Models/User.cs b/SCHALE.GameServer/Models/User.cs index 4d8694b..af49547 100644 --- a/SCHALE.GameServer/Models/User.cs +++ b/SCHALE.GameServer/Models/User.cs @@ -45,7 +45,7 @@ namespace SCHALE.GameServer.Models class UserCreateResponse : BaseResponse { [JsonPropertyName("uid")] - public uint Uid { get; set; } + public long Uid { get; set; } [JsonPropertyName("token")] public string Token { get; set; } diff --git a/SCHALE.GameServer/Services/SessionKeyService.cs b/SCHALE.GameServer/Services/SessionKeyService.cs new file mode 100644 index 0000000..be26b36 --- /dev/null +++ b/SCHALE.GameServer/Services/SessionKeyService.cs @@ -0,0 +1,75 @@ +using SCHALE.Common.Database; +using SCHALE.Common.NetworkProtocol; + +namespace SCHALE.GameServer.Services +{ + public class MemorySessionKeyService : ISessionKeyService + { + /// + /// A map of to + /// + private readonly Dictionary sessions = []; + private readonly SCHALEContext context; + + public MemorySessionKeyService(SCHALEContext _context) + { + context = _context; + } + + public AccountDB GetAccount(SessionKey sessionKey) + { + if (sessions.TryGetValue(sessionKey.AccountServerId, out Guid token) && token.ToString() == sessionKey.MxToken) + { + var account = context.Accounts.SingleOrDefault(x => x.ServerId == sessionKey.AccountServerId); + + if (account is not null) + return account; + } + + throw new InvalidSessionKeyException(); + } + + public SessionKey? Create(long publisherAccountId) + { + var account = context.Accounts.SingleOrDefault(x => x.PublisherAccountId == publisherAccountId); + if (account is null) + return null; + + if (sessions.ContainsKey(account.ServerId)) + { + sessions[account.ServerId] = Guid.NewGuid(); + } + else + { + sessions.Add(account.ServerId, Guid.NewGuid()); + } + + return new() + { + AccountServerId = account.ServerId, + MxToken = sessions[account.ServerId].ToString() + }; + } + } + + internal static class ServiceExtensions + { + public static void AddMemorySessionKeyService(this IServiceCollection services) + { + services.AddSingleton(); + } + } + + public interface ISessionKeyService + { + public SessionKey? Create(long publisherAccountId); + public AccountDB GetAccount(SessionKey sessionKey); + } + + public class InvalidSessionKeyException : Exception + { + public InvalidSessionKeyException() : base() { } + public InvalidSessionKeyException(string message) : base(message) { } + public InvalidSessionKeyException(string message, Exception innerException) : base(message, innerException) { } + } +}