mirror of
https://github.com/MikuLeaks/MikuSB.git
synced 2026-06-05 20:13:59 +00:00
ResourceDownloader
This commit is contained in:
@@ -11,6 +11,8 @@ if (!argsMap.TryGetValue("--package", out var packagePath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
argsMap.TryGetValue("--pid", out var pidValue);
|
argsMap.TryGetValue("--pid", out var pidValue);
|
||||||
|
argsMap.TryGetValue("--resource-package", out var resourcePackagePath);
|
||||||
|
argsMap.TryGetValue("--resource-target", out var resourceTargetDirectory);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -23,6 +25,9 @@ try
|
|||||||
ZipFile.ExtractToDirectory(packagePath, stagingDirectory, overwriteFiles: true);
|
ZipFile.ExtractToDirectory(packagePath, stagingDirectory, overwriteFiles: true);
|
||||||
CopyDirectory(stagingDirectory, targetDirectory);
|
CopyDirectory(stagingDirectory, targetDirectory);
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(resourcePackagePath) && !string.IsNullOrWhiteSpace(resourceTargetDirectory))
|
||||||
|
UpdateResources(resourcePackagePath, resourceTargetDirectory);
|
||||||
|
|
||||||
Process.Start(new ProcessStartInfo
|
Process.Start(new ProcessStartInfo
|
||||||
{
|
{
|
||||||
FileName = restartExecutable,
|
FileName = restartExecutable,
|
||||||
@@ -88,3 +93,20 @@ static bool ShouldSkip(string relativePath)
|
|||||||
{
|
{
|
||||||
return relativePath.StartsWith("Config", StringComparison.OrdinalIgnoreCase);
|
return relativePath.StartsWith("Config", StringComparison.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UpdateResources(string resourcePackagePath, string resourceTargetDirectory)
|
||||||
|
{
|
||||||
|
var resourceStagingDirectory = Path.Combine(Path.GetTempPath(), "MikuSB", "resource-staging", Guid.NewGuid().ToString("N"));
|
||||||
|
Directory.CreateDirectory(resourceStagingDirectory);
|
||||||
|
|
||||||
|
ZipFile.ExtractToDirectory(resourcePackagePath, resourceStagingDirectory, overwriteFiles: true);
|
||||||
|
|
||||||
|
var extractedRoot = Directory.GetDirectories(resourceStagingDirectory).FirstOrDefault() ?? resourceStagingDirectory;
|
||||||
|
var excelOutputSource = Path.Combine(extractedRoot, "ExcelOutput");
|
||||||
|
if (!Directory.Exists(excelOutputSource))
|
||||||
|
throw new DirectoryNotFoundException($"ExcelOutput directory was not found in resource package: {excelOutputSource}");
|
||||||
|
|
||||||
|
var excelOutputTarget = Path.Combine(resourceTargetDirectory, "ExcelOutput");
|
||||||
|
Directory.CreateDirectory(excelOutputTarget);
|
||||||
|
CopyDirectory(excelOutputSource, excelOutputTarget);
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using MikuSB.GameServer.Server.CallGS;
|
|||||||
using MikuSB.GameServer.Server.Packet;
|
using MikuSB.GameServer.Server.Packet;
|
||||||
using MikuSB.Internationalization;
|
using MikuSB.Internationalization;
|
||||||
using MikuSB.MikuSB.Tool;
|
using MikuSB.MikuSB.Tool;
|
||||||
|
using MikuSB.MikuSB.Update;
|
||||||
using MikuSB.Proto;
|
using MikuSB.Proto;
|
||||||
using MikuSB.SdkServer;
|
using MikuSB.SdkServer;
|
||||||
using MikuSB.TcpSharp;
|
using MikuSB.TcpSharp;
|
||||||
@@ -146,6 +147,7 @@ public class LoaderManager : MikuSB
|
|||||||
// Load the game data
|
// Load the game data
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
await UpdateService.EnsureResourcesPresentAsync();
|
||||||
Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadingItem", I18NManager.Translate("Word.GameData")));
|
Logger.Info(I18NManager.Translate("Server.ServerInfo.LoadingItem", I18NManager.Translate("Word.GameData")));
|
||||||
ResourceManager.LoadGameData();
|
ResourceManager.LoadGameData();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
|
using System.IO.Compression;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
using MikuSB.Util;
|
using MikuSB.Util;
|
||||||
@@ -16,6 +17,13 @@ public static class UpdateService
|
|||||||
private static readonly string RepositoryName = "MikuSB";
|
private static readonly string RepositoryName = "MikuSB";
|
||||||
private static readonly string AssetName = "MikuSB-win-x64.zip";
|
private static readonly string AssetName = "MikuSB-win-x64.zip";
|
||||||
private static readonly int TimeoutSeconds = 5;
|
private static readonly int TimeoutSeconds = 5;
|
||||||
|
private static readonly string ResourceArchiveUrl =
|
||||||
|
"https://github.com/Kei-Luna/MikuSB-Resource/archive/refs/heads/main.zip";
|
||||||
|
private static readonly string[] RequiredResourceFiles =
|
||||||
|
[
|
||||||
|
"card.json",
|
||||||
|
"weapon.json"
|
||||||
|
];
|
||||||
|
|
||||||
public static async Task<bool> TryStartSelfUpdateAsync()
|
public static async Task<bool> TryStartSelfUpdateAsync()
|
||||||
{
|
{
|
||||||
@@ -72,6 +80,10 @@ public static class UpdateService
|
|||||||
Logger.Info($"Downloading update {release.TagName}.");
|
Logger.Info($"Downloading update {release.TagName}.");
|
||||||
await DownloadFileAsync(client, asset.DownloadUrl, packagePath, cts.Token);
|
await DownloadFileAsync(client, asset.DownloadUrl, packagePath, cts.Token);
|
||||||
|
|
||||||
|
var resourcePackagePath = Path.Combine(tempRoot, "MikuSB-Resource-main.zip");
|
||||||
|
Logger.Info("Downloading resource package.");
|
||||||
|
await DownloadFileAsync(client, ResourceArchiveUrl, resourcePackagePath, cts.Token);
|
||||||
|
|
||||||
var checksumAsset = release.Assets.FirstOrDefault(x =>
|
var checksumAsset = release.Assets.FirstOrDefault(x =>
|
||||||
string.Equals(x.Name, AssetName + ".sha256", StringComparison.OrdinalIgnoreCase));
|
string.Equals(x.Name, AssetName + ".sha256", StringComparison.OrdinalIgnoreCase));
|
||||||
if (checksumAsset != null)
|
if (checksumAsset != null)
|
||||||
@@ -90,7 +102,9 @@ public static class UpdateService
|
|||||||
ArgumentList =
|
ArgumentList =
|
||||||
{
|
{
|
||||||
"--package", packagePath,
|
"--package", packagePath,
|
||||||
|
"--resource-package", resourcePackagePath,
|
||||||
"--target", AppContext.BaseDirectory,
|
"--target", AppContext.BaseDirectory,
|
||||||
|
"--resource-target", Path.Combine(AppContext.BaseDirectory, ConfigManager.Config.Path.ResourcePath),
|
||||||
"--restart", Path.Combine(AppContext.BaseDirectory, "MikuSB.exe"),
|
"--restart", Path.Combine(AppContext.BaseDirectory, "MikuSB.exe"),
|
||||||
"--pid", Environment.ProcessId.ToString()
|
"--pid", Environment.ProcessId.ToString()
|
||||||
}
|
}
|
||||||
@@ -112,6 +126,15 @@ public static class UpdateService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task EnsureResourcesPresentAsync()
|
||||||
|
{
|
||||||
|
if (!AreRequiredResourcesPresent())
|
||||||
|
{
|
||||||
|
Logger.Warn("Required resources are missing. Downloading resource package.");
|
||||||
|
await DownloadAndInstallResourcesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static string StageUpdaterExecutable()
|
private static string StageUpdaterExecutable()
|
||||||
{
|
{
|
||||||
var sourceDirectory = AppContext.BaseDirectory;
|
var sourceDirectory = AppContext.BaseDirectory;
|
||||||
@@ -131,6 +154,45 @@ public static class UpdateService
|
|||||||
return stagedUpdaterPath;
|
return stagedUpdaterPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool AreRequiredResourcesPresent()
|
||||||
|
{
|
||||||
|
var excelOutputPath = Path.Combine(AppContext.BaseDirectory, ConfigManager.Config.Path.ResourcePath, "ExcelOutput");
|
||||||
|
if (!Directory.Exists(excelOutputPath))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return RequiredResourceFiles.All(fileName => File.Exists(Path.Combine(excelOutputPath, fileName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static async Task DownloadAndInstallResourcesAsync()
|
||||||
|
{
|
||||||
|
using var client = CreateHttpClient();
|
||||||
|
using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(Math.Max(1, TimeoutSeconds)));
|
||||||
|
var tempRoot = Path.Combine(Path.GetTempPath(), "MikuSB", "resources", Guid.NewGuid().ToString("N"));
|
||||||
|
Directory.CreateDirectory(tempRoot);
|
||||||
|
|
||||||
|
var resourcePackagePath = Path.Combine(tempRoot, "MikuSB-Resource-main.zip");
|
||||||
|
await DownloadFileAsync(client, ResourceArchiveUrl, resourcePackagePath, cts.Token);
|
||||||
|
InstallResourcesFromArchive(resourcePackagePath,
|
||||||
|
Path.Combine(AppContext.BaseDirectory, ConfigManager.Config.Path.ResourcePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void InstallResourcesFromArchive(string resourcePackagePath, string resourceTargetDirectory)
|
||||||
|
{
|
||||||
|
var resourceStagingDirectory = Path.Combine(Path.GetTempPath(), "MikuSB", "resource-staging", Guid.NewGuid().ToString("N"));
|
||||||
|
Directory.CreateDirectory(resourceStagingDirectory);
|
||||||
|
|
||||||
|
ZipFile.ExtractToDirectory(resourcePackagePath, resourceStagingDirectory, overwriteFiles: true);
|
||||||
|
|
||||||
|
var extractedRoot = Directory.GetDirectories(resourceStagingDirectory).FirstOrDefault() ?? resourceStagingDirectory;
|
||||||
|
var excelOutputSource = Path.Combine(extractedRoot, "ExcelOutput");
|
||||||
|
if (!Directory.Exists(excelOutputSource))
|
||||||
|
throw new DirectoryNotFoundException($"ExcelOutput directory was not found in resource package: {excelOutputSource}");
|
||||||
|
|
||||||
|
var excelOutputTarget = Path.Combine(resourceTargetDirectory, "ExcelOutput");
|
||||||
|
Directory.CreateDirectory(excelOutputTarget);
|
||||||
|
CopyDirectory(excelOutputSource, excelOutputTarget);
|
||||||
|
}
|
||||||
|
|
||||||
private static bool ConfirmUpdate(string latestVersion)
|
private static bool ConfirmUpdate(string latestVersion)
|
||||||
{
|
{
|
||||||
Console.Write($"New version found: {BuildVersion.Current} -> {latestVersion}. Update now? [Y/n]: ");
|
Console.Write($"New version found: {BuildVersion.Current} -> {latestVersion}. Update now? [Y/n]: ");
|
||||||
@@ -199,6 +261,23 @@ public static class UpdateService
|
|||||||
await source.CopyToAsync(destination, cancellationToken);
|
await source.CopyToAsync(destination, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CopyDirectory(string sourceDirectory, string targetDirectory)
|
||||||
|
{
|
||||||
|
foreach (var directory in Directory.GetDirectories(sourceDirectory, "*", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
var relativePath = Path.GetRelativePath(sourceDirectory, directory);
|
||||||
|
Directory.CreateDirectory(Path.Combine(targetDirectory, relativePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var file in Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories))
|
||||||
|
{
|
||||||
|
var relativePath = Path.GetRelativePath(sourceDirectory, file);
|
||||||
|
var destinationPath = Path.Combine(targetDirectory, relativePath);
|
||||||
|
Directory.CreateDirectory(Path.GetDirectoryName(destinationPath)!);
|
||||||
|
File.Copy(file, destinationPath, overwrite: true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void VerifySha256(string packagePath, string checksumPath)
|
private static void VerifySha256(string packagePath, string checksumPath)
|
||||||
{
|
{
|
||||||
var expected = File.ReadAllText(checksumPath).Split(' ', StringSplitOptions.RemoveEmptyEntries)[0].Trim();
|
var expected = File.ReadAllText(checksumPath).Split(' ', StringSplitOptions.RemoveEmptyEntries)[0].Trim();
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
v=0.3
|
v=0.4
|
||||||
Reference in New Issue
Block a user