283 lines
8.4 KiB
C#
283 lines
8.4 KiB
C#
using System;
|
||
using System.IO;
|
||
using System.Net.Http;
|
||
using System.Security.Cryptography;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
using System.Collections.Generic;
|
||
using YamlDotNet.Serialization;
|
||
using YamlDotNet.Serialization.NamingConventions;
|
||
using System.Diagnostics;
|
||
using System.Management;
|
||
|
||
class Program
|
||
{
|
||
static string gameDir = Path.GetFullPath(Path.Combine(AppContext.BaseDirectory, ".."));
|
||
static string updateDir = AppContext.BaseDirectory;
|
||
static string streamingAssetsDir => Path.Combine(gameDir, "Sinmai_Data", "StreamingAssets");
|
||
static string configPath => Path.Combine(updateDir, "config.yml");
|
||
static string serverJsonUrl = "";
|
||
|
||
static async Task Main()
|
||
{
|
||
try
|
||
{
|
||
Console.ForegroundColor = ConsoleColor.White;
|
||
Console.Clear();
|
||
Console.Title = "Sinmai 更新工具";
|
||
|
||
|
||
Config cfg = LoadOrCreateConfig(configPath);
|
||
|
||
|
||
if (!await VerifyAPIAsync(cfg.mc))
|
||
{
|
||
Console.ForegroundColor = ConsoleColor.Red;
|
||
Console.WriteLine("机器码验证失败了呢zako~");
|
||
Console.ResetColor();
|
||
return;
|
||
}
|
||
|
||
|
||
Console.WriteLine("检查更新中...");
|
||
var updates = await CheckUpdates();
|
||
|
||
if (updates.Count == 0)
|
||
{
|
||
Console.WriteLine("当前版本已是最新版本");
|
||
}
|
||
else
|
||
{
|
||
foreach (var file in updates)
|
||
{
|
||
await DownloadFile(file.Name, file.Url);
|
||
}
|
||
}
|
||
|
||
|
||
StartGame(cfg);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.ForegroundColor = ConsoleColor.Red;
|
||
Console.WriteLine("程序运行出现异常了呢zako:");
|
||
Console.WriteLine(ex.ToString());
|
||
Console.ResetColor();
|
||
Console.WriteLine("按任意键退出...");
|
||
Console.ReadKey();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
static Config LoadOrCreateConfig(string path)
|
||
{
|
||
var deserializer = new DeserializerBuilder()
|
||
.WithNamingConvention(UnderscoredNamingConvention.Instance)
|
||
.Build();
|
||
|
||
var serializer = new SerializerBuilder()
|
||
.WithNamingConvention(UnderscoredNamingConvention.Instance)
|
||
.Build();
|
||
|
||
Config cfg;
|
||
|
||
if (File.Exists(path))
|
||
{
|
||
string yaml = File.ReadAllText(path);
|
||
cfg = deserializer.Deserialize<Config>(yaml);
|
||
|
||
string newMC = GenerateMachineCode();
|
||
if (cfg.mc != newMC)
|
||
{
|
||
cfg.mc = newMC;
|
||
string newYaml = serializer.Serialize(cfg);
|
||
File.WriteAllText(path, newYaml);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
cfg = new Config
|
||
{
|
||
sinmaiargs = "-screen-fullscreen 1 -screen-width 1080 -screen-height 1920 -silent-crashes",
|
||
mc = GenerateMachineCode()
|
||
};
|
||
string yaml = serializer.Serialize(cfg);
|
||
File.WriteAllText(path, yaml);
|
||
Console.ForegroundColor = ConsoleColor.Yellow;
|
||
Console.WriteLine("首次运行已生成 config.yml");
|
||
Console.WriteLine("请复制以下机器码保存:");
|
||
Console.ResetColor();
|
||
Console.WriteLine($"机器码:{cfg.mc}");
|
||
Environment.Exit(0);
|
||
}
|
||
|
||
return cfg;
|
||
}
|
||
|
||
public class Config
|
||
{
|
||
public string sinmaiargs { get; set; } = "";
|
||
public string mc { get; set; } = "";
|
||
}
|
||
|
||
|
||
static string GenerateMachineCode()
|
||
{
|
||
try
|
||
{
|
||
string boardSerial = "";
|
||
string cpuId = "";
|
||
|
||
}
|
||
catch
|
||
{
|
||
return Guid.NewGuid().ToString("N");
|
||
}
|
||
}
|
||
|
||
|
||
|
||
static async Task<bool> VerifyAPIAsync(string mc)
|
||
{
|
||
try
|
||
{
|
||
using var client = new HttpClient();
|
||
client.DefaultRequestHeaders.UserAgent.ParseAdd("");
|
||
string url = $"";
|
||
string response = await client.GetStringAsync(url);
|
||
|
||
var jsonDoc = System.Text.Json.JsonDocument.Parse(response);
|
||
if (jsonDoc.RootElement.TryGetProperty("success", out var successProp))
|
||
{
|
||
return successProp.GetBoolean();
|
||
}
|
||
|
||
return false;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.ForegroundColor = ConsoleColor.Red;
|
||
Console.WriteLine("API 验证异常:");
|
||
Console.WriteLine(ex.ToString());
|
||
Console.ResetColor();
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
public class UpdateFile
|
||
{
|
||
public string Name { get; set; } = "";
|
||
public string Url { get; set; } = "";
|
||
}
|
||
|
||
static async Task<List<UpdateFile>> CheckUpdates()
|
||
{
|
||
List<UpdateFile> updates = new();
|
||
try
|
||
{
|
||
using var client = new HttpClient();
|
||
client.DefaultRequestHeaders.UserAgent.ParseAdd("Maimai/xin");
|
||
|
||
string json = await client.GetStringAsync(serverJsonUrl);
|
||
var serverFiles = System.Text.Json.JsonSerializer.Deserialize<List<UpdateFile>>(json,
|
||
new System.Text.Json.JsonSerializerOptions
|
||
{
|
||
PropertyNameCaseInsensitive = true
|
||
});
|
||
|
||
foreach (var file in serverFiles ?? new List<UpdateFile>())
|
||
{
|
||
string localPath = Path.Combine(streamingAssetsDir, file.Name.Replace('/', Path.DirectorySeparatorChar));
|
||
if (!File.Exists(localPath))
|
||
{
|
||
updates.Add(file);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.ForegroundColor = ConsoleColor.Red;
|
||
Console.WriteLine("检查更新异常:");
|
||
Console.WriteLine(ex.ToString());
|
||
Console.ResetColor();
|
||
}
|
||
return updates;
|
||
}
|
||
|
||
|
||
static async Task DownloadFile(string relativePath, string url)
|
||
{
|
||
string localPath = Path.Combine(streamingAssetsDir, relativePath.Replace('/', Path.DirectorySeparatorChar));
|
||
Directory.CreateDirectory(Path.GetDirectoryName(localPath)!);
|
||
|
||
try
|
||
{
|
||
using var client = new HttpClient();
|
||
using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
|
||
response.EnsureSuccessStatusCode();
|
||
|
||
using var stream = await response.Content.ReadAsStreamAsync();
|
||
using var fileStream = File.Create(localPath);
|
||
|
||
byte[] buffer = new byte[8192];
|
||
long totalRead = 0;
|
||
long total = response.Content.Headers.ContentLength ?? -1;
|
||
int read;
|
||
while ((read = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
|
||
{
|
||
await fileStream.WriteAsync(buffer, 0, read);
|
||
totalRead += read;
|
||
if (total > 0)
|
||
{
|
||
Console.Write($"\r下载 {relativePath} {totalRead * 100 / total}%");
|
||
Console.Out.Flush();
|
||
}
|
||
}
|
||
Console.WriteLine($"\r下载 {relativePath} 完成");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.ForegroundColor = ConsoleColor.Red;
|
||
Console.WriteLine($"下载 {relativePath} 出错:");
|
||
Console.WriteLine(ex.ToString());
|
||
Console.ResetColor();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
static void StartGame(Config cfg)
|
||
{
|
||
try
|
||
{
|
||
string gameRoot = gameDir;
|
||
string batPath = Path.Combine(gameRoot, "");
|
||
|
||
string batContent = $@"
|
||
|
||
";
|
||
|
||
File.WriteAllText(batPath, batContent, Encoding.Default);
|
||
|
||
var psi = new ProcessStartInfo
|
||
{
|
||
FileName = batPath,
|
||
WorkingDirectory = gameRoot,
|
||
UseShellExecute = true
|
||
};
|
||
Process.Start(psi);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.ForegroundColor = ConsoleColor.Red;
|
||
Console.WriteLine("启动游戏出错:");
|
||
Console.WriteLine(ex.ToString());
|
||
Console.ResetColor();
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
}
|