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;
internal class GamePathParser : IGamePathParser
public class GamePathParser : IGamePathParser
{
/// <summary> Obtain basic information about a file path. </summary>
public GameObjectInfo GetFileInfo(string path)
{
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)
{
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;
}
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";
/// <summary> Obtain the ObjectType from a given path.</summary>
public ObjectType PathToObjectType(string path)
{
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)
{
if (!Names.ExtensionToFileType.TryGetValue(Path.GetExtension(path), out var fileType))

View file

@ -16,6 +16,7 @@ using Penumbra.Collections;
using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.Meta.Manipulations;
using Penumbra.Services;
namespace Penumbra.Api;
@ -458,17 +459,17 @@ public class IpcTester : IDisposable
}
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" );
var tmp = _redrawIndex;
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();
@ -489,12 +490,12 @@ public class IpcTester : IDisposable
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 = $"{Dalamud.Objects[ index ]!.Name} (0x{address:X}, {index})";
_lastRedrawnString = $"{DalamudServices.Objects[ index ]!.Name} (0x{address:X}, {index})";
}
}

View file

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

View file

@ -11,6 +11,7 @@ using System.Threading.Tasks;
using Dalamud.Interface.Internal.Notifications;
using Penumbra.GameData.Actors;
using Penumbra.Util;
using Penumbra.Services;
namespace Penumbra.Collections;
@ -205,7 +206,7 @@ public partial class ModCollection
=> name.Length == 0 ? Empty.Index : _collections.IndexOf( c => c.Name == name );
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.
// 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 OtterGui.Filesystem;
using Penumbra.Mods;
using Penumbra.Services;
using System;
using System.Collections.Generic;
using System.IO;
@ -14,7 +15,7 @@ namespace Penumbra.Collections;
public partial class ModCollection
{
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.
public FileInfo FileName

View file

@ -9,6 +9,7 @@ using Penumbra.Collections;
using Penumbra.GameData.Actors;
using Penumbra.Interop;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI;
namespace Penumbra;
@ -120,27 +121,27 @@ public class CommandHandler : IDisposable
{
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
{
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 );
Dalamud.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 );
Dalamud.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 );
Dalamud.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( "enable", "Enable modding and force a redraw of all game objects if it was previously disabled." ).BuiltString );
DalamudServices.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( "toggle", "Toggle modding and force a redraw of all game objects." ).BuiltString );
DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "reload", "Rediscover the mod directory and reload all mods." ).BuiltString );
DalamudServices.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( "lockui", "Toggle the locked state of the main Penumbra window. Can be used with [on|off] to force specific state." )
.BuiltString );
Dalamud.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( "debug", "Toggle debug mode for Penumbra. Can be used with [on|off] to force specific state." ).BuiltString );
DalamudServices.Chat.Print( new SeStringBuilder().AddCommand( "collection", "Change your active collection setup. Use without further parameters for more detailed help." )
.BuiltString );
Dalamud.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( "mod", "Change a specific mods settings. Use without further parameters for more detailed help." ).BuiltString );
DalamudServices.Chat.Print( new SeStringBuilder()
.AddCommand( "bulktag", "Change multiple mods settings based on their tags. Use without further parameters for more detailed help." )
.BuiltString );
return true;
@ -240,26 +241,26 @@ public class CommandHandler : IDisposable
{
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 );
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( "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)." )
.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 );
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 );
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 );
Dalamud.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( "r" ).AddText( " | " ).AddWhite( "[Retainer Name]" ).BuiltString );
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" )
.AddInitialPurple( "Event NPC" ).AddText( "or " )
.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 );
return true;
}
@ -269,13 +270,13 @@ public class CommandHandler : IDisposable
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;
}
if( split.Length == 1 )
{
Dalamud.Chat.Print( "There was no collection name provided." );
DalamudServices.Chat.Print( "There was no collection name provided." );
return false;
}
@ -289,7 +290,7 @@ public class CommandHandler : IDisposable
{
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;
}
@ -300,7 +301,7 @@ public class CommandHandler : IDisposable
identifier = _actors.FromObject( obj, false, true, true );
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 );
return false;
}
@ -312,7 +313,7 @@ public class CommandHandler : IDisposable
}
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 );
return false;
}
@ -321,7 +322,7 @@ public class CommandHandler : IDisposable
var oldCollection = _collectionManager.ByType( type, identifier );
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"
: $"{collection.Name} already is the {type.ToName()} Collection{( identifier.IsValid ? $" for {identifier}." : "." )}" );
return false;
@ -354,7 +355,7 @@ public class CommandHandler : IDisposable
}
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;
}
@ -374,7 +375,7 @@ public class CommandHandler : IDisposable
var seString = new SeStringBuilder()
.AddText( "Use with /penumbra mod " ).AddBlue( "[enable|disable|inherit|toggle]" ).AddText( " " ).AddYellow( "[Collection Name]" ).AddText( " | " )
.AddPurple( "[Mod Name or Mod Directory Name]" );
Dalamud.Chat.Print( seString.BuiltString );
DalamudServices.Chat.Print( seString.BuiltString );
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 );
if( nameSplit.Length != 2 )
{
Dalamud.Chat.Print( "Not enough arguments provided." );
DalamudServices.Chat.Print( "Not enough arguments provided." );
return false;
}
var state = ConvertToSettingState( split[ 0 ] );
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;
}
@ -400,7 +401,7 @@ public class CommandHandler : IDisposable
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;
}
@ -409,7 +410,7 @@ public class CommandHandler : IDisposable
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 );
return false;
}
@ -421,7 +422,7 @@ public class CommandHandler : IDisposable
var seString = new SeStringBuilder()
.AddText( "Use with /penumbra bulktag " ).AddBlue( "[enable|disable|toggle|inherit]" ).AddText( " " ).AddYellow( "[Collection Name]" ).AddText( " | " )
.AddPurple( "[Local Tag]" );
Dalamud.Chat.Print( seString.BuiltString );
DalamudServices.Chat.Print( seString.BuiltString );
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 );
if( nameSplit.Length != 2 )
{
Dalamud.Chat.Print( "Not enough arguments provided." );
DalamudServices.Chat.Print( "Not enough arguments provided." );
return false;
}
@ -437,7 +438,7 @@ public class CommandHandler : IDisposable
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;
}
@ -450,7 +451,7 @@ public class CommandHandler : IDisposable
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;
}
@ -482,7 +483,7 @@ public class CommandHandler : IDisposable
: _collectionManager[ lowerName ];
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;
}
@ -574,7 +575,7 @@ public class CommandHandler : IDisposable
{
if( Penumbra.Config.PrintSuccessfulCommandsToChat )
{
Dalamud.Chat.Print( text );
DalamudServices.Chat.Print( text );
}
}
@ -582,7 +583,7 @@ public class CommandHandler : IDisposable
{
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 )
{
Dalamud.Chat.Print( text() );
DalamudServices.Chat.Print( text() );
}
}
}

View file

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

View file

@ -11,6 +11,7 @@ using OtterGui.Widgets;
using Penumbra.GameData.Enums;
using Penumbra.Import;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI;
using Penumbra.UI.Classes;
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
@ -97,9 +98,9 @@ public partial class Configuration : IPluginConfiguration
}
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
{
Error = HandleDeserializationError,
@ -125,7 +126,7 @@ public partial class Configuration : IPluginConfiguration
try
{
var text = JsonConvert.SerializeObject( this, Formatting.Indented );
File.WriteAllText( Dalamud.PluginInterface.ConfigFile.FullName, text );
File.WriteAllText( DalamudServices.PluginInterface.ConfigFile.FullName, text );
}
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 Lumina.Data.Files;
using OtterTex;
using Penumbra.Services;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
@ -48,7 +49,7 @@ public partial class CombinedTexture : IDisposable
{
var (width, height) = CombineImage();
_centerStorage.TextureWrap =
Dalamud.PluginInterface.UiBuilder.LoadImageRaw( _centerStorage.RGBAPixels, width, height, 4 );
DalamudServices.PluginInterface.UiBuilder.LoadImageRaw( _centerStorage.RGBAPixels, width, height, 4 );
}
_current?.Draw( size );

View file

@ -10,6 +10,7 @@ using Lumina.Data.Files;
using OtterGui;
using OtterGui.Raii;
using OtterTex;
using Penumbra.Services;
using Penumbra.String.Classes;
using Penumbra.UI.Classes;
using SixLabors.ImageSharp.PixelFormats;
@ -195,12 +196,12 @@ public sealed class Texture : IDisposable
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." );
}
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;
@ -215,7 +216,7 @@ public sealed class Texture : IDisposable
{
if( game )
{
if( !Dalamud.GameData.FileExists( path ) )
if( !DalamudServices.GameData.FileExists( path ) )
{
continue;
}

View file

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

View file

@ -4,18 +4,22 @@ using Penumbra.GameData;
using System;
using FFXIVClientStructs.FFXIV.Client.Game.Character;
using FFXIVClientStructs.FFXIV.Client.Game.Object;
using OtterGui.Log;
using Penumbra.Interop.Structs;
namespace Penumbra.Interop;
public unsafe class GameEventManager : IDisposable
{
private const string Prefix = $"[{nameof(GameEventManager)}]";
public GameEventManager()
{
SignatureHelper.Initialise(this);
_characterDtorHook.Enable();
_copyCharacterHook.Enable();
_resourceHandleDestructorHook.Enable();
Penumbra.Log.Verbose($"{Prefix} Created.");
}
public void Dispose()
@ -23,6 +27,7 @@ public unsafe class GameEventManager : IDisposable
_characterDtorHook.Dispose();
_copyCharacterHook.Dispose();
_resourceHandleDestructorHook.Dispose();
Penumbra.Log.Verbose($"{Prefix} Disposed.");
}
#region Character Destructor
@ -35,7 +40,6 @@ public unsafe class GameEventManager : IDisposable
private void CharacterDestructorDetour(Character* character)
{
if (CharacterDestructor != null)
{
foreach (var subscriber in CharacterDestructor.GetInvocationList())
{
try
@ -44,12 +48,11 @@ public unsafe class GameEventManager : IDisposable
}
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);
}
@ -68,7 +71,6 @@ public unsafe class GameEventManager : IDisposable
private ulong CopyCharacterDetour(GameObject* target, GameObject* source, uint unk)
{
if (CopyCharacter != null)
{
foreach (var subscriber in CopyCharacter.GetInvocationList())
{
try
@ -77,12 +79,13 @@ public unsafe class GameEventManager : IDisposable
}
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(
$"{Prefix} {nameof(CopyCharacter)} triggered with target 0x{(nint)target:X} and source 0x{(nint)source:X}.");
return _copyCharacterHook.Original(target, source, unk);
}
@ -101,7 +104,6 @@ public unsafe class GameEventManager : IDisposable
private IntPtr ResourceHandleDestructorDetour(ResourceHandle* handle)
{
if (ResourceHandleDestructor != null)
{
foreach (var subscriber in ResourceHandleDestructor.GetInvocationList())
{
try
@ -110,12 +112,12 @@ public unsafe class GameEventManager : IDisposable
}
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);
}

View file

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

View file

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

View file

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

View file

@ -5,6 +5,7 @@ using Penumbra.Collections;
using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.Interop.Structs;
using Penumbra.Services;
using Penumbra.String;
using Penumbra.String.Classes;
using Penumbra.Util;
@ -137,9 +138,9 @@ public unsafe partial class PathResolver
{
var getGameObjectIdx = ( ( delegate* unmanaged< IntPtr, int >** )timeline )[ 0 ][ Offsets.GetGameObjectIdxVfunc ];
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;
}
}
@ -203,9 +204,9 @@ public unsafe partial class PathResolver
if( timelinePtr != IntPtr.Zero )
{
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 )
{
var owner = Dalamud.Objects.SearchById( id );
var owner = DalamudServices.Objects.SearchById( id );
if( owner == null )
{
return null;
}
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 )
@ -251,8 +252,8 @@ public unsafe partial class PathResolver
{
var obj = vfxParams->GameObjectType switch
{
0 => Dalamud.Objects.SearchById( vfxParams->GameObjectId ),
2 => Dalamud.Objects[ ( int )vfxParams->GameObjectId ],
0 => DalamudServices.Objects.SearchById( vfxParams->GameObjectId ),
2 => DalamudServices.Objects[ ( int )vfxParams->GameObjectId ],
4 => GetOwnedObject( vfxParams->GameObjectId ),
_ => null,
};

View file

@ -12,6 +12,7 @@ using Penumbra.GameData;
using Penumbra.GameData.Enums;
using Penumbra.String.Classes;
using Penumbra.Util;
using Penumbra.Services;
namespace Penumbra.Interop.Resolver;
@ -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.
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;
if( gameObject != null
&& ( 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.
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 )
{
_drawObjectToObject[ ( IntPtr )ptr->DrawObject ] = ( IdentifyCollection( ptr, false ), ptr->ObjectIndex );

View file

@ -8,6 +8,7 @@ using OtterGui;
using Penumbra.Collections;
using Penumbra.GameData.Actors;
using Penumbra.GameData.Enums;
using Penumbra.Services;
using Penumbra.Util;
using Character = FFXIVClientStructs.FFXIV.Client.Game.Character.Character;
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,
// so it is not possible to fetch names from the ui list.
// 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 )
?? CollectionByAttributes( gameObject )
@ -46,7 +47,7 @@ public unsafe partial class PathResolver
}
// 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 collection2 = ( player.IsValid ? CollectionByIdentifier( player ) : null )
@ -86,7 +87,7 @@ public unsafe partial class PathResolver
public static ModCollection PlayerCollection()
{
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 )
{
return Penumbra.CollectionManager.ByType( CollectionType.Yourself )

View file

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

View file

@ -5,6 +5,7 @@ using Penumbra.GameData.Enums;
using Penumbra.GameData.Structs;
using Penumbra.Interop.Structs;
using Penumbra.Meta.Manipulations;
using Penumbra.Services;
using Penumbra.String.Classes;
using Penumbra.String.Functions;
@ -140,7 +141,7 @@ public unsafe class ImcFile : MetaBaseFile
public override void Reset()
{
var file = Dalamud.GameData.GetFile( Path.ToString() );
var file = DalamudServices.GameData.GetFile( Path.ToString() );
fixed( byte* ptr = file!.Data )
{
MemoryUtility.MemCpyUnchecked( Data, ptr, file.Data.Length );
@ -152,7 +153,7 @@ public unsafe class ImcFile : MetaBaseFile
: base( 0 )
{
Path = manip.GamePath();
var file = Dalamud.GameData.GetFile( Path.ToString() );
var file = DalamudServices.GameData.GetFile( Path.ToString() );
if( file == null )
{
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 )
{
var file = Dalamud.GameData.GetFile( path );
var file = DalamudServices.GameData.GetFile( path );
exists = false;
if( file == null )
{

View file

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

View file

@ -8,6 +8,7 @@ using System.Linq;
using System.Security.Cryptography;
using Penumbra.GameData.Enums;
using static Penumbra.Mods.ItemSwap.ItemSwap;
using Penumbra.Services;
namespace Penumbra.Mods.ItemSwap;
@ -139,7 +140,7 @@ public sealed class FileSwap : Swap
}
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.FileData = type switch

View file

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

View file

@ -5,13 +5,14 @@ using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using OtterGui.Filesystem;
using Penumbra.Services;
namespace Penumbra.Mods;
public sealed class ModFileSystem : FileSystem< Mod >, IDisposable
{
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.
// 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 ImGuiNET;
using Lumina.Excel.GeneratedSheets;
using Microsoft.Extensions.DependencyInjection;
using OtterGui;
using OtterGui.Classes;
using OtterGui.Log;
@ -31,6 +32,42 @@ using ResidentResourceManager = Penumbra.Interop.ResidentResourceManager;
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 string Name
@ -87,22 +124,24 @@ public class Penumbra : IDalamudPlugin
try
{
Dalamud.Initialize( pluginInterface );
DalamudServices.Initialize( pluginInterface );
Performance = new PerformanceTracker< PerformanceType >( Dalamud.Framework );
Performance = new PerformanceTracker< PerformanceType >( DalamudServices.Framework );
Log = new Logger();
ValidityChecker = new ValidityChecker( Dalamud.PluginInterface );
ValidityChecker = new ValidityChecker( DalamudServices.PluginInterface );
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.Stains, () => StainManager = new StainManager( Dalamud.PluginInterface, Dalamud.GameData ) );
ItemData = StartTimer.Measure( StartTimeType.Items, () => new ItemData( Dalamud.PluginInterface, Dalamud.GameData, Dalamud.GameData.Language ) );
StartTimer.Measure( StartTimeType.Stains, () => StainManager = new StainManager( DalamudServices.PluginInterface, DalamudServices.GameData ) );
ItemData = StartTimer.Measure( StartTimeType.Items,
() => new ItemData( DalamudServices.PluginInterface, DalamudServices.GameData, DalamudServices.GameData.Language ) );
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 ) );
Framework = new FrameworkManager( Dalamud.Framework, Log );
Framework = new FrameworkManager( DalamudServices.Framework, Log );
CharacterUtility = new CharacterUtility();
StartTimer.Measure( StartTimeType.Backup, () => Backup.CreateBackup( pluginInterface.ConfigDirectory, PenumbraBackupFiles() ) );
@ -147,7 +186,7 @@ public class Penumbra : IDalamudPlugin
using( var tApi = StartTimer.Measure( StartTimeType.Api ) )
{
Api = new PenumbraApi( this );
IpcProviders = new PenumbraIpcProviders( Dalamud.PluginInterface, Api );
IpcProviders = new PenumbraIpcProviders( DalamudServices.PluginInterface, Api );
HttpApi = new HttpApi( Api );
if( Config.EnableHttpApi )
{
@ -159,7 +198,7 @@ public class Penumbra : IDalamudPlugin
ValidityChecker.LogExceptions();
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}." );
if( CharacterUtility.Ready )
@ -186,7 +225,7 @@ public class Penumbra : IDalamudPlugin
};
var btn = new LaunchButton( cfg );
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.ModEditPopup );
system.AddWindow( changelog );
@ -197,8 +236,8 @@ public class Penumbra : IDalamudPlugin
_windowSystem = system;
_launchButton = btn;
_commandHandler = cmd;
Dalamud.PluginInterface.UiBuilder.OpenConfigUi += cfg.Toggle;
Dalamud.PluginInterface.UiBuilder.Draw += _windowSystem.Draw;
DalamudServices.PluginInterface.UiBuilder.OpenConfigUi += cfg.Toggle;
DalamudServices.PluginInterface.UiBuilder.Draw += _windowSystem.Draw;
}
else
{
@ -214,13 +253,13 @@ public class Penumbra : IDalamudPlugin
{
if( _windowSystem != null )
{
Dalamud.PluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
DalamudServices.PluginInterface.UiBuilder.Draw -= _windowSystem.Draw;
}
_launchButton?.Dispose();
if( ConfigWindow != null )
{
Dalamud.PluginInterface.UiBuilder.OpenConfigUi -= ConfigWindow.Toggle;
DalamudServices.PluginInterface.UiBuilder.OpenConfigUi -= ConfigWindow.Toggle;
ConfigWindow.Dispose();
}
}
@ -331,7 +370,7 @@ public class Penumbra : IDalamudPlugin
? new DirectoryInfo( collectionDir ).EnumerateFiles( "*.json" ).ToList()
: new List< 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( ModCollection.Manager.ActiveCollectionFile ) );
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( $"> **`Auto-Deduplication: `** {Config.AutoDeduplicateOnImport}\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( $"> **`Use Ownership: `** {Config.UseOwnerNameForCharacterCollection}\n" );
sb.AppendLine( "**Mods**" );

View file

@ -71,6 +71,7 @@
<PackageReference Include="EmbedIO" Version="3.4.3" />
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.2" />
<PackageReference Include="SharpCompress" Version="0.32.1" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0" />
</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.IO;
using System.Linq;
using System.Reflection;
using Dalamud.Interface.Internal.Notifications;
using Dalamud.Plugin;
using Penumbra.Util;
@ -20,11 +21,18 @@ public class ValidityChecker
public readonly List<Exception> ImcExceptions = new();
public readonly string Version;
public readonly string CommitHash;
public ValidityChecker(DalamudPluginInterface pi)
{
DevPenumbraExists = CheckDevPluginPenumbra(pi);
IsNotInstalledPenumbra = CheckIsNotInstalled(pi);
IsValidSourceRepo = CheckSourceRepo(pi);
var assembly = Assembly.GetExecutingAssembly();
Version = assembly.GetName().Version?.ToString() ?? string.Empty;
CommitHash = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "Unknown";
}
public void LogExceptions()

View file

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

View file

@ -10,6 +10,7 @@ using OtterGui.Classes;
using OtterGui.Raii;
using Penumbra.GameData.Data;
using Penumbra.GameData.Files;
using Penumbra.Services;
using Penumbra.String.Classes;
using Penumbra.Util;
using static Penumbra.GameData.Files.ShpkFile;
@ -80,7 +81,7 @@ public partial class ModEditWindow
LoadedShpkPath = path;
var data = LoadedShpkPath.IsRooted
? 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." );
LoadedShpkPathName = path.ToPath();
}

View file

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

View file

@ -11,6 +11,7 @@ using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Interface.Components;
using OtterGui.Widgets;
using Penumbra.GameData.Actors;
using Penumbra.Services;
namespace Penumbra.UI;
@ -287,7 +288,7 @@ public partial class ConfigWindow
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 tt = result switch
{

View file

@ -14,6 +14,7 @@ using Penumbra.GameData.Files;
using Penumbra.Interop.Loader;
using Penumbra.Interop.Resolver;
using Penumbra.Interop.Structs;
using Penumbra.Services;
using Penumbra.String;
using Penumbra.Util;
using static OtterGui.Raii.ImRaii;
@ -207,7 +208,7 @@ public partial class ConfigWindow
DrawSpecial( "Current Card", Penumbra.Actors.GetCardPlayer() );
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( $"0x{obj.Address:X}" );
@ -243,7 +244,7 @@ public partial class ConfigWindow
ImGui.TableNextColumn();
ImGui.TextUnformatted( idx.ToString() );
ImGui.TableNextColumn();
var obj = ( GameObject* )Dalamud.Objects.GetObjectAddress( idx );
var obj = ( GameObject* )DalamudServices.Objects.GetObjectAddress( idx );
var (address, name) =
obj != null ? ( $"0x{( ulong )obj:X}", new ByteString( obj->Name ).ToString() ) : ( "NULL", "NULL" );
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.
private static unsafe void DrawPlayerModelInfo()
{
var player = Dalamud.ClientState.LocalPlayer;
var player = DalamudServices.ClientState.LocalPlayer;
var name = player?.Name.ToString() ?? "NULL";
if( !ImGui.CollapsingHeader( $"Player Model Info: {name}##Draw" ) || player == null )
{

View file

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

View file

@ -9,6 +9,7 @@ using System.Numerics;
using Dalamud.Interface;
using OtterGui.Widgets;
using Penumbra.Api.Enums;
using Penumbra.Services;
namespace Penumbra.UI;
@ -121,7 +122,7 @@ public partial class ConfigWindow
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();
var buttonWidth = frameHeight with { X = ImGui.GetContentRegionAvail().X / 4 };
DrawButton( buttonWidth, "All", string.Empty );

View file

@ -11,6 +11,7 @@ using OtterGui;
using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.Interop.Loader;
using Penumbra.Services;
using Penumbra.String.Classes;
namespace Penumbra.UI;
@ -50,7 +51,7 @@ public partial class ConfigWindow
ImGui.NewLine();
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}" );
}
}

View file

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

View file

@ -11,6 +11,7 @@ using ImGuiNET;
using OtterGui;
using OtterGui.Raii;
using OtterGui.Widgets;
using Penumbra.Services;
using Penumbra.UI.Classes;
namespace Penumbra.UI;
@ -117,7 +118,7 @@ public partial class ConfigWindow
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 ) )
{
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 );
}
var gameDir = Dalamud.GameData.GameData.DataPath.Parent!.Parent!.FullName;
var gameDir = DalamudServices.GameData.GameData.DataPath.Parent!.Parent!.FullName;
if( IsSubPathOf( gameDir, newName ) )
{
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 Penumbra.Api.Enums;
using Penumbra.Mods;
using Penumbra.Services;
using Penumbra.UI.Classes;
using Penumbra.Util;
@ -54,9 +55,9 @@ public sealed partial class ConfigWindow : Window, IDisposable
Flags |= ImGuiWindowFlags.NoResize | ImGuiWindowFlags.NoMove;
}
Dalamud.PluginInterface.UiBuilder.DisableGposeUiHide = !Penumbra.Config.HideUiInGPose;
Dalamud.PluginInterface.UiBuilder.DisableCutsceneUiHide = !Penumbra.Config.HideUiInCutscenes;
Dalamud.PluginInterface.UiBuilder.DisableUserUiHide = !Penumbra.Config.HideUiWhenUiHidden;
DalamudServices.PluginInterface.UiBuilder.DisableGposeUiHide = !Penumbra.Config.HideUiInGPose;
DalamudServices.PluginInterface.UiBuilder.DisableCutsceneUiHide = !Penumbra.Config.HideUiInCutscenes;
DalamudServices.PluginInterface.UiBuilder.DisableUserUiHide = !Penumbra.Config.HideUiWhenUiHidden;
RespectCloseHotkey = true;
SizeConstraints = new WindowSizeConstraints()
{
@ -96,14 +97,14 @@ public sealed partial class ConfigWindow : Window, IDisposable
else if( !Penumbra.ValidityChecker.IsValidSourceRepo )
{
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"
+ "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 )
{
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"
+ "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 );
@ -111,7 +112,7 @@ public sealed partial class ConfigWindow : Window, IDisposable
else if( Penumbra.ValidityChecker.DevPenumbraExists )
{
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"
+ "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 );

View file

@ -2,6 +2,7 @@ using System;
using System.IO;
using Dalamud.Interface;
using ImGuiScene;
using Penumbra.Services;
namespace Penumbra.UI;
@ -21,17 +22,17 @@ public class LaunchButton : IDisposable
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" ) );
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()
@ -42,7 +43,7 @@ public class LaunchButton : IDisposable
_icon?.Dispose();
if( _entry != null )
{
Dalamud.TitleScreenMenu.RemoveEntry( _entry );
DalamudServices.TitleScreenMenu.RemoveEntry( _entry );
}
}
}

View file

@ -6,6 +6,7 @@ using Dalamud.Interface.Internal.Notifications;
using Dalamud.Utility;
using Lumina.Excel.GeneratedSheets;
using OtterGui.Log;
using Penumbra.Services;
namespace Penumbra.Util;
@ -30,7 +31,7 @@ public static class ChatUtil
var payload = new SeString( payloadList );
Dalamud.Chat.PrintChat( new XivChatEntry
DalamudServices.Chat.PrintChat( new XivChatEntry
{
Message = payload,
} );
@ -47,7 +48,7 @@ public static class ChatUtil
NotificationType.Info => Logger.LogLevel.Information,
_ => 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}" );
}
}

View file

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

View file

@ -11,6 +11,15 @@
"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": {
"type": "Direct",
"requested": "[0.32.1, )",
@ -27,6 +36,11 @@
"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": {
"type": "Transitive",
"resolved": "5.0.0",
@ -67,8 +81,8 @@
"penumbra.gamedata": {
"type": "Project",
"dependencies": {
"Penumbra.Api": "[1.0.5, )",
"Penumbra.String": "[1.0.1, )"
"Penumbra.Api": "[1.0.7, )",
"Penumbra.String": "[1.0.3, )"
}
},
"penumbra.string": {