Extract Strings to separate submodule.

This commit is contained in:
Ottermandias 2022-10-29 15:53:45 +02:00
parent bc901f3ff6
commit 35baba18bf
75 changed files with 751 additions and 1657 deletions

View file

@ -3,7 +3,6 @@ using Dalamud.Plugin;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.ByteString;
using Penumbra.Mods;
using System;
using System.Collections.Generic;
@ -12,6 +11,8 @@ using System.Linq;
using System.Numerics;
using Penumbra.Api.Enums;
using Penumbra.Api.Helpers;
using Penumbra.String;
using Penumbra.String.Classes;
namespace Penumbra.Api;
@ -536,7 +537,7 @@ public class IpcTester : IDisposable
private unsafe void UpdateLastCreated( IntPtr gameObject, string _, IntPtr _2, IntPtr _3, IntPtr _4 )
{
var obj = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )gameObject;
_lastCreatedGameObjectName = new Utf8String( obj->GetName() ).ToString();
_lastCreatedGameObjectName = new ByteString( obj->GetName() ).ToString();
_lastCreatedGameObjectTime = DateTimeOffset.Now;
_lastCreatedDrawObject = IntPtr.Zero;
}
@ -544,7 +545,7 @@ public class IpcTester : IDisposable
private unsafe void UpdateLastCreated2( IntPtr gameObject, string _, IntPtr drawObject )
{
var obj = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )gameObject;
_lastCreatedGameObjectName = new Utf8String( obj->GetName() ).ToString();
_lastCreatedGameObjectName = new ByteString( obj->GetName() ).ToString();
_lastCreatedGameObjectTime = DateTimeOffset.Now;
_lastCreatedDrawObject = drawObject;
}
@ -552,7 +553,7 @@ public class IpcTester : IDisposable
private unsafe void UpdateGameObjectResourcePath( IntPtr gameObject, string gamePath, string fullPath )
{
var obj = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )gameObject;
_lastResolvedObject = obj != null ? new Utf8String( obj->GetName() ).ToString() : "Unknown";
_lastResolvedObject = obj != null ? new ByteString( obj->GetName() ).ToString() : "Unknown";
_lastResolvedGamePath = gamePath;
_lastResolvedFullPath = fullPath;
_lastResolvedGamePathTime = DateTimeOffset.Now;

View file

@ -3,7 +3,6 @@ using Lumina.Data;
using Newtonsoft.Json;
using OtterGui;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Manipulations;
@ -15,6 +14,7 @@ using System.IO;
using System.Linq;
using System.Reflection;
using Penumbra.Api.Enums;
using Penumbra.String.Classes;
namespace Penumbra.Api;

View file

@ -1,11 +1,11 @@
using OtterGui;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.Meta.Manipulations;
using Penumbra.Mods;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using Penumbra.String.Classes;
namespace Penumbra.Api;

View file

@ -143,8 +143,8 @@ public partial class ModCollection
return false;
}
_specialCollections[ ( int )collectionType ] = Empty;
CollectionChanged.Invoke( collectionType, null, Empty, null );
_specialCollections[ ( int )collectionType ] = Default;
CollectionChanged.Invoke( collectionType, null, Default, null );
return true;
}
@ -172,8 +172,8 @@ public partial class ModCollection
return false;
}
_characters[ characterName ] = Empty;
CollectionChanged.Invoke( CollectionType.Character, null, Empty, characterName );
_characters[ characterName ] = Default;
CollectionChanged.Invoke( CollectionType.Character, null, Default, characterName );
return true;
}

View file

@ -1,5 +1,4 @@
using OtterGui.Classes;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Meta.Manager;
using Penumbra.Mods;
@ -8,8 +7,8 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
using Penumbra.Interop;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Classes;
namespace Penumbra.Collections;

View file

