forked from Raphael/SCHALE.GameServer
Rework Excel Downloader
This commit is contained in:
parent
7d1a57c984
commit
e42ea74608
|
@ -1 +0,0 @@
|
||||||
*
|
|
|
@ -1 +0,0 @@
|
||||||
*
|
|
|
@ -1 +0,0 @@
|
||||||
https://prod-clientpatch.bluearchiveyostar.com/r67_utfwo6vcvx7rhl017phc
|
|
|
@ -27,8 +27,8 @@ namespace SCHALE.GameServer.Controllers.Api.ProtocolHandlers
|
||||||
{
|
{
|
||||||
IrcConfig = new()
|
IrcConfig = new()
|
||||||
{
|
{
|
||||||
HostAddress = Config.Instance.Address,
|
HostAddress = Config.Instance.IRCAddress,
|
||||||
Port = Config.Instance.Port,
|
Port = Config.Instance.IRCPort,
|
||||||
Password = ""
|
Password = ""
|
||||||
},
|
},
|
||||||
AccountClanDB = new()
|
AccountClanDB = new()
|
||||||
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -63,32 +63,15 @@ namespace SCHALE.GameServer
|
||||||
Log.Information("Starting...");
|
Log.Information("Starting...");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Log.Information("Downloading Excels...");
|
// Load Config
|
||||||
await ExcelTableService.Init();
|
Config.Load();
|
||||||
|
|
||||||
|
// Load Excels
|
||||||
|
await ExcelTableService.LoadExcels();
|
||||||
|
|
||||||
// Load Commands
|
// Load Commands
|
||||||
CommandFactory.LoadCommands();
|
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);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,4 @@
|
||||||
<ProjectReference Include="..\SCHALE.Common\SCHALE.Common.csproj" />
|
<ProjectReference Include="..\SCHALE.Common\SCHALE.Common.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="Controllers\Data\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -6,6 +6,8 @@ using System.Threading.Tasks;
|
||||||
using Google.FlatBuffers;
|
using Google.FlatBuffers;
|
||||||
using Ionic.Zip;
|
using Ionic.Zip;
|
||||||
using SCHALE.Common.Crypto;
|
using SCHALE.Common.Crypto;
|
||||||
|
using SCHALE.GameServer.Utils;
|
||||||
|
using Serilog;
|
||||||
|
|
||||||
namespace SCHALE.GameServer.Services
|
namespace SCHALE.GameServer.Services
|
||||||
{
|
{
|
||||||
|
@ -15,63 +17,34 @@ namespace SCHALE.GameServer.Services
|
||||||
private readonly ILogger<ExcelTableService> logger = _logger;
|
private readonly ILogger<ExcelTableService> logger = _logger;
|
||||||
private readonly Dictionary<Type, object> caches = [];
|
private readonly Dictionary<Type, object> caches = [];
|
||||||
|
|
||||||
private static string? ResourcesFolder;
|
public static async Task LoadExcels()
|
||||||
private static string? ExcelFolder;
|
{
|
||||||
|
var excelZipUrl = $"https://prod-clientpatch.bluearchiveyostar.com/{Config.Instance.VersionId}/TableBundles/Excel.zip";
|
||||||
|
|
||||||
private static string GetUrl()
|
var excelDir = $"{Path.GetDirectoryName(AppContext.BaseDirectory)}/Resources/excel/";
|
||||||
{
|
var excelZipPath = Path.Combine(excelDir, "Excel.zip");
|
||||||
string urlPath;
|
|
||||||
if (ResourcesFolder == null)
|
|
||||||
{
|
|
||||||
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()
|
if (Directory.Exists(excelDir))
|
||||||
{
|
{
|
||||||
|
Log.Information("Excels already downloaded, skipping...");
|
||||||
string url = GetUrl();
|
|
||||||
string filePath = "TableBundles/Excel.zip";
|
|
||||||
string zipPath = Path.Combine(ResourcesFolder!, "download", filePath);
|
|
||||||
|
|
||||||
ExcelFolder = zipPath[..^4];
|
|
||||||
if (File.Exists(zipPath))
|
|
||||||
return;
|
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async Task Init()
|
Log.Information("Downloading Excels...");
|
||||||
{
|
Directory.CreateDirectory(excelDir);
|
||||||
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>
|
/// <summary>
|
||||||
|
@ -80,16 +53,14 @@ namespace SCHALE.GameServer.Services
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
/// <exception cref="FileNotFoundException"></exception>
|
/// <exception cref="FileNotFoundException"></exception>
|
||||||
public T GetTable<T>()
|
public T GetTable<T>() where T : IFlatbufferObject
|
||||||
where T : IFlatbufferObject
|
|
||||||
{
|
{
|
||||||
var type = typeof(T);
|
var type = typeof(T);
|
||||||
|
|
||||||
if (caches.TryGetValue(type, out var cache))
|
if (caches.TryGetValue(type, out var cache))
|
||||||
return (T)cache;
|
return (T)cache;
|
||||||
|
|
||||||
ArgumentNullException.ThrowIfNull(ExcelFolder);
|
var bytesFilePath = Path.Join(Path.GetDirectoryName(AppContext.BaseDirectory), "Resources/excel/", $"{type.Name.ToLower()}.bytes");
|
||||||
var bytesFilePath = Path.Join(ExcelFolder, $"{type.Name.ToLower()}.bytes");
|
|
||||||
if (!File.Exists(bytesFilePath))
|
if (!File.Exists(bytesFilePath))
|
||||||
{
|
{
|
||||||
throw new FileNotFoundException($"bytes files for {type.Name} not found");
|
throw new FileNotFoundException($"bytes files for {type.Name} not found");
|
||||||
|
@ -97,12 +68,7 @@ namespace SCHALE.GameServer.Services
|
||||||
|
|
||||||
var bytes = File.ReadAllBytes(bytesFilePath);
|
var bytes = File.ReadAllBytes(bytesFilePath);
|
||||||
TableEncryptionService.XOR(type.Name, bytes);
|
TableEncryptionService.XOR(type.Name, bytes);
|
||||||
var inst = type.GetMethod(
|
var inst = type.GetMethod($"GetRootAs{type.Name}", BindingFlags.Static | BindingFlags.Public, [typeof(ByteBuffer)])!.Invoke(null, [new ByteBuffer(bytes)]);
|
||||||
$"GetRootAs{type.Name}",
|
|
||||||
BindingFlags.Static | BindingFlags.Public,
|
|
||||||
[typeof(ByteBuffer)]
|
|
||||||
)!
|
|
||||||
.Invoke(null, [new ByteBuffer(bytes)]);
|
|
||||||
|
|
||||||
caches.Add(type, inst!);
|
caches.Add(type, inst!);
|
||||||
logger.LogDebug("{Excel} loaded and cached", type.Name);
|
logger.LogDebug("{Excel} loaded and cached", type.Name);
|
||||||
|
|
|
@ -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;
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace SCHALE.GameServer.Utils
|
namespace SCHALE.GameServer.Utils
|
||||||
|
@ -7,29 +11,49 @@ namespace SCHALE.GameServer.Utils
|
||||||
{
|
{
|
||||||
public static string ConfigPath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
|
public static string ConfigPath => Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Config.json");
|
||||||
|
|
||||||
public string Address { get; set; } = "127.0.0.1";
|
public string IRCAddress { get; set; } = "127.0.0.1";
|
||||||
public int Port { get; set; } = 6667;
|
public int IRCPort { get; set; } = 6667;
|
||||||
|
|
||||||
|
public string VersionId { get; set; } = "r67_utfwo6vcvx7rhl017phc";
|
||||||
|
|
||||||
public static void Load()
|
public static void Load()
|
||||||
{
|
{
|
||||||
if (!File.Exists(ConfigPath))
|
if (!File.Exists(ConfigPath))
|
||||||
|
{
|
||||||
|
Instance.IRCAddress = GetLocalIPv4(NetworkInterfaceType.Wireless80211) == string.Empty ? GetLocalIPv4(NetworkInterfaceType.Ethernet) : GetLocalIPv4(NetworkInterfaceType.Wireless80211);
|
||||||
Save();
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
#if !DOCKER_BUILD
|
|
||||||
string json = File.ReadAllText(ConfigPath);
|
string json = File.ReadAllText(ConfigPath);
|
||||||
Instance = JsonSerializer.Deserialize<Config>(json);
|
Instance = JsonSerializer.Deserialize<Config>(json);
|
||||||
#endif
|
|
||||||
|
|
||||||
Log.Debug($"Config loaded");
|
Log.Debug($"Config loaded");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Save()
|
public static void Save()
|
||||||
{
|
{
|
||||||
#if !DOCKER_BUILD
|
|
||||||
File.WriteAllText(ConfigPath, JsonSerializer.Serialize(Instance));
|
File.WriteAllText(ConfigPath, JsonSerializer.Serialize(Instance));
|
||||||
#endif
|
|
||||||
|
|
||||||
Log.Debug($"Config saved");
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue