enter intro cutscene

This commit is contained in:
Naruse
2026-04-20 12:40:38 +08:00
parent 2826239284
commit 279da58dc1
81 changed files with 7279 additions and 0 deletions

View File

@@ -0,0 +1,285 @@
using Microsoft.AspNetCore.Mvc;
using MikuSB.Configuration;
using MikuSB.SdkServer.Models;
using MikuSB.Util;
using System.Text;
using System.Text.Json;
namespace MikuSB.SdkServer.Handlers;
[ApiController]
public class RouteController : ControllerBase
{
public static ConfigContainer Config = ConfigManager.Config;
public static object BuildServerList(string version = "")
{
return new
{
code = 0,
ret = 0,
msg = "ok",
message = "ok",
version,
server_time = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
servers = new[]
{
new
{
id = 1,
server_id = 1,
name = Config.GameServer.GameServerName,
title = Config.GameServer.GameServerName,
host = Config.GameServer.PublicAddress,
ip = Config.GameServer.PublicAddress,
port = Config.GameServer.Port,
status = 1,
state = 1,
is_open = true,
open = true,
recommend = true
}
},
game_server = new
{
host = Config.GameServer.PublicAddress,
ip = Config.GameServer.PublicAddress,
port = Config.GameServer.Port
},
http_server = new
{
host = Config.HttpServer.PublicAddress,
port = Config.HttpServer.Port
}
};
}
private static string? ExtractUid(string? authInfo)
{
if (string.IsNullOrWhiteSpace(authInfo))
return null;
try
{
var normalized = Uri.UnescapeDataString(authInfo).Trim();
var padding = normalized.Length % 4;
if (padding > 0)
normalized = normalized.PadRight(normalized.Length + (4 - padding), '=');
var json = Encoding.UTF8.GetString(Convert.FromBase64String(normalized));
using var document = JsonDocument.Parse(json);
return document.RootElement.TryGetProperty("uid", out var uid) ? uid.GetString() : null;
}
catch
{
return null;
}
}
[HttpGet("/getGameConfig")]
[HttpPost("/getGameConfig")]
public IActionResult GetGameConfig()
{
object rsp = new
{
code = "0",
data = new
{
agreementUpdateTime = "1728552600000",
appDownLoadUrl = "",
enableReportDataToDouyin = false,
loginType = new[] { "channel" },
openActivationCode = false,
qqGroup = (string?)null
},
msg = "success"
};
return Ok(rsp);
}
[HttpGet("/seasun/config")]
[HttpPost("/seasun/config")]
public IActionResult GetSeasunConfig()
{
object rsp = new
{
code = 0,
data = new
{
agreementUpdateTime = "1728552600000",
appDownLoadUrl = "",
enableReportDataToDouyin = false,
loginType = new[] { "channel" },
openActivationCode = false,
qqGroup = (string?)null,
privacyUpdateTime = "1728552600000",
realNameAuth = false
},
msg = "success"
};
return Ok(rsp);
}
[HttpGet("/seasun/loginByToken")]
[HttpPost("/seasun/loginByToken")]
public IActionResult LoginByToken(
[FromQuery] string? uid,
[FromQuery] string? token,
[FromForm] string? form_uid,
[FromForm] string? form_token
)
{
string finalUid = uid ?? form_uid ?? "10001";
string finalToken = token ?? form_token ?? Guid.NewGuid().ToString("N");
object rsp = new
{
code = 0,
data = new
{
associatedAccounts = new[]
{
new { bindStatus = false, nickname = "", thirdPartyType = "mail" },
new { bindStatus = true, nickname = Config.GameServer.GameServerName, thirdPartyType = "google" },
new { bindStatus = false, nickname = "", thirdPartyType = "twitter" },
new { bindStatus = false, nickname = "", thirdPartyType = "guest" },
new { bindStatus = false, nickname = "", thirdPartyType = "steam" }
},
isFirstLogin = false,
isNeedKoreaSciAuth = false,
ksOpenId = $"ks_{finalUid}",
nickname = Config.GameServer.GameServerName,
passportId = finalUid.Length > 10 ? finalUid[^10..] : finalUid,
playerFillAgeUrl = "",
status = 0,
thirdPartyUid = "",
finalToken,
type = "google",
uid = finalUid
},
msg = "操作成功"
};
return Ok(rsp);
}
[HttpGet("/seasun/getAccountInfoForGame")]
[HttpPost("/seasun/getAccountInfoForGame")]
public IActionResult GetAccountInfoForGame(
[FromQuery] string? uid,
[FromForm] string? form_uid
)
{
string uidString = uid ?? form_uid ?? "10001";
var finalUid = int.TryParse(uidString, out int parsedUid) ? parsedUid : 10001;
object rsp = new
{
code = 0,
data = new
{
bindAccountTypes = new[] { "google" },
channelUid = uidString,
loginAccountType = "google",
nickName = Config.GameServer.GameServerName,
passportId = uidString.Length > 10 ? uidString[^10..] : uidString,
uid = $"seasun__{uid}"
},
msg = "操作成功"
};
return Ok(rsp);
}
[HttpPost("/bisdk/batchpush")]
public IActionResult GetBatchPush()
{
object rsp = new
{
code = 0,
ret = 0,
msg = "ok",
message = "ok"
};
return Ok(rsp);
}
[HttpGet("/query")]
public IActionResult GetQuery([FromQuery] string? version, [FromQuery] string? platform)
{
object rsp = new
{
platform,
version,
host = Config.GameServer.PublicAddress,
port = Config.GameServer.Port
};
return Ok(rsp);
}
[HttpGet("/query_version={version}")]
public IActionResult GetQueryVersionV1(string version)
{
return Ok(BuildServerList(version));
}
[HttpGet("/query_version")]
public IActionResult GetQueryVersionV2([FromQuery] string version)
{
return Ok(BuildServerList(version));
}
[HttpGet("/api/serverlist")]
public IActionResult GetServerList()
{
return Ok(BuildServerList());
}
[HttpGet("/account/query-uid/{appId}")]
public IActionResult QueryUid(string appId, [FromQuery] string authInfo)
{
var uid = ExtractUid(authInfo) ?? "10001";
object rsp = new
{
code = "0",
msg = "success",
data = new
{
uid = $"seasun__{uid}"
}
};
return Ok(rsp);
}
[HttpGet("/health")]
public IActionResult HealthCheck()
{
object rsp = new
{
status = "ok",
service = Config.GameServer.GameServerName
};
return Ok(rsp);
}
[HttpPost("/api/auth/guest")]
public IActionResult AuthGuest([FromQuery] string? Token)
{
object rsp = new
{
Provider = "Guest",
Token = Token,
Account = "Account",
Pid = "123813131321312"
};
return Ok(rsp);
}
}

