Rework Excel Downloader

This commit is contained in:
raphaeIl 2024-05-31 16:15:26 +08:00
parent 7d1a57c984
commit e42ea74608
9 changed files with 67 additions and 182 deletions

View File

@ -1 +0,0 @@
*

View File

@ -1 +0,0 @@
*

View File

@ -1 +0,0 @@
https://prod-clientpatch.bluearchiveyostar.com/r67_utfwo6vcvx7rhl017phc

View File

@ -27,8 +27,8 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
{
IrcConfig = new()
{
HostAddress = Config.Instance.Address,
Port = Config.Instance.Port,
HostAddress = Config.Instance.IRCAddress,
Port = Config.Instance.IRCPort,
Password = ""
},
AccountClanDB = new()

View File

@ -1,81 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using SCHALE.Common.Crypto;
using SCHALE.Common.NetworkProtocol;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
namespace SCHALE.GameServer.Controllers.Data
{
[ApiController]
[Route("/data")]
public class DataController : ControllerBase
{
private readonly string absFolder;
private readonly ILogger<DataController> logger;
public DataController(ILogger<DataController> _logger)
{
logger = _logger;
var folder = Path.GetDirectoryName(AppContext.BaseDirectory);
string dataFolder;
while (true)
{
dataFolder = Path.Join(folder, "Resources/data");
if (Directory.Exists(dataFolder)) break;
folder = Path.GetDirectoryName(folder);
if (folder == null)
throw new FileNotFoundException($"Excel folder is not found.");
}
absFolder = dataFolder;
}
string? AbsPath(string relPath)
{
string filePath = Path.Combine(absFolder, relPath);
if (!System.IO.File.Exists(filePath)) return null;
logger.LogDebug($"Use our own {relPath}.");
return filePath;
}
[HttpGet("TableBundles/{fileName}")]
public IActionResult GetTableBundles(string fileName)
{
string relPath = $"TableBundles/{fileName}";
string? filePath = AbsPath(relPath);
if (filePath == null) return CatchAll(relPath);
if (fileName.EndsWith(".json"))
{
var jsonContent = System.IO.File.ReadAllText(filePath);
return Content(jsonContent, "application/json");
}
if (fileName.EndsWith(".zip"))
{
var fileStream = System.IO.File.OpenRead(filePath);
return File(fileStream, "application/zip", fileName);
}
if (fileName.EndsWith(".bytes"))
{
var fileStream = System.IO.File.OpenRead(filePath);
return File(fileStream, "application/octet-stream", fileName);
}
return CatchAll(relPath);
}
[HttpGet("{*catchAll}")]
public IActionResult CatchAll(string catchAll)
{
logger.LogDebug("Data path: {path}", catchAll);
string re = $"https://prod-clientpatch.bluearchiveyostar.com/r68_10iazxytt13razwn7x9n_3/{catchAll}";
return Redirect(re);
// return RedirectPermanent(re);
}
}
}

View File

@ -63,32 +63,15 @@ namespace SCHALE.GameServer
Log.Information("Starting...");
try
{
Log.Information("Downloading Excels...");
await ExcelTableService.Init();
// Load Config
Config.Load();
// Load Excels
await ExcelTableService.LoadExcels();
// Load Commands
CommandFactory.LoadCommands();
// Load Config
Config.Load();
if (Config.Instance.Address == "127.0.0.1")
{
Config.Instance.Address = NetworkInterface
.GetAllNetworkInterfaces()
.Where(i =>
i.NetworkInterfaceType != NetworkInterfaceType.Loopback
&& i.OperationalStatus == OperationalStatus.Up
)
.First()
.GetIPProperties()
.UnicastAddresses.Where(a =>
a.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork
)
.First()
.Address.ToString();
Config.Save();
}
var builder = WebApplication.CreateBuilder(args);

View File

@ -20,8 +20,4 @@
<ProjectReference Include="..\SCHALE.Common\SCHALE.Common.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controllers\Data\" />
</ItemGroup>
</Project>

View File

@ -6,6 +6,8 @@ using System.Threading.Tasks;
using Google.FlatBuffers;
using Ionic.Zip;
using SCHALE.Common.Crypto;
using SCHALE.GameServer.Utils;
using Serilog;
namespace SCHALE.GameServer.Services
{
@ -15,63 +17,34 @@ namespace SCHALE.GameServer.Services
private readonly ILogger<ExcelTableService> logger = _logger;
private readonly Dictionary<Type, object> caches = [];
private static string? ResourcesFolder;
private static string? ExcelFolder;
private static string GetUrl()
public static async Task LoadExcels()
{
string urlPath;
if (ResourcesFolder == null)
var excelZipUrl = $"https://prod-clientpatch.bluearchiveyostar.com/{Config.Instance.VersionId}/TableBundles/Excel.zip";
var excelDir = $"{Path.GetDirectoryName(AppContext.BaseDirectory)}/Resources/excel/";
var excelZipPath = Path.Combine(excelDir, "Excel.zip");
if (Directory.Exists(excelDir))
{
var folder = Path.GetDirectoryName(AppContext.BaseDirectory);
while (true)
{
urlPath = Path.Join(folder, "Resources/url.txt");
if (File.Exists(urlPath))
break;
folder = Path.GetDirectoryName(folder);
if (folder == null)
throw new FileNotFoundException($"Resources folder is not found.");
}
ResourcesFolder = Path.GetDirectoryName(urlPath);
}
else
{
urlPath = Path.Join(ResourcesFolder, "url.txt");
}
string url = File.ReadAllText(urlPath);
return url + "/";
}
private static async Task GetZip()
{
string url = GetUrl();
string filePath = "TableBundles/Excel.zip";
string zipPath = Path.Combine(ResourcesFolder!, "download", filePath);
ExcelFolder = zipPath[..^4];
if (File.Exists(zipPath))
Log.Information("Excels already downloaded, skipping...");
return;
Directory.CreateDirectory(Path.GetDirectoryName(zipPath)!);
using HttpClient client = new();
HttpResponseMessage response = await client.GetAsync(url + filePath);
response.EnsureSuccessStatusCode();
byte[] content = await response.Content.ReadAsByteArrayAsync();
File.WriteAllBytes(zipPath, content);
using ZipFile zip = ZipFile.Read(zipPath);
zip.Password = Convert.ToBase64String(TableService.CreatePassword(Path.GetFileName(filePath)));
foreach (ZipEntry e in zip)
{
e.Extract(ExcelFolder, ExtractExistingFileAction.OverwriteSilently);
}
}
Log.Information("Downloading Excels...");
Directory.CreateDirectory(excelDir);
public static async Task Init()
{
await GetZip();
using var client = new HttpClient();
var zipBytes = await client.GetByteArrayAsync(excelZipUrl);
File.WriteAllBytes(excelZipPath, zipBytes);
using (var zip = ZipFile.Read(excelZipPath)) {
zip.Password = Convert.ToBase64String(TableService.CreatePassword(Path.GetFileName(excelZipPath)));
zip.ExtractAll(excelDir, ExtractExistingFileAction.OverwriteSilently);
}
File.Delete(excelZipPath);
Log.Information($"Excel Version {Config.Instance.VersionId} downloaded! Notice that versions higher than r67 currently does not work");
}
/// <summary>
@ -80,16 +53,14 @@ namespace SCHALE.GameServer.Services
/// <typeparam name="T"></typeparam>
/// <returns></returns>
/// <exception cref="FileNotFoundException"></exception>
public T GetTable<T>()
where T : IFlatbufferObject
public T GetTable<T>() where T : IFlatbufferObject
{
var type = typeof(T);
if (caches.TryGetValue(type, out var cache))
return (T)cache;
ArgumentNullException.ThrowIfNull(ExcelFolder);
var bytesFilePath = Path.Join(ExcelFolder, $"{type.Name.ToLower()}.bytes");
var bytesFilePath = Path.Join(Path.GetDirectoryName(AppContext.BaseDirectory), "Resources/excel/", $"{type.Name.ToLower()}.bytes");
if (!File.Exists(bytesFilePath))
{
throw new FileNotFoundException($"bytes files for {type.Name} not found");
@ -97,12 +68,7 @@ namespace SCHALE.GameServer.Services
var bytes = File.ReadAllBytes(bytesFilePath);
TableEncryptionService.XOR(type.Name, bytes);
var inst = type.GetMethod(
$"GetRootAs{type.Name}",
BindingFlags.Static | BindingFlags.Public,
[typeof(ByteBuffer)]
)!
.Invoke(null, [new ByteBuffer(bytes)]);
var inst = type.GetMethod($"GetRootAs{type.Name}", BindingFlags.Static | BindingFlags.Public, [typeof(ByteBuffer)])!.Invoke(null, [new ByteBuffer(bytes)]);
caches.Add(type, inst!);
logger.LogDebug("{Excel} loaded and cached", type.Name);

View File

@ -1,4 +1,8 @@
using Serilog;
using SCHALE.GameServer.Controllers.Api.ProtocolHandlers;
using Serilog;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Text.Json;
namespace SCHALE.GameServer.Utils
@ -7,29 +11,49 @@ namespace SCHALE.GameServer.Utils
{
public static string ConfigPath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
public string Address { get; set; } = "127.0.0.1";
public int Port { get; set; } = 6667;
public string IRCAddress { get; set; } = "127.0.0.1";
public int IRCPort { get; set; } = 6667;
public string VersionId { get; set; } = "r67_utfwo6vcvx7rhl017phc";
public static void Load()
{
if (!File.Exists(ConfigPath))
{
Instance.IRCAddress = GetLocalIPv4(NetworkInterfaceType.Wireless80211) == string.Empty ? GetLocalIPv4(NetworkInterfaceType.Ethernet) : GetLocalIPv4(NetworkInterfaceType.Wireless80211);
Save();
}
#if !DOCKER_BUILD
string json = File.ReadAllText(ConfigPath);
Instance = JsonSerializer.Deserialize<Config>(json);
#endif
Log.Debug($"Config loaded");
}
public static void Save()
{
#if !DOCKER_BUILD
File.WriteAllText(ConfigPath, JsonSerializer.Serialize(Instance));
#endif
Log.Debug($"Config saved");
}
public static string GetLocalIPv4(NetworkInterfaceType _type)
{
string output = "";
foreach (NetworkInterface item in NetworkInterface.GetAllNetworkInterfaces())
{
if (item.NetworkInterfaceType == _type && item.OperationalStatus == OperationalStatus.Up)
{
foreach (UnicastIPAddressInformation ip in item.GetIPProperties().UnicastAddresses)
{
if (ip.Address.AddressFamily == AddressFamily.InterNetwork)
{
output = ip.Address.ToString();
}
}
}
}
return output;
}
}
}