LazyLoad some assets
This commit is contained in:
@@ -171,8 +171,8 @@ public class DataCallbacks(
|
||||
{
|
||||
var localeId = url.Replace("/client/locale/", "");
|
||||
var locales = _databaseService.GetLocales();
|
||||
var result = locales.Global?[localeId]
|
||||
?? locales.Global?.FirstOrDefault(m => m.Key == "en").Value;
|
||||
var result = locales.Global?[localeId].Value
|
||||
?? locales.Global?.FirstOrDefault(m => m.Key == "en").Value.Value;
|
||||
|
||||
return _httpResponseUtil.GetUnclearedBody(result);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using Core.Models.Eft.Common.Tables;
|
||||
using Core.Utils.Json;
|
||||
|
||||
namespace Core.Models.Eft.Common;
|
||||
|
||||
@@ -11,15 +12,15 @@ public record Location
|
||||
|
||||
/** Loose loot positions and item weights */
|
||||
[JsonPropertyName("looseLoot")]
|
||||
public LooseLoot? LooseLoot { get; set; }
|
||||
public LazyLoad<LooseLoot>? LooseLoot { get; set; }
|
||||
|
||||
/** Static loot item weights */
|
||||
[JsonPropertyName("staticLoot")]
|
||||
public Dictionary<string, StaticLootDetails>? StaticLoot { get; set; }
|
||||
public LazyLoad<Dictionary<string, StaticLootDetails>>? StaticLoot { get; set; }
|
||||
|
||||
/** Static container positions and item weights */
|
||||
[JsonPropertyName("staticContainers")]
|
||||
public StaticContainerDetails? StaticContainers { get; set; }
|
||||
public LazyLoad<StaticContainerDetails>? StaticContainers { get; set; }
|
||||
|
||||
[JsonPropertyName("staticAmmo")]
|
||||
public Dictionary<string, List<StaticAmmoDetails>> StaticAmmo { get; set; }
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using Core.Utils.Json;
|
||||
|
||||
namespace Core.Models.Spt.Server;
|
||||
|
||||
public record LocaleBase
|
||||
{
|
||||
[JsonPropertyName("global")]
|
||||
public Dictionary<string, Dictionary<string, string>>? Global { get; set; }
|
||||
public Dictionary<string, LazyLoad<Dictionary<string, string>>>? Global { get; set; }
|
||||
|
||||
[JsonPropertyName("menu")]
|
||||
public Dictionary<string, Dictionary<string, object>>? Menu { get; set; }
|
||||
|
||||
[JsonPropertyName("languages")]
|
||||
public Dictionary<string, string>? Languages { get; set; }
|
||||
|
||||
[JsonPropertyName("server")]
|
||||
public Dictionary<string, Dictionary<string, string>>? Server { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Core.Utils;
|
||||
using Core.Utils.Json;
|
||||
using SptCommon.Extensions;
|
||||
|
||||
namespace Core.Services;
|
||||
@@ -13,7 +14,7 @@ public class I18nService
|
||||
private FileUtil _fileUtil;
|
||||
private string _setLocale;
|
||||
|
||||
private Dictionary<string, Dictionary<string, string>> _loadedLocales = new();
|
||||
private Dictionary<string, LazyLoad<Dictionary<string, string>>> _loadedLocales = new();
|
||||
// TODO: try convert to primary ctor
|
||||
public I18nService(
|
||||
FileUtil fileUtil,
|
||||
@@ -41,8 +42,10 @@ public class I18nService
|
||||
throw new Exception($"Localisation files in directory {_directory} not found.");
|
||||
foreach (var file in files)
|
||||
_loadedLocales.Add(_fileUtil.StripExtension(file),
|
||||
_jsonUtil.Deserialize<Dictionary<string, string>>(_fileUtil.ReadFile(file)) ??
|
||||
new Dictionary<string, string>());
|
||||
new LazyLoad<Dictionary<string, string>>(
|
||||
() => _jsonUtil.Deserialize<Dictionary<string, string>>(_fileUtil.ReadFile(file)) ??
|
||||
new Dictionary<string, string>()
|
||||
));
|
||||
|
||||
if (!_loadedLocales.ContainsKey(_defaultLocale))
|
||||
throw new Exception($"The default locale '{_defaultLocale}' does not exist on the loaded locales.");
|
||||
@@ -74,10 +77,10 @@ public class I18nService
|
||||
{
|
||||
if (!_loadedLocales.TryGetValue(_setLocale, out var locales))
|
||||
return key;
|
||||
if (!locales.TryGetValue(key, out var value))
|
||||
if (!locales.Value.TryGetValue(key, out var value))
|
||||
{
|
||||
_loadedLocales.TryGetValue(_defaultLocale, out var defaults);
|
||||
defaults.TryGetValue(key, out value);
|
||||
defaults.Value.TryGetValue(key, out value);
|
||||
return value ?? key;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,13 +25,13 @@ public class LocaleService(
|
||||
public Dictionary<string, string> GetLocaleDb()
|
||||
{
|
||||
var desiredLocale = _databaseServer.GetTables().Locales.Global[GetDesiredGameLocale()];
|
||||
if (desiredLocale != null) return desiredLocale;
|
||||
if (desiredLocale != null) return desiredLocale.Value;
|
||||
|
||||
_logger.Warning(
|
||||
$"Unable to find desired locale file using locale: {GetDesiredGameLocale()} from config/locale.json, falling back to 'en'"
|
||||
);
|
||||
|
||||
return _databaseServer.GetTables().Locales.Global["en"];
|
||||
return _databaseServer.GetTables().Locales.Global["en"].Value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -330,7 +330,7 @@ public class LocationLifecycleService
|
||||
locationBaseClone.Loot.AddRange(staticLoot);
|
||||
|
||||
// Add dynamic loot to output loot
|
||||
var dynamicLootDistClone = _cloner.Clone(location.LooseLoot);
|
||||
var dynamicLootDistClone = _cloner.Clone(location.LooseLoot.Value);
|
||||
var dynamicSpawnPoints = _locationLootGenerator.GenerateDynamicLoot(
|
||||
dynamicLootDistClone,
|
||||
staticAmmoDist,
|
||||
|
||||
@@ -763,8 +763,8 @@ public class SeasonalEventService(
|
||||
protected void RenameBitcoin()
|
||||
{
|
||||
var enLocale = _databaseService.GetLocales().Global["en"];
|
||||
enLocale[$"{ItemTpl.BARTER_PHYSICAL_BITCOIN} Name"] = "Physical SPT Coin";
|
||||
enLocale[$"{ItemTpl.BARTER_PHYSICAL_BITCOIN} ShortName"] = "0.2SPT";
|
||||
enLocale.Value[$"{ItemTpl.BARTER_PHYSICAL_BITCOIN} Name"] = "Physical SPT Coin";
|
||||
enLocale.Value[$"{ItemTpl.BARTER_PHYSICAL_BITCOIN} ShortName"] = "0.2SPT";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
using SptCommon.Annotations;
|
||||
using Core.Models.Utils;
|
||||
using Core.Utils.Json;
|
||||
|
||||
namespace Core.Utils;
|
||||
|
||||
@@ -12,6 +14,7 @@ public class ImporterUtil
|
||||
protected ISptLogger<ImporterUtil> _logger;
|
||||
|
||||
protected HashSet<string> filesToIgnore = ["bearsuits.json", "usecsuits.json", "archivedquests.json"];
|
||||
protected HashSet<string> directoriesToIgnore = ["./Assets/database/locales/server"];
|
||||
|
||||
public ImporterUtil(ISptLogger<ImporterUtil> logger, FileUtil fileUtil, JsonUtil jsonUtil)
|
||||
{
|
||||
@@ -26,7 +29,8 @@ public class ImporterUtil
|
||||
Action<string, object>? onObjectDeserialized = null
|
||||
)
|
||||
{
|
||||
return LoadRecursiveAsync(filepath, typeof(T), onReadCallback, onObjectDeserialized).ContinueWith(res => (T) res.Result);
|
||||
return LoadRecursiveAsync(filepath, typeof(T), onReadCallback, onObjectDeserialized)
|
||||
.ContinueWith(res => (T)res.Result);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +74,40 @@ public class ImporterUtil
|
||||
);
|
||||
try
|
||||
{
|
||||
var fileDeserialized = _jsonUtil.Deserialize(fileData, propertyType);
|
||||
object fileDeserialized = null;
|
||||
if (propertyType.IsGenericType &&
|
||||
propertyType.GetGenericTypeDefinition() == typeof(LazyLoad<>))
|
||||
{
|
||||
// This expression is create a generic type delegate for lazy loading a LazyLoad type
|
||||
var expression = Expression.Lambda(
|
||||
// this is the expected type of the lambda which is a function of whatever generic type LazyLoad<> is
|
||||
typeof(Func<>).MakeGenericType(propertyType.GetGenericArguments()),
|
||||
// An expression block will have a return type and then will execute the expression
|
||||
Expression.Block(
|
||||
// this is the return type
|
||||
propertyType.GetGenericArguments()[0],
|
||||
// this is the expression
|
||||
// This expression casts the result of the Call expression as the generic argument type
|
||||
Expression.TypeAs(
|
||||
// this expression calls the json util Deserialize method
|
||||
Expression.Call(
|
||||
Expression.Constant(_jsonUtil),
|
||||
"Deserialize",
|
||||
[],
|
||||
[Expression.Constant(fileData), Expression.Constant(propertyType.GetGenericArguments()[0])]
|
||||
),
|
||||
propertyType.GetGenericArguments()[0]
|
||||
)
|
||||
)
|
||||
)
|
||||
.Compile();
|
||||
fileDeserialized = Activator.CreateInstance(propertyType, expression);
|
||||
}
|
||||
else
|
||||
{
|
||||
fileDeserialized = _jsonUtil.Deserialize(fileData, propertyType);
|
||||
}
|
||||
|
||||
if (onObjectDeserialized != null)
|
||||
onObjectDeserialized(file, fileDeserialized);
|
||||
|
||||
@@ -96,6 +133,7 @@ public class ImporterUtil
|
||||
// deep tree search
|
||||
foreach (var directory in directories)
|
||||
{
|
||||
if (directoriesToIgnore.Contains(directory)) continue;
|
||||
tasks.Add(
|
||||
Task.Factory.StartNew(
|
||||
() =>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace Core.Utils.Json;
|
||||
|
||||
public class LazyLoad<T>(Func<T> deserialize)
|
||||
{
|
||||
private T? _result;
|
||||
private bool _isLoaded;
|
||||
|
||||
private Timer? autoCleanerTimeout;
|
||||
private static readonly TimeSpan _autoCleanerTimeout = TimeSpan.FromSeconds(30);
|
||||
|
||||
public T? Value
|
||||
{
|
||||
get
|
||||
{
|
||||
if (!_isLoaded)
|
||||
{
|
||||
_result = deserialize();
|
||||
_isLoaded = true;
|
||||
autoCleanerTimeout = new Timer(_ =>
|
||||
{
|
||||
_result = default;
|
||||
_isLoaded = false;
|
||||
autoCleanerTimeout?.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
|
||||
autoCleanerTimeout = null;
|
||||
},null, _autoCleanerTimeout, Timeout.InfiniteTimeSpan
|
||||
);
|
||||
}
|
||||
|
||||
autoCleanerTimeout?.Change(_autoCleanerTimeout, Timeout.InfiniteTimeSpan);
|
||||
return _result;
|
||||
}
|
||||
set => _result = value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user