This commit is contained in:
Ottermandias 2023-03-10 18:29:58 +01:00
parent 3c564add0e
commit 73e2793da6
48 changed files with 4231 additions and 456 deletions

File diff suppressed because it is too large Load diff

View file

@ -8,8 +8,9 @@ using Penumbra.GameData.Structs;
namespace Penumbra.GameData.Data; namespace Penumbra.GameData.Data;
internal class GamePathParser : IGamePathParser public class GamePathParser : IGamePathParser
{ {
/// <summary> Obtain basic information about a file path. </summary>
public GameObjectInfo GetFileInfo(string path) public GameObjectInfo GetFileInfo(string path)
{ {
path = path.ToLowerInvariant().Replace('\\', '/'); path = path.ToLowerInvariant().Replace('\\', '/');
@ -49,6 +50,8 @@ internal class GamePathParser : IGamePathParser
}; };
} }
/// <summary> Get the key of a VFX symbol. </summary>
/// <returns>The lower-case key or an empty string if no match is found.</returns>
public string VfxToKey(string path) public string VfxToKey(string path)
{ {
var match = GamePaths.Vfx.Tmb().Match(path); var match = GamePaths.Vfx.Tmb().Match(path);
@ -59,25 +62,7 @@ internal class GamePathParser : IGamePathParser
return match.Success ? match.Groups["key"].Value.ToLowerInvariant() : string.Empty; return match.Success ? match.Groups["key"].Value.ToLowerInvariant() : string.Empty;
} }
private const string CharacterFolder = "chara"; /// <summary> Obtain the ObjectType from a given path.</summary>
private const string EquipmentFolder = "equipment";
private const string PlayerFolder = "human";
private const string WeaponFolder = "weapon";
private const string AccessoryFolder = "accessory";
private const string DemiHumanFolder = "demihuman";
private const string MonsterFolder = "monster";
private const string CommonFolder = "common";
private const string UiFolder = "ui";
private const string IconFolder = "icon";
private const string LoadingFolder = "loadingimage";
private const string MapFolder = "map";
private const string InterfaceFolder = "uld";
private const string FontFolder = "font";
private const string HousingFolder = "hou";
private const string VfxFolder = "vfx";
private const string WorldFolder1 = "bgcommon";
private const string WorldFolder2 = "bg";
public ObjectType PathToObjectType(string path) public ObjectType PathToObjectType(string path)
{ {
if (path.Length == 0) if (path.Length == 0)
@ -125,6 +110,25 @@ internal class GamePathParser : IGamePathParser
}; };
} }
private const string CharacterFolder = "chara";
private const string EquipmentFolder = "equipment";
private const string PlayerFolder = "human";
private const string WeaponFolder = "weapon";
private const string AccessoryFolder = "accessory";
private const string DemiHumanFolder = "demihuman";
private const string MonsterFolder = "monster";
private const string CommonFolder = "common";
private const string UiFolder = "ui";
private const string IconFolder = "icon";
private const string LoadingFolder = "loadingimage";
private const string MapFolder = "map";
private const string InterfaceFolder = "uld";
private const string FontFolder = "font";
private const string HousingFolder = "hou";
private const string VfxFolder = "vfx";
private const string WorldFolder1 = "bgcommon";
private const string WorldFolder2 = "bg";
private (FileType, ObjectType, Match?) ParseGamePath(string path) private (FileType, ObjectType, Match?) ParseGamePath(string path)
{ {
if (!Names.ExtensionToFileType.TryGetValue(Path.GetExtension(path), out var fileType)) if (!Names.ExtensionToFileType.TryGetValue(Path.GetExtension(path), out var fileType))

View file

@ -16,7 +16,8 @@ using Penumbra.Collections;
using Penumbra.String; using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.Meta.Manipulations; using Penumbra.Meta.Manipulations;
using Penumbra.Services;
namespace Penumbra.Api; namespace Penumbra.Api;
public class IpcTester : IDisposable public class IpcTester : IDisposable
@ -458,17 +459,17 @@ public class IpcTester : IDisposable
} }
DrawIntro( Ipc.RedrawObject.Label, "Redraw Player Character" ); DrawIntro( Ipc.RedrawObject.Label, "Redraw Player Character" );
if( ImGui.Button( "Redraw##pc" ) && Dalamud.ClientState.LocalPlayer != null ) if( ImGui.Button( "Redraw##pc" ) && DalamudServices.ClientState.LocalPlayer != null )
{ {
Ipc.RedrawObject.Subscriber( _pi ).Invoke( Dalamud.ClientState.LocalPlayer, RedrawType.Redraw ); Ipc.RedrawObject.Subscriber( _pi ).Invoke( DalamudServices.ClientState.LocalPlayer, RedrawType.Redraw );
} }
DrawIntro( Ipc.RedrawObjectByIndex.Label, "Redraw by Index" ); DrawIntro( Ipc.RedrawObjectByIndex.Label, "Redraw by Index" );
var tmp = _redrawIndex; var tmp = _redrawIndex;
ImGui.SetNextItemWidth( 100 * ImGuiHelpers.GlobalScale ); ImGui.SetNextItemWidth( 100 * ImGuiHelpers.GlobalScale );
if( ImGui.DragInt( "##redrawIndex", ref tmp, 0.1f, 0, Dalamud.Objects.Length ) ) if( ImGui.DragInt( "##redrawIndex", ref tmp, 0.1f, 0, DalamudServices.Objects.Length ) )
{ {
_redrawIndex = Math.Clamp( tmp, 0, Dalamud.Objects.Length ); _redrawIndex = Math.Clamp( tmp, 0, DalamudServices.Objects.Length );
} }
ImGui.SameLine(); ImGui.SameLine();
@ -489,12 +490,12 @@ public class IpcTester : IDisposable
private void SetLastRedrawn( IntPtr address, int index ) private void SetLastRedrawn( IntPtr address, int index )
{ {
if( index < 0 || index > Dalamud.Objects.Length || address == IntPtr.Zero || Dalamud.Objects[ index ]?.Address != address ) if( index < 0 || index > DalamudServices.Objects.Length || address == IntPtr.Zero || DalamudServices.Objects[ index ]?.Address != address )
{ {
_lastRedrawnString = "Invalid"; _lastRedrawnString = "Invalid";
} }
_lastRedrawnString = $"{Dalamud.Objects[ index ]!.Name} (0x{address:X}, {index})"; _lastRedrawnString = $"{DalamudServices.Objects[ index ]!.Name} (0x{address:X}, {index})";
} }
} }

View file

@ -18,7 +18,8 @@ using Penumbra.Api.Enums;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.String; using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.Services;
namespace Penumbra.Api; namespace Penumbra.Api;
public class PenumbraApi : IDisposable, IPenumbraApi public class PenumbraApi : IDisposable, IPenumbraApi
@ -84,9 +85,9 @@ public class PenumbraApi : IDisposable, IPenumbraApi
public unsafe PenumbraApi( Penumbra penumbra ) public unsafe PenumbraApi( Penumbra penumbra )
{ {
_penumbra = penumbra; _penumbra = penumbra;
_lumina = ( Lumina.GameData? )Dalamud.GameData.GetType() _lumina = ( Lumina.GameData? )DalamudServices.GameData.GetType()
.GetField( "gameData", BindingFlags.Instance | BindingFlags.NonPublic ) .GetField( "gameData", BindingFlags.Instance | BindingFlags.NonPublic )
?.GetValue( Dalamud.GameData ); ?.GetValue( DalamudServices.GameData );
foreach( var collection in Penumbra.CollectionManager ) foreach( var collection in Penumbra.CollectionManager )
{ {
SubscribeToCollection( collection ); SubscribeToCollection( collection );
@ -889,12 +890,12 @@ public class PenumbraApi : IDisposable, IPenumbraApi
{ {
CheckInitialized(); CheckInitialized();
if( actorIndex < 0 || actorIndex >= Dalamud.Objects.Length ) if( actorIndex < 0 || actorIndex >= DalamudServices.Objects.Length )
{ {
return PenumbraApiEc.InvalidArgument; return PenumbraApiEc.InvalidArgument;
} }
var identifier = Penumbra.Actors.FromObject( Dalamud.Objects[ actorIndex ], false, false, true ); var identifier = Penumbra.Actors.FromObject( DalamudServices.Objects[ actorIndex ], false, false, true );
if( !identifier.IsValid ) if( !identifier.IsValid )
{ {
return PenumbraApiEc.InvalidArgument; return PenumbraApiEc.InvalidArgument;
@ -1064,12 +1065,12 @@ public class PenumbraApi : IDisposable, IPenumbraApi
private static unsafe bool AssociatedCollection( int gameObjectIdx, out ModCollection collection ) private static unsafe bool AssociatedCollection( int gameObjectIdx, out ModCollection collection )
{ {
collection = Penumbra.CollectionManager.Default; collection = Penumbra.CollectionManager.Default;
if( gameObjectIdx < 0 || gameObjectIdx >= Dalamud.Objects.Length ) if( gameObjectIdx < 0 || gameObjectIdx >= DalamudServices.Objects.Length )
{ {
return false; return false;
} }
var ptr = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )Dalamud.Objects.GetObjectAddress( gameObjectIdx ); var ptr = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )DalamudServices.Objects.GetObjectAddress( gameObjectIdx );
var data = PathResolver.IdentifyCollection( ptr, false ); var data = PathResolver.IdentifyCollection( ptr, false );
if( data.Valid ) if( data.Valid )
{ {
@ -1082,12 +1083,12 @@ public class PenumbraApi : IDisposable, IPenumbraApi
[MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )] [MethodImpl( MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization )]
private static unsafe ActorIdentifier AssociatedIdentifier( int gameObjectIdx ) private static unsafe ActorIdentifier AssociatedIdentifier( int gameObjectIdx )
{ {
if( gameObjectIdx < 0 || gameObjectIdx >= Dalamud.Objects.Length ) if( gameObjectIdx < 0 || gameObjectIdx >= DalamudServices.Objects.Length )
{ {
return ActorIdentifier.Invalid; return ActorIdentifier.Invalid;
} }
var ptr = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )Dalamud.Objects.GetObjectAddress( gameObjectIdx ); var ptr = ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )DalamudServices.Objects.GetObjectAddress( gameObjectIdx );
return Penumbra.Actors.FromObject( ptr, out _, false, true, true ); return Penumbra.Actors.FromObject( ptr, out _, false, true, true );
} }
@ -1116,7 +1117,7 @@ public class PenumbraApi : IDisposable, IPenumbraApi
return _lumina?.GetFileFromDisk< T >( resolvedPath ); return _lumina?.GetFileFromDisk< T >( resolvedPath );
} }
return Dalamud.GameData.GetFile< T >( resolvedPath ); return DalamudServices.GameData.GetFile< T >( resolvedPath );
} }
catch( Exception e ) catch( Exception e )
{ {

View file

@ -11,7 +11,8 @@ using System.Threading.Tasks;
using Dalamud.Interface.Internal.Notifications; using Dalamud.Interface.Internal.Notifications;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.Util; using Penumbra.Util;
using Penumbra.Services;
namespace Penumbra.Collections; namespace Penumbra.Collections;
public partial class ModCollection public partial class ModCollection
@ -205,7 +206,7 @@ public partial class ModCollection
=> name.Length == 0 ? Empty.Index : _collections.IndexOf( c => c.Name == name ); => name.Length == 0 ? Empty.Index : _collections.IndexOf( c => c.Name == name );
public static string ActiveCollectionFile public static string ActiveCollectionFile
=> Path.Combine( Dalamud.PluginInterface.ConfigDirectory.FullName, "active_collections.json" ); => Path.Combine( DalamudServices.PluginInterface.ConfigDirectory.FullName, "active_collections.json" );
// Load default, current, special, and character collections from config. // Load default, current, special, and character collections from config.
// Then create caches. If a collection does not exist anymore, reset it to an appropriate default. // Then create caches. If a collection does not exist anymore, reset it to an appropriate default.

View file

@ -2,6 +2,7 @@ using Newtonsoft.Json;
using Newtonsoft.Json.Linq; using Newtonsoft.Json.Linq;
using OtterGui.Filesystem; using OtterGui.Filesystem;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Services;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
@ -14,7 +15,7 @@ namespace Penumbra.Collections;
public partial class ModCollection public partial class ModCollection
{ {
public static string CollectionDirectory public static string CollectionDirectory
=> Path.Combine( Dalamud.PluginInterface.GetPluginConfigDirectory(), "collections" ); => Path.Combine( DalamudServices.PluginInterface.GetPluginConfigDirectory(), "collections" );
// We need to remove all invalid path symbols from the collection name to be able to save it to file. // We need to remove all invalid path symbols from the collection name to be able to save it to file.
public FileInfo FileName public FileInfo FileName

View file

@ -9,6 +9,7 @@ using Penumbra.Collections;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.Interop; using Penumbra.Interop;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI; using Penumbra.UI;
namespace Penumbra; namespace Penumbra;
@ -120,27 +121,27 @@ public class CommandHandler : IDisposable
{ {
if( !string.Equals( arguments, "help", StringComparison.OrdinalIgnoreCase ) && arguments == "?" ) if( !string.Equals( arguments, "help", StringComparison.OrdinalIgnoreCase ) && arguments == "?" )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddText( "The given argument " ).AddRed( arguments, true ).AddText( " is not valid. Valid arguments are:" ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddText( "The given argument " ).AddRed( arguments, true ).AddText( " is not valid. Valid arguments are:" ).BuiltString );
} }
else else
{ {
Dalamud.Chat.Print( "Valid arguments for /penumbra are:" ); DalamudServices.Chat.Print( "Valid arguments for /penumbra are:" );
} }
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "window", DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "window",
"Toggle the Penumbra main config window. Can be used with [on|off] to force specific state. Also used when no argument is provided." ).BuiltString ); "Toggle the Penumbra main config window. Can be used with [on|off] to force specific state. Also used when no argument is provided." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "enable", "Enable modding and force a redraw of all game objects if it was previously disabled." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "enable", "Enable modding and force a redraw of all game objects if it was previously disabled." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "disable", "Disable modding and force a redraw of all game objects if it was previously enabled." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "disable", "Disable modding and force a redraw of all game objects if it was previously enabled." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "toggle", "Toggle modding and force a redraw of all game objects." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "toggle", "Toggle modding and force a redraw of all game objects." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "reload", "Rediscover the mod directory and reload all mods." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "reload", "Rediscover the mod directory and reload all mods." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "redraw", "Redraw all game objects. Specify a placeholder or a name to redraw specific objects." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "redraw", "Redraw all game objects. Specify a placeholder or a name to redraw specific objects." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "lockui", "Toggle the locked state of the main Penumbra window. Can be used with [on|off] to force specific state." ) DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "lockui", "Toggle the locked state of the main Penumbra window. Can be used with [on|off] to force specific state." )
.BuiltString ); .BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "debug", "Toggle debug mode for Penumbra. Can be used with [on|off] to force specific state." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "debug", "Toggle debug mode for Penumbra. Can be used with [on|off] to force specific state." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "collection", "Change your active collection setup. Use without further parameters for more detailed help." ) DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "collection", "Change your active collection setup. Use without further parameters for more detailed help." )
.BuiltString ); .BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddCommand( "mod", "Change a specific mods settings. Use without further parameters for more detailed help." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "mod", "Change a specific mods settings. Use without further parameters for more detailed help." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder() DalamudServices.Chat.Print( new SeStringBuilder()
.AddCommand( "bulktag", "Change multiple mods settings based on their tags. Use without further parameters for more detailed help." ) .AddCommand( "bulktag", "Change multiple mods settings based on their tags. Use without further parameters for more detailed help." )
.BuiltString ); .BuiltString );
return true; return true;
@ -240,26 +241,26 @@ public class CommandHandler : IDisposable
{ {
if( arguments.Length == 0 ) if( arguments.Length == 0 )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddText( "Use with /penumbra collection " ).AddBlue( "[Collection Type]" ).AddText( " | " ).AddYellow( "[Collection Name]" ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( "Use with /penumbra collection " ).AddBlue( "[Collection Type]" ).AddText( " | " ).AddYellow( "[Collection Name]" )
.AddText( " | " ).AddGreen( "<Identifier>" ).BuiltString ); .AddText( " | " ).AddGreen( "<Identifier>" ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddText( " 》 Valid Collection Types are " ).AddBlue( "Base" ).AddText( ", " ).AddBlue( "Ui" ).AddText( ", " ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( " 》 Valid Collection Types are " ).AddBlue( "Base" ).AddText( ", " ).AddBlue( "Ui" ).AddText( ", " )
.AddBlue( "Selected" ).AddText( ", " ) .AddBlue( "Selected" ).AddText( ", " )
.AddBlue( "Individual" ).AddText( ", and all those selectable in Character Groups." ).BuiltString ); .AddBlue( "Individual" ).AddText( ", and all those selectable in Character Groups." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddText( " 》 Valid Collection Names are " ).AddYellow( "None" ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( " 》 Valid Collection Names are " ).AddYellow( "None" )
.AddText( ", all collections you have created by their full names, and " ).AddYellow( "Delete" ).AddText( " to remove assignments (not valid for all types)." ) .AddText( ", all collections you have created by their full names, and " ).AddYellow( "Delete" ).AddText( " to remove assignments (not valid for all types)." )
.BuiltString ); .BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddText( " 》 If the type is " ).AddBlue( "Individual" ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( " 》 If the type is " ).AddBlue( "Individual" )
.AddText( " you need to specify an individual with an identifier of the form:" ).BuiltString ); .AddText( " you need to specify an individual with an identifier of the form:" ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "<me>" ).AddText( " or " ).AddGreen( "<t>" ).AddText( " or " ).AddGreen( "<mo>" ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "<me>" ).AddText( " or " ).AddGreen( "<t>" ).AddText( " or " ).AddGreen( "<mo>" )
.AddText( " or " ).AddGreen( "<f>" ).AddText( " as placeholders for your character, your target, your mouseover or your focus, if they exist." ).BuiltString ); .AddText( " or " ).AddGreen( "<f>" ).AddText( " as placeholders for your character, your target, your mouseover or your focus, if they exist." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "p" ).AddText( " | " ).AddWhite( "[Player Name]@<World Name>" ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "p" ).AddText( " | " ).AddWhite( "[Player Name]@<World Name>" )
.AddText( ", if no @ is provided, Any World is used." ).BuiltString ); .AddText( ", if no @ is provided, Any World is used." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "r" ).AddText( " | " ).AddWhite( "[Retainer Name]" ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "r" ).AddText( " | " ).AddWhite( "[Retainer Name]" ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "n" ).AddText( " | " ).AddPurple( "[NPC Type]" ).AddText( " : " ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "n" ).AddText( " | " ).AddPurple( "[NPC Type]" ).AddText( " : " )
.AddRed( "[NPC Name]" ).AddText( ", where NPC Type can be " ).AddInitialPurple( "Mount" ).AddInitialPurple( "Companion" ).AddInitialPurple( "Accessory" ) .AddRed( "[NPC Name]" ).AddText( ", where NPC Type can be " ).AddInitialPurple( "Mount" ).AddInitialPurple( "Companion" ).AddInitialPurple( "Accessory" )
.AddInitialPurple( "Event NPC" ).AddText( "or " ) .AddInitialPurple( "Event NPC" ).AddText( "or " )
.AddInitialPurple( "Battle NPC", false ).AddText( "." ).BuiltString ); .AddInitialPurple( "Battle NPC", false ).AddText( "." ).BuiltString );
Dalamud.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "o" ).AddText( " | " ).AddPurple( "[NPC Type]" ).AddText( " : " ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( " 》》》 " ).AddGreen( "o" ).AddText( " | " ).AddPurple( "[NPC Type]" ).AddText( " : " )
.AddRed( "[NPC Name]" ).AddText( " | " ).AddWhite( "[Player Name]@<World Name>" ).AddText( "." ).BuiltString ); .AddRed( "[NPC Name]" ).AddText( " | " ).AddWhite( "[Player Name]@<World Name>" ).AddText( "." ).BuiltString );
return true; return true;
} }
@ -269,13 +270,13 @@ public class CommandHandler : IDisposable
if( !CollectionTypeExtensions.TryParse( typeName, out var type ) ) if( !CollectionTypeExtensions.TryParse( typeName, out var type ) )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddText( "The argument " ).AddRed( typeName, true ).AddText( " is not a valid collection type." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddText( "The argument " ).AddRed( typeName, true ).AddText( " is not a valid collection type." ).BuiltString );
return false; return false;
} }
if( split.Length == 1 ) if( split.Length == 1 )
{ {
Dalamud.Chat.Print( "There was no collection name provided." ); DalamudServices.Chat.Print( "There was no collection name provided." );
return false; return false;
} }
@ -289,7 +290,7 @@ public class CommandHandler : IDisposable
{ {
if( split.Length == 2 ) if( split.Length == 2 )
{ {
Dalamud.Chat.Print( "Setting an individual collection requires a collection name and an identifier, but no identifier was provided." ); DalamudServices.Chat.Print( "Setting an individual collection requires a collection name and an identifier, but no identifier was provided." );
return false; return false;
} }
@ -300,7 +301,7 @@ public class CommandHandler : IDisposable
identifier = _actors.FromObject( obj, false, true, true ); identifier = _actors.FromObject( obj, false, true, true );
if( !identifier.IsValid ) if( !identifier.IsValid )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddText( "The placeholder " ).AddGreen( split[ 2 ] ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( "The placeholder " ).AddGreen( split[ 2 ] )
.AddText( " did not resolve to a game object with a valid identifier." ).BuiltString ); .AddText( " did not resolve to a game object with a valid identifier." ).BuiltString );
return false; return false;
} }
@ -312,7 +313,7 @@ public class CommandHandler : IDisposable
} }
catch( ActorManager.IdentifierParseError e ) catch( ActorManager.IdentifierParseError e )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddText( "The argument " ).AddRed( split[ 2 ], true ).AddText( $" could not be converted to an identifier. {e.Message}" ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( "The argument " ).AddRed( split[ 2 ], true ).AddText( $" could not be converted to an identifier. {e.Message}" )
.BuiltString ); .BuiltString );
return false; return false;
} }
@ -321,7 +322,7 @@ public class CommandHandler : IDisposable
var oldCollection = _collectionManager.ByType( type, identifier ); var oldCollection = _collectionManager.ByType( type, identifier );
if( collection == oldCollection ) if( collection == oldCollection )
{ {
Dalamud.Chat.Print( collection == null DalamudServices.Chat.Print( collection == null
? $"The {type.ToName()} Collection{( identifier.IsValid ? $" for {identifier}" : string.Empty )} is already unassigned" ? $"The {type.ToName()} Collection{( identifier.IsValid ? $" for {identifier}" : string.Empty )} is already unassigned"
: $"{collection.Name} already is the {type.ToName()} Collection{( identifier.IsValid ? $" for {identifier}." : "." )}" ); : $"{collection.Name} already is the {type.ToName()} Collection{( identifier.IsValid ? $" for {identifier}." : "." )}" );
return false; return false;
@ -354,7 +355,7 @@ public class CommandHandler : IDisposable
} }
else else
{ {
Dalamud.Chat.Print( $"Can not remove the {type.ToName()} Collection assignment {( identifier.IsValid ? $" for {identifier}." : "." )}" ); DalamudServices.Chat.Print( $"Can not remove the {type.ToName()} Collection assignment {( identifier.IsValid ? $" for {identifier}." : "." )}" );
return false; return false;
} }
@ -374,7 +375,7 @@ public class CommandHandler : IDisposable
var seString = new SeStringBuilder() var seString = new SeStringBuilder()
.AddText( "Use with /penumbra mod " ).AddBlue( "[enable|disable|inherit|toggle]" ).AddText( " " ).AddYellow( "[Collection Name]" ).AddText( " | " ) .AddText( "Use with /penumbra mod " ).AddBlue( "[enable|disable|inherit|toggle]" ).AddText( " " ).AddYellow( "[Collection Name]" ).AddText( " | " )
.AddPurple( "[Mod Name or Mod Directory Name]" ); .AddPurple( "[Mod Name or Mod Directory Name]" );
Dalamud.Chat.Print( seString.BuiltString ); DalamudServices.Chat.Print( seString.BuiltString );
return true; return true;
} }
@ -382,14 +383,14 @@ public class CommandHandler : IDisposable
var nameSplit = split.Length != 2 ? Array.Empty< string >() : split[ 1 ].Split( '|', 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries ); var nameSplit = split.Length != 2 ? Array.Empty< string >() : split[ 1 ].Split( '|', 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries );
if( nameSplit.Length != 2 ) if( nameSplit.Length != 2 )
{ {
Dalamud.Chat.Print( "Not enough arguments provided." ); DalamudServices.Chat.Print( "Not enough arguments provided." );
return false; return false;
} }
var state = ConvertToSettingState( split[ 0 ] ); var state = ConvertToSettingState( split[ 0 ] );
if( state == -1 ) if( state == -1 )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddRed( split[ 0 ], true ).AddText( " is not a valid type of setting." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddRed( split[ 0 ], true ).AddText( " is not a valid type of setting." ).BuiltString );
return false; return false;
} }
@ -400,7 +401,7 @@ public class CommandHandler : IDisposable
if( !_modManager.TryGetMod( nameSplit[ 1 ], nameSplit[ 1 ], out var mod ) ) if( !_modManager.TryGetMod( nameSplit[ 1 ], nameSplit[ 1 ], out var mod ) )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddText( "The mod " ).AddRed( nameSplit[ 1 ], true ).AddText( " does not exist." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddText( "The mod " ).AddRed( nameSplit[ 1 ], true ).AddText( " does not exist." ).BuiltString );
return false; return false;
} }
@ -409,7 +410,7 @@ public class CommandHandler : IDisposable
return true; return true;
} }
Dalamud.Chat.Print( new SeStringBuilder().AddText( "Mod " ).AddPurple( mod.Name, true ).AddText( "already had the desired state in collection " ) DalamudServices.Chat.Print( new SeStringBuilder().AddText( "Mod " ).AddPurple( mod.Name, true ).AddText( "already had the desired state in collection " )
.AddYellow( collection!.Name, true ).AddText( "." ).BuiltString ); .AddYellow( collection!.Name, true ).AddText( "." ).BuiltString );
return false; return false;
} }
@ -421,7 +422,7 @@ public class CommandHandler : IDisposable
var seString = new SeStringBuilder() var seString = new SeStringBuilder()
.AddText( "Use with /penumbra bulktag " ).AddBlue( "[enable|disable|toggle|inherit]" ).AddText( " " ).AddYellow( "[Collection Name]" ).AddText( " | " ) .AddText( "Use with /penumbra bulktag " ).AddBlue( "[enable|disable|toggle|inherit]" ).AddText( " " ).AddYellow( "[Collection Name]" ).AddText( " | " )
.AddPurple( "[Local Tag]" ); .AddPurple( "[Local Tag]" );
Dalamud.Chat.Print( seString.BuiltString ); DalamudServices.Chat.Print( seString.BuiltString );
return true; return true;
} }
@ -429,7 +430,7 @@ public class CommandHandler : IDisposable
var nameSplit = split.Length != 2 ? Array.Empty< string >() : split[ 1 ].Split( '|', 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries ); var nameSplit = split.Length != 2 ? Array.Empty< string >() : split[ 1 ].Split( '|', 2, StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries );
if( nameSplit.Length != 2 ) if( nameSplit.Length != 2 )
{ {
Dalamud.Chat.Print( "Not enough arguments provided." ); DalamudServices.Chat.Print( "Not enough arguments provided." );
return false; return false;
} }
@ -437,7 +438,7 @@ public class CommandHandler : IDisposable
if( state == -1 ) if( state == -1 )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddRed( split[ 0 ], true ).AddText( " is not a valid type of setting." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddRed( split[ 0 ], true ).AddText( " is not a valid type of setting." ).BuiltString );
return false; return false;
} }
@ -450,7 +451,7 @@ public class CommandHandler : IDisposable
if( mods.Count == 0 ) if( mods.Count == 0 )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddText( "The tag " ).AddRed( nameSplit[ 1 ], true ).AddText( " does not match any mods." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddText( "The tag " ).AddRed( nameSplit[ 1 ], true ).AddText( " does not match any mods." ).BuiltString );
return false; return false;
} }
@ -482,7 +483,7 @@ public class CommandHandler : IDisposable
: _collectionManager[ lowerName ]; : _collectionManager[ lowerName ];
if( collection == null ) if( collection == null )
{ {
Dalamud.Chat.Print( new SeStringBuilder().AddText( "The collection " ).AddRed( collectionName, true ).AddText( " does not exist." ).BuiltString ); DalamudServices.Chat.Print( new SeStringBuilder().AddText( "The collection " ).AddRed( collectionName, true ).AddText( " does not exist." ).BuiltString );
return false; return false;
} }
@ -574,7 +575,7 @@ public class CommandHandler : IDisposable
{ {
if( Penumbra.Config.PrintSuccessfulCommandsToChat ) if( Penumbra.Config.PrintSuccessfulCommandsToChat )
{ {
Dalamud.Chat.Print( text ); DalamudServices.Chat.Print( text );
} }
} }
@ -582,7 +583,7 @@ public class CommandHandler : IDisposable
{ {
if( Penumbra.Config.PrintSuccessfulCommandsToChat ) if( Penumbra.Config.PrintSuccessfulCommandsToChat )
{ {
Dalamud.Chat.Print( text.ToStringAndClear() ); DalamudServices.Chat.Print( text.ToStringAndClear() );
} }
} }
@ -590,7 +591,7 @@ public class CommandHandler : IDisposable
{ {
if( Penumbra.Config.PrintSuccessfulCommandsToChat ) if( Penumbra.Config.PrintSuccessfulCommandsToChat )
{ {
Dalamud.Chat.Print( text() ); DalamudServices.Chat.Print( text() );
} }
} }
} }

View file

@ -7,7 +7,8 @@ using Newtonsoft.Json.Linq;
using OtterGui.Filesystem; using OtterGui.Filesystem;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Services;
namespace Penumbra; namespace Penumbra;
public partial class Configuration public partial class Configuration
@ -30,7 +31,7 @@ public partial class Configuration
public static void Migrate( Configuration config ) public static void Migrate( Configuration config )
{ {
if( !File.Exists( Dalamud.PluginInterface.ConfigFile.FullName ) ) if( !File.Exists( DalamudServices.PluginInterface.ConfigFile.FullName ) )
{ {
return; return;
} }
@ -38,7 +39,7 @@ public partial class Configuration
var m = new Migration var m = new Migration
{ {
_config = config, _config = config,
_data = JObject.Parse( File.ReadAllText( Dalamud.PluginInterface.ConfigFile.FullName ) ), _data = JObject.Parse( File.ReadAllText( DalamudServices.PluginInterface.ConfigFile.FullName ) ),
}; };
CreateBackup(); CreateBackup();
@ -342,7 +343,7 @@ public partial class Configuration
// Create a backup of the configuration file specifically. // Create a backup of the configuration file specifically.
private static void CreateBackup() private static void CreateBackup()
{ {
var name = Dalamud.PluginInterface.ConfigFile.FullName; var name = DalamudServices.PluginInterface.ConfigFile.FullName;
var bakName = name + ".bak"; var bakName = name + ".bak";
try try
{ {

View file

@ -11,6 +11,7 @@ using OtterGui.Widgets;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.Import; using Penumbra.Import;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI; using Penumbra.UI;
using Penumbra.UI.Classes; using Penumbra.UI.Classes;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs; using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
@ -97,9 +98,9 @@ public partial class Configuration : IPluginConfiguration
} }
Configuration? configuration = null; Configuration? configuration = null;
if( File.Exists( Dalamud.PluginInterface.ConfigFile.FullName ) ) if( File.Exists( DalamudServices.PluginInterface.ConfigFile.FullName ) )
{ {
var text = File.ReadAllText( Dalamud.PluginInterface.ConfigFile.FullName ); var text = File.ReadAllText( DalamudServices.PluginInterface.ConfigFile.FullName );
configuration = JsonConvert.DeserializeObject< Configuration >( text, new JsonSerializerSettings configuration = JsonConvert.DeserializeObject< Configuration >( text, new JsonSerializerSettings
{ {
Error = HandleDeserializationError, Error = HandleDeserializationError,
@ -125,7 +126,7 @@ public partial class Configuration : IPluginConfiguration
try try
{ {
var text = JsonConvert.SerializeObject( this, Formatting.Indented ); var text = JsonConvert.SerializeObject( this, Formatting.Indented );
File.WriteAllText( Dalamud.PluginInterface.ConfigFile.FullName, text ); File.WriteAllText( DalamudServices.PluginInterface.ConfigFile.FullName, text );
} }
catch( Exception e ) catch( Exception e )
{ {

View file

@ -1,150 +0,0 @@
using System;
using Dalamud.Data;
using Dalamud.Game;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.Interface;
using Dalamud.IoC;
using Dalamud.Plugin;
using System.Linq;
using System.Reflection;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
namespace Penumbra;
public class Dalamud
{
public static void Initialize( DalamudPluginInterface pluginInterface )
=> pluginInterface.Create< Dalamud >();
// @formatter:off
[PluginService][RequiredVersion("1.0")] public static DalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static CommandManager Commands { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static DataManager GameData { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static ClientState ClientState { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static ChatGui Chat { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static Framework Framework { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static Condition Conditions { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static TargetManager Targets { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static ObjectTable Objects { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static TitleScreenMenu TitleScreenMenu { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static GameGui GameGui { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static KeyState KeyState { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public static SigScanner SigScanner { get; private set; } = null!;
// @formatter:on
private static readonly object? DalamudConfig;
private static readonly MethodInfo? InterfaceGetter;
private static readonly MethodInfo? SaveDalamudConfig;
public const string WaitingForPluginsOption = "IsResumeGameAfterPluginLoad";
static Dalamud()
{
try
{
var serviceType = typeof( DalamudPluginInterface ).Assembly.DefinedTypes.FirstOrDefault( t => t.Name == "Service`1" && t.IsGenericType );
var configType = typeof( DalamudPluginInterface ).Assembly.DefinedTypes.FirstOrDefault( t => t.Name == "DalamudConfiguration" );
var interfaceType = typeof( DalamudPluginInterface ).Assembly.DefinedTypes.FirstOrDefault( t => t.Name == "DalamudInterface" );
if( serviceType == null || configType == null || interfaceType == null )
{
return;
}
var configService = serviceType.MakeGenericType( configType );
var interfaceService = serviceType.MakeGenericType( interfaceType );
var configGetter = configService.GetMethod( "Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic );
InterfaceGetter = interfaceService.GetMethod( "Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic );
if( configGetter == null || InterfaceGetter == null )
{
return;
}
DalamudConfig = configGetter.Invoke( null, null );
if( DalamudConfig != null )
{
SaveDalamudConfig = DalamudConfig.GetType().GetMethod( "Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
if( SaveDalamudConfig == null )
{
DalamudConfig = null;
InterfaceGetter = null;
}
}
}
catch
{
DalamudConfig = null;
SaveDalamudConfig = null;
InterfaceGetter = null;
}
}
public static bool GetDalamudConfig< T >( string fieldName, out T? value )
{
value = default;
try
{
if( DalamudConfig == null )
{
return false;
}
var getter = DalamudConfig.GetType().GetProperty( fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
if( getter == null )
{
return false;
}
var result = getter.GetValue( DalamudConfig );
if( result is not T v )
{
return false;
}
value = v;
return true;
}
catch( Exception e )
{
Penumbra.Log.Error( $"Error while fetching Dalamud Config {fieldName}:\n{e}" );
return false;
}
}
public static bool SetDalamudConfig< T >( string fieldName, in T? value, string? windowFieldName = null )
{
try
{
if( DalamudConfig == null )
{
return false;
}
var getter = DalamudConfig.GetType().GetProperty( fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic );
if( getter == null )
{
return false;
}
getter.SetValue( DalamudConfig, value );
if( windowFieldName != null )
{
var inter = InterfaceGetter!.Invoke( null, null );
var settingsWindow = inter?.GetType().GetField( "settingsWindow", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic )?.GetValue( inter );
settingsWindow?.GetType().GetField( windowFieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic )?.SetValue( settingsWindow, value );
}
SaveDalamudConfig!.Invoke( DalamudConfig, null );
return true;
}
catch( Exception e )
{
Penumbra.Log.Error( $"Error while fetching Dalamud Config {fieldName}:\n{e}" );
return false;
}
}
}

View file

@ -3,6 +3,7 @@ using System.IO;
using System.Numerics; using System.Numerics;
using Lumina.Data.Files; using Lumina.Data.Files;
using OtterTex; using OtterTex;
using Penumbra.Services;
using SixLabors.ImageSharp; using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png; using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -48,7 +49,7 @@ public partial class CombinedTexture : IDisposable
{ {
var (width, height) = CombineImage(); var (width, height) = CombineImage();
_centerStorage.TextureWrap = _centerStorage.TextureWrap =
Dalamud.PluginInterface.UiBuilder.LoadImageRaw( _centerStorage.RGBAPixels, width, height, 4 ); DalamudServices.PluginInterface.UiBuilder.LoadImageRaw( _centerStorage.RGBAPixels, width, height, 4 );
} }
_current?.Draw( size ); _current?.Draw( size );

View file

@ -10,6 +10,7 @@ using Lumina.Data.Files;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterTex; using OtterTex;
using Penumbra.Services;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.UI.Classes; using Penumbra.UI.Classes;
using SixLabors.ImageSharp.PixelFormats; using SixLabors.ImageSharp.PixelFormats;
@ -195,12 +196,12 @@ public sealed class Texture : IDisposable
return File.OpenRead( Path ); return File.OpenRead( Path );
} }
var file = Dalamud.GameData.GetFile( Path ); var file = DalamudServices.GameData.GetFile( Path );
return file != null ? new MemoryStream( file.Data ) : throw new Exception( $"Unable to obtain \"{Path}\" from game files." ); return file != null ? new MemoryStream( file.Data ) : throw new Exception( $"Unable to obtain \"{Path}\" from game files." );
} }
private void CreateTextureWrap( int width, int height ) private void CreateTextureWrap( int width, int height )
=> TextureWrap = Dalamud.PluginInterface.UiBuilder.LoadImageRaw( RGBAPixels, width, height, 4 ); => TextureWrap = DalamudServices.PluginInterface.UiBuilder.LoadImageRaw( RGBAPixels, width, height, 4 );
private string? _tmpPath; private string? _tmpPath;
@ -215,7 +216,7 @@ public sealed class Texture : IDisposable
{ {
if( game ) if( game )
{ {
if( !Dalamud.GameData.FileExists( path ) ) if( !DalamudServices.GameData.FileExists( path ) )
{ {
continue; continue;
} }

View file

@ -3,7 +3,8 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using Dalamud.Utility.Signatures; using Dalamud.Utility.Signatures;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.Services;
namespace Penumbra.Interop; namespace Penumbra.Interop;
public unsafe partial class CharacterUtility : IDisposable public unsafe partial class CharacterUtility : IDisposable
@ -58,7 +59,7 @@ public unsafe partial class CharacterUtility : IDisposable
LoadDefaultResources( null! ); LoadDefaultResources( null! );
if( !Ready ) if( !Ready )
{ {
Dalamud.Framework.Update += LoadDefaultResources; DalamudServices.Framework.Update += LoadDefaultResources;
} }
} }
@ -98,7 +99,7 @@ public unsafe partial class CharacterUtility : IDisposable
if( !anyMissing ) if( !anyMissing )
{ {
Ready = true; Ready = true;
Dalamud.Framework.Update -= LoadDefaultResources; DalamudServices.Framework.Update -= LoadDefaultResources;
LoadingFinished.Invoke(); LoadingFinished.Invoke();
} }
} }

View file

@ -4,18 +4,22 @@ using Penumbra.GameData;
using System; using System;
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object; using FFXIVClientStructs.FFXIV.Client.Game.Object;
using OtterGui.Log;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
namespace Penumbra.Interop; namespace Penumbra.Interop;
public unsafe class GameEventManager : IDisposable public unsafe class GameEventManager : IDisposable
{ {
private const string Prefix = $"[{nameof(GameEventManager)}]";
public GameEventManager() public GameEventManager()
{ {
SignatureHelper.Initialise( this ); SignatureHelper.Initialise(this);
_characterDtorHook.Enable(); _characterDtorHook.Enable();
_copyCharacterHook.Enable(); _copyCharacterHook.Enable();
_resourceHandleDestructorHook.Enable(); _resourceHandleDestructorHook.Enable();
Penumbra.Log.Verbose($"{Prefix} Created.");
} }
public void Dispose() public void Dispose()
@ -23,104 +27,102 @@ public unsafe class GameEventManager : IDisposable
_characterDtorHook.Dispose(); _characterDtorHook.Dispose();
_copyCharacterHook.Dispose(); _copyCharacterHook.Dispose();
_resourceHandleDestructorHook.Dispose(); _resourceHandleDestructorHook.Dispose();
Penumbra.Log.Verbose($"{Prefix} Disposed.");
} }
#region Character Destructor #region Character Destructor
private delegate void CharacterDestructorDelegate( Character* character ); private delegate void CharacterDestructorDelegate(Character* character);
[Signature( Sigs.CharacterDestructor, DetourName = nameof( CharacterDestructorDetour ) )] [Signature(Sigs.CharacterDestructor, DetourName = nameof(CharacterDestructorDetour))]
private readonly Hook< CharacterDestructorDelegate > _characterDtorHook = null!; private readonly Hook<CharacterDestructorDelegate> _characterDtorHook = null!;
private void CharacterDestructorDetour( Character* character ) private void CharacterDestructorDetour(Character* character)
{ {
if( CharacterDestructor != null ) if (CharacterDestructor != null)
{ foreach (var subscriber in CharacterDestructor.GetInvocationList())
foreach( var subscriber in CharacterDestructor.GetInvocationList() )
{ {
try try
{ {
( ( CharacterDestructorEvent )subscriber ).Invoke( character ); ((CharacterDestructorEvent)subscriber).Invoke(character);
} }
catch( Exception ex ) catch (Exception ex)
{ {
Penumbra.Log.Error( $"Error in {nameof( CharacterDestructor )} event when executing {subscriber.Method.Name}:\n{ex}" ); Penumbra.Log.Error($"{Prefix} Error in {nameof(CharacterDestructor)} event when executing {subscriber.Method.Name}:\n{ex}");
} }
} }
}
Penumbra.Log.Verbose( $"{nameof( CharacterDestructor )} triggered with 0x{( nint )character:X}." ); Penumbra.Log.Verbose($"{Prefix} {nameof(CharacterDestructor)} triggered with 0x{(nint)character:X}.");
_characterDtorHook.Original( character ); _characterDtorHook.Original(character);
} }
public delegate void CharacterDestructorEvent( Character* character ); public delegate void CharacterDestructorEvent(Character* character);
public event CharacterDestructorEvent? CharacterDestructor; public event CharacterDestructorEvent? CharacterDestructor;
#endregion #endregion
#region Copy Character #region Copy Character
private unsafe delegate ulong CopyCharacterDelegate( GameObject* target, GameObject* source, uint unk ); private unsafe delegate ulong CopyCharacterDelegate(GameObject* target, GameObject* source, uint unk);
[Signature( Sigs.CopyCharacter, DetourName = nameof( CopyCharacterDetour ) )] [Signature(Sigs.CopyCharacter, DetourName = nameof(CopyCharacterDetour))]
private readonly Hook< CopyCharacterDelegate > _copyCharacterHook = null!; private readonly Hook<CopyCharacterDelegate> _copyCharacterHook = null!;
private ulong CopyCharacterDetour( GameObject* target, GameObject* source, uint unk ) private ulong CopyCharacterDetour(GameObject* target, GameObject* source, uint unk)
{ {
if( CopyCharacter != null ) if (CopyCharacter != null)
{ foreach (var subscriber in CopyCharacter.GetInvocationList())
foreach( var subscriber in CopyCharacter.GetInvocationList() )
{ {
try try
{ {
( ( CopyCharacterEvent )subscriber ).Invoke( ( Character* )target, ( Character* )source ); ((CopyCharacterEvent)subscriber).Invoke((Character*)target, (Character*)source);
} }
catch( Exception ex ) catch (Exception ex)
{ {
Penumbra.Log.Error( $"Error in {nameof( CopyCharacter )} event when executing {subscriber.Method.Name}:\n{ex}" ); Penumbra.Log.Error(
$"{Prefix} Error in {nameof(CopyCharacter)} event when executing {subscriber.Method.Name}:\n{ex}");
} }
} }
}
Penumbra.Log.Verbose( $"{nameof( CopyCharacter )} triggered with target 0x{( nint )target:X} and source 0x{( nint )source:X}." ); Penumbra.Log.Verbose(
return _copyCharacterHook.Original( target, source, unk ); $"{Prefix} {nameof(CopyCharacter)} triggered with target 0x{(nint)target:X} and source 0x{(nint)source:X}.");
return _copyCharacterHook.Original(target, source, unk);
} }
public delegate void CopyCharacterEvent( Character* target, Character* source ); public delegate void CopyCharacterEvent(Character* target, Character* source);
public event CopyCharacterEvent? CopyCharacter; public event CopyCharacterEvent? CopyCharacter;
#endregion #endregion
#region ResourceHandle Destructor #region ResourceHandle Destructor
private delegate IntPtr ResourceHandleDestructorDelegate( ResourceHandle* handle ); private delegate IntPtr ResourceHandleDestructorDelegate(ResourceHandle* handle);
[Signature( Sigs.ResourceHandleDestructor, DetourName = nameof( ResourceHandleDestructorDetour ) )] [Signature(Sigs.ResourceHandleDestructor, DetourName = nameof(ResourceHandleDestructorDetour))]
private readonly Hook< ResourceHandleDestructorDelegate > _resourceHandleDestructorHook = null!; private readonly Hook<ResourceHandleDestructorDelegate> _resourceHandleDestructorHook = null!;
private IntPtr ResourceHandleDestructorDetour( ResourceHandle* handle ) private IntPtr ResourceHandleDestructorDetour(ResourceHandle* handle)
{ {
if( ResourceHandleDestructor != null ) if (ResourceHandleDestructor != null)
{ foreach (var subscriber in ResourceHandleDestructor.GetInvocationList())
foreach( var subscriber in ResourceHandleDestructor.GetInvocationList() )
{ {
try try
{ {
( ( ResourceHandleDestructorEvent )subscriber ).Invoke( handle ); ((ResourceHandleDestructorEvent)subscriber).Invoke(handle);
} }
catch( Exception ex ) catch (Exception ex)
{ {
Penumbra.Log.Error( $"Error in {nameof( ResourceHandleDestructor )} event when executing {subscriber.Method.Name}:\n{ex}" ); Penumbra.Log.Error(
$"{Prefix} Error in {nameof(ResourceHandleDestructor)} event when executing {subscriber.Method.Name}:\n{ex}");
} }
} }
}
Penumbra.Log.Verbose( $"{nameof( ResourceHandleDestructor )} triggered with 0x{( nint )handle:X}." ); Penumbra.Log.Verbose($"{Prefix} {nameof(ResourceHandleDestructor)} triggered with 0x{(nint)handle:X}.");
return _resourceHandleDestructorHook!.Original( handle ); return _resourceHandleDestructorHook!.Original(handle);
} }
public delegate void ResourceHandleDestructorEvent( ResourceHandle* handle ); public delegate void ResourceHandleDestructorEvent(ResourceHandle* handle);
public event ResourceHandleDestructorEvent? ResourceHandleDestructor; public event ResourceHandleDestructorEvent? ResourceHandleDestructor;
#endregion #endregion
} }

View file

@ -10,7 +10,8 @@ using Penumbra.Api.Enums;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Services;
namespace Penumbra.Interop; namespace Penumbra.Interop;
public unsafe partial class ObjectReloader public unsafe partial class ObjectReloader
@ -34,7 +35,7 @@ public unsafe partial class ObjectReloader
// Also clear the name list. // Also clear the name list.
private void SetGPose() private void SetGPose()
{ {
_inGPose = Dalamud.Objects[ GPosePlayerIdx ] != null; _inGPose = DalamudServices.Objects[ GPosePlayerIdx ] != null;
_gPoseNameCounter = 0; _gPoseNameCounter = 0;
} }
@ -49,7 +50,7 @@ public unsafe partial class ObjectReloader
// this will be in obj and true will be returned. // this will be in obj and true will be returned.
private bool FindCorrectActor( int idx, out GameObject? obj ) private bool FindCorrectActor( int idx, out GameObject? obj )
{ {
obj = Dalamud.Objects[ idx ]; obj = DalamudServices.Objects[ idx ];
if( !_inGPose || obj == null || IsGPoseActor( idx ) ) if( !_inGPose || obj == null || IsGPoseActor( idx ) )
{ {
return false; return false;
@ -66,14 +67,14 @@ public unsafe partial class ObjectReloader
if( name == gPoseName ) if( name == gPoseName )
{ {
obj = Dalamud.Objects[ GPosePlayerIdx + i ]; obj = DalamudServices.Objects[ GPosePlayerIdx + i ];
return true; return true;
} }
} }
for( ; _gPoseNameCounter < GPoseSlots; ++_gPoseNameCounter ) for( ; _gPoseNameCounter < GPoseSlots; ++_gPoseNameCounter )
{ {
var gPoseName = Dalamud.Objects[ GPosePlayerIdx + _gPoseNameCounter ]?.Name.ToString(); var gPoseName = DalamudServices.Objects[ GPosePlayerIdx + _gPoseNameCounter ]?.Name.ToString();
_gPoseNames[ _gPoseNameCounter ] = gPoseName; _gPoseNames[ _gPoseNameCounter ] = gPoseName;
if( gPoseName == null ) if( gPoseName == null )
{ {
@ -82,7 +83,7 @@ public unsafe partial class ObjectReloader
if( name == gPoseName ) if( name == gPoseName )
{ {
obj = Dalamud.Objects[ GPosePlayerIdx + _gPoseNameCounter ]; obj = DalamudServices.Objects[ GPosePlayerIdx + _gPoseNameCounter ];
return true; return true;
} }
} }
@ -113,10 +114,10 @@ public sealed unsafe partial class ObjectReloader : IDisposable
public event GameObjectRedrawnDelegate? GameObjectRedrawn; public event GameObjectRedrawnDelegate? GameObjectRedrawn;
public ObjectReloader() public ObjectReloader()
=> Dalamud.Framework.Update += OnUpdateEvent; => DalamudServices.Framework.Update += OnUpdateEvent;
public void Dispose() public void Dispose()
=> Dalamud.Framework.Update -= OnUpdateEvent; => DalamudServices.Framework.Update -= OnUpdateEvent;
public static DrawState* ActorDrawState( GameObject actor ) public static DrawState* ActorDrawState( GameObject actor )
=> ( DrawState* )( &( ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )actor.Address )->RenderFlags ); => ( DrawState* )( &( ( FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* )actor.Address )->RenderFlags );
@ -139,7 +140,7 @@ public sealed unsafe partial class ObjectReloader : IDisposable
DisableDraw( actor! ); DisableDraw( actor! );
} }
if( actor is PlayerCharacter && Dalamud.Objects[ tableIndex + 1 ] is { ObjectKind: ObjectKind.MountType } mount ) if( actor is PlayerCharacter && DalamudServices.Objects[ tableIndex + 1 ] is { ObjectKind: ObjectKind.MountType } mount )
{ {
*ActorDrawState( mount ) |= DrawState.Invisibility; *ActorDrawState( mount ) |= DrawState.Invisibility;
if( gPose ) if( gPose )
@ -164,7 +165,7 @@ public sealed unsafe partial class ObjectReloader : IDisposable
EnableDraw( actor! ); EnableDraw( actor! );
} }
if( actor is PlayerCharacter && Dalamud.Objects[ tableIndex + 1 ] is { ObjectKind: ObjectKind.MountType } mount ) if( actor is PlayerCharacter && DalamudServices.Objects[ tableIndex + 1 ] is { ObjectKind: ObjectKind.MountType } mount )
{ {
*ActorDrawState( mount ) &= ~DrawState.Invisibility; *ActorDrawState( mount ) &= ~DrawState.Invisibility;
if( gPose ) if( gPose )
@ -183,7 +184,7 @@ public sealed unsafe partial class ObjectReloader : IDisposable
return; return;
} }
if( actor!.Address == Dalamud.Targets.Target?.Address ) if( actor!.Address == DalamudServices.Targets.Target?.Address )
{ {
_target = tableIndex; _target = tableIndex;
} }
@ -193,7 +194,7 @@ public sealed unsafe partial class ObjectReloader : IDisposable
private void ReloadActorAfterGPose( GameObject? actor ) private void ReloadActorAfterGPose( GameObject? actor )
{ {
if( Dalamud.Objects[ GPosePlayerIdx ] != null ) if( DalamudServices.Objects[ GPosePlayerIdx ] != null )
{ {
ReloadActor( actor ); ReloadActor( actor );
return; return;
@ -213,13 +214,13 @@ public sealed unsafe partial class ObjectReloader : IDisposable
return; return;
} }
var actor = Dalamud.Objects[ _target ]; var actor = DalamudServices.Objects[ _target ];
if( actor == null || Dalamud.Targets.Target != null ) if( actor == null || DalamudServices.Targets.Target != null )
{ {
return; return;
} }
Dalamud.Targets.SetTarget( actor ); DalamudServices.Targets.SetTarget( actor );
_target = -1; _target = -1;
} }
@ -270,12 +271,12 @@ public sealed unsafe partial class ObjectReloader : IDisposable
if( idx < 0 ) if( idx < 0 )
{ {
var newIdx = ~idx; var newIdx = ~idx;
WriteInvisible( Dalamud.Objects[ newIdx ] ); WriteInvisible( DalamudServices.Objects[ newIdx ] );
_afterGPoseQueue[ numKept++ ] = newIdx; _afterGPoseQueue[ numKept++ ] = newIdx;
} }
else else
{ {
WriteVisible( Dalamud.Objects[ idx ] ); WriteVisible( DalamudServices.Objects[ idx ] );
} }
} }
@ -284,9 +285,9 @@ public sealed unsafe partial class ObjectReloader : IDisposable
private void OnUpdateEvent( object framework ) private void OnUpdateEvent( object framework )
{ {
if( Dalamud.Conditions[ ConditionFlag.BetweenAreas51 ] if( DalamudServices.Conditions[ ConditionFlag.BetweenAreas51 ]
|| Dalamud.Conditions[ ConditionFlag.BetweenAreas ] || DalamudServices.Conditions[ ConditionFlag.BetweenAreas ]
|| Dalamud.Conditions[ ConditionFlag.OccupiedInCutSceneEvent ] ) || DalamudServices.Conditions[ ConditionFlag.OccupiedInCutSceneEvent ] )
{ {
return; return;
} }
@ -313,8 +314,8 @@ public sealed unsafe partial class ObjectReloader : IDisposable
private static GameObject? GetLocalPlayer() private static GameObject? GetLocalPlayer()
{ {
var gPosePlayer = Dalamud.Objects[ GPosePlayerIdx ]; var gPosePlayer = DalamudServices.Objects[ GPosePlayerIdx ];
return gPosePlayer ?? Dalamud.Objects[ 0 ]; return gPosePlayer ?? DalamudServices.Objects[ 0 ];
} }
public static bool GetName( string lowerName, out GameObject? actor ) public static bool GetName( string lowerName, out GameObject? actor )
@ -324,12 +325,12 @@ public sealed unsafe partial class ObjectReloader : IDisposable
"" => ( null, true ), "" => ( null, true ),
"<me>" => ( GetLocalPlayer(), true ), "<me>" => ( GetLocalPlayer(), true ),
"self" => ( GetLocalPlayer(), true ), "self" => ( GetLocalPlayer(), true ),
"<t>" => ( Dalamud.Targets.Target, true ), "<t>" => ( DalamudServices.Targets.Target, true ),
"target" => ( Dalamud.Targets.Target, true ), "target" => ( DalamudServices.Targets.Target, true ),
"<f>" => ( Dalamud.Targets.FocusTarget, true ), "<f>" => ( DalamudServices.Targets.FocusTarget, true ),
"focus" => ( Dalamud.Targets.FocusTarget, true ), "focus" => ( DalamudServices.Targets.FocusTarget, true ),
"<mo>" => ( Dalamud.Targets.MouseOverTarget, true ), "<mo>" => ( DalamudServices.Targets.MouseOverTarget, true ),
"mouseover" => ( Dalamud.Targets.MouseOverTarget, true ), "mouseover" => ( DalamudServices.Targets.MouseOverTarget, true ),
_ => ( null, false ), _ => ( null, false ),
}; };
return ret; return ret;
@ -337,9 +338,9 @@ public sealed unsafe partial class ObjectReloader : IDisposable
public void RedrawObject( int tableIndex, RedrawType settings ) public void RedrawObject( int tableIndex, RedrawType settings )
{ {
if( tableIndex >= 0 && tableIndex < Dalamud.Objects.Length ) if( tableIndex >= 0 && tableIndex < DalamudServices.Objects.Length )
{ {
RedrawObject( Dalamud.Objects[ tableIndex ], settings ); RedrawObject( DalamudServices.Objects[ tableIndex ], settings );
} }
} }
@ -352,7 +353,7 @@ public sealed unsafe partial class ObjectReloader : IDisposable
} }
else else
{ {
foreach( var actor in Dalamud.Objects.Where( a => a.Name.ToString().ToLowerInvariant() == lowerName ) ) foreach( var actor in DalamudServices.Objects.Where( a => a.Name.ToString().ToLowerInvariant() == lowerName ) )
{ {
RedrawObject( actor, settings ); RedrawObject( actor, settings );
} }
@ -361,7 +362,7 @@ public sealed unsafe partial class ObjectReloader : IDisposable
public void RedrawAll( RedrawType settings ) public void RedrawAll( RedrawType settings )
{ {
foreach( var actor in Dalamud.Objects ) foreach( var actor in DalamudServices.Objects )
{ {
RedrawObject( actor, settings ); RedrawObject( actor, settings );
} }

View file

@ -3,7 +3,8 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using FFXIVClientStructs.FFXIV.Client.Game.Character; using FFXIVClientStructs.FFXIV.Client.Game.Character;
using Penumbra.Services;
namespace Penumbra.Interop.Resolver; namespace Penumbra.Interop.Resolver;
public class CutsceneCharacters : IDisposable public class CutsceneCharacters : IDisposable
@ -17,8 +18,8 @@ public class CutsceneCharacters : IDisposable
public IEnumerable< KeyValuePair< int, global::Dalamud.Game.ClientState.Objects.Types.GameObject > > Actors public IEnumerable< KeyValuePair< int, global::Dalamud.Game.ClientState.Objects.Types.GameObject > > Actors
=> Enumerable.Range( CutsceneStartIdx, CutsceneSlots ) => Enumerable.Range( CutsceneStartIdx, CutsceneSlots )
.Where( i => Dalamud.Objects[ i ] != null ) .Where( i => DalamudServices.Objects[ i ] != null )
.Select( i => KeyValuePair.Create( i, this[ i ] ?? Dalamud.Objects[ i ]! ) ); .Select( i => KeyValuePair.Create( i, this[ i ] ?? DalamudServices.Objects[ i ]! ) );
public CutsceneCharacters(GameEventManager events) public CutsceneCharacters(GameEventManager events)
{ {
@ -35,7 +36,7 @@ public class CutsceneCharacters : IDisposable
{ {
Debug.Assert( idx is >= CutsceneStartIdx and < CutsceneEndIdx ); Debug.Assert( idx is >= CutsceneStartIdx and < CutsceneEndIdx );
idx = _copiedCharacters[ idx - CutsceneStartIdx ]; idx = _copiedCharacters[ idx - CutsceneStartIdx ];
return idx < 0 ? null : Dalamud.Objects[ idx ]; return idx < 0 ? null : DalamudServices.Objects[ idx ];
} }
} }

View file

@ -5,7 +5,8 @@ using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object; using FFXIVClientStructs.FFXIV.Client.Game.Object;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.Services;
namespace Penumbra.Interop.Resolver; namespace Penumbra.Interop.Resolver;
public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable< (IntPtr Address, ActorIdentifier Identifier, ModCollection Collection) > public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable< (IntPtr Address, ActorIdentifier Identifier, ModCollection Collection) >
@ -29,7 +30,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable< (IntPt
Penumbra.CollectionManager.CollectionChanged += CollectionChangeClear; Penumbra.CollectionManager.CollectionChanged += CollectionChangeClear;
Penumbra.TempMods.CollectionChanged += CollectionChangeClear; Penumbra.TempMods.CollectionChanged += CollectionChangeClear;
Dalamud.ClientState.TerritoryChanged += TerritoryClear; DalamudServices.ClientState.TerritoryChanged += TerritoryClear;
_events.CharacterDestructor += OnCharacterDestruct; _events.CharacterDestructor += OnCharacterDestruct;
_enabled = true; _enabled = true;
} }
@ -43,7 +44,7 @@ public unsafe class IdentifiedCollectionCache : IDisposable, IEnumerable< (IntPt
Penumbra.CollectionManager.CollectionChanged -= CollectionChangeClear; Penumbra.CollectionManager.CollectionChanged -= CollectionChangeClear;
Penumbra.TempMods.CollectionChanged -= CollectionChangeClear; Penumbra.TempMods.CollectionChanged -= CollectionChangeClear;
Dalamud.ClientState.TerritoryChanged -= TerritoryClear; DalamudServices.ClientState.TerritoryChanged -= TerritoryClear;
_events.CharacterDestructor -= OnCharacterDestruct; _events.CharacterDestructor -= OnCharacterDestruct;
_enabled = false; _enabled = false;
} }

View file

@ -5,6 +5,7 @@ using Penumbra.Collections;
using Penumbra.GameData; using Penumbra.GameData;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Services;
using Penumbra.String; using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.Util; using Penumbra.Util;
@ -137,9 +138,9 @@ public unsafe partial class PathResolver
{ {
var getGameObjectIdx = ( ( delegate* unmanaged< IntPtr, int >** )timeline )[ 0 ][ Offsets.GetGameObjectIdxVfunc ]; var getGameObjectIdx = ( ( delegate* unmanaged< IntPtr, int >** )timeline )[ 0 ][ Offsets.GetGameObjectIdxVfunc ];
var idx = getGameObjectIdx( timeline ); var idx = getGameObjectIdx( timeline );
if( idx >= 0 && idx < Dalamud.Objects.Length ) if( idx >= 0 && idx < DalamudServices.Objects.Length )
{ {
var obj = Dalamud.Objects[ idx ]; var obj = DalamudServices.Objects[ idx ];
return obj != null ? IdentifyCollection( ( GameObject* )obj.Address, true ) : ResolveData.Invalid; return obj != null ? IdentifyCollection( ( GameObject* )obj.Address, true ) : ResolveData.Invalid;
} }
} }
@ -203,9 +204,9 @@ public unsafe partial class PathResolver
if( timelinePtr != IntPtr.Zero ) if( timelinePtr != IntPtr.Zero )
{ {
var actorIdx = ( int )( *( *( ulong** )timelinePtr + 1 ) >> 3 ); var actorIdx = ( int )( *( *( ulong** )timelinePtr + 1 ) >> 3 );
if( actorIdx >= 0 && actorIdx < Dalamud.Objects.Length ) if( actorIdx >= 0 && actorIdx < DalamudServices.Objects.Length )
{ {
_animationLoadData = IdentifyCollection( ( GameObject* )( Dalamud.Objects[ actorIdx ]?.Address ?? IntPtr.Zero ), true ); _animationLoadData = IdentifyCollection( ( GameObject* )( DalamudServices.Objects[ actorIdx ]?.Address ?? IntPtr.Zero ), true );
} }
} }
@ -233,14 +234,14 @@ public unsafe partial class PathResolver
private global::Dalamud.Game.ClientState.Objects.Types.GameObject? GetOwnedObject( uint id ) private global::Dalamud.Game.ClientState.Objects.Types.GameObject? GetOwnedObject( uint id )
{ {
var owner = Dalamud.Objects.SearchById( id ); var owner = DalamudServices.Objects.SearchById( id );
if( owner == null ) if( owner == null )
{ {
return null; return null;
} }
var idx = ( ( GameObject* )owner.Address )->ObjectIndex; var idx = ( ( GameObject* )owner.Address )->ObjectIndex;
return Dalamud.Objects[ idx + 1 ]; return DalamudServices.Objects[ idx + 1 ];
} }
private IntPtr LoadCharacterVfxDetour( byte* vfxPath, VfxParams* vfxParams, byte unk1, byte unk2, float unk3, int unk4 ) private IntPtr LoadCharacterVfxDetour( byte* vfxPath, VfxParams* vfxParams, byte unk1, byte unk2, float unk3, int unk4 )
@ -251,8 +252,8 @@ public unsafe partial class PathResolver
{ {
var obj = vfxParams->GameObjectType switch var obj = vfxParams->GameObjectType switch
{ {
0 => Dalamud.Objects.SearchById( vfxParams->GameObjectId ), 0 => DalamudServices.Objects.SearchById( vfxParams->GameObjectId ),
2 => Dalamud.Objects[ ( int )vfxParams->GameObjectId ], 2 => DalamudServices.Objects[ ( int )vfxParams->GameObjectId ],
4 => GetOwnedObject( vfxParams->GameObjectId ), 4 => GetOwnedObject( vfxParams->GameObjectId ),
_ => null, _ => null,
}; };

View file

@ -12,7 +12,8 @@ using Penumbra.GameData;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.Util; using Penumbra.Util;
using Penumbra.Services;
namespace Penumbra.Interop.Resolver; namespace Penumbra.Interop.Resolver;
public unsafe partial class PathResolver public unsafe partial class PathResolver
@ -113,7 +114,7 @@ public unsafe partial class PathResolver
// Check that a linked DrawObject still corresponds to the correct actor and that it still exists, otherwise remove it. // Check that a linked DrawObject still corresponds to the correct actor and that it still exists, otherwise remove it.
private bool VerifyEntry( IntPtr drawObject, int gameObjectIdx, out GameObject* gameObject ) private bool VerifyEntry( IntPtr drawObject, int gameObjectIdx, out GameObject* gameObject )
{ {
gameObject = ( GameObject* )Dalamud.Objects.GetObjectAddress( gameObjectIdx ); gameObject = ( GameObject* )DalamudServices.Objects.GetObjectAddress( gameObjectIdx );
var draw = ( DrawObject* )drawObject; var draw = ( DrawObject* )drawObject;
if( gameObject != null if( gameObject != null
&& ( gameObject->DrawObject == draw || draw != null && gameObject->DrawObject == draw->Object.ParentObject ) ) && ( gameObject->DrawObject == draw || draw != null && gameObject->DrawObject == draw->Object.ParentObject ) )
@ -251,9 +252,9 @@ public unsafe partial class PathResolver
// We do not iterate the Dalamud table because it does not work when not logged in. // We do not iterate the Dalamud table because it does not work when not logged in.
private void InitializeDrawObjects() private void InitializeDrawObjects()
{ {
for( var i = 0; i < Dalamud.Objects.Length; ++i ) for( var i = 0; i < DalamudServices.Objects.Length; ++i )
{ {
var ptr = ( GameObject* )Dalamud.Objects.GetObjectAddress( i ); var ptr = ( GameObject* )DalamudServices.Objects.GetObjectAddress( i );
if( ptr != null && ptr->IsCharacter() && ptr->DrawObject != null ) if( ptr != null && ptr->IsCharacter() && ptr->DrawObject != null )
{ {
_drawObjectToObject[ ( IntPtr )ptr->DrawObject ] = ( IdentifyCollection( ptr, false ), ptr->ObjectIndex ); _drawObjectToObject[ ( IntPtr )ptr->DrawObject ] = ( IdentifyCollection( ptr, false ), ptr->ObjectIndex );

View file

@ -8,6 +8,7 @@ using OtterGui;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.Services;
using Penumbra.Util; using Penumbra.Util;
using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character; using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character;
using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject; using GameObject = FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject;
@ -37,7 +38,7 @@ public unsafe partial class PathResolver
// Login screen. Names are populated after actors are drawn, // Login screen. Names are populated after actors are drawn,
// so it is not possible to fetch names from the ui list. // so it is not possible to fetch names from the ui list.
// Actors are also not named. So use Yourself > Players > Racial > Default. // Actors are also not named. So use Yourself > Players > Racial > Default.
if( !Dalamud.ClientState.IsLoggedIn ) if( !DalamudServices.ClientState.IsLoggedIn )
{ {
var collection2 = Penumbra.CollectionManager.ByType( CollectionType.Yourself ) var collection2 = Penumbra.CollectionManager.ByType( CollectionType.Yourself )
?? CollectionByAttributes( gameObject ) ?? CollectionByAttributes( gameObject )
@ -46,7 +47,7 @@ public unsafe partial class PathResolver
} }
// Aesthetician. The relevant actor is yourself, so use player collection when possible. // Aesthetician. The relevant actor is yourself, so use player collection when possible.
if( Dalamud.GameGui.GetAddonByName( "ScreenLog" ) == IntPtr.Zero ) if( DalamudServices.GameGui.GetAddonByName( "ScreenLog" ) == IntPtr.Zero )
{ {
var player = Penumbra.Actors.GetCurrentPlayer(); var player = Penumbra.Actors.GetCurrentPlayer();
var collection2 = ( player.IsValid ? CollectionByIdentifier( player ) : null ) var collection2 = ( player.IsValid ? CollectionByIdentifier( player ) : null )
@ -86,7 +87,7 @@ public unsafe partial class PathResolver
public static ModCollection PlayerCollection() public static ModCollection PlayerCollection()
{ {
using var performance = Penumbra.Performance.Measure( PerformanceType.IdentifyCollection ); using var performance = Penumbra.Performance.Measure( PerformanceType.IdentifyCollection );
var gameObject = ( GameObject* )Dalamud.Objects.GetObjectAddress( 0 ); var gameObject = ( GameObject* )DalamudServices.Objects.GetObjectAddress( 0 );
if( gameObject == null ) if( gameObject == null )
{ {
return Penumbra.CollectionManager.ByType( CollectionType.Yourself ) return Penumbra.CollectionManager.ByType( CollectionType.Yourself )

View file

@ -8,6 +8,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Resource;
using Penumbra.Collections; using Penumbra.Collections;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using Penumbra.Interop.Loader; using Penumbra.Interop.Loader;
using Penumbra.Services;
using Penumbra.String; using Penumbra.String;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.Util; using Penumbra.Util;
@ -34,7 +35,7 @@ public partial class PathResolver : IDisposable
private readonly SubfileHelper _subFiles; private readonly SubfileHelper _subFiles;
static PathResolver() static PathResolver()
=> ValidHumanModels = GetValidHumanModels( Dalamud.GameData ); => ValidHumanModels = GetValidHumanModels( DalamudServices.GameData );
public unsafe PathResolver( ResourceLoader loader ) public unsafe PathResolver( ResourceLoader loader )
{ {

View file

@ -5,6 +5,7 @@ using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Meta.Manipulations; using Penumbra.Meta.Manipulations;
using Penumbra.Services;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.String.Functions; using Penumbra.String.Functions;
@ -140,7 +141,7 @@ public unsafe class ImcFile : MetaBaseFile
public override void Reset() public override void Reset()
{ {
var file = Dalamud.GameData.GetFile( Path.ToString() ); var file = DalamudServices.GameData.GetFile( Path.ToString() );
fixed( byte* ptr = file!.Data ) fixed( byte* ptr = file!.Data )
{ {
MemoryUtility.MemCpyUnchecked( Data, ptr, file.Data.Length ); MemoryUtility.MemCpyUnchecked( Data, ptr, file.Data.Length );
@ -152,7 +153,7 @@ public unsafe class ImcFile : MetaBaseFile
: base( 0 ) : base( 0 )
{ {
Path = manip.GamePath(); Path = manip.GamePath();
var file = Dalamud.GameData.GetFile( Path.ToString() ); var file = DalamudServices.GameData.GetFile( Path.ToString() );
if( file == null ) if( file == null )
{ {
throw new ImcException( manip, Path ); throw new ImcException( manip, Path );
@ -171,7 +172,7 @@ public unsafe class ImcFile : MetaBaseFile
public static ImcEntry GetDefault( string path, EquipSlot slot, int variantIdx, out bool exists ) public static ImcEntry GetDefault( string path, EquipSlot slot, int variantIdx, out bool exists )
{ {
var file = Dalamud.GameData.GetFile( path ); var file = DalamudServices.GameData.GetFile( path );
exists = false; exists = false;
if( file == null ) if( file == null )
{ {

View file

@ -8,6 +8,7 @@ using Penumbra.GameData.Files;
using Penumbra.GameData.Structs; using Penumbra.GameData.Structs;
using Penumbra.Meta.Files; using Penumbra.Meta.Files;
using Penumbra.Meta.Manipulations; using Penumbra.Meta.Manipulations;
using Penumbra.Services;
using Penumbra.String.Classes; using Penumbra.String.Classes;
namespace Penumbra.Mods.ItemSwap; namespace Penumbra.Mods.ItemSwap;
@ -38,7 +39,7 @@ public static class ItemSwap
return true; return true;
} }
var file = Dalamud.GameData.GetFile( path.InternalName.ToString() ); var file = DalamudServices.GameData.GetFile( path.InternalName.ToString() );
if( file != null ) if( file != null )
{ {
data = file.Data; data = file.Data;

View file

@ -8,7 +8,8 @@ using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using Penumbra.GameData.Enums; using Penumbra.GameData.Enums;
using static Penumbra.Mods.ItemSwap.ItemSwap; using static Penumbra.Mods.ItemSwap.ItemSwap;
using Penumbra.Services;
namespace Penumbra.Mods.ItemSwap; namespace Penumbra.Mods.ItemSwap;
public class Swap public class Swap
@ -139,7 +140,7 @@ public sealed class FileSwap : Swap
} }
swap.SwapToModded = redirections( swap.SwapToRequestPath ); swap.SwapToModded = redirections( swap.SwapToRequestPath );
swap.SwapToModdedExistsInGame = !swap.SwapToModded.IsRooted && Dalamud.GameData.FileExists( swap.SwapToModded.InternalName.ToString() ); swap.SwapToModdedExistsInGame = !swap.SwapToModded.IsRooted && DalamudServices.GameData.FileExists( swap.SwapToModded.InternalName.ToString() );
swap.SwapToModdedEqualsOriginal = !swap.SwapToModded.IsRooted && swap.SwapToModded.InternalName.Equals( swap.SwapFromRequestPath.Path ); swap.SwapToModdedEqualsOriginal = !swap.SwapToModded.IsRooted && swap.SwapToModded.InternalName.Equals( swap.SwapFromRequestPath.Path );
swap.FileData = type switch swap.FileData = type switch

View file

@ -4,13 +4,14 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Newtonsoft.Json; using Newtonsoft.Json;
using Penumbra.Services;
namespace Penumbra.Mods; namespace Penumbra.Mods;
public sealed partial class Mod public sealed partial class Mod
{ {
public static DirectoryInfo LocalDataDirectory public static DirectoryInfo LocalDataDirectory
=> new(Path.Combine( Dalamud.PluginInterface.ConfigDirectory.FullName, "mod_data" )); => new(Path.Combine( DalamudServices.PluginInterface.ConfigDirectory.FullName, "mod_data" ));
public long ImportDate { get; private set; } = DateTimeOffset.UnixEpoch.ToUnixTimeMilliseconds(); public long ImportDate { get; private set; } = DateTimeOffset.UnixEpoch.ToUnixTimeMilliseconds();
@ -21,7 +22,7 @@ public sealed partial class Mod
public bool Favorite { get; private set; } = false; public bool Favorite { get; private set; } = false;
private FileInfo LocalDataFile private FileInfo LocalDataFile
=> new(Path.Combine( Dalamud.PluginInterface.ConfigDirectory.FullName, "mod_data", $"{ModPath.Name}.json" )); => new(Path.Combine( DalamudServices.PluginInterface.ConfigDirectory.FullName, "mod_data", $"{ModPath.Name}.json" ));
private ModDataChangeType LoadLocalData() private ModDataChangeType LoadLocalData()
{ {
@ -113,8 +114,8 @@ public sealed partial class Mod
private static void MoveDataFile( DirectoryInfo oldMod, DirectoryInfo newMod ) private static void MoveDataFile( DirectoryInfo oldMod, DirectoryInfo newMod )
{ {
var oldFile = Path.Combine( Dalamud.PluginInterface.ConfigDirectory.FullName, "mod_data", $"{oldMod.Name}.json" ); var oldFile = Path.Combine( DalamudServices.PluginInterface.ConfigDirectory.FullName, "mod_data", $"{oldMod.Name}.json" );
var newFile = Path.Combine( Dalamud.PluginInterface.ConfigDirectory.FullName, "mod_data", $"{newMod.Name}.json" ); var newFile = Path.Combine( DalamudServices.PluginInterface.ConfigDirectory.FullName, "mod_data", $"{newMod.Name}.json" );
if( File.Exists( oldFile ) ) if( File.Exists( oldFile ) )
{ {
try try

View file

@ -5,13 +5,14 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using OtterGui.Filesystem; using OtterGui.Filesystem;
using Penumbra.Services;
namespace Penumbra.Mods; namespace Penumbra.Mods;
public sealed class ModFileSystem : FileSystem< Mod >, IDisposable public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
{ {
public static string ModFileSystemFile public static string ModFileSystemFile
=> Path.Combine( Dalamud.PluginInterface.GetPluginConfigDirectory(), "sort_order.json" ); => Path.Combine( DalamudServices.PluginInterface.GetPluginConfigDirectory(), "sort_order.json" );
// Save the current sort order. // Save the current sort order.
// Does not save or copy the backup in the current mod directory, // Does not save or copy the backup in the current mod directory,

View file

@ -9,6 +9,7 @@ using Dalamud.Interface.Windowing;
using Dalamud.Plugin; using Dalamud.Plugin;
using ImGuiNET; using ImGuiNET;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
using Microsoft.Extensions.DependencyInjection;
using OtterGui; using OtterGui;
using OtterGui.Classes; using OtterGui.Classes;
using OtterGui.Log; using OtterGui.Log;
@ -31,6 +32,42 @@ using ResidentResourceManager = Penumbra.Interop.ResidentResourceManager;
namespace Penumbra; namespace Penumbra;
public class PenumbraNew
{
public string Name
=> "Penumbra";
public static readonly Logger Log = new();
public readonly StartTimeTracker< StartTimeType > StartTimer = new();
public readonly IServiceCollection Services = new ServiceCollection();
public PenumbraNew( DalamudPluginInterface pi )
{
using var time = StartTimer.Measure( StartTimeType.Total );
// Add meta services.
Services.AddSingleton( Log );
Services.AddSingleton( StartTimer );
Services.AddSingleton< ValidityChecker >();
Services.AddSingleton< PerformanceTracker< PerformanceType > >();
// Add Dalamud services
var dalamud = new DalamudServices( pi );
dalamud.AddServices( Services );
// Add Game Data
// Add Configuration
Services.AddSingleton< Configuration >();
}
public void Dispose()
{ }
}
public class Penumbra : IDalamudPlugin public class Penumbra : IDalamudPlugin
{ {
public string Name public string Name
@ -87,22 +124,24 @@ public class Penumbra : IDalamudPlugin
try try
{ {
Dalamud.Initialize( pluginInterface ); DalamudServices.Initialize( pluginInterface );
Performance = new PerformanceTracker< PerformanceType >( Dalamud.Framework ); Performance = new PerformanceTracker< PerformanceType >( DalamudServices.Framework );
Log = new Logger(); Log = new Logger();
ValidityChecker = new ValidityChecker( Dalamud.PluginInterface ); ValidityChecker = new ValidityChecker( DalamudServices.PluginInterface );
GameEvents = new GameEventManager(); GameEvents = new GameEventManager();
StartTimer.Measure( StartTimeType.Identifier, () => Identifier = GameData.GameData.GetIdentifier( Dalamud.PluginInterface, Dalamud.GameData ) ); StartTimer.Measure( StartTimeType.Identifier, () => Identifier = GameData.GameData.GetIdentifier( DalamudServices.PluginInterface, DalamudServices.GameData ) );
StartTimer.Measure( StartTimeType.GamePathParser, () => GamePathParser = GameData.GameData.GetGamePathParser() ); StartTimer.Measure( StartTimeType.GamePathParser, () => GamePathParser = GameData.GameData.GetGamePathParser() );
StartTimer.Measure( StartTimeType.Stains, () => StainManager = new StainManager( Dalamud.PluginInterface, Dalamud.GameData ) ); StartTimer.Measure( StartTimeType.Stains, () => StainManager = new StainManager( DalamudServices.PluginInterface, DalamudServices.GameData ) );
ItemData = StartTimer.Measure( StartTimeType.Items, () => new ItemData( Dalamud.PluginInterface, Dalamud.GameData, Dalamud.GameData.Language ) ); ItemData = StartTimer.Measure( StartTimeType.Items,
() => new ItemData( DalamudServices.PluginInterface, DalamudServices.GameData, DalamudServices.GameData.Language ) );
StartTimer.Measure( StartTimeType.Actors, StartTimer.Measure( StartTimeType.Actors,
() => Actors = new ActorManager( Dalamud.PluginInterface, Dalamud.Objects, Dalamud.ClientState, Dalamud.Framework, Dalamud.GameData, Dalamud.GameGui, () => Actors = new ActorManager( DalamudServices.PluginInterface, DalamudServices.Objects, DalamudServices.ClientState, DalamudServices.Framework,
DalamudServices.GameData, DalamudServices.GameGui,
ResolveCutscene ) ); ResolveCutscene ) );
Framework = new FrameworkManager( Dalamud.Framework, Log ); Framework = new FrameworkManager( DalamudServices.Framework, Log );
CharacterUtility = new CharacterUtility(); CharacterUtility = new CharacterUtility();
StartTimer.Measure( StartTimeType.Backup, () => Backup.CreateBackup( pluginInterface.ConfigDirectory, PenumbraBackupFiles() ) ); StartTimer.Measure( StartTimeType.Backup, () => Backup.CreateBackup( pluginInterface.ConfigDirectory, PenumbraBackupFiles() ) );
@ -147,7 +186,7 @@ public class Penumbra : IDalamudPlugin
using( var tApi = StartTimer.Measure( StartTimeType.Api ) ) using( var tApi = StartTimer.Measure( StartTimeType.Api ) )
{ {
Api = new PenumbraApi( this ); Api = new PenumbraApi( this );
IpcProviders = new PenumbraIpcProviders( Dalamud.PluginInterface, Api ); IpcProviders = new PenumbraIpcProviders( DalamudServices.PluginInterface, Api );
HttpApi = new HttpApi( Api ); HttpApi = new HttpApi( Api );
if( Config.EnableHttpApi ) if( Config.EnableHttpApi )
{ {
@ -159,7 +198,7 @@ public class Penumbra : IDalamudPlugin
ValidityChecker.LogExceptions(); ValidityChecker.LogExceptions();
Log.Information( $"Penumbra Version {Version}, Commit #{CommitHash} successfully Loaded from {pluginInterface.SourceRepository}." ); Log.Information( $"Penumbra Version {Version}, Commit #{CommitHash} successfully Loaded from {pluginInterface.SourceRepository}." );
OtterTex.NativeDll.Initialize( Dalamud.PluginInterface.AssemblyLocation.DirectoryName ); OtterTex.NativeDll.Initialize( DalamudServices.PluginInterface.AssemblyLocation.DirectoryName );
Log.Information( $"Loading native OtterTex assembly from {OtterTex.NativeDll.Directory}." ); Log.Information( $"Loading native OtterTex assembly from {OtterTex.NativeDll.Directory}." );
if( CharacterUtility.Ready ) if( CharacterUtility.Ready )
@ -186,19 +225,19 @@ public class Penumbra : IDalamudPlugin
}; };
var btn = new LaunchButton( cfg ); var btn = new LaunchButton( cfg );
var system = new WindowSystem( Name ); var system = new WindowSystem( Name );
var cmd = new CommandHandler( Dalamud.Commands, ObjectReloader, Config, this, cfg, ModManager, CollectionManager, Actors ); var cmd = new CommandHandler( DalamudServices.Commands, ObjectReloader, Config, this, cfg, ModManager, CollectionManager, Actors );
system.AddWindow( cfg ); system.AddWindow( cfg );
system.AddWindow( cfg.ModEditPopup ); system.AddWindow( cfg.ModEditPopup );
system.AddWindow( changelog ); system.AddWindow( changelog );
if( !_disposed ) if( !_disposed )
{ {
_changelog = changelog; _changelog = changelog;
ConfigWindow = cfg; ConfigWindow = cfg;
_windowSystem = system; _windowSystem = system;
_launchButton = btn; _launchButton = btn;
_commandHandler = cmd; _commandHandler = cmd;
Dalamud.PluginInterface.UiBuilder.OpenConfigUi += cfg.Toggle; DalamudServices.PluginInterface.UiBuilder.OpenConfigUi += cfg.Toggle;
Dalamud.PluginInterface.UiBuilder.Draw += _windowSystem.Draw; DalamudServices.PluginInterface.UiBuilder.Draw += _windowSystem.Draw;
} }
else else
{ {
@ -214,13 +253,13 @@ public class Penumbra : IDalamudPlugin
{ {
if( _windowSystem != null ) if( _windowSystem != null )
{ {
Dalamud.PluginInterface.UiBuilder.Draw -= _windowSystem.Draw; DalamudServices.PluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
} }
_launchButton?.Dispose(); _launchButton?.Dispose();
if( ConfigWindow != null ) if( ConfigWindow != null )
{ {
Dalamud.PluginInterface.UiBuilder.OpenConfigUi -= ConfigWindow.Toggle; DalamudServices.PluginInterface.UiBuilder.OpenConfigUi -= ConfigWindow.Toggle;
ConfigWindow.Dispose(); ConfigWindow.Dispose();
} }
} }
@ -331,7 +370,7 @@ public class Penumbra : IDalamudPlugin
? new DirectoryInfo( collectionDir ).EnumerateFiles( "*.json" ).ToList() ? new DirectoryInfo( collectionDir ).EnumerateFiles( "*.json" ).ToList()
: new List< FileInfo >(); : new List< FileInfo >();
list.AddRange( Mod.LocalDataDirectory.Exists ? Mod.LocalDataDirectory.EnumerateFiles( "*.json" ) : Enumerable.Empty< FileInfo >() ); list.AddRange( Mod.LocalDataDirectory.Exists ? Mod.LocalDataDirectory.EnumerateFiles( "*.json" ) : Enumerable.Empty< FileInfo >() );
list.Add( Dalamud.PluginInterface.ConfigFile ); list.Add( DalamudServices.PluginInterface.ConfigFile );
list.Add( new FileInfo( ModFileSystem.ModFileSystemFile ) ); list.Add( new FileInfo( ModFileSystem.ModFileSystemFile ) );
list.Add( new FileInfo( ModCollection.Manager.ActiveCollectionFile ) ); list.Add( new FileInfo( ModCollection.Manager.ActiveCollectionFile ) );
return list; return list;
@ -352,7 +391,8 @@ public class Penumbra : IDalamudPlugin
sb.Append( $"> **`Free Drive Space: `** {( drive != null ? Functions.HumanReadableSize( drive.AvailableFreeSpace ) : "Unknown" )}\n" ); sb.Append( $"> **`Free Drive Space: `** {( drive != null ? Functions.HumanReadableSize( drive.AvailableFreeSpace ) : "Unknown" )}\n" );
sb.Append( $"> **`Auto-Deduplication: `** {Config.AutoDeduplicateOnImport}\n" ); sb.Append( $"> **`Auto-Deduplication: `** {Config.AutoDeduplicateOnImport}\n" );
sb.Append( $"> **`Debug Mode: `** {Config.DebugMode}\n" ); sb.Append( $"> **`Debug Mode: `** {Config.DebugMode}\n" );
sb.Append( $"> **`Synchronous Load (Dalamud): `** {( Dalamud.GetDalamudConfig( Dalamud.WaitingForPluginsOption, out bool v ) ? v.ToString() : "Unknown" )}\n" ); sb.Append(
$"> **`Synchronous Load (Dalamud): `** {( DalamudServices.GetDalamudConfig( DalamudServices.WaitingForPluginsOption, out bool v ) ? v.ToString() : "Unknown" )}\n" );
sb.Append( $"> **`Logging: `** Log: {Config.EnableResourceLogging}, Watcher: {Config.EnableResourceWatcher} ({Config.MaxResourceWatcherRecords})\n" ); sb.Append( $"> **`Logging: `** Log: {Config.EnableResourceLogging}, Watcher: {Config.EnableResourceWatcher} ({Config.MaxResourceWatcherRecords})\n" );
sb.Append( $"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n" ); sb.Append( $"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n" );
sb.AppendLine( "**Mods**" ); sb.AppendLine( "**Mods**" );

View file

@ -71,6 +71,7 @@
<PackageReference Include="EmbedIO" Version="3.4.3" /> <PackageReference Include="EmbedIO" Version="3.4.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.2" /> <PackageReference Include="SixLabors.ImageSharp" Version="2.1.2" />
<PackageReference Include="SharpCompress" Version="0.32.1" /> <PackageReference Include="SharpCompress" Version="0.32.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

50
Penumbra/PenumbraNew.cs Normal file
View file

@ -0,0 +1,50 @@
using System.IO;
using Dalamud.Plugin;
using Microsoft.Extensions.DependencyInjection;
using OtterGui.Classes;
using OtterGui.Log;
using Penumbra.GameData;
using Penumbra.GameData.Data;
using Penumbra.Interop;
using Penumbra.Services;
using Penumbra.Util;
namespace Penumbra;
public class PenumbraNew
{
public string Name
=> "Penumbra";
public static readonly Logger Log = new();
public readonly StartTimeTracker<StartTimeType> StartTimer = new();
public readonly IServiceCollection Services = new ServiceCollection();
public PenumbraNew(DalamudPluginInterface pi)
{
using var time = StartTimer.Measure(StartTimeType.Total);
// Add meta services.
Services.AddSingleton(Log);
Services.AddSingleton(StartTimer);
Services.AddSingleton<ValidityChecker>();
Services.AddSingleton<PerformanceTracker<PerformanceType>>();
// Add Dalamud services
var dalamud = new DalamudServices(pi);
dalamud.AddServices(Services);
// Add Game Data
Services.AddSingleton<GameEventManager>();
Services.AddSingleton<IGamePathParser, GamePathParser>();
Services.AddSingleton<IObjectIdentifier, ObjectIdentifier>();
// Add Configuration
Services.AddSingleton<Configuration>();
}
public void Dispose()
{ }
}

View file

@ -0,0 +1,168 @@
using System;
using Dalamud.Data;
using Dalamud.Game;
using Dalamud.Game.ClientState;
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Game.ClientState.Keys;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.Interface;
using Dalamud.IoC;
using Dalamud.Plugin;
using System.Linq;
using System.Reflection;
using Microsoft.Extensions.DependencyInjection;
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
namespace Penumbra.Services;
public class DalamudServices
{
public DalamudServices(DalamudPluginInterface pluginInterface)
{
pluginInterface.Inject(this);
try
{
var serviceType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "Service`1" && t.IsGenericType);
var configType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudConfiguration");
var interfaceType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudInterface");
if (serviceType == null || configType == null || interfaceType == null)
{
return;
}
var configService = serviceType.MakeGenericType(configType);
var interfaceService = serviceType.MakeGenericType(interfaceType);
var configGetter = configService.GetMethod("Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
_interfaceGetter = interfaceService.GetMethod("Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
if (configGetter == null || _interfaceGetter == null)
{
return;
}
_dalamudConfig = configGetter.Invoke(null, null);
if (_dalamudConfig != null)
{
_saveDalamudConfig = _dalamudConfig.GetType().GetMethod("Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (_saveDalamudConfig == null)
{
_dalamudConfig = null;
_interfaceGetter = null;
}
}
}
catch
{
_dalamudConfig = null;
_saveDalamudConfig = null;
_interfaceGetter = null;
}
}
public void AddServices(IServiceCollection services)
{
services.AddSingleton(PluginInterface);
services.AddSingleton(Commands);
services.AddSingleton(GameData);
services.AddSingleton(ClientState);
services.AddSingleton(Chat);
services.AddSingleton(Framework);
services.AddSingleton(Conditions);
services.AddSingleton(Targets);
services.AddSingleton(Objects);
services.AddSingleton(TitleScreenMenu);
services.AddSingleton(GameGui);
services.AddSingleton(KeyState);
services.AddSingleton(SigScanner);
services.AddSingleton(this);
}
// @formatter:off
[PluginService][RequiredVersion("1.0")] public DalamudPluginInterface PluginInterface { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public CommandManager Commands { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public DataManager GameData { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ClientState ClientState { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ChatGui Chat { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public Framework Framework { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public Condition Conditions { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public TargetManager Targets { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public ObjectTable Objects { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public TitleScreenMenu TitleScreenMenu { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public GameGui GameGui { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public KeyState KeyState { get; private set; } = null!;
[PluginService][RequiredVersion("1.0")] public SigScanner SigScanner { get; private set; } = null!;
// @formatter:on
public const string WaitingForPluginsOption = "IsResumeGameAfterPluginLoad";
private readonly object? _dalamudConfig;
private readonly MethodInfo? _interfaceGetter;
private readonly MethodInfo? _saveDalamudConfig;
public bool GetDalamudConfig<T>(string fieldName, out T? value)
{
value = default;
try
{
if (_dalamudConfig == null)
{
return false;
}
var getter = _dalamudConfig.GetType().GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (getter == null)
{
return false;
}
var result = getter.GetValue(_dalamudConfig);
if (result is not T v)
{
return false;
}
value = v;
return true;
}
catch (Exception e)
{
Penumbra.Log.Error($"Error while fetching Dalamud Config {fieldName}:\n{e}");
return false;
}
}
public bool SetDalamudConfig<T>(string fieldName, in T? value, string? windowFieldName = null)
{
try
{
if (_dalamudConfig == null)
{
return false;
}
var getter = _dalamudConfig.GetType().GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (getter == null)
{
return false;
}
getter.SetValue(_dalamudConfig, value);
if (windowFieldName != null)
{
var inter = _interfaceGetter!.Invoke(null, null);
var settingsWindow = inter?.GetType().GetField("settingsWindow", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(inter);
settingsWindow?.GetType().GetField(windowFieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(settingsWindow, value);
}
_saveDalamudConfig!.Invoke(_dalamudConfig, null);
return true;
}
catch (Exception e)
{
Penumbra.Log.Error($"Error while fetching Dalamud Config {fieldName}:\n{e}");
return false;
}
}
}

View file

@ -0,0 +1,66 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Dalamud.Data;
using Dalamud.Plugin;
using Lumina.Excel.GeneratedSheets;
using OtterGui.Classes;
using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.Util;
using Action = System.Action;
namespace Penumbra.Services;
public sealed class ObjectIdentifier : IObjectIdentifier
{
private const string Prefix = $"[{nameof(ObjectIdentifier)}]";
public IObjectIdentifier? Identifier { get; private set; }
public bool IsDisposed { get; private set; }
public bool Ready
=> Identifier != null && !IsDisposed;
public event Action? FinishedCreation;
public ObjectIdentifier(StartTimeTracker<StartTimeType> tracker, DalamudPluginInterface pi, DataManager data)
{
Task.Run(() =>
{
using var timer = tracker.Measure(StartTimeType.Identifier);
var identifier = GameData.GameData.GetIdentifier(pi, data);
if (IsDisposed)
{
identifier.Dispose();
}
else
{
Identifier = identifier;
Penumbra.Log.Verbose($"{Prefix} Created.");
FinishedCreation?.Invoke();
}
});
}
public void Dispose()
{
Identifier?.Dispose();
IsDisposed = true;
Penumbra.Log.Verbose($"{Prefix} Disposed.");
}
public IGamePathParser GamePathParser
=> Identifier?.GamePathParser ?? throw new Exception($"{Prefix} Not yet ready.");
public void Identify(IDictionary<string, object?> set, string path)
=> Identifier?.Identify(set, path);
public Dictionary<string, object?> Identify(string path)
=> Identifier?.Identify(path) ?? new Dictionary<string, object?>();
public IEnumerable<Item> Identify(SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot)
=> Identifier?.Identify(setId, weaponType, variant, slot) ?? Array.Empty<Item>();
}

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection;
using Dalamud.Interface.Internal.Notifications; using Dalamud.Interface.Internal.Notifications;
using Dalamud.Plugin; using Dalamud.Plugin;
using Penumbra.Util; using Penumbra.Util;
@ -20,11 +21,18 @@ public class ValidityChecker
public readonly List<Exception> ImcExceptions = new(); public readonly List<Exception> ImcExceptions = new();
public readonly string Version;
public readonly string CommitHash;
public ValidityChecker(DalamudPluginInterface pi) public ValidityChecker(DalamudPluginInterface pi)
{ {
DevPenumbraExists = CheckDevPluginPenumbra(pi); DevPenumbraExists = CheckDevPluginPenumbra(pi);
IsNotInstalledPenumbra = CheckIsNotInstalled(pi); IsNotInstalledPenumbra = CheckIsNotInstalled(pi);
IsValidSourceRepo = CheckSourceRepo(pi); IsValidSourceRepo = CheckSourceRepo(pi);
var assembly = Assembly.GetExecutingAssembly();
Version = assembly.GetName().Version?.ToString() ?? string.Empty;
CommitHash = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "Unknown";
} }
public void LogExceptions() public void LogExceptions()

View file

@ -10,6 +10,7 @@ using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using Penumbra.GameData.Files; using Penumbra.GameData.Files;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.String.Classes; using Penumbra.String.Classes;
namespace Penumbra.UI.Classes; namespace Penumbra.UI.Classes;
@ -82,7 +83,7 @@ public partial class ModEditWindow
_fileDialog.Reset(); _fileDialog.Reset();
try try
{ {
var file = Dalamud.GameData.GetFile( _defaultPath ); var file = DalamudServices.GameData.GetFile( _defaultPath );
if( file != null ) if( file != null )
{ {
_defaultException = null; _defaultException = null;

View file

@ -10,6 +10,7 @@ using OtterGui.Classes;
using OtterGui.Raii; using OtterGui.Raii;
using Penumbra.GameData.Data; using Penumbra.GameData.Data;
using Penumbra.GameData.Files; using Penumbra.GameData.Files;
using Penumbra.Services;
using Penumbra.String.Classes; using Penumbra.String.Classes;
using Penumbra.Util; using Penumbra.Util;
using static Penumbra.GameData.Files.ShpkFile; using static Penumbra.GameData.Files.ShpkFile;
@ -80,7 +81,7 @@ public partial class ModEditWindow
LoadedShpkPath = path; LoadedShpkPath = path;
var data = LoadedShpkPath.IsRooted var data = LoadedShpkPath.IsRooted
? File.ReadAllBytes( LoadedShpkPath.FullName ) ? File.ReadAllBytes( LoadedShpkPath.FullName )
: Dalamud.GameData.GetFile( LoadedShpkPath.InternalName.ToString() )?.Data; : DalamudServices.GameData.GetFile( LoadedShpkPath.InternalName.ToString() )?.Data;
AssociatedShpk = data?.Length > 0 ? new ShpkFile( data ) : throw new Exception( "Failure to load file data." ); AssociatedShpk = data?.Length > 0 ? new ShpkFile( data ) : throw new Exception( "Failure to load file data." );
LoadedShpkPathName = path.ToPath(); LoadedShpkPathName = path.ToPath();
} }

View file

@ -14,7 +14,8 @@ using System.IO;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Services;
namespace Penumbra.UI.Classes; namespace Penumbra.UI.Classes;
public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, ModFileSystemSelector.ModState > public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, ModFileSystemSelector.ModState >
@ -25,7 +26,7 @@ public sealed partial class ModFileSystemSelector : FileSystemSelector< Mod, Mod
public ModCollection SelectedSettingCollection { get; private set; } = ModCollection.Empty; public ModCollection SelectedSettingCollection { get; private set; } = ModCollection.Empty;
public ModFileSystemSelector( ModFileSystem fileSystem ) public ModFileSystemSelector( ModFileSystem fileSystem )
: base( fileSystem, Dalamud.KeyState ) : base( fileSystem, DalamudServices.KeyState )
{ {
SubscribeRightClickFolder( EnableDescendants, 10 ); SubscribeRightClickFolder( EnableDescendants, 10 );
SubscribeRightClickFolder( DisableDescendants, 10 ); SubscribeRightClickFolder( DisableDescendants, 10 );

View file

@ -11,7 +11,8 @@ using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Interface.Components; using Dalamud.Interface.Components;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.GameData.Actors; using Penumbra.GameData.Actors;
using Penumbra.Services;
namespace Penumbra.UI; namespace Penumbra.UI;
public partial class ConfigWindow public partial class ConfigWindow
@ -287,7 +288,7 @@ public partial class ConfigWindow
private static bool DrawNewTargetCollection( Vector2 width ) private static bool DrawNewTargetCollection( Vector2 width )
{ {
var target = Penumbra.Actors.FromObject( Dalamud.Targets.Target, false, true, true ); var target = Penumbra.Actors.FromObject( DalamudServices.Targets.Target, false, true, true );
var result = Penumbra.CollectionManager.Individuals.CanAdd( target ); var result = Penumbra.CollectionManager.Individuals.CanAdd( target );
var tt = result switch var tt = result switch
{ {

View file

@ -14,6 +14,7 @@ using Penumbra.GameData.Files;
using Penumbra.Interop.Loader; using Penumbra.Interop.Loader;
using Penumbra.Interop.Resolver; using Penumbra.Interop.Resolver;
using Penumbra.Interop.Structs; using Penumbra.Interop.Structs;
using Penumbra.Services;
using Penumbra.String; using Penumbra.String;
using Penumbra.Util; using Penumbra.Util;
using static OtterGui.Raii.ImRaii; using static OtterGui.Raii.ImRaii;
@ -207,7 +208,7 @@ public partial class ConfigWindow
DrawSpecial( "Current Card", Penumbra.Actors.GetCardPlayer() ); DrawSpecial( "Current Card", Penumbra.Actors.GetCardPlayer() );
DrawSpecial( "Current Glamour", Penumbra.Actors.GetGlamourPlayer() ); DrawSpecial( "Current Glamour", Penumbra.Actors.GetGlamourPlayer() );
foreach( var obj in Dalamud.Objects ) foreach( var obj in DalamudServices.Objects )
{ {
ImGuiUtil.DrawTableColumn( $"{( ( GameObject* )obj.Address )->ObjectIndex}" ); ImGuiUtil.DrawTableColumn( $"{( ( GameObject* )obj.Address )->ObjectIndex}" );
ImGuiUtil.DrawTableColumn( $"0x{obj.Address:X}" ); ImGuiUtil.DrawTableColumn( $"0x{obj.Address:X}" );
@ -243,7 +244,7 @@ public partial class ConfigWindow
ImGui.TableNextColumn(); ImGui.TableNextColumn();
ImGui.TextUnformatted( idx.ToString() ); ImGui.TextUnformatted( idx.ToString() );
ImGui.TableNextColumn(); ImGui.TableNextColumn();
var obj = ( GameObject* )Dalamud.Objects.GetObjectAddress( idx ); var obj = ( GameObject* )DalamudServices.Objects.GetObjectAddress( idx );
var (address, name) = var (address, name) =
obj != null ? ( $"0x{( ulong )obj:X}", new ByteString( obj->Name ).ToString() ) : ( "NULL", "NULL" ); obj != null ? ( $"0x{( ulong )obj:X}", new ByteString( obj->Name ).ToString() ) : ( "NULL", "NULL" );
ImGui.TextUnformatted( address ); ImGui.TextUnformatted( address );
@ -541,7 +542,7 @@ public partial class ConfigWindow
// Draw information about the models, materials and resources currently loaded by the local player. // Draw information about the models, materials and resources currently loaded by the local player.
private static unsafe void DrawPlayerModelInfo() private static unsafe void DrawPlayerModelInfo()
{ {
var player = Dalamud.ClientState.LocalPlayer; var player = DalamudServices.ClientState.LocalPlayer;
var name = player?.Name.ToString() ?? "NULL"; var name = player?.Name.ToString() ?? "NULL";
if( !ImGui.CollapsingHeader( $"Player Model Info: {name}##Draw" ) || player == null ) if( !ImGui.CollapsingHeader( $"Player Model Info: {name}##Draw" ) || player == null )
{ {

View file

@ -6,6 +6,7 @@ using Dalamud.Interface.GameFonts;
using ImGuiNET; using ImGuiNET;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using Penumbra.Services;
using Penumbra.UI.Classes; using Penumbra.UI.Classes;
namespace Penumbra.UI; namespace Penumbra.UI;
@ -16,7 +17,7 @@ public partial class ConfigWindow
{ {
// We use a big, nice game font for the title. // We use a big, nice game font for the title.
private readonly GameFontHandle _nameFont = private readonly GameFontHandle _nameFont =
Dalamud.PluginInterface.UiBuilder.GetGameFontHandle( new GameFontStyle( GameFontFamilyAndSize.Jupiter23 ) ); DalamudServices.PluginInterface.UiBuilder.GetGameFontHandle( new GameFontStyle( GameFontFamilyAndSize.Jupiter23 ) );
// Header data. // Header data.
private string _modName = string.Empty; private string _modName = string.Empty;

View file

@ -9,7 +9,8 @@ using System.Numerics;
using Dalamud.Interface; using Dalamud.Interface;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Services;
namespace Penumbra.UI; namespace Penumbra.UI;
public partial class ConfigWindow public partial class ConfigWindow
@ -121,7 +122,7 @@ public partial class ConfigWindow
ImGuiUtil.HoverTooltip( lower.Length > 0 ? $"Execute '/penumbra redraw {lower}'." : $"Execute '/penumbra redraw'." ); ImGuiUtil.HoverTooltip( lower.Length > 0 ? $"Execute '/penumbra redraw {lower}'." : $"Execute '/penumbra redraw'." );
} }
using var disabled = ImRaii.Disabled( Dalamud.ClientState.LocalPlayer == null ); using var disabled = ImRaii.Disabled( DalamudServices.ClientState.LocalPlayer == null );
ImGui.SameLine(); ImGui.SameLine();
var buttonWidth = frameHeight with { X = ImGui.GetContentRegionAvail().X / 4 }; var buttonWidth = frameHeight with { X = ImGui.GetContentRegionAvail().X / 4 };
DrawButton( buttonWidth, "All", string.Empty ); DrawButton( buttonWidth, "All", string.Empty );

View file

@ -11,6 +11,7 @@ using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Interop.Loader; using Penumbra.Interop.Loader;
using Penumbra.Services;
using Penumbra.String.Classes; using Penumbra.String.Classes;
namespace Penumbra.UI; namespace Penumbra.UI;
@ -50,7 +51,7 @@ public partial class ConfigWindow
ImGui.NewLine(); ImGui.NewLine();
unsafe unsafe
{ {
ImGui.TextUnformatted( $"Static Address: 0x{( ulong )ResourceLoader.ResourceManager:X} (+0x{( ulong )ResourceLoader.ResourceManager - ( ulong )Dalamud.SigScanner.Module.BaseAddress:X})" ); ImGui.TextUnformatted( $"Static Address: 0x{( ulong )ResourceLoader.ResourceManager:X} (+0x{( ulong )ResourceLoader.ResourceManager - ( ulong )DalamudServices.SigScanner.Module.BaseAddress:X})" );
ImGui.TextUnformatted( $"Actual Address: 0x{( ulong )*ResourceLoader.ResourceManager:X}" ); ImGui.TextUnformatted( $"Actual Address: 0x{( ulong )*ResourceLoader.ResourceManager:X}" );
} }
} }

View file

@ -3,7 +3,8 @@ using ImGuiNET;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using Penumbra.Interop; using Penumbra.Interop;
using Penumbra.Services;
namespace Penumbra.UI; namespace Penumbra.UI;
public partial class ConfigWindow public partial class ConfigWindow
@ -104,7 +105,7 @@ public partial class ConfigWindow
private static void DrawWaitForPluginsReflection() private static void DrawWaitForPluginsReflection()
{ {
if( !Dalamud.GetDalamudConfig( Dalamud.WaitingForPluginsOption, out bool value ) ) if( !DalamudServices.GetDalamudConfig( DalamudServices.WaitingForPluginsOption, out bool value ) )
{ {
using var disabled = ImRaii.Disabled(); using var disabled = ImRaii.Disabled();
Checkbox( "Wait for Plugins on Startup (Disabled, can not access Dalamud Configuration)", string.Empty, false, v => { } ); Checkbox( "Wait for Plugins on Startup (Disabled, can not access Dalamud Configuration)", string.Empty, false, v => { } );
@ -112,7 +113,7 @@ public partial class ConfigWindow
else else
{ {
Checkbox( "Wait for Plugins on Startup", "This changes a setting in the Dalamud Configuration found at /xlsettings -> General.", value, Checkbox( "Wait for Plugins on Startup", "This changes a setting in the Dalamud Configuration found at /xlsettings -> General.", value,
v => Dalamud.SetDalamudConfig( Dalamud.WaitingForPluginsOption, v, "doWaitForPluginsOnStartup" ) ); v => DalamudServices.SetDalamudConfig( DalamudServices.WaitingForPluginsOption, v, "doWaitForPluginsOnStartup" ) );
} }
} }
} }

View file

@ -6,7 +6,8 @@ using ImGuiNET;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Services;
namespace Penumbra.UI; namespace Penumbra.UI;
public partial class ConfigWindow public partial class ConfigWindow
@ -76,21 +77,21 @@ public partial class ConfigWindow
v => v =>
{ {
Penumbra.Config.HideUiWhenUiHidden = v; Penumbra.Config.HideUiWhenUiHidden = v;
Dalamud.PluginInterface.UiBuilder.DisableUserUiHide = !v; DalamudServices.PluginInterface.UiBuilder.DisableUserUiHide = !v;
} ); } );
Checkbox( "Hide Config Window when in Cutscenes", Checkbox( "Hide Config Window when in Cutscenes",
"Hide the penumbra main window when you are currently watching a cutscene.", Penumbra.Config.HideUiInCutscenes, "Hide the penumbra main window when you are currently watching a cutscene.", Penumbra.Config.HideUiInCutscenes,
v => v =>
{ {
Penumbra.Config.HideUiInCutscenes = v; Penumbra.Config.HideUiInCutscenes = v;
Dalamud.PluginInterface.UiBuilder.DisableCutsceneUiHide = !v; DalamudServices.PluginInterface.UiBuilder.DisableCutsceneUiHide = !v;
} ); } );
Checkbox( "Hide Config Window when in GPose", Checkbox( "Hide Config Window when in GPose",
"Hide the penumbra main window when you are currently in GPose mode.", Penumbra.Config.HideUiInGPose, "Hide the penumbra main window when you are currently in GPose mode.", Penumbra.Config.HideUiInGPose,
v => v =>
{ {
Penumbra.Config.HideUiInGPose = v; Penumbra.Config.HideUiInGPose = v;
Dalamud.PluginInterface.UiBuilder.DisableGposeUiHide = !v; DalamudServices.PluginInterface.UiBuilder.DisableGposeUiHide = !v;
} ); } );
ImGui.Dummy( _window._defaultSpace ); ImGui.Dummy( _window._defaultSpace );

View file

@ -11,6 +11,7 @@ using ImGuiNET;
using OtterGui; using OtterGui;
using OtterGui.Raii; using OtterGui.Raii;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Services;
using Penumbra.UI.Classes; using Penumbra.UI.Classes;
namespace Penumbra.UI; namespace Penumbra.UI;
@ -117,7 +118,7 @@ public partial class ConfigWindow
return ( "Path is not allowed to be in ProgramFiles.", false ); return ( "Path is not allowed to be in ProgramFiles.", false );
} }
var dalamud = Dalamud.PluginInterface.ConfigDirectory.Parent!.Parent!; var dalamud = DalamudServices.PluginInterface.ConfigDirectory.Parent!.Parent!;
if( IsSubPathOf( dalamud.FullName, newName ) ) if( IsSubPathOf( dalamud.FullName, newName ) )
{ {
return ( "Path is not allowed to be inside your Dalamud directories.", false ); return ( "Path is not allowed to be inside your Dalamud directories.", false );
@ -128,7 +129,7 @@ public partial class ConfigWindow
return ( "Path is not allowed to be inside your Downloads folder.", false ); return ( "Path is not allowed to be inside your Downloads folder.", false );
} }
var gameDir = Dalamud.GameData.GameData.DataPath.Parent!.Parent!.FullName; var gameDir = DalamudServices.GameData.GameData.DataPath.Parent!.Parent!.FullName;
if( IsSubPathOf( gameDir, newName ) ) if( IsSubPathOf( gameDir, newName ) )
{ {
return ( "Path is not allowed to be inside your game folder.", false ); return ( "Path is not allowed to be inside your game folder.", false );

View file

@ -8,6 +8,7 @@ using OtterGui.Raii;
using OtterGui.Widgets; using OtterGui.Widgets;
using Penumbra.Api.Enums; using Penumbra.Api.Enums;
using Penumbra.Mods; using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI.Classes; using Penumbra.UI.Classes;
using Penumbra.Util; using Penumbra.Util;
@ -54,9 +55,9 @@ public sealed partial class ConfigWindow : Window, IDisposable
Flags |= ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove; Flags |= ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove;
} }
Dalamud.PluginInterface.UiBuilder.DisableGposeUiHide = !Penumbra.Config.HideUiInGPose; DalamudServices.PluginInterface.UiBuilder.DisableGposeUiHide = !Penumbra.Config.HideUiInGPose;
Dalamud.PluginInterface.UiBuilder.DisableCutsceneUiHide = !Penumbra.Config.HideUiInCutscenes; DalamudServices.PluginInterface.UiBuilder.DisableCutsceneUiHide = !Penumbra.Config.HideUiInCutscenes;
Dalamud.PluginInterface.UiBuilder.DisableUserUiHide = !Penumbra.Config.HideUiWhenUiHidden; DalamudServices.PluginInterface.UiBuilder.DisableUserUiHide = !Penumbra.Config.HideUiWhenUiHidden;
RespectCloseHotkey = true; RespectCloseHotkey = true;
SizeConstraints = new WindowSizeConstraints() SizeConstraints = new WindowSizeConstraints()
{ {
@ -96,14 +97,14 @@ public sealed partial class ConfigWindow : Window, IDisposable
else if( !Penumbra.ValidityChecker.IsValidSourceRepo ) else if( !Penumbra.ValidityChecker.IsValidSourceRepo )
{ {
DrawProblemWindow( DrawProblemWindow(
$"You are loading a release version of Penumbra from the repository \"{Dalamud.PluginInterface.SourceRepository}\" instead of the official repository.\n" $"You are loading a release version of Penumbra from the repository \"{DalamudServices.PluginInterface.SourceRepository}\" instead of the official repository.\n"
+ $"Please use the official repository at {ValidityChecker.Repository}.\n\n" + $"Please use the official repository at {ValidityChecker.Repository}.\n\n"
+ "If you are developing for Penumbra and see this, you should compile your version in debug mode to avoid it.", false ); + "If you are developing for Penumbra and see this, you should compile your version in debug mode to avoid it.", false );
} }
else if( Penumbra.ValidityChecker.IsNotInstalledPenumbra ) else if( Penumbra.ValidityChecker.IsNotInstalledPenumbra )
{ {
DrawProblemWindow( DrawProblemWindow(
$"You are loading a release version of Penumbra from \"{Dalamud.PluginInterface.AssemblyLocation.Directory?.FullName ?? "Unknown"}\" instead of the installedPlugins directory.\n\n" $"You are loading a release version of Penumbra from \"{DalamudServices.PluginInterface.AssemblyLocation.Directory?.FullName ?? "Unknown"}\" instead of the installedPlugins directory.\n\n"
+ "You should not install Penumbra manually, but rather add the plugin repository under settings and then install it via the plugin installer.\n\n" + "You should not install Penumbra manually, but rather add the plugin repository under settings and then install it via the plugin installer.\n\n"
+ "If you do not know how to do this, please take a look at the readme in Penumbras github repository or join us in discord.\n" + "If you do not know how to do this, please take a look at the readme in Penumbras github repository or join us in discord.\n"
+ "If you are developing for Penumbra and see this, you should compile your version in debug mode to avoid it.", false ); + "If you are developing for Penumbra and see this, you should compile your version in debug mode to avoid it.", false );
@ -111,7 +112,7 @@ public sealed partial class ConfigWindow : Window, IDisposable
else if( Penumbra.ValidityChecker.DevPenumbraExists ) else if( Penumbra.ValidityChecker.DevPenumbraExists )
{ {
DrawProblemWindow( DrawProblemWindow(
$"You are loading a installed version of Penumbra from \"{Dalamud.PluginInterface.AssemblyLocation.Directory?.FullName ?? "Unknown"}\", " $"You are loading a installed version of Penumbra from \"{DalamudServices.PluginInterface.AssemblyLocation.Directory?.FullName ?? "Unknown"}\", "
+ "but also still have some remnants of a custom install of Penumbra in your devPlugins folder.\n\n" + "but also still have some remnants of a custom install of Penumbra in your devPlugins folder.\n\n"
+ "This can cause some issues, so please go to your \"%%appdata%%\\XIVLauncher\\devPlugins\" folder and delete the Penumbra folder from there.\n\n" + "This can cause some issues, so please go to your \"%%appdata%%\\XIVLauncher\\devPlugins\" folder and delete the Penumbra folder from there.\n\n"
+ "If you are developing for Penumbra, try to avoid mixing versions. This warning will not appear if compiled in Debug mode.", false ); + "If you are developing for Penumbra, try to avoid mixing versions. This warning will not appear if compiled in Debug mode.", false );

View file

@ -2,7 +2,8 @@ using System;
using System.IO; using System.IO;
using Dalamud.Interface; using Dalamud.Interface;
using ImGuiScene; using ImGuiScene;
using Penumbra.Services;
namespace Penumbra.UI; namespace Penumbra.UI;
// A Launch Button used in the title screen of the game, // A Launch Button used in the title screen of the game,
@ -21,17 +22,17 @@ public class LaunchButton : IDisposable
void CreateEntry() void CreateEntry()
{ {
_icon = Dalamud.PluginInterface.UiBuilder.LoadImage( Path.Combine( Dalamud.PluginInterface.AssemblyLocation.DirectoryName!, _icon = DalamudServices.PluginInterface.UiBuilder.LoadImage( Path.Combine( DalamudServices.PluginInterface.AssemblyLocation.DirectoryName!,
"tsmLogo.png" ) ); "tsmLogo.png" ) );
if( _icon != null ) if( _icon != null )
{ {
_entry = Dalamud.TitleScreenMenu.AddEntry( "Manage Penumbra", _icon, OnTriggered ); _entry = DalamudServices.TitleScreenMenu.AddEntry( "Manage Penumbra", _icon, OnTriggered );
} }
Dalamud.PluginInterface.UiBuilder.Draw -= CreateEntry; DalamudServices.PluginInterface.UiBuilder.Draw -= CreateEntry;
} }
Dalamud.PluginInterface.UiBuilder.Draw += CreateEntry; DalamudServices.PluginInterface.UiBuilder.Draw += CreateEntry;
} }
private void OnTriggered() private void OnTriggered()
@ -42,7 +43,7 @@ public class LaunchButton : IDisposable
_icon?.Dispose(); _icon?.Dispose();
if( _entry != null ) if( _entry != null )
{ {
Dalamud.TitleScreenMenu.RemoveEntry( _entry ); DalamudServices.TitleScreenMenu.RemoveEntry( _entry );
} }
} }
} }

View file

@ -6,7 +6,8 @@ using Dalamud.Interface.Internal.Notifications;
using Dalamud.Utility; using Dalamud.Utility;
using Lumina.Excel.GeneratedSheets; using Lumina.Excel.GeneratedSheets;
using OtterGui.Log; using OtterGui.Log;
using Penumbra.Services;
namespace Penumbra.Util; namespace Penumbra.Util;
public static class ChatUtil public static class ChatUtil
@ -30,7 +31,7 @@ public static class ChatUtil
var payload = new SeString( payloadList ); var payload = new SeString( payloadList );
Dalamud.Chat.PrintChat( new XivChatEntry DalamudServices.Chat.PrintChat( new XivChatEntry
{ {
Message = payload, Message = payload,
} ); } );
@ -47,7 +48,7 @@ public static class ChatUtil
NotificationType.Info => Logger.LogLevel.Information, NotificationType.Info => Logger.LogLevel.Information,
_ => Logger.LogLevel.Debug, _ => Logger.LogLevel.Debug,
}; };
Dalamud.PluginInterface.UiBuilder.AddNotification( content, title, type ); DalamudServices.PluginInterface.UiBuilder.AddNotification( content, title, type );
Penumbra.Log.Message( logLevel, title.IsNullOrEmpty() ? content : $"[{title}] {content}" ); Penumbra.Log.Message( logLevel, title.IsNullOrEmpty() ? content : $"[{title}] {content}" );
} }
} }

View file

@ -6,7 +6,6 @@ public enum StartTimeType
{ {
Total, Total,
Identifier, Identifier,
GamePathParser,
Stains, Stains,
Items, Items,
Actors, Actors,
@ -53,7 +52,6 @@ public static class TimingExtensions
{ {
StartTimeType.Total => "Total Construction", StartTimeType.Total => "Total Construction",
StartTimeType.Identifier => "Identification Data", StartTimeType.Identifier => "Identification Data",
StartTimeType.GamePathParser => "Game Path Data",
StartTimeType.Stains => "Stain Data", StartTimeType.Stains => "Stain Data",
StartTimeType.Items => "Item Data", StartTimeType.Items => "Item Data",
StartTimeType.Actors => "Actor Data", StartTimeType.Actors => "Actor Data",

View file

@ -11,6 +11,15 @@
"Unosquare.Swan.Lite": "3.0.0" "Unosquare.Swan.Lite": "3.0.0"
} }
}, },
"Microsoft.Extensions.DependencyInjection": {
"type": "Direct",
"requested": "[7.0.0, )",
"resolved": "7.0.0",
"contentHash": "elNeOmkeX3eDVG6pYVeV82p29hr+UKDaBhrZyWvWLw/EVZSYEkZlQdkp0V39k/Xehs2Qa0mvoCvkVj3eQxNQ1Q==",
"dependencies": {
"Microsoft.Extensions.DependencyInjection.Abstractions": "7.0.0"
}
},
"SharpCompress": { "SharpCompress": {
"type": "Direct", "type": "Direct",
"requested": "[0.32.1, )", "requested": "[0.32.1, )",
@ -27,6 +36,11 @@
"System.Text.Encoding.CodePages": "5.0.0" "System.Text.Encoding.CodePages": "5.0.0"
} }
}, },
"Microsoft.Extensions.DependencyInjection.Abstractions": {
"type": "Transitive",
"resolved": "7.0.0",
"contentHash": "h3j/QfmFN4S0w4C2A6X7arXij/M/OVw3uQHSOFxnND4DyAzO1F9eMX7Eti7lU/OkSthEE0WzRsfT/Dmx86jzCw=="
},
"Microsoft.NETCore.Platforms": { "Microsoft.NETCore.Platforms": {
"type": "Transitive", "type": "Transitive",
"resolved": "5.0.0", "resolved": "5.0.0",
@ -67,8 +81,8 @@
"penumbra.gamedata": { "penumbra.gamedata": {
"type": "Project", "type": "Project",
"dependencies": { "dependencies": {
"Penumbra.Api": "[1.0.5, )", "Penumbra.Api": "[1.0.7, )",
"Penumbra.String": "[1.0.1, )" "Penumbra.String": "[1.0.3, )"
} }
}, },
"penumbra.string": { "penumbra.string": {