Use CiByteString for anything path-related.

This commit is contained in:
Ottermandias 2024-07-30 18:53:55 +02:00
parent 9d128a4d83
commit d247f83e1d
42 changed files with 163 additions and 124 deletions

View file

@ -7,6 +7,7 @@ using Penumbra.Api.Enums;
using Penumbra.Interop.Hooks.ResourceLoading;
using Penumbra.Interop.PathResolving;
using Penumbra.Interop.SafeHandles;
using Penumbra.String;
using Penumbra.String.Classes;
using CharacterUtility = Penumbra.Interop.Services.CharacterUtility;
@ -15,7 +16,7 @@ namespace Penumbra.Interop.Hooks.PostProcessing;
public sealed unsafe class PreBoneDeformerReplacer : IDisposable, IRequiredService
{
public static readonly Utf8GamePath PreBoneDeformerPath =
Utf8GamePath.FromSpan("chara/xls/boneDeformer/human.pbd"u8, out var p) ? p : Utf8GamePath.Empty;
Utf8GamePath.FromSpan("chara/xls/boneDeformer/human.pbd"u8, MetaDataComputation.All, out var p) ? p : Utf8GamePath.Empty;
// Approximate name guesses.
private delegate void CharacterBaseSetupScalingDelegate(CharacterBase* drawObject, uint slotIndex);

View file

@ -102,7 +102,7 @@ public unsafe class CreateFileWHook : IDisposable, IRequiredService
{
// Use static storage.
var ptr = WriteFileName(name);
Penumbra.Log.Excessive($"[ResourceHooks] Calling CreateFileWDetour with {ByteString.FromSpanUnsafe(name, false)}.");
Penumbra.Log.Excessive($"[ResourceHooks] Calling CreateFileWDetour with {CiByteString.FromSpanUnsafe(name, false)}.");
return _createFileWHook.OriginalDisposeSafe(ptr, access, shareMode, security, creation, flags, template);
}

View file

@ -41,7 +41,7 @@ public unsafe class ResourceLoader : IDisposable, IService
private int PapResourceHandler(void* self, byte* path, int length)
{
if (!_config.EnableMods || !Utf8GamePath.FromPointer(path, out var gamePath))
if (!_config.EnableMods || !Utf8GamePath.FromPointer(path, MetaDataComputation.CiCrc32, out var gamePath))
return length;
var (resolvedPath, data) = _incMode.Value
@ -64,7 +64,7 @@ public unsafe class ResourceLoader : IDisposable, IService
}
/// <summary> Load a resource for a given path and a specific collection. </summary>
public ResourceHandle* LoadResolvedResource(ResourceCategory category, ResourceType type, ByteString path, ResolveData resolveData)
public ResourceHandle* LoadResolvedResource(ResourceCategory category, ResourceType type, CiByteString path, ResolveData resolveData)
{
_resolvedData = resolveData;
var ret = _resources.GetResource(category, type, path);
@ -73,7 +73,7 @@ public unsafe class ResourceLoader : IDisposable, IService
}
/// <summary> Load a resource for a given path and a specific collection. </summary>
public SafeResourceHandle LoadResolvedSafeResource(ResourceCategory category, ResourceType type, ByteString path, ResolveData resolveData)
public SafeResourceHandle LoadResolvedSafeResource(ResourceCategory category, ResourceType type, CiByteString path, ResolveData resolveData)
{
_resolvedData = resolveData;
var ret = _resources.GetSafeResource(category, type, path);
@ -98,7 +98,7 @@ public unsafe class ResourceLoader : IDisposable, IService
/// </summary>
public event ResourceLoadedDelegate? ResourceLoaded;
public delegate void FileLoadedDelegate(ResourceHandle* resource, ByteString path, bool returnValue, bool custom,
public delegate void FileLoadedDelegate(ResourceHandle* resource, CiByteString path, bool returnValue, bool custom,
ReadOnlySpan<byte> additionalData);
/// <summary>
@ -172,7 +172,8 @@ public unsafe class ResourceLoader : IDisposable, IService
return;
}
var path = ByteString.FromSpanUnsafe(actualPath, gamePath.Path.IsNullTerminated, gamePath.Path.IsAsciiLowerCase, gamePath.Path.IsAscii);
var path = CiByteString.FromSpanUnsafe(actualPath, gamePath.Path.IsNullTerminated, gamePath.Path.IsAsciiLowerCase,
gamePath.Path.IsAscii);
fileDescriptor->ResourceHandle->FileNameData = path.Path;
fileDescriptor->ResourceHandle->FileNameLength = path.Length;
MtrlForceSync(fileDescriptor, ref isSync);
@ -184,7 +185,7 @@ public unsafe class ResourceLoader : IDisposable, IService
/// <summary> Load a resource by its path. If it is rooted, it will be loaded from the drive, otherwise from the SqPack. </summary>
private byte DefaultLoadResource(ByteString gamePath, SeFileDescriptor* fileDescriptor, int priority,
private byte DefaultLoadResource(CiByteString gamePath, SeFileDescriptor* fileDescriptor, int priority,
bool isSync, ReadOnlySpan<byte> additionalData)
{
if (Utf8GamePath.IsRooted(gamePath))
@ -265,7 +266,7 @@ public unsafe class ResourceLoader : IDisposable, IService
}
/// <summary> Compute the CRC32 hash for a given path together with potential resource parameters. </summary>
private static int ComputeHash(ByteString path, GetResourceParameters* pGetResParams)
private static int ComputeHash(CiByteString path, GetResourceParameters* pGetResParams)
{
if (pGetResParams == null || !pGetResParams->IsPartialRead)
return path.Crc32;
@ -273,11 +274,11 @@ public unsafe class ResourceLoader : IDisposable, IService
// When the game requests file only partially, crc32 includes that information, in format of:
// path/to/file.ext.hex_offset.hex_size
// ex) music/ex4/BGM_EX4_System_Title.scd.381adc.30000
return ByteString.Join(
return CiByteString.Join(
(byte)'.',
path,
ByteString.FromStringUnsafe(pGetResParams->SegmentOffset.ToString("x"), true),
ByteString.FromStringUnsafe(pGetResParams->SegmentLength.ToString("x"), true)
CiByteString.FromString(pGetResParams->SegmentOffset.ToString("x"), out var s1, MetaDataComputation.None) ? s1 : CiByteString.Empty,
CiByteString.FromString(pGetResParams->SegmentLength.ToString("x"), out var s2, MetaDataComputation.None) ? s2 : CiByteString.Empty
).Crc32;
}

View file

@ -39,14 +39,14 @@ public unsafe class ResourceService : IDisposable, IRequiredService
}
}
public ResourceHandle* GetResource(ResourceCategory category, ResourceType type, ByteString path)
public ResourceHandle* GetResource(ResourceCategory category, ResourceType type, CiByteString path)
{
var hash = path.Crc32;
return GetResourceHandler(true, (ResourceManager*)_resourceManager.ResourceManagerAddress,
&category, &type, &hash, path.Path, null, false);
}
public SafeResourceHandle GetSafeResource(ResourceCategory category, ResourceType type, ByteString path)
public SafeResourceHandle GetSafeResource(ResourceCategory category, ResourceType type, CiByteString path)
=> new((CSResourceHandle*)GetResource(category, type, path), false);
public void Dispose()
@ -102,7 +102,7 @@ public unsafe class ResourceService : IDisposable, IRequiredService
ResourceType* resourceType, int* resourceHash, byte* path, GetResourceParameters* pGetResParams, bool isUnk)
{
using var performance = _performance.Measure(PerformanceType.GetResourceHandler);
if (!Utf8GamePath.FromPointer(path, out var gamePath))
if (!Utf8GamePath.FromPointer(path, MetaDataComputation.CiCrc32, out var gamePath))
{
Penumbra.Log.Error("[ResourceService] Could not create GamePath from resource path.");
return isSync
@ -120,7 +120,7 @@ public unsafe class ResourceService : IDisposable, IRequiredService
}
/// <summary> Call the original GetResource function. </summary>
public ResourceHandle* GetOriginalResource(bool sync, ResourceCategory categoryId, ResourceType type, int hash, ByteString path,
public ResourceHandle* GetOriginalResource(bool sync, ResourceCategory categoryId, ResourceType type, int hash, CiByteString path,
GetResourceParameters* resourceParameters = null, bool unk = false)
=> sync
? _getResourceSyncHook.OriginalDisposeSafe(_resourceManager.ResourceManager, &categoryId, &type, &hash, path.Path,