sql server + items,character,tuts & echelons impl.

This commit is contained in:
rfi 2024-05-01 16:11:11 +07:00
parent 56f6826cfe
commit e96ebfd33f
34 changed files with 2330 additions and 347 deletions

3
.gitignore vendored
View File

@ -361,3 +361,6 @@ MigrationBackup/
# Fody - auto-generated XML schema # Fody - auto-generated XML schema
FodyWeavers.xsd FodyWeavers.xsd
# EF migration
efbundle.exe

View File

@ -153,55 +153,4 @@ namespace SCHALE.Common.Crypto
return Encoding.Unicode.GetString(strBytes); return Encoding.Unicode.GetString(strBytes);
} }
} }
public static class FlatBuffersExtension
{
private static readonly Dictionary<Type, PropertyInfo[]> propertiesCache = [];
private static readonly Dictionary<Type, byte[]> keyCache = [];
/// <summary>
/// <b>Only</b> to be invoked by ExcelT, and only be invoked <b>once</b> per object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="table"></param>
public static void Decode<T>(this T table) where T : class
{
var type = table.GetType();
PropertyInfo[] props;
if (!propertiesCache.TryGetValue(type, out props!))
{
props = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
propertiesCache.Add(type, props);
}
foreach (var prop in props)
{
byte[] key;
if (!keyCache.TryGetValue(type, out key!))
{
key = TableEncryptionService.CreateKey(type.Name.Replace("ExcelT", ""));
keyCache.Add(type, key);
}
var baseType = prop.PropertyType.Name == "List`1" ? prop.PropertyType.GenericTypeArguments[0] : prop.PropertyType;
var convertMethod = TableEncryptionService.GetConvertMethod(baseType.IsEnum ? Enum.GetUnderlyingType(baseType) : baseType);
if (convertMethod is not null)
{
if (prop.PropertyType.Name == "List`1")
{
var list = (IList)prop.GetValue(table, null)!;
for (int i = 0; i < list.Count; i++)
{
list[i] = convertMethod.Invoke(null, [list[i], key]);
}
}
else
{
prop.SetValue(table, convertMethod.Invoke(null, [prop.GetValue(table, null), key]));
}
}
}
}
}
} }

View File

