mirror of
https://github.com/kwsch/NHSE.git
synced 2026-03-29 13:04:39 -05:00
90 lines
3.4 KiB
C#
90 lines
3.4 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Resources;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using static System.Buffers.Binary.BinaryPrimitives;
|
|
|
|
namespace NHSE.Core;
|
|
|
|
/// <summary>
|
|
/// Logic for retrieving resources from the dll
|
|
/// </summary>
|
|
public static class ResourceUtil
|
|
{
|
|
private static readonly Assembly thisAssembly = typeof(ResourceUtil).GetTypeInfo().Assembly;
|
|
private static readonly string[] manifestResourceNames = thisAssembly.GetManifestResourceNames();
|
|
private static readonly Dictionary<string, string> resourceNameMap = new();
|
|
private static readonly Dictionary<string, string[]> stringListCache = new();
|
|
private static readonly Lock getStringListLoadLock = new();
|
|
|
|
public static string[] GetStringList(string fileName)
|
|
{
|
|
if (IsStringListCached(fileName, out var result))
|
|
return result;
|
|
var txt = GetStringResource(fileName); // Fetch File, \n to list.
|
|
return LoadStringList(fileName, txt);
|
|
}
|
|
|
|
public static bool IsStringListCached(string fileName, [NotNullWhen(true)] out string[]? result)
|
|
{
|
|
lock (getStringListLoadLock) // Make sure only one thread can read the cache
|
|
return stringListCache.TryGetValue(fileName, out result);
|
|
}
|
|
|
|
public static string[] LoadStringList(string file, string? txt)
|
|
{
|
|
if (txt == null)
|
|
return [];
|
|
string[] rawlist = txt.TrimEnd('\r', '\n').Split('\n');
|
|
for (int i = 0; i < rawlist.Length; i++)
|
|
rawlist[i] = rawlist[i].TrimEnd('\r');
|
|
|
|
lock (getStringListLoadLock) // Make sure only one thread can write to the cache
|
|
stringListCache.TryAdd(file, rawlist); // Check cache again in case of race condition
|
|
|
|
return (string[])rawlist.Clone();
|
|
}
|
|
|
|
public static string[] GetStringList(string fileName, string lang2char, string type = "text") => GetStringList($"{type}_{fileName}_{lang2char}");
|
|
|
|
public static byte[] GetBinaryResource(string name)
|
|
{
|
|
using var resource = thisAssembly.GetManifestResourceStream($"NHSE.Core.Resources.byte.{name}")
|
|
?? throw new MissingManifestResourceException($"Resource not found: {name}");
|
|
var buffer = new byte[resource.Length];
|
|
_ = resource.Read(buffer, 0, (int)resource.Length);
|
|
return buffer;
|
|
}
|
|
|
|
public static ushort[] GetBinaryResourceAsUshort(string name)
|
|
{
|
|
ReadOnlySpan<byte> byteBuffer = GetBinaryResource(name);
|
|
var result = MemoryMarshal.Cast<byte, ushort>(byteBuffer).ToArray();
|
|
if (!BitConverter.IsLittleEndian)
|
|
ReverseEndianness(result, result);
|
|
return result;
|
|
|
|
}
|
|
|
|
public static string? GetStringResource(string name)
|
|
{
|
|
if (!resourceNameMap.TryGetValue(name, out var resname))
|
|
{
|
|
bool Match(string x) => x.StartsWith("NHSE.Core.Resources.text.") && x.EndsWith($"{name}.txt", StringComparison.OrdinalIgnoreCase);
|
|
resname = Array.Find(manifestResourceNames, Match);
|
|
if (resname == null)
|
|
return null;
|
|
resourceNameMap.Add(name, resname);
|
|
}
|
|
|
|
using var resource = thisAssembly.GetManifestResourceStream(resname);
|
|
if (resource == null)
|
|
return null;
|
|
using var reader = new StreamReader(resource);
|
|
return reader.ReadToEnd();
|
|
}
|
|
} |