diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json
index 096af38dd..c7e935435 100644
--- a/.config/dotnet-tools.json
+++ b/.config/dotnet-tools.json
@@ -9,7 +9,7 @@
]
},
"csharpier": {
- "version": "0.28.0",
+ "version": "0.28.2",
"commands": [
"dotnet-csharpier"
]
diff --git a/.csharpierignore b/.csharpierignore
index c872553bb..ac7711a65 100644
--- a/.csharpierignore
+++ b/.csharpierignore
@@ -1 +1 @@
-DragaliaAPI/DragaliaAPI.Database/Migrations/*
+DragaliaAPI/DragaliaAPI.Database/Migrations/*
\ No newline at end of file
diff --git a/.csharpierrc b/.csharpierrc
deleted file mode 100644
index e4cb4480e..000000000
--- a/.csharpierrc
+++ /dev/null
@@ -1,3 +0,0 @@
-printWidth: 100
-useTabs: false
-tabWidth: 4
\ No newline at end of file
diff --git a/.editorconfig b/.editorconfig
index cb1c9326b..adece24aa 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -107,7 +107,7 @@ csharp_preferred_modifier_order = public,private,protected,internal,static,exter
csharp_style_prefer_readonly_struct = true
# Code-block preferences
-csharp_prefer_braces = when_multiline:warning
+csharp_prefer_braces = true:warning
csharp_prefer_simple_using_statement = true:warning
csharp_style_namespace_declarations = file_scoped:warning
csharp_style_prefer_method_group_conversion = true:warning
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 03155da42..95bc7c075 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -13,3 +13,18 @@ updates:
directory: "/"
schedule:
interval: "weekly"
+ groups:
+ microsoft-extensions:
+ patterns:
+ - "Microsoft.Extensions*"
+ microsoft-entityframeworkcore:
+ patterns:
+ - "Microsoft.EntityFrameworkCore*"
+ - package-ecosystem: "docker"
+ directory: "/DragaliaAPI"
+ schedule:
+ interval: "weekly"
+ - package-ecosystem: "docker"
+ directory: "/PhotonStateManager"
+ schedule:
+ interval: "weekly"
diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml
index 332608112..c6f33fc51 100644
--- a/.github/workflows/build.yaml
+++ b/.github/workflows/build.yaml
@@ -78,9 +78,6 @@ jobs:
context: .
push: true
file: ${{ inputs.dockerfile }}
- build-args: |
- CI=true
- BASE_DOTNET_IMAGE=mcr.microsoft.com/dotnet/aspnet:8.0-jammy-chiseled
tags: ghcr.io/sapiensanatis/${{ inputs.image-name }}:${{ steps.derive-tag.outputs.tag }}
cache-from: type=gha
cache-to: type=gha,mode=max
diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml
index 04c96c4d6..184588ece 100644
--- a/.github/workflows/deploy.yaml
+++ b/.github/workflows/deploy.yaml
@@ -12,6 +12,9 @@ jobs:
deploy:
name: Deploy
runs-on: ubuntu-latest
+ concurrency:
+ group: deploy
+ cancel-in-progress: false
environment:
name: ${{ inputs.github-environment }}
url: https://dawnshard.co.uk
diff --git a/.github/workflows/missiondesigner.yaml b/.github/workflows/missiondesigner.yaml
deleted file mode 100644
index b65cdd611..000000000
--- a/.github/workflows/missiondesigner.yaml
+++ /dev/null
@@ -1,25 +0,0 @@
-name: MissionDesigner
-
-on:
- pull_request:
- paths:
- - DragaliaAPI.MissionDesigner/**/*
-
-env:
- HUSKY: 0
- CI_BUILD: true
-
-jobs:
- missiondesigner:
- name: Check MissionProgressionInfo.json
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - name: Setup .NET Core SDK
- uses: actions/setup-dotnet@v4
- with:
- dotnet-version: "8.0.x"
- - name: Run MissionDesigner
- run: |
- dotnet run --project DragaliaAPI/DragaliaAPI.MissionDesigner -- NewProgressionInfo.json
- cmp NewProgressionInfo.json DragaliaAPI/DragaliaAPI.Shared/Resources/Missions/MissionProgressionInfo.json
diff --git a/.github/workflows/publish-api.yaml b/.github/workflows/publish-api.yaml
index dc594e5b5..850ef3dbf 100644
--- a/.github/workflows/publish-api.yaml
+++ b/.github/workflows/publish-api.yaml
@@ -7,7 +7,6 @@ on:
paths:
- DragaliaAPI/**
- Shared/**
- - Directory.Build.props
- Directory.Packages.props
env:
diff --git a/.github/workflows/publish-statemanager.yaml b/.github/workflows/publish-statemanager.yaml
index a05e023b8..5f612ccf0 100644
--- a/.github/workflows/publish-statemanager.yaml
+++ b/.github/workflows/publish-statemanager.yaml
@@ -7,7 +7,6 @@ on:
paths:
- PhotonStateManager/**
- Shared/**
- - Directory.Build.props
- Directory.Packages.props
env:
diff --git a/.github/workflows/test-api.yaml b/.github/workflows/test-api.yaml
index 99fc915a4..9fcf25528 100644
--- a/.github/workflows/test-api.yaml
+++ b/.github/workflows/test-api.yaml
@@ -10,7 +10,6 @@ on:
paths:
- DragaliaAPI/**
- Shared/**
- - Directory.Build.props
- Directory.Packages.props
jobs:
@@ -32,11 +31,11 @@ jobs:
"DragaliaAPI/DragaliaAPI.Test",
"DragaliaAPI/DragaliaAPI.Database.Test",
"DragaliaAPI/DragaliaAPI.Shared.Test",
- "DragaliaAPI/DragaliaAPI.Shared.SourceGenerator.Test"
+ "DragaliaAPI/DragaliaAPI.Shared.SourceGenerator.Test",
]
uses: ./.github/workflows/test.yaml
with:
project: ${{ matrix.project }}
before-test: |
dotnet restore DragaliaAPI/DragaliaAPI.MissionDesigner/DragaliaAPI.MissionDesigner.csproj
- dotnet restore DragaliaAPI/DragaliaAPI.MasterAssetConverter/DragaliaAPI.MasterAssetConverter.csproj
\ No newline at end of file
+ dotnet restore DragaliaAPI/DragaliaAPI.MasterAssetConverter/DragaliaAPI.MasterAssetConverter.csproj
diff --git a/.gitignore b/.gitignore
index 20b142bcd..eb3784921 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,6 @@ PhotonRealtimeDotnetSdk/**/*
.run
.env
test_coverage.json
-launchSettings.json
appsettings.Development.json
test_coverage.json
.run
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 000000000..5082cf607
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,17 @@
+# Contributing
+
+Dawnshard welcomes contributions from everyone!
+
+## Filing issues
+
+If you notice a bug with the server, or have a feature request, you can file an issue at https://github.com/SapiensAnatis/Dawnshard/issues, or make a thread in the `#dawnshard-support` channel on Discord.
+Please be sure to include an appropriate amount of context and details so that your issue can be thorougly investigated.
+
+## Development
+
+Pull requests to add new features or fix issues are welcome. Check the issues page to see if the task you want to work on has been noted already - it may include some good information about how to get started.
+
+### Development environment
+
+To set up a development environment to work on DragaliaAPI, the main server component, see the guidance README file in the component folder: [README.md](./DragaliaAPI/README.md)
+
diff --git a/Directory.Build.props b/Directory.Build.props
deleted file mode 100644
index ce7267d81..000000000
--- a/Directory.Build.props
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
- net8.0
- latest
- enable
- enable
- latest-minimum
-
-
-
-
- TEST;$(DefineConstants)
-
-
diff --git a/Directory.Build.targets b/Directory.Build.targets
deleted file mode 100644
index c1df2220d..000000000
--- a/Directory.Build.targets
+++ /dev/null
@@ -1,2 +0,0 @@
-
-
\ No newline at end of file
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0e8dba8a0..24d082d9d 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -3,78 +3,80 @@
true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/DragaliaAPI.sln b/DragaliaAPI.sln
index 44ba5e2f2..73f951223 100644
--- a/DragaliaAPI.sln
+++ b/DragaliaAPI.sln
@@ -7,15 +7,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI", "DragaliaAPI\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.Test", "DragaliaAPI\DragaliaAPI.Test\DragaliaAPI.Test.csproj", "{A1E6C76A-4D4F-427D-80AF-CF289CBBAF00}"
EndProject
-Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{6E4BCC4D-1998-4135-A474-681EC6E6AF57}"
-EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{BC72B633-A158-4169-9B47-3CB9C689A57E}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
- .env = .env
- .env.default = .env.default
.gitignore = .gitignore
- Directory.Build.props = Directory.Build.props
Directory.Packages.props = Directory.Packages.props
.config\dotnet-tools.json = .config\dotnet-tools.json
global.json = global.json
@@ -33,18 +28,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.Database.Test",
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1A23D473-87C4-40FB-8DF0-43F4B0FE7414}"
ProjectSection(SolutionItems) = preProject
+ .github\workflows\build-manual.yaml = .github\workflows\build-manual.yaml
.github\workflows\build.yaml = .github\workflows\build.yaml
.github\workflows\deploy.yaml = .github\workflows\deploy.yaml
.github\workflows\integration-test.yaml = .github\workflows\integration-test.yaml
.github\workflows\lint.yaml = .github\workflows\lint.yaml
- .github\workflows\missiondesigner.yaml = .github\workflows\missiondesigner.yaml
.github\workflows\publish-api.yaml = .github\workflows\publish-api.yaml
.github\workflows\publish-statemanager.yaml = .github\workflows\publish-statemanager.yaml
.github\workflows\test-api.yaml = .github\workflows\test-api.yaml
.github\workflows\test-report.yaml = .github\workflows\test-report.yaml
.github\workflows\test-statemanager.yaml = .github\workflows\test-statemanager.yaml
.github\workflows\test.yaml = .github\workflows\test.yaml
- .github\workflows\build-manual.yaml = .github\workflows\build-manual.yaml
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.Test.Utils", "DragaliaAPI\DragaliaAPI.Test.Utils\DragaliaAPI.Test.Utils.csproj", "{41916B7C-6304-4504-99C0-B24D23982F7E}"
@@ -54,6 +48,10 @@ EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.Photon.Plugin", "PhotonPlugin\DragaliaAPI.Photon.Plugin\DragaliaAPI.Photon.Plugin.csproj", "{D9AC51A5-38F6-4DD1-8839-9FE881396A6B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PhotonStateManager", "PhotonStateManager", "{8B4B2FE9-B1FC-44FC-BC49-0E277731A68A}"
+ ProjectSection(SolutionItems) = preProject
+ PhotonStateManager\Directory.Build.props = PhotonStateManager\Directory.Build.props
+ PhotonStateManager\README.md = PhotonStateManager\README.md
+ EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.Integration.Test", "DragaliaAPI\DragaliaAPI.Integration.Test\DragaliaAPI.Integration.Test.csproj", "{CA0AE7C5-2742-4FC9-B668-BC7459E4BCE5}"
EndProject
@@ -63,7 +61,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.Photon.StateMan
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".husky", ".husky", "{7D333F35-F74C-4A63-AB6E-5F0EE4590ADB}"
ProjectSection(SolutionItems) = preProject
- .husky\pre-commit = .husky\pre-commit
.husky\task-runner.json = .husky\task-runner.json
EndProjectSection
EndProject
@@ -74,10 +71,15 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{F6545B66-0303-4E4C-B872-7E89091885A8}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "PhotonPlugin", "PhotonPlugin", "{5A97773C-C23E-4CFE-8B1F-15D8244D2134}"
+ ProjectSection(SolutionItems) = preProject
+ PhotonPlugin\Directory.Build.props = PhotonPlugin\Directory.Build.props
+ PhotonPlugin\README.md = PhotonPlugin\README.md
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DragaliaAPI", "DragaliaAPI", "{F0C76530-C14A-4601-829B-EE0F4C7E24E6}"
ProjectSection(SolutionItems) = preProject
DragaliaAPI\Directory.Build.props = DragaliaAPI\Directory.Build.props
+ DragaliaAPI\README.md = DragaliaAPI\README.md
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.MasterAssetConverter", "DragaliaAPI\DragaliaAPI.MasterAssetConverter\DragaliaAPI.MasterAssetConverter.csproj", "{F0DFB899-ADC2-407E-AB32-647BA1C4122C}"
@@ -86,7 +88,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{18AB580B
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.Shared.SourceGenerator", "DragaliaAPI\DragaliaAPI.Shared.SourceGenerator\DragaliaAPI.Shared.SourceGenerator.csproj", "{FD0F2BDF-715C-417D-9059-1F2EF8FA8901}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DragaliaAPI.Shared.SourceGenerator.Test", "DragaliaAPI\DragaliaAPI.Shared.SourceGenerator.Test\DragaliaAPI.Shared.SourceGenerator.Test.csproj", "{517FBE68-58A1-48DB-A798-13D6BDECF623}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.Shared.SourceGenerator.Test", "DragaliaAPI\DragaliaAPI.Shared.SourceGenerator.Test\DragaliaAPI.Shared.SourceGenerator.Test.csproj", "{517FBE68-58A1-48DB-A798-13D6BDECF623}"
+EndProject
+Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{AB163A1E-1339-4CFC-82AD-E59ECFADA3C2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -102,10 +106,6 @@ Global
{A1E6C76A-4D4F-427D-80AF-CF289CBBAF00}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A1E6C76A-4D4F-427D-80AF-CF289CBBAF00}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A1E6C76A-4D4F-427D-80AF-CF289CBBAF00}.Release|Any CPU.Build.0 = Release|Any CPU
- {6E4BCC4D-1998-4135-A474-681EC6E6AF57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {6E4BCC4D-1998-4135-A474-681EC6E6AF57}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {6E4BCC4D-1998-4135-A474-681EC6E6AF57}.Release|Any CPU.ActiveCfg = Debug|Any CPU
- {6E4BCC4D-1998-4135-A474-681EC6E6AF57}.Release|Any CPU.Build.0 = Debug|Any CPU
{3B1A86CE-A656-453B-BC3F-EA42DF9E3FC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3B1A86CE-A656-453B-BC3F-EA42DF9E3FC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3B1A86CE-A656-453B-BC3F-EA42DF9E3FC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -166,6 +166,10 @@ Global
{517FBE68-58A1-48DB-A798-13D6BDECF623}.Debug|Any CPU.Build.0 = Debug|Any CPU
{517FBE68-58A1-48DB-A798-13D6BDECF623}.Release|Any CPU.ActiveCfg = Release|Any CPU
{517FBE68-58A1-48DB-A798-13D6BDECF623}.Release|Any CPU.Build.0 = Release|Any CPU
+ {AB163A1E-1339-4CFC-82AD-E59ECFADA3C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {AB163A1E-1339-4CFC-82AD-E59ECFADA3C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {AB163A1E-1339-4CFC-82AD-E59ECFADA3C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {AB163A1E-1339-4CFC-82AD-E59ECFADA3C2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/DragaliaAPI/Directory.Build.props b/DragaliaAPI/Directory.Build.props
index 0213cded6..3d6a902d2 100644
--- a/DragaliaAPI/Directory.Build.props
+++ b/DragaliaAPI/Directory.Build.props
@@ -1,5 +1,16 @@
-
+
+ net8.0
+ enable
+ enable
+ latest-minimum
+
+
+
+
+ TEST;$(DefineConstants)
+
$(MSBuildThisFileDirectory)DragaliaAPI.Shared\Resources\
@@ -8,16 +19,16 @@
-
+
-
+
-
+
-
+
-
+
\ No newline at end of file
diff --git a/DragaliaAPI/DragaliaAPI.Database.Test/DbTestFixture.cs b/DragaliaAPI/DragaliaAPI.Database.Test/DbTestFixture.cs
index 5a4a36fb0..000fa39f3 100644
--- a/DragaliaAPI/DragaliaAPI.Database.Test/DbTestFixture.cs
+++ b/DragaliaAPI/DragaliaAPI.Database.Test/DbTestFixture.cs
@@ -1,6 +1,4 @@
using AutoMapper;
-using DragaliaAPI.Database.Repositories;
-using DragaliaAPI.Features.SavefileUpdate;
using DragaliaAPI.Services.Game;
using DragaliaAPI.Test.Utils;
using Microsoft.EntityFrameworkCore;
@@ -28,8 +26,6 @@ public DbTestFixture()
// Unused for creating saves
Mock> mockLogger = new(MockBehavior.Loose);
Mock mockCache = new(MockBehavior.Loose);
- // Used but we probably don't want it to actually add characters?
- Mock mockUnitRepository = new(MockBehavior.Loose);
SavefileService savefileService =
new(
@@ -40,8 +36,7 @@ public DbTestFixture()
).CreateMapper(),
mockLogger.Object,
IdentityTestUtils.MockPlayerDetailsService.Object,
- Enumerable.Empty(),
- mockUnitRepository.Object
+ []
);
savefileService.Create().Wait();
}
diff --git a/DragaliaAPI/DragaliaAPI.Database.Test/Repositories/UserDataRepositoryTest.cs b/DragaliaAPI/DragaliaAPI.Database.Test/Repositories/UserDataRepositoryTest.cs
index d686c195b..e114586ed 100644
--- a/DragaliaAPI/DragaliaAPI.Database.Test/Repositories/UserDataRepositoryTest.cs
+++ b/DragaliaAPI/DragaliaAPI.Database.Test/Repositories/UserDataRepositoryTest.cs
@@ -27,19 +27,6 @@ public UserDataRepositoryTest(DbTestFixture fixture)
);
}
- [Fact]
- public async Task GetPlayerInfo_ValidId_ReturnsInfo()
- {
- (await this.userDataRepository.UserData.ToListAsync()).Should().NotBeEmpty();
- }
-
- [Fact]
- public async Task GetPlayerInfo_InvalidId_ReturnsEmptyQueryable()
- {
- this.mockPlayerIdentityService.SetupGet(x => x.ViewerId).Returns(400);
- (await this.userDataRepository.UserData.ToListAsync()).Should().BeEmpty();
- }
-
[Fact]
public async Task UpdateName_UpdatesName()
{
diff --git a/DragaliaAPI/DragaliaAPI.Database/ApiContext.cs b/DragaliaAPI/DragaliaAPI.Database/ApiContext.cs
index 6889bb554..cef7aa7c4 100644
--- a/DragaliaAPI/DragaliaAPI.Database/ApiContext.cs
+++ b/DragaliaAPI/DragaliaAPI.Database/ApiContext.cs
@@ -133,8 +133,16 @@ IPlayerIdentityService playerIdentityService
public DbSet DataProtectionKeys { get; set; } = null!;
+ public DbSet WallRewardDates { get; set; } = null!;
+
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
+ modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApiContext).Assembly);
+
+ modelBuilder
+ .Entity()
+ .HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
+
modelBuilder
.Entity()
.HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
@@ -158,5 +166,33 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
modelBuilder
.Entity()
.HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
+
+ modelBuilder
+ .Entity()
+ .HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
+
+ modelBuilder
+ .Entity()
+ .HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
+
+ modelBuilder
+ .Entity()
+ .HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
+
+ modelBuilder
+ .Entity()
+ .HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
+
+ modelBuilder
+ .Entity()
+ .HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
+
+ modelBuilder
+ .Entity()
+ .HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
+
+ modelBuilder
+ .Entity()
+ .HasQueryFilter(x => x.ViewerId == this.playerIdentityService.ViewerId);
}
}
diff --git a/DragaliaAPI/DragaliaAPI.Database/DatabaseConfiguration.cs b/DragaliaAPI/DragaliaAPI.Database/DatabaseConfiguration.cs
index da4256e36..548ddc63b 100644
--- a/DragaliaAPI/DragaliaAPI.Database/DatabaseConfiguration.cs
+++ b/DragaliaAPI/DragaliaAPI.Database/DatabaseConfiguration.cs
@@ -3,9 +3,10 @@
using DragaliaAPI.Database.Repositories;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
-using Npgsql;
+using Microsoft.Extensions.Options;
[assembly: InternalsVisibleTo("DragaliaAPI.Database.Test")]
[assembly: InternalsVisibleTo("DragaliaAPI.Test")]
@@ -19,14 +20,22 @@ public static class DatabaseConfiguration
public static IServiceCollection ConfigureDatabaseServices(
this IServiceCollection services,
- PostgresOptions postgresOptions
+ IConfiguration config
)
{
- services = services
- .AddDbContext(options =>
- options
- .UseNpgsql(postgresOptions.GetConnectionString("ApiContext"))
- .EnableDetailedErrors()
+ services.Configure(config.GetRequiredSection(nameof(PostgresOptions)));
+
+ services
+ .AddDbContext(
+ (serviceProvider, options) =>
+ {
+ PostgresOptions postgresOptions = serviceProvider
+ .GetRequiredService>()
+ .Value;
+ options
+ .UseNpgsql(postgresOptions.GetConnectionString("ApiContext"))
+ .EnableDetailedErrors();
+ }
)
#pragma warning disable CS0618 // Type or member is obsolete
.AddScoped()
@@ -38,7 +47,6 @@ PostgresOptions postgresOptions
.AddScoped()
.AddScoped()
.AddScoped()
- .AddScoped()
.AddScoped();
return services;
diff --git a/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayer.cs b/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayer.cs
index bf9793d5c..9d0bf9cf4 100644
--- a/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayer.cs
+++ b/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayer.cs
@@ -90,4 +90,6 @@ public class DbPlayer
public List SummonTickets { get; set; } = [];
public List Emblems { get; set; } = [];
+
+ public DbWallRewardDate? WallRewardDate { get; set; }
}
diff --git a/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayerDragonData.cs b/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayerDragonData.cs
index 77d567b64..994a38ec1 100644
--- a/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayerDragonData.cs
+++ b/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayerDragonData.cs
@@ -9,6 +9,15 @@ namespace DragaliaAPI.Database.Entities;
[Table("PlayerDragonData")]
public class DbPlayerDragonData : DbPlayerData, IHasXp
{
+ public DbPlayerDragonData() { }
+
+ public DbPlayerDragonData(long viewerId, Dragons id)
+ {
+ this.ViewerId = viewerId;
+ this.DragonId = id;
+ this.GetTime = DateTimeOffset.UtcNow;
+ }
+
[Column("DragonKeyId")]
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
diff --git a/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayerDragonReliability.cs b/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayerDragonReliability.cs
index cad9be823..98c646b98 100644
--- a/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayerDragonReliability.cs
+++ b/DragaliaAPI/DragaliaAPI.Database/Entities/DbPlayerDragonReliability.cs
@@ -34,24 +34,19 @@ public class DbPlayerDragonReliability : DbPlayerData, IHasXp
[Required]
[TypeConverter(typeof(DateTimeOffsetConverter))]
public DateTimeOffset GetTime { get; set; }
-}
-public static class DbPlayerDragonReliabilityFactory
-{
- public static DbPlayerDragonReliability Create(long viewerId, Dragons id)
+ public DbPlayerDragonReliability() { }
+
+ public DbPlayerDragonReliability(long viewerId, Dragons id)
{
byte defaultRelLevel = (byte)MasterAsset.DragonData.Get(id).DefaultReliabilityLevel;
defaultRelLevel = defaultRelLevel == default ? (byte)1 : defaultRelLevel;
- DbPlayerDragonReliability newReliability =
- new()
- {
- ViewerId = (int)viewerId,
- DragonId = id,
- Level = defaultRelLevel,
- Exp = DragonConstants.BondXpLimits[defaultRelLevel - 1],
- GetTime = DateTimeOffset.UtcNow,
- LastContactTime = DateTimeOffset.UtcNow
- };
- return newReliability;
+
+ this.ViewerId = (int)viewerId;
+ this.DragonId = id;
+ this.Level = defaultRelLevel;
+ this.Exp = DragonConstants.BondXpLimits[defaultRelLevel - 1];
+ this.GetTime = DateTimeOffset.UtcNow;
+ this.LastContactTime = DateTimeOffset.UtcNow;
}
}
diff --git a/DragaliaAPI/DragaliaAPI.Database/Entities/DbSummonTicket.cs b/DragaliaAPI/DragaliaAPI.Database/Entities/DbSummonTicket.cs
index 48442aff7..021f1b817 100644
--- a/DragaliaAPI/DragaliaAPI.Database/Entities/DbSummonTicket.cs
+++ b/DragaliaAPI/DragaliaAPI.Database/Entities/DbSummonTicket.cs
@@ -1,7 +1,6 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using DragaliaAPI.Database.Entities.Abstract;
-using DragaliaAPI.Shared.Definitions.Enums;
using DragaliaAPI.Shared.Definitions.Enums.Summon;
namespace DragaliaAPI.Database.Entities;
diff --git a/DragaliaAPI/DragaliaAPI.Database/Entities/DbWallRewardDate.cs b/DragaliaAPI/DragaliaAPI.Database/Entities/DbWallRewardDate.cs
new file mode 100644
index 000000000..349ce878f
--- /dev/null
+++ b/DragaliaAPI/DragaliaAPI.Database/Entities/DbWallRewardDate.cs
@@ -0,0 +1,22 @@
+using DragaliaAPI.Database.Entities.Abstract;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace DragaliaAPI.Database.Entities;
+
+///
+/// Entity for tracking Mercurial Gauntlet Victor's Trove claim information.
+///
+public class DbWallRewardDate : DbPlayerData
+{
+ ///
+ /// Gets or sets the last time at which a player claimed their Mercurial Gauntlet trove.
+ ///
+ public DateTimeOffset LastClaimDate { get; set; }
+
+ public class Configuration : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder) =>
+ builder.HasKey(e => e.ViewerId);
+ }
+}
diff --git a/DragaliaAPI/DragaliaAPI.Database/Factories/DbPlayerDragonDataFactory.cs b/DragaliaAPI/DragaliaAPI.Database/Factories/DbPlayerDragonDataFactory.cs
deleted file mode 100644
index 3decbf564..000000000
--- a/DragaliaAPI/DragaliaAPI.Database/Factories/DbPlayerDragonDataFactory.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using DragaliaAPI.Database.Entities;
-using DragaliaAPI.Shared.Definitions.Enums;
-
-namespace DragaliaAPI.Database.Factories;
-
-public static class DbPlayerDragonDataFactory
-{
- public static DbPlayerDragonData Create(long viewerId, Dragons id)
- {
- return new()
- {
- ViewerId = viewerId,
- DragonId = id,
- Exp = 0,
- Level = 1,
- HpPlusCount = 0,
- AttackPlusCount = 0,
- LimitBreakCount = 0,
- IsLock = false,
- IsNew = true,
- Skill1Level = 1,
- Ability1Level = 1,
- Ability2Level = 1,
- GetTime = DateTimeOffset.UtcNow
- };
- }
-}
diff --git a/DragaliaAPI/DragaliaAPI.Database/Migrations/20240513202914_wall_rewards.Designer.cs b/DragaliaAPI/DragaliaAPI.Database/Migrations/20240513202914_wall_rewards.Designer.cs
new file mode 100644
index 000000000..225c5f97c
--- /dev/null
+++ b/DragaliaAPI/DragaliaAPI.Database/Migrations/20240513202914_wall_rewards.Designer.cs
@@ -0,0 +1,2634 @@
+//
+using System;
+using DragaliaAPI.Database;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace DragaliaAPI.Database.Migrations
+{
+ [DbContext(typeof(ApiContext))]
+ [Migration("20240513202914_wall_rewards")]
+ partial class wall_rewards
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.4")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbAbilityCrest", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("AbilityCrestId")
+ .HasColumnType("integer");
+
+ b.Property("AttackPlusCount")
+ .HasColumnType("integer");
+
+ b.Property("BuildupCount")
+ .HasColumnType("integer");
+
+ b.Property("EquipableCount")
+ .HasColumnType("integer");
+
+ b.Property("GetTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("HpPlusCount")
+ .HasColumnType("integer");
+
+ b.Property("IsFavorite")
+ .HasColumnType("boolean");
+
+ b.Property("IsNew")
+ .HasColumnType("boolean");
+
+ b.Property("LimitBreakCount")
+ .HasColumnType("integer");
+
+ b.HasKey("ViewerId", "AbilityCrestId");
+
+ b.ToTable("PlayerAbilityCrests");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbAbilityCrestSet", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("AbilityCrestSetNo")
+ .HasColumnType("integer");
+
+ b.Property("AbilityCrestSetName")
+ .IsRequired()
+ .HasMaxLength(32)
+ .HasColumnType("character varying(32)");
+
+ b.Property("CrestSlotType1CrestId1")
+ .HasColumnType("integer");
+
+ b.Property("CrestSlotType1CrestId2")
+ .HasColumnType("integer");
+
+ b.Property("CrestSlotType1CrestId3")
+ .HasColumnType("integer");
+
+ b.Property("CrestSlotType2CrestId1")
+ .HasColumnType("integer");
+
+ b.Property("CrestSlotType2CrestId2")
+ .HasColumnType("integer");
+
+ b.Property("CrestSlotType3CrestId1")
+ .HasColumnType("integer");
+
+ b.Property("CrestSlotType3CrestId2")
+ .HasColumnType("integer");
+
+ b.Property("TalismanKeyId")
+ .HasColumnType("numeric(20,0)");
+
+ b.HasKey("ViewerId", "AbilityCrestSetNo");
+
+ b.ToTable("PlayerAbilityCrestSets");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbCompletedDailyMission", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("Date")
+ .HasColumnType("date");
+
+ b.Property("EndDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Progress")
+ .HasColumnType("integer");
+
+ b.Property("StartDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("ViewerId", "Id", "Date");
+
+ b.ToTable("CompletedDailyMissions");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbDeviceAccount", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("text");
+
+ b.Property("HashedPassword")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("DeviceAccounts");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbEmblem", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("EmblemId")
+ .HasColumnType("integer")
+ .HasColumnName("EmblemId");
+
+ b.Property("GetTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("GetTime");
+
+ b.Property("IsNew")
+ .HasColumnType("boolean")
+ .HasColumnName("IsNew");
+
+ b.HasKey("ViewerId", "EmblemId");
+
+ b.ToTable("Emblems");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbEquippedStamp", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("Slot")
+ .HasColumnType("integer");
+
+ b.Property("StampId")
+ .HasColumnType("integer");
+
+ b.HasKey("ViewerId", "Slot");
+
+ b.ToTable("EquippedStamps");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbFortBuild", b =>
+ {
+ b.Property("BuildId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("BuildId"));
+
+ b.Property("BuildEndDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("BuildStartDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("IsNew")
+ .HasColumnType("boolean");
+
+ b.Property("LastIncomeDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Level")
+ .HasColumnType("integer");
+
+ b.Property("PlantId")
+ .HasColumnType("integer");
+
+ b.Property("PositionX")
+ .HasColumnType("integer");
+
+ b.Property("PositionZ")
+ .HasColumnType("integer");
+
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.HasKey("BuildId");
+
+ b.HasIndex("ViewerId");
+
+ b.ToTable("PlayerFortBuilds");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbFortDetail", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("CarpenterNum")
+ .HasColumnType("integer")
+ .HasColumnName("CarpenterNum");
+
+ b.HasKey("ViewerId");
+
+ b.ToTable("PlayerFortDetail");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbLoginBonus", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("Id")
+ .HasColumnType("integer");
+
+ b.Property("CurrentDay")
+ .HasColumnType("integer");
+
+ b.Property("IsComplete")
+ .HasColumnType("boolean");
+
+ b.HasKey("ViewerId", "Id");
+
+ b.ToTable("LoginBonuses");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbNewsItem", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Description")
+ .IsRequired()
+ .HasMaxLength(4096)
+ .HasColumnType("character varying(4096)");
+
+ b.Property("Headline")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)");
+
+ b.Property("Time")
+ .HasColumnType("timestamp with time zone");
+
+ b.HasKey("Id");
+
+ b.ToTable("NewsItems");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbParty", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("PartyNo")
+ .HasColumnType("integer");
+
+ b.Property("PartyName")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)");
+
+ b.HasKey("ViewerId", "PartyNo");
+
+ b.ToTable("PartyData");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPartyPower", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("MaxPartyPower")
+ .HasColumnType("integer")
+ .HasColumnName("MaxPartyPower");
+
+ b.HasKey("ViewerId");
+
+ b.ToTable("PartyPowers");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPartyUnit", b =>
+ {
+ b.Property("Id")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)");
+
+ b.Property("CharaId")
+ .HasColumnType("integer");
+
+ b.Property("EditSkill1CharaId")
+ .HasColumnType("integer");
+
+ b.Property("EditSkill2CharaId")
+ .HasColumnType("integer");
+
+ b.Property("EquipCrestSlotType1CrestId1")
+ .HasColumnType("integer");
+
+ b.Property("EquipCrestSlotType1CrestId2")
+ .HasColumnType("integer");
+
+ b.Property("EquipCrestSlotType1CrestId3")
+ .HasColumnType("integer");
+
+ b.Property("EquipCrestSlotType2CrestId1")
+ .HasColumnType("integer");
+
+ b.Property("EquipCrestSlotType2CrestId2")
+ .HasColumnType("integer");
+
+ b.Property("EquipCrestSlotType3CrestId1")
+ .HasColumnType("integer");
+
+ b.Property("EquipCrestSlotType3CrestId2")
+ .HasColumnType("integer");
+
+ b.Property("EquipDragonKeyId")
+ .HasColumnType("bigint");
+
+ b.Property("EquipTalismanKeyId")
+ .HasColumnType("bigint");
+
+ b.Property("EquipWeaponBodyId")
+ .HasColumnType("integer");
+
+ b.Property("EquipWeaponSkinId")
+ .HasColumnType("integer");
+
+ b.Property("PartyNo")
+ .HasColumnType("integer");
+
+ b.Property("UnitNo")
+ .HasColumnType("integer");
+
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ViewerId", "PartyNo");
+
+ b.ToTable("PlayerPartyUnits");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayer", b =>
+ {
+ b.Property("ViewerId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("ViewerId"));
+
+ b.Property("AccountId")
+ .IsRequired()
+ .HasMaxLength(16)
+ .HasColumnType("character varying(16)");
+
+ b.Property("SavefileVersion")
+ .HasColumnType("integer");
+
+ b.HasKey("ViewerId");
+
+ b.HasIndex("AccountId");
+
+ b.ToTable("Players");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerBannerData", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("SummonBannerId")
+ .HasColumnType("integer")
+ .HasColumnName("SummonBannerId");
+
+ b.Property("ConsecutionSummonPoints")
+ .HasColumnType("integer")
+ .HasColumnName("CsSummonPoints");
+
+ b.Property("ConsecutionSummonPointsMaxDate")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("CsSummonPointsMaxDate");
+
+ b.Property("ConsecutionSummonPointsMinDate")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("CsSummonPointsMinDate");
+
+ b.Property("DailyLimitedSummonCount")
+ .HasColumnType("integer")
+ .HasColumnName("DailyLimitedSummons");
+
+ b.Property("IsBeginnerFreeSummonAvailable")
+ .HasColumnType("integer")
+ .HasColumnName("BeginnerSummonAvailable");
+
+ b.Property("IsConsecutionFreeSummonAvailable")
+ .HasColumnType("integer")
+ .HasColumnName("CsSummonAvailable");
+
+ b.Property("IsFreeSummonAvailable")
+ .HasColumnType("integer")
+ .HasColumnName("FreeSummonAvailable");
+
+ b.Property("PityRate")
+ .HasColumnType("smallint")
+ .HasColumnName("Pity");
+
+ b.Property("SummonCount")
+ .HasColumnType("integer")
+ .HasColumnName("SummonCount");
+
+ b.Property("SummonPoints")
+ .HasColumnType("integer")
+ .HasColumnName("SummonPoints");
+
+ b.HasKey("ViewerId", "SummonBannerId");
+
+ b.ToTable("PlayerBannerData");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerCharaData", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("CharaId")
+ .HasColumnType("integer")
+ .HasColumnName("CharaId");
+
+ b.Property("Ability1Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Abil1Lvl");
+
+ b.Property("Ability2Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Abil2Lvl");
+
+ b.Property("Ability3Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Abil3Lvl");
+
+ b.Property("AttackBase")
+ .HasColumnType("integer")
+ .HasColumnName("AtkBase");
+
+ b.Property("AttackNode")
+ .HasColumnType("integer")
+ .HasColumnName("AtkNode");
+
+ b.Property("AttackPlusCount")
+ .HasColumnType("smallint")
+ .HasColumnName("AtkPlusCount");
+
+ b.Property("BurstAttackLevel")
+ .HasColumnType("smallint")
+ .HasColumnName("BurstAtkLvl");
+
+ b.Property("ComboBuildupCount")
+ .HasColumnType("integer")
+ .HasColumnName("ComboBuildupCount");
+
+ b.Property("ExAbility2Level")
+ .HasColumnType("smallint")
+ .HasColumnName("ExAbility2Lvl");
+
+ b.Property("ExAbilityLevel")
+ .HasColumnType("smallint")
+ .HasColumnName("ExAbility1Lvl");
+
+ b.Property("Exp")
+ .HasColumnType("integer")
+ .HasColumnName("Exp");
+
+ b.Property("GetTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("GetTime");
+
+ b.Property("HpBase")
+ .HasColumnType("integer")
+ .HasColumnName("HpBase");
+
+ b.Property("HpNode")
+ .HasColumnType("integer")
+ .HasColumnName("HpNode");
+
+ b.Property("HpPlusCount")
+ .HasColumnType("smallint")
+ .HasColumnName("HpPlusCount");
+
+ b.Property("IsNew")
+ .HasColumnType("boolean")
+ .HasColumnName("IsNew");
+
+ b.Property("IsTemporary")
+ .HasColumnType("boolean")
+ .HasColumnName("IsTemp");
+
+ b.Property("IsUnlockEditSkill")
+ .HasColumnType("boolean")
+ .HasColumnName("IsUnlockEditSkill");
+
+ b.Property("Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Level");
+
+ b.Property("ListViewFlag")
+ .HasColumnType("boolean")
+ .HasColumnName("ListViewFlag");
+
+ b.Property("ManaNodeUnlockCount")
+ .HasColumnType("integer")
+ .HasColumnName("ManaNodeUnlockCount");
+
+ b.Property("Rarity")
+ .HasColumnType("smallint")
+ .HasColumnName("Rarity");
+
+ b.Property("Skill1Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Skill1Lvl");
+
+ b.Property("Skill2Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Skill2Lvl");
+
+ b.HasKey("ViewerId", "CharaId");
+
+ b.ToTable("PlayerCharaData");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerDmodeChara", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("CharaId")
+ .HasColumnType("integer")
+ .HasColumnName("CharaId");
+
+ b.Property("MaxFloor")
+ .HasColumnType("integer")
+ .HasColumnName("MaxFloor");
+
+ b.Property("MaxScore")
+ .HasColumnType("integer")
+ .HasColumnName("MaxScore");
+
+ b.Property("SelectEditSkillCharaId1")
+ .HasColumnType("integer")
+ .HasColumnName("SelectEditSkillCharaId1");
+
+ b.Property("SelectEditSkillCharaId2")
+ .HasColumnType("integer")
+ .HasColumnName("SelectEditSkillCharaId2");
+
+ b.Property("SelectEditSkillCharaId3")
+ .HasColumnType("integer")
+ .HasColumnName("SelectEditSkillCharaId3");
+
+ b.Property("SelectedServitorId")
+ .HasColumnType("integer")
+ .HasColumnName("SelectedServitorId");
+
+ b.HasKey("ViewerId", "CharaId");
+
+ b.ToTable("PlayerDmodeCharas");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerDmodeDungeon", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("CharaId")
+ .HasColumnType("integer")
+ .HasColumnName("CharaId");
+
+ b.Property("DungeonScore")
+ .HasColumnType("integer")
+ .HasColumnName("DungeonScore");
+
+ b.Property("Floor")
+ .HasColumnType("integer")
+ .HasColumnName("Floor");
+
+ b.Property("IsPlayEnd")
+ .HasColumnType("boolean")
+ .HasColumnName("IsPlayEnd");
+
+ b.Property("QuestTime")
+ .HasColumnType("integer")
+ .HasColumnName("QuestTime");
+
+ b.Property("State")
+ .HasColumnType("integer")
+ .HasColumnName("State");
+
+ b.HasKey("ViewerId");
+
+ b.ToTable("PlayerDmodeDungeons");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerDmodeExpedition", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("CharaId1")
+ .HasColumnType("integer")
+ .HasColumnName("CharaId1");
+
+ b.Property("CharaId2")
+ .HasColumnType("integer")
+ .HasColumnName("CharaId2");
+
+ b.Property("CharaId3")
+ .HasColumnType("integer")
+ .HasColumnName("CharaId3");
+
+ b.Property("CharaId4")
+ .HasColumnType("integer")
+ .HasColumnName("CharaId4");
+
+ b.Property("StartTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("StartTime");
+
+ b.Property("State")
+ .HasColumnType("integer")
+ .HasColumnName("State");
+
+ b.Property("TargetFloor")
+ .HasColumnType("integer")
+ .HasColumnName("TargetFloor");
+
+ b.HasKey("ViewerId");
+
+ b.ToTable("PlayerDmodeExpeditions");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerDmodeInfo", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("FloorSkipCount")
+ .HasColumnType("integer")
+ .HasColumnName("FloorSkipCount");
+
+ b.Property("FloorSkipTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("FloorSkipTime");
+
+ b.Property("Point1Quantity")
+ .HasColumnType("integer")
+ .HasColumnName("Point1Quantity");
+
+ b.Property("Point2Quantity")
+ .HasColumnType("integer")
+ .HasColumnName("Point2Quantity");
+
+ b.Property("RecoveryCount")
+ .HasColumnType("integer")
+ .HasColumnName("RecoveryCount");
+
+ b.Property("RecoveryTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("RecoveryTime");
+
+ b.HasKey("ViewerId");
+
+ b.ToTable("PlayerDmodeInfos");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerDmodeServitorPassive", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("PassiveId")
+ .HasColumnType("integer")
+ .HasColumnName("PassiveId");
+
+ b.Property("Level")
+ .HasColumnType("integer")
+ .HasColumnName("Level");
+
+ b.HasKey("ViewerId", "PassiveId");
+
+ b.ToTable("PlayerDmodeServitorPassives");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerDragonData", b =>
+ {
+ b.Property("DragonKeyId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasColumnName("DragonKeyId");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("DragonKeyId"));
+
+ b.Property("Ability1Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Abil1Level");
+
+ b.Property("Ability2Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Abil2Level");
+
+ b.Property("AttackPlusCount")
+ .HasColumnType("smallint")
+ .HasColumnName("AttackPlusCount");
+
+ b.Property("DragonId")
+ .HasColumnType("integer")
+ .HasColumnName("DragonId");
+
+ b.Property("Exp")
+ .HasColumnType("integer")
+ .HasColumnName("Exp");
+
+ b.Property("GetTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("GetTime");
+
+ b.Property("HpPlusCount")
+ .HasColumnType("smallint")
+ .HasColumnName("HpPlusCount");
+
+ b.Property("IsLock")
+ .HasColumnType("boolean")
+ .HasColumnName("IsLocked");
+
+ b.Property("IsNew")
+ .HasColumnType("boolean")
+ .HasColumnName("IsNew");
+
+ b.Property("Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Level");
+
+ b.Property("LimitBreakCount")
+ .HasColumnType("smallint")
+ .HasColumnName("LimitBreakCount");
+
+ b.Property("Skill1Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Skill1Level");
+
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.HasKey("DragonKeyId");
+
+ b.HasIndex("ViewerId");
+
+ b.ToTable("PlayerDragonData");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerDragonGift", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("DragonGiftId")
+ .HasColumnType("integer")
+ .HasColumnName("DragonGiftId");
+
+ b.Property("Quantity")
+ .HasColumnType("integer")
+ .HasColumnName("Quantity");
+
+ b.HasKey("ViewerId", "DragonGiftId");
+
+ b.ToTable("PlayerDragonGift");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerDragonReliability", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("DragonId")
+ .HasColumnType("integer")
+ .HasColumnName("DragonId");
+
+ b.Property("Exp")
+ .HasColumnType("integer")
+ .HasColumnName("TotalExp");
+
+ b.Property("GetTime")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("LastContactTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("LastContactTime");
+
+ b.Property("Level")
+ .HasColumnType("smallint")
+ .HasColumnName("Level");
+
+ b.HasKey("ViewerId", "DragonId");
+
+ b.ToTable("PlayerDragonReliability");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerEventData", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("EventId")
+ .HasColumnType("integer")
+ .HasColumnName("EventId");
+
+ b.Property("CustomEventFlag")
+ .HasColumnType("boolean")
+ .HasColumnName("CustomEventFlag");
+
+ b.HasKey("ViewerId", "EventId");
+
+ b.ToTable("PlayerEventData");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerEventItem", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("Id")
+ .HasColumnType("integer")
+ .HasColumnName("Id");
+
+ b.Property("EventId")
+ .HasColumnType("integer")
+ .HasColumnName("EventId");
+
+ b.Property("Quantity")
+ .HasColumnType("integer")
+ .HasColumnName("Quantity");
+
+ b.Property("Type")
+ .HasColumnType("integer")
+ .HasColumnName("Type");
+
+ b.HasKey("ViewerId", "Id");
+
+ b.HasIndex("ViewerId", "EventId");
+
+ b.ToTable("PlayerEventItems");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerEventPassive", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("EventId")
+ .HasColumnType("integer")
+ .HasColumnName("EventId");
+
+ b.Property("PassiveId")
+ .HasColumnType("integer")
+ .HasColumnName("PassiveId");
+
+ b.Property("Progress")
+ .HasColumnType("integer")
+ .HasColumnName("Progress");
+
+ b.HasKey("ViewerId", "EventId", "PassiveId");
+
+ b.ToTable("PlayerEventPassives");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerEventReward", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("EventId")
+ .HasColumnType("integer")
+ .HasColumnName("EventId");
+
+ b.Property("RewardId")
+ .HasColumnType("integer")
+ .HasColumnName("RewardId");
+
+ b.HasKey("ViewerId", "EventId", "RewardId");
+
+ b.ToTable("PlayerEventRewards");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerMaterial", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("MaterialId")
+ .HasColumnType("integer")
+ .HasColumnName("MaterialId");
+
+ b.Property("Quantity")
+ .HasColumnType("integer")
+ .HasColumnName("Quantity");
+
+ b.HasKey("ViewerId", "MaterialId");
+
+ b.ToTable("PlayerMaterial");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerMission", b =>
+ {
+ b.Property("ViewerId")
+ .HasColumnType("bigint");
+
+ b.Property("Id")
+ .HasColumnType("integer")
+ .HasColumnName("MissionId");
+
+ b.Property("Type")
+ .HasColumnType("integer")
+ .HasColumnName("Type");
+
+ b.Property("End")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("EndDate");
+
+ b.Property("GroupId")
+ .HasColumnType("integer")
+ .HasColumnName("GroupId");
+
+ b.Property("Pickup")
+ .HasColumnType("boolean")
+ .HasColumnName("Pickup");
+
+ b.Property("Progress")
+ .HasColumnType("integer")
+ .HasColumnName("Progress");
+
+ b.Property("Start")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("StartDate");
+
+ b.Property("State")
+ .HasColumnType("integer")
+ .HasColumnName("State");
+
+ b.HasKey("ViewerId", "Id", "Type");
+
+ b.ToTable("PlayerMissions");
+ });
+
+ modelBuilder.Entity("DragaliaAPI.Database.Entities.DbPlayerPresent", b =>
+ {
+ b.Property("PresentId")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("bigint")
+ .HasColumnName("PresentId");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("PresentId"));
+
+ b.Property("CreateTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("CreateTime");
+
+ b.Property("EntityId")
+ .HasColumnType("integer")
+ .HasColumnName("EntityId");
+
+ b.Property("EntityLevel")
+ .HasColumnType("integer")
+ .HasColumnName("EntityLevel");
+
+ b.Property("EntityLimitBreakCount")
+ .HasColumnType("integer")
+ .HasColumnName("EntityLimitBreakCount");
+
+ b.Property("EntityQuantity")
+ .HasColumnType("integer")
+ .HasColumnName("EntityQuantity");
+
+ b.Property("EntityStatusPlusCount")
+ .HasColumnType("integer")
+ .HasColumnName("EntityStatusPlusCount");
+
+ b.Property("EntityType")
+ .HasColumnType("integer")
+ .HasColumnName("EntityType");
+
+ b.Property("MasterId")
+ .HasColumnType("bigint")
+ .HasColumnName("MasterId");
+
+ b.Property("MessageId")
+ .HasColumnType("integer")
+ .HasColumnName("MessageId");
+
+ b.Property("MessageParamValue1")
+ .HasColumnType("integer")
+ .HasColumnName("MessageParamValue1");
+
+ b.Property("MessageParamValue2")
+ .HasColumnType("integer")
+ .HasColumnName("MessageParamValue2");
+
+ b.Property("MessageParamValue3")
+ .HasColumnType("integer")
+ .HasColumnName("MessageParamValue3");
+
+ b.Property("MessageParamValue4")
+ .HasColumnType("integer")
+ .HasColumnName("MessageParamValue4");
+
+ b.Property("ReceiveLimitTime")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("ReceiveLimitTime");
+
+ b.Property("State")
+ .HasColumnType("bigint")
+ .HasColumnName("State");
+
+ b.Property