@ -1,6 +1,5 @@
using OtterGui;
using OtterGui.Classes;
using Penumbra.GameData.ByteString;
using Penumbra.Meta.Manager;
using Penumbra.Meta.Manipulations;
using Penumbra.Mods;
@ -8,6 +7,8 @@ using System;
using System.Collections.Generic;
using System.Linq;
using Penumbra.Api.Enums;
using Penumbra.GameData.Util;
using Penumbra.String.Classes;
namespace Penumbra.Collections;
@ -240,7 +241,7 @@ public partial class ModCollection
if( addMetaChanges )
{
++_collection.ChangeCounter;
if( _collection == Penumbra.CollectionManager.Default && Penumbra.CharacterUtility.Ready && Penumbra.Config.EnableMods )
if( _collection == Penumbra.CollectionManager.Default && Penumbra.CharacterUtility.Ready && Penumbra.Config.EnableMods )
{
Penumbra.ResidentResources.Reload();
MetaManipulations.SetFiles();
@ -413,7 +414,7 @@ public partial class ModCollection
// Add the same conflict list to both conflict directions.
var conflictList = new List< object > { data };
_conflicts[ addedMod ] = addedConflicts.Append( new ModConflicts( existingMod, conflictList, existingPriority < addedPriority,
existingPriority != addedPriority ) );
existingPriority != addedPriority ) );
_conflicts[ existingMod ] = existingConflicts.Append( new ModConflicts( addedMod, conflictList,
existingPriority >= addedPriority,
existingPriority != addedPriority ) );
@ -474,9 +475,9 @@ public partial class ModCollection
// Skip IMCs because they would result in far too many false-positive items,
// since they are per set instead of per item-slot/item/variant.
var identifier = GameData.GameData.GetIdentifier();
foreach( var (resolved, modPath) in ResolvedFiles.Where( file => !file.Key.Path.EndsWith( 'i', 'm', 'c' ) ) )
foreach( var (resolved, modPath) in ResolvedFiles.Where( file => !file.Key.Path.EndsWith( "imc"u8 ) ) )
{
foreach( var (name, obj) in identifier.Identify( resolved.ToGamePath() ) )
foreach( var (name, obj) in identifier.Identify( new GamePath( resolved.ToString() ) ) )
{
if( !_changedItems.TryGetValue( name, out var data ) )
{

View file

@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using Dalamud.Interface;
using Dalamud.Interface.ImGuiFileDialog;
@ -11,7 +10,7 @@ using Lumina.Data.Files;
using OtterGui;
using OtterGui.Raii;
using OtterTex;
using Penumbra.GameData.ByteString;
using Penumbra.String.Classes;
using Penumbra.UI.Classes;
using SixLabors.ImageSharp.PixelFormats;
using Image = SixLabors.ImageSharp.Image;

View file

@ -1,8 +1,8 @@
using System;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.String.Classes;
namespace Penumbra.Interop;

View file

@ -7,8 +7,9 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using FFXIVClientStructs.STD;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.String;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Loader;
@ -19,7 +20,7 @@ public unsafe partial class ResourceLoader
private readonly Hook< ResourceHandleDecRef > _decRefHook;
public delegate IntPtr ResourceHandleDestructor( ResourceHandle* handle );
[Signature( "48 89 5C 24 ?? 57 48 83 EC ?? 48 8D 05 ?? ?? ?? ?? 48 8B D9 48 89 01 B8",
DetourName = nameof( ResourceHandleDestructorDetour ) )]
public static Hook< ResourceHandleDestructor >? ResourceHandleDestructorHook;
@ -28,7 +29,7 @@ public unsafe partial class ResourceLoader
{
if( handle != null )
{
Penumbra.Log.Information( $"[ResourceLoader] Destructing Resource Handle {handle->FileName} at 0x{( ulong )handle:X} (Refcount {handle->RefCount}).");
Penumbra.Log.Information( $"[ResourceLoader] Destructing Resource Handle {handle->FileName} at 0x{( ulong )handle:X} (Refcount {handle->RefCount})." );
}
return ResourceHandleDestructorHook!.Original( handle );
@ -248,7 +249,7 @@ public unsafe partial class ResourceLoader
Penumbra.Log.Information( $"[ResourceLoader] Loaded {pathString} to 0x{( ulong )handle:X}. (Refcount {handle->RefCount})" );
}
private static void LogLoadedFile( Utf8String path, bool success, bool custom )
private static void LogLoadedFile( ByteString path, bool success, bool custom )
=> Penumbra.Log.Information( success
? $"[ResourceLoader] Loaded {path} from {( custom ? "local files" : "SqPack" )}"
: $"[ResourceLoader] Failed to load {path} from {( custom ? "local files" : "SqPack" )}." );

View file

@ -7,9 +7,10 @@ using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.String.Classes;
using FileMode = Penumbra.Interop.Structs.FileMode;
using ResourceHandle = FFXIVClientStructs.FFXIV.Client.System.Resource.Handle.ResourceHandle;
@ -71,7 +72,7 @@ public unsafe partial class ResourceLoader
private event Action< Utf8GamePath, ResourceType, FullPath?, object? >? PathResolved;
public ResourceHandle* ResolvePathSync( ResourceCategory category, ResourceType type, Utf8String path )
public ResourceHandle* ResolvePathSync( ResourceCategory category, ResourceType type, ByteString path )
{
var hash = path.Crc32;
return GetResourceHandler( true, *ResourceManager, &category, &type, &hash, path.Path, null, false );
@ -209,7 +210,7 @@ public unsafe partial class ResourceLoader
}
// Load the resource from an SqPack and trigger the FileLoaded event.
private byte DefaultResourceLoad( Utf8String path, ResourceManager* resourceManager,
private byte DefaultResourceLoad( ByteString path, ResourceManager* resourceManager,
SeFileDescriptor* fileDescriptor, int priority, bool isSync )
{
var ret = Penumbra.ResourceLoader.ReadSqPackHook.Original( resourceManager, fileDescriptor, priority, isSync );
@ -218,7 +219,7 @@ public unsafe partial class ResourceLoader
}
// Load the resource from a path on the users hard drives.
private byte DefaultRootedResourceLoad( Utf8String gamePath, ResourceManager* resourceManager,
private byte DefaultRootedResourceLoad( ByteString gamePath, ResourceManager* resourceManager,
SeFileDescriptor* fileDescriptor, int priority, bool isSync )
{
// Specify that we are loading unpacked files from the drive.
@ -246,7 +247,7 @@ public unsafe partial class ResourceLoader
}
// Load a resource by its path. If it is rooted, it will be loaded from the drive, otherwise from the SqPack.
internal byte DefaultLoadResource( Utf8String gamePath, ResourceManager* resourceManager, SeFileDescriptor* fileDescriptor, int priority,
internal byte DefaultLoadResource( ByteString gamePath, ResourceManager* resourceManager, SeFileDescriptor* fileDescriptor, int priority,
bool isSync )
=> Utf8GamePath.IsRooted( gamePath )
? DefaultRootedResourceLoad( gamePath, resourceManager, fileDescriptor, priority, isSync )
@ -262,7 +263,7 @@ public unsafe partial class ResourceLoader
_incRefHook.Dispose();
}
private static int ComputeHash( Utf8String path, GetResourceParameters* pGetResParams )
private static int ComputeHash( ByteString path, GetResourceParameters* pGetResParams )
{
if( pGetResParams == null || !pGetResParams->IsPartialRead )
{
@ -272,11 +273,11 @@ public unsafe partial class ResourceLoader
// 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 Utf8String.Join(
return ByteString.Join(
( byte )'.',
path,
Utf8String.FromStringUnsafe( pGetResParams->SegmentOffset.ToString( "x" ), true ),
Utf8String.FromStringUnsafe( pGetResParams->SegmentLength.ToString( "x" ), true )
ByteString.FromStringUnsafe( pGetResParams->SegmentOffset.ToString( "x" ), true ),
ByteString.FromStringUnsafe( pGetResParams->SegmentLength.ToString( "x" ), true )
).Crc32;
}

View file

@ -3,8 +3,8 @@ using System.Collections.Generic;
using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Loader;
@ -26,7 +26,7 @@ public unsafe partial class ResourceLoader
// We use it to check against our stored CRC64s and if it corresponds, we return the custom flag.
public delegate IntPtr CheckFileStatePrototype( IntPtr unk1, ulong crc64 );
[Signature( "E8 ?? ?? ?? ?? 48 85 c0 74 ?? 45 0f b6 ce 48 89 44 24", DetourName = nameof(CheckFileStateDetour) )]
[Signature( "E8 ?? ?? ?? ?? 48 85 c0 74 ?? 45 0f b6 ce 48 89 44 24", DetourName = nameof( CheckFileStateDetour ) )]
public Hook< CheckFileStatePrototype > CheckFileStateHook = null!;
private IntPtr CheckFileStateDetour( IntPtr ptr, ulong crc64 )
@ -48,7 +48,7 @@ public unsafe partial class ResourceLoader
// We hook the extern functions to just return the local one if given the custom flag as last argument.
public delegate byte LoadTexFileExternPrototype( ResourceHandle* handle, int unk1, IntPtr unk2, bool unk3, IntPtr unk4 );
[Signature( "E8 ?? ?? ?? ?? 0F B6 E8 48 8B CB E8", DetourName = nameof(LoadTexFileExternDetour) )]
[Signature( "E8 ?? ?? ?? ?? 0F B6 E8 48 8B CB E8", DetourName = nameof( LoadTexFileExternDetour ) )]
public Hook< LoadTexFileExternPrototype > LoadTexFileExternHook = null!;
private byte LoadTexFileExternDetour( ResourceHandle* resourceHandle, int unk1, IntPtr unk2, bool unk3, IntPtr ptr )
@ -59,7 +59,7 @@ public unsafe partial class ResourceLoader
public delegate byte LoadMdlFileExternPrototype( ResourceHandle* handle, IntPtr unk1, bool unk2, IntPtr unk3 );
[Signature( "E8 ?? ?? ?? ?? EB 02 B0 F1", DetourName = nameof(LoadMdlFileExternDetour) )]
[Signature( "E8 ?? ?? ?? ?? EB 02 B0 F1", DetourName = nameof( LoadMdlFileExternDetour ) )]
public Hook< LoadMdlFileExternPrototype > LoadMdlFileExternHook = null!;
private byte LoadMdlFileExternDetour( ResourceHandle* resourceHandle, IntPtr unk1, bool unk2, IntPtr ptr )

View file

@ -3,9 +3,10 @@ using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Loader;
@ -127,7 +128,7 @@ public unsafe partial class ResourceLoader : IDisposable
// Event fired whenever a resource is newly loaded.
// Success indicates the return value of the loading function (which does not imply that the resource was actually successfully loaded)
// custom is true if the file was loaded from local files instead of the default SqPacks.
public delegate void FileLoadedDelegate( Utf8String path, bool success, bool custom );
public delegate void FileLoadedDelegate( ByteString path, bool success, bool custom );
public event FileLoadedDelegate? FileLoaded;
// Customization point to control how path resolving is handled.
@ -140,7 +141,7 @@ public unsafe partial class ResourceLoader : IDisposable
// Customize file loading for any GamePaths that start with "|".
// Same procedure as above.
public delegate bool ResourceLoadCustomizationDelegate( Utf8String split, Utf8String path, ResourceManager* resourceManager,
public delegate bool ResourceLoadCustomizationDelegate( ByteString split, ByteString path, ResourceManager* resourceManager,
SeFileDescriptor* fileDescriptor, int priority, bool isSync, out byte retValue );
public event ResourceLoadCustomizationDelegate? ResourceLoadCustomization;

View file

@ -1,6 +1,7 @@
using System;
using System.Text.RegularExpressions;
using Penumbra.GameData.ByteString;
using Penumbra.String;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Loader;
@ -84,7 +85,7 @@ public class ResourceLogger : IDisposable
// Returns the converted string if the filter matches, and null otherwise.
// The filter matches if it is empty, if it is a valid and matching regex or if the given string contains it.
private string? Match( Utf8String data )
private string? Match( ByteString data )
{
var s = data.ToString();
return Filter.Length == 0 || ( _filterRegex?.IsMatch( s ) ?? s.Contains( Filter, StringComparison.OrdinalIgnoreCase ) )

View file

@ -2,8 +2,8 @@ using System;
using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.String.Classes;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
namespace Penumbra.Interop.Resolver;

View file

@ -8,8 +8,8 @@ using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Penumbra.Api;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using OtterGui.Classes;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Resolver;
@ -57,7 +57,7 @@ public unsafe partial class PathResolver
{
if( type == ResourceType.Tex
&& LastCreatedCollection.Valid
&& gamePath.Path.Substring( "chara/common/texture/".Length ).StartsWith( 'd', 'e', 'c', 'a', 'l' ) )
&& gamePath.Path.Substring( "chara/common/texture/".Length ).StartsWith( "decal"u8 ) )
{
resolveData = LastCreatedCollection;
return true;

View file

@ -7,8 +7,8 @@ using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
using Lumina.Excel.GeneratedSheets;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.String;
using CustomizeData = Penumbra.GameData.Structs.CustomizeData;
using ObjectKind = Dalamud.Game.ClientState.Objects.Enums.ObjectKind;
@ -66,7 +66,7 @@ public unsafe partial class PathResolver
}
var block = data + 0x7A;
return new Utf8String( block ).ToString();
return new ByteString( block ).ToString();
}
// Obtain the name of the player character if the glamour plate edit window is open.
@ -130,7 +130,7 @@ public unsafe partial class PathResolver
if( owner != null )
{
return new Utf8String( owner->Name ).ToString();
return new ByteString( owner->Name ).ToString();
}
return null;
@ -169,7 +169,7 @@ public unsafe partial class PathResolver
if( Penumbra.Config.PreferNamedCollectionsOverOwners )
{
// Early return if we prefer the actors own name over its owner.
actorName = new Utf8String( gameObject->Name ).ToString();
actorName = new ByteString( gameObject->Name ).ToString();
if( actorName.Length > 0
&& CollectionByActorName( actorName, out var actorCollection ) )
{
@ -189,7 +189,7 @@ public unsafe partial class PathResolver
>= CutsceneCharacters.CutsceneStartIdx and < CutsceneCharacters.CutsceneEndIdx => GetCutsceneName( gameObject ),
_ => null,
}
?? GetOwnerName( gameObject ) ?? actorName ?? new Utf8String( gameObject->Name ).ToString();
?? GetOwnerName( gameObject ) ?? actorName ?? new ByteString( gameObject->Name ).ToString();
// First check temporary character collections, then the own configuration, then special collections.
var collection = CollectionByActorName( actualName, out var c )

View file

@ -4,9 +4,10 @@ using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Resolver;
@ -78,7 +79,7 @@ public unsafe partial class PathResolver
// We need to set the correct collection for the actual material path that is loaded
// before actually loading the file.
public bool MtrlLoadHandler( Utf8String split, Utf8String path, ResourceManager* resourceManager,
public bool MtrlLoadHandler( ByteString split, ByteString path, ResourceManager* resourceManager,
SeFileDescriptor* fileDescriptor, int priority, bool isSync, out byte ret )
{
ret = 0;
@ -149,7 +150,7 @@ public unsafe partial class PathResolver
}
var mtrl = ( MtrlResource* )mtrlResourceHandle;
var mtrlPath = Utf8String.FromSpanUnsafe( mtrl->Handle.FileNameSpan(), true, null, true );
var mtrlPath = ByteString.FromSpanUnsafe( mtrl->Handle.FileNameSpan(), true, null, true );
_mtrlData = _paths.TryGetValue( mtrlPath, out var c ) ? c : ResolveData.Invalid;
}
}

View file

@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Runtime.CompilerServices;
using Dalamud.Utility.Signatures;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.String;
namespace Penumbra.Interop.Resolver;
@ -31,7 +31,7 @@ public unsafe partial class PathResolver
private readonly ResolverHooks _monster;
// This map links files to their corresponding collection, if it is non-default.
private readonly ConcurrentDictionary< Utf8String, ResolveData > _pathCollections = new();
private readonly ConcurrentDictionary< ByteString, ResolveData > _pathCollections = new();
public PathState( PathResolver parent )
{
@ -69,13 +69,13 @@ public unsafe partial class PathResolver
public int Count
=> _pathCollections.Count;
public IEnumerable< KeyValuePair< Utf8String, ResolveData > > Paths
public IEnumerable< KeyValuePair< ByteString, ResolveData > > Paths
=> _pathCollections;
public bool TryGetValue( Utf8String path, out ResolveData collection )
public bool TryGetValue( ByteString path, out ResolveData collection )
=> _pathCollections.TryGetValue( path, out collection );
public bool Consume( Utf8String path, out ResolveData collection )
public bool Consume( ByteString path, out ResolveData collection )
=> _pathCollections.TryRemove( path, out collection );
// Just add or remove the resolved path.
@ -87,13 +87,13 @@ public unsafe partial class PathResolver
return path;
}
var gamePath = new Utf8String( ( byte* )path );
var gamePath = new ByteString( ( byte* )path );
SetCollection( gameObject, gamePath, collection );
return path;
}
// Special handling for paths so that we do not store non-owned temporary strings in the dictionary.
public void SetCollection( IntPtr gameObject, Utf8String path, ModCollection collection )
public void SetCollection( IntPtr gameObject, ByteString path, ModCollection collection )
{
if( _pathCollections.ContainsKey( path ) || path.IsOwned )
{

View file

@ -5,9 +5,10 @@ using FFXIVClientStructs.FFXIV.Client.Game.Object;
using FFXIVClientStructs.FFXIV.Client.Graphics.Scene;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader;
using Penumbra.String;
using Penumbra.String.Classes;
namespace Penumbra.Interop.Resolver;
@ -151,7 +152,7 @@ public partial class PathResolver : IDisposable
return resolveData;
}
internal IEnumerable< KeyValuePair< Utf8String, ResolveData > > PathCollections
internal IEnumerable< KeyValuePair< ByteString, ResolveData > > PathCollections
=> _paths.Paths;
internal IEnumerable< KeyValuePair< IntPtr, (ResolveData, int) > > DrawObjectMap

View file

@ -4,6 +4,7 @@ using Penumbra.GameData.Structs;
using Penumbra.GameData.Util;
using Penumbra.Interop.Structs;
using System.Collections.Generic;
using Penumbra.String.Functions;
namespace Penumbra.Meta.Files;
@ -23,7 +24,7 @@ public sealed unsafe class CmpFile : MetaBaseFile
}
public override void Reset()
=> Functions.MemCpyUnchecked( Data, ( byte* )DefaultData.Data, DefaultData.Length );
=> MemoryUtility.MemCpyUnchecked( Data, ( byte* )DefaultData.Data, DefaultData.Length );
public void Reset( IEnumerable< (SubRace, RspAttribute) > entries )
{

View file

@ -4,6 +4,7 @@ using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.GameData.Util;
using Penumbra.Interop.Structs;
using Penumbra.String.Functions;
namespace Penumbra.Meta.Files;
@ -63,7 +64,7 @@ public sealed unsafe class ExpandedEqdpFile : MetaBaseFile
public override void Reset()
{
var def = ( byte* )DefaultData.Data;
Functions.MemCpyUnchecked( Data, def, IdentifierSize + PreambleSize );
MemoryUtility.MemCpyUnchecked( Data, def, IdentifierSize + PreambleSize );
var controlPtr = ( ushort* )( def + IdentifierSize + PreambleSize );
var dataBasePtr = controlPtr + BlockCount;
@ -73,18 +74,18 @@ public sealed unsafe class ExpandedEqdpFile : MetaBaseFile
{
if( controlPtr[ i ] == CollapsedBlock )
{
Functions.MemSet( myDataPtr, 0, BlockSize * EqdpEntrySize );
MemoryUtility.MemSet( myDataPtr, 0, BlockSize * EqdpEntrySize );
}
else
{
Functions.MemCpyUnchecked( myDataPtr, dataBasePtr + controlPtr[ i ], BlockSize * EqdpEntrySize );
MemoryUtility.MemCpyUnchecked( myDataPtr, dataBasePtr + controlPtr[ i ], BlockSize * EqdpEntrySize );
}
myControlPtr[ i ] = ( ushort )( i * BlockSize );
myDataPtr += BlockSize;
}
Functions.MemSet( myDataPtr, 0, Length - ( int )( ( byte* )myDataPtr - Data ) );
MemoryUtility.MemSet( myDataPtr, 0, Length - ( int )( ( byte* )myDataPtr - Data ) );
}
public void Reset( IEnumerable< int > entries )

View file

@ -5,6 +5,7 @@ using System.Numerics;
using Penumbra.GameData.Structs;
using Penumbra.GameData.Util;
using Penumbra.Interop.Structs;
using Penumbra.String.Functions;
namespace Penumbra.Meta.Files;
@ -49,7 +50,7 @@ public unsafe class ExpandedEqpGmpBase : MetaBaseFile
protected virtual void SetEmptyBlock( int idx )
{
Functions.MemSet( Data + idx * BlockSize * EntrySize, 0, BlockSize * EntrySize );
MemoryUtility.MemSet( Data + idx * BlockSize * EntrySize, 0, BlockSize * EntrySize );
}
public sealed override void Reset()
@ -62,7 +63,7 @@ public unsafe class ExpandedEqpGmpBase : MetaBaseFile
var collapsed = ( ( controlBlock >> i ) & 1 ) == 0;
if( !collapsed )
{
Functions.MemCpyUnchecked( Data + i * BlockSize * EntrySize, ptr + expandedBlocks * BlockSize * EntrySize, BlockSize * EntrySize );
MemoryUtility.MemCpyUnchecked( Data + i * BlockSize * EntrySize, ptr + expandedBlocks * BlockSize * EntrySize, BlockSize * EntrySize );
expandedBlocks++;
}
else

View file

@ -4,6 +4,7 @@ using Penumbra.GameData.Enums;
using Penumbra.GameData.Util;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Functions;
namespace Penumbra.Meta.Files;
@ -170,8 +171,8 @@ public sealed unsafe class EstFile : MetaBaseFile
{
var (d, length) = DefaultData;
var data = ( byte* )d;
Functions.MemCpyUnchecked( Data, data, length );
Functions.MemSet( Data + length, 0, Length - length );
MemoryUtility.MemCpyUnchecked( Data, data, length );
MemoryUtility.MemSet( Data + length, 0, Length - length );
}
public EstFile( EstManipulation.EstType estType )

View file

@ -1,11 +1,12 @@
using System;
using System.Numerics;
using Newtonsoft.Json;
using Penumbra.GameData.ByteString;
using OtterGui;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Util;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Classes;
using Penumbra.String.Functions;
namespace Penumbra.Meta.Files;
@ -150,7 +151,7 @@ public unsafe class ImcFile : MetaBaseFile
var defaultPtr = ( ImcEntry* )( Data + PreambleSize );
for( var i = oldCount + 1; i < numVariants + 1; ++i )
{
Functions.MemCpyUnchecked( defaultPtr + i * NumParts, defaultPtr, NumParts * sizeof( ImcEntry ) );
MemoryUtility.MemCpyUnchecked( defaultPtr + i * NumParts, defaultPtr, NumParts * sizeof( ImcEntry ) );
}
Penumbra.Log.Verbose( $"Expanded IMC {Path} from {oldCount} to {numVariants} variants." );
@ -188,8 +189,8 @@ public unsafe class ImcFile : MetaBaseFile
var file = Dalamud.GameData.GetFile( Path.ToString() );
fixed( byte* ptr = file!.Data )
{
Functions.MemCpyUnchecked( Data, ptr, file.Data.Length );
Functions.MemSet( Data + file.Data.Length, 0, Length - file.Data.Length );
MemoryUtility.MemCpyUnchecked( Data, ptr, file.Data.Length );
MemoryUtility.MemSet( Data + file.Data.Length, 0, Length - file.Data.Length );
}
}
@ -207,7 +208,7 @@ public unsafe class ImcFile : MetaBaseFile
{
NumParts = BitOperations.PopCount( *( ushort* )( ptr + 2 ) );
AllocateData( file.Data.Length );
Functions.MemCpyUnchecked( Data, ptr, file.Data.Length );
MemoryUtility.MemCpyUnchecked( Data, ptr, file.Data.Length );
}
}
@ -243,7 +244,7 @@ public unsafe class ImcFile : MetaBaseFile
return;
}
Functions.MemCpyUnchecked( newData, Data, ActualLength );
MemoryUtility.MemCpyUnchecked( newData, Data, ActualLength );
Penumbra.MetaFileManager.Free( data, length );
resource->SetData( ( IntPtr )newData, ActualLength );

View file

@ -1,6 +1,7 @@
using System;
using Dalamud.Memory;
using Penumbra.GameData.Util;
using Penumbra.String.Functions;
using CharacterUtility = Penumbra.Interop.CharacterUtility;
namespace Penumbra.Meta.Files;
@ -57,12 +58,12 @@ public unsafe class MetaBaseFile : IDisposable
var data = ( byte* )Penumbra.MetaFileManager.AllocateFileMemory( ( ulong )newLength );
if( newLength > Length )
{
Functions.MemCpyUnchecked( data, Data, Length );
Functions.MemSet( data + Length, 0, newLength - Length );
MemoryUtility.MemCpyUnchecked( data, Data, Length );
MemoryUtility.MemSet( data + Length, 0, newLength - Length );
}
else
{
Functions.MemCpyUnchecked( data, Data, newLength );
MemoryUtility.MemCpyUnchecked( data, Data, newLength );
}
ReleaseUnmanagedResources();

View file

@ -2,11 +2,12 @@ using System;
using System.Collections.Generic;
using FFXIVClientStructs.FFXIV.Client.System.Resource;
using OtterGui.Filesystem;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations;
using Penumbra.String;
using Penumbra.String.Classes;
namespace Penumbra.Meta.Manager;
@ -149,7 +150,7 @@ public partial class MetaManager
=> new($"|{_collection.Name}_{_collection.ChangeCounter}|{path}");
private static unsafe bool ImcLoadHandler( Utf8String split, Utf8String path, ResourceManager* resourceManager,
private static unsafe bool ImcLoadHandler( ByteString split, ByteString path, ResourceManager* resourceManager,
SeFileDescriptor* fileDescriptor, int priority, bool isSync, out byte ret )
{
ret = 0;

View file

@ -2,10 +2,10 @@ using System;
using System.Runtime.InteropServices;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Files;
using Penumbra.String.Classes;
namespace Penumbra.Meta.Manipulations;

View file

@ -4,6 +4,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Penumbra.GameData.Util;
using Penumbra.Interop.Structs;
using Penumbra.String.Functions;
namespace Penumbra.Meta.Manipulations;
@ -217,7 +218,7 @@ public readonly struct MetaManipulation : IEquatable< MetaManipulation >, ICompa
{
fixed( MetaManipulation* lhs = &this )
{
return Functions.MemCmpUnchecked( lhs, &other, sizeof( MetaManipulation ) );
return MemoryUtility.MemCmpUnchecked( lhs, &other, sizeof( MetaManipulation ) );
}
}

View file

@ -5,7 +5,7 @@ using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Threading.Tasks;
using Penumbra.GameData.ByteString;
using Penumbra.String.Classes;
namespace Penumbra.Mods;
@ -124,7 +124,7 @@ public partial class Mod
foreach( var file in files )
{
// Skip any UI Files because deduplication causes weird crashes for those.
if( file.SubModUsage.Any( f => f.Item2.Path.StartsWith( 'u', 'i', '/' ) ) )
if( file.SubModUsage.Any( f => f.Item2.Path.StartsWith( "ui/"u8 ) ) )
{
continue;
}

View file

@ -1,6 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Penumbra.GameData.ByteString;
using Penumbra.String.Classes;
using Penumbra.Util;
namespace Penumbra.Mods;

View file

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using Penumbra.GameData.ByteString;
using Penumbra.String.Classes;
namespace Penumbra.Mods;

View file

@ -5,9 +5,9 @@ using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using OtterGui;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Files;
using Penumbra.String.Classes;
namespace Penumbra.Mods;

View file

@ -4,8 +4,8 @@ using System.Linq;
using OtterGui;
using OtterGui.Filesystem;
using Penumbra.Api.Enums;
using Penumbra.GameData.ByteString;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Classes;
using Penumbra.Util;
namespace Penumbra.Mods;

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using System.Linq;
using Penumbra.GameData.Util;
namespace Penumbra.Mods;
@ -14,7 +15,7 @@ public sealed partial class Mod
ChangedItems.Clear();
foreach( var gamePath in AllRedirects )
{
identifier.Identify( ChangedItems, gamePath.ToGamePath() );
identifier.Identify( ChangedItems, new GamePath(gamePath.ToString()) );
}
// TODO: manipulations

View file

@ -6,8 +6,8 @@ using Dalamud.Utility;
using OtterGui.Classes;
using OtterGui.Filesystem;
using Penumbra.Api.Enums;
using Penumbra.GameData.ByteString;
using Penumbra.Import;
using Penumbra.String.Classes;
namespace Penumbra.Mods;

View file

@ -5,8 +5,8 @@ using System.Linq;
using Newtonsoft.Json.Linq;
using OtterGui;
using Penumbra.Api.Enums;
using Penumbra.GameData.ByteString;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Classes;
namespace Penumbra.Mods;

View file

@ -7,7 +7,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OtterGui;
using Penumbra.Api.Enums;
using Penumbra.GameData.ByteString;
using Penumbra.String.Classes;
namespace Penumbra.Mods;

View file

@ -4,8 +4,8 @@ using System.IO;
using System.Linq;
using OtterGui.Classes;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Classes;
namespace Penumbra.Mods;
@ -59,7 +59,7 @@ public sealed partial class Mod
var defaultMod = mod._default;
foreach( var (gamePath, fullPath) in collection.ResolvedFiles )
{
if( gamePath.Path.EndsWith( '.', 'i', 'm', 'c' ) )
if( gamePath.Path.EndsWith( ".imc"u8 ) )
{
continue;
}

View file

@ -1,8 +1,8 @@
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json;
using Penumbra.GameData.ByteString;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Classes;
namespace Penumbra.Mods;

View file

@ -4,9 +4,9 @@ using System.IO;
using System.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Penumbra.GameData.ByteString;
using Penumbra.Import;
using Penumbra.Meta.Manipulations;
using Penumbra.String.Classes;
namespace Penumbra.Mods;

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using Dalamud.Game.Command;
using Dalamud.Interface.Windowing;
@ -21,6 +22,8 @@ using Penumbra.Interop;
using Penumbra.UI;
using Penumbra.Util;
using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.GameData.Actors;
using Penumbra.Interop.Loader;
using Penumbra.Interop.Resolver;
using Penumbra.Mods;
@ -55,6 +58,8 @@ public class Penumbra : IDalamudPlugin
public static TempModManager TempMods { get; private set; } = null!;
public static ResourceLoader ResourceLoader { get; private set; } = null!;
public static FrameworkManager Framework { get; private set; } = null!;
public static ActorManager Actors { get; private set; } = null!;
public static readonly List< Exception > ImcExceptions = new();
public readonly ResourceLogger ResourceLogger;
@ -98,6 +103,7 @@ public class Penumbra : IDalamudPlugin
ModFileSystem = ModFileSystem.Load();
ObjectReloader = new ObjectReloader();
PathResolver = new PathResolver( ResourceLoader );
Actors = new ActorManager( Dalamud.Objects, Dalamud.ClientState, Dalamud.GameData, u => ( short )PathResolver.CutsceneActor( u ) );
Dalamud.Commands.AddHandler( CommandName, new CommandInfo( OnCommand )
{
@ -144,7 +150,7 @@ public class Penumbra : IDalamudPlugin
{
Log.Information( $"Penumbra Version {Version}, Commit #{CommitHash} successfully Loaded." );
}
Dalamud.PluginInterface.UiBuilder.Draw += _windowSystem.Draw;
OtterTex.NativeDll.Initialize( Dalamud.PluginInterface.AssemblyLocation.DirectoryName );
@ -283,6 +289,8 @@ public class Penumbra : IDalamudPlugin
public void Dispose()
{
Dalamud.PluginInterface.RelinquishData( "test1" );
Framework?.Dispose();
ShutdownWebServer();
DisposeInterface();
IpcProviders?.Dispose();
@ -290,7 +298,6 @@ public class Penumbra : IDalamudPlugin
ObjectReloader?.Dispose();
ModFileSystem?.Dispose();
CollectionManager?.Dispose();
Framework?.Dispose();
Dalamud.Commands.RemoveHandler( CommandName );

View file

@ -9,10 +9,10 @@ using Dalamud.Interface;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Files;
using Penumbra.Mods;
using Functions = Penumbra.GameData.Util.Functions;
using Penumbra.String.Classes;
using Penumbra.String.Functions;
namespace Penumbra.UI.Classes;
@ -459,14 +459,14 @@ public partial class ModEditWindow
ref var rows = ref file.ColorSets[ colorSetIdx ].Rows;
fixed( void* ptr = data, output = &rows )
{
Functions.MemCpyUnchecked( output, ptr, Marshal.SizeOf< MtrlFile.ColorSet.RowArray >() );
MemoryUtility.MemCpyUnchecked( output, ptr, Marshal.SizeOf< MtrlFile.ColorSet.RowArray >() );
if( data.Length >= Marshal.SizeOf< MtrlFile.ColorSet.RowArray >() + Marshal.SizeOf< MtrlFile.ColorDyeSet.RowArray >()
&& file.ColorDyeSets.Length > colorSetIdx )
{
ref var dyeRows = ref file.ColorDyeSets[ colorSetIdx ].Rows;
fixed( void* output2 = &dyeRows )
{
Functions.MemCpyUnchecked( output2, ( byte* )ptr + Marshal.SizeOf< MtrlFile.ColorSet.RowArray >(), Marshal.SizeOf< MtrlFile.ColorDyeSet.RowArray >() );
MemoryUtility.MemCpyUnchecked( output2, ( byte* )ptr + Marshal.SizeOf< MtrlFile.ColorSet.RowArray >(), Marshal.SizeOf< MtrlFile.ColorDyeSet.RowArray >() );
}
}
}
@ -489,8 +489,8 @@ public partial class ModEditWindow
var data = new byte[MtrlFile.ColorSet.Row.Size + 2];
fixed( byte* ptr = data )
{
Functions.MemCpyUnchecked( ptr, &row, MtrlFile.ColorSet.Row.Size );
Functions.MemCpyUnchecked( ptr + MtrlFile.ColorSet.Row.Size, &dye, 2 );
MemoryUtility.MemCpyUnchecked( ptr, &row, MtrlFile.ColorSet.Row.Size );
MemoryUtility.MemCpyUnchecked( ptr + MtrlFile.ColorSet.Row.Size, &dye, 2 );
}
var text = Convert.ToBase64String( data );

View file

@ -7,9 +7,8 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Classes;
using OtterGui.Raii;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Util;
using Penumbra.Mods;
using Penumbra.String.Classes;
namespace Penumbra.UI.Classes;

View file

@ -8,11 +8,11 @@ using Dalamud.Interface.Windowing;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Files;
using Penumbra.Import.Textures;
using Penumbra.Mods;
using Penumbra.String.Classes;
using Penumbra.Util;
using static Penumbra.Mods.Mod;

View file

@ -32,6 +32,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
SubscribeRightClickFolder( InheritDescendants, 15 );
SubscribeRightClickFolder( OwnDescendants, 15 );
SubscribeRightClickFolder( SetDefaultImportFolder, 100 );
SubscribeRightClickLeaf( ToggleLeafFavorite, 0 );
SubscribeRightClickMain( ClearDefaultImportFolder, 100 );
AddButton( AddNewModButton, 0 );
AddButton( AddImportModButton, 1 );
@ -117,9 +118,10 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
protected override void DrawLeafName( FileSystem< Mod >.Leaf leaf, in ModState state, bool selected )
{
var flags = selected ? ImGuiTreeNodeFlags.Selected | LeafFlags : LeafFlags;
using var c = ImRaii.PushColor( ImGuiCol.Text, state.Color.Value() );
using var id = ImRaii.PushId( leaf.Value.Index );
var flags = selected ? ImGuiTreeNodeFlags.Selected | LeafFlags : LeafFlags;
using var c = ImRaii.PushColor( ImGuiCol.Text, state.Color.Value() )
.Push( ImGuiCol.HeaderHovered, 0x4000FFFF, leaf.Value.Favorite );
using var id = ImRaii.PushId( leaf.Value.Index );
ImRaii.TreeNode( leaf.Value.Name, flags ).Dispose();
}
@ -157,6 +159,14 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
}
}
private static void ToggleLeafFavorite( FileSystem< Mod >.Leaf mod )
{
if( ImGui.MenuItem( mod.Value.Favorite ? "Remove Favorite" : "Mark as Favorite" ) )
{
Penumbra.ModManager.ChangeModFavorite( mod.Value.Index, !mod.Value.Favorite );
}
}
private static void SetDefaultImportFolder( ModFileSystem.Folder folder )
{
if( ImGui.MenuItem( "Set As Default Import Folder" ) )

View file

@ -9,9 +9,9 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.ByteString;
using Penumbra.Interop.Loader;
using Penumbra.Interop.Structs;
using Penumbra.String;
using CharacterUtility = Penumbra.Interop.CharacterUtility;
namespace Penumbra.UI;
@ -56,6 +56,8 @@ public partial class ConfigWindow
ImGui.NewLine();
DrawPathResolverDebug();
ImGui.NewLine();
DrawActorsDebug();
ImGui.NewLine();
DrawDebugCharacterUtility();
ImGui.NewLine();
DrawDebugTabMetaLists();
@ -148,6 +150,31 @@ public partial class ConfigWindow
}
}
private static unsafe void DrawActorsDebug()
{
if( !ImGui.CollapsingHeader( "Actors" ) )
{
return;
}
using var table = ImRaii.Table( "##actors", 4, ImGuiTableFlags.RowBg | ImGuiTableFlags.SizingFixedFit,
-Vector2.UnitX );
if( !table )
{
return;
}
foreach( var obj in Dalamud.Objects )
{
ImGuiUtil.DrawTableColumn( $"{( ( GameObject* )obj.Address )->ObjectIndex}" );
ImGuiUtil.DrawTableColumn( $"0x{obj.Address:X}" );
var identifier = Penumbra.Actors.FromObject( obj );
ImGuiUtil.DrawTableColumn( Penumbra.Actors.ToString( identifier ) );
ImGuiUtil.DrawTableColumn( identifier.DataId.ToString() );
}
}
// Draw information about which draw objects correspond to which game objects
// and which paths are due to be loaded by which collection.
private unsafe void DrawPathResolverDebug()
@ -173,7 +200,7 @@ public partial class ConfigWindow
ImGui.TableNextColumn();
var obj = ( GameObject* )Dalamud.Objects.GetObjectAddress( idx );
var (address, name) =
obj != null ? ( $"0x{( ulong )obj:X}", new Utf8String( obj->Name ).ToString() ) : ( "NULL", "NULL" );
obj != null ? ( $"0x{( ulong )obj:X}", new ByteString( obj->Name ).ToString() ) : ( "NULL", "NULL" );
ImGui.TextUnformatted( address );
ImGui.TableNextColumn();
ImGui.TextUnformatted( name );

View file

@ -7,9 +7,9 @@ using OtterGui;
using OtterGui.Classes;
using OtterGui.Raii;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.Meta.Manipulations;
using Penumbra.Mods;
using Penumbra.String.Classes;
namespace Penumbra.UI;

View file

@ -9,17 +9,16 @@ using OtterGui;
using OtterGui.Raii;
using Penumbra.Api.Enums;
using Penumbra.Collections;
using Penumbra.GameData.ByteString;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs;
using Penumbra.String;
using Penumbra.UI.Classes;
namespace Penumbra.UI;
public partial class ConfigWindow
{
// Draw text given by a Utf8String.
internal static unsafe void Text( Utf8String s )
// Draw text given by a ByteString.
internal static unsafe void Text( ByteString s )
=> ImGuiNative.igTextUnformatted( s.Path, s.Path + s.Length );
// Draw text given by a byte pointer.
@ -30,8 +29,8 @@ public partial class ConfigWindow
private static unsafe void Text( ResourceHandle* resource )
=> Text( resource->FileName(), resource->FileNameLength );
// Draw a Utf8String as a selectable.
internal static unsafe bool Selectable( Utf8String s, bool selected )
// Draw a ByteString as a selectable.
internal static unsafe bool Selectable( ByteString s, bool selected )
{
var tmp = ( byte )( selected ? 1 : 0 );
return ImGuiNative.igSelectable_Bool( s.Path, tmp, ImGuiSelectableFlags.None, Vector2.Zero ) != 0;
@ -77,8 +76,8 @@ public partial class ConfigWindow
}
// A selectable that copies its text to clipboard on selection and provides a on-hover tooltip about that,
// using an Utf8String.
private static unsafe void CopyOnClickSelectable( Utf8String text )
// using an ByteString.
private static unsafe void CopyOnClickSelectable( ByteString text )
{
if( ImGuiNative.igSelectable_Bool( text.Path, 0, ImGuiSelectableFlags.None, Vector2.Zero ) != 0 )
{

View file

@ -6,9 +6,10 @@ using OtterGui;
using OtterGui.Classes;
using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.GameData.ByteString;
using Penumbra.Meta.Manipulations;
using Penumbra.Mods;
using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.UI.Classes;
namespace Penumbra.UI;
@ -32,11 +33,11 @@ public partial class ConfigWindow
private Tabs _availableTabs = 0;
// Required to use tabs that can not be closed but have a flag to set them open.
private static readonly Utf8String ConflictTabHeader = Utf8String.FromStringUnsafe( "Conflicts", false );
private static readonly Utf8String DescriptionTabHeader = Utf8String.FromStringUnsafe( "Description", false );
private static readonly Utf8String SettingsTabHeader = Utf8String.FromStringUnsafe( "Settings", false );
private static readonly Utf8String ChangedItemsTabHeader = Utf8String.FromStringUnsafe( "Changed Items", false );
private static readonly Utf8String EditModTabHeader = Utf8String.FromStringUnsafe( "Edit Mod", false );
private static readonly ByteString ConflictTabHeader = ByteString.FromSpanUnsafe( "Conflicts"u8, true, false, true );
private static readonly ByteString DescriptionTabHeader = ByteString.FromSpanUnsafe( "Description"u8, true, false, true );
private static readonly ByteString SettingsTabHeader = ByteString.FromSpanUnsafe( "Settings"u8, true, false, true );
private static readonly ByteString ChangedItemsTabHeader = ByteString.FromSpanUnsafe( "Changed Items"u8, true, false, true );
private static readonly ByteString EditModTabHeader = ByteString.FromSpanUnsafe( "Edit Mod"u8, true, false, true );
private readonly TagButtons _modTags = new();
@ -147,6 +148,7 @@ public partial class ConfigWindow
{
Penumbra.ModManager.ChangeLocalTag( _mod.Index, tagIdx, editedTag );
}
if( _mod.ModTags.Count > 0 )
{
_modTags.Draw( "Mod Tags: ", "Tags assigned by the mod creator and saved with the mod data. To edit these, look at Edit Mod.", _mod.ModTags, out var _, false,
@ -226,7 +228,7 @@ public partial class ConfigWindow
// Draw a tab by given name if it is available, and deal with changing the preferred tab.
private ImRaii.IEndObject DrawTab( Utf8String name, Tabs flag )
private ImRaii.IEndObject DrawTab( ByteString name, Tabs flag )
{
if( !_availableTabs.HasFlag( flag ) )
{

View file

@ -8,8 +8,8 @@ using FFXIVClientStructs.STD;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.ByteString;
using Penumbra.Interop.Loader;
using Penumbra.String.Classes;
namespace Penumbra.UI;

View file

@ -3,8 +3,8 @@ using Dalamud.Interface;
using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using Penumbra.GameData.ByteString;
using Penumbra.Interop;
using Penumbra.String.Classes;
using Penumbra.UI.Classes;
namespace Penumbra.UI;

View file

@ -67,8 +67,12 @@
"penumbra.gamedata": {
"type": "Project",
"dependencies": {
"Penumbra.Api": "[1.0.0, )"
"Penumbra.Api": "[1.0.0, )",
"Penumbra.String": "[1.0.0, )"
}
},
"penumbra.string": {
"type": "Project"
}
}
}