diff --git a/DCGEngine.Database/Models/BaseEntity.cs b/DCGEngine.Database/Models/BaseEntity.cs index 4e15dfd..21bfe67 100644 --- a/DCGEngine.Database/Models/BaseEntity.cs +++ b/DCGEngine.Database/Models/BaseEntity.cs @@ -1,4 +1,5 @@ using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using DCGEngine.Database.Interfaces; namespace DCGEngine.Database.Models; @@ -6,6 +7,7 @@ namespace DCGEngine.Database.Models; public class BaseEntity : ITimeTrackedEntity, IDbTrackedEntity { [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] public virtual TKey Id { get; set; } public DateTime? DateCreated { get; set; } diff --git a/DCGEngine.Database/Models/CardEntry.cs b/DCGEngine.Database/Models/CardEntry.cs index f0af1fc..d25ecef 100644 --- a/DCGEngine.Database/Models/CardEntry.cs +++ b/DCGEngine.Database/Models/CardEntry.cs @@ -1,3 +1,5 @@ +using System.ComponentModel.DataAnnotations; + namespace DCGEngine.Database.Models; /// @@ -8,7 +10,8 @@ public abstract class CardEntry : BaseEntity /// /// The name of this card used internally, to separate it from any localization key stored. /// - public virtual string InternalName { get; set; } + [Required(AllowEmptyStrings = false)] + public virtual string Name { get; set; } = string.Empty; /// /// The offensive power of this card. diff --git a/DCGEngine.Database/Models/CardSetEntry.cs b/DCGEngine.Database/Models/CardSetEntry.cs new file mode 100644 index 0000000..2c832c9 --- /dev/null +++ b/DCGEngine.Database/Models/CardSetEntry.cs @@ -0,0 +1,17 @@ +namespace DCGEngine.Database.Models; + +/// +/// A set containing 0 or more s. All cards must belong to a set. +/// +public abstract class CardSetEntry : BaseEntity +{ + /// + /// The internal name of the set. + /// + public virtual string Name { get; set; } = string.Empty; + + /// + /// The cards in the set. + /// + public virtual List Cards { get; set; } = new List(); +} \ No newline at end of file diff --git a/DCGEngine.Database/Models/DeckCard.cs b/DCGEngine.Database/Models/DeckCard.cs new file mode 100644 index 0000000..f74e174 --- /dev/null +++ b/DCGEngine.Database/Models/DeckCard.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; + +namespace DCGEngine.Database.Models; + +/// +/// A that is in a X times. +/// +[Owned] +public class DeckCard +{ + /// + /// The card in the deck. + /// + public virtual CardEntry Card { get; set; } + + /// + /// The number of the card that is in the deck. + /// + public virtual int Count { get; set; } + + /// + /// The deck this belongs to. + /// + public virtual DeckEntry Deck { get; set; } +} \ No newline at end of file diff --git a/DCGEngine.Database/Models/DeckEntry.cs b/DCGEngine.Database/Models/DeckEntry.cs index 437bcc3..37a0953 100644 --- a/DCGEngine.Database/Models/DeckEntry.cs +++ b/DCGEngine.Database/Models/DeckEntry.cs @@ -1,3 +1,5 @@ +using System.ComponentModel.DataAnnotations; + namespace DCGEngine.Database.Models; /// @@ -8,10 +10,11 @@ public abstract class DeckEntry : BaseEntity /// /// How this deck is referred to internally. /// - public virtual string InternalName { get; set; } - + [Required(AllowEmptyStrings = false)] + public virtual string Name { get; set; } = string.Empty; + /// /// The cards present in this deck. /// - public virtual List Cards { get; set; } + public virtual List Cards { get; set; } = new List(); } \ No newline at end of file diff --git a/SVSim.Database/Enums/FeatureMaintenance.cs b/SVSim.Database/Enums/FeatureMaintenance.cs new file mode 100644 index 0000000..2fbc7e0 --- /dev/null +++ b/SVSim.Database/Enums/FeatureMaintenance.cs @@ -0,0 +1,101 @@ +namespace SVSim.Database.Enums; + +public enum FeatureMaintenance +{ + ProfileMaintenance = 2001, + MypageMaintenance, + GiftMaintenance, + SignupMaintenance, + PaymentMaintenanceIOs, + PaymentMaintenanceAndroid, + PaymentMaintenanceDmm = 2025, + PaymentMaintenanceSteam, + ShopCardpackMaintenance = 2007, + ShopBuilddeckMaintenance = 2032, + ShopSleeveMaintenance = 2008, + ShopSkinMaintenance = 2024, + ShopItemMaintenance = 2037, + AchievementMaintenance = 2009, + MissionMaintenance, + BpPointMaintenance, + FreebattleMaintenance, + RankbattleMaintenance, + RoomBattleMaintenance, + StoryMaintenance, + PracticeMaintenance, + ArenaTwopickMaintenance, + CardMaintenance, + DeckMaintenance, + TutorialMaintenance, + AccountMaintenance, + FriendMaintenance, + ArenaTwopickBattleMaintenance, + RoomTwopickMaintenance = 2029, + RoomAllMaintenance, + RoomWatchingMaintenance, + RoomRuleBo1 = 2038, + RoomRuleTwoPick, + RoomRuleTwoPickBackdraft, + RoomRuleBo3, + RoomRuleBo5, + RoomRuleBo3Ban1 = 2071, + RoomRuleBo5Ban1, + ArenaConvention = 2043, + FreebattleUnlimited, + FreebattleRotation, + RankbattleUnlimited, + RankbattleRotation, + RoomUnlimited, + RoomRotation, + Colosseum, + ColosseumBattle, + ColosseumRankMatchUser, + RoomRuleTwoPickQube, + GuildMaintenance, + ArenaSealedMaintenance, + ArenaSealedBattleMaintenance, + RoomFormatHof, + SealedDeckCode = 2059, + SpotcardExchange, + RoomPreRotation, + RoomRuleTwoPickBo3, + RoomRuleTwoPickBo5, + FreebattlePrerotation = 2065, + GatheringAll, + GatheringCreate, + BattlePass = 2070, + RoomRuleTwoPickChaos = 2073, + Quest = 2077, + RoomFormatWindfall, + DeckQrCode, + AutoDeckCreate, + CompetitionAll, + CompetitionBattle, + CompetitionRankMatchUser, + FreebattleCrossover, + RankbattleCrossover, + RoomFormatCrossover, + GatheringCrossover, + PracticePuzzle, + FreebattleMyrotation = 2093, + RoomFormatMyrotation, + GatheringMyrotation, + BossRush, + SecretBossBattle = 2100, + ReplayAll = 2034, + NewreplayAll = 2097, + NewreplayExcludeRotation, + NewreplayRecord, + ChatGuild = 2101, + ChatGathering, + FreebattleAvatar, + RoomFormatAvatar, + GatheringAvatar, + RoomRuleTwoPickCubeBackdraft, + RoomRuleTwoPickCubeBo3, + RoomRuleTwoPickCubeBo5, + RoomRuleTwoPickChaosBackdraft, + RoomRuleTwoPickChaosBo3, + RoomRuleTwoPickChaosBo5, + InvalidValue = 0 +} \ No newline at end of file diff --git a/SVSim.Database/Enums/PickTwoFormat.cs b/SVSim.Database/Enums/PickTwoFormat.cs new file mode 100644 index 0000000..4895f0f --- /dev/null +++ b/SVSim.Database/Enums/PickTwoFormat.cs @@ -0,0 +1,12 @@ +namespace SVSim.Database.Enums; + +public enum PickTwoFormat +{ + None, + Normal, + Backdraft, + Cube, + Chaos, + BackdraftCube, + BackdraftChaos +} \ No newline at end of file diff --git a/SVSim.Database/Enums/Rarity.cs b/SVSim.Database/Enums/Rarity.cs new file mode 100644 index 0000000..bcd922a --- /dev/null +++ b/SVSim.Database/Enums/Rarity.cs @@ -0,0 +1,10 @@ +namespace SVSim.Database.Enums; + +public enum Rarity +{ + Unknown = 0, + Bronze = 1, + Silver = 2, + Gold = 3, + Legendary = 4 +} \ No newline at end of file diff --git a/SVSim.Database/Models/ClassEntry.cs b/SVSim.Database/Models/ClassEntry.cs new file mode 100644 index 0000000..f19c9c8 --- /dev/null +++ b/SVSim.Database/Models/ClassEntry.cs @@ -0,0 +1,12 @@ +using System.ComponentModel.DataAnnotations.Schema; +using DCGEngine.Database.Models; + +namespace SVSim.Database.Models; + +public class ClassEntry : BaseEntity +{ + /// + /// The name of the class. + /// + public string Name { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/SVSim.Database/Models/CollectionInfo.cs b/SVSim.Database/Models/CollectionInfo.cs new file mode 100644 index 0000000..668218b --- /dev/null +++ b/SVSim.Database/Models/CollectionInfo.cs @@ -0,0 +1,10 @@ +using Microsoft.EntityFrameworkCore; + +namespace SVSim.Database.Models; + +[Owned] +public class CollectionInfo +{ + public int CraftCost { get; set; } + public int DustReward { get; set; } +} \ No newline at end of file diff --git a/SVSim.Database/Models/DegreeEntry.cs b/SVSim.Database/Models/DegreeEntry.cs new file mode 100644 index 0000000..0cbb9b8 --- /dev/null +++ b/SVSim.Database/Models/DegreeEntry.cs @@ -0,0 +1,8 @@ +using DCGEngine.Database.Models; + +namespace SVSim.Database.Models; + +public class DegreeEntry : BaseEntity +{ + +} \ No newline at end of file diff --git a/SVSim.Database/Models/EmblemEntry.cs b/SVSim.Database/Models/EmblemEntry.cs new file mode 100644 index 0000000..86d1583 --- /dev/null +++ b/SVSim.Database/Models/EmblemEntry.cs @@ -0,0 +1,8 @@ +using DCGEngine.Database.Models; + +namespace SVSim.Database.Models; + +public class EmblemEntry : BaseEntity +{ + +} \ No newline at end of file diff --git a/SVSim.Database/Models/FormatEntry.cs b/SVSim.Database/Models/FormatEntry.cs new file mode 100644 index 0000000..cd8123e --- /dev/null +++ b/SVSim.Database/Models/FormatEntry.cs @@ -0,0 +1,8 @@ +using DCGEngine.Database.Models; + +namespace SVSim.Database.Models; + +public class FormatEntry : BaseEntity +{ + public string Name { get; set; } = string.Empty; +} \ No newline at end of file diff --git a/SVSim.Database/Models/ShadowverseCardEntry.cs b/SVSim.Database/Models/ShadowverseCardEntry.cs index 8dfd1af..ae81da9 100644 --- a/SVSim.Database/Models/ShadowverseCardEntry.cs +++ b/SVSim.Database/Models/ShadowverseCardEntry.cs @@ -1,12 +1,37 @@ using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; using DCGEngine.Database.Models; +using SVSim.Database.Enums; namespace SVSim.Database.Models; public class ShadowverseCardEntry : CardEntry { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public override long Id { get; set; } + /// + /// The rarity of this card. + /// + public Rarity Rarity { get; set; } + + #region Owned + + /// + /// Info about this card in the collection, if it can be collected. + /// + public CollectionInfo? CollectionInfo { get; set; } + + #endregion + + #region Navigation Properties + + /// + /// The class this card belongs to, or optionally none for neutral cards. + /// + public ClassEntry? Class { get; set; } + + /// + /// The set this card belongs to. + /// + public CardSetEntry CardSet { get; set; } = new ShadowverseCardSetEntry(); + + #endregion } \ No newline at end of file diff --git a/SVSim.Database/Models/ShadowverseCardSetEntry.cs b/SVSim.Database/Models/ShadowverseCardSetEntry.cs new file mode 100644 index 0000000..a7242a8 --- /dev/null +++ b/SVSim.Database/Models/ShadowverseCardSetEntry.cs @@ -0,0 +1,8 @@ +using System.ComponentModel.DataAnnotations.Schema; +using DCGEngine.Database.Models; + +namespace SVSim.Database.Models; + +public class ShadowverseCardSetEntry : CardSetEntry +{ +} \ No newline at end of file diff --git a/SVSim.Database/Models/SocialAccountConnection.cs b/SVSim.Database/Models/SocialAccountConnection.cs index fcd295d..b066aec 100644 --- a/SVSim.Database/Models/SocialAccountConnection.cs +++ b/SVSim.Database/Models/SocialAccountConnection.cs @@ -1,3 +1,4 @@ +using System.ComponentModel.DataAnnotations.Schema; using DCGEngine.Database.Models; using SVSim.Database.Enums; @@ -8,6 +9,9 @@ namespace SVSim.Database.Models; /// public class SocialAccountConnection : BaseEntity { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public override Guid Id { get; set; } + /// /// The type of the social account. /// diff --git a/SVSim.Database/Models/Viewer.cs b/SVSim.Database/Models/Viewer.cs index 9c73883..13a89f9 100644 --- a/SVSim.Database/Models/Viewer.cs +++ b/SVSim.Database/Models/Viewer.cs @@ -1,3 +1,4 @@ +using System.ComponentModel.DataAnnotations.Schema; using DCGEngine.Database.Models; namespace SVSim.Database.Models; @@ -7,6 +8,9 @@ namespace SVSim.Database.Models; /// public class Viewer : BaseEntity { + [DatabaseGenerated(DatabaseGeneratedOption.Identity)] + public override ulong Id { get; set; } + /// /// This user's name displayed in game. /// @@ -16,6 +20,18 @@ public class Viewer : BaseEntity /// This user's short identifier. /// public ulong ShortUdid { get; set; } + + public DateTime LastLogin { get; set; } + + #region Owned + + public ViewerInfo Info { get; set; } = new ViewerInfo(); + + public ViewerMissionData MissionData { get; set; } = new ViewerMissionData(); + + public ViewerCurrency Currency { get; set; } = new ViewerCurrency(); + + #endregion #region Navigation Properties diff --git a/SVSim.Database/Models/ViewerCurrency.cs b/SVSim.Database/Models/ViewerCurrency.cs new file mode 100644 index 0000000..b9bf0ed --- /dev/null +++ b/SVSim.Database/Models/ViewerCurrency.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; + +namespace SVSim.Database.Models; + +[Owned] +public class ViewerCurrency +{ + public ulong Crystals { get; set; } + public ulong AndroidCrystals { get; set; } + public ulong IosCrystals { get; set; } + public ulong SteamCrystals { get; set; } + public ulong DmmCrystals { get; set; } + public ulong FreeCrystals { get; set; } + public ulong TotalCrystals { get; set; } + public ulong LifeTotalCrystals { get; set; } + public ulong RedEther { get; set; } + public ulong Rupees { get; set; } +} \ No newline at end of file diff --git a/SVSim.Database/Models/ViewerInfo.cs b/SVSim.Database/Models/ViewerInfo.cs new file mode 100644 index 0000000..8d27224 --- /dev/null +++ b/SVSim.Database/Models/ViewerInfo.cs @@ -0,0 +1,21 @@ +using Microsoft.EntityFrameworkCore; + +namespace SVSim.Database.Models; + +[Owned] +public class ViewerInfo +{ + public DateTime BirthDate { get; set; } + public string CountryCode { get; set; } = string.Empty; + public int MaxFriends { get; set; } + public bool IsOfficial { get; set; } + public bool IsOfficialMarkDisplayed { get; set; } + + #region Navigation Properties + + public EmblemEntry SelectedEmblem { get; set; } = new EmblemEntry(); + + public DegreeEntry SelectedDegree { get; set; } = new DegreeEntry(); + + #endregion +} \ No newline at end of file diff --git a/SVSim.Database/Models/ViewerMissionData.cs b/SVSim.Database/Models/ViewerMissionData.cs new file mode 100644 index 0000000..61cc72e --- /dev/null +++ b/SVSim.Database/Models/ViewerMissionData.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; + +namespace SVSim.Database.Models; + +[Owned] +public class ViewerMissionData +{ + public bool HasReceivedPickTwoMission { get; set; } + public int MissionReceiveType { get; set; } + public DateTime MissionChangeTime { get; set; } + public int TutorialState { get; set; } +} \ No newline at end of file diff --git a/SVSim.Database/Repositories/Viewer/IViewerRepository.cs b/SVSim.Database/Repositories/Viewer/IViewerRepository.cs index f69080a..56a4ae6 100644 --- a/SVSim.Database/Repositories/Viewer/IViewerRepository.cs +++ b/SVSim.Database/Repositories/Viewer/IViewerRepository.cs @@ -6,4 +6,5 @@ public interface IViewerRepository { Task GetViewerBySocialConnection(SocialAccountType accountType, ulong socialId); Task GetViewerWithSocials(ulong id); + Task GetViewerByShortUdid(ulong shortUdid); } \ No newline at end of file diff --git a/SVSim.Database/Repositories/Viewer/ViewerRepository.cs b/SVSim.Database/Repositories/Viewer/ViewerRepository.cs index 0bba929..33005ae 100644 --- a/SVSim.Database/Repositories/Viewer/ViewerRepository.cs +++ b/SVSim.Database/Repositories/Viewer/ViewerRepository.cs @@ -27,4 +27,10 @@ public class ViewerRepository : IViewerRepository return await _dbContext.Set().AsNoTracking().Include(viewer => viewer.SocialAccountConnections) .FirstOrDefaultAsync(viewer => viewer.Id == id); } + + public async Task GetViewerByShortUdid(ulong shortUdid) + { + return await _dbContext.Set().AsNoTracking().Include(viewer => viewer.MissionData) + .Include(viewer => viewer.Info).FirstOrDefaultAsync(viewer => viewer.ShortUdid == shortUdid); + } } \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Controllers/LoadController.cs b/SVSim.EmulatedEntrypoint/Controllers/LoadController.cs new file mode 100644 index 0000000..2c2be03 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Controllers/LoadController.cs @@ -0,0 +1,42 @@ +using Microsoft.AspNetCore.Mvc; +using SVSim.Database.Models; +using SVSim.Database.Repositories.Viewer; +using SVSim.EmulatedEntrypoint.Constants; +using SVSim.EmulatedEntrypoint.Models.Dtos; +using SVSim.EmulatedEntrypoint.Models.Dtos.Requests; +using SVSim.EmulatedEntrypoint.Models.Dtos.Responses; + +namespace SVSim.EmulatedEntrypoint.Controllers; + +public class LoadController : SVSimController +{ + private readonly IViewerRepository _viewerRepository; + + public LoadController(IViewerRepository viewerRepository) + { + _viewerRepository = viewerRepository; + } + + [HttpPost("index")] + public async Task> Index(IndexRequest request) + { + Viewer? viewer = await _viewerRepository.GetViewerByShortUdid(ulong.Parse(User.Claims + .FirstOrDefault(claim => claim.Type == ShadowverseClaimTypes.ShortUdidClaim).Value)); + + if (viewer == null) + { + return NotFound(); + } + + return new IndexResponse + { + UserTutorial = new UserTutorial() + { + TutorialStep = viewer.MissionData.TutorialState + }, + UserInfo = new UserInfo(int.Parse(Request.Headers["DEVICE"].FirstOrDefault()), viewer), + UserCurrency = new UserCurrency(), + + }; + } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Middlewares/ShadowverseTranslationMiddleware.cs b/SVSim.EmulatedEntrypoint/Middlewares/ShadowverseTranslationMiddleware.cs index c26231f..ef0b64a 100644 --- a/SVSim.EmulatedEntrypoint/Middlewares/ShadowverseTranslationMiddleware.cs +++ b/SVSim.EmulatedEntrypoint/Middlewares/ShadowverseTranslationMiddleware.cs @@ -1,5 +1,6 @@ using System.Text; using MessagePack; +using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Mvc.Controllers; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.Extensions.Primitives; @@ -8,6 +9,7 @@ using SVSim.Database.Models; using SVSim.EmulatedEntrypoint.Constants; using SVSim.EmulatedEntrypoint.Extensions; using SVSim.EmulatedEntrypoint.Models.Dtos; +using SVSim.EmulatedEntrypoint.Models.Dtos.Internal; using SVSim.EmulatedEntrypoint.Security; using SVSim.EmulatedEntrypoint.Services; @@ -31,7 +33,7 @@ public class ShadowverseTranslationMiddleware : IMiddleware { bool isUnity = context.Request.Headers.UserAgent.Any(agent => agent?.Contains("UnityPlayer") ?? false); string path = context.Request.Path; - var endpointDescriptor = + ActionDescriptor? endpointDescriptor = _actionDescriptorCollectionProvider.ActionDescriptors.Items.FirstOrDefault(ad => $"/{ad.AttributeRouteInfo.Template}".Equals(path, StringComparison.InvariantCultureIgnoreCase)); if (!isUnity || endpointDescriptor == null) @@ -41,12 +43,12 @@ public class ShadowverseTranslationMiddleware : IMiddleware } // Replace response body stream to re-access it. - using var tempResponseBody = new MemoryStream(); - var originalResponsebody = context.Response.Body; + using MemoryStream tempResponseBody = new MemoryStream(); + Stream originalResponsebody = context.Response.Body; context.Response.Body = tempResponseBody; // Pull out the request bytes into a stream - using var requestBytesStream = new MemoryStream(); + using MemoryStream requestBytesStream = new MemoryStream(); await context.Request.Body.CopyToAsync(requestBytesStream); byte[] requestBytes = requestBytesStream.ToArray(); @@ -58,8 +60,8 @@ public class ShadowverseTranslationMiddleware : IMiddleware requestBytes = Encryption.Decrypt(requestBytes, udid); object? data = MessagePackSerializer.Deserialize(endpointDescriptor.Parameters.FirstOrDefault().ParameterType, requestBytes); - var json = JsonConvert.SerializeObject(data); - var newStream = new StringContent(json, Encoding.UTF8, "application/json"); + string json = JsonConvert.SerializeObject(data); + StringContent newStream = new StringContent(json, Encoding.UTF8, "application/json"); context.Request.Body = newStream.ReadAsStream(); context.Request.Headers.ContentType = new StringValues("application/json"); @@ -68,16 +70,16 @@ public class ShadowverseTranslationMiddleware : IMiddleware Viewer? viewer = context.GetViewer(); // Grab the response object - var responseType = ((ControllerActionDescriptor)endpointDescriptor).MethodInfo.ReturnType; + Type responseType = ((ControllerActionDescriptor)endpointDescriptor).MethodInfo.ReturnType; if (responseType.IsGenericType && responseType.GetGenericTypeDefinition() == typeof(Task<>)) { responseType = responseType.GetGenericArguments()[0]; } - using var responseBytesStream = new MemoryStream(); + using MemoryStream responseBytesStream = new MemoryStream(); context.Response.Body.Seek(0, SeekOrigin.Begin); await context.Response.Body.CopyToAsync(responseBytesStream); - var responseBytes = responseBytesStream.ToArray(); - var responseData = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(responseBytes), responseType); + byte[] responseBytes = responseBytesStream.ToArray(); + object? responseData = JsonConvert.DeserializeObject(Encoding.UTF8.GetString(responseBytes), responseType); // Wrap the response in a datawrapper DataWrapper wrappedResponseData = new DataWrapper @@ -96,7 +98,7 @@ public class ShadowverseTranslationMiddleware : IMiddleware }; // Convert the response into a messagepack, encrypt it - var packedData = MessagePackSerializer.Serialize(wrappedResponseData); + byte[] packedData = MessagePackSerializer.Serialize(wrappedResponseData); packedData = Encryption.Encrypt(packedData, udid); await originalResponsebody.WriteAsync(Encoding.UTF8.GetBytes(Convert.ToBase64String(packedData))); context.Response.Body = originalResponsebody; diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaConfig.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaConfig.cs new file mode 100644 index 0000000..2086f54 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaConfig.cs @@ -0,0 +1,12 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class ArenaConfig +{ + [Key("use_challenge_two_pick_premium_card")] + public int UseChallengePickTwoPremiumCard { get; set; } + [Key("challenge_two_pick_sleeve_id")] + public int ChallengePickTwoCardSleeve { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaFormatInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaFormatInfo.cs new file mode 100644 index 0000000..0a3a73a --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaFormatInfo.cs @@ -0,0 +1,21 @@ +using MessagePack; +using SVSim.Database.Enums; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class ArenaFormatInfo +{ + [Key("two_pick_type")] + public PickTwoFormat PickTwoFormat { get; set; } + [Key("card_pool_name")] + public string CardPoolName { get; set; } = string.Empty; + [Key("announce_id")] + public string AnnounceId { get; set; } = "0"; + [Key("card_pool_url")] + public string CardPoolUrl { get; set; } = string.Empty; + [Key("start_time")] + public DateTime StartTime { get; set; } + [Key("end_time")] + public DateTime EndTime { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaInfo.cs new file mode 100644 index 0000000..5d84380 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/ArenaInfo.cs @@ -0,0 +1,24 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class ArenaInfo +{ + [Key("mode")] + public int Mode { get; set; } + [Key("enable")] + public int Enable { get; set; } + [Key("cost")] + public ulong Cost { get; set; } + [Key("rupy_cost")] + public ulong RupeeCost { get; set; } + [Key("ticket_cost")] + public int TicketCost { get; set; } + [Key("is_join")] + public bool IsJoin { get; set; } + [Key("sales_period_info")] + public ShopExpiryInfo? SalesPeriodInfo { get; set; } + [Key("format_info")] + public ArenaFormatInfo? FormatInfo { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/AvatarAbility.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/AvatarAbility.cs new file mode 100644 index 0000000..92bd90d --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/AvatarAbility.cs @@ -0,0 +1,17 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class AvatarAbility +{ + public int LeaderSkinId { get; set; } + public int BattleStartFirstPlayerBp { get; set; } + public int BattleStartSecondPlayerBp { get; set; } + public int BattleStartMaxLife { get; set; } + public string AbilityCost { get; set; } + public string Ability { get; set; } + public string PassiveAbility { get; set; } + public string AbilityDesc { get; set; } + public string PassiveAbilityDesc { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/AvatarInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/AvatarInfo.cs new file mode 100644 index 0000000..6fbf2b6 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/AvatarInfo.cs @@ -0,0 +1,10 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class AvatarInfo +{ + public Dictionary Abilities { get; set; } = new Dictionary(); + public SpecialRotationSchedule Schedules { get; set; } = new SpecialRotationSchedule(); +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/BattlePassLevel.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/BattlePassLevel.cs new file mode 100644 index 0000000..da1ee16 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/BattlePassLevel.cs @@ -0,0 +1,12 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class BattlePassLevel +{ + [Key("level")] + public int Level { get; set; } + [Key("required_point")] + public int RequiredPoints { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/CardIdentifier.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/CardIdentifier.cs new file mode 100644 index 0000000..c34f054 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/CardIdentifier.cs @@ -0,0 +1,16 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +/// +/// Identifies a card in the game system. +/// +[MessagePackObject] +public class CardIdentifier +{ + /// + /// The identifier of the card. + /// + [Key("card_id")] + public long CardId { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/CardSetIdentifier.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/CardSetIdentifier.cs new file mode 100644 index 0000000..f935ede --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/CardSetIdentifier.cs @@ -0,0 +1,10 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class CardSetIdentifier +{ + [Key("card_set_id")] + public int SetId { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/ClassExp.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/ClassExp.cs new file mode 100644 index 0000000..a725427 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/ClassExp.cs @@ -0,0 +1,16 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class ClassExp +{ + [Key("level")] + public int Level { get; set; } + [Key("necessary_exp")] + public int NecessaryExp { get; set; } + [Key("diff_exp")] + public int DiffExp { get; set; } + [Key("accumulate_exp")] + public int AccumulateExp { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/DailyLoginBonus.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/DailyLoginBonus.cs new file mode 100644 index 0000000..5091ab0 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/DailyLoginBonus.cs @@ -0,0 +1,14 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class DailyLoginBonus +{ + [Key("total")] + public LoginBonusCampaign? Total { get; set; } + [Key("normal")] + public LoginBonusCampaign? Normal { get; set; } + [Key("campaign")] + public LoginBonusCampaign? Campaign { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/DateRange.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/DateRange.cs new file mode 100644 index 0000000..0ea9b9b --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/DateRange.cs @@ -0,0 +1,12 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class DateRange +{ + [Key("begin_time")] + public DateTime BeginTime { get; set; } + [Key("end_time")] + public DateTime EndTime { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/DefaultSettings.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/DefaultSettings.cs new file mode 100644 index 0000000..3dc23f0 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/DefaultSettings.cs @@ -0,0 +1,14 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class DefaultSettings +{ + [Key("default_emblem_id")] + public ulong DefaultEmblemId { get; set; } + [Key("default_degree_id")] + public int DefaultDegreeId { get; set; } + [Key("default_mypage_id")] + public ulong DefaultMyPageBackground { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/DegreeIdentifier.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/DegreeIdentifier.cs new file mode 100644 index 0000000..0781558 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/DegreeIdentifier.cs @@ -0,0 +1,10 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class DegreeIdentifier +{ + [Key("degree_id")] + public int DegreeId { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/EmblemIdentifier.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/EmblemIdentifier.cs new file mode 100644 index 0000000..41251f6 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/EmblemIdentifier.cs @@ -0,0 +1,10 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class EmblemIdentifier +{ + [Key("emblem_id")] + public int EmblemId { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/GatheringInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/GatheringInfo.cs new file mode 100644 index 0000000..74c5ac9 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/GatheringInfo.cs @@ -0,0 +1,10 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class GatheringInfo +{ + [Key("has_invite")] + public int HasInvite { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/DataHeaders.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/Internal/DataHeaders.cs similarity index 86% rename from SVSim.EmulatedEntrypoint/Models/Dtos/DataHeaders.cs rename to SVSim.EmulatedEntrypoint/Models/Dtos/Internal/DataHeaders.cs index 548bba3..4fec365 100644 --- a/SVSim.EmulatedEntrypoint/Models/Dtos/DataHeaders.cs +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/Internal/DataHeaders.cs @@ -1,6 +1,6 @@ using MessagePack; -namespace SVSim.EmulatedEntrypoint.Models.Dtos; +namespace SVSim.EmulatedEntrypoint.Models.Dtos.Internal; [MessagePackObject] public class DataHeaders diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/DataWrapper.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/Internal/DataWrapper.cs similarity index 91% rename from SVSim.EmulatedEntrypoint/Models/Dtos/DataWrapper.cs rename to SVSim.EmulatedEntrypoint/Models/Dtos/Internal/DataWrapper.cs index 73bab6a..697ea74 100644 --- a/SVSim.EmulatedEntrypoint/Models/Dtos/DataWrapper.cs +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/Internal/DataWrapper.cs @@ -1,6 +1,6 @@ using MessagePack; -namespace SVSim.EmulatedEntrypoint.Models.Dtos; +namespace SVSim.EmulatedEntrypoint.Models.Dtos.Internal; /// /// Wraps responses in the format the official game client expects, with a header section for additional data. Not for manual endpoint use, this wrapping is done automatically in a middleware. diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/LoginBonusCampaign.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/LoginBonusCampaign.cs new file mode 100644 index 0000000..56d69bb --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/LoginBonusCampaign.cs @@ -0,0 +1,20 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class LoginBonusCampaign +{ + [Key("name")] + public string Name { get; set; } = string.Empty; + [Key("campaign_id")] + public int CampaignId { get; set; } + [Key("img")] + public int Image { get; set; } + [Key("now_count")] + public int NowCount { get; set; } + [Key("is_next_reward")] + public bool IsNextReward { get; set; } + [Key("reward")] + public List Rewards { get; set; } = new List(); +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/LoginBonusReward.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/LoginBonusReward.cs new file mode 100644 index 0000000..d53d994 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/LoginBonusReward.cs @@ -0,0 +1,31 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class LoginBonusReward +{ + /// + /// The effect shown ingame. + /// + [Key("effect_id")] + public int EffectId { get; set; } + + /// + /// The type of reward. + /// + [Key("reward_type")] + public int RewardType { get; set; } + + /// + /// A more specified reward type (ie if a pack, which pack). + /// + [Key("reward_detail_id")] + public int RewardDetailId { get; set; } + + /// + /// The count of the reward. + /// + [Key("reward_number")] + public int RewardNumber { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/LootBoxRegulations.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/LootBoxRegulations.cs new file mode 100644 index 0000000..414f111 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/LootBoxRegulations.cs @@ -0,0 +1,23 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +/// +/// What features are restricted by a user's country's loot box regulations. 1 indicates restricted, 0 indicates +/// +[MessagePackObject] +public class LootBoxRegulations +{ + [Key("pack")] + public int Pack { get; set; } + [Key("arena_2pick")] + public int ArenaPickTwo { get; set; } + [Key("arena_sealed")] + public int ArenaSealed { get; set; } + [Key("arena_colosseum")] + public int ArenaColosseum { get; set; } + [Key("arena_competition")] + public int ArenaCompetition { get; set; } + [Key("special_shop")] + public int SpecialShop { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/MyRotationAbility.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/MyRotationAbility.cs new file mode 100644 index 0000000..334de57 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/MyRotationAbility.cs @@ -0,0 +1,15 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject()] +public class MyRotationAbility +{ + public int AbilityId { get; set; } + public int AddStartPp { get; set; } + public int AddStartLife { get; set; } + public int IncreaseAddPpTotalAmount { get; set; } + public int IncreaseAddPpTotalTurn { get; set; } + public string Ability { get; set; } = string.Empty; + public string AbilityDesc { get; set; } = String.Empty; +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/MyRotationInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/MyRotationInfo.cs new file mode 100644 index 0000000..2578f45 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/MyRotationInfo.cs @@ -0,0 +1,29 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class MyRotationInfo +{ + [Key("abilities")] + public Dictionary Abilities { get; set; } = new Dictionary(); + [Key("schedules")] + public SpecialRotationSchedule Schedules { get; set; } = new SpecialRotationSchedule(); + [Key("setting")] + public Dictionary? Settings { get; set; } + [Key("disabled_card_set_ids")] + public List? DisabledCardSets { get; set; } + + /// + /// Set to card to card reprinted list. + /// + [Key("reprinted_base_card_ids")] + public Dictionary>? ReprintedCards { get; set; } + + + /// + /// Set to card to count banlist. + /// + [Key("restricted_base_card_id_list")] + public Dictionary>? Banlist { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/PreReleaseInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/PreReleaseInfo.cs new file mode 100644 index 0000000..bc564b8 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/PreReleaseInfo.cs @@ -0,0 +1,36 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class PreReleaseInfo +{ + [Key("id")] + public int Id { get; set; } + [Key("start_time")] + public DateTime StartTime { get; set; } + [Key("end_time")] + public DateTime EndTime { get; set; } + [Key("display_end_time")] + public DateTime DisplayEndTime { get; set; } + [Key("next_card_set_id")] + public int NextCardSetId { get; set; } + [Key("default_card_master_id")] + public int DefaultCardMasterId { get; set; } + [Key("pre_release_card_master_id")] + public int PreReleaseCardMasterId { get; set; } + [Key("free_match_start_time")] + public DateTime FreeMatchStartTime { get; set; } + [Key("card_master_id")] + public int CardMasterId { get; set; } + [Key("rotation_card_set_id_list")] + public List RotationCardSets { get; set; } = new List(); + [Key("reprinted_base_card_ids")] + public Dictionary ReprintedCardIds { get; set; } = new Dictionary(); + [Key("latest_reprinted_base_card_ids")] + public List LatestReprintedCardIds { get; set; } = new List(); + [Key("pre_release_status")] + public int PreReleaseStatus { get; set; } + [Key("is_pre_rotation_free_match_term")] + public int IsPreRotationFreeMatchTerm { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/RankInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/RankInfo.cs new file mode 100644 index 0000000..adb3892 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/RankInfo.cs @@ -0,0 +1,42 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class RankInfo +{ + [Key("rank_id")] + public int RankId { get; set; } + [Key("rank_name")] + public string RankName { get; set; } = string.Empty; + [Key("necessary_point")] + public int NecessaryPoints { get; set; } + [Key("accumulate_point")] + public int AccumulatePoints { get; set; } + [Key("lower_limit_point")] + public int LowerLimitPoints { get; set; } + [Key("base_add_bp")] + public int BaseAddBp { get; set; } + [Key("base_drop_bp")] + public int BaseDropBp { get; set; } + [Key("streak_bonus_pt")] + public int StreakBonusPoints { get; set; } + [Key("win_bonus")] + public double WinBonus { get; set; } + [Key("lose_bonus")] + public double LoseBonus { get; set; } + [Key("max_win_bonus")] + public int MaxWinBonus { get; set; } + [Key("max_lose_bonus")] + public int MaxLoseBonus { get; set; } + [Key("is_promotion_war")] + public int IsPromotionWar { get; set; } + [Key("match_count")] + public int MatchCount { get; set; } + [Key("necessary_win")] + public int NecessaryWins { get; set; } + [Key("reset_lose")] + public int ResetLose { get; set; } + [Key("accumulate_master_point")] + public int AccumulateMasterPoints { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/RedEtherOverride.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/RedEtherOverride.cs new file mode 100644 index 0000000..439dccf --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/RedEtherOverride.cs @@ -0,0 +1,22 @@ +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +/// +/// An indication that a specific card has had it's red ether amounts overriden from the normal amounts. +/// +public class RedEtherOverride +{ + /// + /// The id of the affected card. + /// + public ulong CardId { get; set; } + + /// + /// How much red ether is now provided from dusting the card. + /// + public int GetRedEther { get; set; } + + /// + /// How much red ether is now required to craft the card. + /// + public int UseRedEther { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/Responses/IndexResponse.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/Responses/IndexResponse.cs index 7a3a2f4..efae99f 100644 --- a/SVSim.EmulatedEntrypoint/Models/Dtos/Responses/IndexResponse.cs +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/Responses/IndexResponse.cs @@ -1,6 +1,286 @@ +using MessagePack; +using SVSim.Database.Enums; + namespace SVSim.EmulatedEntrypoint.Models.Dtos.Responses; +[MessagePackObject] public class IndexResponse { + #region Primitive Returns + + [Key("ts_card_rotation")] + public string TsCardRotation { get; set; } = string.Empty; + [Key("is_beginner_mission")] + public int IsBeginnerMission { get; set; } + [Key("spot_point")] + public int SpotPoint { get; set; } + [Key("is_available_colosseum_free_entry")] + public bool IsAvailableColosseumFreeEntry { get; set; } + [Key("friend_battle_invite_count")] + public int FriendBattleInviteCount { get; set; } + [Key("battle_recovery_status")] + public int BattleRecoveryStatus { get; set; } + [Key("room_recovery_status")] + public int RoomRecoveryStatus { get; set; } + [Key("is_battle_pass_period")] + public bool IsBattlePassPeriod { get; set; } + [Key("card_set_id_for_resource_dl_view")] + public int CardSetIdForResourceDlView { get; set; } + + #endregion + + #region Basic User Data + + /// + /// The user's tutorial progress state. + /// + [Key("user_tutorial")] + public UserTutorial UserTutorial { get; set; } = new UserTutorial(); + /// + /// Basic information about the user. + /// + [Key("user_info")] + public UserInfo UserInfo { get; set; } = new UserInfo(); + + /// + /// The in-game currency information for this user. + /// + [Key("user_crystal_count")] + public UserCurrency UserCurrency { get; set; } = new UserCurrency(); + + #endregion + + #region Inventory Data + + /// + /// Items that the user has and how many of each. + /// + [Key("user_item_list")] + public List UserItems { get; set; } = new List(); + + /// + /// Decks for the rotation format. + /// + [Key("user_deck_rotation")] + public UserFormatDeckInfo UserRotationDecks { get; set; } = new UserFormatDeckInfo(); + + /// + /// Decks for the unlimited format. + /// + [Key("user_deck_unlimited")] + public UserFormatDeckInfo UserUnlimitedDecks { get; set; } = new UserFormatDeckInfo(); + + /// + /// Decks for the unlimited format. + /// + [Key("user_deck_my_rotation")] + public UserFormatDeckInfo UserMyRotationDecks { get; set; } = new UserFormatDeckInfo(); + + /// + /// The list of cards and how many of each this user has. + /// + [Key("user_card_list")] + public List UserCards { get; set; } = new List(); + + /// + /// The classes a user has and their stats. + /// + [Key("user_class_list")] + public List UserClasses { get; set; } = new List(); + + /// + /// Mapping of SleeveId to a object. + /// + [Key("user_sleeve_list")] + public Dictionary Sleeves { get; set; } = new Dictionary(); + + /// + /// The emblems available to this user. + /// + [Key("user_emblem_list")] + public List UserEmblems { get; set; } = new List(); + + /// + /// The degrees available to this user. + /// + [Key("degree_id")] + public List UserDegrees { get; set; } = new List(); + + /// + /// Leader skins available to the leader. + /// + [Key("user_leader_skin_list")] + public Dictionary LeaderSkins { get; set; } = new Dictionary(); + + /// + /// Backgrounds for 'My Page' the user has collected. + /// + [Key("user_mypage_list")] + public List MyPageBackgrounds { get; set; } = new List(); + + #endregion + + #region Advanced Player Data + + /// + /// Maps a deck format (as a string) to info about ranked for that format. + /// + [Key("user_rank")] + public Dictionary UserRankInfo { get; set; } = new Dictionary(); + + /// + /// The number of ranked matches for each class the user has played. + /// + [Key("user_rank_match_list")] + public List UserRankedMatches { get; set; } = new List(); + + /// + /// The daily login bonuses currently going on, including if the player should receive the next reward for any. + /// + [Key("daily_login_bonus")] + public DailyLoginBonus DailyLoginBonus { get; set; } = new DailyLoginBonus(); + + /// + /// User configuration for the arena. + /// + [Key("challenge_config")] + public ArenaConfig ArenaConfig { get; set; } = new ArenaConfig(); + + #endregion + + #region Global Data + + /// + /// Cards that have had their red ether values overriden. + /// + [Key("red_ether_overwrite_list")] + public List RedEtherOverrides { get; set; } = new List(); + + /// + /// Cards that are currently undergoing maintenance. + /// + [Key("maintenance_card_list")] + public List MaintenanceCards { get; set; } = new List(); + + /// + /// The arena formats currently available. + /// + [Key("arena_info")] + public List ArenaInfos { get; set; } = new List(); + + /// + /// Dictionary of rank id to information about that rank. + /// + [Key("rank_info")] + public Dictionary RankInfo { get; set; } = new Dictionary(); + + /// + /// Dictionary mapping a class level to information about that level. + /// + [Key("class_exp")] + public Dictionary ClassExp { get; set; } = new Dictionary(); + + /// + /// Card ids that should not show up on loading screen tips. + /// + [Key("loading_exclusion_card_list")] + public List LoadingTipCardExclusions { get; set; } = new List(); + + /// + /// The default settings for every user. + /// + [Key("default_setting")] + public DefaultSettings DefaultSettings { get; set; } = new DefaultSettings(); + + /// + /// Any cards that are restricted in unlimited, and the maximum count that can be run of the card. + /// + [Key("unlimited_restricted_base_card_id_list")] + public Dictionary UnlimitedBanList { get; set; } = new Dictionary(); + + /// + /// Sets currently available in rotation. + /// + [Key("rotation_card_set_id_list")] + public List RotationSets { get; set; } = new List(); + + /// + /// Allows cards out of your 'My Rotation' to still be used. TODO investigate + /// + [Key("reprinted_base_card_ids")] + public Dictionary ReprintedCards { get; set; } = new Dictionary(); + + /// + /// Something to do with destroying cards. TODO investigate + /// + [Key("spot_cards")] + public Dictionary SpotCards { get; set; } = new Dictionary(); + + /// + /// Info about the next set to be released? TODO investigate + /// + [Key("pre_release_info")] + public PreReleaseInfo? PreReleaseInfo { get; set; } + + /// + /// Information for the 'My Rotation' mode. + /// + [Key("my_rotation_info")] + public MyRotationInfo? MyRotationInfo { get; set; } + + /// + /// Information about some avatar mode? TODO investigate + /// + [Key("avatar_info")] + public MyRotationInfo? AvatarRotationInfo { get; set; } + + /// + /// List of features that are undergoing maintenance. + /// + [Key("feature_maintenance_list")] + public List FeatureMaintenances { get; set; } = new List(); + + + /// + /// Special deals on crystal purchases. + /// + [Key("special_crystal_info")] + public List SpecialCrystalInfos { get; set; } = new List(); + + /// + /// Current battle pass levels and required points for each. + /// + [Key("battle_pass_level_info")] + public Dictionary? BattlePassLevelInfo { get; set; } + + /// + /// Battlefields that can currently be picked. + /// + [Key("open_battle_field_id_list")] + public Dictionary OpenBattlefieldIds { get; set; } = new Dictionary(); + + #endregion + + #region Misc Data + + /// + /// What loot box features are disabled for this user. + /// + [Key("loot_box_regulation")] + public LootBoxRegulations LootBoxRegulations { get; set; } = new LootBoxRegulations(); + + /// + /// Something about whether the user has an invite notification. + /// + [Key("gathering_info")] + public GatheringInfo GatheringInfo { get; set; } = new GatheringInfo(); + + /// + /// User configuration. + /// + [Key("user_config")] + public UserConfig UserConfig { get; set; } = new UserConfig(); + + #endregion } \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/ShopExpiryInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/ShopExpiryInfo.cs new file mode 100644 index 0000000..3a0f522 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/ShopExpiryInfo.cs @@ -0,0 +1,12 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class ShopExpiryInfo +{ + [Key("sales_period_time")] + public DateTime? SalesPeriodTime { get; set; } + [Key("sales_period_series")] + public int? SalesPeriodSeries { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/SleeveIdentifier.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/SleeveIdentifier.cs new file mode 100644 index 0000000..4b4df69 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/SleeveIdentifier.cs @@ -0,0 +1,16 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +/// +/// Identifies a card sleeve. +/// +[MessagePackObject] +public class SleeveIdentifier +{ + /// + /// The id of the sleeve. + /// + [Key("sleeve_id")] + public int SleeveId { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialCrystalInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialCrystalInfo.cs new file mode 100644 index 0000000..d08347d --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialCrystalInfo.cs @@ -0,0 +1,9 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class SpecialCrystalInfo +{ + +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialRotationSchedule.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialRotationSchedule.cs new file mode 100644 index 0000000..c495e15 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialRotationSchedule.cs @@ -0,0 +1,12 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class SpecialRotationSchedule +{ + [Key("gathering")] + public DateRange Gathering { get; set; } = new DateRange(); + [Key("free_battle")] + public DateRange FreeBattle { get; set; } = new DateRange(); +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialRotationSetting.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialRotationSetting.cs new file mode 100644 index 0000000..078c98a --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/SpecialRotationSetting.cs @@ -0,0 +1,22 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class SpecialRotationSetting +{ + [Key("rotation_id")] + public int RotationId { get; set; } + + /// + /// Formatted as 'setid|setid|setid...'. + /// + [Key("card_set_ids")] + public string CardSetIds { get; set; } + + /// + /// Formatted as 'abilityid|abilityid|abilityid...'. + /// + [Key("abilities")] + public string Abilities { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserCard.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserCard.cs new file mode 100644 index 0000000..58e4313 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserCard.cs @@ -0,0 +1,22 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +/// +/// A card in a user's collection and the number possessed. +/// +[MessagePackObject] +public class UserCard : CardIdentifier +{ + /// + /// The number of the specified card the user has. + /// + [Key("number")] + public int Count { get; set; } + + /// + /// Whether the card is protected from dusting. + /// + [Key("is_protected")] + public int IsProtected { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserClass.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserClass.cs new file mode 100644 index 0000000..376b479 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserClass.cs @@ -0,0 +1,31 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserClass +{ + [Key("class_id")] + public int ClassId { get; set; } + + [Key("is_available")] + public int IsAvailable { get; set; } + + [Key("level")] + public int Level { get; set; } + + [Key("exp")] + public int Exp { get; set; } + + [Key("is_random_leader_skin")] + public int IsRandomLeaderSkin { get; set; } + + [Key("leader_skin_id")] + public int LeaderSkinId { get; set; } + + [Key("leader_skin_id_list")] + public List LeaderSkinIds { get; set; } = new List(); + + [Key("default_leader_skin_id")] + public int DefaultLeaderSkinId { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserConfig.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserConfig.cs new file mode 100644 index 0000000..bbce7f8 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserConfig.cs @@ -0,0 +1,22 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserConfig +{ + [Key("receive_invitation")] + public int ReceiveInvitation { get; set; } + [Key("receive_invitation_in_battle")] + public int ReceiveInvitationInBattle { get; set; } + [Key("receive_invitation_in_offline")] + public int ReceiveInvitationInOffline { get; set; } + [Key("receive_friend_apply")] + public int ReceiveFriendApply { get; set; } + [Key("is_allow_send_adjust")] + public int IsAllowSendAdjust { get; set; } + [Key("is_foil_preferred")] + public int IsFoilPreferred { get; set; } + [Key("is_prize_preferred")] + public int IsPrizePreferred { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserCurrency.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserCurrency.cs new file mode 100644 index 0000000..9c2f164 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserCurrency.cs @@ -0,0 +1,52 @@ +using MessagePack; +using SVSim.Database.Models; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserCurrency +{ + [Key("viewer_id")] + public ulong ViewerId { get; set; } + [Key("crystal")] + public ulong Crystals { get; set; } + [Key("crystal_android")] + public ulong AndroidCrystals { get; set; } + [Key("crystal_ios")] + public ulong IosCrystals { get; set; } + [Key("crystal_steam")] + public ulong SteamCrystals { get; set; } + [Key("crystal_dmm")] + public ulong DmmCrystals { get; set; } + [Key("free_crystal")] + public ulong FreeCrystals { get; set; } + [Key("total_crystal")] + public ulong TotalCrystals { get; set; } + [Key("life_total_crystal")] + public ulong LifeTotalCrystals { get; set; } + [Key("red_ether")] + public ulong RedEther { get; set; } + [Key("rupy")] + public ulong Rupees { get; set; } + + public UserCurrency() + { + + } + + public UserCurrency(Viewer viewer) + { + ViewerCurrency currency = viewer.Currency; + this.Crystals = currency.Crystals; + this.RedEther = currency.RedEther; + this.LifeTotalCrystals = currency.LifeTotalCrystals; + this.TotalCrystals = currency.LifeTotalCrystals; + this.Rupees = currency.Rupees; + this.FreeCrystals = currency.FreeCrystals; + this.AndroidCrystals = currency.AndroidCrystals; + this.DmmCrystals = currency.DmmCrystals; + this.SteamCrystals = currency.SteamCrystals; + this.IosCrystals = currency.IosCrystals; + this.ViewerId = viewer.Id; + } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserDeck.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserDeck.cs new file mode 100644 index 0000000..0e73e82 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserDeck.cs @@ -0,0 +1,41 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +/// +/// A deck belonging to a user. +/// +[MessagePackObject] +public class UserDeck +{ + [Key("deck_no")] + public int DeckNumber { get; set; } + [Key("class_id")] + public int ClassId { get; set; } + [Key("sleeve_id")] + public int SleeveId { get; set; } + [Key("leader_skin_id")] + public int LeaderSkinId { get; set; } + [Key("deck_name")] + public string DeckName { get; set; } = string.Empty; + [Key("card_id_array")] + public List Cards { get; set; } = new List(); + [Key("is_complete_deck")] + public int IsCompleteDeck { get; set; } + [Key("restricted_card_exists")] + public bool RestrictedCardExists { get; set; } + [Key("is_available_deck")] + public int IsAvailable { get; set; } + [Key("maintenance_card_ids")] + public List MaintenanceCards { get; set; } = new List(); + [Key("is_include_un_possession_card")] + public bool IncludesNonCollectibleCards { get; set; } + [Key("is_random_leader_skin")] + public int IsRandomLeaderSkin { get; set; } + [Key("leader_skin_id_list")] + public List LeaderSkinIds { get; set; } = new List { 0 }; + [Key("order_num")] + public int Order { get; set; } + [Key("create_deck_time")] + public DateTime DeckCreateTime { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserFormatDeckInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserFormatDeckInfo.cs new file mode 100644 index 0000000..4ed377c --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserFormatDeckInfo.cs @@ -0,0 +1,13 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserFormatDeckInfo +{ + [Key("format")] + public string Format { get; set; } = string.Empty; + + [Key("user_deck_list")] + public List UserDecks { get; set; } = new List(); +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserInfo.cs new file mode 100644 index 0000000..1f33d7c --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserInfo.cs @@ -0,0 +1,56 @@ +using MessagePack; +using SVSim.Database.Models; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserInfo +{ + [Key("device_type")] + public int DeviceType { get; set; } + [Key("name")] + public string Name { get; set; } = string.Empty; + [Key("country_code")] + public string CountryCode { get; set; } = string.Empty; + [Key("max_friend")] + public int MaxFriend { get; set; } + [Key("last_play_time")] + public DateTime LastPlayTime { get; set; } + [Key("is_received_two_pick_mission")] + public int HasReceivedPickTwoMission { get; set; } + [Key("birth")] + public long Birthday { get; set; } + [Key("selected_emblem_id")] + public long SelectedEmblemId { get; set; } + [Key("selected_degree_id")] + public int SelectedDegreeId { get; set; } + [Key("mission_change_time")] + public DateTime MissionChangeTime { get; set; } + [Key("mission_receive_type")] + public int MissionReceiveType { get; set; } + [Key("is_official")] + public int IsOfficial { get; set; } + [Key("is_official_mark_displayed")] + public int IsOfficialMarkDisplayed { get; set; } + + public UserInfo() + { + } + + public UserInfo(int deviceType, Viewer viewer) + { + this.DeviceType = deviceType; + this.Name = viewer.DisplayName; + this.CountryCode = viewer.Info.CountryCode; + this.MaxFriend = viewer.Info.MaxFriends; + this.LastPlayTime = viewer.LastLogin; + this.HasReceivedPickTwoMission = viewer.MissionData.HasReceivedPickTwoMission ? 1 : 0; + this.Birthday = viewer.Info.BirthDate.Ticks; + this.SelectedEmblemId = viewer.Info.SelectedEmblem.Id; + this.SelectedDegreeId = viewer.Info.SelectedDegree.Id; + this.MissionChangeTime = viewer.MissionData.MissionChangeTime; + this.MissionReceiveType = viewer.MissionData.MissionReceiveType; + this.IsOfficial = viewer.Info.IsOfficial ? 1 : 0; + this.IsOfficialMarkDisplayed = viewer.Info.IsOfficialMarkDisplayed ? 1 : 0; + } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserItem.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserItem.cs new file mode 100644 index 0000000..2c7bb1d --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserItem.cs @@ -0,0 +1,13 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserItem +{ + [Key("item_id")] + public int ItemId { get; set; } + + [Key("number")] + public int Number { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserLeaderSkin.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserLeaderSkin.cs new file mode 100644 index 0000000..10bb5b4 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserLeaderSkin.cs @@ -0,0 +1,18 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserLeaderSkin +{ + [Key("leader_skin_id")] + public int Id { get; set; } + [Key("leader_skin_name")] + public string Name { get; set; } = string.Empty; + [Key("class_id")] + public int ClassId { get; set; } + [Key("emote_id")] + public int EmoteId { get; set; } + [Key("is_owned")] + public bool IsOwned { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserPromotionMatch.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserPromotionMatch.cs new file mode 100644 index 0000000..4995cd8 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserPromotionMatch.cs @@ -0,0 +1,16 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserPromotionMatch +{ + [Key("match_count")] + public int MatchCount { get; set; } + [Key("battle_result")] + public int BattleResult { get; set; } + [Key("win")] + public int Wins { get; set; } + [Key("lose")] + public int Losses { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserRankInfo.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserRankInfo.cs new file mode 100644 index 0000000..1dc5473 --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserRankInfo.cs @@ -0,0 +1,34 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserRankInfo +{ + [Key("deck_format")] + public int DeckFormat { get; set; } + [Key("rank")] + public int Rank { get; set; } + [Key("battle_point")] + public int BattlePoints { get; set; } + [Key("successive_win_number")] + public int WinStreak { get; set; } + [Key("successive_losses_number")] + public int LossStreak { get; set; } + [Key("is_promotion")] + public int IsPromotion { get; set; } + [Key("is_master_rank")] + public int IsMasterRank { get; set; } + [Key("is_grand_master_rank")] + public bool IsGrandMasterRank { get; set; } + [Key("master_point")] + public int MasterPoints { get; set; } + [Key("period_grand_master_point")] + public int PeriodGrandMasterPoints { get; set; } + [Key("target_grand_master_point")] + public int TargetGrandMasterPoints { get; set; } + [Key("current_grand_master_point")] + public int CurrentGrandMasterPoints { get; set; } + [Key("user_promotion_match")] + public UserPromotionMatch? UserPromotionMatch { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserRankedMatches.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserRankedMatches.cs new file mode 100644 index 0000000..a1e706b --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserRankedMatches.cs @@ -0,0 +1,18 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +[MessagePackObject] +public class UserRankedMatches +{ + [Key("class_id")] + public int ClassId { get; set; } + [Key("match_count")] + public int MatchCount { get; set; } + [Key("win")] + public int Wins { get; set; } + [Key("lose")] + public int Losses { get; set; } + [Key("viewer_id")] + public ulong ViewerId { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/Models/Dtos/UserTutorial.cs b/SVSim.EmulatedEntrypoint/Models/Dtos/UserTutorial.cs new file mode 100644 index 0000000..3419a7f --- /dev/null +++ b/SVSim.EmulatedEntrypoint/Models/Dtos/UserTutorial.cs @@ -0,0 +1,16 @@ +using MessagePack; + +namespace SVSim.EmulatedEntrypoint.Models.Dtos; + +/// +/// The state of a user's tutorial progress. +/// +[MessagePackObject] +public class UserTutorial +{ + /// + /// The current tutorial step they are on. + /// + [Key("tutorial_step")] + public int TutorialStep { get; set; } +} \ No newline at end of file diff --git a/SVSim.EmulatedEntrypoint/SVSim.EmulatedEntrypoint.csproj b/SVSim.EmulatedEntrypoint/SVSim.EmulatedEntrypoint.csproj index 04c951a..fa1d9ee 100644 --- a/SVSim.EmulatedEntrypoint/SVSim.EmulatedEntrypoint.csproj +++ b/SVSim.EmulatedEntrypoint/SVSim.EmulatedEntrypoint.csproj @@ -24,7 +24,6 @@ -