View File

@@ -0,0 +1,9 @@
namespace MikuSB.SdkServer.Models;
public class ResponseBase
{
public string Msg { get; set; } = "OK";
public bool Success { get; set; } = true;
public int Code { get; set; }
public object? Data { get; set; }
}

95
SdkServer/SdkServer.cs Normal file
View File

@@ -0,0 +1,95 @@
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using MikuSB.SdkServer.Handlers;
using MikuSB.SdkServer.Utils;
using MikuSB.Util;
using System.Text.Json;
namespace MikuSB.SdkServer;
public static class SdkServer
{
public static void Start(string[] args)
{
BuildWebHost(args).RunAsync();
}
private static IWebHost BuildWebHost(string[] args)
{
var builder = WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging((_, logging) => { logging.ClearProviders(); })
.UseUrls(ConfigManager.Config.HttpServer.GetDisplayAddress());
return builder.Build();
}
}
public class Startup
{
private static bool LooksLikeServerListRequest(string path, string? query)
{
var value = $"{path}?{query}".ToLowerInvariant();
return value.Contains("server")
|| value.Contains("version")
|| value.Contains("query_version")
|| value.Contains("serverlist");
}
public static void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment()) app.UseDeveloperExceptionPage();
app.UseRouting();
app.UseCors("AllowAll");
app.UseAuthorization();
app.UseMiddleware<RequestLoggingMiddleware>();
app.UseEndpoints(endpoints => { endpoints.MapControllers(); });
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
endpoints.MapFallback(async context =>
{
var path = context.Request.Path.Value ?? "";
if (LooksLikeServerListRequest(path, context.Request.QueryString.Value))
{
var response = RouteController.BuildServerList("");
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonSerializer.Serialize(response));
return;
}
var fallbackResponse = new
{
code = 0,
message = "ok",
service = ConfigManager.Config.GameServer.GameServerName,
path = path,
query = context.Request.QueryString.Value ?? ""
};
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonSerializer.Serialize(fallbackResponse));
});
});
}
public static void ConfigureServices(IServiceCollection services)
{
services.AddCors(options =>
{
options.AddPolicy("AllowAll",
builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); });
});
services.AddControllers()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower;
});
services.AddSingleton<Logger>(_ => new Logger("HttpServer"));
}
}

View File

@@ -0,0 +1,19 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>MikuSB.SdkServer</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" Version="3.0.0-preview3-19153-02" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,24 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace MikuSB.SdkServer.Utils;
public class JsonStringToObjectConverter<T> : JsonConverter<T> where T : class
{
public override T? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType != JsonTokenType.String)
return JsonSerializer.Deserialize<T>(ref reader, options);
var jsonString = reader.GetString();
return !string.IsNullOrEmpty(jsonString)
? JsonSerializer.Deserialize<T>(jsonString, options)
: null;
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
{
var json = JsonSerializer.Serialize(value, options);
writer.WriteStringValue(json);
}
}

View File

@@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Http;
using MikuSB.Util;
namespace MikuSB.SdkServer.Utils;
public class RequestLoggingMiddleware(RequestDelegate next)
{
public async Task InvokeAsync(HttpContext context, Logger logger)
{
var request = context.Request;
var method = request.Method;
var path = request.Path + request.QueryString;
await next(context);
var statusCode = context.Response.StatusCode;
if (path.StartsWith("/report") || path.Contains("/log/") || path == "/alive")
return;
if (statusCode == 200)
{
logger.Info($"{method} {path} => {statusCode}");
}
else if (statusCode == 404)
{
logger.Warn($"{method} {path} => {statusCode}");
}
else
{
logger.Error($"{method} {path} => {statusCode}");
}
}
}