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/.github/dependabot.yml b/.github/dependabot.yml index e93d5af6b..95bc7c075 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -21,10 +21,10 @@ updates: patterns: - "Microsoft.EntityFrameworkCore*" - package-ecosystem: "docker" - directory: "/DragaliaAPI/DragaliaAPI" + directory: "/DragaliaAPI" schedule: interval: "weekly" - package-ecosystem: "docker" - directory: "/PhotonStateManager/DragaliaAPI.Photon.StateManager" + directory: "/PhotonStateManager" schedule: interval: "weekly" 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..a1a56e080 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: @@ -19,7 +18,7 @@ jobs: uses: ./.github/workflows/build.yaml with: ref: main - dockerfile: "DragaliaAPI/DragaliaAPI/Dockerfile" + dockerfile: "DragaliaAPI/Dockerfile" image-name: "dragalia-api" secrets: inherit deploy: diff --git a/.github/workflows/publish-statemanager.yaml b/.github/workflows/publish-statemanager.yaml index a05e023b8..a09a2b041 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: @@ -19,7 +18,7 @@ jobs: uses: ./.github/workflows/build.yaml with: ref: main - dockerfile: "PhotonStateManager/DragaliaAPI.Photon.StateManager/Dockerfile" + dockerfile: "PhotonStateManager/Dockerfile" image-name: "photon-state-manager" secrets: inherit deploy: 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/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 fbed00726..3d88ca62b 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -14,7 +14,6 @@ - diff --git a/DragaliaAPI.sln b/DragaliaAPI.sln index 44ba5e2f2..4e8047288 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\Dockerfile = PhotonStateManager\Dockerfile + 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,14 @@ 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 + 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\Dockerfile = DragaliaAPI\Dockerfile EndProjectSection EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DragaliaAPI.MasterAssetConverter", "DragaliaAPI\DragaliaAPI.MasterAssetConverter\DragaliaAPI.MasterAssetConverter.csproj", "{F0DFB899-ADC2-407E-AB32-647BA1C4122C}" @@ -86,7 +87,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 +105,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 +165,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/Dockerfile b/DragaliaAPI/Dockerfile similarity index 96% rename from DragaliaAPI/DragaliaAPI/Dockerfile rename to DragaliaAPI/Dockerfile index f22f137af..24a2f586f 100644 --- a/DragaliaAPI/DragaliaAPI/Dockerfile +++ b/DragaliaAPI/Dockerfile @@ -7,7 +7,7 @@ FROM mcr.microsoft.com/dotnet/sdk:8.0.300 AS build WORKDIR /src COPY ["DragaliaAPI/DragaliaAPI.MissionDesigner/DragaliaAPI.MissionDesigner.csproj", "DragaliaAPI/DragaliaAPI.MissionDesigner/"] COPY ["DragaliaAPI/DragaliaAPI.MasterAssetConverter/DragaliaAPI.MasterAssetConverter.csproj", "DragaliaAPI/DragaliaAPI.MasterAssetConverter/"] -COPY ["Directory.Build.props", "."] +COPY ["DragaliaAPI/Directory.Build.props", "."] COPY ["Directory.Packages.props", "."] COPY ["nuget.config", "."] RUN dotnet restore "DragaliaAPI/DragaliaAPI.MissionDesigner/DragaliaAPI.MissionDesigner.csproj" diff --git a/DragaliaAPI/DragaliaAPI.MasterAssetConverter/AttributeHelper.cs b/DragaliaAPI/DragaliaAPI.MasterAssetConverter/AttributeHelper.cs index 6419e40e1..6729913cc 100644 --- a/DragaliaAPI/DragaliaAPI.MasterAssetConverter/AttributeHelper.cs +++ b/DragaliaAPI/DragaliaAPI.MasterAssetConverter/AttributeHelper.cs @@ -1,7 +1,7 @@ using DragaliaAPI.Shared.MasterAsset; using DragaliaAPI.Shared.MasterAsset.Models; -namespace DragaliaAPI.MemoryPack; +namespace DragaliaAPI.MasterAssetConverter; public static class AttributeHelper { diff --git a/DragaliaAPI/DragaliaAPI.MasterAssetConverter/Program.cs b/DragaliaAPI/DragaliaAPI.MasterAssetConverter/Program.cs index 32f81592e..578e43681 100644 --- a/DragaliaAPI/DragaliaAPI.MasterAssetConverter/Program.cs +++ b/DragaliaAPI/DragaliaAPI.MasterAssetConverter/Program.cs @@ -1,7 +1,7 @@ using System.Diagnostics; using System.Reflection; using System.Text.Json; -using DragaliaAPI.MemoryPack; +using DragaliaAPI.MasterAssetConverter; using DragaliaAPI.Shared.MasterAsset; using DragaliaAPI.Shared.Serialization; using MessagePack; diff --git a/DragaliaAPI/DragaliaAPI.Shared.SourceGenerator/DragaliaAPI.Shared.SourceGenerator.csproj b/DragaliaAPI/DragaliaAPI.Shared.SourceGenerator/DragaliaAPI.Shared.SourceGenerator.csproj index 931c31ed2..f2aa8797d 100644 --- a/DragaliaAPI/DragaliaAPI.Shared.SourceGenerator/DragaliaAPI.Shared.SourceGenerator.csproj +++ b/DragaliaAPI/DragaliaAPI.Shared.SourceGenerator/DragaliaAPI.Shared.SourceGenerator.csproj @@ -2,6 +2,7 @@ netstandard2.0 + 12 false true true diff --git a/DragaliaAPI/DragaliaAPI/DragaliaAPI.csproj b/DragaliaAPI/DragaliaAPI/DragaliaAPI.csproj index 3acd76544..58f3562ac 100644 --- a/DragaliaAPI/DragaliaAPI/DragaliaAPI.csproj +++ b/DragaliaAPI/DragaliaAPI/DragaliaAPI.csproj @@ -5,116 +5,113 @@ ..\docker-compose.dcproj 3.0.0 f95759aa-167b-4511-aeb2-ea87d3c0798c + ..\.. - - - - - - - - - - - - + + + + + + + + + + + + all build; native; contentfiles; analyzers; buildtransitive - - - - - - - - + + + + + + + + all build; native; contentfiles; analyzers - - - - - - - - - - - - - + + + + + + + + + + + + + - - + + - + - - - + + + - - - + + + - - ..\DragaliaAPI.Shared\Resources\ - - - - + + - + %(DesignerOutputs.Identity) - + - + - + %(ConverterOutputs.Identity) - + - + - + - + - + diff --git a/DragaliaAPI/README.md b/DragaliaAPI/README.md new file mode 100644 index 000000000..84cfdc5dd --- /dev/null +++ b/DragaliaAPI/README.md @@ -0,0 +1,15 @@ +# DragaliaAPI + +DragaliaAPI is the main server component of Dawnshard, which handles the vast majority of game functionality. + +## Hosting your own instance + +The application is deployed as three services: the main ASP.NET service which is stateless, and two stateful services in Redis (session management) and PostgreSQL (savefile storage). + +### Locally + +The recommended way to self-host (for personal use or development) is using `docker-compose` -- please see the [self-hosting guide](https://github.com/SapiensAnatis/Dawnshard/wiki/Self-hosting-guide) in the wiki for more information. + +### Dedicated server + +On a dedicated server, the basic `docker-compose` setup will work, but additional considerations should be made regarding reverse proxying, logging, etc. Speak to the maintainer if you are interested in hosting your own instance for further guidance. diff --git a/PhotonPlugin/Directory.Build.props b/PhotonPlugin/Directory.Build.props new file mode 100644 index 000000000..e3a1e3e00 --- /dev/null +++ b/PhotonPlugin/Directory.Build.props @@ -0,0 +1,9 @@ + + + net481 + disable + disable + 7.3 + x64 + + \ No newline at end of file diff --git a/PhotonPlugin/DragaliaAPI.Photon.Plugin.Test/MemberCountTableTest.cs b/PhotonPlugin/DragaliaAPI.Photon.Plugin.Test/MemberCountTableTest.cs index ca0397c0a..e7655f0d7 100644 --- a/PhotonPlugin/DragaliaAPI.Photon.Plugin.Test/MemberCountTableTest.cs +++ b/PhotonPlugin/DragaliaAPI.Photon.Plugin.Test/MemberCountTableTest.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using DragaliaAPI.Photon.Plugin.Plugins.GameLogic.Events; using FluentAssertions; using Xunit; diff --git a/PhotonPlugin/DragaliaAPI.Photon.Plugin/DragaliaAPI.Photon.Plugin.csproj b/PhotonPlugin/DragaliaAPI.Photon.Plugin/DragaliaAPI.Photon.Plugin.csproj index 3d69c9330..6ee2d89aa 100644 --- a/PhotonPlugin/DragaliaAPI.Photon.Plugin/DragaliaAPI.Photon.Plugin.csproj +++ b/PhotonPlugin/DragaliaAPI.Photon.Plugin/DragaliaAPI.Photon.Plugin.csproj @@ -1,11 +1,6 @@  - net481 - disable - disable - 7.3 - x64 OnBuildSuccess 3.2.4 @@ -22,11 +17,11 @@ - + - + \ No newline at end of file diff --git a/PhotonPlugin/README.md b/PhotonPlugin/README.md new file mode 100644 index 000000000..20cc8daca --- /dev/null +++ b/PhotonPlugin/README.md @@ -0,0 +1,181 @@ +# PhotonPlugin + +The Photon plugin is a DLL that integrates into Photon Server product to provide the custom logic required for the game's co-op mode to function. + +To install this plugin, you must first acquire a license for Photon Server. This requires joining the Photon industries or gaming circle for $125/mo, and then purchasing a Photon Server license for $95/mo. + +## How to build the plugin + +The plugin can be compiled from the source code provided from each release, but you must first add a reference to +PhotonHivePlugin.dll, which can be downloaded as part of +the [Plugins SDK](https://www.photonengine.com/sdks#server-sdkserverserverplugin) from Photon's website. Builds of the +plugin are not provided with the releases to avoid redistributing this proprietary component. + +Ensure the plugin is compiled in Release mode before deploying to production. + +## How to set up a Photon server + +### Part 1: Configuring Photon Server + +1. Follow + the [instructions from the Photon documentation](https://doc.photonengine.com/server/current/getting-started/photon-server-in-5min#ip_address_config) + to setting up the server. Pay particular attention to step 7 if you intend to expose the server on a public or local + IP address. +2. Place the plugin binary files in `Plugins/GluonPlugin//bin`. +3. Install the plugin, by editing `LoadBalancing/GameServer/bin/plugin.config`. Below is a sample configuration: + + ```xml + + + + + + + + + ``` + + The config values have the following meanings: + + | Key | Explanation | + | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | Name | Do not change. Name of the plugin as sent to the Dragalia client. | + | Version | Plugin version -- the example above will look in Plugins/GluonPlugin/v1/bin for binary files. Can be hot reloaded. | + | AssemblyName | Do not change. Plugin assembly name. | + | Type | Do not change. Plugin factory type name. | + | ApiServerUrl | URL of the main API server. Used to make requests for party data. | + | StateManagerUrl | URL of hosted room state manager (e.g. DragaliaAPI.Photon.StateManager) | + | DungeonRecordMultiEndpoint | Endpoint to call on behalf of players when clearing a quest | + | TimeAttackEndpoint | Endpoint to call when registering a Time Attack clear. | + | ReplayTimeoutSeconds | The number of seconds players have to confirm whether they want to play again after a clear | + | BearerToken | Token to embed in Authorization header when making requests to the state manager | + | RandomMatchingStartDelayMs | The duration in milliseconds to wait for a random matching room (e.g. invasion events) to start when more than one player is present. | + | EnableSecondaryServer | Whether or not to enable secondary server connections. This allows another API server to host rooms on the same Photon server. Each server must have a distinct viewer ID range, as this is how the plugin determines which server belongs to. | + | SecondaryViewerIdCriterion | The threshold value at which the viewer ID of a joining player means they are joining from the secondary server. All players with viewer IDs less than this value will be considered as being from the primary server. | + | SecondaryApiServerUrl | Used instead of ApiServerUrl when a room is in secondary server mode. | + | StateManagerUrl | Used instead of StateManagerUrl when a room is in secondary server mode. | + | SecondaryBearerToken | Used instead of BearerToken when a room is in secondary server mode. | + | EnableDiscordIntegration | Whether to enable requests to a Discord bot for posting active rooms. N.B. due to a bug, setting this to false does not disable Discord integration. | + | DiscordUrl | The URL of a server to send Discord bot requests to. | + | DiscordBearerToken | The bearer token to use in the Authorization header when making Discord bot requests. | + +4. Update LoadBalancing/GameServer/bin/GameServer.xml.config to increase the maximum property size: + +```xml + + + + + 100000 + 1000 + 100000 + + + + 510000 + 9000000 + + + + + +``` + +5. Optionally, update `bin_Win64/PhotonServer.config` and decrease the `MinimumTimeout` and `MaximumTimeout` values. + These will control the amount of time before a player who stops sending packets is kicked from the room. The defaults + cause players to leave after between 10 and 30 seconds of inactivity. For Dragalia, it can be beneficial to decrease + this so that 1) AI units take over faster in quests and 2) if a player leaves while the room is loading, other + players are not locked in the loading screen waiting for them for too long. + +6. If deploying in production, follow best practices such as: + + - disable debug logging + - remove the console log appender + - change the AuthToken from the default on all 3 servers + - ensure the server-to-server port (4520) is not publicly accessible + +### Part 2: Configuring the state manager + +The state manager application should be comparitively easy to deploy. It is a Docker container that expects to be +deployed alongside a `redis/redis-stack` image. See the `docker-compose.yml` file in the repository for reference. It +does not need to be on the same server as Photon. + +It expects an environment variable, `PHOTON_TOKEN`, to match that which is configured in `plugin.config` above, so as to +authenticate requests from the Photon server. A sample Docker compose file could look like: + +```yaml +version: "3.4" + +services: + photonstatemanager: + hostname: photonstatemanager + image: sapiensanatis/dragalia-api-statemanager:latest + ports: + - "3000:80" + environment: + PHOTON_TOKEN: yourtoken + + redis: + hostname: redis + image: redis/redis-stack-server +``` + +In `appsettings.json` configure the following values: + +- `$.SeqOptions`: set up your Seq logging config, or leave it disabled if you don't want to log to Seq. +- `$.ConnectionStrings.Redis`: set up your Redis Stack connection string. The default will suffice if using + docker-compose with the default networking. +- `$.RedisOptions.KeyExpiryTimeMins`: this can be changed to control the time after which rooms naturally expire in + Redis. + +### Part 3: Configuring the main API server + +In the main API `appsettings.json`, configure the following values in `$.PhotonOptions`: + +- `ServerUrl`: the Photon server URL. Must end with :5055 due to Dragalia using a legacy client. +- `StateManagerUrl` the Photon state manager URL. + +Configure the following environment variables: + +- `PHOTON_TOKEN`: the same photon token as the plugin and state manager use. Used to authenticate requests from Photon. + +#### Other servers + +If you are not using DragaliaAPI / Dawnshard as your main API server, you will need to implement the following +endpoints: + +- `/heroparam/batch`: Get party information based on the list of viewer IDs and party numbers in the request body. + See [HeroParamService.cs](https://github.com/SapiensAnatis/Dawnshard/blob/develop/DragaliaAPI/Services/Photon/HeroParamService.cs). +- `/matching/get_room_list`: Get a list of all open rooms. Typically can call `/get/gamelist` on the state manager. + - Additional work must be done by the API server to populate fields such as host lead character. + See [MatchingService.cs](https://github.com/SapiensAnatis/Dawnshard/blob/develop/DragaliaAPI/Services/Photon/MatchingService.cs). +- `/matching/get_room_list_by_quest_id`: Get a list of open rooms for a quest. Can call `/get/gamelist?questId=XXXXX` on + the state manager. +- `/matching/get_room_name`: Get a private room based on the passcode. Can call `/get/byid/{id}` on the state manager. + +Additionally: + +- You must set `is_host` correctly in `/dungeon_start/start_multi`, `/dungeon/fail`, and `/dungeon_record/record_multi`. + The state manager provides an endpoint: `GET /get/ishost/` returning a response body of `true` or `false` ( + JSON scalar) to help with this. +- `/dungeon_record/record_multi` must be able to accept requests from the Photon server. The Photon server will provide + an `Authorization Bearer ` header, as well as `Auth-ViewerId` for authentication. diff --git a/PhotonStateManager/Directory.Build.props b/PhotonStateManager/Directory.Build.props new file mode 100644 index 000000000..886c4dccf --- /dev/null +++ b/PhotonStateManager/Directory.Build.props @@ -0,0 +1,8 @@ + + + net8.0 + enable + enable + latest-minimum + + \ No newline at end of file diff --git a/PhotonStateManager/DragaliaAPI.Photon.StateManager/Dockerfile b/PhotonStateManager/Dockerfile similarity index 94% rename from PhotonStateManager/DragaliaAPI.Photon.StateManager/Dockerfile rename to PhotonStateManager/Dockerfile index 861f89e1c..a0f47fbe0 100644 --- a/PhotonStateManager/DragaliaAPI.Photon.StateManager/Dockerfile +++ b/PhotonStateManager/Dockerfile @@ -6,7 +6,7 @@ WORKDIR /app FROM mcr.microsoft.com/dotnet/sdk:8.0.300 AS build WORKDIR /src COPY ["PhotonStateManager/DragaliaAPI.Photon.StateManager/DragaliaAPI.Photon.StateManager.csproj", "PhotonStateManager/DragaliaAPI.Photon.StateManager/"] -COPY ["Directory.Build.props", "."] +COPY ["PhotonStateManager/Directory.Build.props", "."] COPY ["Directory.Packages.props", "."] COPY ["nuget.config", "."] RUN dotnet restore "PhotonStateManager/DragaliaAPI.Photon.StateManager/DragaliaAPI.Photon.StateManager.csproj" diff --git a/PhotonStateManager/DragaliaAPI.Photon.StateManager/DragaliaAPI.Photon.StateManager.csproj b/PhotonStateManager/DragaliaAPI.Photon.StateManager/DragaliaAPI.Photon.StateManager.csproj index 144cce430..cf6b91bed 100644 --- a/PhotonStateManager/DragaliaAPI.Photon.StateManager/DragaliaAPI.Photon.StateManager.csproj +++ b/PhotonStateManager/DragaliaAPI.Photon.StateManager/DragaliaAPI.Photon.StateManager.csproj @@ -32,4 +32,8 @@ + + + + diff --git a/PhotonStateManager/README.md b/PhotonStateManager/README.md new file mode 100644 index 000000000..71bb2497f --- /dev/null +++ b/PhotonStateManager/README.md @@ -0,0 +1,18 @@ +# PhotonStateManager + +This is a very basic ASP.NET Core microservice that acts as a stateful storage of Photon rooms for the purposes of matchmaking and display in the main API server. + +It operates by receiving webhook events from the Photon server, which trigger rooms to be created, updated, and deleted in the backing Redis storage. It further exposes a REST API to retrieve this data from the main API server. + +## API + +PhotonStateManager exposes a very simple REST API that is divided into two halves: 'private' endpoints designed for consumption by the Photon server, and 'public' endpoints that are designed to be consumed by the main Dragalia Lost API server. The private endpoints are under the /event/ route group, and the public endpoints are under the /get/ route group. + +The private endpoints are secured by bearer token authentication set by an environment variable `PHOTON_TOKEN`. + +### /get/ endpoints + +- `/get/gamelist`: Returns a list of currently open games that are available to join for public matchmaking. +- `/get/byid/{roomId}`: Searches for a room by its numeric passcode. This can include private rooms as well. If found, returns 200 OK, otherwise 404 Not Found. +- `/get/ishost/{viewerId}`: Returns a scalar boolean indicating whether a user with the provided player ID is a host in any room. +- `/get/byviewerid/{viewerId}`: Returns the room that a player is in, or 404 if they could not be found in a room. diff --git a/README.md b/README.md index 6f0dbe3d9..4c1b2edf5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,6 @@ # Dawnshard -[![Last Updated](https://img.shields.io/github/last-commit/sapiensanatis/dawnshard/main?label=updated -)](https://github.com/SapiensAnatis/Dawnshard/commits/main/) +[![Last Updated](https://img.shields.io/github/last-commit/sapiensanatis/dawnshard/main?label=updated)](https://github.com/SapiensAnatis/Dawnshard/commits/main/) [![GitHub License](https://img.shields.io/github/license/sapiensanatis/dawnshard)](https://github.com/SapiensAnatis/Dawnshard/blob/main/LICENSE) [![Open Issues](https://img.shields.io/github/issues/sapiensanatis/dawnshard)](https://github.com/sapiensAnatis/dawnshard/issues) [![Closed Issues](https://img.shields.io/github/issues-closed/sapiensanatis/dawnshard?color=%238957e5)](https://github.com/SapiensAnatis/Dawnshard/issues?q=is%3Aissue+is%3Aclosed) @@ -12,6 +11,15 @@ You can play using the [Dragalipatch](https://github.com/lukeFZ/dragalipatch) ap If you haven't already, please also consider joining the Dragalia Lost Reverse Engineering [Discord server](https://discord.gg/j9zSttjjWj); this is where development is discussed and where bugs/issues are most easily reported. +## Components + +This is a mono-repository that contains the following components. Each of them is documented further in their respective folders. + +- [DragaliaAPI](./DragaliaAPI/) +- [PhotonStateManager](./PhotonStateManager/) +- [PhotonPlugin](./PhotonPlugin/) +- [MaintenanceWorker](./MaintenanceWorker/) + ## Contributing Contributions are more than welcome! Feel free to fork the repository and open a pull request with these changes. @@ -20,18 +28,6 @@ For guidance on contributing, including the process for setting up a development See also the [API documentation](https://dragalia-api-docs.readthedocs.io/en/latest/) for reference on what existing endpoints do and how to implement new ones. -## Hosting your own instance - -The application is deployed as three services: the main ASP.NET service which is stateless, and two stateful services in Redis (session management) and PostgreSQL (savefile storage). - -### Locally - -The recommended way to self-host (for personal use or development) is using `docker-compose` -- please see the [self-hosting guide](https://github.com/SapiensAnatis/Dawnshard/wiki/Self-hosting-guide) in the wiki for more information. - -### Dedicated server - -On a dedicated server, the basic `docker-compose` setup will work, but additional considerations should be made regarding reverse proxying, logging, etc. Speak to the maintainer if you are interested in hosting your own instance for further guidance. - ## Acknowledgements A big thanks to JetBrains for providing open source licenses for this project. diff --git a/Shared/DragaliaAPI.Photon.Shared/DragaliaAPI.Photon.Shared.csproj b/Shared/DragaliaAPI.Photon.Shared/DragaliaAPI.Photon.Shared.csproj index ad781965c..f3bc1d0b4 100644 --- a/Shared/DragaliaAPI.Photon.Shared/DragaliaAPI.Photon.Shared.csproj +++ b/Shared/DragaliaAPI.Photon.Shared/DragaliaAPI.Photon.Shared.csproj @@ -2,6 +2,8 @@ netstandard2.0 + 12 + enable disable diff --git a/docker-compose.dcproj b/docker-compose.dcproj index 801e27518..ab710c3f9 100644 --- a/docker-compose.dcproj +++ b/docker-compose.dcproj @@ -1,19 +1,21 @@ - - 2.1 - Linux - 6e4bcc4d-1998-4135-a474-681ec6e6af57 - None - {Scheme}://localhost:{ServicePort}/weatherforecast - dragaliaapi - dragaliaapi - - - - - docker-compose.yml - - - + + 2.1 + Linux + False + ab163a1e-1339-4cfc-82ad-e59ecfada3c2 + LaunchBrowser + {Scheme}://localhost:{ServicePort} + dragaliaapi + + + + docker-compose.yml + + + + + + \ No newline at end of file diff --git a/docker-compose.override.yml b/docker-compose.override.yml index fe4d2317c..2fe8f0757 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -4,6 +4,7 @@ services: dragaliaapi: environment: - ASPNETCORE_ENVIRONMENT=Development -# photonstatemanager: -# environment: -# - ASPNETCORE_ENVIRONMENT=Development \ No newline at end of file + + photonstatemanager: + environment: + - ASPNETCORE_ENVIRONMENT=Development \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index b2142ec33..d4850aa5e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -10,7 +10,7 @@ services: hostname: dragaliaapi build: context: . - dockerfile: DragaliaAPI/DragaliaAPI/Dockerfile + dockerfile: DragaliaAPI/Dockerfile environment: - PostgresOptions__Username=$POSTGRES_USER - PostgresOptions__Password=$POSTGRES_PASSWORD @@ -28,7 +28,7 @@ services: image: ${DOCKER_REGISTRY-}photonstatemanager build: context: . - dockerfile: PhotonStateManager/DragaliaAPI.Photon.StateManager/Dockerfile + dockerfile: PhotonStateManager/Dockerfile ports: - "5001:8080" env_file: @@ -52,13 +52,3 @@ services: ports: - "6379:6379" - "8001:8001" - - #seq: - # image: datalust/seq:latest - # ports: - # - 5340:80 - # - 5341:5341 - # environment: - # ACCEPT_EULA: "Y" - # volumes: - # - logs:/data