255 lines
8.3 KiB
C#
255 lines
8.3 KiB
C#
using SptCommon.Annotations;
|
|
using Core.DI;
|
|
using Core.Models.Eft.Common.Tables;
|
|
using Core.Models.Spt.Config;
|
|
using Core.Models.Spt.Server;
|
|
using Core.Models.Utils;
|
|
using Core.Routers;
|
|
using Core.Servers;
|
|
using Core.Services;
|
|
|
|
namespace Core.Utils;
|
|
|
|
[Injectable(InjectionType.Singleton, InjectableTypeOverride = typeof(OnLoad), TypePriority = OnLoadOrder.Database)]
|
|
public class DatabaseImporter : OnLoad
|
|
{
|
|
private object hashedFile;
|
|
private ValidationResult valid = ValidationResult.UNDEFINED;
|
|
private string filepath;
|
|
private HttpConfig httpConfig;
|
|
|
|
protected ISptLogger<DatabaseImporter> _logger;
|
|
protected LocalisationService _localisationService;
|
|
|
|
protected DatabaseServer _databaseServer;
|
|
|
|
protected ImageRouter _imageRouter;
|
|
protected EncodingUtil _encodingUtil;
|
|
protected HashUtil _hashUtil;
|
|
protected ImporterUtil _importerUtil;
|
|
protected ConfigServer _configServer;
|
|
protected FileUtil _fileUtil;
|
|
|
|
public DatabaseImporter(
|
|
ISptLogger<DatabaseImporter> logger,
|
|
// TODO: are we gonna use this? @inject("JsonUtil") protected jsonUtil: JsonUtil,
|
|
FileUtil fileUtil,
|
|
LocalisationService localisationService,
|
|
DatabaseServer databaseServer,
|
|
ImageRouter imageRouter,
|
|
EncodingUtil encodingUtil,
|
|
HashUtil hashUtil,
|
|
ImporterUtil importerUtil,
|
|
ConfigServer configServer
|
|
)
|
|
{
|
|
_logger = logger;
|
|
_localisationService = localisationService;
|
|
_databaseServer = databaseServer;
|
|
_encodingUtil = encodingUtil;
|
|
_hashUtil = hashUtil;
|
|
_importerUtil = importerUtil;
|
|
_configServer = configServer;
|
|
_fileUtil = fileUtil;
|
|
_imageRouter = imageRouter;
|
|
httpConfig = _configServer.GetConfig<HttpConfig>();
|
|
}
|
|
|
|
/**
|
|
* Get path to spt data
|
|
* @returns path to data
|
|
*/
|
|
public string GetSptDataPath()
|
|
{
|
|
return "./Assets/";
|
|
}
|
|
|
|
public async Task OnLoad()
|
|
{
|
|
filepath = GetSptDataPath();
|
|
|
|
/*
|
|
if (ProgramStatics.COMPILED) {
|
|
try {
|
|
// Reading the dynamic SHA1 file
|
|
const file = "checks.dat";
|
|
const fileWithPath = `${this.filepath}${file}`;
|
|
if (this.vfs.exists(fileWithPath)) {
|
|
this.hashedFile = this.jsonUtil.deserialize(
|
|
this.encodingUtil.fromBase64(this.vfs.readFile(fileWithPath)),
|
|
file,
|
|
);
|
|
} else {
|
|
this.valid = ValidationResult.NOT_FOUND;
|
|
this.logger.debug(this.localisationService.getText("validation_not_found"));
|
|
}
|
|
} catch (e) {
|
|
this.valid = ValidationResult.FAILED;
|
|
this.logger.warning(this.localisationService.getText("validation_error_decode"));
|
|
}
|
|
}
|
|
*/
|
|
|
|
await HydrateDatabase(filepath);
|
|
|
|
var imageFilePath = $"{filepath}images/";
|
|
CreateRouteMapping(imageFilePath, "files");
|
|
}
|
|
|
|
private void CreateRouteMapping(string directory, string newBasePath)
|
|
{
|
|
var directoryContent = GetAllFilesInDirectory(directory);
|
|
|
|
foreach (var fileNameWithPath in directoryContent)
|
|
{
|
|
var fileNameWithNoSPTPath = fileNameWithPath.Replace(directory, "");
|
|
var filePathNoExtension = _fileUtil.StripExtension(fileNameWithNoSPTPath, true);
|
|
if (filePathNoExtension.StartsWith("/") || fileNameWithPath.StartsWith("\\"))
|
|
filePathNoExtension = $"{filePathNoExtension.Substring(1)}";
|
|
|
|
var bsgPath = $"/{newBasePath}/{filePathNoExtension}".Replace("\\", "/");
|
|
_imageRouter.AddRoute(bsgPath, fileNameWithPath);
|
|
}
|
|
}
|
|
|
|
private List<string> GetAllFilesInDirectory(string directoryPath)
|
|
{
|
|
List<string> result = [];
|
|
result.AddRange(Directory.GetFiles(directoryPath));
|
|
|
|
foreach (var subdirectory in Directory.GetDirectories(directoryPath))
|
|
{
|
|
result.AddRange(GetAllFilesInDirectory(subdirectory));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Read all json files in database folder and map into a json object
|
|
* @param filepath path to database folder
|
|
*/
|
|
protected async Task HydrateDatabase(string filePath)
|
|
{
|
|
_logger.Info(_localisationService.GetText("importing_database"));
|
|
|
|
var dataToImport = await _importerUtil.LoadRecursiveAsync<DatabaseTables>(
|
|
$"{filePath}database/",
|
|
OnReadValidate
|
|
);
|
|
|
|
// TODO: Fix loading of traders, so their full path is not included as the key
|
|
|
|
var tempTraders = new Dictionary<string, Trader>();
|
|
|
|
// temp fix for trader keys
|
|
foreach (var trader in dataToImport.Traders)
|
|
{
|
|
// fix string for key
|
|
var tempKey = trader.Key.Split("/").Last();
|
|
tempTraders.Add(tempKey, trader.Value);
|
|
}
|
|
|
|
dataToImport.Traders = tempTraders;
|
|
|
|
var validation = valid == ValidationResult.FAILED || valid == ValidationResult.NOT_FOUND ? "." : "";
|
|
_logger.Info($"{_localisationService.GetText("importing_database_finish")}{validation}");
|
|
_databaseServer.SetTables((DatabaseTables)dataToImport);
|
|
}
|
|
|
|
protected void OnReadValidate(string fileWithPath, string data)
|
|
{
|
|
// Validate files
|
|
//if (ProgramStatics.COMPILED && hashedFile && !ValidateFile(fileWithPath, data)) {
|
|
// this.valid = ValidationResult.FAILED;
|
|
//}
|
|
}
|
|
|
|
public string GetRoute()
|
|
{
|
|
return "spt-database";
|
|
}
|
|
|
|
protected bool ValidateFile(string filePathAndName, object fileData)
|
|
{
|
|
/*
|
|
try {
|
|
const finalPath = filePathAndName.replace(this.filepath, "").replace(".json", "");
|
|
let tempObject: any;
|
|
for (const prop of finalPath.split("/")) {
|
|
if (!tempObject) {
|
|
tempObject = this.hashedFile[prop];
|
|
} else {
|
|
tempObject = tempObject[prop];
|
|
}
|
|
}
|
|
|
|
if (tempObject !== this.hashUtil.generateSha1ForData(fileData)) {
|
|
this.logger.debug(this.localisationService.getText("validation_error_file", filePathAndName));
|
|
return false;
|
|
}
|
|
} catch (e) {
|
|
this.logger.warning(this.localisationService.getText("validation_error_exception", filePathAndName));
|
|
this.logger.warning(e);
|
|
return false;
|
|
}
|
|
return true;
|
|
*/
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* absolute dogshit, do not use
|
|
* Find and map files with image router inside a designated path
|
|
* @param filepath Path to find files in
|
|
*/
|
|
[Obsolete]
|
|
public void LoadImages(string filepath, string[] directories, List<string> routes)
|
|
{
|
|
for (var i = 0; i < directories.Length; i++)
|
|
{
|
|
// Get all files in directory
|
|
var filesInDirectory = _fileUtil.GetFiles(directories[i]);
|
|
foreach (var file in filesInDirectory)
|
|
{
|
|
var imagePath = file;
|
|
// Register each file in image router
|
|
var filename = _fileUtil.StripExtension(file);
|
|
var routeKey = $"{routes[i]}{filename}";
|
|
//var imagePath = $"{filepath}{directories[i]}/{file}";
|
|
|
|
var pathOverride = GetImagePathOverride(imagePath);
|
|
if (!string.IsNullOrEmpty(pathOverride)) {
|
|
_logger.Debug($"overrode route: {routeKey} endpoint: {imagePath} with {pathOverride}");
|
|
imagePath = pathOverride;
|
|
}
|
|
|
|
_imageRouter.AddRoute(routeKey, imagePath);
|
|
}
|
|
}
|
|
|
|
// Map icon file separately
|
|
_imageRouter.AddRoute("/favicon.ico", $"{filepath}icon.ico");
|
|
}
|
|
|
|
/**
|
|
* Check for a path override in the http json config file
|
|
* @param imagePath Key
|
|
* @returns override for key
|
|
*/
|
|
protected string? GetImagePathOverride(string imagePath)
|
|
{
|
|
if (httpConfig.ServerImagePathOverride.TryGetValue(imagePath, out var value))
|
|
return value;
|
|
return null;
|
|
}
|
|
}
|
|
|
|
internal enum ValidationResult
|
|
{
|
|
SUCCESS = 0,
|
|
FAILED = 1,
|
|
NOT_FOUND = 2,
|
|
UNDEFINED = 3
|
|
}
|