@ -40,7 +40,7 @@ namespace SCHALE.Common.Crypto
{ {
foreach (var type in Assembly.GetAssembly(typeof(AcademyFavorScheduleExcelTable))!.GetTypes().Where(t => t.IsAssignableTo(typeof(IFlatbufferObject)) && t.Name.EndsWith("ExcelTable"))) foreach (var type in Assembly.GetAssembly(typeof(AcademyFavorScheduleExcelTable))!.GetTypes().Where(t => t.IsAssignableTo(typeof(IFlatbufferObject)) && t.Name.EndsWith("ExcelTable")))
{ {
var bytesFilePath = Path.Join(bytesDir, $"{type.Name}.bytes"); var bytesFilePath = Path.Join(bytesDir, $"{type.Name.ToLower()}.bytes");
if (!File.Exists(bytesFilePath)) if (!File.Exists(bytesFilePath))
{ {
Console.WriteLine($"bytes files for {type.Name} not found. skipping..."); Console.WriteLine($"bytes files for {type.Name} not found. skipping...");

View File

@ -0,0 +1,16 @@
namespace SCHALE.Common.Database.ModelExtensions
{
public static class AccountExtensions
{
public static List<CharacterDB> AddCharacters(this AccountDB account, SCHALEContext context, params CharacterDB[] characters)
{
foreach (var character in characters)
{
character.AccountServerId = account.ServerId;
context.Characters.Add(character);
}
return [.. characters];
}
}
}

View File

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
namespace SCHALE.Common.Database.Models
{
public class AccountTutorial
{
[Key]
public required long AccountServerId { get; set; }
public List<long> TutorialIds { get; set; }
}
}

View File

@ -7,7 +7,6 @@ namespace SCHALE.Common.Database.Models
public class GuestAccount public class GuestAccount
{ {
[Key] [Key]
[Column("_id")]
public long Uid { get; set; } public long Uid { get; set; }
public string DeviceId { get; set; } public string DeviceId { get; set; }

View File

@ -1,7 +1,7 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.ValueGeneration; using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MongoDB.EntityFrameworkCore.Extensions; using Newtonsoft.Json;
using SCHALE.Common.Database.Models; using SCHALE.Common.Database.Models;
namespace SCHALE.Common.Database namespace SCHALE.Common.Database
@ -11,7 +11,15 @@ namespace SCHALE.Common.Database
public DbSet<GuestAccount> GuestAccounts { get; set; } public DbSet<GuestAccount> GuestAccounts { get; set; }
public DbSet<AccountDB> Accounts { get; set; } public DbSet<AccountDB> Accounts { get; set; }
public DbSet<MissionProgressDB> MissionProgresses { get; set; } public DbSet<MissionProgressDB> MissionProgresses { get; set; }
public DbSet<Counter> Counters { get; set; } public DbSet<ItemDB> Items { get; set; }
public DbSet<CharacterDB> Characters { get; set; }
public DbSet<EchelonDB> Echelons { get; set; }
public DbSet<AccountTutorial> AccountTutorials { get; set; }
public static SCHALEContext Create(string connectionString) =>
new(new DbContextOptionsBuilder<SCHALEContext>()
.UseSqlServer(connectionString)
.Options);
public SCHALEContext(DbContextOptions<SCHALEContext> options) : base(options) public SCHALEContext(DbContextOptions<SCHALEContext> options) : base(options)
{ {
@ -21,59 +29,53 @@ namespace SCHALE.Common.Database
{ {
base.OnModelCreating(modelBuilder); base.OnModelCreating(modelBuilder);
modelBuilder.Entity<GuestAccount>().Property(x => x.Uid).HasValueGenerator<GuestAccountAutoIncrementValueGenerator>(); modelBuilder.Entity<GuestAccount>().Property(x => x.Uid).ValueGeneratedOnAdd();
modelBuilder.Entity<GuestAccount>().ToCollection("guest_accounts");
modelBuilder.Entity<AccountDB>().Property(x => x.ServerId).HasValueGenerator<AccountAutoIncrementValueGenerator>(); modelBuilder.Entity<AccountDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<AccountDB>().ToCollection("accounts"); modelBuilder.Entity<AccountDB>()
.HasMany(x => x.Items)
.WithOne(x => x.Account)
.HasForeignKey(x => x.AccountServerId)
.IsRequired();
modelBuilder.Entity<AccountDB>()
.HasMany(x => x.Characters)
.WithOne(x => x.Account)
.HasForeignKey(x => x.AccountServerId)
.IsRequired();
modelBuilder.Entity<AccountDB>()
.HasMany(x => x.MissionProgresses)
.WithOne(x => x.Account)
.HasForeignKey(x => x.AccountServerId)
.IsRequired();
modelBuilder.Entity<MissionProgressDB>().Property(x => x.ServerId).HasValueGenerator<MissionProgressAutoIncrementValueGenerator>(); modelBuilder.Entity<ItemDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<MissionProgressDB>().ToCollection("mission_progresses"); modelBuilder.Entity<EchelonDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<Counter>().ToCollection("counters"); modelBuilder.Entity<CharacterDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<CharacterDB>().Property(x => x.EquipmentSlotAndDBIds).HasJsonConversion();
modelBuilder.Entity<CharacterDB>().Property(x => x.PotentialStats).HasJsonConversion();
modelBuilder.Entity<AccountTutorial>().Property(x => x.AccountServerId).ValueGeneratedNever();
modelBuilder.Entity<MissionProgressDB>().Property(x => x.ServerId).ValueGeneratedOnAdd();
modelBuilder.Entity<MissionProgressDB>().Property(x => x.ProgressParameters).HasJsonConversion();
}
} }
private class AccountAutoIncrementValueGenerator : AutoIncrementValueGenerator public static class PropertyBuilderExtensions
{ {
protected override string Collection => "account"; public static PropertyBuilder<T> HasJsonConversion<T>(this PropertyBuilder<T> propertyBuilder) where T : class, new()
}
private class GuestAccountAutoIncrementValueGenerator : AutoIncrementValueGenerator
{ {
protected override string Collection => "guest_account"; ValueConverter<T, string> converter = new
} (
v => JsonConvert.SerializeObject(v),
v => JsonConvert.DeserializeObject<T>(v) ?? new T()
);
private class MissionProgressAutoIncrementValueGenerator : AutoIncrementValueGenerator propertyBuilder.HasConversion(converter);
{ propertyBuilder.Metadata.SetValueConverter(converter);
protected override string Collection => "mission_progress";
}
private abstract class AutoIncrementValueGenerator : ValueGenerator<long> return propertyBuilder;
{
protected abstract string Collection { get; }
public override bool GeneratesTemporaryValues => false;
public override long Next(EntityEntry entry)
{
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;
}
} }
} }
} }

View File

@ -1,19 +1,19 @@
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.ChangeTracking;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
namespace SCHALE.Common.Database namespace SCHALE.Common.Database
{ {
public static class ServicesExtesions public static class ServicesExtesions
{ {
public static void AddMongoDBProvider(this IServiceCollection services, string connectionString) public static void AddSQLServerProvider(this IServiceCollection services, string connectionString)
{ {
services.AddDbContext<SCHALEContext>(opt => services.AddDbContext<SCHALEContext>(o =>
{ {
opt.UseMongoDB(connectionString, "SCHALE"); o.UseSqlServer(connectionString, b =>
{
b.EnableRetryOnFailure(5, TimeSpan.FromSeconds(10), null);
})
.UseLazyLoadingProxies();
}, ServiceLifetime.Singleton, ServiceLifetime.Singleton); }, ServiceLifetime.Singleton, ServiceLifetime.Singleton);
} }
} }

View File

@ -1,9 +1,9 @@
using Newtonsoft.Json;
using SCHALE.Common.FlatData; using SCHALE.Common.FlatData;
using SCHALE.Common.NetworkProtocol; using SCHALE.Common.NetworkProtocol;
using SCHALE.Common.Parcel; using SCHALE.Common.Parcel;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
namespace SCHALE.Common.Database namespace SCHALE.Common.Database
{ {
@ -185,6 +185,18 @@ namespace SCHALE.Common.Database
public class AccountDB public class AccountDB
{ {
[JsonIgnore]
public virtual ICollection<ItemDB> Items { get; }
[JsonIgnore]
public virtual ICollection<CharacterDB> Characters { get; }
[JsonIgnore]
public virtual ICollection<MissionProgressDB> MissionProgresses { get; }
[JsonIgnore]
public virtual ICollection<EchelonDB> Echelons { get; }
public AccountDB() { } public AccountDB() { }
public AccountDB(long publisherAccountId) public AccountDB(long publisherAccountId)
@ -197,14 +209,13 @@ namespace SCHALE.Common.Database
} }
[Key] [Key]
[Column("_id")]
public long ServerId { get; set; } public long ServerId { get; set; }
public string Nickname { get; set; } public string? Nickname { get; set; }
public string CallName { get; set; } public string? CallName { get; set; }
public string DevId { get; set; } public string? DevId { get; set; }
public AccountState State { get; set; } public AccountState State { get; set; }
@ -212,7 +223,7 @@ namespace SCHALE.Common.Database
public long Exp { get; set; } public long Exp { get; set; }
public string Comment { get; set; } public string? Comment { get; set; }
public int LobbyMode { get; set; } public int LobbyMode { get; set; }
@ -222,7 +233,7 @@ namespace SCHALE.Common.Database
public DateTime LastConnectTime { get; set; } public DateTime LastConnectTime { get; set; }
public DateTime BirthDay { get; set; } public DateTime? BirthDay { get; set; }
public DateTime CallNameUpdateTime { get; set; } public DateTime CallNameUpdateTime { get; set; }
@ -429,6 +440,8 @@ namespace SCHALE.Common.Database
public int CafeRank { get; set; } public int CafeRank { get; set; }
public DateTime LastUpdate { get; set; } public DateTime LastUpdate { get; set; }
public DateTime? LastSummonDate { get; set; } public DateTime? LastSummonDate { get; set; }
[NotMapped]
public bool IsNew { get; set; } public bool IsNew { get; set; }
public Dictionary<long, CafeCharacterDB> CafeVisitCharacterDBs { get; set; } public Dictionary<long, CafeCharacterDB> CafeVisitCharacterDBs { get; set; }
public List<FurnitureDB> FurnitureDBs { get; set; } public List<FurnitureDB> FurnitureDBs { get; set; }
@ -560,11 +573,20 @@ namespace SCHALE.Common.Database
public class CharacterDB : ParcelBase public class CharacterDB : ParcelBase
{ {
[NotMapped]
public override ParcelType Type { get => ParcelType.Character; } public override ParcelType Type { get => ParcelType.Character; }
[JsonIgnore] [JsonIgnore]
public virtual AccountDB Account { get; set; }
[JsonIgnore]
public long AccountServerId { get; set; }
[JsonIgnore]
[NotMapped]
public override IEnumerable<ParcelInfo> ParcelInfos { get; } public override IEnumerable<ParcelInfo> ParcelInfos { get; }
[Key]
public long ServerId { get; set; } public long ServerId { get; set; }
public long UniqueId { get; set; } public long UniqueId { get; set; }
public int StarGrade { get; set; } public int StarGrade { get; set; }
@ -577,12 +599,14 @@ namespace SCHALE.Common.Database
public int PassiveSkillLevel { get; set; } public int PassiveSkillLevel { get; set; }
public int ExtraPassiveSkillLevel { get; set; } public int ExtraPassiveSkillLevel { get; set; }
public int LeaderSkillLevel { get; set; } public int LeaderSkillLevel { get; set; }
[NotMapped]
public bool IsNew { get; set; } public bool IsNew { get; set; }
public bool IsLocked { get; set; } public bool IsLocked { get; set; }
public bool IsFavorite { get; set; } public bool IsFavorite { get; set; }
public List<long> EquipmentServerIds { get; set; } public List<long> EquipmentServerIds { get; set; } = [];
public Dictionary<int, int> PotentialStats { get; set; } = new() { }; public Dictionary<int, int> PotentialStats { get; set; } = [];
public Dictionary<int, long> EquipmentSlotAndDBIds { get; set; } public Dictionary<int, long> EquipmentSlotAndDBIds { get; set; } = [];
} }
@ -831,12 +855,19 @@ namespace SCHALE.Common.Database
public abstract class ConsumableItemBaseDB : ParcelBase public abstract class ConsumableItemBaseDB : ParcelBase
{ {
[JsonIgnore]
public virtual AccountDB Account { get; set; }
[JsonIgnore] [JsonIgnore]
public abstract bool CanConsume { get; } public abstract bool CanConsume { get; }
[JsonIgnore] [JsonIgnore]
public ParcelKeyPair Key { get; } public ParcelKeyPair Key { get; }
[JsonIgnore]
public long AccountServerId { get; set; }
[Key]
public long ServerId { get; set; } public long ServerId { get; set; }
public long UniqueId { get; set; } public long UniqueId { get; set; }
@ -1002,22 +1033,23 @@ namespace SCHALE.Common.Database
public class EchelonDB public class EchelonDB
{ {
[Key]
[JsonIgnore]
public long ServerId { get; set; }
[JsonIgnore]
public virtual AccountDB Account { get; set; }
public long AccountServerId { get; set; } public long AccountServerId { get; set; }
public EchelonType EchelonType { get; set; } public EchelonType EchelonType { get; set; }
public long EchelonNumber { get; set; } public long EchelonNumber { get; set; }
public EchelonExtensionType ExtensionType { get; set; } public EchelonExtensionType ExtensionType { get; set; }
public long LeaderServerId { get; set; } public long LeaderServerId { get; set; }
public int MainSlotCount { get; set; } public List<long> MainSlotServerIds { get; set; } = [];
public int SupportSlotCount { get; set; } public List<long> SupportSlotServerIds { get; set; } = [];
public List<long> MainSlotServerIds { get; set; }
public List<long> SupportSlotServerIds { get; set; }
public long TSSInteractionServerId { get; set; } public long TSSInteractionServerId { get; set; }
public EchelonStatusFlag UsingFlag { get; set; } public EchelonStatusFlag UsingFlag { get; set; }
public bool IsUsing { get; set; } public List<long> SkillCardMulliganCharacterIds { get; set; } = [];
public List<long> AllCharacterServerIds { get; set; }
public List<long> AllCharacterWithoutTSSServerIds { get; set; }
public List<long> BattleCharacterServerIds { get; set; }
public List<long> SkillCardMulliganCharacterIds { get; set; }
} }
@ -1088,6 +1120,8 @@ namespace SCHALE.Common.Database
public long Exp { get; set; } public long Exp { get; set; }
public int Tier { get; set; } public int Tier { get; set; }
public long BoundCharacterServerId { get; set; } public long BoundCharacterServerId { get; set; }
[NotMapped]
public bool IsNew { get; set; } public bool IsNew { get; set; }
public bool IsLocked { get; set; } public bool IsLocked { get; set; }
} }
@ -1464,15 +1498,20 @@ namespace SCHALE.Common.Database
public class ItemDB : ConsumableItemBaseDB public class ItemDB : ConsumableItemBaseDB
{ {
public override ParcelType Type { get => ParcelType.Item; } [NotMapped]
public override ParcelType Type => ParcelType.Item;
[NotMapped]
[JsonIgnore] [JsonIgnore]
public override IEnumerable<ParcelInfo> ParcelInfos { get; } public override IEnumerable<ParcelInfo> ParcelInfos { get; }
[NotMapped]
[JsonIgnore] [JsonIgnore]
public override bool CanConsume { get; } public override bool CanConsume => true;
[NotMapped]
public bool IsNew { get; set; } public bool IsNew { get; set; }
public bool IsLocked { get; set; } public bool IsLocked { get; set; }
} }
@ -1566,32 +1605,19 @@ namespace SCHALE.Common.Database
public class MissionProgressDB public class MissionProgressDB
{ {
[Key] [Key]
[Column("_id")]
[JsonIgnore] [JsonIgnore]
public long ServerId { get; set; } public long ServerId { get; set; }
[JsonIgnore]
public virtual AccountDB Account { get; set; }
[JsonIgnore] [JsonIgnore]
public long AccountServerId { get; set; } public long AccountServerId { get; set; }
public long MissionUniqueId { get; set; } public long MissionUniqueId { get; set; }
public bool Complete { get; set; } public bool Complete { get; set; }
public DateTime StartTime { get; set; } public DateTime StartTime { get; set; }
public Dictionary<long, long> ProgressParameters { get; set; } = [];
[JsonIgnore]
public string SerializedProgressParameters { get; private set; } = "{}";
[NotMapped]
public Dictionary<long, long> ProgressParameters
{
get
{
return JsonConvert.DeserializeObject<Dictionary<long, long>>(SerializedProgressParameters) ?? [];
}
set
{
SerializedProgressParameters = JsonConvert.SerializeObject(value);
}
}
} }

View File

@ -20,11 +20,11 @@ public struct Form : IFlatbufferObject
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public Form __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public Form __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public SCHALE.Common.FlatData.MoveEndTable? MoveEnd { get { int o = __p.__offset(4); return o != 0 ? (SCHALE.Common.FlatData.MoveEndTable?)(new SCHALE.Common.FlatData.MoveEndTable()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } } public SCHALE.Common.FlatData.MoveEnd? MoveEnd { get { int o = __p.__offset(4); return o != 0 ? (SCHALE.Common.FlatData.MoveEnd?)(new SCHALE.Common.FlatData.MoveEnd()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public SCHALE.Common.FlatData.Motion? PublicSkill { get { int o = __p.__offset(6); return o != 0 ? (SCHALE.Common.FlatData.Motion?)(new SCHALE.Common.FlatData.Motion()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } } public SCHALE.Common.FlatData.Motion? PublicSkill { get { int o = __p.__offset(6); return o != 0 ? (SCHALE.Common.FlatData.Motion?)(new SCHALE.Common.FlatData.Motion()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public static Offset<SCHALE.Common.FlatData.Form> CreateForm(FlatBufferBuilder builder, public static Offset<SCHALE.Common.FlatData.Form> CreateForm(FlatBufferBuilder builder,
Offset<SCHALE.Common.FlatData.MoveEndTable> MoveEndOffset = default(Offset<SCHALE.Common.FlatData.MoveEndTable>), Offset<SCHALE.Common.FlatData.MoveEnd> MoveEndOffset = default(Offset<SCHALE.Common.FlatData.MoveEnd>),
Offset<SCHALE.Common.FlatData.Motion> PublicSkillOffset = default(Offset<SCHALE.Common.FlatData.Motion>)) { Offset<SCHALE.Common.FlatData.Motion> PublicSkillOffset = default(Offset<SCHALE.Common.FlatData.Motion>)) {
builder.StartTable(2); builder.StartTable(2);
Form.AddPublicSkill(builder, PublicSkillOffset); Form.AddPublicSkill(builder, PublicSkillOffset);
@ -33,7 +33,7 @@ public struct Form : IFlatbufferObject
} }
public static void StartForm(FlatBufferBuilder builder) { builder.StartTable(2); } public static void StartForm(FlatBufferBuilder builder) { builder.StartTable(2); }
public static void AddMoveEnd(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.MoveEndTable> moveEndOffset) { builder.AddOffset(0, moveEndOffset.Value, 0); } public static void AddMoveEnd(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.MoveEnd> moveEndOffset) { builder.AddOffset(0, moveEndOffset.Value, 0); }
public static void AddPublicSkill(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.Motion> publicSkillOffset) { builder.AddOffset(1, publicSkillOffset.Value, 0); } public static void AddPublicSkill(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.Motion> publicSkillOffset) { builder.AddOffset(1, publicSkillOffset.Value, 0); }
public static Offset<SCHALE.Common.FlatData.Form> EndForm(FlatBufferBuilder builder) { public static Offset<SCHALE.Common.FlatData.Form> EndForm(FlatBufferBuilder builder) {
int o = builder.EndTable(); int o = builder.EndTable();
@ -51,7 +51,7 @@ public struct Form : IFlatbufferObject
} }
public static Offset<SCHALE.Common.FlatData.Form> Pack(FlatBufferBuilder builder, FormT _o) { public static Offset<SCHALE.Common.FlatData.Form> Pack(FlatBufferBuilder builder, FormT _o) {
if (_o == null) return default(Offset<SCHALE.Common.FlatData.Form>); if (_o == null) return default(Offset<SCHALE.Common.FlatData.Form>);
var _MoveEnd = _o.MoveEnd == null ? default(Offset<SCHALE.Common.FlatData.MoveEndTable>) : SCHALE.Common.FlatData.MoveEndTable.Pack(builder, _o.MoveEnd); var _MoveEnd = _o.MoveEnd == null ? default(Offset<SCHALE.Common.FlatData.MoveEnd>) : SCHALE.Common.FlatData.MoveEnd.Pack(builder, _o.MoveEnd);
var _PublicSkill = _o.PublicSkill == null ? default(Offset<SCHALE.Common.FlatData.Motion>) : SCHALE.Common.FlatData.Motion.Pack(builder, _o.PublicSkill); var _PublicSkill = _o.PublicSkill == null ? default(Offset<SCHALE.Common.FlatData.Motion>) : SCHALE.Common.FlatData.Motion.Pack(builder, _o.PublicSkill);
return CreateForm( return CreateForm(
builder, builder,
@ -62,7 +62,7 @@ public struct Form : IFlatbufferObject
public class FormT public class FormT
{ {
public SCHALE.Common.FlatData.MoveEndTableT MoveEnd { get; set; } public SCHALE.Common.FlatData.MoveEndT MoveEnd { get; set; }
public SCHALE.Common.FlatData.MotionT PublicSkill { get; set; } public SCHALE.Common.FlatData.MotionT PublicSkill { get; set; }
public FormT() { public FormT() {
@ -77,7 +77,7 @@ static public class FormVerify
static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos) static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
{ {
return verifier.VerifyTableStart(tablePos) return verifier.VerifyTableStart(tablePos)
&& verifier.VerifyTable(tablePos, 4 /*MoveEnd*/, SCHALE.Common.FlatData.MoveEndTableVerify.Verify, false) && verifier.VerifyTable(tablePos, 4 /*MoveEnd*/, SCHALE.Common.FlatData.MoveEndVerify.Verify, false)
&& verifier.VerifyTable(tablePos, 6 /*PublicSkill*/, SCHALE.Common.FlatData.MotionVerify.Verify, false) && verifier.VerifyTable(tablePos, 6 /*PublicSkill*/, SCHALE.Common.FlatData.MotionVerify.Verify, false)
&& verifier.VerifyTableEnd(tablePos); && verifier.VerifyTableEnd(tablePos);
} }

View File

@ -10,56 +10,56 @@ using global::System.Collections.Generic;
using global::SCHALE.Common.Crypto; using global::SCHALE.Common.Crypto;
using global::Google.FlatBuffers; using global::Google.FlatBuffers;
public struct MoveEndTable : IFlatbufferObject public struct MoveEnd : IFlatbufferObject
{ {
private Table __p; private Table __p;
public ByteBuffer ByteBuffer { get { return __p.bb; } } public ByteBuffer ByteBuffer { get { return __p.bb; } }
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_24_3_25(); } public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_24_3_25(); }
public static MoveEndTable GetRootAsMoveEndTable(ByteBuffer _bb) { return GetRootAsMoveEndTable(_bb, new MoveEndTable()); } public static MoveEnd GetRootAsMoveEnd(ByteBuffer _bb) { return GetRootAsMoveEnd(_bb, new MoveEnd()); }
public static MoveEndTable GetRootAsMoveEndTable(ByteBuffer _bb, MoveEndTable obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); } public static MoveEnd GetRootAsMoveEnd(ByteBuffer _bb, MoveEnd obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); } public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
public MoveEndTable __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; } public MoveEnd __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
public SCHALE.Common.FlatData.Motion? Normal { get { int o = __p.__offset(4); return o != 0 ? (SCHALE.Common.FlatData.Motion?)(new SCHALE.Common.FlatData.Motion()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } } public SCHALE.Common.FlatData.Motion? Normal { get { int o = __p.__offset(4); return o != 0 ? (SCHALE.Common.FlatData.Motion?)(new SCHALE.Common.FlatData.Motion()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public SCHALE.Common.FlatData.Motion? Stand { get { int o = __p.__offset(6); return o != 0 ? (SCHALE.Common.FlatData.Motion?)(new SCHALE.Common.FlatData.Motion()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } } public SCHALE.Common.FlatData.Motion? Stand { get { int o = __p.__offset(6); return o != 0 ? (SCHALE.Common.FlatData.Motion?)(new SCHALE.Common.FlatData.Motion()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public SCHALE.Common.FlatData.Motion? Kneel { get { int o = __p.__offset(8); return o != 0 ? (SCHALE.Common.FlatData.Motion?)(new SCHALE.Common.FlatData.Motion()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } } public SCHALE.Common.FlatData.Motion? Kneel { get { int o = __p.__offset(8); return o != 0 ? (SCHALE.Common.FlatData.Motion?)(new SCHALE.Common.FlatData.Motion()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
public static Offset<SCHALE.Common.FlatData.MoveEndTable> CreateMoveEndTable(FlatBufferBuilder builder, public static Offset<SCHALE.Common.FlatData.MoveEnd> CreateMoveEnd(FlatBufferBuilder builder,
Offset<SCHALE.Common.FlatData.Motion> NormalOffset = default(Offset<SCHALE.Common.FlatData.Motion>), Offset<SCHALE.Common.FlatData.Motion> NormalOffset = default(Offset<SCHALE.Common.FlatData.Motion>),
Offset<SCHALE.Common.FlatData.Motion> StandOffset = default(Offset<SCHALE.Common.FlatData.Motion>), Offset<SCHALE.Common.FlatData.Motion> StandOffset = default(Offset<SCHALE.Common.FlatData.Motion>),
Offset<SCHALE.Common.FlatData.Motion> KneelOffset = default(Offset<SCHALE.Common.FlatData.Motion>)) { Offset<SCHALE.Common.FlatData.Motion> KneelOffset = default(Offset<SCHALE.Common.FlatData.Motion>)) {
builder.StartTable(3); builder.StartTable(3);
MoveEndTable.AddKneel(builder, KneelOffset); MoveEnd.AddKneel(builder, KneelOffset);
MoveEndTable.AddStand(builder, StandOffset); MoveEnd.AddStand(builder, StandOffset);
MoveEndTable.AddNormal(builder, NormalOffset); MoveEnd.AddNormal(builder, NormalOffset);
return MoveEndTable.EndMoveEndTable(builder); return MoveEnd.EndMoveEnd(builder);
} }
public static void StartMoveEndTable(FlatBufferBuilder builder) { builder.StartTable(3); } public static void StartMoveEnd(FlatBufferBuilder builder) { builder.StartTable(3); }
public static void AddNormal(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.Motion> normalOffset) { builder.AddOffset(0, normalOffset.Value, 0); } public static void AddNormal(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.Motion> normalOffset) { builder.AddOffset(0, normalOffset.Value, 0); }
public static void AddStand(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.Motion> standOffset) { builder.AddOffset(1, standOffset.Value, 0); } public static void AddStand(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.Motion> standOffset) { builder.AddOffset(1, standOffset.Value, 0); }
public static void AddKneel(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.Motion> kneelOffset) { builder.AddOffset(2, kneelOffset.Value, 0); } public static void AddKneel(FlatBufferBuilder builder, Offset<SCHALE.Common.FlatData.Motion> kneelOffset) { builder.AddOffset(2, kneelOffset.Value, 0); }
public static Offset<SCHALE.Common.FlatData.MoveEndTable> EndMoveEndTable(FlatBufferBuilder builder) { public static Offset<SCHALE.Common.FlatData.MoveEnd> EndMoveEnd(FlatBufferBuilder builder) {
int o = builder.EndTable(); int o = builder.EndTable();
return new Offset<SCHALE.Common.FlatData.MoveEndTable>(o); return new Offset<SCHALE.Common.FlatData.MoveEnd>(o);
} }
public MoveEndTableT UnPack() { public MoveEndT UnPack() {
var _o = new MoveEndTableT(); var _o = new MoveEndT();
this.UnPackTo(_o); this.UnPackTo(_o);
return _o; return _o;
} }
public void UnPackTo(MoveEndTableT _o) { public void UnPackTo(MoveEndT _o) {
byte[] key = { 0 }; byte[] key = { 0 };
_o.Normal = this.Normal.HasValue ? this.Normal.Value.UnPack() : null; _o.Normal = this.Normal.HasValue ? this.Normal.Value.UnPack() : null;
_o.Stand = this.Stand.HasValue ? this.Stand.Value.UnPack() : null; _o.Stand = this.Stand.HasValue ? this.Stand.Value.UnPack() : null;
_o.Kneel = this.Kneel.HasValue ? this.Kneel.Value.UnPack() : null; _o.Kneel = this.Kneel.HasValue ? this.Kneel.Value.UnPack() : null;
} }
public static Offset<SCHALE.Common.FlatData.MoveEndTable> Pack(FlatBufferBuilder builder, MoveEndTableT _o) { public static Offset<SCHALE.Common.FlatData.MoveEnd> Pack(FlatBufferBuilder builder, MoveEndT _o) {
if (_o == null) return default(Offset<SCHALE.Common.FlatData.MoveEndTable>); if (_o == null) return default(Offset<SCHALE.Common.FlatData.MoveEnd>);
var _Normal = _o.Normal == null ? default(Offset<SCHALE.Common.FlatData.Motion>) : SCHALE.Common.FlatData.Motion.Pack(builder, _o.Normal); var _Normal = _o.Normal == null ? default(Offset<SCHALE.Common.FlatData.Motion>) : SCHALE.Common.FlatData.Motion.Pack(builder, _o.Normal);
var _Stand = _o.Stand == null ? default(Offset<SCHALE.Common.FlatData.Motion>) : SCHALE.Common.FlatData.Motion.Pack(builder, _o.Stand); var _Stand = _o.Stand == null ? default(Offset<SCHALE.Common.FlatData.Motion>) : SCHALE.Common.FlatData.Motion.Pack(builder, _o.Stand);
var _Kneel = _o.Kneel == null ? default(Offset<SCHALE.Common.FlatData.Motion>) : SCHALE.Common.FlatData.Motion.Pack(builder, _o.Kneel); var _Kneel = _o.Kneel == null ? default(Offset<SCHALE.Common.FlatData.Motion>) : SCHALE.Common.FlatData.Motion.Pack(builder, _o.Kneel);
return CreateMoveEndTable( return CreateMoveEnd(
builder, builder,
_Normal, _Normal,
_Stand, _Stand,
@ -67,13 +67,13 @@ public struct MoveEndTable : IFlatbufferObject
} }
} }
public class MoveEndTableT public class MoveEndT
{ {
public SCHALE.Common.FlatData.MotionT Normal { get; set; } public SCHALE.Common.FlatData.MotionT Normal { get; set; }
public SCHALE.Common.FlatData.MotionT Stand { get; set; } public SCHALE.Common.FlatData.MotionT Stand { get; set; }
public SCHALE.Common.FlatData.MotionT Kneel { get; set; } public SCHALE.Common.FlatData.MotionT Kneel { get; set; }
public MoveEndTableT() { public MoveEndT() {
this.Normal = null; this.Normal = null;
this.Stand = null; this.Stand = null;
this.Kneel = null; this.Kneel = null;
@ -81,7 +81,7 @@ public class MoveEndTableT
} }
static public class MoveEndTableVerify static public class MoveEndVerify
{ {
static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos) static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
{ {

View File

@ -0,0 +1,189 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SCHALE.Common.Database;
#nullable disable
namespace SCHALE.Common.Migrations
{
[DbContext(typeof(SCHALEContext))]
[Migration("20240501053823_Init")]
partial class Init
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<DateTime?>("BirthDay")
.HasColumnType("datetime2");
b.Property<string>("CallName")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CallNameUpdateTime")
.HasColumnType("datetime2");
b.Property<string>("Comment")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreateDate")
.HasColumnType("datetime2");
b.Property<string>("DevId")
.HasColumnType("nvarchar(max)");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<DateTime>("LastConnectTime")
.HasColumnType("datetime2");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<DateTime?>("LinkRewardDate")
.HasColumnType("datetime2");
b.Property<int>("LobbyMode")
.HasColumnType("int");
b.Property<long>("MemoryLobbyUniqueId")
.HasColumnType("bigint");
b.Property<string>("Nickname")
.HasColumnType("nvarchar(max)");
b.Property<long>("PublisherAccountId")
.HasColumnType("bigint");
b.Property<int>("RepresentCharacterServerId")
.HasColumnType("int");
b.Property<int?>("RetentionDays")
.HasColumnType("int");
b.Property<int>("State")
.HasColumnType("int");
b.Property<int?>("UnReadMailCount")
.HasColumnType("int");
b.Property<int?>("VIPLevel")
.HasColumnType("int");
b.HasKey("ServerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<long>("StackCount")
.HasColumnType("bigint");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.ToTable("Items");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("Complete")
.HasColumnType("bit");
b.Property<long>("MissionUniqueId")
.HasColumnType("bigint");
b.Property<string>("ProgressParameters")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("StartTime")
.HasColumnType("datetime2");
b.HasKey("ServerId");
b.ToTable("MissionProgresses");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.AccountTutorial", b =>
{
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("TutorialIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("AccountServerId");
b.ToTable("AccountTutorials");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.GuestAccount", b =>
{
b.Property<long>("Uid")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Uid"));
b.Property<string>("DeviceId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Uid");
b.ToTable("GuestAccounts");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,124 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SCHALE.Common.Migrations
{
/// <inheritdoc />
public partial class Init : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Accounts",
columns: table => new
{
ServerId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
Nickname = table.Column<string>(type: "nvarchar(max)", nullable: true),
CallName = table.Column<string>(type: "nvarchar(max)", nullable: true),
DevId = table.Column<string>(type: "nvarchar(max)", nullable: true),
State = table.Column<int>(type: "int", nullable: false),
Level = table.Column<int>(type: "int", nullable: false),
Exp = table.Column<long>(type: "bigint", nullable: false),
Comment = table.Column<string>(type: "nvarchar(max)", nullable: true),
LobbyMode = table.Column<int>(type: "int", nullable: false),
RepresentCharacterServerId = table.Column<int>(type: "int", nullable: false),
MemoryLobbyUniqueId = table.Column<long>(type: "bigint", nullable: false),
LastConnectTime = table.Column<DateTime>(type: "datetime2", nullable: false),
BirthDay = table.Column<DateTime>(type: "datetime2", nullable: true),
CallNameUpdateTime = table.Column<DateTime>(type: "datetime2", nullable: false),
PublisherAccountId = table.Column<long>(type: "bigint", nullable: false),
RetentionDays = table.Column<int>(type: "int", nullable: true),
VIPLevel = table.Column<int>(type: "int", nullable: true),
CreateDate = table.Column<DateTime>(type: "datetime2", nullable: false),
UnReadMailCount = table.Column<int>(type: "int", nullable: true),
LinkRewardDate = table.Column<DateTime>(type: "datetime2", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Accounts", x => x.ServerId);
});
migrationBuilder.CreateTable(
name: "AccountTutorials",
columns: table => new
{
AccountServerId = table.Column<long>(type: "bigint", nullable: false),
TutorialIds = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AccountTutorials", x => x.AccountServerId);
});
migrationBuilder.CreateTable(
name: "GuestAccounts",
columns: table => new
{
Uid = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
DeviceId = table.Column<string>(type: "nvarchar(max)", nullable: false),
Token = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_GuestAccounts", x => x.Uid);
});
migrationBuilder.CreateTable(
name: "Items",
columns: table => new
{
ServerId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
IsLocked = table.Column<bool>(type: "bit", nullable: false),
AccountServerId = table.Column<long>(type: "bigint", nullable: false),
UniqueId = table.Column<long>(type: "bigint", nullable: false),
StackCount = table.Column<long>(type: "bigint", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Items", x => x.ServerId);
});
migrationBuilder.CreateTable(
name: "MissionProgresses",
columns: table => new
{
ServerId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
AccountServerId = table.Column<long>(type: "bigint", nullable: false),
MissionUniqueId = table.Column<long>(type: "bigint", nullable: false),
Complete = table.Column<bool>(type: "bit", nullable: false),
StartTime = table.Column<DateTime>(type: "datetime2", nullable: false),
ProgressParameters = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_MissionProgresses", x => x.ServerId);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Accounts");
migrationBuilder.DropTable(
name: "AccountTutorials");
migrationBuilder.DropTable(
name: "GuestAccounts");
migrationBuilder.DropTable(
name: "Items");
migrationBuilder.DropTable(
name: "MissionProgresses");
}
}
}

View File

@ -0,0 +1,307 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SCHALE.Common.Database;
#nullable disable
namespace SCHALE.Common.Migrations
{
[DbContext(typeof(SCHALEContext))]
[Migration("20240501071717_CharacterAndRelations")]
partial class CharacterAndRelations
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<DateTime?>("BirthDay")
.HasColumnType("datetime2");
b.Property<string>("CallName")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CallNameUpdateTime")
.HasColumnType("datetime2");
b.Property<string>("Comment")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreateDate")
.HasColumnType("datetime2");
b.Property<string>("DevId")
.HasColumnType("nvarchar(max)");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<DateTime>("LastConnectTime")
.HasColumnType("datetime2");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<DateTime?>("LinkRewardDate")
.HasColumnType("datetime2");
b.Property<int>("LobbyMode")
.HasColumnType("int");
b.Property<long>("MemoryLobbyUniqueId")
.HasColumnType("bigint");
b.Property<string>("Nickname")
.HasColumnType("nvarchar(max)");
b.Property<long>("PublisherAccountId")
.HasColumnType("bigint");
b.Property<int>("RepresentCharacterServerId")
.HasColumnType("int");
b.Property<int?>("RetentionDays")
.HasColumnType("int");
b.Property<int>("State")
.HasColumnType("int");
b.Property<int?>("UnReadMailCount")
.HasColumnType("int");
b.Property<int?>("VIPLevel")
.HasColumnType("int");
b.HasKey("ServerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("EquipmentServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("EquipmentSlotAndDBIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("ExSkillLevel")
.HasColumnType("int");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<int>("ExtraPassiveSkillLevel")
.HasColumnType("int");
b.Property<long>("FavorExp")
.HasColumnType("bigint");
b.Property<int>("FavorRank")
.HasColumnType("int");
b.Property<bool>("IsFavorite")
.HasColumnType("bit");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<bool>("IsNew")
.HasColumnType("bit");
b.Property<int>("LeaderSkillLevel")
.HasColumnType("int");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<int>("PassiveSkillLevel")
.HasColumnType("int");
b.Property<string>("PotentialStats")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("PublicSkillLevel")
.HasColumnType("int");
b.Property<int>("StarGrade")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Characters");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<long>("StackCount")
.HasColumnType("bigint");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Items");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("Complete")
.HasColumnType("bit");
b.Property<long>("MissionUniqueId")
.HasColumnType("bigint");
b.Property<string>("ProgressParameters")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("StartTime")
.HasColumnType("datetime2");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("MissionProgresses");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.AccountTutorial", b =>
{
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("TutorialIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("AccountServerId");
b.ToTable("AccountTutorials");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.GuestAccount", b =>
{
b.Property<long>("Uid")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Uid"));
b.Property<string>("DeviceId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Uid");
b.ToTable("GuestAccounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Characters")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Items")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("MissionProgresses")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Navigation("Characters");
b.Navigation("Items");
b.Navigation("MissionProgresses");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,104 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SCHALE.Common.Migrations
{
/// <inheritdoc />
public partial class CharacterAndRelations : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Characters",
columns: table => new
{
ServerId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
AccountServerId = table.Column<long>(type: "bigint", nullable: false),
UniqueId = table.Column<long>(type: "bigint", nullable: false),
StarGrade = table.Column<int>(type: "int", nullable: false),
Level = table.Column<int>(type: "int", nullable: false),
Exp = table.Column<long>(type: "bigint", nullable: false),
FavorRank = table.Column<int>(type: "int", nullable: false),
FavorExp = table.Column<long>(type: "bigint", nullable: false),
PublicSkillLevel = table.Column<int>(type: "int", nullable: false),
ExSkillLevel = table.Column<int>(type: "int", nullable: false),
PassiveSkillLevel = table.Column<int>(type: "int", nullable: false),
ExtraPassiveSkillLevel = table.Column<int>(type: "int", nullable: false),
LeaderSkillLevel = table.Column<int>(type: "int", nullable: false),
IsNew = table.Column<bool>(type: "bit", nullable: false),
IsLocked = table.Column<bool>(type: "bit", nullable: false),
IsFavorite = table.Column<bool>(type: "bit", nullable: false),
EquipmentServerIds = table.Column<string>(type: "nvarchar(max)", nullable: false),
PotentialStats = table.Column<string>(type: "nvarchar(max)", nullable: false),
EquipmentSlotAndDBIds = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Characters", x => x.ServerId);
table.ForeignKey(
name: "FK_Characters_Accounts_AccountServerId",
column: x => x.AccountServerId,
principalTable: "Accounts",
principalColumn: "ServerId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_MissionProgresses_AccountServerId",
table: "MissionProgresses",
column: "AccountServerId");
migrationBuilder.CreateIndex(
name: "IX_Items_AccountServerId",
table: "Items",
column: "AccountServerId");
migrationBuilder.CreateIndex(
name: "IX_Characters_AccountServerId",
table: "Characters",
column: "AccountServerId");
migrationBuilder.AddForeignKey(
name: "FK_Items_Accounts_AccountServerId",
table: "Items",
column: "AccountServerId",
principalTable: "Accounts",
principalColumn: "ServerId",
onDelete: ReferentialAction.Cascade);
migrationBuilder.AddForeignKey(
name: "FK_MissionProgresses_Accounts_AccountServerId",
table: "MissionProgresses",
column: "AccountServerId",
principalTable: "Accounts",
principalColumn: "ServerId",
onDelete: ReferentialAction.Cascade);
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropForeignKey(
name: "FK_Items_Accounts_AccountServerId",
table: "Items");
migrationBuilder.DropForeignKey(
name: "FK_MissionProgresses_Accounts_AccountServerId",
table: "MissionProgresses");
migrationBuilder.DropTable(
name: "Characters");
migrationBuilder.DropIndex(
name: "IX_MissionProgresses_AccountServerId",
table: "MissionProgresses");
migrationBuilder.DropIndex(
name: "IX_Items_AccountServerId",
table: "Items");
}
}
}

View File

@ -0,0 +1,307 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SCHALE.Common.Database;
#nullable disable
namespace SCHALE.Common.Migrations
{
[DbContext(typeof(SCHALEContext))]
[Migration("20240501081158_UnMapIsNew")]
partial class UnMapIsNew
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Proxies:ChangeTracking", false)
.HasAnnotation("Proxies:CheckEquality", false)
.HasAnnotation("Proxies:LazyLoading", true)
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<DateTime?>("BirthDay")
.HasColumnType("datetime2");
b.Property<string>("CallName")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CallNameUpdateTime")
.HasColumnType("datetime2");
b.Property<string>("Comment")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreateDate")
.HasColumnType("datetime2");
b.Property<string>("DevId")
.HasColumnType("nvarchar(max)");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<DateTime>("LastConnectTime")
.HasColumnType("datetime2");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<DateTime?>("LinkRewardDate")
.HasColumnType("datetime2");
b.Property<int>("LobbyMode")
.HasColumnType("int");
b.Property<long>("MemoryLobbyUniqueId")
.HasColumnType("bigint");
b.Property<string>("Nickname")
.HasColumnType("nvarchar(max)");
b.Property<long>("PublisherAccountId")
.HasColumnType("bigint");
b.Property<int>("RepresentCharacterServerId")
.HasColumnType("int");
b.Property<int?>("RetentionDays")
.HasColumnType("int");
b.Property<int>("State")
.HasColumnType("int");
b.Property<int?>("UnReadMailCount")
.HasColumnType("int");
b.Property<int?>("VIPLevel")
.HasColumnType("int");
b.HasKey("ServerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("EquipmentServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("EquipmentSlotAndDBIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("ExSkillLevel")
.HasColumnType("int");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<int>("ExtraPassiveSkillLevel")
.HasColumnType("int");
b.Property<long>("FavorExp")
.HasColumnType("bigint");
b.Property<int>("FavorRank")
.HasColumnType("int");
b.Property<bool>("IsFavorite")
.HasColumnType("bit");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<int>("LeaderSkillLevel")
.HasColumnType("int");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<int>("PassiveSkillLevel")
.HasColumnType("int");
b.Property<string>("PotentialStats")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("PublicSkillLevel")
.HasColumnType("int");
b.Property<int>("StarGrade")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Characters");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<long>("StackCount")
.HasColumnType("bigint");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Items");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("Complete")
.HasColumnType("bit");
b.Property<long>("MissionUniqueId")
.HasColumnType("bigint");
b.Property<string>("ProgressParameters")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("StartTime")
.HasColumnType("datetime2");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("MissionProgresses");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.AccountTutorial", b =>
{
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("TutorialIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("AccountServerId");
b.ToTable("AccountTutorials");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.GuestAccount", b =>
{
b.Property<long>("Uid")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Uid"));
b.Property<string>("DeviceId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Uid");
b.ToTable("GuestAccounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Characters")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Items")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("MissionProgresses")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Navigation("Characters");
b.Navigation("Items");
b.Navigation("MissionProgresses");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,29 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SCHALE.Common.Migrations
{
/// <inheritdoc />
public partial class UnMapIsNew : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "IsNew",
table: "Characters");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<bool>(
name: "IsNew",
table: "Characters",
type: "bit",
nullable: false,
defaultValue: false);
}
}
}

View File

@ -0,0 +1,368 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SCHALE.Common.Database;
#nullable disable
namespace SCHALE.Common.Migrations
{
[DbContext(typeof(SCHALEContext))]
[Migration("20240501090227_Echelons")]
partial class Echelons
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Proxies:ChangeTracking", false)
.HasAnnotation("Proxies:CheckEquality", false)
.HasAnnotation("Proxies:LazyLoading", true)
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<DateTime?>("BirthDay")
.HasColumnType("datetime2");
b.Property<string>("CallName")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CallNameUpdateTime")
.HasColumnType("datetime2");
b.Property<string>("Comment")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreateDate")
.HasColumnType("datetime2");
b.Property<string>("DevId")
.HasColumnType("nvarchar(max)");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<DateTime>("LastConnectTime")
.HasColumnType("datetime2");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<DateTime?>("LinkRewardDate")
.HasColumnType("datetime2");
b.Property<int>("LobbyMode")
.HasColumnType("int");
b.Property<long>("MemoryLobbyUniqueId")
.HasColumnType("bigint");
b.Property<string>("Nickname")
.HasColumnType("nvarchar(max)");
b.Property<long>("PublisherAccountId")
.HasColumnType("bigint");
b.Property<int>("RepresentCharacterServerId")
.HasColumnType("int");
b.Property<int?>("RetentionDays")
.HasColumnType("int");
b.Property<int>("State")
.HasColumnType("int");
b.Property<int?>("UnReadMailCount")
.HasColumnType("int");
b.Property<int?>("VIPLevel")
.HasColumnType("int");
b.HasKey("ServerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("EquipmentServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("EquipmentSlotAndDBIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("ExSkillLevel")
.HasColumnType("int");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<int>("ExtraPassiveSkillLevel")
.HasColumnType("int");
b.Property<long>("FavorExp")
.HasColumnType("bigint");
b.Property<int>("FavorRank")
.HasColumnType("int");
b.Property<bool>("IsFavorite")
.HasColumnType("bit");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<int>("LeaderSkillLevel")
.HasColumnType("int");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<int>("PassiveSkillLevel")
.HasColumnType("int");
b.Property<string>("PotentialStats")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("PublicSkillLevel")
.HasColumnType("int");
b.Property<int>("StarGrade")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Characters");
});
modelBuilder.Entity("SCHALE.Common.Database.EchelonDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<long>("EchelonNumber")
.HasColumnType("bigint");
b.Property<int>("EchelonType")
.HasColumnType("int");
b.Property<int>("ExtensionType")
.HasColumnType("int");
b.Property<long>("LeaderServerId")
.HasColumnType("bigint");
b.Property<string>("MainSlotServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SkillCardMulliganCharacterIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SupportSlotServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<long>("TSSInteractionServerId")
.HasColumnType("bigint");
b.Property<int>("UsingFlag")
.HasColumnType("int");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Echelons");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<long>("StackCount")
.HasColumnType("bigint");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Items");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("Complete")
.HasColumnType("bit");
b.Property<long>("MissionUniqueId")
.HasColumnType("bigint");
b.Property<string>("ProgressParameters")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("StartTime")
.HasColumnType("datetime2");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("MissionProgresses");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.AccountTutorial", b =>
{
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("TutorialIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("AccountServerId");
b.ToTable("AccountTutorials");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.GuestAccount", b =>
{
b.Property<long>("Uid")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Uid"));
b.Property<string>("DeviceId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Uid");
b.ToTable("GuestAccounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Characters")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.EchelonDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Echelons")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Items")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("MissionProgresses")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Navigation("Characters");
b.Navigation("Echelons");
b.Navigation("Items");
b.Navigation("MissionProgresses");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,54 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace SCHALE.Common.Migrations
{
/// <inheritdoc />
public partial class Echelons : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Echelons",
columns: table => new
{
ServerId = table.Column<long>(type: "bigint", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
AccountServerId = table.Column<long>(type: "bigint", nullable: false),
EchelonType = table.Column<int>(type: "int", nullable: false),
EchelonNumber = table.Column<long>(type: "bigint", nullable: false),
ExtensionType = table.Column<int>(type: "int", nullable: false),
LeaderServerId = table.Column<long>(type: "bigint", nullable: false),
MainSlotServerIds = table.Column<string>(type: "nvarchar(max)", nullable: false),
SupportSlotServerIds = table.Column<string>(type: "nvarchar(max)", nullable: false),
TSSInteractionServerId = table.Column<long>(type: "bigint", nullable: false),
UsingFlag = table.Column<int>(type: "int", nullable: false),
SkillCardMulliganCharacterIds = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Echelons", x => x.ServerId);
table.ForeignKey(
name: "FK_Echelons_Accounts_AccountServerId",
column: x => x.AccountServerId,
principalTable: "Accounts",
principalColumn: "ServerId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Echelons_AccountServerId",
table: "Echelons",
column: "AccountServerId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Echelons");
}
}
}

View File

@ -0,0 +1,365 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using SCHALE.Common.Database;
#nullable disable
namespace SCHALE.Common.Migrations
{
[DbContext(typeof(SCHALEContext))]
partial class SCHALEContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.2")
.HasAnnotation("Proxies:ChangeTracking", false)
.HasAnnotation("Proxies:CheckEquality", false)
.HasAnnotation("Proxies:LazyLoading", true)
.HasAnnotation("Relational:MaxIdentifierLength", 128);
SqlServerModelBuilderExtensions.UseIdentityColumns(modelBuilder);
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<DateTime?>("BirthDay")
.HasColumnType("datetime2");
b.Property<string>("CallName")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CallNameUpdateTime")
.HasColumnType("datetime2");
b.Property<string>("Comment")
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("CreateDate")
.HasColumnType("datetime2");
b.Property<string>("DevId")
.HasColumnType("nvarchar(max)");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<DateTime>("LastConnectTime")
.HasColumnType("datetime2");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<DateTime?>("LinkRewardDate")
.HasColumnType("datetime2");
b.Property<int>("LobbyMode")
.HasColumnType("int");
b.Property<long>("MemoryLobbyUniqueId")
.HasColumnType("bigint");
b.Property<string>("Nickname")
.HasColumnType("nvarchar(max)");
b.Property<long>("PublisherAccountId")
.HasColumnType("bigint");
b.Property<int>("RepresentCharacterServerId")
.HasColumnType("int");
b.Property<int?>("RetentionDays")
.HasColumnType("int");
b.Property<int>("State")
.HasColumnType("int");
b.Property<int?>("UnReadMailCount")
.HasColumnType("int");
b.Property<int?>("VIPLevel")
.HasColumnType("int");
b.HasKey("ServerId");
b.ToTable("Accounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("EquipmentServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("EquipmentSlotAndDBIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("ExSkillLevel")
.HasColumnType("int");
b.Property<long>("Exp")
.HasColumnType("bigint");
b.Property<int>("ExtraPassiveSkillLevel")
.HasColumnType("int");
b.Property<long>("FavorExp")
.HasColumnType("bigint");
b.Property<int>("FavorRank")
.HasColumnType("int");
b.Property<bool>("IsFavorite")
.HasColumnType("bit");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<int>("LeaderSkillLevel")
.HasColumnType("int");
b.Property<int>("Level")
.HasColumnType("int");
b.Property<int>("PassiveSkillLevel")
.HasColumnType("int");
b.Property<string>("PotentialStats")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<int>("PublicSkillLevel")
.HasColumnType("int");
b.Property<int>("StarGrade")
.HasColumnType("int");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Characters");
});
modelBuilder.Entity("SCHALE.Common.Database.EchelonDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<long>("EchelonNumber")
.HasColumnType("bigint");
b.Property<int>("EchelonType")
.HasColumnType("int");
b.Property<int>("ExtensionType")
.HasColumnType("int");
b.Property<long>("LeaderServerId")
.HasColumnType("bigint");
b.Property<string>("MainSlotServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SkillCardMulliganCharacterIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("SupportSlotServerIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<long>("TSSInteractionServerId")
.HasColumnType("bigint");
b.Property<int>("UsingFlag")
.HasColumnType("int");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Echelons");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("IsLocked")
.HasColumnType("bit");
b.Property<long>("StackCount")
.HasColumnType("bigint");
b.Property<long>("UniqueId")
.HasColumnType("bigint");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("Items");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.Property<long>("ServerId")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("ServerId"));
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<bool>("Complete")
.HasColumnType("bit");
b.Property<long>("MissionUniqueId")
.HasColumnType("bigint");
b.Property<string>("ProgressParameters")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<DateTime>("StartTime")
.HasColumnType("datetime2");
b.HasKey("ServerId");
b.HasIndex("AccountServerId");
b.ToTable("MissionProgresses");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.AccountTutorial", b =>
{
b.Property<long>("AccountServerId")
.HasColumnType("bigint");
b.Property<string>("TutorialIds")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("AccountServerId");
b.ToTable("AccountTutorials");
});
modelBuilder.Entity("SCHALE.Common.Database.Models.GuestAccount", b =>
{
b.Property<long>("Uid")
.ValueGeneratedOnAdd()
.HasColumnType("bigint");
SqlServerPropertyBuilderExtensions.UseIdentityColumn(b.Property<long>("Uid"));
b.Property<string>("DeviceId")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.Property<string>("Token")
.IsRequired()
.HasColumnType("nvarchar(max)");
b.HasKey("Uid");
b.ToTable("GuestAccounts");
});
modelBuilder.Entity("SCHALE.Common.Database.CharacterDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Characters")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.EchelonDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Echelons")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.ItemDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("Items")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.MissionProgressDB", b =>
{
b.HasOne("SCHALE.Common.Database.AccountDB", "Account")
.WithMany("MissionProgresses")
.HasForeignKey("AccountServerId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Account");
});
modelBuilder.Entity("SCHALE.Common.Database.AccountDB", b =>
{
b.Navigation("Characters");
b.Navigation("Echelons");
b.Navigation("Items");
b.Navigation("MissionProgresses");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -9,7 +9,12 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Google.FlatBuffers" Version="24.3.25" /> <PackageReference Include="Google.FlatBuffers" Version="24.3.25" />
<PackageReference Include="MongoDB.EntityFrameworkCore" Version="7.0.0-preview.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
</ItemGroup> </ItemGroup>

View File

@ -1,21 +1,22 @@
using SCHALE.Common.Database; using SCHALE.Common.Database;
using SCHALE.Common.NetworkProtocol; using SCHALE.Common.NetworkProtocol;
using SCHALE.GameServer.Services; using SCHALE.GameServer.Services;
using MongoDB.Driver.Linq;
using SCHALE.Common.FlatData; using SCHALE.Common.FlatData;
using Serilog; using SCHALE.Common.Database.ModelExtensions;
namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{ {
public class Account : ProtocolHandlerBase public class Account : ProtocolHandlerBase
{ {
private ISessionKeyService sessionKeyService; private readonly ISessionKeyService sessionKeyService;
private SCHALEContext context; private readonly SCHALEContext context;
private readonly ExcelTableService excelTableService;
public Account(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context) : base(protocolHandlerFactory) public Account(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context, ExcelTableService _excelTableService) : base(protocolHandlerFactory)
{ {
sessionKeyService = _sessionKeyService; sessionKeyService = _sessionKeyService;
context = _context; context = _context;
excelTableService = _excelTableService;
} }
// most handlers empty // most handlers empty
@ -60,7 +61,59 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{ {
CurrentVersion = req.Version, CurrentVersion = req.Version,
AccountDB = account, AccountDB = account,
StaticOpenConditions = new()
{
{ OpenConditionContent.Shop, OpenConditionLockReason.None },
{ OpenConditionContent.Gacha, OpenConditionLockReason.None },
{ OpenConditionContent.LobbyIllust, OpenConditionLockReason.None },
{ OpenConditionContent.Raid, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Cafe, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Unit_Growth_Skill, OpenConditionLockReason.None },
{ OpenConditionContent.Unit_Growth_LevelUp, OpenConditionLockReason.None },
{ OpenConditionContent.Unit_Growth_Transcendence, OpenConditionLockReason.None },
{ OpenConditionContent.WeekDungeon, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Arena, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Academy, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Equip, OpenConditionLockReason.None },
{ OpenConditionContent.Item, OpenConditionLockReason.None },
{ OpenConditionContent.Mission, OpenConditionLockReason.None },
{ OpenConditionContent.WeekDungeon_Chase, OpenConditionLockReason.StageClear },
{ OpenConditionContent.__Deprecated_WeekDungeon_FindGift, OpenConditionLockReason.None },
{ OpenConditionContent.__Deprecated_WeekDungeon_Blood, OpenConditionLockReason.None },
{ OpenConditionContent.Story_Sub, OpenConditionLockReason.None },
{ OpenConditionContent.Story_Replay, OpenConditionLockReason.None },
{ OpenConditionContent.None, OpenConditionLockReason.None },
{ OpenConditionContent.Shop_Gem, OpenConditionLockReason.None },
{ OpenConditionContent.Craft, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Student, OpenConditionLockReason.None },
{ OpenConditionContent.GuideMission, OpenConditionLockReason.None },
{ OpenConditionContent.Clan, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Echelon, OpenConditionLockReason.None },
{ OpenConditionContent.Campaign, OpenConditionLockReason.None },
{ OpenConditionContent.EventContent, OpenConditionLockReason.None },
{ OpenConditionContent.EventStage_1, OpenConditionLockReason.StageClear },
{ OpenConditionContent.EventStage_2, OpenConditionLockReason.None },
{ OpenConditionContent.Talk, OpenConditionLockReason.None },
{ OpenConditionContent.Billing, OpenConditionLockReason.None },
{ OpenConditionContent.Schedule, OpenConditionLockReason.None },
{ OpenConditionContent.Story, OpenConditionLockReason.None },
{ OpenConditionContent.Tactic_Speed, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Cafe_Invite, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Cafe_Invite_2, OpenConditionLockReason.CafeRank | OpenConditionLockReason.StageClear },
{ OpenConditionContent.EventMiniGame_1, OpenConditionLockReason.StageClear },
{ OpenConditionContent.SchoolDungeon, OpenConditionLockReason.StageClear },
{ OpenConditionContent.TimeAttackDungeon, OpenConditionLockReason.StageClear },
{ OpenConditionContent.ShiftingCraft, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Tactic_Skip, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Mulligan, OpenConditionLockReason.StageClear },
{ OpenConditionContent.EventPermanent, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Main_L_1_2, OpenConditionLockReason.ScenarioModeClear },
{ OpenConditionContent.Main_L_1_3, OpenConditionLockReason.ScenarioModeClear },
{ OpenConditionContent.Main_L_1_4, OpenConditionLockReason.ScenarioModeClear },
{ OpenConditionContent.EliminateRaid, OpenConditionLockReason.StageClear },
{ OpenConditionContent.Cafe_2, OpenConditionLockReason.StageClear },
{ OpenConditionContent.MultiFloorRaid, OpenConditionLockReason.StageClear }
},
MissionProgressDBs = [.. context.MissionProgresses.Where(x => x.AccountServerId == account.ServerId)] MissionProgressDBs = [.. context.MissionProgresses.Where(x => x.AccountServerId == account.ServerId)]
}; };
@ -84,6 +137,58 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
context.Accounts.Add(account); context.Accounts.Add(account);
context.SaveChanges(); context.SaveChanges();
// Default items
context.Items.Add(new()
{
AccountServerId = account.ServerId,
UniqueId = 2,
StackCount = 5
});
// Default chars
var defaultCharacters = excelTableService.GetTable<DefaultCharacterExcelTable>().UnPack().DataList;
var newCharacters = defaultCharacters.Select(x =>
{
var characterExcel = excelTableService.GetTable<CharacterExcelTable>().UnPack().DataList.Find(y => y.Id == x.CharacterId);
return new CharacterDB()
{
UniqueId = x.CharacterId,
StarGrade = x.StarGrade,
Level = x.Level,
Exp = x.Exp,
FavorRank = x.FavorRank,
FavorExp = x.FavorExp,
PublicSkillLevel = 1,
ExSkillLevel = x.ExSkillLevel,
PassiveSkillLevel = x.PassiveSkillLevel,
ExtraPassiveSkillLevel = x.ExtraPassiveSkillLevel,
LeaderSkillLevel = x.LeaderSkillLevel,
IsNew = true,
IsLocked = true,
EquipmentServerIds = characterExcel is not null ? characterExcel.EquipmentSlot.Select(x => (long)0).ToList() : [0, 0, 0],
PotentialStats = { { 1, 0 }, { 2, 0 }, { 3, 0 } }
};
}).ToList();
account.AddCharacters(context, [.. newCharacters]);
context.SaveChanges();
var favCharacter = defaultCharacters.Find(x => x.FavoriteCharacter);
if (favCharacter is not null)
{
account.RepresentCharacterServerId = (int)newCharacters.First(x => x.UniqueId == favCharacter.CharacterId).ServerId;
}
if (newCharacters.Count > 0)
{
context.Echelons.Add(new()
{
AccountServerId = account.ServerId,
LeaderServerId = newCharacters[0].ServerId,
MainSlotServerIds = newCharacters.Take(3).Select(x => x.ServerId).Append(0).ToList()
});
}
context.SaveChanges();
return new AccountCreateResponse() return new AccountCreateResponse()
{ {
SessionKey = sessionKeyService.Create(account.PublisherAccountId) SessionKey = sessionKeyService.Create(account.PublisherAccountId)
@ -93,7 +198,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
[ProtocolHandler(Protocol.Account_Nickname)] [ProtocolHandler(Protocol.Account_Nickname)]
public ResponsePacket NicknameHandler(AccountNicknameRequest req) public ResponsePacket NicknameHandler(AccountNicknameRequest req)
{ {
var account = sessionKeyService.GetAccount(req.SessionKey!); var account = sessionKeyService.GetAccount(req.SessionKey);
account.Nickname = req.Nickname; account.Nickname = req.Nickname;
context.SaveChanges(); context.SaveChanges();
@ -108,6 +213,8 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
[ProtocolHandler(Protocol.Account_LoginSync)] [ProtocolHandler(Protocol.Account_LoginSync)]
public ResponsePacket LoginSyncHandler(AccountLoginSyncRequest req) public ResponsePacket LoginSyncHandler(AccountLoginSyncRequest req)
{ {
var account = sessionKeyService.GetAccount(req.SessionKey);
return new AccountLoginSyncResponse() return new AccountLoginSyncResponse()
{ {
AccountCurrencySyncResponse = new AccountCurrencySyncResponse() AccountCurrencySyncResponse = new AccountCurrencySyncResponse()
@ -172,77 +279,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
}, },
CharacterListResponse = new CharacterListResponse() CharacterListResponse = new CharacterListResponse()
{ {
CharacterDBs = new List<CharacterDB> CharacterDBs = [.. account.Characters],
{
new CharacterDB
{
ServerId = 1043998219,
UniqueId = 13003,
StarGrade = 2,
Level = 1,
FavorRank = 1,
PublicSkillLevel = 1,
ExSkillLevel = 1,
PassiveSkillLevel = 1,
ExtraPassiveSkillLevel = 1,
LeaderSkillLevel = 1,
IsNew = true,
IsLocked = true,
EquipmentServerIds = new List<long> { 0, 0, 0 },
PotentialStats = new Dictionary<int, int> { { 1, 0 }, { 2, 0 }, { 3, 0 } }
},
new CharacterDB
{
ServerId = 1043998217,
UniqueId = 13010,
StarGrade = 2,
Level = 1,
FavorRank = 1,
PublicSkillLevel = 1,
ExSkillLevel = 1,
PassiveSkillLevel = 1,
ExtraPassiveSkillLevel = 1,
LeaderSkillLevel = 1,
IsNew = true,
IsLocked = true,
EquipmentServerIds = new List<long> { 0, 0, 0 },
PotentialStats = new Dictionary<int, int> { { 1, 0 }, { 2, 0 }, { 3, 0 } }
},
new CharacterDB
{
ServerId = 1043998218,
UniqueId = 16003,
StarGrade = 1,
Level = 1,
FavorRank = 1,
PublicSkillLevel = 1,
ExSkillLevel = 1,
PassiveSkillLevel = 1,
ExtraPassiveSkillLevel = 1,
LeaderSkillLevel = 1,
IsNew = true,
IsLocked = true,
EquipmentServerIds = new List<long> { 0, 0, 0 },
PotentialStats = new Dictionary<int, int> { { 1, 0 }, { 2, 0 }, { 3, 0 } }
},
new CharacterDB
{
ServerId = 1043998220,
UniqueId = 26000,
StarGrade = 1,
Level = 1,
FavorRank = 1,
PublicSkillLevel = 1,
ExSkillLevel = 1,
PassiveSkillLevel = 1,
ExtraPassiveSkillLevel = 1,
LeaderSkillLevel = 1,
IsNew = true,
IsLocked = true,
EquipmentServerIds = new List<long> { 0, 0, 0 },
PotentialStats = new Dictionary<int, int> { { 1, 0 }, { 2, 0 }, { 3, 0 } }
}
},
TSSCharacterDBs = [], TSSCharacterDBs = [],
WeaponDBs = [], WeaponDBs = [],
CostumeDBs = [], CostumeDBs = [],
@ -255,8 +292,8 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
AccountServerId = req.AccountId, AccountServerId = req.AccountId,
EchelonType = EchelonType.Adventure, EchelonType = EchelonType.Adventure,
EchelonNumber = 1, EchelonNumber = 1,
LeaderServerId = 123, LeaderServerId = 1,
MainSlotServerIds = [1043998217, 1043998218, 1043998219, 0 ], MainSlotServerIds = [1, 2, 3, 0 ],
SupportSlotServerIds = [ 444, 0], SupportSlotServerIds = [ 444, 0],
SkillCardMulliganCharacterIds = [] SkillCardMulliganCharacterIds = []
} }
@ -280,48 +317,51 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
new() { EventContentId = 900701 }, new() { EventContentId = 900701 },
], ],
}, },
FriendCode = "SCHALE"
FriendCode = "SCHALEPS",
ServerNotification = ServerNotificationFlag.HasUnreadMail,
SessionKey = new()
{
AccountServerId = req.AccountId,
MxToken = req.SessionKey.MxToken,
},
}; };
} }
[ProtocolHandler(Protocol.Account_GetTutorial)] [ProtocolHandler(Protocol.Account_GetTutorial)]
public ResponsePacket GetTutorialHandler(AccountGetTutorialRequest req) public ResponsePacket GetTutorialHandler(AccountGetTutorialRequest req)
{ {
var tutorialIds = context.AccountTutorials.SingleOrDefault(x => x.AccountServerId == sessionKeyService.GetAccount(req.SessionKey).ServerId)?.TutorialIds;
return new AccountGetTutorialResponse() return new AccountGetTutorialResponse()
{ {
#if DEBUG TutorialIds = tutorialIds ?? []
TutorialIds = [1, 2]
#endif
}; };
} }
[ProtocolHandler(Protocol.Account_SetTutorial)] [ProtocolHandler(Protocol.Account_SetTutorial)]
public ResponsePacket SetTutorialHandler(AccountSetTutorialRequest req) public ResponsePacket SetTutorialHandler(AccountSetTutorialRequest req)
{ {
var account = sessionKeyService.GetAccount(req.SessionKey);
return new AccountSetTutorialResponse() var tutorial = context.AccountTutorials.SingleOrDefault(x => x.AccountServerId == account.ServerId);
if (tutorial == null)
{ {
tutorial = new()
{
AccountServerId = account.ServerId,
TutorialIds = req.TutorialIds
}; };
context.AccountTutorials.Add(tutorial);
}
else
{
tutorial.TutorialIds = req.TutorialIds;
}
context.SaveChanges();
return new AccountSetTutorialResponse();
} }
// others handlers, move to different handler group later // TODO: others handlers, move to different handler group later
[ProtocolHandler(Protocol.NetworkTime_Sync)] [ProtocolHandler(Protocol.NetworkTime_Sync)]
public ResponsePacket NetworkTime_SyncHandler(NetworkTimeSyncRequest req) public ResponsePacket NetworkTime_SyncHandler(NetworkTimeSyncRequest req)
{ {
long received_tick = DateTimeOffset.Now.Ticks;
return new NetworkTimeSyncResponse() return new NetworkTimeSyncResponse()
{ {
ReceiveTick = received_tick, ReceiveTick = DateTimeOffset.Now.Ticks,
EchoSendTick = DateTimeOffset.Now.Ticks EchoSendTick = DateTimeOffset.Now.Ticks
}; };
} }
@ -329,70 +369,49 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
[ProtocolHandler(Protocol.ContentSave_Get)] [ProtocolHandler(Protocol.ContentSave_Get)]
public ResponsePacket ContentSave_GetHandler(ContentSaveGetRequest req) public ResponsePacket ContentSave_GetHandler(ContentSaveGetRequest req)
{ {
return new ContentSaveGetResponse() return new ContentSaveGetResponse();
{
ServerNotification = ServerNotificationFlag.HasUnreadMail,
};
} }
[ProtocolHandler(Protocol.Toast_List)] [ProtocolHandler(Protocol.Toast_List)]
public ResponsePacket ToastListHandler(ToastListRequest req) public ResponsePacket ToastListHandler(ToastListRequest req)
{ {
return new ToastListResponse() return new ToastListResponse();
{
};
} }
[ProtocolHandler(Protocol.ContentLog_UIOpenStatistics)] [ProtocolHandler(Protocol.ContentLog_UIOpenStatistics)]
public ResponsePacket ContentLog_UIOpenStatisticsHandler(ContentLogUIOpenStatisticsRequest req) public ResponsePacket ContentLog_UIOpenStatisticsHandler(ContentLogUIOpenStatisticsRequest req)
{ {
return new ContentLogUIOpenStatisticsResponse() return new ContentLogUIOpenStatisticsResponse();
{
};
} }
[ProtocolHandler(Protocol.Event_RewardIncrease)] [ProtocolHandler(Protocol.Event_RewardIncrease)]
public ResponsePacket Event_RewardIncreaseHandler(EventRewardIncreaseRequest req) public ResponsePacket Event_RewardIncreaseHandler(EventRewardIncreaseRequest req)
{ {
return new EventRewardIncreaseResponse() return new EventRewardIncreaseResponse();
{
};
} }
[ProtocolHandler(Protocol.OpenCondition_EventList)] [ProtocolHandler(Protocol.OpenCondition_EventList)]
public ResponsePacket OpenCondition_EventListHandler(OpenConditionEventListRequest req) public ResponsePacket OpenCondition_EventListHandler(OpenConditionEventListRequest req)
{ {
return new OpenConditionEventListResponse() return new OpenConditionEventListResponse();
{
};
} }
[ProtocolHandler(Protocol.Notification_EventContentReddotCheck)] [ProtocolHandler(Protocol.Notification_EventContentReddotCheck)]
public ResponsePacket Notification_EventContentReddotCheckHandler(NotificationEventContentReddotRequest req) public ResponsePacket Notification_EventContentReddotCheckHandler(NotificationEventContentReddotRequest req)
{ {
return new NotificationEventContentReddotResponse() return new NotificationEventContentReddotResponse();
{
};
} }
[ProtocolHandler(Protocol.Billing_PurchaseListByYostar)] [ProtocolHandler(Protocol.Billing_PurchaseListByYostar)]
public ResponsePacket Billing_PurchaseListByYostarHandler(BillingPurchaseListByYostarRequest req) public ResponsePacket Billing_PurchaseListByYostarHandler(BillingPurchaseListByYostarRequest req)
{ {
return new BillingPurchaseListByYostarResponse() return new BillingPurchaseListByYostarResponse();
{
};
} }
} }

View File

@ -18,11 +18,12 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
[ProtocolHandler(Protocol.Item_List)] [ProtocolHandler(Protocol.Item_List)]
public ResponsePacket ListHandler(ItemListRequest req) public ResponsePacket ListHandler(ItemListRequest req)
{ {
var account = sessionKeyService.GetAccount(req.SessionKey);
return new ItemListResponse() return new ItemListResponse()
{ {
ItemDBs = [], ItemDBs = [.. account.Items],
ExpiryItemDBs = [], ExpiryItemDBs = []
ServerNotification = ServerNotificationFlag.HasUnreadMail,
}; };
} }
} }

View File

@ -1,5 +1,4 @@
using MongoDB.Driver.Linq; using SCHALE.Common.Database;
using SCHALE.Common.Database;
using SCHALE.Common.NetworkProtocol; using SCHALE.Common.NetworkProtocol;
using SCHALE.GameServer.Services; using SCHALE.GameServer.Services;
using Serilog; using Serilog;
@ -8,8 +7,8 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{ {
public class Mission : ProtocolHandlerBase public class Mission : ProtocolHandlerBase
{ {
private ISessionKeyService sessionKeyService; private readonly ISessionKeyService sessionKeyService;
private SCHALEContext context; private readonly SCHALEContext context;
public Mission(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context) : base(protocolHandlerFactory) public Mission(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context) : base(protocolHandlerFactory)
{ {
@ -33,10 +32,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
[ProtocolHandler(Protocol.Mission_GuideMissionSeasonList)] [ProtocolHandler(Protocol.Mission_GuideMissionSeasonList)]
public ResponsePacket GuideMissionSeasonListHandler(GuideMissionSeasonListRequest req) public ResponsePacket GuideMissionSeasonListHandler(GuideMissionSeasonListRequest req)
{ {
return new GuideMissionSeasonListResponse() return new GuideMissionSeasonListResponse();
{
};
} }
} }
} }

View File

@ -14,22 +14,13 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
Log.Information($"ScenarioSkipRequest SkipPointScriptCount: " + req.SkipPointScriptCount); Log.Information($"ScenarioSkipRequest SkipPointScriptCount: " + req.SkipPointScriptCount);
// skip story doesn't work yet, probably need to implement missiondb // skip story doesn't work yet, probably need to implement missiondb
return new ScenarioSkipResponse() return new ScenarioSkipResponse();
{
};
} }
[ProtocolHandler(Protocol.Scenario_Select)] [ProtocolHandler(Protocol.Scenario_Select)]
public ResponsePacket SelectHandler(ScenarioSelectRequest req) public ResponsePacket SelectHandler(ScenarioSelectRequest req)
{ {
return new ScenarioSelectResponse();
return new ScenarioSelectResponse()
{
};
} }
} }
} }

View File

@ -1,16 +1,16 @@
using SCHALE.Common.Database; using SCHALE.Common.Database;
using SCHALE.Common.NetworkProtocol; using SCHALE.Common.NetworkProtocol;
using SCHALE.GameServer.Services; using SCHALE.GameServer.Services;
using Serilog;
namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{ {
public class Shop : ProtocolHandlerBase public class Shop : ProtocolHandlerBase
{ {
private ISessionKeyService sessionKeyService; private readonly ISessionKeyService sessionKeyService;
private SCHALEContext context; private readonly SCHALEContext context;
public List<long> SavedGachaResults { get; set; } // temp storage until gacha management // TODO: temp storage until gacha management
public List<long> SavedGachaResults { get; set; } = [];
public Shop(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context) : base(protocolHandlerFactory) public Shop(IProtocolHandlerFactory protocolHandlerFactory, ISessionKeyService _sessionKeyService, SCHALEContext _context) : base(protocolHandlerFactory)
{ {
@ -21,14 +21,7 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
[ProtocolHandler(Protocol.Shop_BeforehandGachaGet)] [ProtocolHandler(Protocol.Shop_BeforehandGachaGet)]
public ResponsePacket BeforehandGachaGetHandler(ShopBeforehandGachaGetRequest req) public ResponsePacket BeforehandGachaGetHandler(ShopBeforehandGachaGetRequest req)
{ {
return new ShopBeforehandGachaGetResponse() return new ShopBeforehandGachaGetResponse();
{
SessionKey = new()
{
MxToken = req.SessionKey.MxToken,
AccountServerId = req.SessionKey.AccountServerId,
}
};
} }
[ProtocolHandler(Protocol.Shop_BeforehandGachaRun)] [ProtocolHandler(Protocol.Shop_BeforehandGachaRun)]

View File

@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using SCHALE.Common.Database; using SCHALE.Common.Database;
using SCHALE.Common.Database.Models;
using SCHALE.GameServer.Models; using SCHALE.GameServer.Models;
namespace SCHALE.GameServer.Controllers namespace SCHALE.GameServer.Controllers
@ -35,8 +34,9 @@ namespace SCHALE.GameServer.Controllers
if (account is null) if (account is null)
{ {
account = new() { DeviceId = deviceId, Token = Guid.NewGuid().ToString() }; account = new() { DeviceId = deviceId, Token = Guid.NewGuid().ToString() };
context.Add(account); context.GuestAccounts.Add(account);
context.SaveChanges(); context.SaveChanges();
rsp.IsNew = 1; rsp.IsNew = 1;
} }

View File

@ -5,6 +5,7 @@ using System.Reflection;
using SCHALE.Common.Database; using SCHALE.Common.Database;
using SCHALE.GameServer.Controllers.Api.ProtocolHandlers; using SCHALE.GameServer.Controllers.Api.ProtocolHandlers;
using SCHALE.GameServer.Services; using SCHALE.GameServer.Services;
using Microsoft.EntityFrameworkCore;
namespace SCHALE.GameServer namespace SCHALE.GameServer
{ {
@ -13,13 +14,15 @@ namespace SCHALE.GameServer
public static void Main(string[] args) public static void Main(string[] args)
{ {
var config = new ConfigurationBuilder() var config = new ConfigurationBuilder()
.SetBasePath(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!) .SetBasePath(Path.GetDirectoryName(AppContext.BaseDirectory)!)
.AddJsonFile("appsettings.json") .AddJsonFile("appsettings.json")
.AddJsonFile("appsettings.Local.json", true)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true) .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", true)
.Build(); .Build();
{ {
var logFilePath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "logs", "log.txt"); var logFilePath = Path.Combine(Path.GetDirectoryName(AppContext.BaseDirectory)!, "logs", "log.txt");
if (File.Exists(logFilePath)) if (File.Exists(logFilePath))
{ {
var prevLogFilePath = Path.Combine(Path.GetDirectoryName(logFilePath)!, "log-prev.txt"); var prevLogFilePath = Path.Combine(Path.GetDirectoryName(logFilePath)!, "log-prev.txt");
@ -28,6 +31,7 @@ namespace SCHALE.GameServer
File.Move(logFilePath, prevLogFilePath); File.Move(logFilePath, prevLogFilePath);
} }
Log.Logger = new LoggerConfiguration() Log.Logger = new LoggerConfiguration()
.WriteTo.Console() .WriteTo.Console()
.WriteTo.File(logFilePath, restrictedToMinimumLevel: LogEventLevel.Verbose, shared: true) .WriteTo.File(logFilePath, restrictedToMinimumLevel: LogEventLevel.Verbose, shared: true)
@ -44,10 +48,11 @@ namespace SCHALE.GameServer
builder.Host.UseSerilog(); builder.Host.UseSerilog();
// Add services to the container. // Add services to the container.
builder.Services.AddSQLServerProvider(config.GetConnectionString("SQLServer") ?? throw new ArgumentNullException("ConnectionStrings/SQLServer in appsettings is missing"));
builder.Services.AddControllers(); builder.Services.AddControllers();
builder.Services.AddMongoDBProvider(config.GetConnectionString("MongoDB") ?? throw new ArgumentNullException("ConnectionStrings/MongoDB in appsettings is missing"));
builder.Services.AddProtocolHandlerFactory(); builder.Services.AddProtocolHandlerFactory();
builder.Services.AddMemorySessionKeyService(); builder.Services.AddMemorySessionKeyService();
builder.Services.AddExcelTableService();
// Add all Handler Groups // Add all Handler Groups
var handlerGroups = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(ProtocolHandlerBase))); var handlerGroups = Assembly.GetExecutingAssembly().GetTypes().Where(t => t.IsSubclassOf(typeof(ProtocolHandlerBase)));
@ -57,6 +62,13 @@ namespace SCHALE.GameServer
var app = builder.Build(); var app = builder.Build();
using (var scope = app.Services.CreateScope())
{
var context = scope.ServiceProvider.GetRequiredService<SCHALEContext>();
if (context.Database.GetPendingMigrations().Any())
context.Database.Migrate();
}
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
app.UseAuthorization(); app.UseAuthorization();
app.UseSerilogRequestLogging(); app.UseSerilogRequestLogging();

View File

@ -5,7 +5,7 @@
"commandName": "Project", "commandName": "Project",
"dotnetRunMessages": true, "dotnetRunMessages": true,
"launchBrowser": false, "launchBrowser": false,
"applicationUrl": "https://0.0.0.0:443;http://0.0.0.0:80", "externalUrlConfiguration": true,
"environmentVariables": { "environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development" "ASPNETCORE_ENVIRONMENT": "Development"
} }

View File

@ -7,6 +7,10 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" /> <PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
</ItemGroup> </ItemGroup>

View File

@ -0,0 +1,55 @@
using Google.FlatBuffers;
using SCHALE.Common.Crypto;
using System.Reflection;
namespace SCHALE.GameServer.Services
{
// TODO: High priority, cache UnPack-ed table!
public class ExcelTableService
{
private readonly ILogger<ExcelTableService> logger;
private readonly Dictionary<Type, object> caches = [];
public ExcelTableService(ILogger<ExcelTableService> _logger)
{
logger = _logger;
}
/// <summary>
/// Please <b>only</b> use this to get table that <b>have a respective file</b> (i.e. <c>CharacterExcelTable</c> have <c>characterexceltable.bytes</c>)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
/// <exception cref="FileNotFoundException"></exception>
public T GetTable<T>() where T : IFlatbufferObject
{
var type = typeof(T);
if (caches.TryGetValue(type, out var cache))
return (T)cache;
var bytesFilePath = Path.Join(Path.GetDirectoryName(AppContext.BaseDirectory), "Resources/excel/", $"{type.Name.ToLower()}.bytes");
if (!File.Exists(bytesFilePath))
{
throw new FileNotFoundException($"bytes files for {type.Name} not found");
}
var bytes = File.ReadAllBytes(bytesFilePath);
TableEncryptionService.XOR(type.Name, bytes);
var inst = type.GetMethod($"GetRootAs{type.Name}", BindingFlags.Static | BindingFlags.Public, [typeof(ByteBuffer)])!.Invoke(null, [new ByteBuffer(bytes)]);
caches.Add(type, inst!);
logger.LogDebug("{Excel} loaded and cached", type.Name);
return (T)inst!;
}
}
internal static class ExcelTableServiceExtensions
{
public static void AddExcelTableService(this IServiceCollection services)
{
services.AddSingleton<ExcelTableService>();
}
}
}

View File

@ -17,8 +17,11 @@ namespace SCHALE.GameServer.Services
context = _context; context = _context;
} }
public AccountDB GetAccount(SessionKey sessionKey) public AccountDB GetAccount(SessionKey? sessionKey)
{ {
if (sessionKey is null)
throw new WebAPIException(WebAPIErrorCode.InvalidSession, "SessionKey not received");
if (sessions.TryGetValue(sessionKey.AccountServerId, out Guid token) && token.ToString() == sessionKey.MxToken) if (sessions.TryGetValue(sessionKey.AccountServerId, out Guid token) && token.ToString() == sessionKey.MxToken)
{ {
var account = context.Accounts.SingleOrDefault(x => x.ServerId == sessionKey.AccountServerId); var account = context.Accounts.SingleOrDefault(x => x.ServerId == sessionKey.AccountServerId);
@ -53,7 +56,7 @@ namespace SCHALE.GameServer.Services
} }
} }
internal static class ServiceExtensions internal static class SessionKeyServiceExtensions
{ {
public static void AddMemorySessionKeyService(this IServiceCollection services) public static void AddMemorySessionKeyService(this IServiceCollection services)
{ {
@ -64,6 +67,6 @@ namespace SCHALE.GameServer.Services
public interface ISessionKeyService public interface ISessionKeyService
{ {
public SessionKey? Create(long publisherAccountId); public SessionKey? Create(long publisherAccountId);
public AccountDB GetAccount(SessionKey sessionKey); public AccountDB GetAccount(SessionKey? sessionKey);
} }
} }

View File

@ -1,4 +1,14 @@
{ {
"Kestrel": {
"EndPoints": {
"Http": {
"Url": "http://0.0.0.0:80"
},
"Https": {
"Url": "https://0.0.0.0:443"
}
}
},
"Serilog": { "Serilog": {
"MinimumLevel": { "MinimumLevel": {
"Default": "Information", "Default": "Information",
@ -9,7 +19,7 @@
} }
}, },
"ConnectionStrings": { "ConnectionStrings": {
"MongoDB": "mongodb://localhost:27017/SCHALE" "SQLServer": "data source=localhost\\SQLEXPRESS;initial catalog=schale;trusted_connection=true;TrustServerCertificate=True"
}, },
"AllowedHosts": "*" "AllowedHosts": "*"
} }

40
Scripts/migrate.ps1 Normal file
View File

@ -0,0 +1,40 @@
[CmdletBinding()]
param(
[Parameter(ValueFromRemainingArguments)]
[string[]]$Arguments
)
$ScriptDir = ([IO.Path]::GetDirectoryName($MyInvocation.MyCommand.Source))
$CommonProjectPath = ([IO.Path]::Join($ScriptDir, "..\SCHALE.Common\SCHALE.Common.csproj"))
$GameServerProjectPath = ([IO.Path]::Join($ScriptDir, "..\SCHALE.GameServer\SCHALE.GameServer.csproj"))
if ($Arguments.Length -lt 1 -Or $Arguments[0].Equals("-h") -Or $Arguments[0].Equals("--help"))
{
Write-Output @"
Commands
-h|--help shows this help output
undo expands to dotnet ef migrations remove, undo latest migration
create expands to dotnet ef migrations add, second positional argument will be the migration name
Examples
migrate.ps1 create Test
migrate.ps1 undo
"@
exit
}
Switch ($Arguments[0])
{
"undo"
{
dotnet ef migrations remove --project $CommonProjectPath --startup-project $GameServerProjectPath --context SCHALEContext
}
"create"
{
dotnet ef migrations add $Arguments[1] --project $CommonProjectPath --startup-project $GameServerProjectPath --context SCHALEContext
}
default
{
Write-Host "Invalid operation" $Arguments[0]
}
}