forked from Moux23333/FreeSR
fork from 1.3
This commit is contained in:
commit
22fc0b0848
1507 changed files with 24139 additions and 0 deletions
398
.gitignore
vendored
Normal file
398
.gitignore
vendored
Normal file
|
@ -0,0 +1,398 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Ww][Ii][Nn]32/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# ASP.NET Scaffolding
|
||||
ScaffoldingReadMe.txt
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
*.obj
|
||||
*.iobj
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.tlog
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Coverlet is a free, cross platform Code Coverage Tool
|
||||
coverage*.json
|
||||
coverage*.xml
|
||||
coverage*.info
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||
*.vbp
|
||||
|
||||
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||
*.dsw
|
||||
*.dsp
|
||||
|
||||
# Visual Studio 6 technical files
|
||||
*.ncb
|
||||
*.aps
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# Visual Studio History (VSHistory) files
|
||||
.vshistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
|
||||
# Fody - auto-generated XML schema
|
||||
FodyWeavers.xsd
|
||||
|
||||
# VS Code files for those working on multiple tools
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
# Local History for Visual Studio Code
|
||||
.history/
|
||||
|
||||
# Windows Installer files from build outputs
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# JetBrains Rider
|
||||
*.sln.iml
|
48
FreeSR.Admin/AdminServer.cs
Normal file
48
FreeSR.Admin/AdminServer.cs
Normal file
|
@ -0,0 +1,48 @@
|
|||
namespace FreeSR.Admin
|
||||
{
|
||||
using FreeSR.Admin.Command.Handlers;
|
||||
using FreeSR.Admin.Service;
|
||||
using FreeSR.Shared.Command;
|
||||
using FreeSR.Shared.Configuration;
|
||||
using FreeSR.Shared.Exceptions;
|
||||
using NLog;
|
||||
|
||||
internal static class AdminServer
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Directory.SetCurrentDirectory(AppContext.BaseDirectory);
|
||||
AppDomain.CurrentDomain.UnhandledException += OnFatalException;
|
||||
|
||||
s_log.Info("Initializing...");
|
||||
|
||||
CommandManager.Instance.Initialize(typeof(AccountCommandCategory));
|
||||
ConfigurationManager<AdminServerConfiguration>.Instance.Initialize("AdminServer.json");
|
||||
var serverConfiguration = ConfigurationManager<AdminServerConfiguration>.Instance.Model;
|
||||
|
||||
HttpAdminService.Initialize(serverConfiguration.Network);
|
||||
|
||||
s_log.Info("Server is ready!");
|
||||
Thread.Sleep(-1);
|
||||
}
|
||||
|
||||
private static void OnFatalException(object sender, UnhandledExceptionEventArgs args)
|
||||
{
|
||||
if (args.ExceptionObject is ServerInitializationException initException)
|
||||
{
|
||||
Console.WriteLine("Server initialization failed, unhandled exception!");
|
||||
Console.WriteLine(initException);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unhandled exception in runtime!");
|
||||
Console.WriteLine(args.ExceptionObject);
|
||||
}
|
||||
|
||||
Console.WriteLine("Press enter to close this window...");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
7
FreeSR.Admin/AdminServer.example.json
Normal file
7
FreeSR.Admin/AdminServer.example.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"Network": {
|
||||
"Host": "0.0.0.0",
|
||||
"Port": 1337
|
||||
},
|
||||
"DispatchUrl": "http://localhost:8888"
|
||||
}
|
10
FreeSR.Admin/AdminServerConfiguration.cs
Normal file
10
FreeSR.Admin/AdminServerConfiguration.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace FreeSR.Admin
|
||||
{
|
||||
using FreeSR.Shared.Configuration;
|
||||
|
||||
internal class AdminServerConfiguration
|
||||
{
|
||||
public NetworkConfiguration Network { get; set; }
|
||||
public string DispatchUrl { get; set; }
|
||||
}
|
||||
}
|
19
FreeSR.Admin/Command/AdminCommandContext.cs
Normal file
19
FreeSR.Admin/Command/AdminCommandContext.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
namespace FreeSR.Admin.Command
|
||||
{
|
||||
using FreeSR.Shared.Command.Context;
|
||||
|
||||
internal class AdminCommandContext : ICommandContext
|
||||
{
|
||||
public string Message { get; private set; }
|
||||
|
||||
public void SendError(string message)
|
||||
{
|
||||
Message = "Error: " + message;
|
||||
}
|
||||
|
||||
public void SendMessage(string message)
|
||||
{
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
}
|
17
FreeSR.Admin/Command/Handlers/AccountCommandCategory.cs
Normal file
17
FreeSR.Admin/Command/Handlers/AccountCommandCategory.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace FreeSR.Admin.Command.Handlers
|
||||
{
|
||||
using FreeSR.Shared.Command;
|
||||
using FreeSR.Shared.Command.Context;
|
||||
using FreeSR.Shared.Configuration;
|
||||
|
||||
[Command("account")]
|
||||
internal class AccountCommandCategory : CommandCategory
|
||||
{
|
||||
[Command("create")]
|
||||
public void AccountCreateCommandHandler(ICommandContext context, string username, string password)
|
||||
{
|
||||
var config = ConfigurationManager<AdminServerConfiguration>.Instance.Model;
|
||||
context.SendMessage($"dohttpreq={config.DispatchUrl}/sdk/createaccount?user={username}&pass={password}");
|
||||
}
|
||||
}
|
||||
}
|
27
FreeSR.Admin/FreeSR.Admin.csproj
Normal file
27
FreeSR.Admin/FreeSR.Admin.csproj
Normal file
|
@ -0,0 +1,27 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ceen.Httpd" Version="0.9.10" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FreeSR.Shared\FreeSR.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="AdminServer.example.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
<None Update="assets\console.html">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
25
FreeSR.Admin/Handlers/ConsolePageRequestHandler.cs
Normal file
25
FreeSR.Admin/Handlers/ConsolePageRequestHandler.cs
Normal file
|
@ -0,0 +1,25 @@
|
|||
namespace FreeSR.Admin.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Admin.Service;
|
||||
|
||||
internal class ConsolePageRequestHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
await context.Response.WriteAllAsync(CreateHTMLDocument(), "text/html");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static string CreateHTMLDocument()
|
||||
{
|
||||
string baseString = HttpAdminService.ConsoleHTML;
|
||||
|
||||
return baseString.Replace("%SERVER_VERSION%", "v0.1.0 dev - experimental open source")
|
||||
.Replace("%GAME_VERSION%", "1.2.0");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
23
FreeSR.Admin/Handlers/ExecuteCommandRequestHandler.cs
Normal file
23
FreeSR.Admin/Handlers/ExecuteCommandRequestHandler.cs
Normal file
|
@ -0,0 +1,23 @@
|
|||
namespace FreeSR.Admin.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Admin.Command;
|
||||
using FreeSR.Shared.Command;
|
||||
|
||||
internal class ExecuteCommandRequestHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
var query = context.Request.QueryString;
|
||||
string command = query["command"];
|
||||
|
||||
var ctx = new AdminCommandContext();
|
||||
CommandManager.Instance.Invoke(ctx, command);
|
||||
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
await context.Response.WriteAllAsync(ctx.Message, "text/plain");
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
43
FreeSR.Admin/Service/HttpAdminService.cs
Normal file
43
FreeSR.Admin/Service/HttpAdminService.cs
Normal file
|
@ -0,0 +1,43 @@
|
|||
namespace FreeSR.Admin.Service
|
||||
{
|
||||
using Ceen.Httpd;
|
||||
using Ceen.Httpd.Logging;
|
||||
using FreeSR.Admin.Handlers;
|
||||
using FreeSR.Shared.Configuration;
|
||||
using System.Net;
|
||||
|
||||
internal static class HttpAdminService
|
||||
{
|
||||
public static string ConsoleHTML { get; private set; }
|
||||
|
||||
private static ServerConfig s_httpdConfiguration;
|
||||
|
||||
public static void Initialize(NetworkConfiguration config)
|
||||
{
|
||||
LoadHtDocs();
|
||||
|
||||
s_httpdConfiguration = CreateConfiguration();
|
||||
_ = BootHttpAsync(config);
|
||||
}
|
||||
|
||||
private static void LoadHtDocs()
|
||||
{
|
||||
ConsoleHTML = File.ReadAllText("assets/console.html");
|
||||
}
|
||||
|
||||
private static ServerConfig CreateConfiguration()
|
||||
{
|
||||
return new ServerConfig().AddLogger(new CLFStdOut())
|
||||
.AddRoute("/console", new ConsolePageRequestHandler())
|
||||
.AddRoute("/console/exec", new ExecuteCommandRequestHandler());
|
||||
}
|
||||
|
||||
private static async Task BootHttpAsync(NetworkConfiguration config)
|
||||
{
|
||||
await HttpServer.ListenAsync(new IPEndPoint(
|
||||
IPAddress.Parse(config.Host),
|
||||
config.Port),
|
||||
false, s_httpdConfiguration);
|
||||
}
|
||||
}
|
||||
}
|
101
FreeSR.Admin/assets/console.html
Normal file
101
FreeSR.Admin/assets/console.html
Normal file
|
@ -0,0 +1,101 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>FreeSR</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
|
||||
#status {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#console {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
font-family: monospace;
|
||||
background-color: #f0f0f0;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
|
||||
#commandInput {
|
||||
width: 100%;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#submitBtn {
|
||||
padding: 5px 10px;
|
||||
margin-top: 10px;
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>FreeSR Control Panel</h1>
|
||||
<div>
|
||||
<h2>Status:</h2>
|
||||
<p id="status">Loading...</p>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Server Statistics:</h2>
|
||||
|
||||
<p>Server build: %SERVER_VERSION%</p>
|
||||
<p>Supported game version: %GAME_VERSION%</p>
|
||||
</div>
|
||||
<div>
|
||||
<h2>Admin Console:</h2>
|
||||
<textarea id="console" readonly></textarea>
|
||||
<input type="text" id="commandInput" placeholder="Enter admin command...">
|
||||
<button id="submitBtn">Execute</button>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const consoleOutput = document.getElementById('console');
|
||||
const commandInput = document.getElementById('commandInput');
|
||||
const submitBtn = document.getElementById('submitBtn');
|
||||
|
||||
// Function to update the status section (replace with actual server status)
|
||||
function updateStatus(statusText) {
|
||||
const statusElement = document.getElementById('status');
|
||||
statusElement.innerText = statusText;
|
||||
}
|
||||
|
||||
// Function to add a new line to the console
|
||||
function addToConsole(text) {
|
||||
consoleOutput.value += text + '\n';
|
||||
consoleOutput.scrollTop = consoleOutput.scrollHeight;
|
||||
}
|
||||
|
||||
function sendCommand() {
|
||||
const command = commandInput.value;
|
||||
if (command.length == 0)
|
||||
return;
|
||||
|
||||
addToConsole(`> ${command}`);
|
||||
|
||||
fetch(`/console/exec?command=${encodeURIComponent(command)}`)
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
if (data.startsWith("dohttpreq")) {
|
||||
fetch(data.replace("dohttpreq=", ""))
|
||||
.then(response => response.text())
|
||||
.then(data => {
|
||||
addToConsole(data);
|
||||
});
|
||||
}
|
||||
else {
|
||||
addToConsole(data);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
addToConsole(`Error: ${error.message}`);
|
||||
});
|
||||
|
||||
commandInput.value = '';
|
||||
}
|
||||
|
||||
submitBtn.addEventListener('click', sendCommand);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
59
FreeSR.Database.Account/AccountDatabase.cs
Normal file
59
FreeSR.Database.Account/AccountDatabase.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
namespace FreeSR.Database.Account
|
||||
{
|
||||
using FreeSR.Database.Account.Model;
|
||||
using FreeSR.Database.Account.Util;
|
||||
using FreeSR.Database.Mongo;
|
||||
using MongoDB.Driver;
|
||||
|
||||
public class AccountDatabase : SRMongoDatabase<AccountModel>
|
||||
{
|
||||
private int _maxUid;
|
||||
|
||||
public AccountDatabase(IMongoDatabase database, string collectionName) : base(database, collectionName)
|
||||
{
|
||||
// AccountDatabase.
|
||||
}
|
||||
|
||||
public async Task<AccountModel> Create(string name, string password)
|
||||
{
|
||||
if (_maxUid == 0)
|
||||
_maxUid = await FetchMaxUid();
|
||||
|
||||
if (await GetByName(name) != null)
|
||||
return null;
|
||||
|
||||
var model = new AccountModel
|
||||
{
|
||||
Uid = Interlocked.Increment(ref _maxUid),
|
||||
Name = name,
|
||||
Password = password,
|
||||
CreationDateUtc = DateTime.UtcNow,
|
||||
Token = AccountTokenUtil.Generate()
|
||||
};
|
||||
|
||||
await Insert(model);
|
||||
return model;
|
||||
}
|
||||
|
||||
public async Task<AccountModel> GetByUid(int uid)
|
||||
{
|
||||
return await FindOne(account => account.Uid == uid);
|
||||
}
|
||||
|
||||
public async Task<AccountModel> GetByName(string name)
|
||||
{
|
||||
return await FindOne(account => account.Name == name);
|
||||
}
|
||||
|
||||
public async Task Update(AccountModel account)
|
||||
{
|
||||
await Update(model => model.Uid == account.Uid, account);
|
||||
}
|
||||
|
||||
private async Task<int> FetchMaxUid()
|
||||
{
|
||||
var maxUidAccount = await FindMax(account => account.Uid);
|
||||
return maxUidAccount?.Uid ?? 0;
|
||||
}
|
||||
}
|
||||
}
|
13
FreeSR.Database.Account/FreeSR.Database.Account.csproj
Normal file
13
FreeSR.Database.Account/FreeSR.Database.Account.csproj
Normal file
|
@ -0,0 +1,13 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FreeSR.Database\FreeSR.Database.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
14
FreeSR.Database.Account/Model/AccountModel.cs
Normal file
14
FreeSR.Database.Account/Model/AccountModel.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace FreeSR.Database.Account.Model
|
||||
{
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
|
||||
[BsonIgnoreExtraElements]
|
||||
public class AccountModel
|
||||
{
|
||||
public int Uid { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Password { get; set; }
|
||||
public string Token { get; set; }
|
||||
public DateTime CreationDateUtc { get; set; }
|
||||
}
|
||||
}
|
37
FreeSR.Database.Account/Util/AccountTokenUtil.cs
Normal file
37
FreeSR.Database.Account/Util/AccountTokenUtil.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
namespace FreeSR.Database.Account.Util
|
||||
{
|
||||
using FreeSR.Database.Account.Model;
|
||||
|
||||
public static class AccountTokenUtil
|
||||
{
|
||||
private const int AccountTokenLength = 128;
|
||||
private const string TokenCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
private static Random s_random;
|
||||
|
||||
static AccountTokenUtil()
|
||||
{
|
||||
s_random = new Random();
|
||||
}
|
||||
|
||||
public static string Generate()
|
||||
{
|
||||
var token = "";
|
||||
|
||||
for (int i = 0; i < AccountTokenLength; i++)
|
||||
{
|
||||
token += TokenCharacters[s_random.Next(TokenCharacters.Length)];
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
public static bool Verify(AccountModel accountModel, string clientToken)
|
||||
{
|
||||
if (accountModel == null)
|
||||
return false;
|
||||
|
||||
return string.Equals(accountModel.Token, clientToken);
|
||||
}
|
||||
}
|
||||
}
|
9
FreeSR.Database/Configuration/DatabaseConfiguration.cs
Normal file
9
FreeSR.Database/Configuration/DatabaseConfiguration.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace FreeSR.Database.Configuration
|
||||
{
|
||||
public class DatabaseConfiguration
|
||||
{
|
||||
public string ConnectionString { get; set; }
|
||||
public string Name { get; set; }
|
||||
public DatabaseEntry[] Entries { get; set; }
|
||||
}
|
||||
}
|
8
FreeSR.Database/Configuration/DatabaseEntry.cs
Normal file
8
FreeSR.Database/Configuration/DatabaseEntry.cs
Normal file
|
@ -0,0 +1,8 @@
|
|||
namespace FreeSR.Database.Configuration
|
||||
{
|
||||
public class DatabaseEntry
|
||||
{
|
||||
public string CollectionName { get; set; }
|
||||
public DatabaseType Type { get; set; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Database.Configuration
|
||||
{
|
||||
using FreeSR.Shared.Exceptions;
|
||||
|
||||
internal class DatabaseMisconfiguredException : ServerInitializationException
|
||||
{
|
||||
public DatabaseMisconfiguredException(string message) : base(message)
|
||||
{
|
||||
// DatabaseMisconfiguredException.
|
||||
}
|
||||
}
|
||||
}
|
7
FreeSR.Database/Configuration/DatabaseType.cs
Normal file
7
FreeSR.Database/Configuration/DatabaseType.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace FreeSR.Database.Configuration
|
||||
{
|
||||
public enum DatabaseType
|
||||
{
|
||||
Account
|
||||
}
|
||||
}
|
55
FreeSR.Database/DatabaseManager.cs
Normal file
55
FreeSR.Database/DatabaseManager.cs
Normal file
|
@ -0,0 +1,55 @@
|
|||
namespace FreeSR.Database
|
||||
{
|
||||
using FreeSR.Database.Configuration;
|
||||
using FreeSR.Shared;
|
||||
using MongoDB.Driver;
|
||||
using NLog;
|
||||
|
||||
public sealed class DatabaseManager : Singleton<DatabaseManager>
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private DatabaseConfiguration _configuration;
|
||||
private Dictionary<Type, object> _databases;
|
||||
|
||||
public IMongoDatabase MongoDatabase { get; private set; }
|
||||
|
||||
private DatabaseManager()
|
||||
{
|
||||
_databases = new Dictionary<Type, object>();
|
||||
}
|
||||
|
||||
public void Initialize(DatabaseConfiguration configuration)
|
||||
{
|
||||
_configuration = configuration;
|
||||
|
||||
var mongoClient = new MongoClient(configuration.ConnectionString);
|
||||
MongoDatabase = mongoClient.GetDatabase(configuration.Name);
|
||||
}
|
||||
|
||||
public string GetCollectionName(DatabaseType databaseType)
|
||||
{
|
||||
foreach (var entry in _configuration.Entries)
|
||||
{
|
||||
if (entry.Type == databaseType)
|
||||
return entry.CollectionName;
|
||||
}
|
||||
|
||||
throw new DatabaseMisconfiguredException($"Can not find database of type {databaseType} in provided configuration.");
|
||||
}
|
||||
|
||||
public DatabaseManager Add<T>(ISRDatabase<T> database) where T : class
|
||||
{
|
||||
_databases.Add(database.GetType(), database);
|
||||
return this;
|
||||
}
|
||||
|
||||
public T Get<T>() where T : class
|
||||
{
|
||||
if (_databases.TryGetValue(typeof(T), out var database))
|
||||
return database as T;
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
17
FreeSR.Database/FreeSR.Database.csproj
Normal file
17
FreeSR.Database/FreeSR.Database.csproj
Normal file
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MongoDB.Driver" Version="2.20.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FreeSR.Shared\FreeSR.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
18
FreeSR.Database/ISRDatabase.cs
Normal file
18
FreeSR.Database/ISRDatabase.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
namespace FreeSR.Database
|
||||
{
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
public interface ISRDatabase<T> where T : class
|
||||
{
|
||||
Task Insert(T document);
|
||||
Task InsertMany(IEnumerable<T> documents);
|
||||
Task<List<T>> Find(Expression<Func<T, bool>> filter);
|
||||
Task<T> FindOne(Expression<Func<T, bool>> filter);
|
||||
Task Update(Expression<Func<T, bool>> filter, T updatedDocument);
|
||||
Task Delete(Expression<Func<T, bool>> filter);
|
||||
Task<long> Count();
|
||||
Task<T> FindMax(Expression<Func<T, object>> fieldSelector);
|
||||
}
|
||||
}
|
58
FreeSR.Database/Mongo/SRMongoDatabase.cs
Normal file
58
FreeSR.Database/Mongo/SRMongoDatabase.cs
Normal file
|
@ -0,0 +1,58 @@
|
|||
namespace FreeSR.Database.Mongo
|
||||
{
|
||||
using MongoDB.Driver;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
public class SRMongoDatabase<T> : ISRDatabase<T> where T : class
|
||||
{
|
||||
protected readonly IMongoCollection<T> _collection;
|
||||
|
||||
public SRMongoDatabase(IMongoDatabase database, string collectionName)
|
||||
{
|
||||
_collection = database.GetCollection<T>(collectionName);
|
||||
}
|
||||
|
||||
public async Task Insert(T document)
|
||||
{
|
||||
await _collection.InsertOneAsync(document);
|
||||
}
|
||||
|
||||
public async Task InsertMany(IEnumerable<T> documents)
|
||||
{
|
||||
await _collection.InsertManyAsync(documents);
|
||||
}
|
||||
|
||||
public async Task<List<T>> Find(Expression<Func<T, bool>> filter)
|
||||
{
|
||||
var result = await _collection.FindAsync(filter);
|
||||
return await result.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<T> FindOne(Expression<Func<T, bool>> filter)
|
||||
{
|
||||
var result = await _collection.FindAsync(filter);
|
||||
return await result.FirstOrDefaultAsync();
|
||||
}
|
||||
|
||||
public async Task Update(Expression<Func<T, bool>> filter, T updatedDocument)
|
||||
{
|
||||
await _collection.ReplaceOneAsync(filter, updatedDocument);
|
||||
}
|
||||
|
||||
public async Task Delete(Expression<Func<T, bool>> filter)
|
||||
{
|
||||
await _collection.DeleteOneAsync(filter);
|
||||
}
|
||||
|
||||
public async Task<long> Count()
|
||||
{
|
||||
return await _collection.CountDocumentsAsync(Builders<T>.Filter.Empty);
|
||||
}
|
||||
|
||||
public async Task<T> FindMax(Expression<Func<T, object>> fieldSelector)
|
||||
{
|
||||
var sortDefinition = Builders<T>.Sort.Descending(fieldSelector);
|
||||
return await _collection.Find(Builders<T>.Filter.Empty).Sort(sortDefinition).FirstOrDefaultAsync();
|
||||
}
|
||||
}
|
||||
}
|
11
FreeSR.Dispatch/Configuration/RegionConfiguration.cs
Normal file
11
FreeSR.Dispatch/Configuration/RegionConfiguration.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Dispatch.Configuration
|
||||
{
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
internal class RegionConfiguration
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string EnvType { get; set; }
|
||||
public string DispatchUrl { get; set; }
|
||||
}
|
||||
}
|
59
FreeSR.Dispatch/DispatchServer.cs
Normal file
59
FreeSR.Dispatch/DispatchServer.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
namespace FreeSR.Dispatch
|
||||
{
|
||||
using FreeSR.Database;
|
||||
using FreeSR.Database.Account;
|
||||
using FreeSR.Database.Configuration;
|
||||
using FreeSR.Dispatch.Service;
|
||||
using FreeSR.Dispatch.Service.Manager;
|
||||
using FreeSR.Shared.Configuration;
|
||||
using FreeSR.Shared.Exceptions;
|
||||
using NLog;
|
||||
|
||||
internal static class DispatchServer
|
||||
{
|
||||
private const string Title = "FreeSR Dispatch Server (EXPERIMENTAL OPEN SOURCE BUILD)";
|
||||
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Directory.SetCurrentDirectory(AppContext.BaseDirectory);
|
||||
AppDomain.CurrentDomain.UnhandledException += OnFatalException;
|
||||
|
||||
Console.Title = Title;
|
||||
s_log.Info("Initializing...");
|
||||
|
||||
ConfigurationManager<DispatchServerConfiguration>.Instance.Initialize("DispatchServer.json");
|
||||
var serverConfiguration = ConfigurationManager<DispatchServerConfiguration>.Instance.Model;
|
||||
|
||||
DatabaseManager.Instance.Initialize(serverConfiguration.Database);
|
||||
|
||||
var mongoDatabase = DatabaseManager.Instance.MongoDatabase;
|
||||
DatabaseManager.Instance.Add(new AccountDatabase(mongoDatabase, DatabaseManager.Instance.GetCollectionName(DatabaseType.Account)));
|
||||
|
||||
RegionManager.Initialize(serverConfiguration.Region);
|
||||
HttpDispatchService.Initialize(serverConfiguration.Network);
|
||||
|
||||
s_log.Info("Server is ready!");
|
||||
|
||||
Thread.Sleep(-1); // TODO: Console handler
|
||||
}
|
||||
|
||||
private static void OnFatalException(object sender, UnhandledExceptionEventArgs args)
|
||||
{
|
||||
if (args.ExceptionObject is ServerInitializationException initException)
|
||||
{
|
||||
Console.WriteLine("Server initialization failed, unhandled exception!");
|
||||
Console.WriteLine(initException);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unhandled exception in runtime!");
|
||||
Console.WriteLine(args.ExceptionObject);
|
||||
}
|
||||
|
||||
Console.WriteLine("Press enter to close this window...");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
21
FreeSR.Dispatch/DispatchServer.example.json
Normal file
21
FreeSR.Dispatch/DispatchServer.example.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"Network": {
|
||||
"Host": "0.0.0.0",
|
||||
"Port": 8888
|
||||
},
|
||||
"Database": {
|
||||
"ConnectionString": "mongodb://127.0.0.1:27017/",
|
||||
"Name": "FreeSR",
|
||||
"Entries": [
|
||||
{
|
||||
"CollectionName": "accounts",
|
||||
"Type": "Account"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Region": {
|
||||
"Name": "FreeSR",
|
||||
"EnvType": "2",
|
||||
"DispatchUrl": "http://dispatch.starrails.com/query_gateway"
|
||||
}
|
||||
}
|
13
FreeSR.Dispatch/DispatchServerConfiguration.cs
Normal file
13
FreeSR.Dispatch/DispatchServerConfiguration.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace FreeSR.Dispatch
|
||||
{
|
||||
using FreeSR.Database.Configuration;
|
||||
using FreeSR.Dispatch.Configuration;
|
||||
using FreeSR.Shared.Configuration;
|
||||
|
||||
internal class DispatchServerConfiguration
|
||||
{
|
||||
public NetworkConfiguration Network { get; set; }
|
||||
public DatabaseConfiguration Database { get; set; }
|
||||
public RegionConfiguration Region { get; set; }
|
||||
}
|
||||
}
|
27
FreeSR.Dispatch/FreeSR.Dispatch.csproj
Normal file
27
FreeSR.Dispatch/FreeSR.Dispatch.csproj
Normal file
|
@ -0,0 +1,27 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Ceen.Httpd" Version="0.9.10" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FreeSR.Database.Account\FreeSR.Database.Account.csproj" />
|
||||
<ProjectReference Include="..\FreeSR.Proto\FreeSR.Proto.csproj" />
|
||||
<ProjectReference Include="..\FreeSR.Shared\FreeSR.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="DispatchServer.example.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
32
FreeSR.Dispatch/Handlers/ComboGranterApiGetConfigHandler.cs
Normal file
32
FreeSR.Dispatch/Handlers/ComboGranterApiGetConfigHandler.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
internal class ComboGranterApiGetConfigHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "application/json";
|
||||
await context.Response.WriteAllJsonAsync(JsonConvert.SerializeObject(new
|
||||
{
|
||||
retcode = 0,
|
||||
message = "OK",
|
||||
data =
|
||||
new
|
||||
{
|
||||
protocol = true,
|
||||
qr_enabled = true,
|
||||
log_level = "INFO",
|
||||
announce_url = "https://sdk.hoyoverse.com/hkrpg/announcement/index.html?sdk_presentation_style=fullscreen\u0026sdk_screen_transparent=true\u0026auth_appid=announcement\u0026authkey_ver=1\u0026sign_type=2#/",
|
||||
push_alias_type = 0,
|
||||
disable_ysdk_guard = true,
|
||||
enable_announce_pic_popup = true
|
||||
}
|
||||
}));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
39
FreeSR.Dispatch/Handlers/ComboTokenRequestHandler.cs
Normal file
39
FreeSR.Dispatch/Handlers/ComboTokenRequestHandler.cs
Normal file
|
@ -0,0 +1,39 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using FreeSR.Proto;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class ComboTokenRequestHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
var data = await context.Request.Body.ReadAllAsStringAsync();
|
||||
var json = JObject.Parse(data);
|
||||
var clientData = JObject.Parse((string)json["data"]);
|
||||
|
||||
var dataObject = new JObject
|
||||
{
|
||||
{"combo_id", 1},
|
||||
{"open_id", clientData["uid"]},
|
||||
{"combo_token", clientData["token"]},
|
||||
{"data", new JObject {{"guest", false}}},
|
||||
{"heartbeat", false},
|
||||
{"account_type", 1},
|
||||
{"fatigue_remind", null}
|
||||
};
|
||||
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "application/json";
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_SUCC)
|
||||
.Message("OK")
|
||||
.Object("data", dataObject)
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
34
FreeSR.Dispatch/Handlers/GetAgreementInfosHandler.cs
Normal file
34
FreeSR.Dispatch/Handlers/GetAgreementInfosHandler.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using FreeSR.Proto;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
internal class GetAgreementInfosHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "application/json";
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_SUCC)
|
||||
.Message("OK")
|
||||
.Object("data", Data)
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static JObject Data
|
||||
{
|
||||
get
|
||||
{
|
||||
return new JObject
|
||||
{
|
||||
{"marketing_agreements", new JArray()}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
FreeSR.Dispatch/Handlers/GetExperimentListHandler.cs
Normal file
22
FreeSR.Dispatch/Handlers/GetExperimentListHandler.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal class GetExperimentListHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "application/json";
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_SUCC)
|
||||
.Boolean("success", true)
|
||||
.String("message", "")
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
26
FreeSR.Dispatch/Handlers/HkrpgDataUploadHandler.cs
Normal file
26
FreeSR.Dispatch/Handlers/HkrpgDataUploadHandler.cs
Normal file
|
@ -0,0 +1,26 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using NLog;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class HkrpgDataUploadHandler : IHttpModule
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
string logs = await context.Request.Body.ReadAllAsStringAsync();
|
||||
s_log.Info(logs);
|
||||
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "application/json";
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Code(0)
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
57
FreeSR.Dispatch/Handlers/LoginRequestHandler.cs
Normal file
57
FreeSR.Dispatch/Handlers/LoginRequestHandler.cs
Normal file
|
@ -0,0 +1,57 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Database;
|
||||
using FreeSR.Database.Account;
|
||||
using FreeSR.Database.Account.Model;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using FreeSR.Proto;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class LoginRequestHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "application/json";
|
||||
|
||||
string data = await context.Request.Body.ReadAllAsStringAsync();
|
||||
JObject loginJson = JObject.Parse(data);
|
||||
|
||||
AccountDatabase accountDatabase = DatabaseManager.Instance.Get<AccountDatabase>();
|
||||
|
||||
string accountName = (string)loginJson["account"];
|
||||
string password = (string)loginJson["password"];
|
||||
|
||||
AccountModel account = await accountDatabase.GetByName(accountName);
|
||||
if (account == null)
|
||||
{
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_FAIL)
|
||||
.Message("Account not found.")
|
||||
.Object("data", null)
|
||||
.Build());
|
||||
return true;
|
||||
}
|
||||
|
||||
// no password check, because client patch is closed-source for now.
|
||||
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_SUCC)
|
||||
.Message("OK")
|
||||
.Object("data", new JObject
|
||||
{
|
||||
{"account", account.ToLoginResponseData()},
|
||||
{"device_grant_required", false},
|
||||
{"safe_moblie_required", false},
|
||||
{"realperson_required", false},
|
||||
{"reactivate_required", false},
|
||||
{"realname_operation", "None"}
|
||||
, })
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
36
FreeSR.Dispatch/Handlers/QueryDispatchHandler.cs
Normal file
36
FreeSR.Dispatch/Handlers/QueryDispatchHandler.cs
Normal file
|
@ -0,0 +1,36 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Dispatch.Service.Manager;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using FreeSR.Proto;
|
||||
using NLog;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class QueryDispatchHandler : IHttpModule
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
var query = context.Request.QueryString;
|
||||
var version = query["version"];
|
||||
var timestamp = query["t"];
|
||||
var languageType = query["language_type"];
|
||||
var platformType = query["platform_type"];
|
||||
|
||||
s_log.Info($"query_dispatch: version: {version}, time: {timestamp}, language: {languageType}, platform: {platformType}");
|
||||
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "text/plain";
|
||||
await context.Response.WriteAllAsync(Convert.ToBase64String(ProtobufUtil.Serialize(new DispatchRegionsData
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
TopSeverRegionName = RegionManager.GetTopServerRegionName(),
|
||||
RegionList = RegionManager.GetRegionList()
|
||||
})));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
34
FreeSR.Dispatch/Handlers/QueryGatewayHandler.cs
Normal file
34
FreeSR.Dispatch/Handlers/QueryGatewayHandler.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using FreeSR.Proto;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class QueryGatewayHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "text/plain";
|
||||
await context.Response.WriteAllAsync(Convert.ToBase64String(ProtobufUtil.Serialize(new Gateserver
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
Msg = "OK",
|
||||
Ip = "127.0.0.1",
|
||||
RegionName = "FreeSR",
|
||||
Port = 22301,
|
||||
Mljaogdhcki = true,
|
||||
LoginWhiteMsg = "Access verification failed. Please check if you have logged in to the correct account and server.",
|
||||
Jcdlppbocpe = true,
|
||||
Gifijbibiin = true,
|
||||
Ibplbfhmgkf = true,
|
||||
MbResVersion = "5335706",
|
||||
AssetBundleUrl = "https://autopatchos.starrails.com/asb/V1.3Live/output_5355192_0007722cfc",
|
||||
ExResourceUrl = "https://autopatchos.starrails.com/design_data/V1.3Live/output_5371504_9fdb2fe63e",
|
||||
})));
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
37
FreeSR.Dispatch/Handlers/RiskyApiCheckHandler.cs
Normal file
37
FreeSR.Dispatch/Handlers/RiskyApiCheckHandler.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using FreeSR.Proto;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class RiskyApiCheckHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "application/json";
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_SUCC)
|
||||
.Message("OK")
|
||||
.Object("data", CaptchaData)
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static JObject CaptchaData
|
||||
{
|
||||
get
|
||||
{
|
||||
return new JObject
|
||||
{
|
||||
{"id", ""},
|
||||
{"action", "ACTION_NONE"},
|
||||
{"geetest", null}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
FreeSR.Dispatch/Handlers/Sdk/CreateAccountHandler.cs
Normal file
32
FreeSR.Dispatch/Handlers/Sdk/CreateAccountHandler.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
namespace FreeSR.Dispatch.Handlers.Sdk
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Database;
|
||||
using FreeSR.Database.Account;
|
||||
|
||||
internal class CreateAccountHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
var query = context.Request.QueryString;
|
||||
|
||||
var name = query["user"];
|
||||
var password = query["pass"];
|
||||
|
||||
var database = DatabaseManager.Instance.Get<AccountDatabase>();
|
||||
var account = await database.Create(name, password);
|
||||
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
if (account == null)
|
||||
{
|
||||
await context.Response.WriteAllAsync("Sorry, this username is already taken.", "text/plain");
|
||||
}
|
||||
else
|
||||
{
|
||||
await context.Response.WriteAllAsync($"Successfully created account with name {account.Name}, uid: {account.Uid}", "text/plain");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
20
FreeSR.Dispatch/Handlers/SdkDataUploadHandler.cs
Normal file
20
FreeSR.Dispatch/Handlers/SdkDataUploadHandler.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class SdkDataUploadHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
context.Response.StatusCode = HttpStatusCode.OK;
|
||||
context.Response.ContentType = "application/json";
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Code(0)
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
61
FreeSR.Dispatch/Handlers/TokenLoginRequestHandler.cs
Normal file
61
FreeSR.Dispatch/Handlers/TokenLoginRequestHandler.cs
Normal file
|
@ -0,0 +1,61 @@
|
|||
namespace FreeSR.Dispatch.Handlers
|
||||
{
|
||||
using Ceen;
|
||||
using FreeSR.Database;
|
||||
using FreeSR.Database.Account;
|
||||
using FreeSR.Database.Account.Model;
|
||||
using FreeSR.Dispatch.Util;
|
||||
using FreeSR.Proto;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
internal class TokenLoginRequestHandler : IHttpModule
|
||||
{
|
||||
public async Task<bool> HandleAsync(IHttpContext context)
|
||||
{
|
||||
var data = await context.Request.Body.ReadAllAsStringAsync();
|
||||
var json = JObject.Parse(data);
|
||||
|
||||
var uid = int.Parse((string)json["uid"]);
|
||||
var token = (string)json["token"];
|
||||
|
||||
AccountDatabase accountDatabase = DatabaseManager.Instance.Get<AccountDatabase>();
|
||||
AccountModel account = await accountDatabase.GetByUid(uid);
|
||||
if (account == null)
|
||||
{
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_FAIL)
|
||||
.Message("Account not found.")
|
||||
.Object("data", null)
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
else if (account.Token != token)
|
||||
{
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_FAIL)
|
||||
.Message("Invalid user token.")
|
||||
.Object("data", null)
|
||||
.Build());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
await context.Response.WriteAllJsonAsync(DispatchResponseBuilder.Create()
|
||||
.Retcode(Retcode.RETCODE_RET_SUCC)
|
||||
.Message("OK")
|
||||
.Object("data", new JObject
|
||||
{
|
||||
{"account", account.ToLoginResponseData()},
|
||||
{"device_grant_required", false},
|
||||
{"safe_moblie_required", false},
|
||||
{"realperson_required", false},
|
||||
{"reactivate_required", false},
|
||||
{"realname_operation", "None"}
|
||||
})
|
||||
.Build());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
45
FreeSR.Dispatch/Service/HttpDispatchService.cs
Normal file
45
FreeSR.Dispatch/Service/HttpDispatchService.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
namespace FreeSR.Dispatch.Service
|
||||
{
|
||||
using Ceen.Httpd;
|
||||
using Ceen.Httpd.Logging;
|
||||
using FreeSR.Dispatch.Handlers;
|
||||
using FreeSR.Dispatch.Handlers.Sdk;
|
||||
using FreeSR.Shared.Configuration;
|
||||
using System.Net;
|
||||
|
||||
internal static class HttpDispatchService
|
||||
{
|
||||
private static ServerConfig s_httpdConfiguration;
|
||||
|
||||
public static void Initialize(NetworkConfiguration config)
|
||||
{
|
||||
s_httpdConfiguration = CreateConfiguration();
|
||||
_ = BootHttpAsync(config);
|
||||
}
|
||||
|
||||
private static ServerConfig CreateConfiguration()
|
||||
{
|
||||
return new ServerConfig().AddLogger(new CLFStdOut())
|
||||
.AddRoute("/query_dispatch", new QueryDispatchHandler())
|
||||
.AddRoute("/query_gateway", new QueryGatewayHandler())
|
||||
.AddRoute("/hkrpg_global/mdk/shield/api/login", new LoginRequestHandler())
|
||||
.AddRoute("/hkrpg_global/combo/granter/login/v2/login", new ComboTokenRequestHandler())
|
||||
.AddRoute("/hkrpg_global/mdk/shield/api/verify", new TokenLoginRequestHandler())
|
||||
.AddRoute("/sdk/dataUpload", new SdkDataUploadHandler())
|
||||
.AddRoute("/hkrpg/dataUpload", new HkrpgDataUploadHandler())
|
||||
.AddRoute("/account/risky/api/check", new RiskyApiCheckHandler())
|
||||
.AddRoute("/hkrpg_global/mdk/agreement/api/getAgreementInfos", new GetAgreementInfosHandler())
|
||||
.AddRoute("/data_abtest_api/config/experiment/list", new GetExperimentListHandler())
|
||||
.AddRoute("/hkrpg_global/combo/granter/api/getConfig", new ComboGranterApiGetConfigHandler())
|
||||
.AddRoute("/sdk/createaccount", new CreateAccountHandler());
|
||||
}
|
||||
|
||||
private static async Task BootHttpAsync(NetworkConfiguration config)
|
||||
{
|
||||
await HttpServer.ListenAsync(new IPEndPoint(
|
||||
IPAddress.Parse(config.Host),
|
||||
config.Port),
|
||||
false, s_httpdConfiguration);
|
||||
}
|
||||
}
|
||||
}
|
31
FreeSR.Dispatch/Service/Manager/RegionManager.cs
Normal file
31
FreeSR.Dispatch/Service/Manager/RegionManager.cs
Normal file
|
@ -0,0 +1,31 @@
|
|||
namespace FreeSR.Dispatch.Service.Manager
|
||||
{
|
||||
using FreeSR.Dispatch.Configuration;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal static class RegionManager
|
||||
{
|
||||
private static RegionConfiguration s_configuration;
|
||||
|
||||
public static void Initialize(RegionConfiguration configuration)
|
||||
{
|
||||
s_configuration = configuration;
|
||||
}
|
||||
|
||||
public static List<RegionEntry> GetRegionList()
|
||||
{
|
||||
var region = new RegionEntry
|
||||
{
|
||||
EnvType = s_configuration.EnvType,
|
||||
DispatchUrl = s_configuration.DispatchUrl,
|
||||
Name = s_configuration.Name,
|
||||
DisplayName = s_configuration.Name,
|
||||
Title = s_configuration.Name
|
||||
};
|
||||
|
||||
return new List<RegionEntry> { region };
|
||||
}
|
||||
|
||||
public static string GetTopServerRegionName() => s_configuration.Name;
|
||||
}
|
||||
}
|
38
FreeSR.Dispatch/Util/DispatchHelper.cs
Normal file
38
FreeSR.Dispatch/Util/DispatchHelper.cs
Normal file
|
@ -0,0 +1,38 @@
|
|||
namespace FreeSR.Dispatch.Util
|
||||
{
|
||||
using FreeSR.Database.Account.Model;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
internal static class DispatchHelper
|
||||
{
|
||||
public static JObject ToLoginResponseData(this AccountModel model)
|
||||
{
|
||||
return new JObject
|
||||
{
|
||||
{"uid", model.Uid},
|
||||
{"name", model.Name},
|
||||
{"email", ""},
|
||||
{"mobile", ""},
|
||||
{"is_email_verify", "0"},
|
||||
{"realname", ""},
|
||||
{"identity_card", ""},
|
||||
{"safe_mobile", ""},
|
||||
{"facebook_name", ""},
|
||||
{"google_name", ""},
|
||||
{"twitter_name", ""},
|
||||
{"game_center_name", ""},
|
||||
{"apple_name", ""},
|
||||
{"sony_name", ""},
|
||||
{"tap_name", ""},
|
||||
{"country", "CN"},
|
||||
{"reactivate_ticket", ""},
|
||||
{"area_code", "**"},
|
||||
{"device_grant_ticket", ""},
|
||||
{"steam_name", ""},
|
||||
{"unmasked_email", ""},
|
||||
{"unmasked_email_type", 0},
|
||||
{"token", model.Token}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
69
FreeSR.Dispatch/Util/DispatchResponseBuilder.cs
Normal file
69
FreeSR.Dispatch/Util/DispatchResponseBuilder.cs
Normal file
|
@ -0,0 +1,69 @@
|
|||
namespace FreeSR.Dispatch.Util
|
||||
{
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
internal class DispatchResponseBuilder
|
||||
{
|
||||
private readonly JObject _jsonObject;
|
||||
|
||||
private DispatchResponseBuilder()
|
||||
{
|
||||
_jsonObject = new JObject();
|
||||
}
|
||||
|
||||
public string Build()
|
||||
{
|
||||
return _jsonObject.ToString();
|
||||
}
|
||||
|
||||
public DispatchResponseBuilder Code(int code)
|
||||
{
|
||||
_jsonObject["code"] = code;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispatchResponseBuilder Retcode(int retcode)
|
||||
{
|
||||
_jsonObject["retcode"] = retcode;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispatchResponseBuilder Message(string message)
|
||||
{
|
||||
_jsonObject["message"] = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispatchResponseBuilder Boolean(string field, bool value)
|
||||
{
|
||||
_jsonObject[field] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispatchResponseBuilder String(string field, string value)
|
||||
{
|
||||
_jsonObject[field] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispatchResponseBuilder Int(string field, int value)
|
||||
{
|
||||
_jsonObject[field] = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispatchResponseBuilder Array(string field, JArray array)
|
||||
{
|
||||
_jsonObject[field] = array;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispatchResponseBuilder Object(string field, JObject jsonObject)
|
||||
{
|
||||
_jsonObject[field] = jsonObject;
|
||||
return this;
|
||||
}
|
||||
|
||||
public static DispatchResponseBuilder Create() => new DispatchResponseBuilder();
|
||||
}
|
||||
}
|
15
FreeSR.Dispatch/Util/ProtobufUtil.cs
Normal file
15
FreeSR.Dispatch/Util/ProtobufUtil.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
namespace FreeSR.Dispatch.Util
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
internal static class ProtobufUtil
|
||||
{
|
||||
public static byte[] Serialize<T>(T obj) where T : class
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
Serializer.Serialize(stream, obj);
|
||||
|
||||
return stream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
26
FreeSR.Gateserver/FreeSR.Gateserver.csproj
Normal file
26
FreeSR.Gateserver/FreeSR.Gateserver.csproj
Normal file
|
@ -0,0 +1,26 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="DotNetty.Handlers" Version="0.7.5" />
|
||||
<PackageReference Include="Nito.AsyncEx.Context" Version="5.1.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\FreeSR.Proto\FreeSR.Proto.csproj" />
|
||||
<ProjectReference Include="..\FreeSR.Shared\FreeSR.Shared.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="GateServer.example.json">
|
||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
47
FreeSR.Gateserver/GateServer.cs
Normal file
47
FreeSR.Gateserver/GateServer.cs
Normal file
|
@ -0,0 +1,47 @@
|
|||
namespace FreeSR.Gateserver
|
||||
{
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Shared.Configuration;
|
||||
using FreeSR.Shared.Exceptions;
|
||||
using NLog;
|
||||
|
||||
internal static class GateServer
|
||||
{
|
||||
private const string Title = "FreeSR Gate Server (EXPERIMENTAL OPEN SOURCE BUILD)";
|
||||
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static void Main(string[] args)
|
||||
{
|
||||
Directory.SetCurrentDirectory(AppContext.BaseDirectory);
|
||||
AppDomain.CurrentDomain.UnhandledException += OnFatalException;
|
||||
|
||||
Console.Title = Title;
|
||||
s_log.Info("Initializing...");
|
||||
|
||||
ConfigurationManager<GateServerConfiguration>.Instance.Initialize("GateServer.json");
|
||||
var serverConfiguration = ConfigurationManager<GateServerConfiguration>.Instance.Model;
|
||||
NetworkManager.Instance.Initialize(serverConfiguration.Network).GetAwaiter().GetResult();
|
||||
|
||||
s_log.Info("Server is ready!");
|
||||
Thread.Sleep(-1); // TODO: Console handler
|
||||
}
|
||||
|
||||
private static void OnFatalException(object sender, UnhandledExceptionEventArgs args)
|
||||
{
|
||||
if (args.ExceptionObject is ServerInitializationException initException)
|
||||
{
|
||||
Console.WriteLine("Server initialization failed, unhandled exception!");
|
||||
Console.WriteLine(initException);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Unhandled exception in runtime!");
|
||||
Console.WriteLine(args.ExceptionObject);
|
||||
}
|
||||
|
||||
Console.WriteLine("Press enter to close this window...");
|
||||
Console.ReadLine();
|
||||
}
|
||||
}
|
||||
}
|
6
FreeSR.Gateserver/GateServer.example.json
Normal file
6
FreeSR.Gateserver/GateServer.example.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"Network": {
|
||||
"Host": "0.0.0.0",
|
||||
"Port": 22301
|
||||
}
|
||||
}
|
9
FreeSR.Gateserver/GateServerConfiguration.cs
Normal file
9
FreeSR.Gateserver/GateServerConfiguration.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace FreeSR.Gateserver
|
||||
{
|
||||
using FreeSR.Shared.Configuration;
|
||||
|
||||
internal class GateServerConfiguration
|
||||
{
|
||||
public NetworkConfiguration Network { get; set; }
|
||||
}
|
||||
}
|
40
FreeSR.Gateserver/Manager/Handlers/AvatarReqGroup.cs
Normal file
40
FreeSR.Gateserver/Manager/Handlers/AvatarReqGroup.cs
Normal file
|
@ -0,0 +1,40 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal static class AvatarReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetAvatarDataCsReq)]
|
||||
public static void OnGetAvatarDataCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as GetAvatarDataCsReq;
|
||||
|
||||
var response = new GetAvatarDataScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
IsAll = request.IsGetAll,
|
||||
AvatarList = new List<Avatar>()
|
||||
};
|
||||
|
||||
int[] characters = new int[] { 8001, 1005, 1003 };
|
||||
|
||||
foreach (int id in characters)
|
||||
{
|
||||
response.AvatarList.Add(new Avatar
|
||||
{
|
||||
BaseAvatarId = id,
|
||||
Exp = 0,
|
||||
Level = 1,
|
||||
Promotion = 0,
|
||||
Rank = 6,
|
||||
SkilltreeList = new List<AvatarSkillTree>(),
|
||||
EquipmentUniqueId = 0
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetAvatarDataScRsp, response);
|
||||
}
|
||||
}
|
||||
}
|
7
FreeSR.Gateserver/Manager/Handlers/ChallengeReqGroup.cs
Normal file
7
FreeSR.Gateserver/Manager/Handlers/ChallengeReqGroup.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
internal static class ChallengeReqGroup
|
||||
{
|
||||
// ChallengeReqGroup.
|
||||
}
|
||||
}
|
18
FreeSR.Gateserver/Manager/Handlers/Core/HandlerAttribute.cs
Normal file
18
FreeSR.Gateserver/Manager/Handlers/Core/HandlerAttribute.cs
Normal file
|
@ -0,0 +1,18 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers.Core
|
||||
{
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
internal class HandlerAttribute : Attribute
|
||||
{
|
||||
public int CmdID { get; }
|
||||
|
||||
public HandlerAttribute(CmdType cmdID)
|
||||
{
|
||||
this.CmdID = (int)cmdID;
|
||||
}
|
||||
|
||||
public delegate void HandlerDelegate(NetSession session, int cmdId, object data);
|
||||
}
|
||||
}
|
343
FreeSR.Gateserver/Manager/Handlers/GachaReqGroup.cs
Normal file
343
FreeSR.Gateserver/Manager/Handlers/GachaReqGroup.cs
Normal file
|
@ -0,0 +1,343 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
using static System.Net.WebRequestMethods;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http.Headers;
|
||||
using System.ComponentModel.Design;
|
||||
|
||||
internal static class GachaReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetGachaInfoCsReq)]
|
||||
public static void OnGetGachaInfoCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var Gacha1List = new List<int>();
|
||||
session.Send(CmdType.GetGachaInfoScRsp, new GetGachaInfoScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
GachaRandom = 0,
|
||||
GachaInfoList = new List<GachaInfo>
|
||||
{
|
||||
new GachaInfo
|
||||
{
|
||||
//ENJHJHKNGOG = "https://webstatic-sea.hoyoverse.com/hkrpg/event/e20211215gacha-v2/index.html?authkey_ver=1&sign_type=2&auth_appid=webview_gacha&win_mode=fullscreen#/log",
|
||||
Dmdldgldfdj = new List<int>(1208),
|
||||
//JDMIIMJFAPK = "https://webstatic-sea.hoyoverse.com/hkrpg/event/e20211215gacha-v2/index.html?authkey_ver=1&sign_type=2&auth_appid=webview_gacha&win_mode=fullscreen&gacha_id=ad9815cdf2308104c377aac42c7f0cdd8d×tamp=1689725163",
|
||||
Pldioknjpjj = new List<int>{1208, 1110, 1109, 1106},
|
||||
BeginTime = 1689719400,
|
||||
EndTime = 4070880000,
|
||||
GachaId = 2010
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.DoGachaCsReq)]
|
||||
public static void OnDoGachaCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var gachaReq = data as DoGachaCsReq;
|
||||
if (gachaReq.GachaNum == 1)
|
||||
{
|
||||
session.Send(CmdType.DoGachaScRsp, new DoGachaScRsp
|
||||
{
|
||||
GachaId = gachaReq.GachaId,
|
||||
Nmaojeiedak = gachaReq.GachaRandom + 1,
|
||||
GachaNum = gachaReq.GachaNum,
|
||||
GachaItemList = new List<GachaItem>
|
||||
{
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1107,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
if (gachaReq.GachaNum == 10)
|
||||
{
|
||||
session.Send(CmdType.DoGachaScRsp, new DoGachaScRsp
|
||||
{
|
||||
GachaId = gachaReq.GachaId,
|
||||
Nmaojeiedak = gachaReq.GachaRandom + 10,
|
||||
GachaNum = gachaReq.GachaNum,
|
||||
GachaItemList = new List<GachaItem>
|
||||
{
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
},
|
||||
new GachaItem
|
||||
{
|
||||
Item = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 1208,
|
||||
Num = 1,
|
||||
}
|
||||
}[0],
|
||||
Dpjjnjflnjm = new List<ItemList>
|
||||
{
|
||||
new ItemList
|
||||
{
|
||||
List = new List<Item>
|
||||
{
|
||||
new Item
|
||||
{
|
||||
ItemId = 252,
|
||||
Num = 40,
|
||||
}
|
||||
}
|
||||
}
|
||||
}[0]
|
||||
}
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
FreeSR.Gateserver/Manager/Handlers/ItemReqGroup.cs
Normal file
30
FreeSR.Gateserver/Manager/Handlers/ItemReqGroup.cs
Normal file
|
@ -0,0 +1,30 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
internal static class ItemReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetBagCsReq)]
|
||||
public static void OnGetBagCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
session.Send(CmdType.GetBagScRsp, new GetBagScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
MaterialList = new List<Material>
|
||||
{
|
||||
new Material
|
||||
{
|
||||
Tid = 101,
|
||||
Num = 10
|
||||
},
|
||||
new Material
|
||||
{
|
||||
Tid = 102,
|
||||
Num = 10
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
92
FreeSR.Gateserver/Manager/Handlers/LineupReqGroup.cs
Normal file
92
FreeSR.Gateserver/Manager/Handlers/LineupReqGroup.cs
Normal file
|
@ -0,0 +1,92 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal static class LineupReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetCurLineupDataCsReq)]
|
||||
public static void OnGetCurLineupDataCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
var response = new GetCurLineupDataScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC
|
||||
};
|
||||
|
||||
response.Lineup = new LineupInfo
|
||||
{
|
||||
ExtraLineupType = ExtraLineupType.LINEUP_NONE,
|
||||
Name = "Squad 1",
|
||||
AvatarList = new List<LineupAvatar>(),
|
||||
LeaderSlot = 5,
|
||||
Foafdgjflmc = 5
|
||||
};
|
||||
|
||||
var characters = new int[] { 8001, 1005, 1003 };
|
||||
|
||||
foreach (int id in characters)
|
||||
{
|
||||
response.Lineup.AvatarList.Add(new LineupAvatar
|
||||
{
|
||||
AvatarType = AvatarType.AVATAR_FORMAL_TYPE,
|
||||
CurHealth = new HealthBarInfo { CurHp = 10000, MaxHp = 10000 },
|
||||
Sp = 10000,
|
||||
Satiety = 100,
|
||||
Id = id,
|
||||
Slot = response.Lineup.AvatarList.Count
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetCurLineupDataScRsp, response);
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetAllLineupDataCsReq)]
|
||||
public static void OnGetAllLineupDataCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var response = new GetAllLineupDataScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
CurIndex = 0,
|
||||
LineupList = new List<LineupInfo>()
|
||||
};
|
||||
|
||||
response.LineupList.Add(new LineupInfo
|
||||
{
|
||||
ExtraLineupType = ExtraLineupType.LINEUP_NONE,
|
||||
Name = "Squad 1",
|
||||
AvatarList = new List<LineupAvatar>(),
|
||||
Foafdgjflmc = 5,
|
||||
LeaderSlot = 3
|
||||
});
|
||||
|
||||
var characters = new int[] { 8001, 1005, 1003 };
|
||||
|
||||
foreach (int id in characters)
|
||||
{
|
||||
response.LineupList[0].AvatarList.Add(new LineupAvatar
|
||||
{
|
||||
AvatarType = AvatarType.AVATAR_FORMAL_TYPE,
|
||||
CurHealth = new HealthBarInfo { CurHp = 10000, MaxHp = 10000 },
|
||||
Sp = 10000,
|
||||
Satiety = 100,
|
||||
Id = id,
|
||||
Slot = response.LineupList[0].AvatarList.Count
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetAllLineupDataScRsp, response);
|
||||
}
|
||||
|
||||
[Handler(CmdType.ChangeLineupLeaderCsReq)]
|
||||
public static void OnChangeLineupLeaderCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as ChangeLineupLeaderCsReq;
|
||||
session.Send(CmdType.ChangeLineupLeaderScRsp, new ChangeLineupLeaderScRsp
|
||||
{
|
||||
Slot = request.Slot,
|
||||
Retcode = Retcode.RETCODE_RET_SUCC
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
7
FreeSR.Gateserver/Manager/Handlers/MailReqGroup.cs
Normal file
7
FreeSR.Gateserver/Manager/Handlers/MailReqGroup.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
internal static class MailReqGroup
|
||||
{
|
||||
// MailReqGroup
|
||||
}
|
||||
}
|
87
FreeSR.Gateserver/Manager/Handlers/MissionReqGroup.cs
Normal file
87
FreeSR.Gateserver/Manager/Handlers/MissionReqGroup.cs
Normal file
|
@ -0,0 +1,87 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal static class MissionReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetMissionStatusCsReq)]
|
||||
public static void OnGetMissionStatusCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as GetMissionStatusCsReq;
|
||||
GetMissionStatusScRsp response = new GetMissionStatusScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
|
||||
DisabledMainMissionIdList = new List<int>(),
|
||||
FinishedMainMissionIdList = new List<int>(),
|
||||
MissionEventStatusList = new List<Mission>(),
|
||||
SubMissionStatusList = new List<Mission>(),
|
||||
UnfinishedMainMissionIdList = new List<int>()
|
||||
};
|
||||
|
||||
response.FinishedMainMissionIdList = new List<int>
|
||||
{
|
||||
1000101,
|
||||
1000112,
|
||||
1000113,
|
||||
1000201,
|
||||
1000202,
|
||||
1000204,
|
||||
1000301,
|
||||
1000401,
|
||||
1000402,
|
||||
1000410,
|
||||
1000510,
|
||||
1000601,
|
||||
1010301,
|
||||
1010302,
|
||||
1010401,
|
||||
1010403,
|
||||
1010701,
|
||||
1011403,
|
||||
1010202,
|
||||
1010902,
|
||||
1011102,
|
||||
4010101
|
||||
};
|
||||
|
||||
if (request.MissionEventIdList != null)
|
||||
{
|
||||
foreach (int id in request.MissionEventIdList)
|
||||
{
|
||||
response.UnfinishedMainMissionIdList.Add(id);
|
||||
}
|
||||
}
|
||||
|
||||
if (request.SubMissionIdList != null)
|
||||
{
|
||||
foreach (int id in request.SubMissionIdList)
|
||||
{
|
||||
response.MissionEventStatusList.Add(new Mission()
|
||||
{
|
||||
Id = id,
|
||||
Progress = 0,
|
||||
Status = MissionStatus.MISSION_FINISH
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (request.MainMissionIdList != null)
|
||||
{
|
||||
foreach (int id in request.MainMissionIdList)
|
||||
{
|
||||
response.SubMissionStatusList.Add(new Mission()
|
||||
{
|
||||
Id = id,
|
||||
Progress = 0,
|
||||
Status = MissionStatus.MISSION_FINISH
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetMissionStatusScRsp, response);
|
||||
}
|
||||
}
|
||||
}
|
41
FreeSR.Gateserver/Manager/Handlers/NPCReqGroup.cs
Normal file
41
FreeSR.Gateserver/Manager/Handlers/NPCReqGroup.cs
Normal file
|
@ -0,0 +1,41 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
using System.ComponentModel.Design;
|
||||
|
||||
internal static class NPCReqGroup
|
||||
{
|
||||
//maybe useless
|
||||
[Handler(CmdType.GetNpcTakenRewardCsReq)]
|
||||
public static void OnGetNpcTakenRewardCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
|
||||
var npcRewardReq = data as GetNpcTakenRewardCsReq;
|
||||
|
||||
session.Send(CmdType.GetNpcTakenRewardScRsp, new GetNpcTakenRewardScRsp
|
||||
{
|
||||
NpcId = npcRewardReq.NpcId,
|
||||
Retcode = Retcode.RETCODE_RET_SUCC
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetFirstTalkByPerformanceNpcCsReq)]
|
||||
public static void OnGetFirstTalkByPerformanceNpcCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
session.Send(CmdType.GetFirstTalkByPerformanceNpcScRsp, new GetFirstTalkByPerformanceNpcScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
NpcMeetStatusList = new List<OCLEPLBNNPA>
|
||||
{
|
||||
new OCLEPLBNNPA
|
||||
{
|
||||
IsMeet = true,
|
||||
Jljhobhmaof = 1
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
113
FreeSR.Gateserver/Manager/Handlers/PlayerReqGroup.cs
Normal file
113
FreeSR.Gateserver/Manager/Handlers/PlayerReqGroup.cs
Normal file
|
@ -0,0 +1,113 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
using NLog;
|
||||
|
||||
internal static class PlayerReqGroup
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Handler(CmdType.PlayerHeartBeatCsReq)]
|
||||
public static void OnPlayerHeartBeatCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var heartbeatReq = data as PlayerHeartBeatCsReq;
|
||||
|
||||
session.Send(CmdType.PlayerHeartBeatScRsp, new PlayerHeartBeatScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
|
||||
DownloadData = new ClientDownloadData(),
|
||||
ClientTimeMs = heartbeatReq.ClientTimeMs,
|
||||
ServerTimeMs = DateTimeOffset.Now.ToUnixTimeMilliseconds()
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetHeroBasicTypeInfoCsReq)]
|
||||
public static void OnGetHeroBasicTypeInfoCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
session.Send(CmdType.GetHeroBasicTypeInfoScRsp, new GetHeroBasicTypeInfoScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
Gender = Gender.GenderMan,
|
||||
BasicTypeInfoList = new List<HeroBasicTypeInfo>
|
||||
{
|
||||
new HeroBasicTypeInfo
|
||||
{
|
||||
BasicType = HeroBasicType.BoyWarrior,
|
||||
Rank = 1,
|
||||
SkillTreeList = new List<AvatarSkillTree>()
|
||||
}
|
||||
},
|
||||
CurBasicType = HeroBasicType.BoyWarrior,
|
||||
IsPlayerInfoModified = false,
|
||||
IsGenderModified = false
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetBasicInfoCsReq)]
|
||||
public static void OnGetBasicInfoCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
session.Send(CmdType.GetBasicInfoScRsp, new GetBasicInfoScRsp
|
||||
{
|
||||
CurDay = 1,
|
||||
ExchangeTimes = 0,
|
||||
Retcode = 0,
|
||||
NextRecoverTime = 2281337,
|
||||
WeekCocoonFinishedCount = 0
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.PlayerLoginCsReq)]
|
||||
public static void OnPlayerLoginCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as PlayerLoginCsReq;
|
||||
|
||||
session.Send(CmdType.PlayerLoginScRsp, new PlayerLoginScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
IsNewPlayer = false,
|
||||
LoginRandom = request.LoginRandom,
|
||||
Stamina = 100,
|
||||
ServerTimestampMs = DateTimeOffset.Now.ToUnixTimeSeconds() * 1000,
|
||||
BasicInfo = new PlayerBasicInfo
|
||||
{
|
||||
Nickname = "xeondev",
|
||||
Level = 30,
|
||||
Exp = 0,
|
||||
Stamina = 100,
|
||||
MCoin = 0,
|
||||
HCoin = 0,
|
||||
SCoin = 0,
|
||||
WorldLevel = 0
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
[Handler(CmdType.PlayerGetTokenCsReq)]
|
||||
public static void OnPlayerGetTokenCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
var request = data as PlayerGetTokenCsReq;
|
||||
|
||||
session.Send(CmdType.PlayerGetTokenScRsp, new PlayerGetTokenScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
Uid = int.Parse(request.AccountUid),
|
||||
BlackInfo = null,
|
||||
Msg = null,
|
||||
SecretKeySeed = 0
|
||||
});
|
||||
|
||||
session.Send(CmdType.BattlePassInfoNotify, new BattlePassInfoNotify
|
||||
{
|
||||
Ibkdaabmege = ILGFODEJBBH.BP_TIER_TYPE_PREMIUM_2,
|
||||
Caajdlolcml = 0,
|
||||
Ipneaeepcmk = 4,
|
||||
Okffhjicndl = 0,
|
||||
Exp = 1000,
|
||||
Level = 50
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
7
FreeSR.Gateserver/Manager/Handlers/QuestReqGroup.cs
Normal file
7
FreeSR.Gateserver/Manager/Handlers/QuestReqGroup.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
internal static class QuestReqGroup
|
||||
{
|
||||
// QuestReqGroup
|
||||
}
|
||||
}
|
45
FreeSR.Gateserver/Manager/Handlers/SceneReqGroup.cs
Normal file
45
FreeSR.Gateserver/Manager/Handlers/SceneReqGroup.cs
Normal file
|
@ -0,0 +1,45 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
|
||||
|
||||
internal static class SceneReqGroup
|
||||
{
|
||||
[Handler(CmdType.GetCurSceneInfoCsReq)]
|
||||
public static void OnGetCurSceneInfoCsReq(NetSession session, int cmdId, object data)
|
||||
{
|
||||
SceneInfo scene = new SceneInfo
|
||||
{
|
||||
GameModeType = 1,
|
||||
Bkmbkahohif = 1,
|
||||
Admbbnbnibk = 1,
|
||||
EntryId = 1000101,
|
||||
PlaneId = 10001,
|
||||
FloorId = 10001001,
|
||||
EntityList = new List<SceneEntityInfo>(),
|
||||
EnvBuffList = new List<BuffInfo>(),
|
||||
LightenSectionList = new List<int>()
|
||||
};
|
||||
|
||||
scene.EntityList.Add(new SceneEntityInfo
|
||||
{
|
||||
EntityId = 0,
|
||||
GroupId = 0,
|
||||
InstId = 0,
|
||||
Motion = new MotionInfo()
|
||||
{
|
||||
Pos = new Vector(),
|
||||
Rot = new Vector()
|
||||
}
|
||||
});
|
||||
|
||||
session.Send(CmdType.GetCurSceneInfoScRsp, new GetCurSceneInfoScRsp
|
||||
{
|
||||
Scene = scene,
|
||||
Retcode = Retcode.RETCODE_RET_SUCC
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
70
FreeSR.Gateserver/Manager/Handlers/TutorialReqGroup.cs
Normal file
70
FreeSR.Gateserver/Manager/Handlers/TutorialReqGroup.cs
Normal file
|
@ -0,0 +1,70 @@
|
|||
namespace FreeSR.Gateserver.Manager.Handlers
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using FreeSR.Proto;
|
||||
using NLog;
|
||||
|
||||
internal static class TutorialReqGroup
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
[Handler(CmdType.GetTutorialGuideCsReq)]
|
||||
public static void OnGetTutorialGuideCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
var response = new GetTutorialGuideScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
TutorialGuideList = new List<TutorialGuide>()
|
||||
};
|
||||
|
||||
int[] guides = new int[]
|
||||
{
|
||||
1101, 1102, 1104, 1105, 1116, 1117, 2006, 2007, 2101, 2105, 2106, 2107, 3007, 3105, 3106, 4001, 4101, 4102, 4103, 4104, 4105, 4106, 4107, 4108, 4109, 5101, 5102, 5103, 5104, 5105, 6001, 6002, 6003, 6004, 6005, 6006, 6007, 9101, 9102, 9103, 9104, 9105, 9106, 9107, 9108
|
||||
};
|
||||
|
||||
foreach (int id in guides)
|
||||
{
|
||||
response.TutorialGuideList.Add(new TutorialGuide
|
||||
{
|
||||
Id = id,
|
||||
Status = TutorialStatus.TUTORIAL_FINISH
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetTutorialGuideScRsp, response);
|
||||
}
|
||||
|
||||
[Handler(CmdType.GetTutorialCsReq)]
|
||||
public static void OnGetTutorialCsReq(NetSession session, int cmdId, object _)
|
||||
{
|
||||
int[] completedTutorials = new int[]
|
||||
{
|
||||
1001, 1002, 1003, 1004, 1005, 1007, 1008, 1010, 1011,
|
||||
2001, 2002, 2003, 2004, 2005, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
|
||||
3001, 3002, 3003, 3004, 3005, 3006,
|
||||
4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009,
|
||||
5001, 5002, 5003, 5004, 5005, 5006, 5007, 5008, 5009, 5010, 5011, 5012,
|
||||
7001,
|
||||
9001, 9002, 9003, 9004, 9005, 9006
|
||||
};
|
||||
|
||||
var response = new GetTutorialScRsp
|
||||
{
|
||||
Retcode = Retcode.RETCODE_RET_SUCC,
|
||||
TutorialList = new List<Tutorial>()
|
||||
};
|
||||
|
||||
foreach (int id in completedTutorials)
|
||||
{
|
||||
response.TutorialList.Add(new Tutorial
|
||||
{
|
||||
Id = id,
|
||||
Status = TutorialStatus.TUTORIAL_FINISH
|
||||
});
|
||||
}
|
||||
|
||||
session.Send(CmdType.GetTutorialScRsp, response);
|
||||
}
|
||||
}
|
||||
}
|
68
FreeSR.Gateserver/Manager/NotifyManager.cs
Normal file
68
FreeSR.Gateserver/Manager/NotifyManager.cs
Normal file
|
@ -0,0 +1,68 @@
|
|||
namespace FreeSR.Gateserver.Manager
|
||||
{
|
||||
using FreeSR.Gateserver.Manager.Handlers.Core;
|
||||
using FreeSR.Gateserver.Network;
|
||||
using Nito.AsyncEx;
|
||||
using NLog;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
internal static class NotifyManager
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
private static List<Type> s_handlerTypes = new List<Type>();
|
||||
private static ImmutableDictionary<int, (HandlerAttribute, HandlerAttribute.HandlerDelegate)> s_notifyReqGroup;
|
||||
|
||||
public static void Init()
|
||||
{
|
||||
var handlers = ImmutableDictionary.CreateBuilder<int, (HandlerAttribute, HandlerAttribute.HandlerDelegate)>();
|
||||
|
||||
foreach (var type in s_handlerTypes)
|
||||
{
|
||||
foreach (var method in type.GetMethods())
|
||||
{
|
||||
var attribute = method.GetCustomAttribute<HandlerAttribute>();
|
||||
if (attribute == null)
|
||||
continue;
|
||||
|
||||
var parameterInfo = method.GetParameters();
|
||||
|
||||
var sessionParameter = Expression.Parameter(typeof(NetSession));
|
||||
var cmdIdParameter = Expression.Parameter(typeof(int));
|
||||
var dataParameter = Expression.Parameter(typeof(object));
|
||||
|
||||
var call = Expression.Call(method,
|
||||
Expression.Convert(sessionParameter, parameterInfo[0].ParameterType),
|
||||
Expression.Convert(cmdIdParameter, parameterInfo[1].ParameterType),
|
||||
Expression.Convert(dataParameter, parameterInfo[2].ParameterType));
|
||||
|
||||
var lambda = Expression.Lambda<HandlerAttribute.HandlerDelegate>(call, sessionParameter, cmdIdParameter, dataParameter);
|
||||
|
||||
if (!handlers.TryGetKey(attribute.CmdID, out _))
|
||||
handlers.Add(attribute.CmdID, (attribute, lambda.Compile()));
|
||||
}
|
||||
}
|
||||
|
||||
s_notifyReqGroup = handlers.ToImmutable();
|
||||
}
|
||||
|
||||
public static void Notify(NetSession session, int cmdId, object data)
|
||||
{
|
||||
if (s_notifyReqGroup.TryGetValue(cmdId, out var handler))
|
||||
{
|
||||
AsyncContext.Run(() => handler.Item2.Invoke(session, cmdId, data));
|
||||
}
|
||||
else
|
||||
{
|
||||
s_log.Warn($"Can't find handler, cmdId: {cmdId}");
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddReqGroupHandler(Type type)
|
||||
{
|
||||
s_handlerTypes.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
53
FreeSR.Gateserver/Network/Factory/ProtoFactory.cs
Normal file
53
FreeSR.Gateserver/Network/Factory/ProtoFactory.cs
Normal file
|
@ -0,0 +1,53 @@
|
|||
namespace FreeSR.Gateserver.Network.Factory
|
||||
{
|
||||
using FreeSR.Proto;
|
||||
using ProtoBuf;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
internal static class ProtoFactory
|
||||
{
|
||||
private static readonly ImmutableDictionary<CmdType, Type> s_types;
|
||||
|
||||
static ProtoFactory()
|
||||
{
|
||||
var builder = ImmutableDictionary.CreateBuilder<CmdType, Type>();
|
||||
builder.AddRange(new Dictionary<CmdType, Type>()
|
||||
{
|
||||
{CmdType.PlayerGetTokenCsReq, typeof(PlayerGetTokenCsReq)},
|
||||
{CmdType.PlayerLoginCsReq, typeof(PlayerLoginCsReq)},
|
||||
{CmdType.GetAvatarDataCsReq, typeof(GetAvatarDataCsReq)},
|
||||
|
||||
{CmdType.GetAllLineupDataCsReq, typeof(GetAllLineupDataCsReq)},
|
||||
{CmdType.GetCurLineupDataCsReq, typeof(GetCurLineupDataCsReq)},
|
||||
{CmdType.ChangeLineupLeaderCsReq, typeof(ChangeLineupLeaderCsReq)},
|
||||
|
||||
{CmdType.GetMissionStatusCsReq, typeof(GetMissionStatusCsReq)},
|
||||
{CmdType.GetQuestDataCsReq, typeof(GetQuestDataCsReq)},
|
||||
{CmdType.GetChallengeCsReq, typeof(GetChallengeCsReq)},
|
||||
{CmdType.GetCurSceneInfoCsReq, typeof(GetCurSceneInfoCsReq)},
|
||||
|
||||
{CmdType.GetBasicInfoCsReq, typeof(GetBasicInfoCsReq)},
|
||||
{CmdType.GetHeroBasicTypeInfoCsReq, typeof(GetHeroBasicTypeInfoCsReq)},
|
||||
{CmdType.PlayerHeartBeatCsReq, typeof(PlayerHeartBeatCsReq)},
|
||||
|
||||
{CmdType.GetGachaInfoCsReq, typeof(GetGachaInfoCsReq)},
|
||||
{CmdType.DoGachaCsReq, typeof(DoGachaCsReq)},
|
||||
|
||||
{CmdType.GetNpcTakenRewardCsReq, typeof(GetNpcTakenRewardCsReq)},
|
||||
{CmdType.GetFirstTalkByPerformanceNpcCsReq, typeof(GetFirstTalkByPerformanceNpcCsReq)},
|
||||
|
||||
{CmdType.GetBagCsReq, typeof(GetBagCsReq)}
|
||||
});
|
||||
|
||||
s_types = builder.ToImmutable();
|
||||
}
|
||||
|
||||
public static object Deserialize(int id, byte[] rawData)
|
||||
{
|
||||
if (s_types.TryGetValue((CmdType)id, out var type))
|
||||
return Serializer.Deserialize(type, new MemoryStream(rawData));
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
29
FreeSR.Gateserver/Network/Handlers/Decoder/PacketDecoder.cs
Normal file
29
FreeSR.Gateserver/Network/Handlers/Decoder/PacketDecoder.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
namespace FreeSR.Gateserver.Network.Handlers.Decoder
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Channels;
|
||||
using FreeSR.Gateserver.Network.Packet;
|
||||
using NLog;
|
||||
|
||||
internal class PacketDecoder : MessageToMessageDecoder<IByteBuffer>
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
protected override void Decode(IChannelHandlerContext context, IByteBuffer message, List<object> output)
|
||||
{
|
||||
var netPacket = new NetPacket();
|
||||
|
||||
DeserializationResult result;
|
||||
if ((result = netPacket.Deserialize(message)) != DeserializationResult.SUCC)
|
||||
{
|
||||
context.CloseAsync();
|
||||
s_log.Info("Closing connection, reason: " + result);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
output.Add(netPacket);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
namespace FreeSR.Gateserver.Network.Handlers.Decoder
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Channels;
|
||||
|
||||
internal class StarRailHeaderDecoder : ByteToMessageDecoder
|
||||
{
|
||||
private IByteBuffer _current;
|
||||
|
||||
public StarRailHeaderDecoder()
|
||||
{
|
||||
_current = Unpooled.Buffer();
|
||||
}
|
||||
|
||||
protected override void Decode(IChannelHandlerContext context, IByteBuffer input, List<object> output)
|
||||
{
|
||||
var allocated = Unpooled.Buffer();
|
||||
allocated.WriteBytes(_current);
|
||||
allocated.WriteBytes(input);
|
||||
_current = allocated;
|
||||
|
||||
byte[] lands = new byte[_current.ReadableBytes];
|
||||
_current.ReadBytes(lands);
|
||||
_current.ResetReaderIndex();
|
||||
|
||||
IByteBuffer packet;
|
||||
while ((packet = Process()) != null)
|
||||
output.Add(packet);
|
||||
}
|
||||
|
||||
private IByteBuffer Process()
|
||||
{
|
||||
if (_current.ReadableBytes < 12)
|
||||
return null;
|
||||
|
||||
_current.ReadInt(); // headMagic
|
||||
_current.ReadShort(); // CmdID
|
||||
int headerLength = _current.ReadShort();
|
||||
int payloadLength = _current.ReadInt();
|
||||
|
||||
int totalLength = 12 + headerLength + payloadLength + 4;
|
||||
_current.ResetReaderIndex();
|
||||
if (_current.ReadableBytes < totalLength)
|
||||
return null;
|
||||
|
||||
IByteBuffer result = _current.ReadBytes(totalLength);
|
||||
_current = _current.ReadBytes(_current.ReadableBytes);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
19
FreeSR.Gateserver/Network/Handlers/Encoder/PacketEncoder.cs
Normal file
19
FreeSR.Gateserver/Network/Handlers/Encoder/PacketEncoder.cs
Normal file
|
@ -0,0 +1,19 @@
|
|||
namespace FreeSR.Gateserver.Network.Handlers.Encoder
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Codecs;
|
||||
using DotNetty.Transport.Channels;
|
||||
using FreeSR.Gateserver.Network.Packet;
|
||||
using NLog;
|
||||
|
||||
internal class PacketEncoder : MessageToByteEncoder<NetPacket>
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
|
||||
protected override void Encode(IChannelHandlerContext context, NetPacket message, IByteBuffer output)
|
||||
{
|
||||
output.WriteBytes(message.Buf);
|
||||
s_log.Info($"Sent packet with cmdId {message.CmdId}");
|
||||
}
|
||||
}
|
||||
}
|
103
FreeSR.Gateserver/Network/Handlers/Manager/PacketHandler.cs
Normal file
103
FreeSR.Gateserver/Network/Handlers/Manager/PacketHandler.cs
Normal file
|
@ -0,0 +1,103 @@
|
|||
namespace FreeSR.Gateserver.Network.Handlers.Manager
|
||||
{
|
||||
using DotNetty.Transport.Channels;
|
||||
using FreeSR.Gateserver.Manager;
|
||||
using FreeSR.Gateserver.Network.Packet;
|
||||
using FreeSR.Proto;
|
||||
using NLog;
|
||||
using ProtoBuf;
|
||||
|
||||
internal class PacketHandler : ChannelHandlerAdapter
|
||||
{
|
||||
private static readonly Logger s_log = LogManager.GetCurrentClassLogger();
|
||||
private readonly NetSession _session;
|
||||
|
||||
public PacketHandler(NetSession session)
|
||||
{
|
||||
_session = session;
|
||||
}
|
||||
|
||||
public override void ChannelRead(IChannelHandlerContext context, object message)
|
||||
{
|
||||
NetPacket packet = message as NetPacket;
|
||||
if (packet.Data == null)
|
||||
{
|
||||
if (!SendDummyResponse(packet.CmdId))
|
||||
s_log.Warn($"CmdID {packet.CmdId} is undefined.");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
s_log.Info($"Received packet {packet.CmdId}!");
|
||||
NotifyManager.Notify(_session, packet.CmdId, packet.Data);
|
||||
}
|
||||
|
||||
private bool SendDummyResponse(int id)
|
||||
{
|
||||
if (s_dummyTable.TryGetValue((CmdType)id, out CmdType rspId))
|
||||
{
|
||||
_session.Send(rspId, new DummyPacket());
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static Dictionary<CmdType, CmdType> s_dummyTable = new Dictionary<CmdType, CmdType>
|
||||
{
|
||||
{CmdType.GetLevelRewardTakenListCsReq, CmdType.GetLevelRewardTakenListScRsp},
|
||||
{CmdType.GetRogueScoreRewardInfoCsReq, CmdType.GetRogueScoreRewardInfoScRsp},
|
||||
{CmdType.GetGachaInfoCsReq, CmdType.GetGachaInfoScRsp},
|
||||
{CmdType.QueryProductInfoCsReq, CmdType.QueryProductInfoScRsp},
|
||||
{CmdType.GetQuestDataCsReq, CmdType.GetQuestDataScRsp},
|
||||
{CmdType.GetQuestRecordCsReq, CmdType.GetQuestRecordScRsp},
|
||||
{CmdType.GetFriendListInfoCsReq, CmdType.GetFriendListInfoScRsp},
|
||||
{CmdType.GetFriendApplyListInfoCsReq, CmdType.GetFriendApplyListInfoScRsp},
|
||||
{CmdType.GetCurAssistCsReq, CmdType.GetCurAssistScRsp},
|
||||
{CmdType.GetRogueHandbookDataCsReq, CmdType.GetRogueHandbookDataScRsp},
|
||||
{CmdType.GetDailyActiveInfoCsReq, CmdType.GetDailyActiveInfoScRsp},
|
||||
{CmdType.GetFightActivityDataCsReq, CmdType.GetFightActivityDataScRsp},
|
||||
{CmdType.GetMultipleDropInfoCsReq, CmdType.GetMultipleDropInfoScRsp},
|
||||
{CmdType.GetPlayerReturnMultiDropInfoCsReq, CmdType.GetPlayerReturnMultiDropInfoScRsp},
|
||||
{CmdType.GetShareDataCsReq, CmdType.GetShareDataScRsp},
|
||||
{CmdType.GetTreasureDungeonActivityDataCsReq, CmdType.GetTreasureDungeonActivityDataScRsp},
|
||||
{CmdType.PlayerReturnInfoQueryCsReq, CmdType.PlayerReturnInfoQueryScRsp},
|
||||
{CmdType.GetBasicInfoCsReq, CmdType.GetBasicInfoScRsp},
|
||||
{CmdType.GetHeroBasicTypeInfoCsReq, CmdType.GetHeroBasicTypeInfoScRsp},
|
||||
{CmdType.GetBagCsReq, CmdType.GetBagScRsp},
|
||||
{CmdType.GetPlayerBoardDataCsReq, CmdType.GetPlayerBoardDataScRsp},
|
||||
{CmdType.GetAvatarDataCsReq, CmdType.GetAvatarDataScRsp},
|
||||
{CmdType.GetAllLineupDataCsReq, CmdType.GetAllLineupDataScRsp},
|
||||
{CmdType.GetActivityScheduleConfigCsReq, CmdType.GetActivityScheduleConfigScRsp},
|
||||
{CmdType.GetMissionDataCsReq, CmdType.GetMissionDataScRsp},
|
||||
{CmdType.GetMissionEventDataCsReq, CmdType.GetMissionEventDataScRsp},
|
||||
{CmdType.GetChallengeCsReq, CmdType.GetChallengeScRsp},
|
||||
{CmdType.GetCurChallengeCsReq, CmdType.GetCurChallengeScRsp},
|
||||
{CmdType.GetRogueInfoCsReq, CmdType.GetRogueInfoScRsp},
|
||||
{CmdType.GetExpeditionDataCsReq, CmdType.GetExpeditionDataScRsp},
|
||||
{CmdType.GetRogueDialogueEventDataCsReq, CmdType.GetRogueDialogueEventDataScRsp},
|
||||
{CmdType.GetJukeboxDataCsReq, CmdType.GetJukeboxDataScRsp},
|
||||
{CmdType.SyncClientResVersionCsReq, CmdType.SyncClientResVersionScRsp},
|
||||
{CmdType.DailyFirstMeetPamCsReq, CmdType.DailyFirstMeetPamScRsp},
|
||||
{CmdType.GetMuseumInfoCsReq, CmdType.GetMuseumInfoScRsp},
|
||||
{CmdType.GetLoginActivityCsReq, CmdType.GetLoginActivityScRsp},
|
||||
{CmdType.GetRaidInfoCsReq, CmdType.GetRaidInfoScRsp},
|
||||
{CmdType.GetTrialActivityDataCsReq, CmdType.GetTrialActivityDataScRsp},
|
||||
{CmdType.GetBoxingClubInfoCsReq, CmdType.GetBoxingClubInfoScRsp},
|
||||
{CmdType.GetNpcStatusCsReq, CmdType.GetNpcStatusScRsp},
|
||||
{CmdType.TextJoinQueryCsReq, CmdType.TextJoinQueryScRsp},
|
||||
{CmdType.GetSpringRecoverDataCsReq, CmdType.GetSpringRecoverDataScRsp},
|
||||
{CmdType.GetChatFriendHistoryCsReq, CmdType.GetChatFriendHistoryScRsp},
|
||||
{CmdType.GetSecretKeyInfoCsReq, CmdType.GetSecretKeyInfoScRsp},
|
||||
{CmdType.GetVideoVersionKeyCsReq, CmdType.GetVideoVersionKeyScRsp},
|
||||
{CmdType.GetCurLineupDataCsReq, CmdType.GetCurLineupDataScRsp},
|
||||
{CmdType.GetCurBattleInfoCsReq, CmdType.GetCurBattleInfoScRsp},
|
||||
{CmdType.GetCurSceneInfoCsReq, CmdType.GetCurSceneInfoScRsp},
|
||||
{CmdType.GetPhoneDataCsReq, CmdType.GetPhoneDataScRsp},
|
||||
{CmdType.PlayerLoginFinishCsReq, CmdType.PlayerLoginFinishScRsp}
|
||||
};
|
||||
|
||||
[ProtoContract]
|
||||
private class DummyPacket { }
|
||||
}
|
||||
}
|
32
FreeSR.Gateserver/Network/NetSession.cs
Normal file
32
FreeSR.Gateserver/Network/NetSession.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
namespace FreeSR.Gateserver.Network
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using DotNetty.Transport.Channels;
|
||||
using FreeSR.Gateserver.Network.Packet;
|
||||
using FreeSR.Proto;
|
||||
|
||||
internal class NetSession
|
||||
{
|
||||
private IChannel _channel;
|
||||
|
||||
public NetSession(IChannel channel)
|
||||
{
|
||||
_channel = channel;
|
||||
}
|
||||
|
||||
public async void Send<T>(CmdType cmdId, T data) where T : class
|
||||
{
|
||||
var packet = new NetPacket()
|
||||
{
|
||||
CmdId = (int)cmdId,
|
||||
Data = data
|
||||
};
|
||||
|
||||
var buffer = Unpooled.Buffer();
|
||||
packet.Serialize<T>(buffer);
|
||||
packet.Buf = buffer;
|
||||
|
||||
await _channel.WriteAndFlushAsync(packet);
|
||||
}
|
||||
}
|
||||
}
|
65
FreeSR.Gateserver/Network/NetworkManager.cs
Normal file
65
FreeSR.Gateserver/Network/NetworkManager.cs
Normal file
|
@ -0,0 +1,65 @@
|
|||
namespace FreeSR.Gateserver.Network
|
||||
{
|
||||
using DotNetty.Transport.Bootstrapping;
|
||||
using DotNetty.Transport.Channels;
|
||||
using DotNetty.Transport.Channels.Sockets;
|
||||
using FreeSR.Gateserver.Manager;
|
||||
using FreeSR.Gateserver.Manager.Handlers;
|
||||
using FreeSR.Gateserver.Network.Handlers.Decoder;
|
||||
using FreeSR.Gateserver.Network.Handlers.Encoder;
|
||||
using FreeSR.Gateserver.Network.Handlers.Manager;
|
||||
using FreeSR.Shared;
|
||||
using FreeSR.Shared.Configuration;
|
||||
using System.Net;
|
||||
|
||||
internal sealed class NetworkManager : Singleton<NetworkManager>
|
||||
{
|
||||
private ServerBootstrap _bootstrap;
|
||||
private IChannel _serverChannel;
|
||||
|
||||
public async Task Initialize(NetworkConfiguration config)
|
||||
{
|
||||
// Notify handlers
|
||||
{
|
||||
NotifyManager.AddReqGroupHandler(typeof(PlayerReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(MailReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(TutorialReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(ItemReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(AvatarReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(LineupReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(MissionReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(QuestReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(ChallengeReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(SceneReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(GachaReqGroup));
|
||||
NotifyManager.AddReqGroupHandler(typeof(NPCReqGroup));
|
||||
|
||||
NotifyManager.Init();
|
||||
}
|
||||
|
||||
var bossGroup = new MultithreadEventLoopGroup();
|
||||
var workerGroup = new MultithreadEventLoopGroup();
|
||||
|
||||
_bootstrap = new ServerBootstrap()
|
||||
.Group(bossGroup, workerGroup)
|
||||
.Channel<TcpServerSocketChannel>()
|
||||
.Option(ChannelOption.SoBacklog, 120)
|
||||
.Option(ChannelOption.TcpNodelay, true)
|
||||
.Option(ChannelOption.SoKeepalive, true)
|
||||
.ChildHandler(
|
||||
new ActionChannelInitializer<IChannel>(channel =>
|
||||
{
|
||||
var session = new NetSession(channel);
|
||||
var pipeline = channel.Pipeline;
|
||||
|
||||
pipeline.AddFirst(new StarRailHeaderDecoder());
|
||||
pipeline.AddLast(new PacketDecoder());
|
||||
pipeline.AddLast(new PacketEncoder());
|
||||
pipeline.AddLast(new PacketHandler(session));
|
||||
})
|
||||
);
|
||||
|
||||
_serverChannel = await _bootstrap.BindAsync(IPAddress.Parse(config.Host), config.Port);
|
||||
}
|
||||
}
|
||||
}
|
77
FreeSR.Gateserver/Network/Packet/NetPacket.cs
Normal file
77
FreeSR.Gateserver/Network/Packet/NetPacket.cs
Normal file
|
@ -0,0 +1,77 @@
|
|||
namespace FreeSR.Gateserver.Network.Packet
|
||||
{
|
||||
using DotNetty.Buffers;
|
||||
using FreeSR.Gateserver.Network.Factory;
|
||||
using ProtoBuf;
|
||||
|
||||
internal class NetPacket
|
||||
{
|
||||
private const uint HeadMagicConst = 0x9d74c714;
|
||||
private const uint TailMagicConst = 0xd7a152c8;
|
||||
|
||||
public int CmdId { get; set; }
|
||||
public int HeadLen { get; set; }
|
||||
public uint HeadMagic { get; set; }
|
||||
public int PacketLen { get; set; }
|
||||
public byte[] RawData { get; set; }
|
||||
public uint TailMagic { get; set; }
|
||||
public object Data { get; set; }
|
||||
public IByteBuffer Buf { get; set; }
|
||||
|
||||
public NetPacket()
|
||||
{
|
||||
// NetPacket.
|
||||
}
|
||||
|
||||
public DeserializationResult Deserialize(IByteBuffer buf)
|
||||
{
|
||||
HeadMagic = buf.ReadUnsignedInt();
|
||||
if (HeadMagic != HeadMagicConst)
|
||||
return DeserializationResult.MAGIC_MISMATCH;
|
||||
|
||||
CmdId = buf.ReadShort();
|
||||
HeadLen = buf.ReadShort();
|
||||
PacketLen = buf.ReadInt();
|
||||
|
||||
if (buf.ReadableBytes < HeadLen + PacketLen + 4)
|
||||
return DeserializationResult.INVALID_LENGTH;
|
||||
|
||||
RawData = new byte[PacketLen];
|
||||
|
||||
_ = buf.ReadBytes(HeadLen);
|
||||
buf.ReadBytes(RawData);
|
||||
|
||||
TailMagic = buf.ReadUnsignedInt();
|
||||
if (TailMagic != TailMagicConst)
|
||||
return DeserializationResult.MAGIC_MISMATCH;
|
||||
|
||||
Data = ProtoFactory.Deserialize(CmdId, RawData);
|
||||
|
||||
return DeserializationResult.SUCC;
|
||||
}
|
||||
|
||||
public void Serialize<T>(IByteBuffer buf) where T : class
|
||||
{
|
||||
var stream = new MemoryStream();
|
||||
Serializer.Serialize(stream, Data as T);
|
||||
RawData = stream.ToArray();
|
||||
PacketLen = RawData.Length;
|
||||
|
||||
buf.WriteUnsignedShort((ushort)(HeadMagicConst >> 16));
|
||||
buf.WriteUnsignedShort(0xc714);
|
||||
buf.WriteShort(CmdId);
|
||||
buf.WriteShort(HeadLen);
|
||||
buf.WriteInt(PacketLen);
|
||||
buf.WriteBytes(RawData);
|
||||
buf.WriteUnsignedShort((ushort)(TailMagicConst >> 16));
|
||||
buf.WriteUnsignedShort(0x52c8);
|
||||
}
|
||||
}
|
||||
|
||||
internal enum DeserializationResult
|
||||
{
|
||||
SUCC = 1,
|
||||
INVALID_LENGTH,
|
||||
MAGIC_MISMATCH
|
||||
}
|
||||
}
|
12
FreeSR.Proto/AACCGBNDAIO.cs
Normal file
12
FreeSR.Proto/AACCGBNDAIO.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AACCGBNDAIO
|
||||
{
|
||||
[ProtoMember(5)] public int Bepmagjiopb;
|
||||
[ProtoMember(8)] public AvatarType AvatarType;
|
||||
}
|
||||
|
||||
}
|
17
FreeSR.Proto/AAEALIKMCLG.cs
Normal file
17
FreeSR.Proto/AAEALIKMCLG.cs
Normal file
|
@ -0,0 +1,17 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AAEALIKMCLG
|
||||
{
|
||||
[ProtoMember(4)] public int Damage;
|
||||
[ProtoMember(6)] public int Nbeecnlkomn;
|
||||
[ProtoMember(10)] public int Bepmagjiopb;
|
||||
[ProtoMember(2)] public int StageId;
|
||||
[ProtoMember(12)] public string Nickname;
|
||||
[ProtoMember(8)] public long Time;
|
||||
[ProtoMember(7)] public int Uid;
|
||||
}
|
||||
|
||||
}
|
12
FreeSR.Proto/ABCCDLAAOOO.cs
Normal file
12
FreeSR.Proto/ABCCDLAAOOO.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ABCCDLAAOOO
|
||||
{
|
||||
[ProtoMember(15)] public int Hmekpnciefb;
|
||||
[ProtoMember(2)] public int Cdgdnnefneb;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/ABJKDBCKFCC.cs
Normal file
11
FreeSR.Proto/ABJKDBCKFCC.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ABJKDBCKFCC
|
||||
{
|
||||
[ProtoMember(6)] public int Retcode;
|
||||
}
|
||||
|
||||
}
|
10
FreeSR.Proto/ABMGNABMJGH.cs
Normal file
10
FreeSR.Proto/ABMGNABMJGH.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ABMGNABMJGH
|
||||
{
|
||||
}
|
||||
|
||||
}
|
14
FreeSR.Proto/ACCJMILCGPF.cs
Normal file
14
FreeSR.Proto/ACCJMILCGPF.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ACCJMILCGPF
|
||||
{
|
||||
[ProtoMember(9)] public int Retcode;
|
||||
[ProtoMember(13)] public ItemList Reward;
|
||||
[ProtoMember(10)] public int TakeDays;
|
||||
[ProtoMember(4)] public int Id;
|
||||
}
|
||||
|
||||
}
|
12
FreeSR.Proto/ACHPPEPELLJ.cs
Normal file
12
FreeSR.Proto/ACHPPEPELLJ.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ACHPPEPELLJ
|
||||
{
|
||||
[ProtoMember(6)] public JOGGEDDHDHG Ngkebflomii;
|
||||
[ProtoMember(13)] public int Retcode;
|
||||
}
|
||||
|
||||
}
|
13
FreeSR.Proto/ACIEPALMNIK.cs
Normal file
13
FreeSR.Proto/ACIEPALMNIK.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ACIEPALMNIK
|
||||
{
|
||||
[ProtoMember(12)] public int Hcekcjdooch;
|
||||
[ProtoMember(14)] public int Retcode;
|
||||
[ProtoMember(11)] public BBNEDLDINPO Lihledalfil;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/ACJBCDBLJEG.cs
Normal file
11
FreeSR.Proto/ACJBCDBLJEG.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ACJBCDBLJEG
|
||||
{
|
||||
[ProtoMember(2)] public int Malnbhckeni;
|
||||
}
|
||||
|
||||
}
|
15
FreeSR.Proto/ACJFOAHHHFN.cs
Normal file
15
FreeSR.Proto/ACJFOAHHHFN.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ACJFOAHHHFN
|
||||
{
|
||||
[ProtoMember(11)] public int Khobiklbdnl;
|
||||
[ProtoMember(9)] public int Pjhbeoiiddl;
|
||||
[ProtoMember(10)] public int Ipfabmcjdmn;
|
||||
[ProtoMember(12)] public int Dfffenfgffn;
|
||||
[ProtoMember(1)] public int Dpnklgjojpl;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/ACKDBJMBHCJ.cs
Normal file
11
FreeSR.Proto/ACKDBJMBHCJ.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ACKDBJMBHCJ
|
||||
{
|
||||
[ProtoMember(2)] public int StageId;
|
||||
}
|
||||
|
||||
}
|
15
FreeSR.Proto/ACNAFDDOMOG.cs
Normal file
15
FreeSR.Proto/ACNAFDDOMOG.cs
Normal file
|
@ -0,0 +1,15 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ACNAFDDOMOG
|
||||
{
|
||||
[ProtoMember(1)] public bool Hgjpcbddcma;
|
||||
[ProtoMember(2)] public int Kfjkgomionh;
|
||||
[ProtoMember(3)] public bool Okeokgaicel;
|
||||
[ProtoMember(4)] public string Bamfbgadfik;
|
||||
[ProtoMember(5)] public bool Peohgknpoji;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/ACPCLKJPLEA.cs
Normal file
11
FreeSR.Proto/ACPCLKJPLEA.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ACPCLKJPLEA
|
||||
{
|
||||
[ProtoMember(2)] public int Retcode;
|
||||
}
|
||||
|
||||
}
|
10
FreeSR.Proto/ADBPNOOODLJ.cs
Normal file
10
FreeSR.Proto/ADBPNOOODLJ.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ADBPNOOODLJ
|
||||
{
|
||||
}
|
||||
|
||||
}
|
12
FreeSR.Proto/ADJGAMMCGGM.cs
Normal file
12
FreeSR.Proto/ADJGAMMCGGM.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
public enum ADJGAMMCGGM
|
||||
{
|
||||
SECRET_KEY_NONE = 0,
|
||||
SECRET_KEY_SERVER_CHECK = 1,
|
||||
SECRET_KEY_VIDEO = 2,
|
||||
SECRET_KEY_BATTLE_TIME = 3,
|
||||
}
|
||||
|
||||
}
|
12
FreeSR.Proto/ADMFMNOFEEJ.cs
Normal file
12
FreeSR.Proto/ADMFMNOFEEJ.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ADMFMNOFEEJ
|
||||
{
|
||||
[ProtoMember(2)] public IEHIDDGOALL Ckajekffbdp;
|
||||
[ProtoMember(14)] public DOFPJABOAAH Cjdfiiacefo;
|
||||
}
|
||||
|
||||
}
|
10
FreeSR.Proto/ADPDFNPMFOG.cs
Normal file
10
FreeSR.Proto/ADPDFNPMFOG.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class ADPDFNPMFOG
|
||||
{
|
||||
}
|
||||
|
||||
}
|
12
FreeSR.Proto/AEAFLDGKLCM.cs
Normal file
12
FreeSR.Proto/AEAFLDGKLCM.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AEAFLDGKLCM
|
||||
{
|
||||
[ProtoMember(4)] public int Opcfmgjjfia;
|
||||
[ProtoMember(6)] public int Retcode;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/AEEBKCJEIDE.cs
Normal file
11
FreeSR.Proto/AEEBKCJEIDE.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AEEBKCJEIDE
|
||||
{
|
||||
[ProtoMember(15)] public JDOFGIPGPBC Kiiipnflhkf;
|
||||
}
|
||||
|
||||
}
|
13
FreeSR.Proto/AEHDBIMPFKO.cs
Normal file
13
FreeSR.Proto/AEHDBIMPFKO.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AEHDBIMPFKO
|
||||
{
|
||||
[ProtoMember(14)] public int Retcode;
|
||||
[ProtoMember(9)] public BBMHAKPCLDC Agodpmobkah;
|
||||
[ProtoMember(11)] public BBMHAKPCLDC Hajhcfooipp;
|
||||
}
|
||||
|
||||
}
|
13
FreeSR.Proto/AEJGPEBIEKD.cs
Normal file
13
FreeSR.Proto/AEJGPEBIEKD.cs
Normal file
|
@ -0,0 +1,13 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AEJGPEBIEKD
|
||||
{
|
||||
[ProtoMember(8)] public int Nmanfpffopk;
|
||||
[ProtoMember(11)] public int Ddpdfgfcdnf;
|
||||
[ProtoMember(5)] public int Kjoacmenfbd;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/AEMFCABAKNJ.cs
Normal file
11
FreeSR.Proto/AEMFCABAKNJ.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AEMFCABAKNJ
|
||||
{
|
||||
[ProtoMember(4)] public int Id;
|
||||
}
|
||||
|
||||
}
|
12
FreeSR.Proto/AFCELKDNCJB.cs
Normal file
12
FreeSR.Proto/AFCELKDNCJB.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
public enum AFCELKDNCJB
|
||||
{
|
||||
ROGUE_HANDBOOK_MIRACLE_STATUS_LOCK = 0,
|
||||
ROGUE_HANDBOOK_MIRACLE_STATUS_UNLOCK = 1,
|
||||
ROGUE_HANDBOOK_MIRACLE_STATUS_MEET = 2,
|
||||
ROGUE_HANDBOOK_MIRACLE_STATUS_GET = 3,
|
||||
}
|
||||
|
||||
}
|
12
FreeSR.Proto/AFDEBFHBBBE.cs
Normal file
12
FreeSR.Proto/AFDEBFHBBBE.cs
Normal file
|
@ -0,0 +1,12 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AFDEBFHBBBE
|
||||
{
|
||||
[ProtoMember(7)] public List<int> Ddhddkakfah;
|
||||
[ProtoMember(10)] public bool Ilblcgbhkhm;
|
||||
}
|
||||
|
||||
}
|
10
FreeSR.Proto/AFHINEFMGON.cs
Normal file
10
FreeSR.Proto/AFHINEFMGON.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AFHINEFMGON
|
||||
{
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/AGAIEHANEIC.cs
Normal file
11
FreeSR.Proto/AGAIEHANEIC.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AGAIEHANEIC
|
||||
{
|
||||
[ProtoMember(6)] public IALMMKMPNCC Fhgojeafidj;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/AGFOJHLHEOC.cs
Normal file
11
FreeSR.Proto/AGFOJHLHEOC.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AGFOJHLHEOC
|
||||
{
|
||||
[ProtoMember(1)] public int Ppenknblbnh;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/AGGKOALBGBI.cs
Normal file
11
FreeSR.Proto/AGGKOALBGBI.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AGGKOALBGBI
|
||||
{
|
||||
[ProtoMember(11)] public List<HLLNFIHFNDP> ItemList;
|
||||
}
|
||||
|
||||
}
|
11
FreeSR.Proto/AGKDJLJMMJL.cs
Normal file
11
FreeSR.Proto/AGKDJLJMMJL.cs
Normal file
|
@ -0,0 +1,11 @@
|
|||
namespace FreeSR.Proto
|
||||
{
|
||||
using ProtoBuf;
|
||||
|
||||
[ProtoContract]
|
||||
public class AGKDJLJMMJL
|
||||
{
|
||||
[ProtoMember(1)] public int Uid;
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue