mirror of
https://github.com/EpinelPS/EpinelPS.git
synced 2025-12-16 08:54:47 +01:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1c733dfb5e | ||
|
|
a94878bce8 | ||
|
|
52b66947fc | ||
|
|
fa531385d1 | ||
|
|
6325cdf70a | ||
|
|
d5ae01af40 | ||
|
|
7a09c5960e | ||
|
|
d00ab6d185 | ||
|
|
7ddaef38df | ||
|
|
107e6b2eed | ||
|
|
d09b887879 | ||
|
|
01a0e70ae3 | ||
|
|
eee538f97f | ||
|
|
e2a0712889 | ||
|
|
42b17682b8 | ||
|
|
fc0e2801ed | ||
|
|
10fc4c3941 | ||
|
|
a1c910f444 | ||
|
|
f41cb1533d | ||
|
|
c1dc421e16 | ||
|
|
8a9447dc09 | ||
|
|
1c29003eaa | ||
|
|
239c4f293f | ||
|
|
0990f46266 | ||
|
|
6fb6c7b1ee | ||
|
|
467a20170f | ||
|
|
8157d5ea3c | ||
|
|
0ebc235a93 | ||
|
|
6f8497e60b | ||
|
|
a139373320 | ||
|
|
8467a5fce9 | ||
|
|
e185b7d87e |
4
.github/workflows/dotnet-desktop.yml
vendored
4
.github/workflows/dotnet-desktop.yml
vendored
@@ -39,10 +39,10 @@ jobs:
|
|||||||
run: dotnet publish ServerSelector.Desktop
|
run: dotnet publish ServerSelector.Desktop
|
||||||
|
|
||||||
- name: Publish Server
|
- name: Publish Server
|
||||||
run: dotnet publish nksrv
|
run: dotnet publish EpinelPS
|
||||||
|
|
||||||
- name: Copy to output
|
- name: Copy to output
|
||||||
run: echo ${{ github.workspace }} && md ${{ github.workspace }}/out/ && xcopy /s /e "${{ github.workspace }}\ServerSelector.Desktop\bin\Release\net8.0\win-x64\publish\" "${{ github.workspace }}\out\" && xcopy /s /e "${{ github.workspace }}\nksrv\bin\Release\net8.0\win-x64\publish\" "${{ github.workspace }}\out\" && copy "${{ github.workspace }}\ServerSelector.Desktop\sodium.dll" "${{ github.workspace }}\out\sodium.dll"
|
run: echo ${{ github.workspace }} && md ${{ github.workspace }}/out/ && xcopy /s /e "${{ github.workspace }}\ServerSelector.Desktop\bin\Release\net8.0\win-x64\publish\" "${{ github.workspace }}\out\" && xcopy /s /e "${{ github.workspace }}\EpinelPS\bin\Release\net8.0\win-x64\publish\" "${{ github.workspace }}\out\" && copy "${{ github.workspace }}\ServerSelector.Desktop\sodium.dll" "${{ github.workspace }}\out\sodium.dll"
|
||||||
|
|
||||||
- name: Upload build artifacts
|
- name: Upload build artifacts
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
|
|||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -454,6 +454,8 @@ $RECYCLE.BIN/
|
|||||||
!.vscode/extensions.json
|
!.vscode/extensions.json
|
||||||
|
|
||||||
# Allow pregenerated ssl cert
|
# Allow pregenerated ssl cert
|
||||||
!nksrv/site.pfx
|
!EpinelPS/site.pfx
|
||||||
!ServerSelector/myCA.pfx
|
!ServerSelector/myCA.pfx
|
||||||
!ServerSelector/sodium.dll
|
!ServerSelector/sodium.dll
|
||||||
|
|
||||||
|
EpinelPS/Protos/allmsgs.proto
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
using System.IO.Compression;
|
|
||||||
|
|
||||||
namespace DataFixupUtil
|
|
||||||
{
|
|
||||||
internal class Program
|
|
||||||
{
|
|
||||||
static void Main(string[] args)
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello, World!");
|
|
||||||
|
|
||||||
foreach (var arg in Directory.GetFiles("C:\\NIKKE\\NIKKE\\Game"))
|
|
||||||
{
|
|
||||||
var fileName = Path.GetFileName(arg);
|
|
||||||
if (fileName.StartsWith("input"))
|
|
||||||
{
|
|
||||||
byte[] FileContents = File.ReadAllBytes(arg);
|
|
||||||
using MemoryStream ms = new MemoryStream(FileContents);
|
|
||||||
File.WriteAllBytes("fullPkt-decr", ms.ToArray());
|
|
||||||
|
|
||||||
var unkVal1 = ms.ReadByte();
|
|
||||||
var pktLen = ms.ReadByte() & 0x1f;
|
|
||||||
|
|
||||||
|
|
||||||
var seqNumB = ms.ReadByte();
|
|
||||||
var seqNum = seqNumB;
|
|
||||||
if (seqNumB >= 24)
|
|
||||||
{
|
|
||||||
var b = ms.ReadByte();
|
|
||||||
|
|
||||||
seqNum = BitConverter.ToUInt16(new byte[] { (byte)b, (byte)seqNumB }, 0);
|
|
||||||
|
|
||||||
// todo support uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
var startPos = (int)ms.Position;
|
|
||||||
|
|
||||||
var contents = FileContents.Skip(startPos).ToArray();
|
|
||||||
if (contents.Length > 2 && contents[0] == 0x1f && contents[1] == 0x8b)
|
|
||||||
{
|
|
||||||
// gzip compression is used
|
|
||||||
using Stream csStream = new GZipStream(new MemoryStream(contents), CompressionMode.Decompress);
|
|
||||||
using MemoryStream decoded = new MemoryStream();
|
|
||||||
csStream.CopyTo(decoded);
|
|
||||||
|
|
||||||
contents = decoded.ToArray();
|
|
||||||
File.WriteAllBytes(arg, contents);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
File.WriteAllBytes(arg, contents);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,11 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
|||||||
# Visual Studio Version 17
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 17.10.34928.147
|
VisualStudioVersion = 17.10.34928.147
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "nksrv", "nksrv\nksrv.csproj", "{5C24A07E-9B8D-4625-BF91-0E9CCBEF5CB0}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EpinelPS", "EpinelPS\EpinelPS.csproj", "{5C24A07E-9B8D-4625-BF91-0E9CCBEF5CB0}"
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DataFixupUtil", "DataFixupUtil\DataFixupUtil.csproj", "{13124DFB-448B-4F4F-A479-537EE067D836}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProtobufViewUtil", "ProtobufViewUtil\ProtobufViewUtil.csproj", "{FDEDD0D6-9C02-4E58-8110-04E8D5639881}"
|
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerSelector", "ServerSelector\ServerSelector.csproj", "{EC613C24-8A35-42E8-92C1-9A8431F74F58}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerSelector", "ServerSelector\ServerSelector.csproj", "{EC613C24-8A35-42E8-92C1-9A8431F74F58}"
|
||||||
EndProject
|
EndProject
|
||||||
@@ -15,8 +11,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerSelector.Desktop", "S
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{4BB2E77F-84A6-4644-9FB3-38E2A7DCDEC0}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Client", "Client", "{4BB2E77F-84A6-4644-9FB3-38E2A7DCDEC0}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GameDownloader", "GameDownloader\GameDownloader.csproj", "{E3512D9F-CB94-4C80-B673-0EB83CA21D12}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -57,54 +51,6 @@ Global
|
|||||||
{5C24A07E-9B8D-4625-BF91-0E9CCBEF5CB0}.ReleaseDLL|x64.Build.0 = Release|Any CPU
|
{5C24A07E-9B8D-4625-BF91-0E9CCBEF5CB0}.ReleaseDLL|x64.Build.0 = Release|Any CPU
|
||||||
{5C24A07E-9B8D-4625-BF91-0E9CCBEF5CB0}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU
|
{5C24A07E-9B8D-4625-BF91-0E9CCBEF5CB0}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU
|
||||||
{5C24A07E-9B8D-4625-BF91-0E9CCBEF5CB0}.ReleaseDLL|x86.Build.0 = Release|Any CPU
|
{5C24A07E-9B8D-4625-BF91-0E9CCBEF5CB0}.ReleaseDLL|x86.Build.0 = Release|Any CPU
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.DebugDLL|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.DebugDLL|x64.Build.0 = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.DebugDLL|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.DebugDLL|x86.Build.0 = Debug|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.ReleaseDLL|x64.Build.0 = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{13124DFB-448B-4F4F-A479-537EE067D836}.ReleaseDLL|x86.Build.0 = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.DebugDLL|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.DebugDLL|x64.Build.0 = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.DebugDLL|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.DebugDLL|x86.Build.0 = Debug|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.ReleaseDLL|x64.Build.0 = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{FDEDD0D6-9C02-4E58-8110-04E8D5639881}.ReleaseDLL|x86.Build.0 = Release|Any CPU
|
|
||||||
{EC613C24-8A35-42E8-92C1-9A8431F74F58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{EC613C24-8A35-42E8-92C1-9A8431F74F58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{EC613C24-8A35-42E8-92C1-9A8431F74F58}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EC613C24-8A35-42E8-92C1-9A8431F74F58}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{EC613C24-8A35-42E8-92C1-9A8431F74F58}.Debug|x64.ActiveCfg = Debug|Any CPU
|
{EC613C24-8A35-42E8-92C1-9A8431F74F58}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||||
@@ -153,30 +99,6 @@ Global
|
|||||||
{01D0A73A-A881-439D-9318-54DB5B00D6F5}.ReleaseDLL|x64.Build.0 = Release|Any CPU
|
{01D0A73A-A881-439D-9318-54DB5B00D6F5}.ReleaseDLL|x64.Build.0 = Release|Any CPU
|
||||||
{01D0A73A-A881-439D-9318-54DB5B00D6F5}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU
|
{01D0A73A-A881-439D-9318-54DB5B00D6F5}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU
|
||||||
{01D0A73A-A881-439D-9318-54DB5B00D6F5}.ReleaseDLL|x86.Build.0 = Release|Any CPU
|
{01D0A73A-A881-439D-9318-54DB5B00D6F5}.ReleaseDLL|x86.Build.0 = Release|Any CPU
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Debug|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Debug|x64.Build.0 = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Debug|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Debug|x86.Build.0 = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.DebugDLL|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.DebugDLL|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.DebugDLL|x64.ActiveCfg = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.DebugDLL|x64.Build.0 = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.DebugDLL|x86.ActiveCfg = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.DebugDLL|x86.Build.0 = Debug|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Release|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Release|x64.Build.0 = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Release|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.Release|x86.Build.0 = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.ReleaseDLL|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.ReleaseDLL|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.ReleaseDLL|x64.ActiveCfg = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.ReleaseDLL|x64.Build.0 = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.ReleaseDLL|x86.ActiveCfg = Release|Any CPU
|
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12}.ReleaseDLL|x86.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -184,7 +106,6 @@ Global
|
|||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{EC613C24-8A35-42E8-92C1-9A8431F74F58} = {4BB2E77F-84A6-4644-9FB3-38E2A7DCDEC0}
|
{EC613C24-8A35-42E8-92C1-9A8431F74F58} = {4BB2E77F-84A6-4644-9FB3-38E2A7DCDEC0}
|
||||||
{01D0A73A-A881-439D-9318-54DB5B00D6F5} = {4BB2E77F-84A6-4644-9FB3-38E2A7DCDEC0}
|
{01D0A73A-A881-439D-9318-54DB5B00D6F5} = {4BB2E77F-84A6-4644-9FB3-38E2A7DCDEC0}
|
||||||
{E3512D9F-CB94-4C80-B673-0EB83CA21D12} = {4BB2E77F-84A6-4644-9FB3-38E2A7DCDEC0}
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {F779F2DC-B207-4091-83B8-0EA250461DCE}
|
SolutionGuid = {F779F2DC-B207-4091-83B8-0EA250461DCE}
|
||||||
106
EpinelPS/Controllers/AccountController.cs
Normal file
106
EpinelPS/Controllers/AccountController.cs
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EpinelPS.Controllers
|
||||||
|
{
|
||||||
|
[Route("account")]
|
||||||
|
[ApiController]
|
||||||
|
public class AccountController : ControllerBase
|
||||||
|
{
|
||||||
|
private const string BadAuthToken = "{\"msg\":\"the account does not exists!\",\"ret\":2001,\"seq\":\"123" + "\"}";
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("login")]
|
||||||
|
public string Login(string seq, [FromBody] LoginEndpoint2Req req)
|
||||||
|
{
|
||||||
|
foreach (var item in JsonDb.Instance.Users)
|
||||||
|
{
|
||||||
|
if (item.Username == req.account && item.Password == req.password)
|
||||||
|
{
|
||||||
|
var tok = CreateLauncherTokenForUser(item);
|
||||||
|
item.LastLogin = DateTime.UtcNow;
|
||||||
|
JsonDb.Save();
|
||||||
|
|
||||||
|
return "{\"expire\":" + tok.ExpirationTime + ",\"is_login\":true,\"msg\":\"Success\",\"register_time\":" + item.RegisterTime + ",\"ret\":0,\"seq\":\"" + seq + "\",\"token\":\"" + tok.Token + "\",\"uid\":\"" + item.ID + "\"}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "{\"msg\":\"the account does not exists!\",\"ret\":2001,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("sendcode")]
|
||||||
|
public string SendCode(string seq, [FromBody] SendCodeRequest req)
|
||||||
|
{
|
||||||
|
// Pretend that we send a code.
|
||||||
|
return "{\"expire_time\":898,\"msg\":\"Success\",\"ret\":0,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("codestatus")]
|
||||||
|
public string CodeStatus(string seq, [FromBody] SendCodeRequest req)
|
||||||
|
{
|
||||||
|
// Pretend that code is valid
|
||||||
|
return "{\"expire_time\":759,\"msg\":\"Success\",\"ret\":0,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("getuserinfo")]
|
||||||
|
public string GetUserInfo(string seq, [FromBody] AuthPkt2 req)
|
||||||
|
{
|
||||||
|
(User?, AccessToken?) res;
|
||||||
|
if ((res = NetUtils.GetUser(req.token)).Item1 == null) return BadAuthToken;
|
||||||
|
User user = res.Item1;
|
||||||
|
AccessToken? tok = res.Item2;
|
||||||
|
|
||||||
|
// Pretend that code is valid
|
||||||
|
return "{\"account_type\":1,\"birthday\":\"1970-01\",\"email\":\"" + user.Username + "\",\"expire\":" + tok.ExpirationTime + ",\"is_receive_email\":1,\"is_receive_email_in_night\":0,\"is_receive_video\":-1,\"lang_type\":\"en\",\"msg\":\"Success\",\"nick_name\":\"\",\"phone\":\"\",\"phone_area_code\":\"\",\"privacy_policy\":\"1\",\"privacy_update_time\":1717783097,\"region\":\"724\",\"ret\":0,\"seq\":\"" + seq + "\",\"terms_of_service\":\"\",\"terms_update_time\":0,\"uid\":\"" + user.ID + "\",\"user_agreed_dt\":\"\",\"user_agreed_pp\":\"1\",\"user_agreed_tos\":\"\",\"user_name\":\"" + user.PlayerName + "\",\"username_pass_verify\":0}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("register")]
|
||||||
|
public string RegisterAccount(string seq, [FromBody] RegisterEPReq req)
|
||||||
|
{
|
||||||
|
// check if the account already exists
|
||||||
|
foreach (var item in JsonDb.Instance.Users)
|
||||||
|
{
|
||||||
|
if (item.Username == req.account)
|
||||||
|
{
|
||||||
|
return "{\"msg\":\"send code failed; invalid account\",\"ret\":2112,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var uid = (ulong)new Random().Next(1, int.MaxValue);
|
||||||
|
|
||||||
|
// Check if we havent generated a UID that exists
|
||||||
|
foreach (var item in JsonDb.Instance.Users)
|
||||||
|
{
|
||||||
|
if (item.ID == uid)
|
||||||
|
{
|
||||||
|
uid -= (ulong)new Random().Next(1, 1221);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var user = new User() { ID = uid, Password = req.password, RegisterTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(), Username = req.account, PlayerName = "Player_" + Rng.RandomString(8) };
|
||||||
|
|
||||||
|
JsonDb.Instance.Users.Add(user);
|
||||||
|
|
||||||
|
var tok = CreateLauncherTokenForUser(user);
|
||||||
|
|
||||||
|
return "{\"expire\":" + tok.ExpirationTime + ",\"is_login\":false,\"msg\":\"Success\",\"register_time\":" + user.RegisterTime + ",\"ret\":0,\"seq\":\"" + seq + "\",\"token\":\"" + tok.Token + "\",\"uid\":\"" + user.ID + "\"}";
|
||||||
|
}
|
||||||
|
public static AccessToken CreateLauncherTokenForUser(User user)
|
||||||
|
{
|
||||||
|
// TODO: implement access token expiration
|
||||||
|
AccessToken token = new() { ExpirationTime = DateTimeOffset.UtcNow.AddYears(1).ToUnixTimeSeconds() };
|
||||||
|
token.Token = Rng.RandomString(64);
|
||||||
|
token.UserID = user.ID;
|
||||||
|
JsonDb.Instance.LauncherAccessTokens.Add(token);
|
||||||
|
JsonDb.Save();
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
98
EpinelPS/Controllers/AdminApiController.cs
Normal file
98
EpinelPS/Controllers/AdminApiController.cs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.LobbyServer;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Org.BouncyCastle.Asn1.X509;
|
||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace EpinelPS.Controllers
|
||||||
|
{
|
||||||
|
[Route("adminapi")]
|
||||||
|
[ApiController]
|
||||||
|
public class AdminApiController : ControllerBase
|
||||||
|
{
|
||||||
|
public static Dictionary<string, User> AdminAuthTokens = new();
|
||||||
|
private static MD5 md5 = MD5.Create();
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("login")]
|
||||||
|
public LoginApiResponse Login([FromBody] LoginApiBody b)
|
||||||
|
{
|
||||||
|
User? user = null;
|
||||||
|
bool nullusernames = false;
|
||||||
|
if (b.Username != null && b.Password != null)
|
||||||
|
{
|
||||||
|
var passwordHash = Convert.ToHexString(md5.ComputeHash(Encoding.ASCII.GetBytes(b.Password))).ToLower();
|
||||||
|
foreach (var item in JsonDb.Instance.Users)
|
||||||
|
{
|
||||||
|
if (item.Username == b.Username)
|
||||||
|
{
|
||||||
|
if (item.Password.ToLower() == passwordHash)
|
||||||
|
{
|
||||||
|
user = item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nullusernames = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (user == null)
|
||||||
|
{
|
||||||
|
if (nullusernames)
|
||||||
|
{
|
||||||
|
return new LoginApiResponse() { Message = "Please enter a username and password" };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new LoginApiResponse() { Message = "Username or password is incorrect" };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (user.IsAdmin)
|
||||||
|
{
|
||||||
|
var tok = CreateAuthToken(user);
|
||||||
|
HttpContext.Response.Cookies.Append("token", tok);
|
||||||
|
return new LoginApiResponse() { OK = true, Token = tok };
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new LoginApiResponse() { Message = "User is not an administrator." };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static string CreateAuthToken(User user)
|
||||||
|
{
|
||||||
|
var tok = RandomString(128);
|
||||||
|
AdminAuthTokens.Add(tok, user);
|
||||||
|
return tok;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RandomString(int length)
|
||||||
|
{
|
||||||
|
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||||
|
return new string(Enumerable.Repeat(chars, length)
|
||||||
|
.Select(s => s[new Random().Next(s.Length)]).ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
public class LoginApiBody
|
||||||
|
{
|
||||||
|
[Required]
|
||||||
|
public string Username { get; set; } = "";
|
||||||
|
[Required]
|
||||||
|
public string Password { get; set; } = "";
|
||||||
|
}
|
||||||
|
public class LoginApiResponse
|
||||||
|
{
|
||||||
|
public string Message { get; set; } = "";
|
||||||
|
public bool OK { get; set; }
|
||||||
|
public string Token { get; set; } = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
58
EpinelPS/Controllers/AdminController.cs
Normal file
58
EpinelPS/Controllers/AdminController.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using EpinelPS.Models;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
|
namespace EpinelPS.Controllers
|
||||||
|
{
|
||||||
|
[Route("admin")]
|
||||||
|
public class AdminController : Controller
|
||||||
|
{
|
||||||
|
private readonly ILogger<AdminController> _logger;
|
||||||
|
|
||||||
|
public AdminController(ILogger<AdminController> logger)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
[Route("index")]
|
||||||
|
public IActionResult Index()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
[Route("dashboard")]
|
||||||
|
public IActionResult Dashboard()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
[Route("Events")]
|
||||||
|
public IActionResult Events()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
[Route("Configuration")]
|
||||||
|
public IActionResult Configuration()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
[Route("Users")]
|
||||||
|
public IActionResult Users()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
[Route("Mail")]
|
||||||
|
public IActionResult Mail()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
[Route("Database")]
|
||||||
|
public IActionResult Database()
|
||||||
|
{
|
||||||
|
return View();
|
||||||
|
}
|
||||||
|
|
||||||
|
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
|
||||||
|
public IActionResult Error()
|
||||||
|
{
|
||||||
|
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
97
EpinelPS/Controllers/LauncherController.cs
Normal file
97
EpinelPS/Controllers/LauncherController.cs
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EpinelPS.Controllers
|
||||||
|
{
|
||||||
|
[Route("/api/v1")]
|
||||||
|
[ApiController]
|
||||||
|
public class LauncherController : Controller
|
||||||
|
{
|
||||||
|
[HttpPost]
|
||||||
|
[Route("fleet.auth.game.AuthSvr/Login")]
|
||||||
|
public string LauncherLogin()
|
||||||
|
{
|
||||||
|
return @"{
|
||||||
|
""result"": {
|
||||||
|
""error_code"": 0,
|
||||||
|
""error_message"": ""COMM_SUCC""
|
||||||
|
},
|
||||||
|
""channel"": 0,
|
||||||
|
""game_id"": ""0"",
|
||||||
|
""openid"": """",
|
||||||
|
""uid"": """",
|
||||||
|
""biz_ticket"": """",
|
||||||
|
""expire_interval"": 0,
|
||||||
|
""refresh_interval"": 0,
|
||||||
|
""login_key"": """",
|
||||||
|
""login_ticket"": """",
|
||||||
|
""third_uid"": """"
|
||||||
|
}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("fleet.repo.game.RepoSVC/GetRegion")]
|
||||||
|
public string LauncherGetRegion()
|
||||||
|
{
|
||||||
|
return @"{
|
||||||
|
""result"": {
|
||||||
|
""error_code"": 0,
|
||||||
|
""error_message"": ""success""
|
||||||
|
},
|
||||||
|
""region_info"": [
|
||||||
|
{
|
||||||
|
""game_id"": ""16601"",
|
||||||
|
""region_id"": ""10001"",
|
||||||
|
""region_name_en_us"": ""Global"",
|
||||||
|
""region_name_i18n"": """",
|
||||||
|
""region_description_en_us"": ""Nikke Global Version"",
|
||||||
|
""region_description_i18n"": """",
|
||||||
|
""bind_branches"": """",
|
||||||
|
""meta_data"": """",
|
||||||
|
""sequence"": 0,
|
||||||
|
""status"": 2,
|
||||||
|
""branch_info"": [
|
||||||
|
{
|
||||||
|
""game_id"": ""16601"",
|
||||||
|
""branch_id"": ""1"",
|
||||||
|
""branch_name"": ""Official_release"",
|
||||||
|
""branch_type"": 0,
|
||||||
|
""description"": ""正式发布环境 release包""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("fleet.repo.game.RepoSVC/GetGameLauncher")]
|
||||||
|
public string LauncherGetLauncher()
|
||||||
|
{
|
||||||
|
return @"{
|
||||||
|
""result"": {
|
||||||
|
""error_code"": 0,
|
||||||
|
""error_message"": ""COMM_SUCC""
|
||||||
|
},
|
||||||
|
""game_launcher_info"": [
|
||||||
|
{
|
||||||
|
""id"": 27,
|
||||||
|
""execute_file"": ""NIKKE\\Game\\NIKKE.exe"",
|
||||||
|
""param"": """",
|
||||||
|
""description"": ""Nikke main process"",
|
||||||
|
""os"": ""any"",
|
||||||
|
""branch_id"": 0,
|
||||||
|
""status"": 1,
|
||||||
|
""param_type"": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("fleet.repo.game.RepoSVC/GetVersion")]
|
||||||
|
public string LauncherGetVersion()
|
||||||
|
{
|
||||||
|
return System.IO.File.ReadAllText(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "gameversion.json"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
129
EpinelPS/Controllers/LevelInfiniteControlller.cs
Normal file
129
EpinelPS/Controllers/LevelInfiniteControlller.cs
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EpinelPS.Controllers
|
||||||
|
{
|
||||||
|
[Route("/v2")]
|
||||||
|
[ApiController]
|
||||||
|
public class LevelInfiniteControlller : Controller
|
||||||
|
{
|
||||||
|
private const string BadAuthToken = "{\"msg\":\"the account does not exists!\",\"ret\":2001,\"seq\":\"123" + "\"}";
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("conf/get_conf")]
|
||||||
|
public string GetConfig(string sig)
|
||||||
|
{
|
||||||
|
return "{\"conf_version\":\"102\",\"msg\":\"\",\"ret\":1,\"seq\":\"" + sig + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("auth/login")]
|
||||||
|
public string AuthLogin(string seq, [FromBody] LoginEndpoint1Req req)
|
||||||
|
{
|
||||||
|
foreach (var tok in JsonDb.Instance.LauncherAccessTokens)
|
||||||
|
{
|
||||||
|
if (tok.Token == req.channel_info.account_token)
|
||||||
|
{
|
||||||
|
var user = JsonDb.Instance.Users.Find(x => x.ID == tok.UserID);
|
||||||
|
if (user != null)
|
||||||
|
{
|
||||||
|
// todo: they use another token here, but we will reuse the same one.
|
||||||
|
// todo: use a class for this, this is a mess
|
||||||
|
return "{\"birthday\":\"1970-01\",\"channel_info\":{\"account\":\"" + user.Username + "\",\"account_plat_type\":131,\"account_token\":\"" + req.channel_info.account_token + "\",\"account_type\":1,\"account_uid\":\"" + user.ID + "\",\"expire_ts\":1721667004,\"is_login\":true,\"lang_type\":\"en\",\"phone_area_code\":\"\",\"token\":\"" + req.channel_info.account_token + "\"},\"del_account_info\":\"{\\\"ret\\\":0,\\\"msg\\\":\\\"\\\",\\\"status\\\":0,\\\"created_at\\\":\\\"0\\\",\\\"target_destroy_at\\\":\\\"0\\\",\\\"destroyed_at\\\":\\\"0\\\",\\\"err_code\\\":0,\\\"seq\\\":\\\"1719075066-0339089836-025921-1161847390\\\"}\",\"del_account_status\":0,\"del_li_account_status\":0,\"email\":\"" + user.Username + "\",\"extra_json\":{\"del_li_account_info\":\"{\\\"ret\\\":0,\\\"msg\\\":\\\"\\\",\\\"status\\\":0,\\\"created_at\\\":\\\"0\\\",\\\"target_destroy_at\\\":\\\"0\\\",\\\"destroyed_at\\\":\\\"0\\\",\\\"err_code\\\":0,\\\"seq\\\":\\\"" + seq + "\\\"}\",\"get_status_rsp\":{\"adult_age\":14,\"adult_age_map\":{},\"adult_check_status\":1,\"adult_check_status_expiration\":\"0\",\"adult_status_map\":{},\"certificate_type\":3,\"email\":\"\",\"eu_user_agree_status\":0,\"game_grade\":0,\"game_grade_map\":{},\"is_dma\":true,\"is_eea\":false,\"is_need_li_cert\":false,\"msg\":\"success\",\"need_parent_control\":0,\"need_realname_auth\":0,\"parent_certificate_status\":0,\"parent_certificate_status_expiration\":\"0\",\"parent_control_map\":{},\"qr_code_ret\":0,\"realname_auth_status\":0,\"region\":\"724\",\"ret\":0,\"ts\":\"1719075065\"},\"need_notify_rsp\":{\"game_sacc_openid\":\"\",\"game_sacc_uid\":\"\",\"has_game_sacc_openid\":false,\"has_game_sacc_uid\":false,\"has_li_openid\":true,\"has_li_uid\":true,\"is_receive_email\":1,\"is_receive_email_in_night\":0,\"li_openid\":\"" + user.ID + "\",\"li_uid\":\"2752409592679849\",\"need_notify\":false,\"user_agreed_game_dma\":\"2\",\"user_agreed_game_pp\":\"1\",\"user_agreed_game_tos\":\"1\",\"user_agreed_li_dt\":\"\",\"user_agreed_li_pp\":\"1\",\"user_agreed_li_tos\":\"\"}},\"first_login\":0,\"gender\":0,\"msg\":\"success\",\"need_name_auth\":false,\"openid\":\"" + user.ID + "\",\"pf\":\"LevelInfinite_LevelInfinite-Windows-windows-Windows-LevelInfinite-09af79d65d6e4fdf2d2569f0d365739d-" + user.ID + "\",\"pf_key\":\"abc\",\"picture_url\":\"\",\"reg_channel_dis\":\"Windows\",\"ret\":0,\"seq\":\"29080-2d28ea26-d71f-4822-9118-0156f1e2dba4-1719075060-99\",\"token\":\"" + tok.Token + "\",\"token_expire_time\":" + tok.ExpirationTime + ",\"uid\":\"" + user.ID + "\",\"user_name\":\"" + user.PlayerName + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: proper token expired message
|
||||||
|
return "{\"msg\":\"the account does not exists!\",\"ret\":2001,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("auth/auto_login")]
|
||||||
|
public string AutoLogin(string seq)
|
||||||
|
{
|
||||||
|
return "{\"del_account_info\":\"{\\\"ret\\\":0,\\\"msg\\\":\\\"\\\",\\\"status\\\":0,\\\"created_at\\\":\\\"0\\\",\\\"target_destroy_at\\\":\\\"0\\\",\\\"destroyed_at\\\":\\\"0\\\",\\\"err_code\\\":0,\\\"seq\\\":\\\"" + seq + "\\\"}\",\"del_account_status\":0,\"del_li_account_status\":0,\"extra_json\":{\"del_li_account_info\":\"{\\\"ret\\\":0,\\\"msg\\\":\\\"\\\",\\\"status\\\":0,\\\"created_at\\\":\\\"0\\\",\\\"target_destroy_at\\\":\\\"0\\\",\\\"destroyed_at\\\":\\\"0\\\",\\\"err_code\\\":0,\\\"seq\\\":\\\"" + seq + "\\\"}\",\"get_status_msg\":\"success\",\"get_status_ret\":0,\"get_status_rsp\":{\"adult_age\":14,\"adult_age_map\":{},\"adult_check_status\":1,\"adult_check_status_expiration\":\"0\",\"adult_status_map\":{},\"certificate_type\":3,\"email\":\"\",\"eu_user_agree_status\":0,\"game_grade\":0,\"game_grade_map\":{},\"is_dma\":true,\"is_eea\":false,\"is_need_li_cert\":false,\"msg\":\"success\",\"need_parent_control\":0,\"need_realname_auth\":0,\"parent_certificate_status\":0,\"parent_certificate_status_expiration\":\"0\",\"parent_control_map\":{},\"qr_code_ret\":0,\"realname_auth_status\":0,\"region\":\"724\",\"ret\":0,\"ts\":\"" + DateTimeOffset.UtcNow.ToUnixTimeSeconds()
|
||||||
|
+ "\"},\"need_notify_msg\":\"success\",\"need_notify_ret\":0,\"need_notify_rsp\":{\"has_bind_li\":true,\"is_receive_email\":1,\"is_receive_email_in_night\":0,\"user_agreed_game_dma\":\"2\",\"user_agreed_game_pp\":\"1\",\"user_agreed_game_tos\":\"1\",\"user_agreed_li_dt\":\"\",\"user_agreed_li_pp\":\"1\",\"user_agreed_li_tos\":\"\"}},\"msg\":\"success\",\"ret\":0,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("minorcer/get_status")]
|
||||||
|
public string MinorcerStatus(string seq)
|
||||||
|
{
|
||||||
|
return "{\"adult_age\":15,\"adult_age_map\":{},\"adult_check_status\":1,\"adult_check_status_expiration\":\"0\",\"adult_status_map\":{},\"certificate_type\":3,\"email\":\"\",\"eu_user_agree_status\":0,\"game_grade\":0,\"game_grade_map\":{},\"is_dma\":true,\"is_eea\":false,\"is_need_li_cert\":false,\"msg\":\"success\",\"need_parent_control\":0,\"need_realname_auth\":0,\"parent_certificate_status\":0,\"parent_certificate_status_expiration\":\"0\",\"parent_control_map\":{},\"qr_code_ret\":0,\"realname_auth_status\":0,\"region\":\"300\",\"ret\":0,\"seq\":\"" + seq + "\",\"ts\":\"1719156511\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("profile/userinfo")]
|
||||||
|
public string QueryUserInfo(string seq, [FromBody] AuthPkt2 req)
|
||||||
|
{
|
||||||
|
User? user;
|
||||||
|
if ((user = NetUtils.GetUser(req.token).Item1) == null) return BadAuthToken;
|
||||||
|
|
||||||
|
return "{\"bind_list\":[{\"channel_info\":{\"birthday\":\"1970-01\",\"email\":\"" + user.Username + "\",\"is_receive_email\":1,\"lang_type\":\"en\",\"last_login_time\":1719075003,\"nick_name\":\"\",\"phone\":\"\",\"phone_area_code\":\"\",\"region\":\"724\",\"register_account\":\"" + user.Username + "\",\"register_account_type\":1,\"register_time\":" + user.RegisterTime + ",\"seq\":\"abc\",\"uid\":\"" + user.ID + "\",\"user_name\":\"" + user.PlayerName + "\",\"username_pass_verify\":0},\"channelid\":131,\"email\":\"" + user.Username + "\",\"picture_url\":\"\",\"user_name\":\"" + user.PlayerName + "\"}],\"birthday\":\"1970-01\",\"email\":\"" + user.Username + "\",\"gender\":0,\"msg\":\"success\",\"picture_url\":\"\",\"ret\":0,\"seq\":\"" + seq + "\",\"user_name\":\"" + user.PlayerName + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("profile/query_account_info")]
|
||||||
|
public string QueryAccountInfo(string seq, [FromBody] AuthPkt req)
|
||||||
|
{
|
||||||
|
User? user;
|
||||||
|
if ((user = NetUtils.GetUser(req.channel_info.token).Item1) == null) return BadAuthToken;
|
||||||
|
|
||||||
|
// Pretend that code is valid
|
||||||
|
return "{\"game_sacc_openid\":\"\",\"game_sacc_uid\":\"\",\"has_game_sacc_openid\":false,\"has_game_sacc_uid\":false,\"has_li_openid\":false,\"has_li_uid\":true,\"is_receive_email\":-1,\"is_receive_email_in_night\":-1,\"li_openid\":\"\",\"li_uid\":\"" + user.ID + "\",\"msg\":\"success\",\"need_notify\":false,\"ret\":0,\"seq\":\"" + seq + "\",\"user_agreed_game_dma\":\"\",\"user_agreed_game_pp\":\"\",\"user_agreed_game_tos\":\"\",\"user_agreed_li_dt\":\"\",\"user_agreed_li_pp\":\"\",\"user_agreed_li_tos\":\"\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("reward/send")]
|
||||||
|
public string SendDailyReward(string seq)
|
||||||
|
{
|
||||||
|
// Level infinite pass daily reward coints, not implemented as they are inaccessible currently
|
||||||
|
return "{\"msg\":\"success\",\"ret\":0,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("profile/set_protocol")]
|
||||||
|
public string SetProtocol(string seq)
|
||||||
|
{
|
||||||
|
// Enable encryption, not used in this server.
|
||||||
|
return "{\"msg\":\"success\",\"ret\":0,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("notice/get_notice_content")]
|
||||||
|
public string GetNotices(string seq)
|
||||||
|
{
|
||||||
|
return "{\r\n \"msg\": \"success\",\r\n \"notice_list\": [\r\n {\r\n \"app_id\": \"3001001\",\r\n \"app_notice_id\": \"post-6rpvwgrdx1b\",\r\n \"area_list\": \"[\\\"81\\\",\\\"82\\\",\\\"83\\\",\\\"84\\\",\\\"85\\\"]\",\r\n \"content_list\": [\r\n {\r\n \"app_content_id\": \"post-9ilpu79xxzp\",\r\n \"content\": \"This isn't working\",\r\n \"extra_data\": \"{}\",\r\n \"id\": 48706,\r\n \"lang_type\": \"en\",\r\n \"picture_list\": [\r\n {\r\n \"extra_data\": \"{\\\"id\\\":\\\"TitleImage\\\"}\",\r\n \"hash\": \"44a99a61152b5b80a0466ff9f0cee2bc\",\r\n \"redirect_url\": \"\",\r\n \"url\": \"pnt-console-cdn.playernetwork.intlgame.com/prod/29080/notice/022681b1121a40259a575fbe587651b4.jpg\"\r\n }\r\n ],\r\n \"title\": \"New Character\",\r\n \"update_time\": 1717637493\r\n }\r\n ],\r\n \"end_time\": 1819431999,\r\n \"extra_data\": \"{\\\"NoticeType\\\":\\\"Event\\\",\\\"Order\\\":\\\"11\\\",\\\"extra_reserved\\\":\\\"{\\\\\\\"Author\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"Category\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"CreateType\\\\\\\":\\\\\\\"4\\\\\\\",\\\\\\\"IsOpenService\\\\\\\":\\\\\\\"0\\\\\\\",\\\\\\\"IsToping\\\\\\\":true,\\\\\\\"Keyword\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"Sort\\\\\\\":\\\\\\\"\\\\\\\",\\\\\\\"TopEnd\\\\\\\":\\\\\\\"2030-01-01 00:00:01\\\\\\\",\\\\\\\"TopStart\\\\\\\":\\\\\\\"2000-01-01 00:00:01\\\\\\\"}\\\"}\",\r\n \"id\": 7560,\r\n \"picture_list\": [],\r\n \"start_time\": 1717617599,\r\n \"status\": 1,\r\n \"update_time\": 1717637494\r\n }\r\n ],\r\n \"ret\": 0,\r\n \"seq\": \"" + seq + "\"\r\n}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("lbs/ipregion")]
|
||||||
|
public string GetIpRegion(string seq)
|
||||||
|
{
|
||||||
|
return "{\"alpha2\":\"GR\",\"extra_json\":{\"certificate_type_map\":{}},\"msg\":\"success\",\"region\":\"300\",\"ret\":0,\"seq\":\"" + seq + "\",\"timestamp\":324234322}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("gnconfig/acquire_config")]
|
||||||
|
public string AcquireConfig(string seq)
|
||||||
|
{
|
||||||
|
return "{\"ret\":23111202,\"msg\":\"no matched config error( [match logic]no match )\",\"rule_id\":\"\",\"resource_list\":\"\",\"sdk_enable\":0,\"sdk_debug_enable\":0,\"report_log_enable\":0,\"log_level\":0,\"inner_seq\":\"" + seq + "\",\"ab_test\":{\"id\":\"\",\"group\":\"\"},\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
[Route("profile/get_bind_info")]
|
||||||
|
public string GetProfileBindInfo(string seq, [FromBody] AuthPkt req)
|
||||||
|
{
|
||||||
|
User? user;
|
||||||
|
if ((user = NetUtils.GetUser(req.channel_info.token).Item1) == null) return BadAuthToken;
|
||||||
|
|
||||||
|
return "{\"bind_list\":[{\"bind_ts\":1717783095,\"channel_info\":{\"birthday\":\"1970-01\",\"email\":\"" + user.Username + "\",\"is_receive_email\":1,\"lang_type\":\"en\",\"last_login_time\":171000000,\"nick_name\":\"\",\"phone\":\"\",\"phone_area_code\":\"\",\"region\":\"724\",\"register_account\":\"" + user.Username + "\",\"register_account_type\":1,\"register_time\":" + user.RegisterTime + ",\"seq\":\"" + seq + "\",\"uid\":\"2752409592679849\",\"user_name\":\"" + user.PlayerName + "\",\"username_pass_verify\":0},\"channelid\":131,\"email\":\"" + user.Username + "\",\"history_scopes\":[],\"is_primary\":1,\"picture_url\":\"\",\"user_name\":\"" + user.PlayerName + "\"}],\"create_ts\":" + user.RegisterTime + ",\"last_login_ts\":171000000,\"msg\":\"success\",\"ret\":0,\"seq\":\"" + seq + "\"}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
18
EpinelPS/Controllers/LobbyApiController.cs
Normal file
18
EpinelPS/Controllers/LobbyApiController.cs
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
using EpinelPS.LobbyServer;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace EpinelPS.Controllers
|
||||||
|
{
|
||||||
|
[Route("v1")]
|
||||||
|
[ApiController]
|
||||||
|
public class LobbyApiController : ControllerBase
|
||||||
|
{
|
||||||
|
[HttpPost]
|
||||||
|
[Route("{**all}", Order = int.MaxValue)]
|
||||||
|
[Consumes("application/octet-stream+protobuf")]
|
||||||
|
public async Task CatchAll(string all)
|
||||||
|
{
|
||||||
|
await LobbyHandler.DispatchSingle(HttpContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
using Newtonsoft.Json;
|
using EpinelPS.LobbyServer;
|
||||||
using nksrv.LobbyServer;
|
using EpinelPS.StaticInfo;
|
||||||
using nksrv.StaticInfo;
|
using EpinelPS.Utils;
|
||||||
using nksrv.Utils;
|
using Newtonsoft.Json;
|
||||||
using Swan.Logging;
|
|
||||||
|
|
||||||
namespace nksrv.Database
|
namespace EpinelPS.Database
|
||||||
{
|
{
|
||||||
public class AccessToken
|
public class AccessToken
|
||||||
{
|
{
|
||||||
@@ -64,6 +63,21 @@ namespace nksrv.Database
|
|||||||
public List<string> CompletedScenarios = new();
|
public List<string> CompletedScenarios = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SynchroSlot
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Index of slot, 1 based
|
||||||
|
/// </summary>
|
||||||
|
public int Slot;
|
||||||
|
/// <summary>
|
||||||
|
/// Character CSN
|
||||||
|
/// </summary>
|
||||||
|
public long CharacterSerialNumber;
|
||||||
|
/// <summary>
|
||||||
|
/// Time when slot cooldown expires
|
||||||
|
/// </summary>
|
||||||
|
public long AvailableAt;
|
||||||
|
}
|
||||||
public class User
|
public class User
|
||||||
{
|
{
|
||||||
// User info
|
// User info
|
||||||
@@ -77,6 +91,7 @@ namespace nksrv.Database
|
|||||||
public string Nickname = "SomePlayer";
|
public string Nickname = "SomePlayer";
|
||||||
public int ProfileIconId = 39900;
|
public int ProfileIconId = 39900;
|
||||||
public bool ProfileIconIsPrism = false;
|
public bool ProfileIconIsPrism = false;
|
||||||
|
public int ProfileFrame = 1;
|
||||||
public bool IsAdmin = false;
|
public bool IsAdmin = false;
|
||||||
|
|
||||||
public bool IsBanned = false;
|
public bool IsBanned = false;
|
||||||
@@ -93,6 +108,9 @@ namespace nksrv.Database
|
|||||||
public Dictionary<CurrencyType, long> Currency = new() {
|
public Dictionary<CurrencyType, long> Currency = new() {
|
||||||
{ CurrencyType.ContentStamina, 2 }
|
{ CurrencyType.ContentStamina, 2 }
|
||||||
};
|
};
|
||||||
|
public List<SynchroSlot> SynchroSlots = new List<SynchroSlot>();
|
||||||
|
public bool SynchroDeviceUpgraded = false;
|
||||||
|
public int SynchroDeviceLevel = 200;
|
||||||
|
|
||||||
public List<ItemData> Items = new();
|
public List<ItemData> Items = new();
|
||||||
public List<Character> Characters = [];
|
public List<Character> Characters = [];
|
||||||
@@ -112,9 +130,12 @@ namespace nksrv.Database
|
|||||||
public List<int> CompletedTacticAcademyLessons = [];
|
public List<int> CompletedTacticAcademyLessons = [];
|
||||||
public List<int> CompletedSideStoryStages = new();
|
public List<int> CompletedSideStoryStages = new();
|
||||||
|
|
||||||
|
public List<int> Memorial = new();
|
||||||
|
public List<int> JukeboxBgm = new();
|
||||||
|
|
||||||
// Event data
|
// Event data
|
||||||
public Dictionary<int, EventData> EventInfo = new();
|
public Dictionary<int, EventData> EventInfo = new();
|
||||||
|
|
||||||
public void SetQuest(int tid, bool recievedReward)
|
public void SetQuest(int tid, bool recievedReward)
|
||||||
{
|
{
|
||||||
if (MainQuestData.ContainsKey(tid))
|
if (MainQuestData.ContainsKey(tid))
|
||||||
@@ -139,7 +160,17 @@ namespace nksrv.Database
|
|||||||
|
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
public int GenerateUniqueCharacterId()
|
||||||
|
{
|
||||||
|
var num = Rng.RandomId();
|
||||||
|
|
||||||
|
while (Characters.Any(x => x.Csn == num))
|
||||||
|
{
|
||||||
|
num = Rng.RandomId();
|
||||||
|
}
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
public bool IsStageCompleted(int id, bool isNorm)
|
public bool IsStageCompleted(int id, bool isNorm)
|
||||||
{
|
{
|
||||||
foreach (var item in FieldInfoNew)
|
foreach (var item in FieldInfoNew)
|
||||||
@@ -195,6 +226,55 @@ namespace nksrv.Database
|
|||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool HasCharacter(int c)
|
||||||
|
{
|
||||||
|
return Characters.Any(x => x.Tid == c);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Character? GetCharacterBySerialNumber(long value)
|
||||||
|
{
|
||||||
|
return Characters.Where(x => x.Csn == value).FirstOrDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
internal bool GetSynchro(long csn)
|
||||||
|
{
|
||||||
|
return SynchroSlots.Where(x => x.CharacterSerialNumber == csn).Count() >= 1;
|
||||||
|
}
|
||||||
|
internal int GetCharacterLevel(int csn)
|
||||||
|
{
|
||||||
|
var c = GetCharacterBySerialNumber(csn);
|
||||||
|
if (c == null) throw new Exception("failed to lookup character");
|
||||||
|
|
||||||
|
return GetCharacterLevel(csn, c.Level);
|
||||||
|
}
|
||||||
|
internal int GetCharacterLevel(int csn, int characterLevel)
|
||||||
|
{
|
||||||
|
foreach (var item in SynchroSlots)
|
||||||
|
{
|
||||||
|
if (item.CharacterSerialNumber == csn)
|
||||||
|
{
|
||||||
|
return GetSynchroLevel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return characterLevel;
|
||||||
|
}
|
||||||
|
internal int GetSynchroLevel()
|
||||||
|
{
|
||||||
|
if (SynchroDeviceUpgraded)
|
||||||
|
return SynchroDeviceLevel;
|
||||||
|
var highestLevelCharacters = Characters.OrderByDescending(x => x.Level).Take(5).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
if (highestLevelCharacters.Count > 0)
|
||||||
|
{
|
||||||
|
return highestLevelCharacters.Last().Level;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
public class CoreInfo
|
public class CoreInfo
|
||||||
{
|
{
|
||||||
@@ -218,7 +298,7 @@ namespace nksrv.Database
|
|||||||
{
|
{
|
||||||
if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + "/db.json"))
|
if (!File.Exists(AppDomain.CurrentDomain.BaseDirectory + "/db.json"))
|
||||||
{
|
{
|
||||||
"users: warning: configuration not found, writing default data".Warn();
|
Console.WriteLine("users: warning: configuration not found, writing default data");
|
||||||
Instance = new CoreInfo();
|
Instance = new CoreInfo();
|
||||||
Save();
|
Save();
|
||||||
}
|
}
|
||||||
@@ -286,7 +366,7 @@ namespace nksrv.Database
|
|||||||
Save();
|
Save();
|
||||||
|
|
||||||
ValidateDb();
|
ValidateDb();
|
||||||
"Loaded db".Info();
|
Console.WriteLine("Loaded db");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -303,7 +383,7 @@ namespace nksrv.Database
|
|||||||
{
|
{
|
||||||
if (c.Level > 1000)
|
if (c.Level > 1000)
|
||||||
{
|
{
|
||||||
$"Warning: Character level for character {c.Tid} cannot be above 1000, setting to 1000".Warn();
|
Console.WriteLine($"Warning: Character level for character {c.Tid} cannot be above 1000, setting to 1000");
|
||||||
c.Level = 1000;
|
c.Level = 1000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
@@ -14,11 +14,11 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ASodium" Version="0.6.1" />
|
<PackageReference Include="ASodium" Version="0.6.1" />
|
||||||
<PackageReference Include="DnsClient" Version="1.8.0" />
|
<PackageReference Include="DnsClient" Version="1.8.0" />
|
||||||
<PackageReference Include="EmbedIO" Version="3.5.2" />
|
|
||||||
<PackageReference Include="Google.Api.CommonProtos" Version="2.15.0" />
|
<PackageReference Include="Google.Api.CommonProtos" Version="2.15.0" />
|
||||||
<PackageReference Include="Google.Protobuf.Tools" Version="3.27.1" />
|
<PackageReference Include="Google.Protobuf.Tools" Version="3.27.3" />
|
||||||
<PackageReference Include="Grpc.AspNetCore" Version="2.63.0" />
|
<PackageReference Include="Grpc.AspNetCore" Version="2.65.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
|
<PackageReference Include="Paseto.Core" Version="1.3.0" />
|
||||||
<PackageReference Include="PeterO.Cbor" Version="5.0.0-alpha1" />
|
<PackageReference Include="PeterO.Cbor" Version="5.0.0-alpha1" />
|
||||||
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
<PackageReference Include="SharpZipLib" Version="1.4.2" />
|
||||||
<PackageReference Include="Sodium.Core" Version="1.4.0-preview.1" />
|
<PackageReference Include="Sodium.Core" Version="1.4.0-preview.1" />
|
||||||
@@ -30,10 +30,18 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Protos\intercept.proto" />
|
<Content Remove="Views\Shared\error.cshtml" />
|
||||||
<None Remove="Protos\liberate.proto" />
|
</ItemGroup>
|
||||||
<None Remove="Protos\shop.proto" />
|
|
||||||
<None Remove="Protos\sidestory.proto" />
|
<ItemGroup>
|
||||||
|
<None Include="Views\Shared\error.cshtml" />
|
||||||
|
<None Include="wwwroot\admin\assets\login.css" />
|
||||||
|
<None Include="wwwroot\admin\assets\login.jpg" />
|
||||||
|
<None Include="wwwroot\admin\assets\style.css" />
|
||||||
|
<None Include="wwwroot\admin\dashbrd.html" />
|
||||||
|
<None Include="wwwroot\admin\index.html" />
|
||||||
|
<None Include="wwwroot\admin\nav.html" />
|
||||||
|
<None Include="wwwroot\nikke_launcher\index.html" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -46,7 +54,7 @@
|
|||||||
<None Update="site.pfx">
|
<None Update="site.pfx">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Update="www\**\*">
|
<None Update="wwwroot\**\*">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -1,29 +1,16 @@
|
|||||||
using ICSharpCode.SharpZipLib.Zip;
|
using EpinelPS.Utils;
|
||||||
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using nksrv.Utils;
|
using System.Diagnostics;
|
||||||
using Swan.Logging;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
namespace nksrv.StaticInfo
|
namespace EpinelPS.StaticInfo
|
||||||
{
|
{
|
||||||
/// <summary>
|
public class GameData
|
||||||
/// "Static data" which is what the game calls it, contains data such as map info, characters, quests, rewards and a lot more.
|
|
||||||
/// </summary>
|
|
||||||
public class StaticDataParser
|
|
||||||
{
|
{
|
||||||
// These fields were extracted from the game.
|
private static GameData? _instance;
|
||||||
public static byte[] PresharedKey = [0xCB, 0xC2, 0x1C, 0x6F, 0xF3, 0xF5, 0x07, 0xF5, 0x05, 0xBA, 0xCA, 0xD4, 0x98, 0x28, 0x84, 0x1F, 0xF0, 0xD1, 0x38, 0xC7, 0x61, 0xDF, 0xD6, 0xE6, 0x64, 0x9A, 0x85, 0x13, 0x3E, 0x1A, 0x6A, 0x0C, 0x68, 0x0E, 0x2B, 0xC4, 0xDF, 0x72, 0xF8, 0xC6, 0x55, 0xE4, 0x7B, 0x14, 0x36, 0x18, 0x3B, 0xA7, 0xD1, 0x20, 0x81, 0x22, 0xD1, 0xA9, 0x18, 0x84, 0x65, 0x13, 0x0B, 0xED, 0xA3, 0x00, 0xE5, 0xD9];
|
public static GameData Instance
|
||||||
public static RSAParameters RSAParameters = new RSAParameters()
|
|
||||||
{
|
|
||||||
Exponent = [0x01, 0x00, 0x01],
|
|
||||||
Modulus = [0x89, 0xD6, 0x66, 0x00, 0x7D, 0xFC, 0x7D, 0xCE, 0x83, 0xA6, 0x62, 0xE3, 0x1A, 0x5E, 0x9A, 0x53, 0xC7, 0x8A, 0x27, 0xF3, 0x67, 0xC1, 0xF3, 0xD4, 0x37, 0xFE, 0x50, 0x6D, 0x38, 0x45, 0xDF, 0x7E, 0x73, 0x5C, 0xF4, 0x9D, 0x40, 0x4C, 0x8C, 0x63, 0x21, 0x97, 0xDF, 0x46, 0xFF, 0xB2, 0x0D, 0x0E, 0xDB, 0xB2, 0x72, 0xB4, 0xA8, 0x42, 0xCD, 0xEE, 0x48, 0x06, 0x74, 0x4F, 0xE9, 0x56, 0x6E, 0x9A, 0xB1, 0x60, 0x18, 0xBC, 0x86, 0x0B, 0xB6, 0x32, 0xA7, 0x51, 0x00, 0x85, 0x7B, 0xC8, 0x72, 0xCE, 0x53, 0x71, 0x3F, 0x64, 0xC2, 0x25, 0x58, 0xEF, 0xB0, 0xC9, 0x1D, 0xE3, 0xB3, 0x8E, 0xFC, 0x55, 0xCF, 0x8B, 0x02, 0xA5, 0xC8, 0x1E, 0xA7, 0x0E, 0x26, 0x59, 0xA8, 0x33, 0xA5, 0xF1, 0x11, 0xDB, 0xCB, 0xD3, 0xA7, 0x1F, 0xB1, 0xC6, 0x10, 0x39, 0xC8, 0x31, 0x1D, 0x60, 0xDB, 0x0D, 0xA4, 0x13, 0x4B, 0x2B, 0x0E, 0xF3, 0x6F, 0x69, 0xCB, 0xA8, 0x62, 0x03, 0x69, 0xE6, 0x95, 0x6B, 0x8D, 0x11, 0xF6, 0xAF, 0xD9, 0xC2, 0x27, 0x3A, 0x32, 0x12, 0x05, 0xC3, 0xB1, 0xE2, 0x81, 0x4B, 0x40, 0xF8, 0x8B, 0x8D, 0xBA, 0x1F, 0x55, 0x60, 0x2C, 0x09, 0xC6, 0xED, 0x73, 0x96, 0x32, 0xAF, 0x5F, 0xEE, 0x8F, 0xEB, 0x5B, 0x93, 0xCF, 0x73, 0x13, 0x15, 0x6B, 0x92, 0x7B, 0x27, 0x0A, 0x13, 0xF0, 0x03, 0x4D, 0x6F, 0x5E, 0x40, 0x7B, 0x9B, 0xD5, 0xCE, 0xFC, 0x04, 0x97, 0x7E, 0xAA, 0xA3, 0x53, 0x2A, 0xCF, 0xD2, 0xD5, 0xCF, 0x52, 0xB2, 0x40, 0x61, 0x28, 0xB1, 0xA6, 0xF6, 0x78, 0xFB, 0x69, 0x9A, 0x85, 0xD6, 0xB9, 0x13, 0x14, 0x6D, 0xC4, 0x25, 0x36, 0x17, 0xDB, 0x54, 0x0C, 0xD8, 0x77, 0x80, 0x9A, 0x00, 0x62, 0x83, 0xDD, 0xB0, 0x06, 0x64, 0xD0, 0x81, 0x5B, 0x0D, 0x23, 0x9E, 0x88, 0xBD],
|
|
||||||
DP = null
|
|
||||||
};
|
|
||||||
|
|
||||||
// Fields
|
|
||||||
private static StaticDataParser? _instance;
|
|
||||||
public static StaticDataParser Instance
|
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@@ -37,35 +24,40 @@ namespace nksrv.StaticInfo
|
|||||||
}
|
}
|
||||||
private ZipFile MainZip;
|
private ZipFile MainZip;
|
||||||
private MemoryStream ZipStream;
|
private MemoryStream ZipStream;
|
||||||
private JArray questDataRecords;
|
private Dictionary<int, MainQuestCompletionRecord> questDataRecords;
|
||||||
private JArray stageDataRecords;
|
private Dictionary<int, CampaignStageRecord> stageDataRecords;
|
||||||
private JArray rewardDataRecords;
|
private Dictionary<int, RewardTableRecord> rewardDataRecords;
|
||||||
private JArray userExpDataRecords;
|
private JArray userExpDataRecords;
|
||||||
private JArray chapterCampaignData;
|
private Dictionary<int, CampaignChapterRecord> chapterCampaignData;
|
||||||
private JArray characterCostumeTable;
|
private JArray characterCostumeTable;
|
||||||
private JArray characterTable;
|
private Dictionary<int, CharacterRecord> characterTable;
|
||||||
private JArray tutorialTable;
|
private Dictionary<int, ClearedTutorialData> tutorialTable;
|
||||||
private JArray itemEquipTable;
|
private Dictionary<int, ItemEquipRecord> itemEquipTable;
|
||||||
private Dictionary<string, JArray> FieldMapData = [];
|
private Dictionary<string, JArray> FieldMapData = [];
|
||||||
private Dictionary<int, CharacterLevelData> LevelData = [];
|
private Dictionary<int, CharacterLevelData> LevelData = [];
|
||||||
private Dictionary<int, TacticAcademyLessonRecord> TacticAcademyLessons = [];
|
private Dictionary<int, TacticAcademyLessonRecord> TacticAcademyLessons = [];
|
||||||
public Dictionary<int, int> SidestoryRewardTable = [];
|
public Dictionary<int, int> SidestoryRewardTable = [];
|
||||||
|
public Dictionary<string, int> PositionReward = new Dictionary<string, int>();
|
||||||
|
public Dictionary<int, FieldItemRecord> FieldItems = [];
|
||||||
|
|
||||||
public byte[] Sha256Hash;
|
public byte[] Sha256Hash;
|
||||||
public int Size;
|
public int Size;
|
||||||
|
|
||||||
static async Task<StaticDataParser> BuildAsync()
|
static async Task<GameData> BuildAsync()
|
||||||
{
|
{
|
||||||
Logger.Info("Decrypting static data");
|
|
||||||
await Load();
|
await Load();
|
||||||
|
|
||||||
Logger.Info("Loading static data");
|
Console.WriteLine("Preparing");
|
||||||
|
var stopWatch = new Stopwatch();
|
||||||
|
stopWatch.Start();
|
||||||
await Instance.Parse();
|
await Instance.Parse();
|
||||||
|
|
||||||
|
stopWatch.Stop();
|
||||||
|
Console.WriteLine("Preparing took " + stopWatch.Elapsed);
|
||||||
return Instance;
|
return Instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StaticDataParser(string filePath)
|
public GameData(string filePath)
|
||||||
{
|
{
|
||||||
if (!File.Exists(filePath)) throw new ArgumentException("Static data file must exist", nameof(filePath));
|
if (!File.Exists(filePath)) throw new ArgumentException("Static data file must exist", nameof(filePath));
|
||||||
|
|
||||||
@@ -85,16 +77,23 @@ namespace nksrv.StaticInfo
|
|||||||
Sha256Hash = SHA256.HashData(rawBytes);
|
Sha256Hash = SHA256.HashData(rawBytes);
|
||||||
Size = rawBytes.Length;
|
Size = rawBytes.Length;
|
||||||
|
|
||||||
DecryptStaticDataAndLoadZip(filePath);
|
LoadGameData(filePath);
|
||||||
if (MainZip == null) throw new Exception("failed to read zip file");
|
if (MainZip == null) throw new Exception("failed to read zip file");
|
||||||
}
|
}
|
||||||
#region Decryption
|
#region Data loading
|
||||||
private void DecryptStaticDataAndLoadZip(string file)
|
private static byte[] PresharedValue = [0xCB, 0xC2, 0x1C, 0x6F, 0xF3, 0xF5, 0x07, 0xF5, 0x05, 0xBA, 0xCA, 0xD4, 0x98, 0x28, 0x84, 0x1F, 0xF0, 0xD1, 0x38, 0xC7, 0x61, 0xDF, 0xD6, 0xE6, 0x64, 0x9A, 0x85, 0x13, 0x3E, 0x1A, 0x6A, 0x0C, 0x68, 0x0E, 0x2B, 0xC4, 0xDF, 0x72, 0xF8, 0xC6, 0x55, 0xE4, 0x7B, 0x14, 0x36, 0x18, 0x3B, 0xA7, 0xD1, 0x20, 0x81, 0x22, 0xD1, 0xA9, 0x18, 0x84, 0x65, 0x13, 0x0B, 0xED, 0xA3, 0x00, 0xE5, 0xD9];
|
||||||
|
private static RSAParameters LoadParameters = new RSAParameters()
|
||||||
|
{
|
||||||
|
Exponent = [0x01, 0x00, 0x01],
|
||||||
|
Modulus = [0x89, 0xD6, 0x66, 0x00, 0x7D, 0xFC, 0x7D, 0xCE, 0x83, 0xA6, 0x62, 0xE3, 0x1A, 0x5E, 0x9A, 0x53, 0xC7, 0x8A, 0x27, 0xF3, 0x67, 0xC1, 0xF3, 0xD4, 0x37, 0xFE, 0x50, 0x6D, 0x38, 0x45, 0xDF, 0x7E, 0x73, 0x5C, 0xF4, 0x9D, 0x40, 0x4C, 0x8C, 0x63, 0x21, 0x97, 0xDF, 0x46, 0xFF, 0xB2, 0x0D, 0x0E, 0xDB, 0xB2, 0x72, 0xB4, 0xA8, 0x42, 0xCD, 0xEE, 0x48, 0x06, 0x74, 0x4F, 0xE9, 0x56, 0x6E, 0x9A, 0xB1, 0x60, 0x18, 0xBC, 0x86, 0x0B, 0xB6, 0x32, 0xA7, 0x51, 0x00, 0x85, 0x7B, 0xC8, 0x72, 0xCE, 0x53, 0x71, 0x3F, 0x64, 0xC2, 0x25, 0x58, 0xEF, 0xB0, 0xC9, 0x1D, 0xE3, 0xB3, 0x8E, 0xFC, 0x55, 0xCF, 0x8B, 0x02, 0xA5, 0xC8, 0x1E, 0xA7, 0x0E, 0x26, 0x59, 0xA8, 0x33, 0xA5, 0xF1, 0x11, 0xDB, 0xCB, 0xD3, 0xA7, 0x1F, 0xB1, 0xC6, 0x10, 0x39, 0xC8, 0x31, 0x1D, 0x60, 0xDB, 0x0D, 0xA4, 0x13, 0x4B, 0x2B, 0x0E, 0xF3, 0x6F, 0x69, 0xCB, 0xA8, 0x62, 0x03, 0x69, 0xE6, 0x95, 0x6B, 0x8D, 0x11, 0xF6, 0xAF, 0xD9, 0xC2, 0x27, 0x3A, 0x32, 0x12, 0x05, 0xC3, 0xB1, 0xE2, 0x81, 0x4B, 0x40, 0xF8, 0x8B, 0x8D, 0xBA, 0x1F, 0x55, 0x60, 0x2C, 0x09, 0xC6, 0xED, 0x73, 0x96, 0x32, 0xAF, 0x5F, 0xEE, 0x8F, 0xEB, 0x5B, 0x93, 0xCF, 0x73, 0x13, 0x15, 0x6B, 0x92, 0x7B, 0x27, 0x0A, 0x13, 0xF0, 0x03, 0x4D, 0x6F, 0x5E, 0x40, 0x7B, 0x9B, 0xD5, 0xCE, 0xFC, 0x04, 0x97, 0x7E, 0xAA, 0xA3, 0x53, 0x2A, 0xCF, 0xD2, 0xD5, 0xCF, 0x52, 0xB2, 0x40, 0x61, 0x28, 0xB1, 0xA6, 0xF6, 0x78, 0xFB, 0x69, 0x9A, 0x85, 0xD6, 0xB9, 0x13, 0x14, 0x6D, 0xC4, 0x25, 0x36, 0x17, 0xDB, 0x54, 0x0C, 0xD8, 0x77, 0x80, 0x9A, 0x00, 0x62, 0x83, 0xDD, 0xB0, 0x06, 0x64, 0xD0, 0x81, 0x5B, 0x0D, 0x23, 0x9E, 0x88, 0xBD],
|
||||||
|
DP = null
|
||||||
|
};
|
||||||
|
private void LoadGameData(string file)
|
||||||
{
|
{
|
||||||
using var fileStream = File.Open(file, FileMode.Open, FileAccess.Read);
|
using var fileStream = File.Open(file, FileMode.Open, FileAccess.Read);
|
||||||
|
|
||||||
var keyDecryptor = new Rfc2898DeriveBytes(PresharedKey, GameConfig.Root.StaticData.GetSalt2Bytes(), 10000, HashAlgorithmName.SHA256);
|
var a = new Rfc2898DeriveBytes(PresharedValue, GameConfig.Root.StaticData.GetSalt2Bytes(), 10000, HashAlgorithmName.SHA256);
|
||||||
var key2 = keyDecryptor.GetBytes(32);
|
var key2 = a.GetBytes(32);
|
||||||
|
|
||||||
byte[] decryptionKey = key2[0..16];
|
byte[] decryptionKey = key2[0..16];
|
||||||
byte[] iv = key2[16..32];
|
byte[] iv = key2[16..32];
|
||||||
@@ -105,22 +104,18 @@ namespace nksrv.StaticInfo
|
|||||||
aes.Key = decryptionKey;
|
aes.Key = decryptionKey;
|
||||||
aes.IV = iv;
|
aes.IV = iv;
|
||||||
var transform = aes.CreateDecryptor();
|
var transform = aes.CreateDecryptor();
|
||||||
|
|
||||||
// Decryption layer 1
|
|
||||||
using CryptoStream stream = new CryptoStream(fileStream, transform, CryptoStreamMode.Read);
|
using CryptoStream stream = new CryptoStream(fileStream, transform, CryptoStreamMode.Read);
|
||||||
|
|
||||||
using MemoryStream ms = new MemoryStream();
|
using MemoryStream ms = new MemoryStream();
|
||||||
stream.CopyTo(ms);
|
stream.CopyTo(ms);
|
||||||
|
|
||||||
var bytes = ms.ToArray();
|
var bytes = ms.ToArray();
|
||||||
|
|
||||||
// Decryption of layer 2
|
|
||||||
var zip = new ZipFile(ms, false);
|
var zip = new ZipFile(ms, false);
|
||||||
|
|
||||||
var signEntry = zip.GetEntry("sign");
|
var signEntry = zip.GetEntry("sign");
|
||||||
if (signEntry == null) throw new Exception("Sign entry not found in decrypted static data pack");
|
if (signEntry == null) throw new Exception("error 1");
|
||||||
var dataEntry = zip.GetEntry("data");
|
var dataEntry = zip.GetEntry("data");
|
||||||
if (dataEntry == null) throw new Exception("Data entry not found in decrypted static data pack");
|
if (dataEntry == null) throw new Exception("error 2");
|
||||||
|
|
||||||
var signStream = zip.GetInputStream(signEntry);
|
var signStream = zip.GetInputStream(signEntry);
|
||||||
var dataStream = zip.GetInputStream(dataEntry);
|
var dataStream = zip.GetInputStream(dataEntry);
|
||||||
@@ -132,28 +127,26 @@ namespace nksrv.StaticInfo
|
|||||||
dataStream.CopyTo(dataMs);
|
dataStream.CopyTo(dataMs);
|
||||||
dataMs.Position = 0;
|
dataMs.Position = 0;
|
||||||
|
|
||||||
var rsa = RSA.Create(RSAParameters);
|
var rsa = RSA.Create(LoadParameters);
|
||||||
if (!rsa.VerifyData(dataMs, signMs.ToArray(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
|
if (!rsa.VerifyData(dataMs, signMs.ToArray(), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1))
|
||||||
throw new Exception("failed to decrypt static data (round 2)");
|
throw new Exception("error 3");
|
||||||
|
|
||||||
dataMs.Position = 0;
|
dataMs.Position = 0;
|
||||||
|
var keyDecryptor2 = new Rfc2898DeriveBytes(PresharedValue, GameConfig.Root.StaticData.GetSalt1Bytes(), 10000, HashAlgorithmName.SHA256);
|
||||||
// Decryption of layer 3
|
|
||||||
var keyDecryptor2 = new Rfc2898DeriveBytes(PresharedKey, GameConfig.Root.StaticData.GetSalt1Bytes(), 10000, HashAlgorithmName.SHA256);
|
|
||||||
var key3 = keyDecryptor2.GetBytes(32);
|
var key3 = keyDecryptor2.GetBytes(32);
|
||||||
|
|
||||||
byte[] decryptionKey2 = key3[0..16];
|
byte[] val2 = key3[0..16];
|
||||||
byte[] iv2 = key3[16..32];
|
byte[] iv2 = key3[16..32];
|
||||||
|
|
||||||
ZipStream = new MemoryStream();
|
ZipStream = new MemoryStream();
|
||||||
AesCtrTransform(decryptionKey2, iv2, dataMs, ZipStream);
|
DoTransformation(val2, iv2, dataMs, ZipStream);
|
||||||
|
|
||||||
ZipStream.Position = 0;
|
ZipStream.Position = 0;
|
||||||
|
|
||||||
MainZip = new ZipFile(ZipStream, false);
|
MainZip = new ZipFile(ZipStream, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AesCtrTransform(byte[] key, byte[] salt, Stream inputStream, Stream outputStream)
|
public static void DoTransformation(byte[] key, byte[] salt, Stream inputStream, Stream outputStream)
|
||||||
{
|
{
|
||||||
SymmetricAlgorithm aes = Aes.Create();
|
SymmetricAlgorithm aes = Aes.Create();
|
||||||
aes.Mode = CipherMode.ECB;
|
aes.Mode = CipherMode.ECB;
|
||||||
@@ -211,7 +204,23 @@ namespace nksrv.StaticInfo
|
|||||||
_instance = new(targetFile);
|
_instance = new(targetFile);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
private async Task<T> LoadZip<T>(string entry, ProgressBar bar)
|
||||||
|
{
|
||||||
|
var mainQuestData = MainZip.GetEntry(entry);
|
||||||
|
if (mainQuestData == null) throw new Exception(entry + " does not exist in static data");
|
||||||
|
|
||||||
|
using StreamReader mainQuestReader = new StreamReader(MainZip.GetInputStream(mainQuestData));
|
||||||
|
var mainQuestDataString = await mainQuestReader.ReadToEndAsync();
|
||||||
|
|
||||||
|
|
||||||
|
var questdata = JsonConvert.DeserializeObject<T>(mainQuestDataString);
|
||||||
|
if (questdata == null) throw new Exception("failed to parse " + entry);
|
||||||
|
|
||||||
|
currentFile++;
|
||||||
|
bar.Report((double)currentFile / totalFiles);
|
||||||
|
|
||||||
|
return questdata;
|
||||||
|
}
|
||||||
private async Task<JArray> LoadZip(string entry, ProgressBar bar)
|
private async Task<JArray> LoadZip(string entry, ProgressBar bar)
|
||||||
{
|
{
|
||||||
var mainQuestData = MainZip.GetEntry(entry);
|
var mainQuestData = MainZip.GetEntry(entry);
|
||||||
@@ -232,21 +241,58 @@ namespace nksrv.StaticInfo
|
|||||||
|
|
||||||
return records;
|
return records;
|
||||||
}
|
}
|
||||||
int totalFiles = 12;
|
int totalFiles = 14;
|
||||||
int currentFile = 0;
|
int currentFile = 0;
|
||||||
|
|
||||||
public async Task Parse()
|
public async Task Parse()
|
||||||
{
|
{
|
||||||
using var progress = new ProgressBar();
|
using var progress = new ProgressBar();
|
||||||
|
|
||||||
questDataRecords = await LoadZip("MainQuestTable.json", progress);
|
var questDataRecords = await LoadZip<MainQuestCompletionTable>("MainQuestTable.json", progress);
|
||||||
stageDataRecords = await LoadZip("CampaignStageTable.json", progress);
|
foreach (var obj in questDataRecords.records)
|
||||||
rewardDataRecords = await LoadZip("RewardTable.json", progress);
|
{
|
||||||
|
this.questDataRecords.Add(obj.id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
var stageDataRecords = await LoadZip<CampaignStageTable>("CampaignStageTable.json", progress);
|
||||||
|
foreach (var obj in stageDataRecords.records)
|
||||||
|
{
|
||||||
|
this.stageDataRecords.Add(obj.id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
var rewardDataRecords = await LoadZip<RewardTable>("RewardTable.json", progress);
|
||||||
|
foreach (var obj in rewardDataRecords.records)
|
||||||
|
{
|
||||||
|
this.rewardDataRecords.Add(obj.id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
var chapterCampaignData = await LoadZip<CampaignChapterTable>("CampaignChapterTable.json", progress);
|
||||||
|
foreach (var obj in chapterCampaignData.records)
|
||||||
|
{
|
||||||
|
this.chapterCampaignData.Add(obj.chapter, obj);
|
||||||
|
}
|
||||||
|
|
||||||
userExpDataRecords = await LoadZip("UserExpTable.json", progress);
|
userExpDataRecords = await LoadZip("UserExpTable.json", progress);
|
||||||
chapterCampaignData = await LoadZip("CampaignChapterTable.json", progress);
|
|
||||||
characterCostumeTable = await LoadZip("CharacterCostumeTable.json", progress);
|
characterCostumeTable = await LoadZip("CharacterCostumeTable.json", progress);
|
||||||
characterTable = await LoadZip("CharacterTable.json", progress);
|
|
||||||
tutorialTable = await LoadZip("ContentsTutorialTable.json", progress);
|
var characterTable = await LoadZip<CharacterTable>("CharacterTable.json", progress);
|
||||||
itemEquipTable = await LoadZip("ItemEquipTable.json", progress);
|
foreach (var obj in characterTable.records)
|
||||||
|
{
|
||||||
|
this.characterTable.Add(obj.id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
var tutorialTable = await LoadZip<TutorialTable>("ContentsTutorialTable.json", progress);
|
||||||
|
foreach (var obj in tutorialTable.records)
|
||||||
|
{
|
||||||
|
this.tutorialTable.Add(obj.id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
var itemEquipTable = await LoadZip<ItemEquipTable>("ItemEquipTable.json", progress);
|
||||||
|
foreach (var obj in itemEquipTable.records)
|
||||||
|
{
|
||||||
|
this.itemEquipTable.Add(obj.id, obj);
|
||||||
|
}
|
||||||
|
|
||||||
var characterLevelTable = await LoadZip("CharacterLevelTable.json", progress);
|
var characterLevelTable = await LoadZip("CharacterLevelTable.json", progress);
|
||||||
|
|
||||||
foreach (JToken item in characterLevelTable)
|
foreach (JToken item in characterLevelTable)
|
||||||
@@ -255,7 +301,7 @@ namespace nksrv.StaticInfo
|
|||||||
if (obj != null)
|
if (obj != null)
|
||||||
LevelData.Add(obj.level, obj);
|
LevelData.Add(obj.level, obj);
|
||||||
else
|
else
|
||||||
Logger.Warn("failed to read character level table entry");
|
Console.WriteLine("failed to read character level table entry");
|
||||||
}
|
}
|
||||||
|
|
||||||
var tacticLessonTable = await LoadZip("TacticAcademyFunctionTable.json", progress);
|
var tacticLessonTable = await LoadZip("TacticAcademyFunctionTable.json", progress);
|
||||||
@@ -297,79 +343,57 @@ namespace nksrv.StaticInfo
|
|||||||
SidestoryRewardTable.Add(id2, reward);
|
SidestoryRewardTable.Add(id2, reward);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach (ZipEntry item in MainZip)
|
||||||
|
{
|
||||||
|
if (item.Name.StartsWith("CampaignMap/"))
|
||||||
|
{
|
||||||
|
var x = await LoadZip(item.Name, progress);
|
||||||
|
|
||||||
|
var items = x[0]["ItemSpawner"];
|
||||||
|
foreach (var item2 in items)
|
||||||
|
{
|
||||||
|
var id = item2["positionId"].ToObject<string>();
|
||||||
|
var reward = item2["itemId"].ToObject<int>();
|
||||||
|
|
||||||
|
if (!PositionReward.ContainsKey(id))
|
||||||
|
PositionReward.Add(id, reward);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var fieldItems = await LoadZip<FieldItemTable>("FieldItemTable.json", progress);
|
||||||
|
foreach (var obj in fieldItems.records)
|
||||||
|
{
|
||||||
|
FieldItems.Add(obj.id, obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MainQuestCompletionData? GetMainQuestForStageClearCondition(int stage)
|
public MainQuestCompletionRecord? GetMainQuestForStageClearCondition(int stage)
|
||||||
{
|
{
|
||||||
foreach (JObject item in questDataRecords)
|
foreach (var item in questDataRecords)
|
||||||
{
|
{
|
||||||
var id = item["condition_id"];
|
if (item.Value.condition_id == stage)
|
||||||
if (id == null) throw new Exception("expected condition_id field in quest data");
|
|
||||||
|
|
||||||
int value = id.ToObject<int>();
|
|
||||||
if (value == stage)
|
|
||||||
{
|
{
|
||||||
MainQuestCompletionData? data = item.ToObject<MainQuestCompletionData>();
|
return item.Value;
|
||||||
if (data == null) throw new Exception("failed to deserialize main quest data item");
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public MainQuestCompletionData? GetMainQuestByTableId(int tid)
|
public MainQuestCompletionRecord? GetMainQuestByTableId(int tid)
|
||||||
{
|
{
|
||||||
foreach (JObject item in questDataRecords)
|
return questDataRecords[tid];
|
||||||
{
|
|
||||||
var id = item["id"];
|
|
||||||
if (id == null) throw new Exception("expected condition_id field in quest data");
|
|
||||||
|
|
||||||
int value = id.ToObject<int>();
|
|
||||||
if (value == tid)
|
|
||||||
{
|
|
||||||
MainQuestCompletionData? data = item.ToObject<MainQuestCompletionData>();
|
|
||||||
if (data == null) throw new Exception("failed to deserialize main quest data item");
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
public CampaignStageRecord? GetStageData(int stage)
|
public CampaignStageRecord? GetStageData(int stage)
|
||||||
{
|
{
|
||||||
foreach (JObject item in stageDataRecords)
|
return stageDataRecords[stage];
|
||||||
{
|
|
||||||
var id = item["id"];
|
|
||||||
if (id == null) throw new Exception("expected id field in campaign data");
|
|
||||||
|
|
||||||
int value = id.ToObject<int>();
|
|
||||||
if (value == stage)
|
|
||||||
{
|
|
||||||
CampaignStageRecord? data = JsonConvert.DeserializeObject<CampaignStageRecord>(item.ToString());
|
|
||||||
if (data == null) throw new Exception("failed to deserialize stage data");
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
public RewardTableRecord? GetRewardTableEntry(int rewardId)
|
public RewardTableRecord? GetRewardTableEntry(int rewardId)
|
||||||
{
|
{
|
||||||
foreach (JObject item in rewardDataRecords)
|
return rewardDataRecords[rewardId];
|
||||||
{
|
|
||||||
var id = item["id"];
|
|
||||||
if (id == null) throw new Exception("expected id field in reward data");
|
|
||||||
|
|
||||||
int value = id.ToObject<int>();
|
|
||||||
if (value == rewardId)
|
|
||||||
{
|
|
||||||
RewardTableRecord? data = JsonConvert.DeserializeObject<RewardTableRecord>(item.ToString());
|
|
||||||
if (data == null) throw new Exception("failed to deserialize reward data");
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the level and its minimum value for XP value
|
/// Returns the level and its minimum value for XP value
|
||||||
@@ -430,24 +454,11 @@ namespace nksrv.StaticInfo
|
|||||||
}
|
}
|
||||||
public int GetNormalChapterNumberFromFieldName(string field)
|
public int GetNormalChapterNumberFromFieldName(string field)
|
||||||
{
|
{
|
||||||
foreach (JObject item in chapterCampaignData)
|
foreach (var item in chapterCampaignData)
|
||||||
{
|
{
|
||||||
var id = item["field_id"];
|
if (item.Value.field_id == field)
|
||||||
if (id == null)
|
|
||||||
{
|
{
|
||||||
throw new Exception("expected id field in reward data");
|
return item.Value.chapter;
|
||||||
}
|
|
||||||
|
|
||||||
string? value = id.ToObject<string>();
|
|
||||||
if (value == field)
|
|
||||||
{
|
|
||||||
var chapter = item["chapter"];
|
|
||||||
if (chapter == null)
|
|
||||||
{
|
|
||||||
throw new Exception("expected id field in reward data");
|
|
||||||
}
|
|
||||||
|
|
||||||
return chapter.ToObject<int>();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -456,14 +467,7 @@ namespace nksrv.StaticInfo
|
|||||||
|
|
||||||
public IEnumerable<int> GetAllCharacterTids()
|
public IEnumerable<int> GetAllCharacterTids()
|
||||||
{
|
{
|
||||||
foreach (JObject item in characterTable)
|
return characterTable.Keys;
|
||||||
{
|
|
||||||
var id = item["id"];
|
|
||||||
if (id == null) throw new Exception("expected id field in reward data");
|
|
||||||
|
|
||||||
int value = id.ToObject<int>();
|
|
||||||
yield return value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
public IEnumerable<int> GetAllCostumes()
|
public IEnumerable<int> GetAllCostumes()
|
||||||
{
|
{
|
||||||
@@ -479,56 +483,20 @@ namespace nksrv.StaticInfo
|
|||||||
|
|
||||||
internal ClearedTutorialData GetTutorialDataById(int TableId)
|
internal ClearedTutorialData GetTutorialDataById(int TableId)
|
||||||
{
|
{
|
||||||
foreach (JObject item in tutorialTable)
|
return tutorialTable[TableId];
|
||||||
{
|
|
||||||
var id = item["id"];
|
|
||||||
if (id == null)
|
|
||||||
{
|
|
||||||
throw new Exception("expected id field in reward data");
|
|
||||||
}
|
|
||||||
|
|
||||||
int idValue = id.ToObject<int>();
|
|
||||||
if (idValue == TableId)
|
|
||||||
{
|
|
||||||
ClearedTutorialData? data = item.ToObject<ClearedTutorialData>();
|
|
||||||
if (data == null) throw new Exception("failed to deserialize reward data");
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Exception("tutorial not found: " + TableId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string? GetItemSubType(int itemType)
|
public string? GetItemSubType(int itemType)
|
||||||
{
|
{
|
||||||
foreach (JObject item in itemEquipTable)
|
return itemEquipTable[itemType].item_sub_type;
|
||||||
{
|
|
||||||
var id = item["id"];
|
|
||||||
if (id == null) throw new Exception("expected id field in reward data");
|
|
||||||
|
|
||||||
int? idValue = id.ToObject<int>();
|
|
||||||
if (idValue == itemType)
|
|
||||||
{
|
|
||||||
var subtype = item["item_sub_type"];
|
|
||||||
if (subtype == null)
|
|
||||||
{
|
|
||||||
throw new Exception("expected item_sub_type field in item equip data");
|
|
||||||
}
|
|
||||||
|
|
||||||
return subtype.ToObject<string>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal IEnumerable<int> GetStageIdsForChapter(int chapterNumber, bool normal)
|
internal IEnumerable<int> GetStageIdsForChapter(int chapterNumber, bool normal)
|
||||||
{
|
{
|
||||||
string mod = normal ? "Normal" : "Hard";
|
string mod = normal ? "Normal" : "Hard";
|
||||||
foreach (JObject item in stageDataRecords)
|
foreach (var item in stageDataRecords)
|
||||||
{
|
{
|
||||||
CampaignStageRecord? data = item.ToObject<CampaignStageRecord>();
|
var data = item.Value;
|
||||||
if (data == null) throw new Exception("failed to deserialize stage data");
|
|
||||||
|
|
||||||
int chVal = data.chapter_id - 1;
|
int chVal = data.chapter_id - 1;
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
namespace nksrv.StaticInfo
|
namespace EpinelPS.StaticInfo
|
||||||
{
|
{
|
||||||
public class MainQuestCompletionData
|
public class MainQuestCompletionRecord
|
||||||
{
|
{
|
||||||
public int id;
|
public int id;
|
||||||
public int group_id;
|
public int group_id;
|
||||||
@@ -10,6 +10,10 @@
|
|||||||
public int reward_id = 0;
|
public int reward_id = 0;
|
||||||
public int target_chapter_id;
|
public int target_chapter_id;
|
||||||
}
|
}
|
||||||
|
public class MainQuestCompletionTable
|
||||||
|
{
|
||||||
|
public List<MainQuestCompletionRecord> records;
|
||||||
|
}
|
||||||
public class CampaignStageRecord
|
public class CampaignStageRecord
|
||||||
{
|
{
|
||||||
public int id;
|
public int id;
|
||||||
@@ -24,6 +28,10 @@
|
|||||||
public string enter_scenario = "";
|
public string enter_scenario = "";
|
||||||
public string exit_scenario = "";
|
public string exit_scenario = "";
|
||||||
}
|
}
|
||||||
|
public class CampaignStageTable
|
||||||
|
{
|
||||||
|
public List<CampaignStageRecord> records;
|
||||||
|
}
|
||||||
public class RewardTableRecord
|
public class RewardTableRecord
|
||||||
{
|
{
|
||||||
public int id;
|
public int id;
|
||||||
@@ -31,6 +39,11 @@
|
|||||||
public int character_exp;
|
public int character_exp;
|
||||||
public RewardEntry[]? rewards;
|
public RewardEntry[]? rewards;
|
||||||
}
|
}
|
||||||
|
public class RewardTable
|
||||||
|
{
|
||||||
|
public List<RewardTableRecord> records;
|
||||||
|
}
|
||||||
|
|
||||||
public class RewardEntry
|
public class RewardEntry
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -53,6 +66,10 @@
|
|||||||
public int NextId;
|
public int NextId;
|
||||||
public bool SaveTutorial;
|
public bool SaveTutorial;
|
||||||
}
|
}
|
||||||
|
public class TutorialTable
|
||||||
|
{
|
||||||
|
public List<ClearedTutorialData> records;
|
||||||
|
}
|
||||||
|
|
||||||
public class CharacterLevelData
|
public class CharacterLevelData
|
||||||
{
|
{
|
||||||
@@ -85,4 +102,49 @@
|
|||||||
public int Id;
|
public int Id;
|
||||||
public int GroupId;
|
public int GroupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class CampaignChapterRecord
|
||||||
|
{
|
||||||
|
public int id;
|
||||||
|
public int chapter;
|
||||||
|
public string field_id;
|
||||||
|
public string hard_field_id;
|
||||||
|
}
|
||||||
|
public class CampaignChapterTable
|
||||||
|
{
|
||||||
|
public List<CampaignChapterRecord> records;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class CharacterRecord
|
||||||
|
{
|
||||||
|
public int id;
|
||||||
|
// TODO: There is more stuff here but it isn't needed yet
|
||||||
|
}
|
||||||
|
public class CharacterTable
|
||||||
|
{
|
||||||
|
public List<CharacterRecord> records;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ItemEquipRecord
|
||||||
|
{
|
||||||
|
public int id;
|
||||||
|
public string item_sub_type;
|
||||||
|
}
|
||||||
|
public class ItemEquipTable
|
||||||
|
{
|
||||||
|
public List<ItemEquipRecord> records;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class FieldItemRecord
|
||||||
|
{
|
||||||
|
public int id;
|
||||||
|
public string item_type;
|
||||||
|
public int type_value;
|
||||||
|
public bool is_final_reward;
|
||||||
|
public string difficulty;
|
||||||
|
}
|
||||||
|
public class FieldItemTable
|
||||||
|
{
|
||||||
|
public List<FieldItemRecord> records;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,11 +1,9 @@
|
|||||||
using ASodium;
|
using ASodium;
|
||||||
using EmbedIO;
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
using nksrv.Database;
|
|
||||||
using nksrv.Utils;
|
|
||||||
using Swan.Logging;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer
|
namespace EpinelPS.LobbyServer
|
||||||
{
|
{
|
||||||
public static class LobbyHandler
|
public static class LobbyHandler
|
||||||
{
|
{
|
||||||
@@ -19,7 +17,7 @@ namespace nksrv.LobbyServer
|
|||||||
var attrib = (PacketPathAttribute?)Attribute.GetCustomAttribute(type, typeof(PacketPathAttribute));
|
var attrib = (PacketPathAttribute?)Attribute.GetCustomAttribute(type, typeof(PacketPathAttribute));
|
||||||
if (attrib == null)
|
if (attrib == null)
|
||||||
{
|
{
|
||||||
Logger.Error("WARNING: Failed to get attribute for " + type.FullName);
|
Console.WriteLine("WARNING: Failed to get attribute for " + type.FullName);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,17 +29,18 @@ namespace nksrv.LobbyServer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger.Error($"WARNING: Type {type.FullName} has PacketPathAttribute but does not implement LobbyMsgHandler");
|
Console.WriteLine($"WARNING: Type {type.FullName} has PacketPathAttribute but does not implement LobbyMsgHandler");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static async Task DispatchSingle(IHttpContext ctx)
|
public static async Task DispatchSingle(HttpContext ctx)
|
||||||
{
|
{
|
||||||
LobbyMsgHandler? handler = null;
|
LobbyMsgHandler? handler = null;
|
||||||
|
string path = ctx.Request.Path.Value.Replace("/v1", "");
|
||||||
foreach (var item in Handlers)
|
foreach (var item in Handlers)
|
||||||
{
|
{
|
||||||
if (ctx.RequestedPath == item.Key)
|
if (path == item.Key)
|
||||||
{
|
{
|
||||||
handler = item.Value;
|
handler = item.Value;
|
||||||
}
|
}
|
||||||
@@ -105,7 +104,7 @@ namespace nksrv.LobbyServer
|
|||||||
{
|
{
|
||||||
NetUserData ret = new()
|
NetUserData ret = new()
|
||||||
{
|
{
|
||||||
Lv = user.userPointData.UserLevel,
|
Level = user.userPointData.UserLevel,
|
||||||
Exp = user.userPointData.ExperiencePoint,
|
Exp = user.userPointData.ExperiencePoint,
|
||||||
CommanderRoomJukebox = 5,
|
CommanderRoomJukebox = 5,
|
||||||
CostumeLv = 1,
|
CostumeLv = 1,
|
||||||
@@ -133,14 +132,14 @@ namespace nksrv.LobbyServer
|
|||||||
{
|
{
|
||||||
var ret = new NetWholeUserData()
|
var ret = new NetWholeUserData()
|
||||||
{
|
{
|
||||||
Lv = user.userPointData.UserLevel,
|
Level = user.userPointData.UserLevel,
|
||||||
Frame = 1,
|
Frame = user.ProfileFrame,
|
||||||
Icon = user.ProfileIconId,
|
Icon = user.ProfileIconId,
|
||||||
IconPrism = user.ProfileIconIsPrism,
|
IconPrism = user.ProfileIconIsPrism,
|
||||||
Nickname = user.Nickname,
|
Nickname = user.Nickname,
|
||||||
Usn = (long)user.ID,
|
Usn = (long)user.ID,
|
||||||
LastActionAt = DateTimeOffset.UtcNow.Ticks,
|
LastActionAt = DateTimeOffset.UtcNow.Ticks,
|
||||||
|
Server = 1001
|
||||||
};
|
};
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
using EmbedIO;
|
using Google.Protobuf;
|
||||||
using Google.Protobuf;
|
using EpinelPS.Database;
|
||||||
using nksrv.Database;
|
using EpinelPS.Utils;
|
||||||
using nksrv.Utils;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer
|
namespace EpinelPS.LobbyServer
|
||||||
{
|
{
|
||||||
public abstract class LobbyMsgHandler
|
public abstract class LobbyMsgHandler
|
||||||
{
|
{
|
||||||
protected IHttpContext? ctx;
|
protected HttpContext? ctx;
|
||||||
protected ulong UserId;
|
protected ulong UserId;
|
||||||
protected string UsedAuthToken = "";
|
protected string UsedAuthToken = "";
|
||||||
public byte[] ReturnBytes = [];
|
public byte[] ReturnBytes = [];
|
||||||
@@ -25,12 +24,12 @@ namespace nksrv.LobbyServer
|
|||||||
ctx = null;
|
ctx = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task HandleAsync(IHttpContext ctx)
|
public async Task HandleAsync(HttpContext ctx)
|
||||||
{
|
{
|
||||||
this.ctx = ctx;
|
this.ctx = ctx;
|
||||||
if (ctx.Request.Headers.AllKeys.Contains("Authorization"))
|
if (ctx.Request.Headers.Keys.Contains("Authorization"))
|
||||||
{
|
{
|
||||||
var token = ctx.Request.Headers["Authorization"];
|
var token = ctx.Request.Headers.Authorization.FirstOrDefault();
|
||||||
if (token != null)
|
if (token != null)
|
||||||
{
|
{
|
||||||
UsedAuthToken = token;
|
UsedAuthToken = token;
|
||||||
@@ -49,7 +48,7 @@ namespace nksrv.LobbyServer
|
|||||||
UserId = item.Value.UserId;
|
UserId = item.Value.UserId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (UserId == 0) throw new HttpException(403);
|
if (UserId == 0) throw new Exception("403");
|
||||||
await HandleAsync();
|
await HandleAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,20 +67,20 @@ namespace nksrv.LobbyServer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ctx.Response.ContentEncoding = null;
|
|
||||||
ctx.Response.ContentType = "application/octet-stream+protobuf";
|
ctx.Response.ContentType = "application/octet-stream+protobuf";
|
||||||
ctx.Response.ContentLength64 = data.CalculateSize();
|
ctx.Response.ContentLength = data.CalculateSize();
|
||||||
bool encrypted = false;
|
bool encrypted = false;
|
||||||
var responseBytes = encrypted ? new MemoryStream() : ctx.Response.OutputStream;
|
var responseBytes = encrypted ? new MemoryStream() : ctx.Response.Body;
|
||||||
var x = new CodedOutputStream(responseBytes);
|
var x = new CodedOutputStream(responseBytes);
|
||||||
data.WriteTo(x);
|
data.WriteTo(x);
|
||||||
|
|
||||||
x.Flush();
|
x.Flush();
|
||||||
|
|
||||||
if (encrypted)
|
if (encrypted)
|
||||||
{
|
{
|
||||||
ctx.Response.Headers.Set(System.Net.HttpRequestHeader.ContentEncoding, "gzip,enc");
|
ctx.Response.Headers.ContentEncoding = new Microsoft.Extensions.Primitives.StringValues("gzip,enc");
|
||||||
var enc = PacketDecryption.EncryptData(((MemoryStream)responseBytes).ToArray(), UsedAuthToken);
|
var enc = PacketDecryption.EncryptData(((MemoryStream)responseBytes).ToArray(), UsedAuthToken);
|
||||||
await ctx.Response.OutputStream.WriteAsync(enc, ctx.CancellationToken);
|
await ctx.Response.Body.WriteAsync(enc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,5 +111,9 @@ namespace nksrv.LobbyServer
|
|||||||
{
|
{
|
||||||
return JsonDb.GetUser(UserId) ?? throw new Exception("null user");
|
return JsonDb.GetUser(UserId) ?? throw new Exception("null user");
|
||||||
}
|
}
|
||||||
|
public User? GetUser(ulong id)
|
||||||
|
{
|
||||||
|
return JsonDb.GetUser(id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Antibot
|
namespace EpinelPS.LobbyServer.Msgs.Antibot
|
||||||
{
|
{
|
||||||
[PacketPath("/antibot/battlereportdata")]
|
[PacketPath("/antibot/battlereportdata")]
|
||||||
public class BattleReportData : LobbyMsgHandler
|
public class BattleReportData : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Antibot
|
namespace EpinelPS.LobbyServer.Msgs.Antibot
|
||||||
{
|
{
|
||||||
[PacketPath("/antibot/recvdata")]
|
[PacketPath("/antibot/recvdata")]
|
||||||
public class RecieveAntibotData : LobbyMsgHandler
|
public class RecieveAntibotData : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Archive
|
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||||
{
|
{
|
||||||
[PacketPath("/bookmark/scenario/exist")]
|
[PacketPath("/bookmark/scenario/exist")]
|
||||||
public class CheckBookmarkScenarioExists : LobbyMsgHandler
|
public class CheckBookmarkScenarioExists : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Archive
|
namespace EpinelPS.LobbyServer.Msgs.Archive
|
||||||
{
|
{
|
||||||
[PacketPath("/archive/get")]
|
[PacketPath("/archive/get")]
|
||||||
public class GetArchives : LobbyMsgHandler
|
public class GetArchives : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Arena
|
namespace EpinelPS.LobbyServer.Msgs.Arena
|
||||||
{
|
{
|
||||||
[PacketPath("/arena/getbaninfo")]
|
[PacketPath("/arena/getbaninfo")]
|
||||||
public class GetArenaBanInfo : LobbyMsgHandler
|
public class GetArenaBanInfo : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Arena
|
namespace EpinelPS.LobbyServer.Msgs.Arena
|
||||||
{
|
{
|
||||||
[PacketPath("/arena/special/showreward")]
|
[PacketPath("/arena/special/showreward")]
|
||||||
public class ShowSpecialArenaReward : LobbyMsgHandler
|
public class ShowSpecialArenaReward : LobbyMsgHandler
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Auth
|
namespace EpinelPS.LobbyServer.Msgs.Auth
|
||||||
{
|
{
|
||||||
[PacketPath("/auth/logout")]
|
[PacketPath("/auth/logout")]
|
||||||
public class AuthLogout : LobbyMsgHandler
|
public class AuthLogout : LobbyMsgHandler
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
using EmbedIO;
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
using Google.Protobuf;
|
using Google.Protobuf;
|
||||||
using Google.Protobuf.WellKnownTypes;
|
using Google.Protobuf.WellKnownTypes;
|
||||||
using nksrv.Database;
|
|
||||||
using nksrv.Utils;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Auth
|
namespace EpinelPS.LobbyServer.Msgs.Auth
|
||||||
{
|
{
|
||||||
[PacketPath("/auth/enterserver")]
|
[PacketPath("/auth/enterserver")]
|
||||||
public class GetUserOnlineStateLog : LobbyMsgHandler
|
public class GetUserOnlineStateLog : LobbyMsgHandler
|
||||||
{
|
{
|
||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var req = await ReadData<EnterServerRequest>();
|
var req = await ReadData<ReqEnterServer>();
|
||||||
|
|
||||||
// request has auth token
|
// request has auth token
|
||||||
UsedAuthToken = req.AuthToken;
|
UsedAuthToken = req.AuthToken;
|
||||||
@@ -22,11 +21,11 @@ namespace nksrv.LobbyServer.Msgs.Auth
|
|||||||
UserId = item.UserID;
|
UserId = item.UserID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (UserId == 0) throw new HttpException(403);
|
if (UserId == 0) throw new BadHttpRequestException("unknown auth token", 403);
|
||||||
|
|
||||||
var user = GetUser();
|
var user = GetUser();
|
||||||
|
|
||||||
var response = new EnterServerResponse();
|
var response = new ResEnterServer();
|
||||||
var rsp = LobbyHandler.GenGameClientTok(req.ClientPublicKey, req.AuthToken);
|
var rsp = LobbyHandler.GenGameClientTok(req.ClientPublicKey, req.AuthToken);
|
||||||
response.GameClientToken = rsp.ClientAuthToken;
|
response.GameClientToken = rsp.ClientAuthToken;
|
||||||
response.FeatureDataInfo = new NetFeatureDataInfo() { UseFeatureData = true };
|
response.FeatureDataInfo = new NetFeatureDataInfo() { UseFeatureData = true };
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
using EmbedIO;
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
using Google.Protobuf.WellKnownTypes;
|
using Google.Protobuf.WellKnownTypes;
|
||||||
using nksrv.Database;
|
|
||||||
using nksrv.Utils;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Auth
|
namespace EpinelPS.LobbyServer.Msgs.Auth
|
||||||
{
|
{
|
||||||
[PacketPath("/auth/intl")]
|
[PacketPath("/auth/intl")]
|
||||||
public class DoIntlAuth : LobbyMsgHandler
|
public class DoIntlAuth : LobbyMsgHandler
|
||||||
@@ -11,7 +10,7 @@ namespace nksrv.LobbyServer.Msgs.Auth
|
|||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var req = await ReadData<ReqAuthIntl>();
|
var req = await ReadData<ReqAuthIntl>();
|
||||||
var response = new AuthIntlResponse();
|
var response = new ResAuth();
|
||||||
|
|
||||||
UsedAuthToken = req.Token;
|
UsedAuthToken = req.Token;
|
||||||
foreach (var item in JsonDb.Instance.LauncherAccessTokens)
|
foreach (var item in JsonDb.Instance.LauncherAccessTokens)
|
||||||
@@ -23,7 +22,7 @@ namespace nksrv.LobbyServer.Msgs.Auth
|
|||||||
}
|
}
|
||||||
if (UserId == 0)
|
if (UserId == 0)
|
||||||
{
|
{
|
||||||
response.AuthError = new NetAuthError() { ErrorCode = AuthErrorCode.Error };
|
response.AuthError = new NetAuthError() { ErrorCode = AuthErrorCode.AuthErrorCodeError };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -44,7 +43,7 @@ namespace nksrv.LobbyServer.Msgs.Auth
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
response.AuthSuccess = new NetAuthSuccess() { AuthToken = req.Token, CentauriZoneId = "84", FirstAuth = "", PurchaseRestriction = new NetUserPurchaseRestriction() { PurchaseRestriction = PurchaseRestriction.Child, UpdatedAt = 638546758794611090 } };
|
response.AuthSuccess = new NetAuthSuccess() { AuthToken = req.Token, CentauriZoneId = "84", FirstAuth = false, PurchaseRestriction = new NetUserPurchaseRestriction() { PurchaseRestriction = PurchaseRestriction.PurchaseRestrictionChild, UpdatedAt = 638546758794611090 } };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Badge
|
namespace EpinelPS.LobbyServer.Msgs.Badge
|
||||||
{
|
{
|
||||||
[PacketPath("/badge/delete")]
|
[PacketPath("/badge/delete")]
|
||||||
public class DeleteBadge : LobbyMsgHandler
|
public class DeleteBadge : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Badge
|
namespace EpinelPS.LobbyServer.Msgs.Badge
|
||||||
{
|
{
|
||||||
[PacketPath("/badge/sync")]
|
[PacketPath("/badge/sync")]
|
||||||
public class SyncBadge : LobbyMsgHandler
|
public class SyncBadge : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Campaign
|
namespace EpinelPS.LobbyServer.Msgs.Campaign
|
||||||
{
|
{
|
||||||
[PacketPath("/shutdownflags/campaignpackage/getall")]
|
[PacketPath("/shutdownflags/campaignpackage/getall")]
|
||||||
public class CampaignPackageGetAll : LobbyMsgHandler
|
public class CampaignPackageGetAll : LobbyMsgHandler
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using nksrv.LobbyServer.Msgs.Stage;
|
using EpinelPS.LobbyServer.Msgs.Stage;
|
||||||
using nksrv.StaticInfo;
|
using EpinelPS.StaticInfo;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Campaign
|
namespace EpinelPS.LobbyServer.Msgs.Campaign
|
||||||
{
|
{
|
||||||
[PacketPath("/campaign/getfield")]
|
[PacketPath("/campaign/getfield")]
|
||||||
public class GetCampaignField : LobbyMsgHandler
|
public class GetCampaignField : LobbyMsgHandler
|
||||||
@@ -15,7 +15,7 @@ namespace nksrv.LobbyServer.Msgs.Campaign
|
|||||||
Console.WriteLine("Map ID: " + req.MapId);
|
Console.WriteLine("Map ID: " + req.MapId);
|
||||||
|
|
||||||
var response = new ResGetCampaignFieldData();
|
var response = new ResGetCampaignFieldData();
|
||||||
response.Field = GetStage.CreateFieldInfo(user, StaticDataParser.Instance.GetNormalChapterNumberFromFieldName(req.MapId), req.MapId.Contains("hard") ? "Hard" : "Normal");
|
response.Field = GetStage.CreateFieldInfo(user, GameData.Instance.GetNormalChapterNumberFromFieldName(req.MapId), req.MapId.Contains("hard") ? "Hard" : "Normal");
|
||||||
|
|
||||||
// todo save this data
|
// todo save this data
|
||||||
response.Team = new NetUserTeamData() { LastContentsTeamNumber = 1, Type = 1 };
|
response.Team = new NetUserTeamData() { LastContentsTeamNumber = 1, Type = 1 };
|
||||||
50
EpinelPS/LobbyServer/Msgs/Campaign/ObtainItem.cs
Normal file
50
EpinelPS/LobbyServer/Msgs/Campaign/ObtainItem.cs
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.LobbyServer.Msgs.Stage;
|
||||||
|
using EpinelPS.StaticInfo;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Campaign
|
||||||
|
{
|
||||||
|
[PacketPath("/campaign/obtain/item")]
|
||||||
|
public class ObtainItem : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqObtainCampaignItem>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
|
var response = new ResObtainCampaignItem();
|
||||||
|
|
||||||
|
var chapter = GameData.Instance.GetNormalChapterNumberFromFieldName(req.MapId);
|
||||||
|
var mod = req.MapId.Contains("hard") ? "Hard" : "Normal";
|
||||||
|
var key = chapter + "_" + mod;
|
||||||
|
var field = user.FieldInfoNew[key];
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var item in field.CompletedObjects)
|
||||||
|
{
|
||||||
|
if (item.PositionId == req.FieldObject.PositionId)
|
||||||
|
{
|
||||||
|
Console.WriteLine("attempted to collect campaign field object twice!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register and return reward
|
||||||
|
|
||||||
|
if (!GameData.Instance.PositionReward.ContainsKey(req.FieldObject.PositionId)) throw new Exception("bad position id");
|
||||||
|
var fieldReward = GameData.Instance.PositionReward[req.FieldObject.PositionId];
|
||||||
|
var positionReward = GameData.Instance.FieldItems[fieldReward];
|
||||||
|
var reward = GameData.Instance.GetRewardTableEntry(positionReward.type_value);
|
||||||
|
if (reward == null) throw new Exception("failed to get reward");
|
||||||
|
response.Reward = ClearStage.RegisterRewardsForUser(user, reward);
|
||||||
|
|
||||||
|
// Hide it from the field
|
||||||
|
field.CompletedObjects.Add(new NetFieldObject() { PositionId = req.FieldObject.PositionId, Type = req.FieldObject.Type});
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Campaign
|
namespace EpinelPS.LobbyServer.Msgs.Campaign
|
||||||
{
|
{
|
||||||
[PacketPath("/campaign/savefield")]
|
[PacketPath("/campaign/savefield")]
|
||||||
public class SaveField : LobbyMsgHandler
|
public class SaveField : LobbyMsgHandler
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.StaticInfo;
|
using EpinelPS.StaticInfo;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Campaign
|
namespace EpinelPS.LobbyServer.Msgs.Campaign
|
||||||
{
|
{
|
||||||
[PacketPath("/campaign/savefieldobject")]
|
[PacketPath("/campaign/savefieldobject")]
|
||||||
public class SaveFieldObject : LobbyMsgHandler
|
public class SaveFieldObject : LobbyMsgHandler
|
||||||
@@ -16,14 +16,14 @@ namespace nksrv.LobbyServer.Msgs.Campaign
|
|||||||
|
|
||||||
var response = new ResSaveCampaignFieldObject();
|
var response = new ResSaveCampaignFieldObject();
|
||||||
|
|
||||||
Console.WriteLine($"save {req.MapId} with {req.FieldObject.PositionID}");
|
Console.WriteLine($"save {req.MapId} with {req.FieldObject.PositionId}");
|
||||||
|
|
||||||
var chapter = StaticDataParser.Instance.GetNormalChapterNumberFromFieldName(req.MapId);
|
var chapter = GameData.Instance.GetNormalChapterNumberFromFieldName(req.MapId);
|
||||||
var mod = req.MapId.Contains("hard") ? "Hard" : "Normal";
|
var mod = req.MapId.Contains("hard") ? "Hard" : "Normal";
|
||||||
var key = chapter + "_" + mod;
|
var key = chapter + "_" + mod;
|
||||||
var field = user.FieldInfoNew[key];
|
var field = user.FieldInfoNew[key];
|
||||||
|
|
||||||
field.CompletedObjects.Add(new NetFieldObject() { PositionId = req.FieldObject.PositionID, Json = req.FieldObject.Json, Type = req.FieldObject.Type });
|
field.CompletedObjects.Add(new NetFieldObject() { PositionId = req.FieldObject.PositionId, Json = req.FieldObject.Json, Type = req.FieldObject.Type });
|
||||||
JsonDb.Save();
|
JsonDb.Save();
|
||||||
|
|
||||||
await WriteDataAsync(response);
|
await WriteDataAsync(response);
|
||||||
54
EpinelPS/LobbyServer/Msgs/Character/ChangeSynchroDevice.cs
Normal file
54
EpinelPS/LobbyServer/Msgs/Character/ChangeSynchroDevice.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
|
{
|
||||||
|
[PacketPath("/character/SynchroDevice/Change")]
|
||||||
|
public class ChangeSynchroDevice : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqSynchroChange>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
|
var response = new ResSynchroChange();
|
||||||
|
|
||||||
|
var highestLevelCharacters = user.Characters.OrderByDescending(x => x.Level).Take(5).ToList();
|
||||||
|
|
||||||
|
int slot = 1;
|
||||||
|
foreach (var item in highestLevelCharacters)
|
||||||
|
{
|
||||||
|
if (item.Level != 200)
|
||||||
|
{
|
||||||
|
throw new Exception("expected level to be 200");
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Characters.Add(new NetUserCharacterData() { Default = new() { Csn = item.Csn, Skill1Lv = item.Skill1Lvl, Skill2Lv = item.Skill2Lvl, CostumeId = item.CostumeId, Level = item.Level, Grade = item.Grade, Tid = item.Tid, UltiSkillLv = item.UltimateLevel }, IsSynchro = user.GetSynchro(item.Csn) });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var s in user.SynchroSlots)
|
||||||
|
{
|
||||||
|
if (s.Slot == slot)
|
||||||
|
{
|
||||||
|
s.CharacterSerialNumber = item.Csn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
slot++;
|
||||||
|
}
|
||||||
|
|
||||||
|
user.SynchroDeviceUpgraded = true;
|
||||||
|
|
||||||
|
foreach (var item in user.SynchroSlots)
|
||||||
|
{
|
||||||
|
response.Slots.Add(new NetSynchroSlot() { Slot = item.Slot, AvailableRegisterAt = item.AvailableAt, Csn = item.CharacterSerialNumber });
|
||||||
|
}
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Character
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
{
|
{
|
||||||
[PacketPath("/character/attractive/get")]
|
[PacketPath("/character/attractive/get")]
|
||||||
public class GetCharacterAttractiveList : LobbyMsgHandler
|
public class GetCharacterAttractiveList : LobbyMsgHandler
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.StaticInfo;
|
using EpinelPS.StaticInfo;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Character
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
{
|
{
|
||||||
[PacketPath("/character/costume/get")]
|
[PacketPath("/character/costume/get")]
|
||||||
public class GetCharacterCostume : LobbyMsgHandler
|
public class GetCharacterCostume : LobbyMsgHandler
|
||||||
@@ -13,7 +13,7 @@ namespace nksrv.LobbyServer.Msgs.Character
|
|||||||
var response = new ResGetCharacterCostumeData();
|
var response = new ResGetCharacterCostumeData();
|
||||||
|
|
||||||
// return all
|
// return all
|
||||||
response.CostumeIds.AddRange(StaticDataParser.Instance.GetAllCostumes());
|
response.CostumeIds.AddRange(GameData.Instance.GetAllCostumes());
|
||||||
|
|
||||||
await WriteDataAsync(response);
|
await WriteDataAsync(response);
|
||||||
}
|
}
|
||||||
30
EpinelPS/LobbyServer/Msgs/Character/GetCharacterData.cs
Normal file
30
EpinelPS/LobbyServer/Msgs/Character/GetCharacterData.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
|
{
|
||||||
|
[PacketPath("/character/get")]
|
||||||
|
public class GetCharacterData : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqGetCharacterData>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
|
var response = new ResGetCharacterData();
|
||||||
|
// TODO: When Squad view opens in the game, or this request is sent, all character levels reset to 1 as well as costume IDs
|
||||||
|
//foreach (var item in user.Characters)
|
||||||
|
//{
|
||||||
|
// response.Character.Add(new NetUserCharacterData() { Default = new() { Csn = item.Csn, Skill1Lv = item.Skill1Lvl, Skill2Lv = item.Skill2Lvl, CostumeId = item.CostumeId, Level = user.GetCharacterLevel(item.Csn, item.Level), Grade = item.Grade, Tid = item.Tid, UltiSkillLv = item.UltimateLevel }, IsSynchro = user.GetSynchro(item.Csn) });
|
||||||
|
//}
|
||||||
|
|
||||||
|
var highestLevelCharacters = user.Characters.OrderByDescending(x => x.Level).Take(5).ToList();
|
||||||
|
|
||||||
|
foreach (var c in highestLevelCharacters)
|
||||||
|
{
|
||||||
|
response.SynchroStandardCharacters.Add(c.Csn);
|
||||||
|
}
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
54
EpinelPS/LobbyServer/Msgs/Character/GetSynchrodevice.cs
Normal file
54
EpinelPS/LobbyServer/Msgs/Character/GetSynchrodevice.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
|
{
|
||||||
|
[PacketPath("/character/synchrodevice/get")]
|
||||||
|
public class GetSynchrodevice : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqGetSynchroData>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
|
if (user.SynchroSlots.Count == 0)
|
||||||
|
{
|
||||||
|
|
||||||
|
user.SynchroSlots = new() {
|
||||||
|
new SynchroSlot() { Slot = 1 },
|
||||||
|
new SynchroSlot() { Slot = 2},
|
||||||
|
new SynchroSlot() { Slot = 3 },
|
||||||
|
new SynchroSlot() { Slot = 4 },
|
||||||
|
new SynchroSlot() { Slot = 5 },
|
||||||
|
|
||||||
|
new SynchroSlot() { Slot = 6 },
|
||||||
|
new SynchroSlot() { Slot = 7 },
|
||||||
|
new SynchroSlot() { Slot = 8 },
|
||||||
|
new SynchroSlot() { Slot = 9 },
|
||||||
|
new SynchroSlot() { Slot = 10 },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
var highestLevelCharacters = user.Characters.OrderByDescending(x => x.Level).Take(5).ToList();
|
||||||
|
|
||||||
|
var response = new ResGetSynchroData();
|
||||||
|
response.Synchro = new NetUserSynchroData();
|
||||||
|
|
||||||
|
foreach (var item in highestLevelCharacters)
|
||||||
|
{
|
||||||
|
response.Synchro.StandardCharacters.Add(new NetUserCharacterData() { Default = new() { Csn = item.Csn, Skill1Lv = item.Skill1Lvl, Skill2Lv = item.Skill2Lvl, CostumeId = item.CostumeId, Level = item.Level, Grade = item.Grade, Tid = item.Tid, UltiSkillLv = item.UltimateLevel }, IsSynchro = user.GetSynchro(item.Csn) });
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var item in user.SynchroSlots)
|
||||||
|
{
|
||||||
|
response.Synchro.Slots.Add(new NetSynchroSlot() { Slot = item.Slot, AvailableRegisterAt = 1, Csn = item.CharacterSerialNumber });
|
||||||
|
}
|
||||||
|
|
||||||
|
response.Synchro.SynchroMaxLv = 1000;
|
||||||
|
response.Synchro.SynchroLv = user.GetSynchroLevel();
|
||||||
|
response.Synchro.IsChanged = user.SynchroDeviceUpgraded;
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,8 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.StaticInfo;
|
using EpinelPS.StaticInfo;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
using Swan.Logging;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Character
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
{
|
{
|
||||||
[PacketPath("/character/levelup")]
|
[PacketPath("/character/levelup")]
|
||||||
public class LevelUp : LobbyMsgHandler
|
public class LevelUp : LobbyMsgHandler
|
||||||
@@ -13,7 +12,7 @@ namespace nksrv.LobbyServer.Msgs.Character
|
|||||||
var req = await ReadData<ReqCharacterLevelUp>();
|
var req = await ReadData<ReqCharacterLevelUp>();
|
||||||
var user = GetUser();
|
var user = GetUser();
|
||||||
var response = new ResCharacterLevelUp();
|
var response = new ResCharacterLevelUp();
|
||||||
var data = StaticDataParser.Instance.GetCharacterLevelUpData();
|
var data = GameData.Instance.GetCharacterLevelUpData();
|
||||||
|
|
||||||
foreach (var item in user.Characters.ToArray())
|
foreach (var item in user.Characters.ToArray())
|
||||||
{
|
{
|
||||||
@@ -42,7 +41,7 @@ namespace nksrv.LobbyServer.Msgs.Character
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// TOOD: log this
|
// TOOD: log this
|
||||||
Logger.Error("ERROR: Not enough currency for upgrade");
|
Console.WriteLine("ERROR: Not enough currency for upgrade");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +49,7 @@ namespace nksrv.LobbyServer.Msgs.Character
|
|||||||
{
|
{
|
||||||
CostumeId = item.CostumeId,
|
CostumeId = item.CostumeId,
|
||||||
Csn = item.Csn,
|
Csn = item.Csn,
|
||||||
Lv = item.Level,
|
Level = item.Level,
|
||||||
Skill1Lv = item.Skill1Lvl,
|
Skill1Lv = item.Skill1Lvl,
|
||||||
Skill2Lv = item.Skill2Lvl,
|
Skill2Lv = item.Skill2Lvl,
|
||||||
UltiSkillLv = item.UltimateLevel,
|
UltiSkillLv = item.UltimateLevel,
|
||||||
@@ -59,11 +58,11 @@ namespace nksrv.LobbyServer.Msgs.Character
|
|||||||
};
|
};
|
||||||
var highestLevelCharacters = user.Characters.OrderByDescending(x => x.Level).Take(5).ToList();
|
var highestLevelCharacters = user.Characters.OrderByDescending(x => x.Level).Take(5).ToList();
|
||||||
|
|
||||||
response.SynchroLv = highestLevelCharacters.Last().Level;
|
response.SynchroLv = user.GetSynchroLevel();
|
||||||
|
|
||||||
foreach (var c in highestLevelCharacters)
|
foreach (var c in highestLevelCharacters)
|
||||||
{
|
{
|
||||||
response.SynchroStandardCharacters.Add(c.Tid);
|
response.SynchroStandardCharacters.Add(c.Csn);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var currency in user.Currency)
|
foreach (var currency in user.Currency)
|
||||||
48
EpinelPS/LobbyServer/Msgs/Character/RegisterSynchroDevice.cs
Normal file
48
EpinelPS/LobbyServer/Msgs/Character/RegisterSynchroDevice.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
|
{
|
||||||
|
[PacketPath("/character/SynchroDevice/Regist")]
|
||||||
|
public class RegisterSynchroDevice : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqSynchroRegister>();
|
||||||
|
var user = GetUser();
|
||||||
|
var targetCharacter = user.GetCharacterBySerialNumber(req.Csn);
|
||||||
|
if (targetCharacter == null) throw new Exception("target character does not exist");
|
||||||
|
|
||||||
|
var response = new ResSynchroRegister();
|
||||||
|
foreach (var item in user.SynchroSlots)
|
||||||
|
{
|
||||||
|
if (item.Slot == req.Slot)
|
||||||
|
{
|
||||||
|
if (item.CharacterSerialNumber != 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("must remove character from synchrodevice first");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item.CharacterSerialNumber = req.Csn;
|
||||||
|
response.IsSynchro = true;
|
||||||
|
response.Character = new NetUserCharacterDefaultData()
|
||||||
|
{
|
||||||
|
Csn = item.CharacterSerialNumber,
|
||||||
|
CostumeId = targetCharacter.CostumeId,
|
||||||
|
Grade = targetCharacter.Grade,
|
||||||
|
Level = user.GetSynchroLevel(),
|
||||||
|
Skill1Lv = targetCharacter.Skill1Lvl,
|
||||||
|
Skill2Lv = targetCharacter.Skill2Lvl,
|
||||||
|
Tid = targetCharacter.Tid,
|
||||||
|
UltiSkillLv = targetCharacter.UltimateLevel
|
||||||
|
};
|
||||||
|
response.Slot = new NetSynchroSlot() { AvailableRegisterAt = item.AvailableAt, Csn = item.CharacterSerialNumber, Slot = item.Slot };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
EpinelPS/LobbyServer/Msgs/Character/ResetLevel.cs
Normal file
81
EpinelPS/LobbyServer/Msgs/Character/ResetLevel.cs
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.StaticInfo;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
|
{
|
||||||
|
[PacketPath("/character/growreset")]
|
||||||
|
public class ResetLevel : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqCharacterGrowReset>();
|
||||||
|
var user = GetUser();
|
||||||
|
var response = new ResCharacterGrowReset();
|
||||||
|
var data = GameData.Instance.GetCharacterLevelUpData();
|
||||||
|
|
||||||
|
foreach (var item in user.Characters.ToArray())
|
||||||
|
{
|
||||||
|
if (item.Csn == req.Csn)
|
||||||
|
{
|
||||||
|
if (item.Level == 1)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Character level is already 1 - cannot reset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (item.Level == 200)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Character level is 200 - cannot reset");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int requiredCredit = 0;
|
||||||
|
int requiredBattleData = 0;
|
||||||
|
int requiredCoreDust = 0;
|
||||||
|
for (int i = 1; i < item.Level; i++)
|
||||||
|
{
|
||||||
|
var levelUpData = data[i];
|
||||||
|
requiredCredit += levelUpData.gold;
|
||||||
|
requiredBattleData += levelUpData.character_exp;
|
||||||
|
requiredCoreDust += levelUpData.character_exp2;
|
||||||
|
}
|
||||||
|
|
||||||
|
user.AddCurrency(CurrencyType.Gold, requiredCredit);
|
||||||
|
user.AddCurrency(CurrencyType.CharacterExp, requiredBattleData);
|
||||||
|
user.AddCurrency(CurrencyType.CharacterExp2, requiredCoreDust);
|
||||||
|
item.Level = 1;
|
||||||
|
|
||||||
|
response.Character = new()
|
||||||
|
{
|
||||||
|
CostumeId = item.CostumeId,
|
||||||
|
Csn = item.Csn,
|
||||||
|
Level = item.Level,
|
||||||
|
Skill1Lv = item.Skill1Lvl,
|
||||||
|
Skill2Lv = item.Skill2Lvl,
|
||||||
|
UltiSkillLv = item.UltimateLevel,
|
||||||
|
Grade = item.Grade,
|
||||||
|
Tid = item.Tid
|
||||||
|
};
|
||||||
|
var highestLevelCharacters = user.Characters.OrderByDescending(x => x.Level).Take(5).ToList();
|
||||||
|
|
||||||
|
response.SynchroLv = highestLevelCharacters.Last().Level;
|
||||||
|
|
||||||
|
foreach (var c in highestLevelCharacters)
|
||||||
|
{
|
||||||
|
response.SynchroStandardCharacters.Add(c.Csn);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var currency in user.Currency)
|
||||||
|
{
|
||||||
|
response.Currencies.Add(new NetUserCurrencyData() { Type = (int)currency.Key, Value = currency.Value });
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
JsonDb.Save();
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Character
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
{
|
{
|
||||||
[PacketPath("/character/costume/set")]
|
[PacketPath("/character/costume/set")]
|
||||||
public class SetCharacterCostume : LobbyMsgHandler
|
public class SetCharacterCostume : LobbyMsgHandler
|
||||||
54
EpinelPS/LobbyServer/Msgs/Character/SynchroLevelUp.cs
Normal file
54
EpinelPS/LobbyServer/Msgs/Character/SynchroLevelUp.cs
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.StaticInfo;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
|
{
|
||||||
|
[PacketPath("/character/SynchroDevice/LevelUp")]
|
||||||
|
public class SynchroLevelUp : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqSynchroLevelUp>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
|
var response = new ResSynchroLevelUp();
|
||||||
|
var data = GameData.Instance.GetCharacterLevelUpData();
|
||||||
|
|
||||||
|
|
||||||
|
int requiredCredit = 0;
|
||||||
|
int requiredBattleData = 0;
|
||||||
|
int requiredCoreDust = 0;
|
||||||
|
var levelUpData = data[user.SynchroDeviceLevel + 1];
|
||||||
|
requiredCredit += levelUpData.gold;
|
||||||
|
requiredBattleData += levelUpData.character_exp;
|
||||||
|
requiredCoreDust += levelUpData.character_exp2;
|
||||||
|
|
||||||
|
if (user.CanSubtractCurrency(CurrencyType.Gold, requiredCredit) &&
|
||||||
|
user.CanSubtractCurrency(CurrencyType.CharacterExp, requiredBattleData) &&
|
||||||
|
user.CanSubtractCurrency(CurrencyType.CharacterExp2, requiredCoreDust))
|
||||||
|
{
|
||||||
|
user.SubtractCurrency(CurrencyType.Gold, requiredCredit);
|
||||||
|
user.SubtractCurrency(CurrencyType.CharacterExp, requiredBattleData);
|
||||||
|
user.SubtractCurrency(CurrencyType.CharacterExp2, requiredCoreDust);
|
||||||
|
user.SynchroDeviceLevel++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TOOD: log this
|
||||||
|
Console.WriteLine("ERROR: Not enough currency for upgrade");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var currency in user.Currency)
|
||||||
|
{
|
||||||
|
response.Currencies.Add(new NetUserCurrencyData() { Type = (int)currency.Key, Value = currency.Value });
|
||||||
|
}
|
||||||
|
response.SynchroLv = user.SynchroDeviceLevel;
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
using EpinelPS.Database;
|
||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Character
|
||||||
|
{
|
||||||
|
[PacketPath("/character/SynchroDevice/Unregist")]
|
||||||
|
public class UnregisterSynchroDevice : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqSynchroUnregist>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
|
var response = new ResSynchroUnregist();
|
||||||
|
|
||||||
|
foreach (var item in user.SynchroSlots)
|
||||||
|
{
|
||||||
|
if (item.Slot == req.Slot)
|
||||||
|
{
|
||||||
|
if (item.CharacterSerialNumber == 0)
|
||||||
|
{
|
||||||
|
Console.WriteLine("must add character from synchrodevice first");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var oldCSN = item.CharacterSerialNumber;
|
||||||
|
item.CharacterSerialNumber = 0;
|
||||||
|
var data = user.GetCharacterBySerialNumber(oldCSN);
|
||||||
|
if (data == null) throw new Exception("failed to lookup character");
|
||||||
|
|
||||||
|
response.Character = new NetUserCharacterDefaultData()
|
||||||
|
{
|
||||||
|
Csn = data.Csn,
|
||||||
|
CostumeId = data.CostumeId,
|
||||||
|
Grade = data.Grade,
|
||||||
|
Level = data.Level,
|
||||||
|
Skill1Lv = data.Skill1Lvl,
|
||||||
|
Skill2Lv = data.Skill2Lvl,
|
||||||
|
Tid = data.Tid,
|
||||||
|
UltiSkillLv = data.UltimateLevel
|
||||||
|
};
|
||||||
|
response.Slot = new NetSynchroSlot() { AvailableRegisterAt = item.AvailableAt, Csn = item.CharacterSerialNumber, Slot = item.Slot };
|
||||||
|
|
||||||
|
response.IsSynchro = false;
|
||||||
|
var highestLevelCharacters = user.Characters.OrderByDescending(x => x.Level).Take(5).ToList();
|
||||||
|
|
||||||
|
|
||||||
|
foreach (var item2 in highestLevelCharacters)
|
||||||
|
{
|
||||||
|
response.SynchroStandardCharacters.Add(item2.Csn);
|
||||||
|
}
|
||||||
|
|
||||||
|
response.SynchroLv = user.GetSynchroLevel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JsonDb.Save();
|
||||||
|
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Event
|
namespace EpinelPS.LobbyServer.Msgs.Event
|
||||||
{
|
{
|
||||||
[PacketPath("/event/scenario/complete")]
|
[PacketPath("/event/scenario/complete")]
|
||||||
public class CompleteEventScenario : LobbyMsgHandler
|
public class CompleteEventScenario : LobbyMsgHandler
|
||||||
@@ -11,16 +11,16 @@ namespace nksrv.LobbyServer.Msgs.Event
|
|||||||
var req = await ReadData<ReqSetEventScenarioComplete>();
|
var req = await ReadData<ReqSetEventScenarioComplete>();
|
||||||
var user = GetUser();
|
var user = GetUser();
|
||||||
|
|
||||||
if (user.EventInfo.ContainsKey(req.EventID))
|
if (user.EventInfo.ContainsKey(req.EventId))
|
||||||
{
|
{
|
||||||
var evt = user.EventInfo[req.EventID];
|
var evt = user.EventInfo[req.EventId];
|
||||||
evt.CompletedScenarios.Add(req.ScenarioId);
|
evt.CompletedScenarios.Add(req.ScenarioId);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var evt = new EventData();
|
var evt = new EventData();
|
||||||
evt.CompletedScenarios.Add(req.ScenarioId);
|
evt.CompletedScenarios.Add(req.ScenarioId);
|
||||||
user.EventInfo.Add(req.EventID, evt);
|
user.EventInfo.Add(req.EventId, evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
var response = new ResSetEventScenarioComplete();
|
var response = new ResSetEventScenarioComplete();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Event
|
namespace EpinelPS.LobbyServer.Msgs.Event
|
||||||
{
|
{
|
||||||
[PacketPath("/eventfield/enter")]
|
[PacketPath("/eventfield/enter")]
|
||||||
public class EnterEventField : LobbyMsgHandler
|
public class EnterEventField : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Event
|
namespace EpinelPS.LobbyServer.Msgs.Event
|
||||||
{
|
{
|
||||||
[PacketPath("/event/mission/getclear")]
|
[PacketPath("/event/mission/getclear")]
|
||||||
public class GetClearedMissions : LobbyMsgHandler
|
public class GetClearedMissions : LobbyMsgHandler
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Event
|
namespace EpinelPS.LobbyServer.Msgs.Event
|
||||||
{
|
{
|
||||||
[PacketPath("/event/scenario/get")]
|
[PacketPath("/event/scenario/get")]
|
||||||
public class GetEventScenario : LobbyMsgHandler
|
public class GetEventScenario : LobbyMsgHandler
|
||||||
@@ -12,14 +12,14 @@ namespace nksrv.LobbyServer.Msgs.Event
|
|||||||
var user = GetUser();
|
var user = GetUser();
|
||||||
|
|
||||||
var response = new ResGetEventScenarioData();
|
var response = new ResGetEventScenarioData();
|
||||||
if (user.EventInfo.ContainsKey(req.EventID))
|
if (user.EventInfo.ContainsKey(req.EventId))
|
||||||
{
|
{
|
||||||
var evt = user.EventInfo[req.EventID];
|
var evt = user.EventInfo[req.EventId];
|
||||||
response.ScenarioIdList.AddRange(evt.CompletedScenarios);
|
response.ScenarioIdList.AddRange(evt.CompletedScenarios);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
user.EventInfo.Add(req.EventID, new EventData());
|
user.EventInfo.Add(req.EventId, new EventData());
|
||||||
}
|
}
|
||||||
|
|
||||||
await WriteDataAsync(response);
|
await WriteDataAsync(response);
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Event
|
namespace EpinelPS.LobbyServer.Msgs.Event
|
||||||
{
|
{
|
||||||
[PacketPath("/event/getjoinedevent")]
|
[PacketPath("/event/getjoinedevent")]
|
||||||
public class GetJoinedEvent : LobbyMsgHandler
|
public class GetJoinedEvent : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Event
|
namespace EpinelPS.LobbyServer.Msgs.Event
|
||||||
{
|
{
|
||||||
[PacketPath("/event/list")]
|
[PacketPath("/event/list")]
|
||||||
public class ListEvents : LobbyMsgHandler
|
public class ListEvents : LobbyMsgHandler
|
||||||
@@ -14,10 +14,10 @@ namespace nksrv.LobbyServer.Msgs.Event
|
|||||||
response.EventList.Add(new NetEventData()
|
response.EventList.Add(new NetEventData()
|
||||||
{
|
{
|
||||||
Id = 81301,
|
Id = 81301,
|
||||||
EventDisableDate = 1000000000000000,
|
EventDisableDate = DateTime.Now.AddDays(20).Ticks,
|
||||||
EventStartDate = 1,
|
EventStartDate = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)).Ticks,
|
||||||
EventEndDate = 1000000000000000,
|
EventEndDate = DateTime.Now.AddDays(20).Ticks,
|
||||||
EventVisibleDate = 0,
|
EventVisibleDate = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)).Ticks,
|
||||||
EventSystemType = 34
|
EventSystemType = 34
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -27,10 +27,10 @@ namespace nksrv.LobbyServer.Msgs.Event
|
|||||||
response.EventList.Add(new NetEventData()
|
response.EventList.Add(new NetEventData()
|
||||||
{
|
{
|
||||||
Id = 20001,
|
Id = 20001,
|
||||||
EventDisableDate = 1000000000000000,
|
EventDisableDate = DateTime.Now.AddDays(20).Ticks,
|
||||||
EventStartDate = 1,
|
EventStartDate = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)).Ticks,
|
||||||
EventEndDate = 1000000000000000,
|
EventEndDate = DateTime.Now.AddDays(20).Ticks,
|
||||||
EventVisibleDate = 0,
|
EventVisibleDate = DateTime.UtcNow.Subtract(TimeSpan.FromDays(1)).Ticks,
|
||||||
EventSystemType = 1
|
EventSystemType = 1
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Event.StoryEvent
|
namespace EpinelPS.LobbyServer.Msgs.Event.StoryEvent
|
||||||
{
|
{
|
||||||
[PacketPath("/event/storydungeon/get")]
|
[PacketPath("/event/storydungeon/get")]
|
||||||
public class GetStoryDungeon : LobbyMsgHandler
|
public class GetStoryDungeon : LobbyMsgHandler
|
||||||
@@ -17,7 +17,8 @@ namespace nksrv.LobbyServer.Msgs.Event.StoryEvent
|
|||||||
|
|
||||||
var response = new ResStoryDungeonEventData()
|
var response = new ResStoryDungeonEventData()
|
||||||
{
|
{
|
||||||
TeamData = new NetUserTeamData()
|
TeamData = new NetUserTeamData(),
|
||||||
|
RemainTicket = 10,
|
||||||
};
|
};
|
||||||
|
|
||||||
// TOOD
|
// TOOD
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.FavoriteItem
|
namespace EpinelPS.LobbyServer.Msgs.FavoriteItem
|
||||||
{
|
{
|
||||||
[PacketPath("/favoriteitem/library")]
|
[PacketPath("/favoriteitem/library")]
|
||||||
public class GetFavoriteItemLibrary : LobbyMsgHandler
|
public class GetFavoriteItemLibrary : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.FavoriteItem
|
namespace EpinelPS.LobbyServer.Msgs.FavoriteItem
|
||||||
{
|
{
|
||||||
[PacketPath("/favoriteitem/list")]
|
[PacketPath("/favoriteitem/list")]
|
||||||
public class ListFavoriteItem : LobbyMsgHandler
|
public class ListFavoriteItem : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.FavoriteItem
|
namespace EpinelPS.LobbyServer.Msgs.FavoriteItem
|
||||||
{
|
{
|
||||||
[PacketPath("/favoriteitem/quest/list")]
|
[PacketPath("/favoriteitem/quest/list")]
|
||||||
public class ListFavoriteItemQuests : LobbyMsgHandler
|
public class ListFavoriteItemQuests : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Friend
|
namespace EpinelPS.LobbyServer.Msgs.Friend
|
||||||
{
|
{
|
||||||
[PacketPath("/friend/get")]
|
[PacketPath("/friend/get")]
|
||||||
public class GetFriends : LobbyMsgHandler
|
public class GetFriends : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Gacha
|
namespace EpinelPS.LobbyServer.Msgs.Gacha
|
||||||
{
|
{
|
||||||
[PacketPath("/gacha/event/check")]
|
[PacketPath("/gacha/event/check")]
|
||||||
public class CheckGachaDailyEvent : LobbyMsgHandler
|
public class CheckGachaDailyEvent : LobbyMsgHandler
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.StaticInfo;
|
using EpinelPS.StaticInfo;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Gacha
|
namespace EpinelPS.LobbyServer.Msgs.Gacha
|
||||||
{
|
{
|
||||||
[PacketPath("/gacha/execute")]
|
[PacketPath("/gacha/execute")]
|
||||||
public class ExecGacha : LobbyMsgHandler
|
public class ExecGacha : LobbyMsgHandler
|
||||||
@@ -19,17 +19,23 @@ namespace nksrv.LobbyServer.Msgs.Gacha
|
|||||||
// TODO implement reward
|
// TODO implement reward
|
||||||
response.Reward = new NetRewardData();
|
response.Reward = new NetRewardData();
|
||||||
|
|
||||||
if (user.GachaTutorialPlayCount == 0)
|
foreach (var c in GameData.Instance.GetAllCharacterTids())
|
||||||
{
|
{
|
||||||
foreach (var c in StaticDataParser.Instance.GetAllCharacterTids())
|
if (!user.HasCharacter(c))
|
||||||
{
|
{
|
||||||
response.Gacha.Add(new NetGachaEntityData() { Corporation = 1, PieceCount = 1, CurrencyValue = 5, Sn = c, Tid = c, Type = 1 });
|
var id = user.GenerateUniqueCharacterId();
|
||||||
|
response.Gacha.Add(new NetGachaEntityData() { Corporation = 1, PieceCount = 1, CurrencyValue = 5, Sn = id, Tid = c, Type = 1 });
|
||||||
|
|
||||||
response.Characters.Add(new NetUserCharacterDefaultData() { CostumeId = 0, Csn = c, Grade = 0, Lv = 1, Skill1Lv = 1, Skill2Lv = 1, Tid = c, UltiSkillLv = 1 });
|
response.Characters.Add(new NetUserCharacterDefaultData() { CostumeId = 0, Csn = id, Grade = 0, Level = 1, Skill1Lv = 1, Skill2Lv = 1, Tid = c, UltiSkillLv = 1 });
|
||||||
user.Characters.Add(new Database.Character() { CostumeId = 0, Csn = c, Grade = 0, Level = 1, Skill1Lvl = 1, Skill2Lvl = 1, Tid = c, UltimateLevel = 1 });
|
|
||||||
|
user.Characters.Add(new Database.Character() { CostumeId = 0, Csn = id, Grade = 0, Level = 1, Skill1Lvl = 1, Skill2Lvl = 1, Tid = c, UltimateLevel = 1 });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO add spare body
|
||||||
}
|
}
|
||||||
user.GachaTutorialPlayCount++;
|
|
||||||
}
|
}
|
||||||
|
user.GachaTutorialPlayCount++;
|
||||||
|
|
||||||
JsonDb.Save();
|
JsonDb.Save();
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using Google.Protobuf.WellKnownTypes;
|
using Google.Protobuf.WellKnownTypes;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs
|
namespace EpinelPS.LobbyServer.Msgs
|
||||||
{
|
{
|
||||||
[PacketPath("/now")]
|
[PacketPath("/now")]
|
||||||
public class GetCurrentTime : LobbyMsgHandler
|
public class GetCurrentTime : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs
|
namespace EpinelPS.LobbyServer.Msgs
|
||||||
{
|
{
|
||||||
[PacketPath("/Gacha/Get")]
|
[PacketPath("/Gacha/Get")]
|
||||||
public class GetGacha : LobbyMsgHandler
|
public class GetGacha : LobbyMsgHandler
|
||||||
23
EpinelPS/LobbyServer/Msgs/Intercept/GetInterceptData.cs
Normal file
23
EpinelPS/LobbyServer/Msgs/Intercept/GetInterceptData.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Intercept
|
||||||
|
{
|
||||||
|
[PacketPath("/intercept/get")]
|
||||||
|
public class GetInterceptData : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqGetInterceptData>();
|
||||||
|
|
||||||
|
var response = new ResGetInterceptData
|
||||||
|
{
|
||||||
|
NormalInterceptGroup = 1,
|
||||||
|
SpecialInterceptId = 1,
|
||||||
|
TicketCount = 5,
|
||||||
|
MaxTicketCount = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
EpinelPS/LobbyServer/Msgs/Intercept/InterceptCheck.cs
Normal file
20
EpinelPS/LobbyServer/Msgs/Intercept/InterceptCheck.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Intercept
|
||||||
|
{
|
||||||
|
[PacketPath("/intercept/check")]
|
||||||
|
public class CheckClearInterceptToday : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqCheckClearInterceptToday>();
|
||||||
|
|
||||||
|
var response = new ResCheckClearInterceptToday
|
||||||
|
{
|
||||||
|
Clear = true
|
||||||
|
};
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
23
EpinelPS/LobbyServer/Msgs/Intercept/InterceptClear.cs
Normal file
23
EpinelPS/LobbyServer/Msgs/Intercept/InterceptClear.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Intercept
|
||||||
|
{
|
||||||
|
[PacketPath("/intercept/clear")]
|
||||||
|
public class ClearInterceptData : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqClearIntercept>();
|
||||||
|
|
||||||
|
var response = new ResClearIntercept
|
||||||
|
{
|
||||||
|
Intercept = 1,
|
||||||
|
InterceptId = 1,
|
||||||
|
TicketCount = 5,
|
||||||
|
MaxTicketCount = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
17
EpinelPS/LobbyServer/Msgs/Intercept/InterceptEnter.cs
Normal file
17
EpinelPS/LobbyServer/Msgs/Intercept/InterceptEnter.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Intercept
|
||||||
|
{
|
||||||
|
[PacketPath("/intercept/enter")]
|
||||||
|
public class EnterInterceptData : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqEnterIntercept>();
|
||||||
|
|
||||||
|
var response = new ResEnterIntercept();
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
22
EpinelPS/LobbyServer/Msgs/Intercept/InterceptFastClear.cs
Normal file
22
EpinelPS/LobbyServer/Msgs/Intercept/InterceptFastClear.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Intercept
|
||||||
|
{
|
||||||
|
[PacketPath("/intercept/fastclear")]
|
||||||
|
public class FastClearInterceptData : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqFastClearIntercept>();
|
||||||
|
|
||||||
|
var response = new ResFastClearIntercept
|
||||||
|
{
|
||||||
|
TicketCount = 3,
|
||||||
|
MaxTicketCount = 10,
|
||||||
|
Damage = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Inventory
|
namespace EpinelPS.LobbyServer.Msgs.Inventory
|
||||||
{
|
{
|
||||||
[PacketPath("/inventory/allclearequipment")]
|
[PacketPath("/inventory/allclearequipment")]
|
||||||
public class ClearAllEquipment : LobbyMsgHandler
|
public class ClearAllEquipment : LobbyMsgHandler
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Inventory
|
namespace EpinelPS.LobbyServer.Msgs.Inventory
|
||||||
{
|
{
|
||||||
[PacketPath("/inventory/clearequipment")]
|
[PacketPath("/inventory/clearequipment")]
|
||||||
public class ClearEquipment : LobbyMsgHandler
|
public class ClearEquipment : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Inventory
|
namespace EpinelPS.LobbyServer.Msgs.Inventory
|
||||||
{
|
{
|
||||||
[PacketPath("/inventory/get")]
|
[PacketPath("/inventory/get")]
|
||||||
public class GetInventoryData : LobbyMsgHandler
|
public class GetInventoryData : LobbyMsgHandler
|
||||||
@@ -13,7 +13,7 @@ namespace nksrv.LobbyServer.Msgs.Inventory
|
|||||||
var response = new ResGetInventoryData();
|
var response = new ResGetInventoryData();
|
||||||
foreach (var item in user.Items)
|
foreach (var item in user.Items)
|
||||||
{
|
{
|
||||||
response.Items.Add(new NetUserItemData() { Count = item.Count, Tid = item.ItemType, Csn = item.Csn, Lv = item.Level, Exp = item.Exp, Corporation = item.Corp, Isn = item.Isn, Position = item.Position });
|
response.Items.Add(new NetUserItemData() { Count = item.Count, Tid = item.ItemType, Csn = item.Csn, Level = item.Level, Exp = item.Exp, Corporation = item.Corp, Isn = item.Isn, Position = item.Position });
|
||||||
}
|
}
|
||||||
// TODO: HarmonyCubes, RunAwakeningIsnList, UserRedeems
|
// TODO: HarmonyCubes, RunAwakeningIsnList, UserRedeems
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Inventory
|
namespace EpinelPS.LobbyServer.Msgs.Inventory
|
||||||
{
|
{
|
||||||
[PacketPath("/inventory/wearequipment")]
|
[PacketPath("/inventory/wearequipment")]
|
||||||
public class WearEquipment : LobbyMsgHandler
|
public class WearEquipment : LobbyMsgHandler
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
using nksrv.Database;
|
using EpinelPS.Database;
|
||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Inventory
|
namespace EpinelPS.LobbyServer.Msgs.Inventory
|
||||||
{
|
{
|
||||||
[PacketPath("/inventory/wearequipmentlist")]
|
[PacketPath("/inventory/wearequipmentlist")]
|
||||||
public class WearEquipmentList : LobbyMsgHandler
|
public class WearEquipmentList : LobbyMsgHandler
|
||||||
@@ -1,28 +1,22 @@
|
|||||||
using nksrv.Net;
|
using EpinelPS.Utils;
|
||||||
using nksrv.Utils;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Liberate
|
namespace EpinelPS.LobbyServer.Msgs.Liberate
|
||||||
{
|
{
|
||||||
[PacketPath("/liberate/choosecharacter")]
|
[PacketPath("/liberate/choosecharacter")]
|
||||||
public class ChooseCharacter : LobbyMsgHandler
|
public class ChooseCharacter : LobbyMsgHandler
|
||||||
{
|
{
|
||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var req = await ReadData<ChooseLiberateCharacterRequest>();
|
var req = await ReadData<ReqChooseLiberateCharacter>();
|
||||||
var user = GetUser();
|
var user = GetUser();
|
||||||
|
|
||||||
var response = new ChooseLiberateCharacterResponse();
|
var response = new ResChooseLiberateCharacter();
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
response.Data = new NetLiberateData() { CharacterId = req.CharacterId };
|
response.Data = new NetLiberateData() { CharacterId = req.CharacterId };
|
||||||
response.Data.MissionData.Add(new NetLiberateMissionData() { MissionState = LiberateMissionState.Running, Id = 1 });
|
response.Data.MissionData.Add(new NetLiberateMissionData() { MissionState = LiberateMissionState.LiberateMissionStateRunning, Id = 1 });
|
||||||
response.Data.MissionData.Add(new NetLiberateMissionData() { MissionState = LiberateMissionState.Running, Id = 2 });
|
response.Data.MissionData.Add(new NetLiberateMissionData() { MissionState = LiberateMissionState.LiberateMissionStateRunning, Id = 2 });
|
||||||
response.Data.MissionData.Add(new NetLiberateMissionData() { MissionState = LiberateMissionState.Running, Id = 3 });
|
response.Data.MissionData.Add(new NetLiberateMissionData() { MissionState = LiberateMissionState.LiberateMissionStateRunning, Id = 3 });
|
||||||
|
|
||||||
await WriteDataAsync(response);
|
await WriteDataAsync(response);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Liberate
|
namespace EpinelPS.LobbyServer.Msgs.Liberate
|
||||||
{
|
{
|
||||||
[PacketPath("/liberate/get")]
|
[PacketPath("/liberate/get")]
|
||||||
public class GetLiberateData : LobbyMsgHandler
|
public class GetLiberateData : LobbyMsgHandler
|
||||||
20
EpinelPS/LobbyServer/Msgs/Liberate/GetProgressList.cs
Normal file
20
EpinelPS/LobbyServer/Msgs/Liberate/GetProgressList.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Liberate
|
||||||
|
{
|
||||||
|
[PacketPath("/liberate/getprogresslist")]
|
||||||
|
public class GetProgressList : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqGetLiberateProgressList>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
|
var response = new ResGetLiberateProgressList();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Lostsector
|
namespace EpinelPS.LobbyServer.Msgs.Lostsector
|
||||||
{
|
{
|
||||||
[PacketPath("/lostsector/get")]
|
[PacketPath("/lostsector/get")]
|
||||||
public class GetLostSectorData : LobbyMsgHandler
|
public class GetLostSectorData : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Messenger
|
namespace EpinelPS.LobbyServer.Msgs.Messenger
|
||||||
{
|
{
|
||||||
[PacketPath("/messenger/daily/pick")]
|
[PacketPath("/messenger/daily/pick")]
|
||||||
public class GetDailyMessage : LobbyMsgHandler
|
public class GetDailyMessage : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Messenger
|
namespace EpinelPS.LobbyServer.Msgs.Messenger
|
||||||
{
|
{
|
||||||
[PacketPath("/messenger/get")]
|
[PacketPath("/messenger/get")]
|
||||||
public class GetMessages : LobbyMsgHandler
|
public class GetMessages : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Messenger
|
namespace EpinelPS.LobbyServer.Msgs.Messenger
|
||||||
{
|
{
|
||||||
[PacketPath("/messenger/picked/get")]
|
[PacketPath("/messenger/picked/get")]
|
||||||
public class GetPickedMessage : LobbyMsgHandler
|
public class GetPickedMessage : LobbyMsgHandler
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Messenger
|
namespace EpinelPS.LobbyServer.Msgs.Messenger
|
||||||
{
|
{
|
||||||
[PacketPath("/messenger/random/pick")]
|
[PacketPath("/messenger/random/pick")]
|
||||||
public class GetRandomPick : LobbyMsgHandler
|
public class GetRandomPick : LobbyMsgHandler
|
||||||
{
|
{
|
||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var req = await ReadData<ReqForcePickTodayRandomMessage>();
|
var req = await ReadData<ReqPickTodayRandomMessage>();
|
||||||
|
|
||||||
// TODO: get proper response
|
// TODO: get proper response
|
||||||
var response = new ResForcePickTodayRandomMessage();
|
var response = new ResPickTodayRandomMessage();
|
||||||
|
|
||||||
await WriteDataAsync(response);
|
await WriteDataAsync(response);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Messenger
|
namespace EpinelPS.LobbyServer.Msgs.Messenger
|
||||||
{
|
{
|
||||||
[PacketPath("/messenger/proceed")]
|
[PacketPath("/messenger/proceed")]
|
||||||
public class ProceedMsg : LobbyMsgHandler
|
public class ProceedMsg : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Minigame.Dave
|
namespace EpinelPS.LobbyServer.Msgs.Minigame.Dave
|
||||||
{
|
{
|
||||||
[PacketPath("/event/minigame/dave/getalldavetrigger")]
|
[PacketPath("/event/minigame/dave/getalldavetrigger")]
|
||||||
public class GetAllDaveTrigger : LobbyMsgHandler
|
public class GetAllDaveTrigger : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Minigame
|
namespace EpinelPS.LobbyServer.Msgs.Minigame
|
||||||
{
|
{
|
||||||
[PacketPath("/minigame/nksv2/get")]
|
[PacketPath("/minigame/nksv2/get")]
|
||||||
public class GetNksv2Minigame : LobbyMsgHandler
|
public class GetNksv2Minigame : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Minigame.IslandAdventure
|
namespace EpinelPS.LobbyServer.Msgs.Minigame.IslandAdventure
|
||||||
{
|
{
|
||||||
[PacketPath("/event/minigame/islandadventure/get/fishing/stepupreward")]
|
[PacketPath("/event/minigame/islandadventure/get/fishing/stepupreward")]
|
||||||
public class GetFishingStepUpRewardStatus : LobbyMsgHandler
|
public class GetFishingStepUpRewardStatus : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Minigame.IslandAdventure
|
namespace EpinelPS.LobbyServer.Msgs.Minigame.IslandAdventure
|
||||||
{
|
{
|
||||||
[PacketPath("/event/minigame/islandadventure/get/photo/stepupreward")]
|
[PacketPath("/event/minigame/islandadventure/get/photo/stepupreward")]
|
||||||
public class GetPhotoStepUpRewardStatus : LobbyMsgHandler
|
public class GetPhotoStepUpRewardStatus : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Minigame.IslandAdventure
|
namespace EpinelPS.LobbyServer.Msgs.Minigame.IslandAdventure
|
||||||
{
|
{
|
||||||
[PacketPath("/event/minigame/islandadventure/list/mission")]
|
[PacketPath("/event/minigame/islandadventure/list/mission")]
|
||||||
public class ListMission : LobbyMsgHandler
|
public class ListMission : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Minigame.PlaySoda
|
namespace EpinelPS.LobbyServer.Msgs.Minigame.PlaySoda
|
||||||
{
|
{
|
||||||
[PacketPath("/event/minigame/playsoda/challenge/getinfo")]
|
[PacketPath("/event/minigame/playsoda/challenge/getinfo")]
|
||||||
public class GetChallengeInfo : LobbyMsgHandler
|
public class GetChallengeInfo : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Misc
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
{
|
{
|
||||||
[PacketPath("/enterlobbyping")]
|
[PacketPath("/enterlobbyping")]
|
||||||
public class EnterLobbyPing : LobbyMsgHandler
|
public class EnterLobbyPing : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Misc
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
{
|
{
|
||||||
[PacketPath("/shutdownflags/gacha/getall")]
|
[PacketPath("/shutdownflags/gacha/getall")]
|
||||||
public class GachaGetAllShutdownFlags : LobbyMsgHandler
|
public class GachaGetAllShutdownFlags : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Misc
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
{
|
{
|
||||||
[PacketPath("/featureflags/get")]
|
[PacketPath("/featureflags/get")]
|
||||||
public class GetFeatureFlags : LobbyMsgHandler
|
public class GetFeatureFlags : LobbyMsgHandler
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
using nksrv.Net;
|
using EpinelPS.Utils;
|
||||||
using nksrv.Utils;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Misc
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
{
|
{
|
||||||
[PacketPath("/maintenancenotice")]
|
[PacketPath("/maintenancenotice")]
|
||||||
public class GetMaintenanceNotice : LobbyMsgHandler
|
public class GetMaintenanceNotice : LobbyMsgHandler
|
||||||
{
|
{
|
||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var r = new MaintenanceNoticeResponse();
|
var r = new ResMaintenanceNotice();
|
||||||
|
|
||||||
await WriteDataAsync(r);
|
await WriteDataAsync(r);
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
using nksrv.Net;
|
using EpinelPS.Utils;
|
||||||
using nksrv.Utils;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Misc
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
{
|
{
|
||||||
[PacketPath("/resourcehosts2")]
|
[PacketPath("/resourcehosts2")]
|
||||||
public class CheckClientVersion : LobbyMsgHandler
|
public class CheckClientVersion : LobbyMsgHandler
|
||||||
{
|
{
|
||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var req = await ReadData<ResourceHostRequest>();
|
var req = await ReadData<ReqGetResourceHosts2>();
|
||||||
|
|
||||||
var r = new ResourceHostResponse();
|
var r = new ResGetResourceHosts2();
|
||||||
r.BaseUrl = GameConfig.Root.ResourceBaseURL;
|
r.BaseUrl = GameConfig.Root.ResourceBaseURL;
|
||||||
|
r.Version = req.Version;
|
||||||
|
|
||||||
await WriteDataAsync(r);
|
await WriteDataAsync(r);
|
||||||
}
|
}
|
||||||
17
EpinelPS/LobbyServer/Msgs/Misc/GetSentryParams.cs
Normal file
17
EpinelPS/LobbyServer/Msgs/Misc/GetSentryParams.cs
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
|
{
|
||||||
|
[PacketPath("/system/sentry/getparams")]
|
||||||
|
public class GetSentryParams : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var r = new ResGetSentryParams();
|
||||||
|
// TODO: Figure out a way so that the game developers would not be annoyed by bogus errors in Sentry dashboard
|
||||||
|
r.SamplingRate = 1E-06;
|
||||||
|
r.TraceSamplingRate = 1E-06;
|
||||||
|
await WriteDataAsync(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
using nksrv.Net;
|
using EpinelPS.Utils;
|
||||||
using nksrv.Utils;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Misc
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
{
|
{
|
||||||
[PacketPath("/getserverinfo")]
|
[PacketPath("/getserverinfo")]
|
||||||
public class GetServerInfo : LobbyMsgHandler
|
public class GetServerInfo : LobbyMsgHandler
|
||||||
{
|
{
|
||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var r = new GetServerInfoResponse();
|
var r = new ResGetServerInfo();
|
||||||
|
|
||||||
// todo: reimplement this as well
|
// todo: reimplement this as well
|
||||||
r.MatchUrl = "https://global-match.nikke-kr.com";
|
r.MatchUrl = "https://global-match.nikke-kr.com";
|
||||||
@@ -1,22 +1,21 @@
|
|||||||
using Google.Protobuf;
|
using EpinelPS.StaticInfo;
|
||||||
using nksrv.Net;
|
using EpinelPS.Utils;
|
||||||
using nksrv.StaticInfo;
|
using Google.Protobuf;
|
||||||
using nksrv.Utils;
|
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Misc
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
{
|
{
|
||||||
[PacketPath("/staticdatapack")]
|
[PacketPath("/staticdatapack")]
|
||||||
public class GetStaticDataPack : LobbyMsgHandler
|
public class GetStaticDataPack : LobbyMsgHandler
|
||||||
{
|
{
|
||||||
protected override async Task HandleAsync()
|
protected override async Task HandleAsync()
|
||||||
{
|
{
|
||||||
var req = await ReadData<StaticDataPackRequest>();
|
var req = await ReadData<ReqStaticDataPackInfo>();
|
||||||
|
|
||||||
var r = new StaticDataPackResponse();
|
var r = new ResStaticDataPackInfo();
|
||||||
r.Url = GameConfig.Root.StaticData.Url;
|
r.Url = GameConfig.Root.StaticData.Url;
|
||||||
r.Version = GameConfig.Root.StaticData.Version;
|
r.Version = GameConfig.Root.StaticData.Version;
|
||||||
r.FileSize = StaticDataParser.Instance.Size;
|
r.Size = GameData.Instance.Size;
|
||||||
r.Sha256Sum = ByteString.CopyFrom(StaticDataParser.Instance.Sha256Hash);
|
r.Sha256Sum = ByteString.CopyFrom(GameData.Instance.Sha256Hash);
|
||||||
r.Salt1 = ByteString.CopyFrom(Convert.FromBase64String(GameConfig.Root.StaticData.Salt1));
|
r.Salt1 = ByteString.CopyFrom(Convert.FromBase64String(GameConfig.Root.StaticData.Salt1));
|
||||||
r.Salt2 = ByteString.CopyFrom(Convert.FromBase64String(GameConfig.Root.StaticData.Salt2));
|
r.Salt2 = ByteString.CopyFrom(Convert.FromBase64String(GameConfig.Root.StaticData.Salt2));
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Misc
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
{
|
{
|
||||||
[PacketPath("/useronlinestatelog")]
|
[PacketPath("/useronlinestatelog")]
|
||||||
public class GetUserOnlineStateLog : LobbyMsgHandler
|
public class GetUserOnlineStateLog : LobbyMsgHandler
|
||||||
22
EpinelPS/LobbyServer/Msgs/Misc/Retroactive.cs
Normal file
22
EpinelPS/LobbyServer/Msgs/Misc/Retroactive.cs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Misc
|
||||||
|
{
|
||||||
|
[PacketPath("/lobby/retroactive")]
|
||||||
|
public class LobbyRetroactive : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqRetroactive>();
|
||||||
|
var user = GetUser();
|
||||||
|
|
||||||
|
var response = new ResRetroactive();
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Mission
|
namespace EpinelPS.LobbyServer.Msgs.Mission
|
||||||
{
|
{
|
||||||
[PacketPath("/mission/getrewarded/achievement")]
|
[PacketPath("/mission/getrewarded/achievement")]
|
||||||
public class GetAchievementRewardedData : LobbyMsgHandler
|
public class GetAchievementRewardedData : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Mission.Rewards
|
namespace EpinelPS.LobbyServer.Msgs.Mission.Rewards
|
||||||
{
|
{
|
||||||
[PacketPath("/mission/getrewarded/daily")]
|
[PacketPath("/mission/getrewarded/daily")]
|
||||||
public class GetDailyRewards : LobbyMsgHandler
|
public class GetDailyRewards : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Outpost
|
namespace EpinelPS.LobbyServer.Msgs.Outpost
|
||||||
{
|
{
|
||||||
[PacketPath("/mission/getrewarded/jukebox")]
|
[PacketPath("/mission/getrewarded/jukebox")]
|
||||||
public class GetJukeboxRewards : LobbyMsgHandler
|
public class GetJukeboxRewards : LobbyMsgHandler
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Mission.Rewards
|
namespace EpinelPS.LobbyServer.Msgs.Mission.Rewards
|
||||||
{
|
{
|
||||||
[PacketPath("/mission/getrewarded/weekly")]
|
[PacketPath("/mission/getrewarded/weekly")]
|
||||||
public class GetWeeklyRewards : LobbyMsgHandler
|
public class GetWeeklyRewards : LobbyMsgHandler
|
||||||
24
EpinelPS/LobbyServer/Msgs/Outpost/BuildBuilding.cs
Normal file
24
EpinelPS/LobbyServer/Msgs/Outpost/BuildBuilding.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
using EpinelPS.Utils;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace EpinelPS.LobbyServer.Msgs.Outpost
|
||||||
|
{
|
||||||
|
[PacketPath("/outpost/building")]
|
||||||
|
public class BuildBuilding : LobbyMsgHandler
|
||||||
|
{
|
||||||
|
protected override async Task HandleAsync()
|
||||||
|
{
|
||||||
|
var req = await ReadData<ReqBuilding>();
|
||||||
|
|
||||||
|
var response = new ResBuilding();
|
||||||
|
response.StartAt = DateTime.UtcNow.Ticks;
|
||||||
|
response.CompleteAt = DateTime.UtcNow.AddDays(1).Ticks;
|
||||||
|
// TODO
|
||||||
|
await WriteDataAsync(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
using nksrv.Utils;
|
using EpinelPS.Utils;
|
||||||
|
|
||||||
namespace nksrv.LobbyServer.Msgs.Outpost
|
namespace EpinelPS.LobbyServer.Msgs.Outpost
|
||||||
{
|
{
|
||||||
[PacketPath("/infracore/check")]
|
[PacketPath("/infracore/check")]
|
||||||
public class CheckInfracore : LobbyMsgHandler
|
public class CheckInfracore : LobbyMsgHandler
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user