mirror of
https://github.com/xivdev/Penumbra.git
synced 2025-12-12 18:27:24 +01:00
Update to API4, use IPC instead of API-project. Replace Actor in most visible names with Object, Character or Player..
This commit is contained in:
parent
3680d2b63f
commit
4dfc2cf665
60 changed files with 812 additions and 740 deletions
|
|
@ -1,41 +0,0 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net472</TargetFramework>
|
|
||||||
<LangVersion>preview</LangVersion>
|
|
||||||
<AssemblyTitle>Penumbra.Api</AssemblyTitle>
|
|
||||||
<Company>absolute gangstas</Company>
|
|
||||||
<Product>Penumbra</Product>
|
|
||||||
<Copyright>Copyright © 2020</Copyright>
|
|
||||||
<FileVersion>1.0.0.0</FileVersion>
|
|
||||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
|
||||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
|
||||||
<DebugType>full</DebugType>
|
|
||||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
|
||||||
<DebugType>pdbonly</DebugType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<MSBuildWarningsAsMessages>$(MSBuildWarningsAsMessages);MSB3277</MSBuildWarningsAsMessages>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="Dalamud">
|
|
||||||
<HintPath>$(DALAMUD_ROOT)\Dalamud.dll</HintPath>
|
|
||||||
<HintPath>..\libs\Dalamud.dll</HintPath>
|
|
||||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Dalamud.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
<Reference Include="Lumina">
|
|
||||||
<HintPath>$(AppData)\XIVLauncher\addon\Hooks\dev\Lumina.dll</HintPath>
|
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
namespace Penumbra.Api
|
namespace Penumbra.GameData.Enums
|
||||||
{
|
{
|
||||||
public enum RedrawType
|
public enum RedrawType
|
||||||
{
|
{
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Dalamud;
|
||||||
|
using Dalamud.Data;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
|
|
@ -13,9 +15,9 @@ namespace Penumbra.GameData
|
||||||
internal static ObjectIdentification? Identification;
|
internal static ObjectIdentification? Identification;
|
||||||
internal static readonly GamePathParser GamePathParser = new();
|
internal static readonly GamePathParser GamePathParser = new();
|
||||||
|
|
||||||
public static IObjectIdentifier GetIdentifier( DalamudPluginInterface pi )
|
public static IObjectIdentifier GetIdentifier( DataManager dataManager, ClientLanguage clientLanguage )
|
||||||
{
|
{
|
||||||
Identification ??= new ObjectIdentification( pi );
|
Identification ??= new ObjectIdentification( dataManager, clientLanguage );
|
||||||
return Identification;
|
return Identification;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Dalamud.Plugin;
|
using Dalamud;
|
||||||
|
using Dalamud.Data;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
@ -63,9 +64,9 @@ namespace Penumbra.GameData
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ObjectIdentification( DalamudPluginInterface plugin )
|
public ObjectIdentification( DataManager dataManager, ClientLanguage clientLanguage )
|
||||||
{
|
{
|
||||||
var items = plugin.Data.GetExcelSheet< Item >( plugin.ClientState.ClientLanguage );
|
var items = dataManager.GetExcelSheet< Item >( clientLanguage )!;
|
||||||
SortedList< ulong, HashSet< Item > > weapons = new();
|
SortedList< ulong, HashSet< Item > > weapons = new();
|
||||||
SortedList< ulong, HashSet< Item > > equipment = new();
|
SortedList< ulong, HashSet< Item > > equipment = new();
|
||||||
foreach( var item in items )
|
foreach( var item in items )
|
||||||
|
|
@ -112,7 +113,7 @@ namespace Penumbra.GameData
|
||||||
}
|
}
|
||||||
|
|
||||||
_actions = new Dictionary< string, HashSet< Action > >();
|
_actions = new Dictionary< string, HashSet< Action > >();
|
||||||
foreach( var action in plugin.Data.GetExcelSheet< Action >( plugin.ClientState.ClientLanguage )
|
foreach( var action in dataManager.GetExcelSheet< Action >( clientLanguage )!
|
||||||
.Where( a => a.Name.ToString().Any() ) )
|
.Where( a => a.Name.ToString().Any() ) )
|
||||||
{
|
{
|
||||||
var startKey = action.AnimationStart?.Value?.Name?.Value?.Key.ToString() ?? string.Empty;
|
var startKey = action.AnimationStart?.Value?.Name?.Value?.Key.ToString() ?? string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net5.0-windows</TargetFramework>
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<AssemblyTitle>Penumbra.GameData</AssemblyTitle>
|
<AssemblyTitle>Penumbra.GameData</AssemblyTitle>
|
||||||
<Company>absolute gangstas</Company>
|
<Company>absolute gangstas</Company>
|
||||||
<Product>Penumbra</Product>
|
<Product>Penumbra</Product>
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
||||||
namespace Penumbra.GameData.Structs
|
namespace Penumbra.GameData.Structs
|
||||||
{
|
{
|
||||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||||
public readonly struct ActorArmor
|
public readonly struct CharacterArmor
|
||||||
{
|
{
|
||||||
public readonly SetId Set;
|
public readonly SetId Set;
|
||||||
public readonly byte Variant;
|
public readonly byte Variant;
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Penumbra.GameData.Enums;
|
|
||||||
|
|
||||||
// Read the customization data regarding weapons and displayable equipment from an actor struct.
|
// Read the customization data regarding weapons and displayable equipment from an actor struct.
|
||||||
// Stores the data in a 56 bytes, i.e. 7 longs for easier comparison.
|
// Stores the data in a 56 bytes, i.e. 7 longs for easier comparison.
|
||||||
namespace Penumbra.GameData.Structs
|
namespace Penumbra.GameData.Structs
|
||||||
{
|
{
|
||||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||||
public class ActorEquipment
|
public class CharacterEquipment
|
||||||
{
|
{
|
||||||
public const int MainWeaponOffset = 0x0F08;
|
public const int MainWeaponOffset = 0x0F08;
|
||||||
public const int OffWeaponOffset = 0x0F70;
|
public const int OffWeaponOffset = 0x0F70;
|
||||||
|
|
@ -16,24 +15,24 @@ namespace Penumbra.GameData.Structs
|
||||||
public const int EquipmentSlots = 10;
|
public const int EquipmentSlots = 10;
|
||||||
public const int WeaponSlots = 2;
|
public const int WeaponSlots = 2;
|
||||||
|
|
||||||
public ActorWeapon MainHand;
|
public CharacterWeapon MainHand;
|
||||||
public ActorWeapon OffHand;
|
public CharacterWeapon OffHand;
|
||||||
public ActorArmor Head;
|
public CharacterArmor Head;
|
||||||
public ActorArmor Body;
|
public CharacterArmor Body;
|
||||||
public ActorArmor Hands;
|
public CharacterArmor Hands;
|
||||||
public ActorArmor Legs;
|
public CharacterArmor Legs;
|
||||||
public ActorArmor Feet;
|
public CharacterArmor Feet;
|
||||||
public ActorArmor Ears;
|
public CharacterArmor Ears;
|
||||||
public ActorArmor Neck;
|
public CharacterArmor Neck;
|
||||||
public ActorArmor Wrists;
|
public CharacterArmor Wrists;
|
||||||
public ActorArmor RFinger;
|
public CharacterArmor RFinger;
|
||||||
public ActorArmor LFinger;
|
public CharacterArmor LFinger;
|
||||||
public ushort IsSet; // Also fills struct size to 56, a multiple of 8.
|
public ushort IsSet; // Also fills struct size to 56, a multiple of 8.
|
||||||
|
|
||||||
public ActorEquipment()
|
public CharacterEquipment()
|
||||||
=> Clear();
|
=> Clear();
|
||||||
|
|
||||||
public ActorEquipment( Actor actor )
|
public CharacterEquipment( Character actor )
|
||||||
: this( actor.Address )
|
: this( actor.Address )
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
|
@ -43,40 +42,40 @@ namespace Penumbra.GameData.Structs
|
||||||
: $"({MainHand}) | ({OffHand}) | ({Head}) | ({Body}) | ({Hands}) | ({Legs}) | "
|
: $"({MainHand}) | ({OffHand}) | ({Head}) | ({Body}) | ({Hands}) | ({Legs}) | "
|
||||||
+ $"({Feet}) | ({Ears}) | ({Neck}) | ({Wrists}) | ({LFinger}) | ({RFinger})";
|
+ $"({Feet}) | ({Ears}) | ({Neck}) | ({Wrists}) | ({LFinger}) | ({RFinger})";
|
||||||
|
|
||||||
public bool Equal( Actor rhs )
|
public bool Equal( Character rhs )
|
||||||
=> CompareData( new ActorEquipment( rhs ) );
|
=> CompareData( new CharacterEquipment( rhs ) );
|
||||||
|
|
||||||
public bool Equal( ActorEquipment rhs )
|
public bool Equal( CharacterEquipment rhs )
|
||||||
=> CompareData( rhs );
|
=> CompareData( rhs );
|
||||||
|
|
||||||
public bool CompareAndUpdate( Actor rhs )
|
public bool CompareAndUpdate( Character rhs )
|
||||||
=> CompareAndOverwrite( new ActorEquipment( rhs ) );
|
=> CompareAndOverwrite( new CharacterEquipment( rhs ) );
|
||||||
|
|
||||||
public bool CompareAndUpdate( ActorEquipment rhs )
|
public bool CompareAndUpdate( CharacterEquipment rhs )
|
||||||
=> CompareAndOverwrite( rhs );
|
=> CompareAndOverwrite( rhs );
|
||||||
|
|
||||||
private unsafe ActorEquipment( IntPtr actorAddress )
|
private unsafe CharacterEquipment( IntPtr actorAddress )
|
||||||
{
|
{
|
||||||
IsSet = 1;
|
IsSet = 1;
|
||||||
var actorPtr = ( byte* )actorAddress.ToPointer();
|
var actorPtr = ( byte* )actorAddress.ToPointer();
|
||||||
fixed( ActorWeapon* main = &MainHand, off = &OffHand )
|
fixed( CharacterWeapon* main = &MainHand, off = &OffHand )
|
||||||
{
|
{
|
||||||
Buffer.MemoryCopy( actorPtr + MainWeaponOffset, main, sizeof( ActorWeapon ), sizeof( ActorWeapon ) );
|
Buffer.MemoryCopy( actorPtr + MainWeaponOffset, main, sizeof( CharacterWeapon ), sizeof( CharacterWeapon ) );
|
||||||
Buffer.MemoryCopy( actorPtr + OffWeaponOffset, off, sizeof( ActorWeapon ), sizeof( ActorWeapon ) );
|
Buffer.MemoryCopy( actorPtr + OffWeaponOffset, off, sizeof( CharacterWeapon ), sizeof( CharacterWeapon ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
fixed( ActorArmor* equipment = &Head )
|
fixed( CharacterArmor* equipment = &Head )
|
||||||
{
|
{
|
||||||
Buffer.MemoryCopy( actorPtr + EquipmentOffset, equipment, EquipmentSlots * sizeof( ActorArmor ),
|
Buffer.MemoryCopy( actorPtr + EquipmentOffset, equipment, EquipmentSlots * sizeof( CharacterArmor ),
|
||||||
EquipmentSlots * sizeof( ActorArmor ) );
|
EquipmentSlots * sizeof( CharacterArmor ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Clear()
|
public unsafe void Clear()
|
||||||
{
|
{
|
||||||
fixed( ActorWeapon* main = &MainHand )
|
fixed( CharacterWeapon* main = &MainHand )
|
||||||
{
|
{
|
||||||
var structSizeEights = ( 2 + EquipmentSlots * sizeof( ActorArmor ) + WeaponSlots * sizeof( ActorWeapon ) ) / 8;
|
var structSizeEights = ( 2 + EquipmentSlots * sizeof( CharacterArmor ) + WeaponSlots * sizeof( CharacterWeapon ) ) / 8;
|
||||||
for( ulong* ptr = ( ulong* )main, end = ptr + structSizeEights; ptr != end; ++ptr )
|
for( ulong* ptr = ( ulong* )main, end = ptr + structSizeEights; ptr != end; ++ptr )
|
||||||
{
|
{
|
||||||
*ptr = 0;
|
*ptr = 0;
|
||||||
|
|
@ -84,11 +83,11 @@ namespace Penumbra.GameData.Structs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe bool CompareAndOverwrite( ActorEquipment rhs )
|
private unsafe bool CompareAndOverwrite( CharacterEquipment rhs )
|
||||||
{
|
{
|
||||||
var structSizeEights = ( 2 + EquipmentSlots * sizeof( ActorArmor ) + WeaponSlots * sizeof( ActorWeapon ) ) / 8;
|
var structSizeEights = ( 2 + EquipmentSlots * sizeof( CharacterArmor ) + WeaponSlots * sizeof( CharacterWeapon ) ) / 8;
|
||||||
var ret = true;
|
var ret = true;
|
||||||
fixed( ActorWeapon* data1 = &MainHand, data2 = &rhs.MainHand )
|
fixed( CharacterWeapon* data1 = &MainHand, data2 = &rhs.MainHand )
|
||||||
{
|
{
|
||||||
var ptr1 = ( ulong* )data1;
|
var ptr1 = ( ulong* )data1;
|
||||||
var ptr2 = ( ulong* )data2;
|
var ptr2 = ( ulong* )data2;
|
||||||
|
|
@ -105,10 +104,10 @@ namespace Penumbra.GameData.Structs
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe bool CompareData( ActorEquipment rhs )
|
private unsafe bool CompareData( CharacterEquipment rhs )
|
||||||
{
|
{
|
||||||
var structSizeEights = ( 2 + EquipmentSlots * sizeof( ActorArmor ) + WeaponSlots * sizeof( ActorWeapon ) ) / 8;
|
var structSizeEights = ( 2 + EquipmentSlots * sizeof( CharacterArmor ) + WeaponSlots * sizeof( CharacterWeapon ) ) / 8;
|
||||||
fixed( ActorWeapon* data1 = &MainHand, data2 = &rhs.MainHand )
|
fixed( CharacterWeapon* data1 = &MainHand, data2 = &rhs.MainHand )
|
||||||
{
|
{
|
||||||
var ptr1 = ( ulong* )data1;
|
var ptr1 = ( ulong* )data1;
|
||||||
var ptr2 = ( ulong* )data2;
|
var ptr2 = ( ulong* )data2;
|
||||||
|
|
@ -126,7 +125,7 @@ namespace Penumbra.GameData.Structs
|
||||||
|
|
||||||
public unsafe void WriteBytes( byte[] array, int offset = 0 )
|
public unsafe void WriteBytes( byte[] array, int offset = 0 )
|
||||||
{
|
{
|
||||||
fixed( ActorWeapon* data = &MainHand )
|
fixed( CharacterWeapon* data = &MainHand )
|
||||||
{
|
{
|
||||||
Marshal.Copy( new IntPtr( data ), array, offset, 56 );
|
Marshal.Copy( new IntPtr( data ), array, offset, 56 );
|
||||||
}
|
}
|
||||||
|
|
@ -141,7 +140,7 @@ namespace Penumbra.GameData.Structs
|
||||||
|
|
||||||
public unsafe void FromBytes( byte[] array, int offset = 0 )
|
public unsafe void FromBytes( byte[] array, int offset = 0 )
|
||||||
{
|
{
|
||||||
fixed( ActorWeapon* data = &MainHand )
|
fixed( CharacterWeapon* data = &MainHand )
|
||||||
{
|
{
|
||||||
Marshal.Copy( array, offset, new IntPtr( data ), 56 );
|
Marshal.Copy( array, offset, new IntPtr( data ), 56 );
|
||||||
}
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
|
||||||
namespace Penumbra.GameData.Structs
|
namespace Penumbra.GameData.Structs
|
||||||
{
|
{
|
||||||
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
[StructLayout( LayoutKind.Sequential, Pack = 1 )]
|
||||||
public readonly struct ActorWeapon
|
public readonly struct CharacterWeapon
|
||||||
{
|
{
|
||||||
public readonly SetId Set;
|
public readonly SetId Set;
|
||||||
public readonly WeaponType Type;
|
public readonly WeaponType Type;
|
||||||
|
|
@ -65,7 +65,7 @@ namespace Penumbra.GameData.Util
|
||||||
return idx == -1 ? _path : idx == _path.Length - 1 ? "" : _path.Substring( idx + 1 );
|
return idx == -1 ? _path : idx == _path.Length - 1 ? "" : _path.Substring( idx + 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
public int CompareTo( object rhs )
|
public int CompareTo( object? rhs )
|
||||||
{
|
{
|
||||||
return rhs switch
|
return rhs switch
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Penumbra.PlayerWatch
|
namespace Penumbra.PlayerWatch
|
||||||
{
|
{
|
||||||
public delegate void ActorChange( Actor actor );
|
public delegate void PlayerChange( Character actor );
|
||||||
|
|
||||||
public interface IPlayerWatcherBase : IDisposable
|
public interface IPlayerWatcherBase : IDisposable
|
||||||
{
|
{
|
||||||
|
|
@ -15,7 +15,7 @@ namespace Penumbra.PlayerWatch
|
||||||
|
|
||||||
public interface IPlayerWatcher : IPlayerWatcherBase
|
public interface IPlayerWatcher : IPlayerWatcherBase
|
||||||
{
|
{
|
||||||
public event ActorChange? ActorChanged;
|
public event PlayerChange? PlayerChanged;
|
||||||
public bool Active { get; }
|
public bool Active { get; }
|
||||||
|
|
||||||
public void Enable();
|
public void Enable();
|
||||||
|
|
@ -24,8 +24,8 @@ namespace Penumbra.PlayerWatch
|
||||||
|
|
||||||
public void AddPlayerToWatch( string playerName );
|
public void AddPlayerToWatch( string playerName );
|
||||||
public void RemovePlayerFromWatch( string playerName );
|
public void RemovePlayerFromWatch( string playerName );
|
||||||
public ActorEquipment UpdateActorWithoutEvent( Actor actor );
|
public CharacterEquipment UpdatePlayerWithoutEvent( Character actor );
|
||||||
|
|
||||||
public IEnumerable< (string, ActorEquipment) > WatchedPlayers();
|
public IEnumerable< (string, CharacterEquipment) > WatchedPlayers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net5.0-windows</TargetFramework>
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<AssemblyTitle>Penumbra.PlayerWatch</AssemblyTitle>
|
<AssemblyTitle>Penumbra.PlayerWatch</AssemblyTitle>
|
||||||
<Company>absolute gangstas</Company>
|
<Company>absolute gangstas</Company>
|
||||||
<Product>Penumbra</Product>
|
<Product>Penumbra</Product>
|
||||||
|
|
|
||||||
|
|
@ -1,36 +1,45 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Dalamud.Game.ClientState.Actors;
|
using Dalamud.Game;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Enums;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Logging;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Penumbra.PlayerWatch
|
namespace Penumbra.PlayerWatch
|
||||||
{
|
{
|
||||||
internal class PlayerWatchBase : IDisposable
|
internal class PlayerWatchBase : IDisposable
|
||||||
{
|
{
|
||||||
public const int GPosePlayerActorIdx = 201;
|
public const int GPosePlayerIdx = 201;
|
||||||
public const int GPoseActorEnd = GPosePlayerActorIdx + 48;
|
public const int GPoseTableEnd = GPosePlayerIdx + 48;
|
||||||
private const int ActorsPerFrame = 8;
|
private const int ObjectsPerFrame = 8;
|
||||||
|
|
||||||
private readonly DalamudPluginInterface _pi;
|
private readonly Framework _framework;
|
||||||
internal readonly HashSet< PlayerWatcher > RegisteredWatchers = new();
|
private readonly ClientState _clientState;
|
||||||
internal readonly Dictionary< string, (ActorEquipment, HashSet< PlayerWatcher >) > Equip = new();
|
private readonly ObjectTable _objects;
|
||||||
private int _frameTicker;
|
internal readonly HashSet< PlayerWatcher > RegisteredWatchers = new();
|
||||||
private bool _inGPose = false;
|
internal readonly Dictionary< string, (CharacterEquipment, HashSet< PlayerWatcher >) > Equip = new();
|
||||||
private bool _enabled = false;
|
private int _frameTicker;
|
||||||
private bool _cancel = false;
|
private bool _inGPose;
|
||||||
|
private bool _enabled;
|
||||||
|
private bool _cancel;
|
||||||
|
|
||||||
internal PlayerWatchBase( DalamudPluginInterface pi )
|
internal PlayerWatchBase( Framework framework, ClientState clientState, ObjectTable objects )
|
||||||
=> _pi = pi;
|
{
|
||||||
|
_framework = framework;
|
||||||
|
_clientState = clientState;
|
||||||
|
_objects = objects;
|
||||||
|
}
|
||||||
|
|
||||||
internal void RegisterWatcher( PlayerWatcher watcher )
|
internal void RegisterWatcher( PlayerWatcher watcher )
|
||||||
{
|
{
|
||||||
RegisteredWatchers.Add( watcher );
|
RegisteredWatchers.Add( watcher );
|
||||||
if( watcher.Active )
|
if( watcher.Active )
|
||||||
{
|
{
|
||||||
EnableActorWatch();
|
EnablePlayerWatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -51,20 +60,20 @@ namespace Penumbra.PlayerWatch
|
||||||
{
|
{
|
||||||
if( RegisteredWatchers.Any( w => w.Active ) )
|
if( RegisteredWatchers.Any( w => w.Active ) )
|
||||||
{
|
{
|
||||||
EnableActorWatch();
|
EnablePlayerWatch();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DisableActorWatch();
|
DisablePlayerWatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal ActorEquipment UpdateActorWithoutEvent( Actor actor )
|
internal CharacterEquipment UpdatePlayerWithoutEvent( Character actor )
|
||||||
{
|
{
|
||||||
var equipment = new ActorEquipment( actor );
|
var equipment = new CharacterEquipment( actor );
|
||||||
if( Equip.ContainsKey( actor.Name ) )
|
if( Equip.ContainsKey( actor.Name.ToString() ) )
|
||||||
{
|
{
|
||||||
Equip[ actor.Name ] = ( equipment, Equip[ actor.Name ].Item2 );
|
Equip[ actor.Name.ToString() ] = ( equipment, Equip[ actor.Name.ToString() ].Item2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
return equipment;
|
return equipment;
|
||||||
|
|
@ -78,7 +87,7 @@ namespace Penumbra.PlayerWatch
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Equip[ playerName ] = ( new ActorEquipment(), new HashSet< PlayerWatcher > { watcher } );
|
Equip[ playerName ] = ( new CharacterEquipment(), new HashSet< PlayerWatcher > { watcher } );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,35 +103,35 @@ namespace Penumbra.PlayerWatch
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void EnableActorWatch()
|
internal void EnablePlayerWatch()
|
||||||
{
|
{
|
||||||
if( !_enabled )
|
if( !_enabled )
|
||||||
{
|
{
|
||||||
_enabled = true;
|
_enabled = true;
|
||||||
_pi.Framework.OnUpdateEvent += OnFrameworkUpdate;
|
_framework.Update += OnFrameworkUpdate;
|
||||||
_pi.ClientState.TerritoryChanged += OnTerritoryChange;
|
_clientState.TerritoryChanged += OnTerritoryChange;
|
||||||
_pi.ClientState.OnLogout += OnLogout;
|
_clientState.Logout += OnLogout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void DisableActorWatch()
|
internal void DisablePlayerWatch()
|
||||||
{
|
{
|
||||||
if( _enabled )
|
if( _enabled )
|
||||||
{
|
{
|
||||||
_enabled = false;
|
_enabled = false;
|
||||||
_pi.Framework.OnUpdateEvent -= OnFrameworkUpdate;
|
_framework.Update -= OnFrameworkUpdate;
|
||||||
_pi.ClientState.TerritoryChanged -= OnTerritoryChange;
|
_clientState.TerritoryChanged -= OnTerritoryChange;
|
||||||
_pi.ClientState.OnLogout -= OnLogout;
|
_clientState.Logout -= OnLogout;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
=> DisableActorWatch();
|
=> DisablePlayerWatch();
|
||||||
|
|
||||||
private void OnTerritoryChange( object _1, ushort _2 )
|
private void OnTerritoryChange( object? _1, ushort _2 )
|
||||||
=> Clear();
|
=> Clear();
|
||||||
|
|
||||||
private void OnLogout( object _1, object _2 )
|
private void OnLogout( object? _1, object? _2 )
|
||||||
=> Clear();
|
=> Clear();
|
||||||
|
|
||||||
internal void Clear()
|
internal void Clear()
|
||||||
|
|
@ -137,66 +146,66 @@ namespace Penumbra.PlayerWatch
|
||||||
_frameTicker = 0;
|
_frameTicker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void TriggerEvents( IEnumerable< PlayerWatcher > watchers, Actor actor )
|
private static void TriggerEvents( IEnumerable< PlayerWatcher > watchers, Character player )
|
||||||
{
|
{
|
||||||
PluginLog.Debug( "Triggering events for {ActorName} at {Address}.", actor.Name, actor.Address );
|
PluginLog.Debug( "Triggering events for {PlayerName} at {Address}.", player.Name, player.Address );
|
||||||
foreach( var watcher in watchers.Where( w => w.Active ) )
|
foreach( var watcher in watchers.Where( w => w.Active ) )
|
||||||
{
|
{
|
||||||
watcher.Trigger( actor );
|
watcher.Trigger( player );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void TriggerGPose()
|
internal void TriggerGPose()
|
||||||
{
|
{
|
||||||
for( var i = GPosePlayerActorIdx; i < GPoseActorEnd; ++i )
|
for( var i = GPosePlayerIdx; i < GPoseTableEnd; ++i )
|
||||||
{
|
{
|
||||||
var actor = _pi.ClientState.Actors[ i ];
|
var player = _objects[ i ];
|
||||||
if( actor == null )
|
if( player == null )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( Equip.TryGetValue( actor.Name, out var watcher ) )
|
if( Equip.TryGetValue( player.Name.ToString(), out var watcher ) )
|
||||||
{
|
{
|
||||||
TriggerEvents( watcher.Item2, actor );
|
TriggerEvents( watcher.Item2, ( Character )player );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Actor CheckGPoseActor( Actor actor )
|
private Character CheckGPoseObject( GameObject player )
|
||||||
{
|
{
|
||||||
if( !_inGPose )
|
if( !_inGPose )
|
||||||
{
|
{
|
||||||
return actor;
|
return ( Character )player;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( var i = GPosePlayerActorIdx; i < GPoseActorEnd; ++i )
|
for( var i = GPosePlayerIdx; i < GPoseTableEnd; ++i )
|
||||||
{
|
{
|
||||||
var a = _pi.ClientState.Actors[ i ];
|
var a = _objects[ i ];
|
||||||
if( a == null )
|
if( a == null )
|
||||||
{
|
{
|
||||||
return actor;
|
return ( Character )player;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( a.Name == actor.Name )
|
if( a.Name == player.Name )
|
||||||
{
|
{
|
||||||
return a;
|
return ( Character )a;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return actor;
|
return ( Character )player;
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool TryGetPlayer( GameObject gameObject, out (CharacterEquipment, HashSet< PlayerWatcher >) equip )
|
||||||
|
{
|
||||||
|
equip = default;
|
||||||
|
var name = gameObject.Name.ToString();
|
||||||
|
return name.Length != 0 && Equip.TryGetValue( name, out equip );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnFrameworkUpdate( object framework )
|
private void OnFrameworkUpdate( object framework )
|
||||||
{
|
{
|
||||||
if( _pi.ClientState.LocalPlayer == null )
|
var newInGPose = _objects[ GPosePlayerIdx ] != null;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var actors = _pi.ClientState.Actors;
|
|
||||||
|
|
||||||
var newInGPose = actors[ GPosePlayerActorIdx ] != null;
|
|
||||||
|
|
||||||
if( newInGPose != _inGPose )
|
if( newInGPose != _inGPose )
|
||||||
{
|
{
|
||||||
|
|
@ -212,28 +221,21 @@ namespace Penumbra.PlayerWatch
|
||||||
_inGPose = newInGPose;
|
_inGPose = newInGPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( var i = 0; i < ActorsPerFrame; ++i )
|
for( var i = 0; i < ObjectsPerFrame; ++i )
|
||||||
{
|
{
|
||||||
if( _pi.ClientState.LocalPlayer == null )
|
_frameTicker = _frameTicker < GPosePlayerIdx - 2
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_frameTicker = _frameTicker < actors.Length - 2
|
|
||||||
? _frameTicker + 2
|
? _frameTicker + 2
|
||||||
: 0;
|
: 0;
|
||||||
|
|
||||||
var actor = actors[ _frameTicker ];
|
var actor = _objects[ _frameTicker ];
|
||||||
if( actor == null
|
if( actor == null
|
||||||
|| actor.ObjectKind != ObjectKind.Player
|
|| actor.ObjectKind != ObjectKind.Player
|
||||||
|| actor.Name == null
|
|| !TryGetPlayer( actor, out var equip ) )
|
||||||
|| actor.Name.Length == 0
|
|
||||||
|| !Equip.TryGetValue( actor.Name, out var equip ) )
|
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
actor = CheckGPoseActor( actor );
|
var character = CheckGPoseObject( actor );
|
||||||
|
|
||||||
if( _cancel )
|
if( _cancel )
|
||||||
{
|
{
|
||||||
|
|
@ -241,10 +243,10 @@ namespace Penumbra.PlayerWatch
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginLog.Verbose( "Comparing Gear for {ActorName} at {Address}...", actor.Name, actor.Address );
|
PluginLog.Verbose( "Comparing Gear for {PlayerName} at {Address}...", character.Name, character.Address );
|
||||||
if( !equip.Item1.CompareAndUpdate( actor ) )
|
if( !equip.Item1.CompareAndUpdate( character ) )
|
||||||
{
|
{
|
||||||
TriggerEvents( equip.Item2, actor );
|
TriggerEvents( equip.Item2, character );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,28 +1,30 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Game.ClientState;
|
||||||
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
||||||
namespace Penumbra.PlayerWatch
|
namespace Penumbra.PlayerWatch
|
||||||
{
|
{
|
||||||
public class PlayerWatcher : IPlayerWatcher
|
public class PlayerWatcher : IPlayerWatcher
|
||||||
{
|
{
|
||||||
public int Version { get; } = 1;
|
public int Version { get; } = 2;
|
||||||
|
|
||||||
private static PlayerWatchBase? _playerWatch;
|
private static PlayerWatchBase? _playerWatch;
|
||||||
|
|
||||||
public event ActorChange? ActorChanged;
|
public event PlayerChange? PlayerChanged;
|
||||||
|
|
||||||
public bool Active { get; set; } = true;
|
public bool Active { get; set; } = true;
|
||||||
|
|
||||||
public bool Valid
|
public bool Valid
|
||||||
=> _playerWatch != null;
|
=> _playerWatch != null;
|
||||||
|
|
||||||
internal PlayerWatcher( DalamudPluginInterface pi )
|
internal PlayerWatcher( Framework framework, ClientState clientState, ObjectTable objects )
|
||||||
{
|
{
|
||||||
_playerWatch ??= new PlayerWatchBase( pi );
|
_playerWatch ??= new PlayerWatchBase( framework, clientState, objects );
|
||||||
_playerWatch.RegisterWatcher( this );
|
_playerWatch.RegisterWatcher( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,8 +40,8 @@ namespace Penumbra.PlayerWatch
|
||||||
_playerWatch?.CheckActiveStatus();
|
_playerWatch?.CheckActiveStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void Trigger( Actor actor )
|
internal void Trigger( Character actor )
|
||||||
=> ActorChanged?.Invoke( actor );
|
=> PlayerChanged?.Invoke( actor );
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
|
|
@ -48,8 +50,8 @@ namespace Penumbra.PlayerWatch
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Active = false;
|
Active = false;
|
||||||
ActorChanged = null;
|
PlayerChanged = null;
|
||||||
_playerWatch.UnregisterWatcher( this );
|
_playerWatch.UnregisterWatcher( this );
|
||||||
if( _playerWatch.RegisteredWatchers.Count == 0 )
|
if( _playerWatch.RegisteredWatchers.Count == 0 )
|
||||||
{
|
{
|
||||||
|
|
@ -78,13 +80,13 @@ namespace Penumbra.PlayerWatch
|
||||||
_playerWatch!.RemovePlayerFromWatch( playerName, this );
|
_playerWatch!.RemovePlayerFromWatch( playerName, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public ActorEquipment UpdateActorWithoutEvent( Actor actor )
|
public CharacterEquipment UpdatePlayerWithoutEvent( Character actor )
|
||||||
{
|
{
|
||||||
CheckValidity();
|
CheckValidity();
|
||||||
return _playerWatch!.UpdateActorWithoutEvent( actor );
|
return _playerWatch!.UpdatePlayerWithoutEvent( actor );
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable< (string, ActorEquipment) > WatchedPlayers()
|
public IEnumerable< (string, CharacterEquipment) > WatchedPlayers()
|
||||||
{
|
{
|
||||||
CheckValidity();
|
CheckValidity();
|
||||||
return _playerWatch!.Equip
|
return _playerWatch!.Equip
|
||||||
|
|
@ -95,7 +97,7 @@ namespace Penumbra.PlayerWatch
|
||||||
|
|
||||||
public static class PlayerWatchFactory
|
public static class PlayerWatchFactory
|
||||||
{
|
{
|
||||||
public static IPlayerWatcher Create( DalamudPluginInterface pi )
|
public static IPlayerWatcher Create( Framework framework, ClientState clientState, ObjectTable objects )
|
||||||
=> new PlayerWatcher( pi );
|
=> new PlayerWatcher( framework, clientState, objects );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -12,8 +12,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.GameData", "Penumbra.GameData\Penumbra.GameData.csproj", "{EE551E87-FDB3-4612-B500-DC870C07C605}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.GameData", "Penumbra.GameData\Penumbra.GameData.csproj", "{EE551E87-FDB3-4612-B500-DC870C07C605}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.Api", "Penumbra.API\Penumbra.Api.csproj", "{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.PlayerWatch", "Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj", "{01685BD8-8847-4B49-BF90-1683B4C76B0E}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Penumbra.PlayerWatch", "Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj", "{01685BD8-8847-4B49-BF90-1683B4C76B0E}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
|
|
@ -30,10 +28,6 @@ Global
|
||||||
{EE551E87-FDB3-4612-B500-DC870C07C605}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{EE551E87-FDB3-4612-B500-DC870C07C605}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.Build.0 = Release|Any CPU
|
{EE551E87-FDB3-4612-B500-DC870C07C605}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{EE8C148E-BF59-43FB-89FC-4CADC9047FDF}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{01685BD8-8847-4B49-BF90-1683B4C76B0E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ namespace Penumbra.Api
|
||||||
{
|
{
|
||||||
public class ModsController : WebApiController
|
public class ModsController : WebApiController
|
||||||
{
|
{
|
||||||
private readonly Plugin _plugin;
|
private readonly Penumbra _penumbra;
|
||||||
|
|
||||||
public ModsController( Plugin plugin )
|
public ModsController( Penumbra penumbra )
|
||||||
=> _plugin = plugin;
|
=> _penumbra = penumbra;
|
||||||
|
|
||||||
[Route( HttpVerbs.Get, "/mods" )]
|
[Route( HttpVerbs.Get, "/mods" )]
|
||||||
public object? GetMods()
|
public object? GetMods()
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Lumina.Data;
|
using Lumina.Data;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
|
||||||
namespace Penumbra.Api
|
namespace Penumbra.Api
|
||||||
{
|
{
|
||||||
|
|
@ -9,14 +10,6 @@ namespace Penumbra.Api
|
||||||
public bool Valid { get; }
|
public bool Valid { get; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum MouseButton
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
Left,
|
|
||||||
Right,
|
|
||||||
Middle,
|
|
||||||
}
|
|
||||||
|
|
||||||
public delegate void ChangedItemHover( object? item );
|
public delegate void ChangedItemHover( object? item );
|
||||||
public delegate void ChangedItemClick( MouseButton button, object? item );
|
public delegate void ChangedItemClick( MouseButton button, object? item );
|
||||||
|
|
||||||
|
|
@ -29,10 +22,10 @@ namespace Penumbra.Api
|
||||||
public event ChangedItemClick? ChangedItemClicked;
|
public event ChangedItemClick? ChangedItemClicked;
|
||||||
|
|
||||||
// Queue redrawing of all actors of the given name with the given RedrawType.
|
// Queue redrawing of all actors of the given name with the given RedrawType.
|
||||||
public void RedrawActor( string name, RedrawType setting );
|
public void RedrawObject( string name, RedrawType setting );
|
||||||
|
|
||||||
// Queue redrawing of the specific actor with the given RedrawType. Should only be used when the actor is sure to be valid.
|
// Queue redrawing of the specific actor with the given RedrawType. Should only be used when the actor is sure to be valid.
|
||||||
public void RedrawActor( Actor actor, RedrawType setting );
|
public void RedrawObject( GameObject gameObject, RedrawType setting );
|
||||||
|
|
||||||
// Queue redrawing of all currently available actors with the given RedrawType.
|
// Queue redrawing of all currently available actors with the given RedrawType.
|
||||||
public void RedrawAll( RedrawType setting );
|
public void RedrawAll( RedrawType setting );
|
||||||
|
|
@ -1,9 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Lumina.Data;
|
using Lumina.Data;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
|
|
@ -12,18 +13,18 @@ namespace Penumbra.Api
|
||||||
{
|
{
|
||||||
public class PenumbraApi : IDisposable, IPenumbraApi
|
public class PenumbraApi : IDisposable, IPenumbraApi
|
||||||
{
|
{
|
||||||
public int ApiVersion { get; } = 2;
|
public int ApiVersion { get; } = 3;
|
||||||
private readonly Plugin _plugin;
|
private readonly Penumbra _penumbra;
|
||||||
private readonly Lumina.GameData? _lumina;
|
private readonly Lumina.GameData? _lumina;
|
||||||
public bool Valid { get; private set; } = false;
|
public bool Valid { get; private set; } = false;
|
||||||
|
|
||||||
public PenumbraApi( Plugin penumbra )
|
public PenumbraApi( Penumbra penumbra )
|
||||||
{
|
{
|
||||||
_plugin = penumbra;
|
_penumbra = penumbra;
|
||||||
Valid = true;
|
Valid = true;
|
||||||
_lumina = ( Lumina.GameData? )_plugin.PluginInterface.Data.GetType()
|
_lumina = ( Lumina.GameData? )Dalamud.GameData.GetType()
|
||||||
.GetField( "gameData", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "gameData", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.PluginInterface.Data );
|
?.GetValue( Dalamud.GameData );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
|
|
@ -52,30 +53,30 @@ namespace Penumbra.Api
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RedrawActor( string name, RedrawType setting )
|
public void RedrawObject( string name, RedrawType setting )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
|
|
||||||
_plugin.ActorRefresher.RedrawActor( name, setting );
|
_penumbra.ObjectReloader.RedrawObject( name, setting );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RedrawActor( Actor? actor, RedrawType setting )
|
public void RedrawObject( GameObject? gameObject, RedrawType setting )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
|
|
||||||
_plugin.ActorRefresher.RedrawActor( actor, setting );
|
_penumbra.ObjectReloader.RedrawObject( gameObject, setting );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RedrawAll( RedrawType setting )
|
public void RedrawAll( RedrawType setting )
|
||||||
{
|
{
|
||||||
CheckInitialized();
|
CheckInitialized();
|
||||||
|
|
||||||
_plugin.ActorRefresher.RedrawAll( setting );
|
_penumbra.ObjectReloader.RedrawAll( setting );
|
||||||
}
|
}
|
||||||
|
|
||||||
private string ResolvePath( string path, ModManager manager, ModCollection collection )
|
private static string ResolvePath( string path, ModManager manager, ModCollection collection )
|
||||||
{
|
{
|
||||||
if( !_plugin.Configuration.IsEnabled )
|
if( !Penumbra.Config.IsEnabled )
|
||||||
{
|
{
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
@ -110,7 +111,7 @@ namespace Penumbra.Api
|
||||||
return _lumina?.GetFileFromDisk< T >( resolvedPath );
|
return _lumina?.GetFileFromDisk< T >( resolvedPath );
|
||||||
}
|
}
|
||||||
|
|
||||||
return _plugin.PluginInterface.Data.GetFile< T >( resolvedPath );
|
return Dalamud.GameData.GetFile< T >( resolvedPath );
|
||||||
}
|
}
|
||||||
catch( Exception e)
|
catch( Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
136
Penumbra/Api/PenumbraIpc.cs
Normal file
136
Penumbra/Api/PenumbraIpc.cs
Normal file
|
|
@ -0,0 +1,136 @@
|
||||||
|
using System;
|
||||||
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
|
using Dalamud.Logging;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
|
|
||||||
|
namespace Penumbra.Api
|
||||||
|
{
|
||||||
|
public class PenumbraIpc
|
||||||
|
{
|
||||||
|
public const string LabelProviderApiVersion = "Penumbra.ApiVersion";
|
||||||
|
public const string LabelProviderRedrawName = "Penumbra.RedrawObjectByName";
|
||||||
|
public const string LabelProviderRedrawObject = "Penumbra.RedrawObject";
|
||||||
|
public const string LabelProviderRedrawAll = "Penumbra.RedrawAll";
|
||||||
|
public const string LabelProviderResolveDefault = "Penumbra.ResolveDefaultPath";
|
||||||
|
public const string LabelProviderResolveCharacter = "Penumbra.ResolveCharacterPath";
|
||||||
|
|
||||||
|
public const string LabelProviderChangedItemTooltip = "Penumbra.ChangedItemTooltip";
|
||||||
|
public const string LabelProviderChangedItemClick = "Penumbra.ChangedItemClick";
|
||||||
|
|
||||||
|
internal ICallGateProvider< int >? ProviderApiVersion;
|
||||||
|
internal ICallGateProvider< string, int, object >? ProviderRedrawName;
|
||||||
|
internal ICallGateProvider< GameObject, int, object >? ProviderRedrawObject;
|
||||||
|
internal ICallGateProvider< int, object >? ProviderRedrawAll;
|
||||||
|
internal ICallGateProvider< string, string >? ProviderResolveDefault;
|
||||||
|
internal ICallGateProvider< string, string, string >? ProviderResolveCharacter;
|
||||||
|
internal ICallGateProvider< object?, object >? ProviderChangedItemTooltip;
|
||||||
|
internal ICallGateProvider< int, object?, object >? ProviderChangedItemClick;
|
||||||
|
|
||||||
|
internal readonly IPenumbraApi _api;
|
||||||
|
|
||||||
|
private static RedrawType CheckRedrawType( int value )
|
||||||
|
{
|
||||||
|
var type = ( RedrawType )value;
|
||||||
|
if( Enum.IsDefined( type ) )
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Exception( "The integer provided for a Redraw Function was not a valid RedrawType." );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnClick( MouseButton click, object? item )
|
||||||
|
=> ProviderChangedItemClick?.SendMessage( ( int )click, item );
|
||||||
|
|
||||||
|
|
||||||
|
public PenumbraIpc( DalamudPluginInterface pi, IPenumbraApi api )
|
||||||
|
{
|
||||||
|
_api = api;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderApiVersion = pi.GetIpcProvider< int >( LabelProviderApiVersion );
|
||||||
|
ProviderApiVersion.RegisterFunc( () => api.ApiVersion );
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderApiVersion}:\n{e}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderRedrawName = pi.GetIpcProvider< string, int, object >( LabelProviderRedrawName );
|
||||||
|
ProviderRedrawName.RegisterAction( ( s, i ) => api.RedrawObject( s, CheckRedrawType( i ) ) );
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawName}:\n{e}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderRedrawObject = pi.GetIpcProvider< GameObject, int, object >( LabelProviderRedrawObject );
|
||||||
|
ProviderRedrawObject.RegisterAction( ( o, i ) => api.RedrawObject( o, CheckRedrawType( i ) ) );
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawObject}:\n{e}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderRedrawAll = pi.GetIpcProvider< int, object >( LabelProviderRedrawAll );
|
||||||
|
ProviderRedrawAll.RegisterFunc( i =>
|
||||||
|
{
|
||||||
|
api.RedrawAll( CheckRedrawType( i ) );
|
||||||
|
return null!;
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderRedrawAll}:\n{e}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderResolveDefault = pi.GetIpcProvider< string, string >( LabelProviderResolveDefault );
|
||||||
|
ProviderResolveDefault.RegisterFunc( api.ResolvePath );
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderResolveDefault}:\n{e}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderResolveCharacter = pi.GetIpcProvider< string, string, string >( LabelProviderResolveCharacter );
|
||||||
|
ProviderResolveCharacter.RegisterFunc( api.ResolvePath );
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderResolveCharacter}:\n{e}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderChangedItemTooltip = pi.GetIpcProvider< object?, object >( LabelProviderChangedItemTooltip );
|
||||||
|
api.ChangedItemTooltip += ProviderChangedItemTooltip.SendMessage;
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderChangedItemTooltip}:\n{e}" );
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ProviderChangedItemClick = pi.GetIpcProvider< int, object?, object >( LabelProviderChangedItemClick );
|
||||||
|
api.ChangedItemClicked += OnClick;
|
||||||
|
}
|
||||||
|
catch( Exception e )
|
||||||
|
{
|
||||||
|
PluginLog.Error( $"Error registering IPC provider for {LabelProviderChangedItemClick}:\n{e}" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Dalamud.Configuration;
|
using Dalamud.Configuration;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Penumbra.Util;
|
|
||||||
|
|
||||||
namespace Penumbra
|
namespace Penumbra
|
||||||
{
|
{
|
||||||
|
|
@ -21,7 +20,7 @@ namespace Penumbra
|
||||||
public bool DisableFileSystemNotifications { get; set; }
|
public bool DisableFileSystemNotifications { get; set; }
|
||||||
|
|
||||||
public bool EnableHttpApi { get; set; }
|
public bool EnableHttpApi { get; set; }
|
||||||
public bool EnableActorWatch { get; set; } = false;
|
public bool EnablePlayerWatch { get; set; } = false;
|
||||||
public int WaitFrames { get; set; } = 30;
|
public int WaitFrames { get; set; } = 30;
|
||||||
|
|
||||||
public string ModDirectory { get; set; } = string.Empty;
|
public string ModDirectory { get; set; } = string.Empty;
|
||||||
|
|
@ -38,33 +37,30 @@ namespace Penumbra
|
||||||
|
|
||||||
public bool InvertModListOrder { internal get; set; }
|
public bool InvertModListOrder { internal get; set; }
|
||||||
|
|
||||||
public static Configuration Load( DalamudPluginInterface pi )
|
public static Configuration Load()
|
||||||
{
|
{
|
||||||
var configuration = pi.GetPluginConfig() as Configuration ?? new Configuration();
|
var configuration = Dalamud.PluginInterface.GetPluginConfig() as Configuration ?? new Configuration();
|
||||||
if( configuration.Version == CurrentVersion )
|
if( configuration.Version == CurrentVersion )
|
||||||
{
|
{
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
MigrateConfiguration.Version0To1( configuration );
|
MigrateConfiguration.Version0To1( configuration );
|
||||||
configuration.Save( pi );
|
configuration.Save();
|
||||||
|
|
||||||
return configuration;
|
return configuration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save( DalamudPluginInterface pi )
|
public void Save()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
pi.SavePluginConfig( this );
|
Dalamud.PluginInterface.SavePluginConfig( this );
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
PluginLog.Error( $"Could not save plugin configuration:\n{e}" );
|
PluginLog.Error( $"Could not save plugin configuration:\n{e}" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Save()
|
|
||||||
=> Save( Service< DalamudPluginInterface >.Get() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
32
Penumbra/Dalamud.cs
Normal file
32
Penumbra/Dalamud.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
using Dalamud.Data;
|
||||||
|
using Dalamud.Game;
|
||||||
|
using Dalamud.Game.ClientState;
|
||||||
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
|
using Dalamud.Game.ClientState.Objects;
|
||||||
|
using Dalamud.Game.Command;
|
||||||
|
using Dalamud.Game.Gui;
|
||||||
|
using Dalamud.IoC;
|
||||||
|
using Dalamud.Plugin;
|
||||||
|
// 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 SigScanner SigScanner { 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!;
|
||||||
|
// @formatter:on
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using Dalamud.Logging;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using ICSharpCode.SharpZipLib.Zip;
|
using ICSharpCode.SharpZipLib.Zip;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
@ -363,7 +364,7 @@ namespace Penumbra.Importer
|
||||||
|
|
||||||
private void ExtractMod( DirectoryInfo outDirectory, SimpleMod mod, PenumbraSqPackStream dataStream )
|
private void ExtractMod( DirectoryInfo outDirectory, SimpleMod mod, PenumbraSqPackStream dataStream )
|
||||||
{
|
{
|
||||||
PluginLog.Log( " -> Extracting {0} at {1}", mod.FullPath, mod.ModOffset.ToString( "X" ) );
|
PluginLog.Log( " -> Extracting {0} at {1}", mod.FullPath!, mod.ModOffset.ToString( "X" ) );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
using Penumbra.GameData.Structs;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
|
using Dalamud.Logging;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Penumbra.Structs;
|
using Penumbra.Structs;
|
||||||
using Reloaded.Hooks.Definitions.X64;
|
|
||||||
|
|
||||||
namespace Penumbra.Interop
|
namespace Penumbra.Interop
|
||||||
{
|
{
|
||||||
|
|
@ -10,16 +11,16 @@ namespace Penumbra.Interop
|
||||||
{
|
{
|
||||||
private const int NumResources = 85;
|
private const int NumResources = 85;
|
||||||
|
|
||||||
[Function( CallingConventions.Microsoft )]
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||||
public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager );
|
public unsafe delegate void* LoadPlayerResourcesPrototype( IntPtr pResourceManager );
|
||||||
|
|
||||||
[Function( CallingConventions.Microsoft )]
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||||
public unsafe delegate void* UnloadPlayerResourcesPrototype( IntPtr pResourceManager );
|
public unsafe delegate void* UnloadPlayerResourcesPrototype( IntPtr pResourceManager );
|
||||||
|
|
||||||
[Function( CallingConventions.Microsoft )]
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||||
public unsafe delegate void* LoadCharacterResourcesPrototype( CharacterResourceManager* pCharacterResourceManager );
|
public unsafe delegate void* LoadCharacterResourcesPrototype( CharacterResourceManager* pCharacterResourceManager );
|
||||||
|
|
||||||
[Function( CallingConventions.Microsoft )]
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||||
public unsafe delegate void* UnloadCharacterResourcePrototype( IntPtr resource );
|
public unsafe delegate void* UnloadCharacterResourcePrototype( IntPtr resource );
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -39,21 +40,19 @@ namespace Penumbra.Interop
|
||||||
public unsafe CharacterResourceManager* CharacterResourceManagerPtr
|
public unsafe CharacterResourceManager* CharacterResourceManagerPtr
|
||||||
=> ( CharacterResourceManager* )Marshal.ReadIntPtr( _characterResourceManagerAddress ).ToPointer();
|
=> ( CharacterResourceManager* )Marshal.ReadIntPtr( _characterResourceManagerAddress ).ToPointer();
|
||||||
|
|
||||||
public GameResourceManagement( DalamudPluginInterface pluginInterface )
|
public GameResourceManagement( )
|
||||||
{
|
{
|
||||||
var scanner = pluginInterface.TargetModuleScanner;
|
|
||||||
|
|
||||||
var loadPlayerResourcesAddress =
|
var loadPlayerResourcesAddress =
|
||||||
scanner.ScanText(
|
Dalamud.SigScanner.ScanText(
|
||||||
"E8 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? BA ?? ?? ?? ?? 41 B8 ?? ?? ?? ?? 48 8B 48 30 48 8B 01 FF 50 10 48 85 C0 74 0A " );
|
"E8 ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? BA ?? ?? ?? ?? 41 B8 ?? ?? ?? ?? 48 8B 48 30 48 8B 01 FF 50 10 48 85 C0 74 0A " );
|
||||||
var unloadPlayerResourcesAddress =
|
var unloadPlayerResourcesAddress =
|
||||||
scanner.ScanText( "41 55 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 4C 8B E9 48 83 C1 08" );
|
Dalamud.SigScanner.ScanText( "41 55 48 81 EC ?? ?? ?? ?? 48 8B 05 ?? ?? ?? ?? 48 33 C4 48 89 84 24 ?? ?? ?? ?? 4C 8B E9 48 83 C1 08" );
|
||||||
var loadCharacterResourcesAddress = scanner.ScanText( "E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
|
var loadCharacterResourcesAddress = Dalamud.SigScanner.ScanText( "E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
|
||||||
var unloadCharacterResourceAddress = scanner.ScanText( "E8 ?? ?? ?? FF 4C 89 37 48 83 C7 08 48 83 ED 01 75 ?? 48 8B CB" );
|
var unloadCharacterResourceAddress = Dalamud.SigScanner.ScanText( "E8 ?? ?? ?? FF 4C 89 37 48 83 C7 08 48 83 ED 01 75 ?? 48 8B CB" );
|
||||||
|
|
||||||
_playerResourceManagerAddress = scanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" );
|
_playerResourceManagerAddress = Dalamud.SigScanner.GetStaticAddressFromSig( "0F 44 FE 48 8B 0D ?? ?? ?? ?? 48 85 C9 74 05" );
|
||||||
_characterResourceManagerAddress =
|
_characterResourceManagerAddress =
|
||||||
scanner.GetStaticAddressFromSig( "48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
|
Dalamud.SigScanner.GetStaticAddressFromSig( "48 8B 0D ?? ?? ?? ?? E8 ?? ?? ?? 00 48 8D 8E ?? ?? 00 00 E8 ?? ?? ?? 00 33 D2" );
|
||||||
|
|
||||||
LoadPlayerResources = Marshal.GetDelegateForFunctionPointer< LoadPlayerResourcesPrototype >( loadPlayerResourcesAddress );
|
LoadPlayerResources = Marshal.GetDelegateForFunctionPointer< LoadPlayerResourcesPrototype >( loadPlayerResourcesAddress );
|
||||||
UnloadPlayerResources = Marshal.GetDelegateForFunctionPointer< UnloadPlayerResourcesPrototype >( unloadPlayerResourcesAddress );
|
UnloadPlayerResources = Marshal.GetDelegateForFunctionPointer< UnloadPlayerResourcesPrototype >( unloadPlayerResourcesAddress );
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using System;
|
using System;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
|
|
||||||
namespace Penumbra.Interop
|
namespace Penumbra.Interop
|
||||||
{
|
{
|
||||||
|
|
@ -9,10 +9,9 @@ namespace Penumbra.Interop
|
||||||
{
|
{
|
||||||
private readonly IntPtr _musicManager;
|
private readonly IntPtr _musicManager;
|
||||||
|
|
||||||
public MusicManager( Plugin plugin )
|
public MusicManager( )
|
||||||
{
|
{
|
||||||
var scanner = plugin!.PluginInterface!.TargetModuleScanner;
|
var framework = Dalamud.Framework.Address.BaseAddress;
|
||||||
var framework = plugin.PluginInterface.Framework.Address.BaseAddress;
|
|
||||||
|
|
||||||
// the wildcard is basically the framework offset we want (lol)
|
// the wildcard is basically the framework offset we want (lol)
|
||||||
// .text:000000000009051A 48 8B 8E 18 2A 00 00 mov rcx, [rsi+2A18h]
|
// .text:000000000009051A 48 8B 8E 18 2A 00 00 mov rcx, [rsi+2A18h]
|
||||||
|
|
@ -20,7 +19,7 @@ namespace Penumbra.Interop
|
||||||
// .text:0000000000090524 0F 94 C2 setz dl
|
// .text:0000000000090524 0F 94 C2 setz dl
|
||||||
// .text:0000000000090527 45 33 C0 xor r8d, r8d
|
// .text:0000000000090527 45 33 C0 xor r8d, r8d
|
||||||
// .text:000000000009052A E8 41 1C 15 00 call musicInit
|
// .text:000000000009052A E8 41 1C 15 00 call musicInit
|
||||||
var musicInitCallLocation = scanner.ScanText( "48 8B 8E ?? ?? ?? ?? 39 78 20 0F 94 C2 45 33 C0" );
|
var musicInitCallLocation = Dalamud.SigScanner.ScanText( "48 8B 8E ?? ?? ?? ?? 39 78 20 0F 94 C2 45 33 C0" );
|
||||||
var musicManagerOffset = *( int* )( musicInitCallLocation + 3 );
|
var musicManagerOffset = *( int* )( musicInitCallLocation + 3 );
|
||||||
PluginLog.Debug( "Found MusicInitCall location at 0x{Location:X16}. Framework offset for MusicManager is 0x{Offset:X8}",
|
PluginLog.Debug( "Found MusicInitCall location at 0x{Location:X16}. Framework offset for MusicManager is 0x{Offset:X8}",
|
||||||
musicInitCallLocation.ToInt64(), musicManagerOffset );
|
musicInitCallLocation.ToInt64(), musicManagerOffset );
|
||||||
|
|
|
||||||
|
|
@ -4,15 +4,14 @@ using System.ComponentModel;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Dalamud.Game.ClientState;
|
using Dalamud.Game.ClientState.Conditions;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using Dalamud.Plugin;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Api;
|
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
|
||||||
namespace Penumbra.Interop
|
namespace Penumbra.Interop
|
||||||
{
|
{
|
||||||
public class ActorRefresher : IDisposable
|
public class ObjectReloader : IDisposable
|
||||||
{
|
{
|
||||||
private delegate void ManipulateDraw( IntPtr actor );
|
private delegate void ManipulateDraw( IntPtr actor );
|
||||||
|
|
||||||
|
|
@ -27,41 +26,39 @@ namespace Penumbra.Interop
|
||||||
MaybeHiddenSummon = 0x00_80_00_00,
|
MaybeHiddenSummon = 0x00_80_00_00,
|
||||||
}
|
}
|
||||||
|
|
||||||
private const int RenderModeOffset = 0x0104;
|
private const int RenderModeOffset = 0x0104;
|
||||||
private const int UnloadAllRedrawDelay = 250;
|
private const int UnloadAllRedrawDelay = 250;
|
||||||
private const int NpcActorId = -536870912;
|
private const uint NpcObjectId = unchecked( ( uint )-536870912 );
|
||||||
public const int GPosePlayerActorIdx = 201;
|
public const int GPosePlayerIdx = 201;
|
||||||
public const int GPoseEndIdx = GPosePlayerActorIdx + 48;
|
public const int GPoseEndIdx = GPosePlayerIdx + 48;
|
||||||
|
|
||||||
private readonly DalamudPluginInterface _pi;
|
private readonly ModManager _mods;
|
||||||
private readonly ModManager _mods;
|
private readonly Queue< (uint actorId, string name, RedrawType s) > _actorIds = new();
|
||||||
private readonly Queue< (int actorId, string name, RedrawType s) > _actorIds = new();
|
|
||||||
|
|
||||||
internal int DefaultWaitFrames;
|
internal int DefaultWaitFrames;
|
||||||
|
|
||||||
private int _waitFrames = 0;
|
private int _waitFrames;
|
||||||
private int _currentFrame = 0;
|
private int _currentFrame;
|
||||||
private bool _changedSettings = false;
|
private bool _changedSettings;
|
||||||
private int _currentActorId = -1;
|
private uint _currentObjectId = uint.MaxValue;
|
||||||
private string? _currentActorName = null;
|
private LoadingFlags _currentObjectStartState = 0;
|
||||||
private LoadingFlags _currentActorStartState = 0;
|
private RedrawType _currentRedrawType = RedrawType.Unload;
|
||||||
private RedrawType _currentActorRedrawType = RedrawType.Unload;
|
private string? _currentObjectName;
|
||||||
private bool _wasTarget = false;
|
private bool _wasTarget;
|
||||||
private bool _inGPose = false;
|
private bool _inGPose;
|
||||||
|
|
||||||
public static IntPtr RenderPtr( Actor actor )
|
public static IntPtr RenderPtr( GameObject actor )
|
||||||
=> actor.Address + RenderModeOffset;
|
=> actor.Address + RenderModeOffset;
|
||||||
|
|
||||||
public ActorRefresher( DalamudPluginInterface pi, ModManager mods, int defaultWaitFrames )
|
public ObjectReloader( ModManager mods, int defaultWaitFrames )
|
||||||
{
|
{
|
||||||
_pi = pi;
|
|
||||||
_mods = mods;
|
_mods = mods;
|
||||||
DefaultWaitFrames = defaultWaitFrames;
|
DefaultWaitFrames = defaultWaitFrames;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ChangeSettings()
|
private void ChangeSettings()
|
||||||
{
|
{
|
||||||
if( _currentActorName != null && _mods.Collections.CharacterCollection.TryGetValue( _currentActorName, out var collection ) )
|
if( _currentObjectName != null && _mods.Collections.CharacterCollection.TryGetValue( _currentObjectName, out var collection ) )
|
||||||
{
|
{
|
||||||
_changedSettings = true;
|
_changedSettings = true;
|
||||||
_mods.Collections.ActiveCollection = collection;
|
_mods.Collections.ActiveCollection = collection;
|
||||||
|
|
@ -74,7 +71,7 @@ namespace Penumbra.Interop
|
||||||
_changedSettings = false;
|
_changedSettings = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void WriteInvisible( Actor actor, int actorIdx )
|
private unsafe void WriteInvisible( GameObject actor, int actorIdx )
|
||||||
{
|
{
|
||||||
var renderPtr = RenderPtr( actor );
|
var renderPtr = RenderPtr( actor );
|
||||||
if( renderPtr == IntPtr.Zero )
|
if( renderPtr == IntPtr.Zero )
|
||||||
|
|
@ -82,7 +79,7 @@ namespace Penumbra.Interop
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentActorStartState = *( LoadingFlags* )renderPtr;
|
_currentObjectStartState = *( LoadingFlags* )renderPtr;
|
||||||
*( LoadingFlags* )renderPtr |= LoadingFlags.Invisibility;
|
*( LoadingFlags* )renderPtr |= LoadingFlags.Invisibility;
|
||||||
|
|
||||||
if( _inGPose )
|
if( _inGPose )
|
||||||
|
|
@ -103,7 +100,7 @@ namespace Penumbra.Interop
|
||||||
if( renderPtr != IntPtr.Zero )
|
if( renderPtr != IntPtr.Zero )
|
||||||
{
|
{
|
||||||
var loadingFlags = *( LoadingFlags* )renderPtr;
|
var loadingFlags = *( LoadingFlags* )renderPtr;
|
||||||
if( loadingFlags == _currentActorStartState )
|
if( loadingFlags == _currentObjectStartState )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -114,7 +111,7 @@ namespace Penumbra.Interop
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void WriteVisible( Actor actor, int actorIdx )
|
private unsafe void WriteVisible( GameObject actor, int actorIdx )
|
||||||
{
|
{
|
||||||
var renderPtr = RenderPtr( actor );
|
var renderPtr = RenderPtr( actor );
|
||||||
*( LoadingFlags* )renderPtr &= ~LoadingFlags.Invisibility;
|
*( LoadingFlags* )renderPtr &= ~LoadingFlags.Invisibility;
|
||||||
|
|
@ -127,52 +124,52 @@ namespace Penumbra.Interop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckActor( Actor actor )
|
private bool CheckObject( GameObject actor )
|
||||||
{
|
{
|
||||||
if( _currentActorId != actor.ActorId )
|
if( _currentObjectId != actor.ObjectId )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _currentActorId != NpcActorId )
|
if( _currentObjectId != NpcObjectId )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return _currentActorName == actor.Name;
|
return _currentObjectName == actor.Name.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool CheckActorGPose( Actor actor )
|
private bool CheckObjectGPose( GameObject actor )
|
||||||
=> actor.ActorId == NpcActorId && _currentActorName == actor.Name;
|
=> actor.ObjectId == NpcObjectId && _currentObjectName == actor.Name.ToString();
|
||||||
|
|
||||||
private (Actor?, int) FindCurrentActor()
|
private (GameObject?, int) FindCurrentObject()
|
||||||
{
|
{
|
||||||
if( _inGPose )
|
if( _inGPose )
|
||||||
{
|
{
|
||||||
for( var i = GPosePlayerActorIdx; i < GPoseEndIdx; ++i )
|
for( var i = GPosePlayerIdx; i < GPoseEndIdx; ++i )
|
||||||
{
|
{
|
||||||
var actor = _pi.ClientState.Actors[ i ];
|
var actor = Dalamud.Objects[ i ];
|
||||||
if( actor == null )
|
if( actor == null )
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( CheckActorGPose( actor ) )
|
if( CheckObjectGPose( actor ) )
|
||||||
{
|
{
|
||||||
return ( actor, i );
|
return ( actor, i );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for( var i = 0; i < _pi.ClientState.Actors.Length; ++i )
|
for( var i = 0; i < Dalamud.Objects.Length; ++i )
|
||||||
{
|
{
|
||||||
if( i == GPosePlayerActorIdx )
|
if( i == GPosePlayerIdx )
|
||||||
{
|
{
|
||||||
i = GPoseEndIdx;
|
i = GPoseEndIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
var actor = _pi.ClientState.Actors[ i ];
|
var actor = Dalamud.Objects[ i ];
|
||||||
if( actor != null && CheckActor( actor ) )
|
if( actor != null && CheckObject( actor ) )
|
||||||
{
|
{
|
||||||
return ( actor, i );
|
return ( actor, i );
|
||||||
}
|
}
|
||||||
|
|
@ -181,40 +178,40 @@ namespace Penumbra.Interop
|
||||||
return ( null, -1 );
|
return ( null, -1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopActor()
|
private void PopObject()
|
||||||
{
|
{
|
||||||
if( _actorIds.Count > 0 )
|
if( _actorIds.Count > 0 )
|
||||||
{
|
{
|
||||||
var (id, name, s) = _actorIds.Dequeue();
|
var (id, name, s) = _actorIds.Dequeue();
|
||||||
_currentActorName = name;
|
_currentObjectName = name;
|
||||||
_currentActorId = id;
|
_currentObjectId = id;
|
||||||
_currentActorRedrawType = s;
|
_currentRedrawType = s;
|
||||||
var (actor, _) = FindCurrentActor();
|
var (actor, _) = FindCurrentObject();
|
||||||
if( actor == null )
|
if( actor == null )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_wasTarget = actor.Address == _pi.ClientState.Targets.CurrentTarget?.Address;
|
_wasTarget = actor.Address == Dalamud.Targets.Target?.Address;
|
||||||
|
|
||||||
++_currentFrame;
|
++_currentFrame;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_pi.Framework.OnUpdateEvent -= OnUpdateEvent;
|
Dalamud.Framework.Update -= OnUpdateEvent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ApplySettingsOrRedraw()
|
private void ApplySettingsOrRedraw()
|
||||||
{
|
{
|
||||||
var (actor, idx) = FindCurrentActor();
|
var (actor, idx) = FindCurrentObject();
|
||||||
if( actor == null )
|
if( actor == null )
|
||||||
{
|
{
|
||||||
_currentFrame = 0;
|
_currentFrame = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch( _currentActorRedrawType )
|
switch( _currentRedrawType )
|
||||||
{
|
{
|
||||||
case RedrawType.Unload:
|
case RedrawType.Unload:
|
||||||
WriteInvisible( actor, idx );
|
WriteInvisible( actor, idx );
|
||||||
|
|
@ -251,12 +248,12 @@ namespace Penumbra.Interop
|
||||||
case RedrawType.AfterGPoseWithoutSettings:
|
case RedrawType.AfterGPoseWithoutSettings:
|
||||||
if( _inGPose )
|
if( _inGPose )
|
||||||
{
|
{
|
||||||
_actorIds.Enqueue( ( _currentActorId, _currentActorName!, _currentActorRedrawType ) );
|
_actorIds.Enqueue( ( _currentObjectId, _currentObjectName!, _currentRedrawType ) );
|
||||||
_currentFrame = 0;
|
_currentFrame = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_currentActorRedrawType = _currentActorRedrawType == RedrawType.AfterGPoseWithSettings
|
_currentRedrawType = _currentRedrawType == RedrawType.AfterGPoseWithSettings
|
||||||
? RedrawType.WithSettings
|
? RedrawType.WithSettings
|
||||||
: RedrawType.WithoutSettings;
|
: RedrawType.WithoutSettings;
|
||||||
}
|
}
|
||||||
|
|
@ -268,7 +265,7 @@ namespace Penumbra.Interop
|
||||||
|
|
||||||
private void StartRedrawAndWait()
|
private void StartRedrawAndWait()
|
||||||
{
|
{
|
||||||
var (actor, idx) = FindCurrentActor();
|
var (actor, idx) = FindCurrentObject();
|
||||||
if( actor == null )
|
if( actor == null )
|
||||||
{
|
{
|
||||||
RevertSettings();
|
RevertSettings();
|
||||||
|
|
@ -281,15 +278,15 @@ namespace Penumbra.Interop
|
||||||
|
|
||||||
private void RevertSettings()
|
private void RevertSettings()
|
||||||
{
|
{
|
||||||
var (actor, _) = FindCurrentActor();
|
var (actor, _) = FindCurrentObject();
|
||||||
if( actor != null )
|
if( actor != null )
|
||||||
{
|
{
|
||||||
if( !StillLoading( RenderPtr( actor ) ) )
|
if( !StillLoading( RenderPtr( actor ) ) )
|
||||||
{
|
{
|
||||||
RestoreSettings();
|
RestoreSettings();
|
||||||
if( _wasTarget && _pi.ClientState.Targets.CurrentTarget == null )
|
if( _wasTarget && Dalamud.Targets.Target == null )
|
||||||
{
|
{
|
||||||
_pi.ClientState.Targets.SetCurrentTarget( actor );
|
Dalamud.Targets.SetTarget( actor );
|
||||||
}
|
}
|
||||||
|
|
||||||
_currentFrame = 0;
|
_currentFrame = 0;
|
||||||
|
|
@ -303,9 +300,9 @@ namespace Penumbra.Interop
|
||||||
|
|
||||||
private void OnUpdateEvent( object framework )
|
private void OnUpdateEvent( object framework )
|
||||||
{
|
{
|
||||||
if( _pi.ClientState.Condition[ ConditionFlag.BetweenAreas51 ]
|
if( Dalamud.Conditions[ ConditionFlag.BetweenAreas51 ]
|
||||||
|| _pi.ClientState.Condition[ ConditionFlag.BetweenAreas ]
|
|| Dalamud.Conditions[ ConditionFlag.BetweenAreas ]
|
||||||
|| _pi.ClientState.Condition[ ConditionFlag.OccupiedInCutSceneEvent ] )
|
|| Dalamud.Conditions[ ConditionFlag.OccupiedInCutSceneEvent ] )
|
||||||
{
|
{
|
||||||
_waitFrames = DefaultWaitFrames;
|
_waitFrames = DefaultWaitFrames;
|
||||||
return;
|
return;
|
||||||
|
|
@ -317,12 +314,12 @@ namespace Penumbra.Interop
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_inGPose = _pi.ClientState.Actors[ GPosePlayerActorIdx ] != null;
|
_inGPose = Dalamud.Objects[ GPosePlayerIdx ] != null;
|
||||||
|
|
||||||
switch( _currentFrame )
|
switch( _currentFrame )
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
PopActor();
|
PopObject();
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
ApplySettingsOrRedraw();
|
ApplySettingsOrRedraw();
|
||||||
|
|
@ -339,35 +336,35 @@ namespace Penumbra.Interop
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RedrawActorIntern( int actorId, string actorName, RedrawType settings )
|
private void RedrawObjectIntern( uint objectId, string actorName, RedrawType settings )
|
||||||
{
|
{
|
||||||
if( _actorIds.Contains( ( actorId, actorName, settings ) ) )
|
if( _actorIds.Contains( ( objectId, actorName, settings ) ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_actorIds.Enqueue( ( actorId, actorName, settings ) );
|
_actorIds.Enqueue( ( objectId, actorName, settings ) );
|
||||||
if( _actorIds.Count == 1 )
|
if( _actorIds.Count == 1 )
|
||||||
{
|
{
|
||||||
_pi.Framework.OnUpdateEvent += OnUpdateEvent;
|
Dalamud.Framework.Update += OnUpdateEvent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RedrawActor( Actor? actor, RedrawType settings = RedrawType.WithSettings )
|
public void RedrawObject( GameObject? actor, RedrawType settings = RedrawType.WithSettings )
|
||||||
{
|
{
|
||||||
if( actor != null )
|
if( actor != null )
|
||||||
{
|
{
|
||||||
RedrawActorIntern( actor.ActorId, actor.Name, settings );
|
RedrawObjectIntern( actor.ObjectId, actor.Name.ToString(), settings );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Actor? GetLocalPlayer()
|
private GameObject? GetLocalPlayer()
|
||||||
{
|
{
|
||||||
var gPoseActor = _pi.ClientState.Actors[ GPosePlayerActorIdx ];
|
var gPosePlayer = Dalamud.Objects[ GPosePlayerIdx ];
|
||||||
return gPoseActor ?? _pi.ClientState.Actors[ 0 ];
|
return gPosePlayer ?? Dalamud.Objects[ 0 ];
|
||||||
}
|
}
|
||||||
|
|
||||||
private Actor? GetName( string name )
|
private GameObject? GetName( string name )
|
||||||
{
|
{
|
||||||
var lowerName = name.ToLowerInvariant();
|
var lowerName = name.ToLowerInvariant();
|
||||||
return lowerName switch
|
return lowerName switch
|
||||||
|
|
@ -375,33 +372,33 @@ namespace Penumbra.Interop
|
||||||
"" => null,
|
"" => null,
|
||||||
"<me>" => GetLocalPlayer(),
|
"<me>" => GetLocalPlayer(),
|
||||||
"self" => GetLocalPlayer(),
|
"self" => GetLocalPlayer(),
|
||||||
"<t>" => _pi.ClientState.Targets.CurrentTarget,
|
"<t>" => Dalamud.Targets.Target,
|
||||||
"target" => _pi.ClientState.Targets.CurrentTarget,
|
"target" => Dalamud.Targets.Target,
|
||||||
"<f>" => _pi.ClientState.Targets.FocusTarget,
|
"<f>" => Dalamud.Targets.FocusTarget,
|
||||||
"focus" => _pi.ClientState.Targets.FocusTarget,
|
"focus" => Dalamud.Targets.FocusTarget,
|
||||||
"<mo>" => _pi.ClientState.Targets.MouseOverTarget,
|
"<mo>" => Dalamud.Targets.MouseOverTarget,
|
||||||
"mouseover" => _pi.ClientState.Targets.MouseOverTarget,
|
"mouseover" => Dalamud.Targets.MouseOverTarget,
|
||||||
_ => _pi.ClientState.Actors.FirstOrDefault(
|
_ => Dalamud.Objects.FirstOrDefault(
|
||||||
a => string.Equals( a.Name, lowerName, StringComparison.InvariantCultureIgnoreCase ) ),
|
a => string.Equals( a.Name.ToString(), lowerName, StringComparison.InvariantCultureIgnoreCase ) ),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RedrawActor( string name, RedrawType settings = RedrawType.WithSettings )
|
public void RedrawObject( string name, RedrawType settings = RedrawType.WithSettings )
|
||||||
=> RedrawActor( GetName( name ), settings );
|
=> RedrawObject( GetName( name ), settings );
|
||||||
|
|
||||||
public void RedrawAll( RedrawType settings = RedrawType.WithSettings )
|
public void RedrawAll( RedrawType settings = RedrawType.WithSettings )
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
foreach( var actor in _pi.ClientState.Actors )
|
foreach( var actor in Dalamud.Objects )
|
||||||
{
|
{
|
||||||
RedrawActor( actor, settings );
|
RedrawObject( actor, settings );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UnloadAll()
|
private void UnloadAll()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
foreach( var (actor, index) in _pi.ClientState.Actors.Select( ( a, i ) => ( a, i ) ) )
|
foreach( var (actor, index) in Dalamud.Objects.Select( ( a, i ) => ( a, i ) ) )
|
||||||
{
|
{
|
||||||
WriteInvisible( actor, index );
|
WriteInvisible( actor, index );
|
||||||
}
|
}
|
||||||
|
|
@ -410,7 +407,7 @@ namespace Penumbra.Interop
|
||||||
private void RedrawAllWithoutSettings()
|
private void RedrawAllWithoutSettings()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
foreach( var (actor, index) in _pi.ClientState.Actors.Select( ( a, i ) => ( a, i ) ) )
|
foreach( var (actor, index) in Dalamud.Objects.Select( ( a, i ) => ( a, i ) ) )
|
||||||
{
|
{
|
||||||
WriteVisible( actor, index );
|
WriteVisible( actor, index );
|
||||||
}
|
}
|
||||||
|
|
@ -442,7 +439,7 @@ namespace Penumbra.Interop
|
||||||
{
|
{
|
||||||
RevertSettings();
|
RevertSettings();
|
||||||
_actorIds.Clear();
|
_actorIds.Clear();
|
||||||
_pi.Framework.OnUpdateEvent -= OnUpdateEvent;
|
Dalamud.Framework.Update -= OnUpdateEvent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -3,21 +3,19 @@ using System.IO;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Hooking;
|
||||||
|
using Dalamud.Logging;
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Structs;
|
using Penumbra.Structs;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
using Reloaded.Hooks;
|
|
||||||
using Reloaded.Hooks.Definitions;
|
|
||||||
using Reloaded.Hooks.Definitions.X64;
|
|
||||||
using FileMode = Penumbra.Structs.FileMode;
|
using FileMode = Penumbra.Structs.FileMode;
|
||||||
|
|
||||||
namespace Penumbra.Interop
|
namespace Penumbra.Interop
|
||||||
{
|
{
|
||||||
public class ResourceLoader : IDisposable
|
public class ResourceLoader : IDisposable
|
||||||
{
|
{
|
||||||
public Plugin Plugin { get; set; }
|
public Penumbra Penumbra { get; set; }
|
||||||
|
|
||||||
public bool IsEnabled { get; set; }
|
public bool IsEnabled { get; set; }
|
||||||
|
|
||||||
|
|
@ -25,24 +23,24 @@ namespace Penumbra.Interop
|
||||||
|
|
||||||
|
|
||||||
// Delegate prototypes
|
// Delegate prototypes
|
||||||
[Function( CallingConventions.Microsoft )]
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||||
public unsafe delegate byte ReadFilePrototype( IntPtr pFileHandler, SeFileDescriptor* pFileDesc, int priority, bool isSync );
|
public unsafe delegate byte ReadFilePrototype( IntPtr pFileHandler, SeFileDescriptor* pFileDesc, int priority, bool isSync );
|
||||||
|
|
||||||
[Function( CallingConventions.Microsoft )]
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||||
public unsafe delegate byte ReadSqpackPrototype( IntPtr pFileHandler, SeFileDescriptor* pFileDesc, int priority, bool isSync );
|
public unsafe delegate byte ReadSqpackPrototype( IntPtr pFileHandler, SeFileDescriptor* pFileDesc, int priority, bool isSync );
|
||||||
|
|
||||||
[Function( CallingConventions.Microsoft )]
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||||
public unsafe delegate void* GetResourceSyncPrototype( IntPtr pFileManager, uint* pCategoryId, char* pResourceType
|
public unsafe delegate void* GetResourceSyncPrototype( IntPtr pFileManager, uint* pCategoryId, char* pResourceType
|
||||||
, uint* pResourceHash, char* pPath, void* pUnknown );
|
, uint* pResourceHash, char* pPath, void* pUnknown );
|
||||||
|
|
||||||
[Function( CallingConventions.Microsoft )]
|
[UnmanagedFunctionPointer( CallingConvention.ThisCall )]
|
||||||
public unsafe delegate void* GetResourceAsyncPrototype( IntPtr pFileManager, uint* pCategoryId, char* pResourceType
|
public unsafe delegate void* GetResourceAsyncPrototype( IntPtr pFileManager, uint* pCategoryId, char* pResourceType
|
||||||
, uint* pResourceHash, char* pPath, void* pUnknown, bool isUnknown );
|
, uint* pResourceHash, char* pPath, void* pUnknown, bool isUnknown );
|
||||||
|
|
||||||
// Hooks
|
// Hooks
|
||||||
public IHook< GetResourceSyncPrototype >? GetResourceSyncHook { get; private set; }
|
public Hook< GetResourceSyncPrototype >? GetResourceSyncHook { get; private set; }
|
||||||
public IHook< GetResourceAsyncPrototype >? GetResourceAsyncHook { get; private set; }
|
public Hook< GetResourceAsyncPrototype >? GetResourceAsyncHook { get; private set; }
|
||||||
public IHook< ReadSqpackPrototype >? ReadSqpackHook { get; private set; }
|
public Hook< ReadSqpackPrototype >? ReadSqpackHook { get; private set; }
|
||||||
|
|
||||||
// Unmanaged functions
|
// Unmanaged functions
|
||||||
public ReadFilePrototype? ReadFile { get; private set; }
|
public ReadFilePrototype? ReadFile { get; private set; }
|
||||||
|
|
@ -52,32 +50,30 @@ namespace Penumbra.Interop
|
||||||
public Regex? LogFileFilter = null;
|
public Regex? LogFileFilter = null;
|
||||||
|
|
||||||
|
|
||||||
public ResourceLoader( Plugin plugin )
|
public ResourceLoader( Penumbra penumbra )
|
||||||
{
|
{
|
||||||
Plugin = plugin;
|
Penumbra = penumbra;
|
||||||
Crc32 = new Crc32();
|
Crc32 = new Crc32();
|
||||||
}
|
}
|
||||||
|
|
||||||
public unsafe void Init()
|
public unsafe void Init()
|
||||||
{
|
{
|
||||||
var scanner = Plugin!.PluginInterface!.TargetModuleScanner;
|
|
||||||
|
|
||||||
var readFileAddress =
|
var readFileAddress =
|
||||||
scanner.ScanText( "E8 ?? ?? ?? ?? 84 C0 0F 84 ?? 00 00 00 4C 8B C3 BA 05" );
|
Dalamud.SigScanner.ScanText( "E8 ?? ?? ?? ?? 84 C0 0F 84 ?? 00 00 00 4C 8B C3 BA 05" );
|
||||||
|
|
||||||
var readSqpackAddress =
|
var readSqpackAddress =
|
||||||
scanner.ScanText( "E8 ?? ?? ?? ?? EB 05 E8 ?? ?? ?? ?? 84 C0 0F 84 ?? 00 00 00 4C 8B C3" );
|
Dalamud.SigScanner.ScanText( "E8 ?? ?? ?? ?? EB 05 E8 ?? ?? ?? ?? 84 C0 0F 84 ?? 00 00 00 4C 8B C3" );
|
||||||
|
|
||||||
var getResourceSyncAddress =
|
var getResourceSyncAddress =
|
||||||
scanner.ScanText( "E8 ?? ?? 00 00 48 8D 8F ?? ?? 00 00 48 89 87 ?? ?? 00 00" );
|
Dalamud.SigScanner.ScanText( "E8 ?? ?? 00 00 48 8D 8F ?? ?? 00 00 48 89 87 ?? ?? 00 00" );
|
||||||
|
|
||||||
var getResourceAsyncAddress =
|
var getResourceAsyncAddress =
|
||||||
scanner.ScanText( "E8 ?? ?? ?? 00 48 8B D8 EB ?? F0 FF 83 ?? ?? 00 00" );
|
Dalamud.SigScanner.ScanText( "E8 ?? ?? ?? 00 48 8B D8 EB ?? F0 FF 83 ?? ?? 00 00" );
|
||||||
|
|
||||||
|
|
||||||
ReadSqpackHook = new Hook< ReadSqpackPrototype >( ReadSqpackHandler, ( long )readSqpackAddress );
|
ReadSqpackHook = new Hook< ReadSqpackPrototype >( readSqpackAddress, ReadSqpackHandler );
|
||||||
GetResourceSyncHook = new Hook< GetResourceSyncPrototype >( GetResourceSyncHandler, ( long )getResourceSyncAddress );
|
GetResourceSyncHook = new Hook< GetResourceSyncPrototype >( getResourceSyncAddress, GetResourceSyncHandler );
|
||||||
GetResourceAsyncHook = new Hook< GetResourceAsyncPrototype >( GetResourceAsyncHandler, ( long )getResourceAsyncAddress );
|
GetResourceAsyncHook = new Hook< GetResourceAsyncPrototype >( getResourceAsyncAddress, GetResourceAsyncHandler );
|
||||||
|
|
||||||
ReadFile = Marshal.GetDelegateForFunctionPointer< ReadFilePrototype >( readFileAddress );
|
ReadFile = Marshal.GetDelegateForFunctionPointer< ReadFilePrototype >( readFileAddress );
|
||||||
}
|
}
|
||||||
|
|
@ -123,7 +119,7 @@ namespace Penumbra.Interop
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetResourceSyncHook.OriginalFunction( pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown );
|
return GetResourceSyncHook.Original( pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( GetResourceAsyncHook == null )
|
if( GetResourceAsyncHook == null )
|
||||||
|
|
@ -132,7 +128,7 @@ namespace Penumbra.Interop
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return GetResourceAsyncHook.OriginalFunction( pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
|
return GetResourceAsyncHook.Original( pFileManager, pCategoryId, pResourceType, pResourceHash, pPath, pUnknown, isUnknown );
|
||||||
}
|
}
|
||||||
|
|
||||||
private unsafe void* GetResourceHandler(
|
private unsafe void* GetResourceHandler(
|
||||||
|
|
@ -149,7 +145,7 @@ namespace Penumbra.Interop
|
||||||
string file;
|
string file;
|
||||||
var modManager = Service< ModManager >.Get();
|
var modManager = Service< ModManager >.Get();
|
||||||
|
|
||||||
if( !Plugin!.Configuration!.IsEnabled || modManager == null )
|
if( !Penumbra.Config.IsEnabled || modManager == null )
|
||||||
{
|
{
|
||||||
if( LogAllFiles )
|
if( LogAllFiles )
|
||||||
{
|
{
|
||||||
|
|
@ -197,7 +193,7 @@ namespace Penumbra.Interop
|
||||||
{
|
{
|
||||||
if( ReadFile == null || pFileDesc == null || pFileDesc->ResourceHandle == null )
|
if( ReadFile == null || pFileDesc == null || pFileDesc->ResourceHandle == null )
|
||||||
{
|
{
|
||||||
return ReadSqpackHook?.OriginalFunction( pFileHandler, pFileDesc, priority, isSync ) ?? 0;
|
return ReadSqpackHook?.Original( pFileHandler, pFileDesc, priority, isSync ) ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var gameFsPath = Marshal.PtrToStringAnsi( new IntPtr( pFileDesc->ResourceHandle->FileName() ) );
|
var gameFsPath = Marshal.PtrToStringAnsi( new IntPtr( pFileDesc->ResourceHandle->FileName() ) );
|
||||||
|
|
@ -206,7 +202,7 @@ namespace Penumbra.Interop
|
||||||
|
|
||||||
if( gameFsPath == null || gameFsPath.Length >= 260 || !isRooted )
|
if( gameFsPath == null || gameFsPath.Length >= 260 || !isRooted )
|
||||||
{
|
{
|
||||||
return ReadSqpackHook?.OriginalFunction( pFileHandler, pFileDesc, priority, isSync ) ?? 0;
|
return ReadSqpackHook?.Original( pFileHandler, pFileDesc, priority, isSync ) ?? 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginLog.Debug( "loading modded file: {GameFsPath}", gameFsPath );
|
PluginLog.Debug( "loading modded file: {GameFsPath}", gameFsPath );
|
||||||
|
|
@ -239,10 +235,6 @@ namespace Penumbra.Interop
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadSqpackHook.Activate();
|
|
||||||
GetResourceSyncHook.Activate();
|
|
||||||
GetResourceAsyncHook.Activate();
|
|
||||||
|
|
||||||
ReadSqpackHook.Enable();
|
ReadSqpackHook.Enable();
|
||||||
GetResourceSyncHook.Enable();
|
GetResourceSyncHook.Enable();
|
||||||
GetResourceAsyncHook.Enable();
|
GetResourceAsyncHook.Enable();
|
||||||
|
|
@ -267,6 +259,9 @@ namespace Penumbra.Interop
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
Disable();
|
Disable();
|
||||||
|
ReadSqpackHook?.Dispose();
|
||||||
|
GetResourceSyncHook?.Dispose();
|
||||||
|
GetResourceAsyncHook?.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -160,7 +160,7 @@ namespace Penumbra.Meta.Files
|
||||||
private void WriteBlocks( BinaryWriter bw )
|
private void WriteBlocks( BinaryWriter bw )
|
||||||
{
|
{
|
||||||
foreach( var entry in Blocks.Where( block => block != null )
|
foreach( var entry in Blocks.Where( block => block != null )
|
||||||
.SelectMany( block => block ) )
|
.SelectMany( block => block! ) )
|
||||||
{
|
{
|
||||||
bw.Write( ( ushort )entry );
|
bw.Write( ( ushort )entry );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ namespace Penumbra.Meta.Files
|
||||||
using var bw = new BinaryWriter( mem );
|
using var bw = new BinaryWriter( mem );
|
||||||
|
|
||||||
foreach( var parameter in blocks.Where( array => array != null )
|
foreach( var parameter in blocks.Where( array => array != null )
|
||||||
.SelectMany( array => array ) )
|
.SelectMany( array => array! ) )
|
||||||
{
|
{
|
||||||
bw.Write( transform( parameter ) );
|
bw.Write( transform( parameter ) );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using Dalamud.Logging;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Lumina.Data;
|
using Lumina.Data;
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
|
|
@ -12,8 +13,6 @@ namespace Penumbra.Meta.Files
|
||||||
// On first call, the default version of any supported file will be cached and can be returned without reparsing.
|
// On first call, the default version of any supported file will be cached and can be returned without reparsing.
|
||||||
public class MetaDefaults
|
public class MetaDefaults
|
||||||
{
|
{
|
||||||
private readonly DalamudPluginInterface _pi;
|
|
||||||
|
|
||||||
private readonly Dictionary< GamePath, object > _defaultFiles = new();
|
private readonly Dictionary< GamePath, object > _defaultFiles = new();
|
||||||
|
|
||||||
private object CreateNewFile( string path )
|
private object CreateNewFile( string path )
|
||||||
|
|
@ -110,14 +109,11 @@ namespace Penumbra.Meta.Files
|
||||||
public CmpFile? GetNewCmpFile()
|
public CmpFile? GetNewCmpFile()
|
||||||
=> GetDefaultCmpFile()?.Clone();
|
=> GetDefaultCmpFile()?.Clone();
|
||||||
|
|
||||||
public MetaDefaults( DalamudPluginInterface pi )
|
private static ImcFile GetImcFile( string path )
|
||||||
=> _pi = pi;
|
=> Dalamud.GameData.GetFile< ImcFile >( path )!;
|
||||||
|
|
||||||
private ImcFile GetImcFile( string path )
|
private static FileResource FetchFile( string name )
|
||||||
=> _pi.Data.GetFile< ImcFile >( path );
|
=> Dalamud.GameData.GetFile( name )!;
|
||||||
|
|
||||||
private FileResource FetchFile( string name )
|
|
||||||
=> _pi.Data.GetFile( name );
|
|
||||||
|
|
||||||
// Check that a given meta manipulation is an actual change to the default value. We don't need to keep changes to default.
|
// Check that a given meta manipulation is an actual change to the default value. We don't need to keep changes to default.
|
||||||
public bool CheckAgainstDefault( MetaManipulation m )
|
public bool CheckAgainstDefault( MetaManipulation m )
|
||||||
|
|
|
||||||
|
|
@ -2,7 +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 Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Penumbra.Importer;
|
using Penumbra.Importer;
|
||||||
using Penumbra.Meta.Files;
|
using Penumbra.Meta.Files;
|
||||||
|
|
@ -23,7 +23,7 @@ namespace Penumbra.Meta
|
||||||
|
|
||||||
// Store total number of manipulations for some ease of access.
|
// Store total number of manipulations for some ease of access.
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
internal int Count = 0;
|
internal int Count;
|
||||||
|
|
||||||
|
|
||||||
// Return an enumeration of all active meta manipulations for a given mod with given settings.
|
// Return an enumeration of all active meta manipulations for a given mod with given settings.
|
||||||
|
|
|
||||||
|
|
@ -2,7 +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 Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Lumina.Data.Files;
|
using Lumina.Data.Files;
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
|
|
@ -57,7 +57,7 @@ namespace Penumbra.Meta
|
||||||
=> _currentManipulations.Count;
|
=> _currentManipulations.Count;
|
||||||
|
|
||||||
public bool TryGetValue( MetaManipulation manip, out Mod.Mod mod )
|
public bool TryGetValue( MetaManipulation manip, out Mod.Mod mod )
|
||||||
=> _currentManipulations.TryGetValue( manip, out mod );
|
=> _currentManipulations.TryGetValue( manip, out mod! );
|
||||||
|
|
||||||
private static void DisposeFile( FileInfo? file )
|
private static void DisposeFile( FileInfo? 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 Dalamud.Logging;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
|
|
@ -73,7 +74,7 @@ namespace Penumbra
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultCollection.Save( Service< DalamudPluginInterface >.Get() );
|
defaultCollection.Save();
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Structs;
|
using Penumbra.Structs;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
|
|
|
||||||
|
|
@ -2,13 +2,13 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra.Mod
|
namespace Penumbra.Mod
|
||||||
{
|
{
|
||||||
public struct SortOrder : IComparable<SortOrder>
|
public struct SortOrder : IComparable< SortOrder >
|
||||||
{
|
{
|
||||||
public ModFolder ParentFolder { get; set; }
|
public ModFolder ParentFolder { get; set; }
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ namespace Penumbra.Mod
|
||||||
|
|
||||||
public SortOrder( ModFolder parentFolder, string name )
|
public SortOrder( ModFolder parentFolder, string name )
|
||||||
{
|
{
|
||||||
ParentFolder = parentFolder;
|
ParentFolder = parentFolder;
|
||||||
_sortOrderName = name.Replace( '/', '\\' );
|
_sortOrderName = name.Replace( '/', '\\' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,7 +43,7 @@ namespace Penumbra.Mod
|
||||||
=> SortOrderPath.Any() ? $"{SortOrderPath}/{SortOrderName}" : SortOrderName;
|
=> SortOrderPath.Any() ? $"{SortOrderPath}/{SortOrderName}" : SortOrderName;
|
||||||
|
|
||||||
public int CompareTo( SortOrder other )
|
public int CompareTo( SortOrder other )
|
||||||
=> string.Compare(FullPath, other.FullPath, StringComparison.InvariantCultureIgnoreCase );
|
=> string.Compare( FullPath, other.FullPath, StringComparison.InvariantCultureIgnoreCase );
|
||||||
}
|
}
|
||||||
|
|
||||||
// ModData contains all permanent information about a mod,
|
// ModData contains all permanent information about a mod,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +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 Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Structs;
|
using Penumbra.Structs;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +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 Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
|
|
@ -12,7 +12,6 @@ namespace Penumbra.Mods
|
||||||
// Contains all collections and respective functions, as well as the collection settings.
|
// Contains all collections and respective functions, as well as the collection settings.
|
||||||
public class CollectionManager
|
public class CollectionManager
|
||||||
{
|
{
|
||||||
private readonly Plugin _plugin;
|
|
||||||
private readonly ModManager _manager;
|
private readonly ModManager _manager;
|
||||||
|
|
||||||
public Dictionary< string, ModCollection > Collections { get; } = new();
|
public Dictionary< string, ModCollection > Collections { get; } = new();
|
||||||
|
|
@ -24,13 +23,12 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
public ModCollection ActiveCollection { get; set; }
|
public ModCollection ActiveCollection { get; set; }
|
||||||
|
|
||||||
public CollectionManager( Plugin plugin, ModManager manager )
|
public CollectionManager( ModManager manager )
|
||||||
{
|
{
|
||||||
_plugin = plugin;
|
|
||||||
_manager = manager;
|
_manager = manager;
|
||||||
|
|
||||||
ReadCollections();
|
ReadCollections();
|
||||||
LoadConfigCollections( _plugin.Configuration );
|
LoadConfigCollections( Penumbra.Config );
|
||||||
ActiveCollection = DefaultCollection;
|
ActiveCollection = DefaultCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,7 +93,7 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
var newCollection = new ModCollection( name, settings );
|
var newCollection = new ModCollection( name, settings );
|
||||||
Collections.Add( name, newCollection );
|
Collections.Add( name, newCollection );
|
||||||
SaveCollection( newCollection );
|
newCollection.Save();
|
||||||
SetCurrentCollection( newCollection );
|
SetCurrentCollection( newCollection );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -133,7 +131,7 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
collection.Delete( _plugin.PluginInterface! );
|
collection.Delete();
|
||||||
Collections.Remove( name );
|
Collections.Remove( name );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -179,7 +177,7 @@ namespace Penumbra.Mods
|
||||||
setter( newCollection );
|
setter( newCollection );
|
||||||
RemoveCache( oldCollection );
|
RemoveCache( oldCollection );
|
||||||
configSetter( newCollection.Name );
|
configSetter( newCollection.Name );
|
||||||
_plugin.Configuration.Save();
|
Penumbra.Config.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetDefaultCollection( ModCollection newCollection )
|
public void SetDefaultCollection( ModCollection newCollection )
|
||||||
|
|
@ -193,13 +191,13 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultCollection = c;
|
DefaultCollection = c;
|
||||||
}, s => _plugin.Configuration.DefaultCollection = s );
|
}, s => Penumbra.Config.DefaultCollection = s );
|
||||||
|
|
||||||
public void SetForcedCollection( ModCollection newCollection )
|
public void SetForcedCollection( ModCollection newCollection )
|
||||||
=> SetCollection( newCollection, ForcedCollection, c => ForcedCollection = c, s => _plugin.Configuration.ForcedCollection = s );
|
=> SetCollection( newCollection, ForcedCollection, c => ForcedCollection = c, s => Penumbra.Config.ForcedCollection = s );
|
||||||
|
|
||||||
public void SetCurrentCollection( ModCollection newCollection )
|
public void SetCurrentCollection( ModCollection newCollection )
|
||||||
=> SetCollection( newCollection, CurrentCollection, c => CurrentCollection = c, s => _plugin.Configuration.CurrentCollection = s );
|
=> SetCollection( newCollection, CurrentCollection, c => CurrentCollection = c, s => Penumbra.Config.CurrentCollection = s );
|
||||||
|
|
||||||
public void SetCharacterCollection( string characterName, ModCollection newCollection )
|
public void SetCharacterCollection( string characterName, ModCollection newCollection )
|
||||||
=> SetCollection( newCollection,
|
=> SetCollection( newCollection,
|
||||||
|
|
@ -215,16 +213,16 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
|
|
||||||
CharacterCollection[ characterName ] = c;
|
CharacterCollection[ characterName ] = c;
|
||||||
}, s => _plugin.Configuration.CharacterCollections[ characterName ] = s );
|
}, s => Penumbra.Config.CharacterCollections[ characterName ] = s );
|
||||||
|
|
||||||
public bool CreateCharacterCollection( string characterName )
|
public bool CreateCharacterCollection( string characterName )
|
||||||
{
|
{
|
||||||
if( !CharacterCollection.ContainsKey( characterName ) )
|
if( !CharacterCollection.ContainsKey( characterName ) )
|
||||||
{
|
{
|
||||||
CharacterCollection[ characterName ] = ModCollection.Empty;
|
CharacterCollection[ characterName ] = ModCollection.Empty;
|
||||||
_plugin.Configuration.CharacterCollections[ characterName ] = string.Empty;
|
Penumbra.Config.CharacterCollections[ characterName ] = string.Empty;
|
||||||
_plugin.Configuration.Save();
|
Penumbra.Config.Save();
|
||||||
_plugin.PlayerWatcher.AddPlayerToWatch( characterName );
|
Penumbra.PlayerWatcher.AddPlayerToWatch( characterName );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -237,12 +235,12 @@ namespace Penumbra.Mods
|
||||||
{
|
{
|
||||||
RemoveCache( collection );
|
RemoveCache( collection );
|
||||||
CharacterCollection.Remove( characterName );
|
CharacterCollection.Remove( characterName );
|
||||||
_plugin.PlayerWatcher.RemovePlayerFromWatch( characterName );
|
Penumbra.PlayerWatcher.RemovePlayerFromWatch( characterName );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _plugin.Configuration.CharacterCollections.Remove( characterName ) )
|
if( Penumbra.Config.CharacterCollections.Remove( characterName ) )
|
||||||
{
|
{
|
||||||
_plugin.Configuration.Save();
|
Penumbra.Config.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -308,7 +306,7 @@ namespace Penumbra.Mods
|
||||||
var configChanged = false;
|
var configChanged = false;
|
||||||
foreach( var kvp in config.CharacterCollections.ToArray() )
|
foreach( var kvp in config.CharacterCollections.ToArray() )
|
||||||
{
|
{
|
||||||
_plugin.PlayerWatcher.AddPlayerToWatch( kvp.Key );
|
Penumbra.PlayerWatcher.AddPlayerToWatch( kvp.Key );
|
||||||
if( kvp.Value == string.Empty )
|
if( kvp.Value == string.Empty )
|
||||||
{
|
{
|
||||||
CharacterCollection.Add( kvp.Key, ModCollection.Empty );
|
CharacterCollection.Add( kvp.Key, ModCollection.Empty );
|
||||||
|
|
@ -345,7 +343,7 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
private void ReadCollections()
|
private void ReadCollections()
|
||||||
{
|
{
|
||||||
var collectionDir = ModCollection.CollectionDir( _plugin.PluginInterface! );
|
var collectionDir = ModCollection.CollectionDir();
|
||||||
if( collectionDir.Exists )
|
if( collectionDir.Exists )
|
||||||
{
|
{
|
||||||
foreach( var file in collectionDir.EnumerateFiles( "*.json" ) )
|
foreach( var file in collectionDir.EnumerateFiles( "*.json" ) )
|
||||||
|
|
@ -373,12 +371,9 @@ namespace Penumbra.Mods
|
||||||
if( !Collections.ContainsKey( ModCollection.DefaultCollection ) )
|
if( !Collections.ContainsKey( ModCollection.DefaultCollection ) )
|
||||||
{
|
{
|
||||||
var defaultCollection = new ModCollection();
|
var defaultCollection = new ModCollection();
|
||||||
SaveCollection( defaultCollection );
|
defaultCollection.Save();
|
||||||
Collections.Add( defaultCollection.Name, defaultCollection );
|
Collections.Add( defaultCollection.Name, defaultCollection );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SaveCollection( ModCollection collection )
|
|
||||||
=> collection.Save( _plugin.PluginInterface! );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -4,6 +4,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Dalamud.Logging;
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
|
|
@ -49,7 +50,7 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
var newSettings = ModSettings.DefaultSettings( mod.Meta );
|
var newSettings = ModSettings.DefaultSettings( mod.Meta );
|
||||||
Settings.Add( mod.BasePath.Name, newSettings );
|
Settings.Add( mod.BasePath.Name, newSettings );
|
||||||
Save( Service< DalamudPluginInterface >.Get() );
|
Save();
|
||||||
return new Mod.Mod( newSettings, mod );
|
return new Mod.Mod( newSettings, mod );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -86,7 +87,7 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
if( changedSettings )
|
if( changedSettings )
|
||||||
{
|
{
|
||||||
Save( Service< DalamudPluginInterface >.Get() );
|
Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
CalculateEffectiveFileList( modDirectory, true, false );
|
CalculateEffectiveFileList( modDirectory, true, false );
|
||||||
|
|
@ -104,7 +105,7 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
if( settings.FixInvalidSettings( mod.Meta ) )
|
if( settings.FixInvalidSettings( mod.Meta ) )
|
||||||
{
|
{
|
||||||
Save( Service< DalamudPluginInterface >.Get() );
|
Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -123,7 +124,7 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
if( changes )
|
if( changes )
|
||||||
{
|
{
|
||||||
Save( Service< DalamudPluginInterface >.Get() );
|
Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,8 +182,8 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static DirectoryInfo CollectionDir( DalamudPluginInterface pi )
|
public static DirectoryInfo CollectionDir()
|
||||||
=> new( Path.Combine( pi.GetPluginConfigDirectory(), "collections" ) );
|
=> new( Path.Combine( Dalamud.PluginInterface.GetPluginConfigDirectory(), "collections" ) );
|
||||||
|
|
||||||
private static FileInfo FileName( DirectoryInfo collectionDir, string name )
|
private static FileInfo FileName( DirectoryInfo collectionDir, string name )
|
||||||
=> new( Path.Combine( collectionDir.FullName, $"{name.RemoveInvalidPathSymbols()}.json" ) );
|
=> new( Path.Combine( collectionDir.FullName, $"{name.RemoveInvalidPathSymbols()}.json" ) );
|
||||||
|
|
@ -191,11 +192,11 @@ namespace Penumbra.Mods
|
||||||
=> new( Path.Combine( Service< DalamudPluginInterface >.Get().GetPluginConfigDirectory(),
|
=> new( Path.Combine( Service< DalamudPluginInterface >.Get().GetPluginConfigDirectory(),
|
||||||
$"{Name.RemoveInvalidPathSymbols()}.json" ) );
|
$"{Name.RemoveInvalidPathSymbols()}.json" ) );
|
||||||
|
|
||||||
public void Save( DalamudPluginInterface pi )
|
public void Save()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var dir = CollectionDir( pi );
|
var dir = CollectionDir();
|
||||||
dir.Create();
|
dir.Create();
|
||||||
var file = FileName( dir, Name );
|
var file = FileName( dir, Name );
|
||||||
SaveToFile( file );
|
SaveToFile( file );
|
||||||
|
|
@ -206,15 +207,15 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ModCollection? Load( string name, DalamudPluginInterface pi )
|
public static ModCollection? Load( string name )
|
||||||
{
|
{
|
||||||
var file = FileName( CollectionDir( pi ), name );
|
var file = FileName( CollectionDir(), name );
|
||||||
return file.Exists ? LoadFromFile( file ) : null;
|
return file.Exists ? LoadFromFile( file ) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Delete( DalamudPluginInterface pi )
|
public void Delete()
|
||||||
{
|
{
|
||||||
var file = FileName( CollectionDir( pi ), Name );
|
var file = FileName( CollectionDir(), Name );
|
||||||
if( file.Exists )
|
if( file.Exists )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -120,8 +120,8 @@ namespace Penumbra.Mods
|
||||||
|
|
||||||
private class PriorityComparer : IComparer< Mod.Mod >
|
private class PriorityComparer : IComparer< Mod.Mod >
|
||||||
{
|
{
|
||||||
public int Compare( Mod.Mod x, Mod.Mod y )
|
public int Compare( Mod.Mod? x, Mod.Mod? y )
|
||||||
=> x.Settings.Priority.CompareTo( y.Settings.Priority );
|
=> (x?.Settings.Priority ?? 0).CompareTo( y?.Settings.Priority ?? 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static readonly PriorityComparer Comparer = new();
|
private static readonly PriorityComparer Comparer = new();
|
||||||
|
|
|
||||||
|
|
@ -141,18 +141,17 @@ namespace Penumbra.Mods
|
||||||
// Sets and saves the sort order of a single mod, removing the entry if it is unnecessary.
|
// Sets and saves the sort order of a single mod, removing the entry if it is unnecessary.
|
||||||
private static void SaveMod( ModData mod )
|
private static void SaveMod( ModData mod )
|
||||||
{
|
{
|
||||||
var config = Service< Configuration >.Get();
|
|
||||||
if( ReferenceEquals( mod.SortOrder.ParentFolder, Root )
|
if( ReferenceEquals( mod.SortOrder.ParentFolder, Root )
|
||||||
&& string.Equals( mod.SortOrder.SortOrderName, mod.Meta.Name.Replace( '/', '\\' ), StringComparison.InvariantCultureIgnoreCase ) )
|
&& string.Equals( mod.SortOrder.SortOrderName, mod.Meta.Name.Replace( '/', '\\' ), StringComparison.InvariantCultureIgnoreCase ) )
|
||||||
{
|
{
|
||||||
config.ModSortOrder.Remove( mod.BasePath.Name );
|
Penumbra.Config.ModSortOrder.Remove( mod.BasePath.Name );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
config.ModSortOrder[ mod.BasePath.Name ] = mod.SortOrder.FullName;
|
Penumbra.Config.ModSortOrder[ mod.BasePath.Name ] = mod.SortOrder.FullName;
|
||||||
}
|
}
|
||||||
|
|
||||||
config.Save();
|
Penumbra.Config.Save();
|
||||||
InvokeChange();
|
InvokeChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -149,30 +149,30 @@ namespace Penumbra.Mods
|
||||||
internal class ModFolderComparer : IComparer< ModFolder >
|
internal class ModFolderComparer : IComparer< ModFolder >
|
||||||
{
|
{
|
||||||
// Compare only the direct folder names since this is only used inside an enumeration of subfolders of one folder.
|
// Compare only the direct folder names since this is only used inside an enumeration of subfolders of one folder.
|
||||||
public int Compare( ModFolder x, ModFolder y )
|
public int Compare( ModFolder? x, ModFolder? y )
|
||||||
=> ReferenceEquals( x, y )
|
=> ReferenceEquals( x, y )
|
||||||
? 0
|
? 0
|
||||||
: string.Compare( x.Name, y.Name, StringComparison.InvariantCultureIgnoreCase );
|
: string.Compare( x?.Name ?? string.Empty, y?.Name ?? string.Empty, StringComparison.InvariantCultureIgnoreCase );
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class ModDataComparer : IComparer< ModData >
|
internal class ModDataComparer : IComparer< ModData >
|
||||||
{
|
{
|
||||||
// Compare only the direct SortOrderNames since this is only used inside an enumeration of direct mod children of one folder.
|
// Compare only the direct SortOrderNames since this is only used inside an enumeration of direct mod children of one folder.
|
||||||
// Since mod SortOrderNames do not have to be unique inside a folder, also compare their BasePaths (and thus their identity) if necessary.
|
// Since mod SortOrderNames do not have to be unique inside a folder, also compare their BasePaths (and thus their identity) if necessary.
|
||||||
public int Compare( ModData x, ModData y )
|
public int Compare( ModData? x, ModData? y )
|
||||||
{
|
{
|
||||||
if( ReferenceEquals( x, y ) )
|
if( ReferenceEquals( x, y ) )
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cmp = string.Compare( x.SortOrder.SortOrderName, y.SortOrder.SortOrderName, StringComparison.InvariantCultureIgnoreCase );
|
var cmp = string.Compare( x?.SortOrder.SortOrderName, y?.SortOrder.SortOrderName, StringComparison.InvariantCultureIgnoreCase );
|
||||||
if( cmp != 0 )
|
if( cmp != 0 )
|
||||||
{
|
{
|
||||||
return cmp;
|
return cmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Compare( x.BasePath.Name, y.BasePath.Name, StringComparison.InvariantCulture );
|
return string.Compare( x?.BasePath.Name, y?.BasePath.Name, StringComparison.InvariantCulture );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +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 Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using ImGuiScene;
|
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Meta;
|
using Penumbra.Meta;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
|
|
@ -14,7 +13,6 @@ namespace Penumbra.Mods
|
||||||
// It also contains the CollectionManager that handles all collections.
|
// It also contains the CollectionManager that handles all collections.
|
||||||
public class ModManager
|
public class ModManager
|
||||||
{
|
{
|
||||||
private readonly Plugin _plugin;
|
|
||||||
public DirectoryInfo BasePath { get; private set; } = null!;
|
public DirectoryInfo BasePath { get; private set; } = null!;
|
||||||
public DirectoryInfo TempPath { get; private set; } = null!;
|
public DirectoryInfo TempPath { get; private set; } = null!;
|
||||||
|
|
||||||
|
|
@ -27,7 +25,7 @@ namespace Penumbra.Mods
|
||||||
public bool TempWritable { get; private set; }
|
public bool TempWritable { get; private set; }
|
||||||
|
|
||||||
public Configuration Config
|
public Configuration Config
|
||||||
=> _plugin.Configuration;
|
=> Penumbra.Config;
|
||||||
|
|
||||||
public void DiscoverMods( string newDir )
|
public void DiscoverMods( string newDir )
|
||||||
{
|
{
|
||||||
|
|
@ -167,12 +165,11 @@ namespace Penumbra.Mods
|
||||||
public void SetTempDirectory( string newPath )
|
public void SetTempDirectory( string newPath )
|
||||||
=> SetTempDirectory( newPath, false );
|
=> SetTempDirectory( newPath, false );
|
||||||
|
|
||||||
public ModManager( Plugin plugin )
|
public ModManager()
|
||||||
{
|
{
|
||||||
_plugin = plugin;
|
|
||||||
SetBaseDirectory( Config.ModDirectory, true );
|
SetBaseDirectory( Config.ModDirectory, true );
|
||||||
SetTempDirectory( Config.TempDirectory, true );
|
SetTempDirectory( Config.TempDirectory, true );
|
||||||
Collections = new CollectionManager( plugin, this );
|
Collections = new CollectionManager( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool SetSortOrderPath( ModData mod, string path )
|
private bool SetSortOrderPath( ModData mod, string path )
|
||||||
|
|
@ -194,7 +191,7 @@ namespace Penumbra.Mods
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SetModStructure(bool removeOldPaths = false )
|
private void SetModStructure( bool removeOldPaths = false )
|
||||||
{
|
{
|
||||||
var changes = false;
|
var changes = false;
|
||||||
|
|
||||||
|
|
@ -204,7 +201,7 @@ namespace Penumbra.Mods
|
||||||
{
|
{
|
||||||
changes |= SetSortOrderPath( mod, kvp.Value );
|
changes |= SetSortOrderPath( mod, kvp.Value );
|
||||||
}
|
}
|
||||||
else if (removeOldPaths)
|
else if( removeOldPaths )
|
||||||
{
|
{
|
||||||
changes = true;
|
changes = true;
|
||||||
Config.ModSortOrder.Remove( kvp.Key );
|
Config.ModSortOrder.Remove( kvp.Key );
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Dalamud.Logging;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
using Penumbra.Structs;
|
using Penumbra.Structs;
|
||||||
|
|
@ -93,7 +94,7 @@ namespace Penumbra.Mods
|
||||||
{
|
{
|
||||||
collection.Settings[ newDir.Name ] = settings;
|
collection.Settings[ newDir.Name ] = settings;
|
||||||
collection.Settings.Remove( oldBasePath.Name );
|
collection.Settings.Remove( oldBasePath.Name );
|
||||||
manager.Collections.SaveCollection( collection );
|
collection.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( collection.Cache != null )
|
if( collection.Cache != null )
|
||||||
|
|
@ -158,7 +159,7 @@ namespace Penumbra.Mods
|
||||||
}
|
}
|
||||||
|
|
||||||
settings.Settings.Remove( oldGroupName );
|
settings.Settings.Remove( oldGroupName );
|
||||||
manager.Collections.SaveCollection( collection );
|
collection.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
@ -203,7 +204,7 @@ namespace Penumbra.Mods
|
||||||
if( newSetting != setting )
|
if( newSetting != setting )
|
||||||
{
|
{
|
||||||
settings.Settings[ group.GroupName ] = newSetting;
|
settings.Settings[ group.GroupName ] = newSetting;
|
||||||
manager.Collections.SaveCollection( collection );
|
collection.Save();
|
||||||
if( collection.Cache != null && settings.Enabled )
|
if( collection.Cache != null && settings.Enabled )
|
||||||
{
|
{
|
||||||
collection.CalculateEffectiveFileList( manager.TempPath, mod.Resources.MetaManipulations.Count > 0,
|
collection.CalculateEffectiveFileList( manager.TempPath, mod.Resources.MetaManipulations.Count > 0,
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,12 @@
|
||||||
using Dalamud.Game.Command;
|
using Dalamud.Game.Command;
|
||||||
|
using Dalamud.Logging;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Plugin;
|
||||||
using EmbedIO;
|
using EmbedIO;
|
||||||
using EmbedIO.WebApi;
|
using EmbedIO.WebApi;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Lumina.Excel.GeneratedSheets;
|
using Lumina.Excel.GeneratedSheets;
|
||||||
using Penumbra.Api;
|
using Penumbra.Api;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
using Penumbra.Meta.Files;
|
using Penumbra.Meta.Files;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
|
@ -14,61 +16,47 @@ using Penumbra.Util;
|
||||||
|
|
||||||
namespace Penumbra
|
namespace Penumbra
|
||||||
{
|
{
|
||||||
public class Plugin : IDalamudPlugin
|
public class Penumbra : IDalamudPlugin
|
||||||
{
|
{
|
||||||
public string Name { get; }
|
public string Name { get; } = "Penumbra";
|
||||||
public string PluginDebugTitleStr { get; }
|
public string PluginDebugTitleStr { get; } = "Penumbra - Debug Build";
|
||||||
|
|
||||||
public Plugin()
|
|
||||||
{
|
|
||||||
Name = "Penumbra";
|
|
||||||
PluginDebugTitleStr = $"{Name} - Debug Build";
|
|
||||||
}
|
|
||||||
|
|
||||||
private const string CommandName = "/penumbra";
|
private const string CommandName = "/penumbra";
|
||||||
|
|
||||||
public DalamudPluginInterface PluginInterface { get; set; } = null!;
|
public static Configuration Config { get; private set; } = null!;
|
||||||
public Configuration Configuration { get; set; } = null!;
|
public static IPlayerWatcher PlayerWatcher { get; private set; } = null!;
|
||||||
public ResourceLoader ResourceLoader { get; set; } = null!;
|
|
||||||
public SettingsInterface SettingsInterface { get; set; } = null!;
|
|
||||||
public MusicManager SoundShit { get; set; } = null!;
|
|
||||||
public ActorRefresher ActorRefresher { get; set; } = null!;
|
|
||||||
public IPlayerWatcher PlayerWatcher { get; set; } = null!;
|
|
||||||
public PenumbraApi Api { get; set; } = null!;
|
|
||||||
|
|
||||||
|
public ResourceLoader ResourceLoader { get; }
|
||||||
|
public SettingsInterface SettingsInterface { get; }
|
||||||
|
public MusicManager SoundShit { get; }
|
||||||
|
public ObjectReloader ObjectReloader { get; }
|
||||||
|
|
||||||
|
public PenumbraApi Api { get; }
|
||||||
|
public PenumbraIpc Ipc { get; }
|
||||||
|
|
||||||
private WebServer? _webServer;
|
private WebServer? _webServer;
|
||||||
|
|
||||||
public static void SaveConfiguration()
|
public Penumbra( DalamudPluginInterface pluginInterface )
|
||||||
{
|
{
|
||||||
var pi = Service< DalamudPluginInterface >.Get();
|
Dalamud.Initialize( pluginInterface );
|
||||||
var config = Service< Configuration >.Get();
|
GameData.GameData.GetIdentifier( Dalamud.GameData, Dalamud.ClientState.ClientLanguage );
|
||||||
pi.SavePluginConfig( config );
|
Config = Configuration.Load();
|
||||||
}
|
|
||||||
|
|
||||||
public void Initialize( DalamudPluginInterface pluginInterface )
|
SoundShit = new MusicManager();
|
||||||
{
|
|
||||||
PluginInterface = pluginInterface;
|
|
||||||
Service< DalamudPluginInterface >.Set( PluginInterface );
|
|
||||||
GameData.GameData.GetIdentifier( PluginInterface );
|
|
||||||
Configuration = Configuration.Load( PluginInterface );
|
|
||||||
Service< Configuration >.Set( Configuration );
|
|
||||||
|
|
||||||
SoundShit = new MusicManager( this );
|
|
||||||
SoundShit.DisableStreaming();
|
SoundShit.DisableStreaming();
|
||||||
|
|
||||||
var gameUtils = Service< GameResourceManagement >.Set( PluginInterface );
|
var gameUtils = Service< GameResourceManagement >.Set();
|
||||||
PlayerWatcher = PlayerWatchFactory.Create( PluginInterface );
|
PlayerWatcher = PlayerWatchFactory.Create( Dalamud.Framework, Dalamud.ClientState, Dalamud.Objects );
|
||||||
Service< MetaDefaults >.Set( PluginInterface );
|
Service< MetaDefaults >.Set();
|
||||||
var modManager = Service< ModManager >.Set( this );
|
var modManager = Service< ModManager >.Set();
|
||||||
|
|
||||||
modManager.DiscoverMods();
|
modManager.DiscoverMods();
|
||||||
|
|
||||||
ActorRefresher = new ActorRefresher( PluginInterface, modManager, Configuration.WaitFrames );
|
ObjectReloader = new ObjectReloader( modManager, Config.WaitFrames );
|
||||||
|
|
||||||
ResourceLoader = new ResourceLoader( this );
|
ResourceLoader = new ResourceLoader( this );
|
||||||
|
|
||||||
PluginInterface.CommandManager.AddHandler( CommandName, new CommandInfo( OnCommand )
|
Dalamud.Commands.AddHandler( CommandName, new CommandInfo( OnCommand )
|
||||||
{
|
{
|
||||||
HelpMessage = "/penumbra - toggle ui\n/penumbra reload - reload mod file lists & discover any new mods",
|
HelpMessage = "/penumbra - toggle ui\n/penumbra reload - reload mod file lists & discover any new mods",
|
||||||
} );
|
} );
|
||||||
|
|
@ -80,24 +68,25 @@ namespace Penumbra
|
||||||
|
|
||||||
SettingsInterface = new SettingsInterface( this );
|
SettingsInterface = new SettingsInterface( this );
|
||||||
|
|
||||||
if( Configuration.EnableHttpApi )
|
if( Config.EnableHttpApi )
|
||||||
{
|
{
|
||||||
CreateWebServer();
|
CreateWebServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !Configuration.EnableActorWatch || !Configuration.IsEnabled )
|
if( !Config.EnablePlayerWatch || !Config.IsEnabled )
|
||||||
{
|
{
|
||||||
PlayerWatcher.Disable();
|
PlayerWatcher.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlayerWatcher.ActorChanged += a =>
|
PlayerWatcher.PlayerChanged += p =>
|
||||||
{
|
{
|
||||||
PluginLog.Debug( "Triggered Redraw of {Actor}.", a.Name );
|
PluginLog.Debug( "Triggered Redraw of {Player}.", p.Name );
|
||||||
ActorRefresher.RedrawActor( a, RedrawType.OnlyWithSettings );
|
ObjectReloader.RedrawObject( p, RedrawType.OnlyWithSettings );
|
||||||
};
|
};
|
||||||
|
|
||||||
Api = new PenumbraApi( this );
|
Api = new PenumbraApi( this );
|
||||||
SubscribeItemLinks();
|
SubscribeItemLinks();
|
||||||
|
Ipc = new PenumbraIpc( pluginInterface, Api );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SubscribeItemLinks()
|
private void SubscribeItemLinks()
|
||||||
|
|
@ -120,7 +109,7 @@ namespace Penumbra
|
||||||
|
|
||||||
public void CreateWebServer()
|
public void CreateWebServer()
|
||||||
{
|
{
|
||||||
var prefix = "http://localhost:42069/";
|
const string prefix = "http://localhost:42069/";
|
||||||
|
|
||||||
ShutdownWebServer();
|
ShutdownWebServer();
|
||||||
|
|
||||||
|
|
@ -146,11 +135,10 @@ namespace Penumbra
|
||||||
{
|
{
|
||||||
Api.Dispose();
|
Api.Dispose();
|
||||||
SettingsInterface.Dispose();
|
SettingsInterface.Dispose();
|
||||||
ActorRefresher.Dispose();
|
ObjectReloader.Dispose();
|
||||||
PlayerWatcher.Dispose();
|
PlayerWatcher.Dispose();
|
||||||
|
|
||||||
PluginInterface.CommandManager.RemoveHandler( CommandName );
|
Dalamud.Commands.RemoveHandler( CommandName );
|
||||||
PluginInterface.Dispose();
|
|
||||||
|
|
||||||
ResourceLoader.Dispose();
|
ResourceLoader.Dispose();
|
||||||
|
|
||||||
|
|
@ -167,7 +155,7 @@ namespace Penumbra
|
||||||
case "reload":
|
case "reload":
|
||||||
{
|
{
|
||||||
Service< ModManager >.Get().DiscoverMods();
|
Service< ModManager >.Get().DiscoverMods();
|
||||||
PluginInterface.Framework.Gui.Chat.Print(
|
Dalamud.Chat.Print(
|
||||||
$"Reloaded Penumbra mods. You have {Service< ModManager >.Get()?.Mods.Count} mods."
|
$"Reloaded Penumbra mods. You have {Service< ModManager >.Get()?.Mods.Count} mods."
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
@ -176,11 +164,11 @@ namespace Penumbra
|
||||||
{
|
{
|
||||||
if( args.Length > 1 )
|
if( args.Length > 1 )
|
||||||
{
|
{
|
||||||
ActorRefresher.RedrawActor( args[ 1 ] );
|
ObjectReloader.RedrawObject( args[ 1 ] );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ActorRefresher.RedrawAll();
|
ObjectReloader.RedrawAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net472</TargetFramework>
|
<TargetFramework>net5.0-windows</TargetFramework>
|
||||||
<LangVersion>preview</LangVersion>
|
<LangVersion>preview</LangVersion>
|
||||||
|
<PlatformTarget>x64</PlatformTarget>
|
||||||
<AssemblyTitle>Penumbra</AssemblyTitle>
|
<AssemblyTitle>Penumbra</AssemblyTitle>
|
||||||
<Company>absolute gangstas</Company>
|
<Company>absolute gangstas</Company>
|
||||||
<Product>Penumbra</Product>
|
<Product>Penumbra</Product>
|
||||||
|
|
@ -11,6 +12,7 @@
|
||||||
<OutputPath>bin\$(Configuration)\</OutputPath>
|
<OutputPath>bin\$(Configuration)\</OutputPath>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
|
@ -59,22 +61,13 @@
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Reference Include="System.Windows.Forms" />
|
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
|
||||||
<Reference Include="Microsoft.CSharp" />
|
|
||||||
<Reference Include="System.Net.Http" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="EmbedIO" Version="3.4.3" />
|
<PackageReference Include="EmbedIO" Version="3.4.3" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="Reloaded.Hooks" Version="2.4.1" />
|
|
||||||
<PackageReference Include="SharpZipLib" Version="1.3.1" />
|
<PackageReference Include="SharpZipLib" Version="1.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Penumbra.API\Penumbra.Api.csproj" />
|
|
||||||
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
<ProjectReference Include="..\Penumbra.GameData\Penumbra.GameData.csproj" />
|
||||||
<ProjectReference Include="..\Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj" />
|
<ProjectReference Include="..\Penumbra.PlayerWatch\Penumbra.PlayerWatch.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -27,17 +27,13 @@ namespace Penumbra.UI
|
||||||
| ImGuiWindowFlags.NoSavedSettings;
|
| ImGuiWindowFlags.NoSavedSettings;
|
||||||
|
|
||||||
private readonly SettingsInterface _base;
|
private readonly SettingsInterface _base;
|
||||||
private readonly Dalamud.Game.ClientState.Condition _condition;
|
|
||||||
|
|
||||||
public ManageModsButton( SettingsInterface ui )
|
public ManageModsButton( SettingsInterface ui )
|
||||||
{
|
=> _base = ui;
|
||||||
_base = ui;
|
|
||||||
_condition = ui._plugin!.PluginInterface!.ClientState.Condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Draw()
|
public void Draw()
|
||||||
{
|
{
|
||||||
if( _condition.Any() || _base._menu.Visible )
|
if( Dalamud.Conditions.Any() || _base._menu.Visible )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
|
@ -21,9 +21,9 @@ namespace Penumbra.UI
|
||||||
private string _collectionNames = null!;
|
private string _collectionNames = null!;
|
||||||
private string _collectionNamesWithNone = null!;
|
private string _collectionNamesWithNone = null!;
|
||||||
private ModCollection[] _collections = null!;
|
private ModCollection[] _collections = null!;
|
||||||
private int _currentCollectionIndex = 0;
|
private int _currentCollectionIndex;
|
||||||
private int _currentForcedIndex = 0;
|
private int _currentForcedIndex;
|
||||||
private int _currentDefaultIndex = 0;
|
private int _currentDefaultIndex;
|
||||||
private readonly Dictionary< string, int > _currentCharacterIndices = new();
|
private readonly Dictionary< string, int > _currentCharacterIndices = new();
|
||||||
private string _newCollectionName = string.Empty;
|
private string _newCollectionName = string.Empty;
|
||||||
private string _newCharacterName = string.Empty;
|
private string _newCharacterName = string.Empty;
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,9 @@ using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Dalamud.Game.ClientState.Actors.Types;
|
using Dalamud.Game.ClientState.Objects.Types;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Penumbra.Api;
|
|
||||||
using Penumbra.GameData.Enums;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Structs;
|
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
using Penumbra.Meta;
|
using Penumbra.Meta;
|
||||||
|
|
@ -20,96 +18,98 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
public partial class SettingsInterface
|
public partial class SettingsInterface
|
||||||
{
|
{
|
||||||
private void DrawDebugTabActors()
|
private static void DrawDebugTabPlayers()
|
||||||
{
|
{
|
||||||
if( !ImGui.CollapsingHeader( "Actors##Debug" ) )
|
if( !ImGui.CollapsingHeader( "Players##Debug" ) )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var actors = _plugin.PlayerWatcher.WatchedPlayers().ToArray();
|
var players = Penumbra.PlayerWatcher.WatchedPlayers().ToArray();
|
||||||
if( !actors.Any() )
|
if( !players.Any() )
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ImGui.BeginTable( "##ActorTable", 13, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX,
|
if( !ImGui.BeginTable( "##ObjectTable", 13, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX,
|
||||||
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 4 * actors.Length ) ) )
|
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 4 * players.Length ) ) )
|
||||||
{
|
{
|
||||||
var identifier = GameData.GameData.GetIdentifier( _plugin.PluginInterface );
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
foreach( var (actor, equip) in actors )
|
var identifier = GameData.GameData.GetIdentifier();
|
||||||
|
|
||||||
|
foreach( var (actor, equip) in players )
|
||||||
|
{
|
||||||
|
// @formatter:off
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( actor );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.MainHand}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.Head}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.Body}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.Hands}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.Legs}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.Feet}" );
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
if (equip.IsSet == 0)
|
||||||
{
|
{
|
||||||
// @formatter:off
|
ImGui.Text( "(not set)" );
|
||||||
ImGui.TableNextRow();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( actor );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.MainHand}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.Head}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.Body}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.Hands}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.Legs}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.Feet}" );
|
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
if (equip.IsSet == 0)
|
|
||||||
{
|
|
||||||
ImGui.Text( "(not set)" );
|
|
||||||
}
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.MainHand.Set, equip.MainHand.Type, equip.MainHand.Variant, EquipSlot.MainHand )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.Head.Set, 0, equip.Head.Variant, EquipSlot.Head )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.Body.Set, 0, equip.Body.Variant, EquipSlot.Body )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.Hands.Set, 0, equip.Hands.Variant, EquipSlot.Hands )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.Legs.Set, 0, equip.Legs.Variant, EquipSlot.Legs )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.Feet.Set, 0, equip.Feet.Variant, EquipSlot.Feet )?.Name.ToString() ?? "Unknown" );
|
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.OffHand}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.Ears}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.Neck}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.Wrists}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.LFinger}" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( $"{equip.RFinger}" );
|
|
||||||
|
|
||||||
ImGui.TableNextRow();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.OffHand.Set, equip.OffHand.Type, equip.OffHand.Variant, EquipSlot.OffHand )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.Ears.Set, 0, equip.Ears.Variant, EquipSlot.Ears )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.Neck.Set, 0, equip.Neck.Variant, EquipSlot.Neck )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.Wrists.Set, 0, equip.Wrists.Variant, EquipSlot.Wrists )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.LFinger.Set, 0, equip.LFinger.Variant, EquipSlot.LFinger )?.Name.ToString() ?? "Unknown" );
|
|
||||||
ImGui.TableNextColumn();
|
|
||||||
ImGui.Text( identifier.Identify( equip.RFinger.Set, 0, equip.RFinger.Variant, EquipSlot.LFinger )?.Name.ToString() ?? "Unknown" );
|
|
||||||
// @formatter:on
|
|
||||||
}
|
}
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.MainHand.Set, equip.MainHand.Type, equip.MainHand.Variant, EquipSlot.MainHand )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.Head.Set, 0, equip.Head.Variant, EquipSlot.Head )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.Body.Set, 0, equip.Body.Variant, EquipSlot.Body )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.Hands.Set, 0, equip.Hands.Variant, EquipSlot.Hands )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.Legs.Set, 0, equip.Legs.Variant, EquipSlot.Legs )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.Feet.Set, 0, equip.Feet.Variant, EquipSlot.Feet )?.Name.ToString() ?? "Unknown" );
|
||||||
|
|
||||||
ImGui.EndTable();
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.OffHand}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.Ears}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.Neck}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.Wrists}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.LFinger}" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( $"{equip.RFinger}" );
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.OffHand.Set, equip.OffHand.Type, equip.OffHand.Variant, EquipSlot.OffHand )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.Ears.Set, 0, equip.Ears.Variant, EquipSlot.Ears )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.Neck.Set, 0, equip.Neck.Variant, EquipSlot.Neck )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.Wrists.Set, 0, equip.Wrists.Variant, EquipSlot.Wrists )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.LFinger.Set, 0, equip.LFinger.Variant, EquipSlot.LFinger )?.Name.ToString() ?? "Unknown" );
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.Text( identifier.Identify( equip.RFinger.Set, 0, equip.RFinger.Variant, EquipSlot.LFinger )?.Name.ToString() ?? "Unknown" );
|
||||||
|
// @formatter:on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void PrintValue( string name, string value )
|
private static void PrintValue( string name, string value )
|
||||||
|
|
@ -121,7 +121,7 @@ namespace Penumbra.UI
|
||||||
ImGui.Text( value );
|
ImGui.Text( value );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawDebugTabGeneral()
|
private static void DrawDebugTabGeneral()
|
||||||
{
|
{
|
||||||
if( !ImGui.CollapsingHeader( "General##Debug" ) )
|
if( !ImGui.CollapsingHeader( "General##Debug" ) )
|
||||||
{
|
{
|
||||||
|
|
@ -138,12 +138,12 @@ namespace Penumbra.UI
|
||||||
PrintValue( "Active Collection", manager.Collections.ActiveCollection.Name );
|
PrintValue( "Active Collection", manager.Collections.ActiveCollection.Name );
|
||||||
PrintValue( "Mod Manager BasePath", manager.BasePath.Name );
|
PrintValue( "Mod Manager BasePath", manager.BasePath.Name );
|
||||||
PrintValue( "Mod Manager BasePath-Full", manager.BasePath.FullName );
|
PrintValue( "Mod Manager BasePath-Full", manager.BasePath.FullName );
|
||||||
PrintValue( "Mod Manager BasePath IsRooted", Path.IsPathRooted( _plugin.Configuration.ModDirectory ).ToString() );
|
PrintValue( "Mod Manager BasePath IsRooted", Path.IsPathRooted( Penumbra.Config.ModDirectory ).ToString() );
|
||||||
PrintValue( "Mod Manager BasePath Exists", Directory.Exists( manager.BasePath.FullName ).ToString() );
|
PrintValue( "Mod Manager BasePath Exists", Directory.Exists( manager.BasePath.FullName ).ToString() );
|
||||||
PrintValue( "Mod Manager Valid", manager.Valid.ToString() );
|
PrintValue( "Mod Manager Valid", manager.Valid.ToString() );
|
||||||
PrintValue( "Mod Manager Temp Path", manager.TempPath.FullName );
|
PrintValue( "Mod Manager Temp Path", manager.TempPath.FullName );
|
||||||
PrintValue( "Mod Manager Temp Path IsRooted",
|
PrintValue( "Mod Manager Temp Path IsRooted",
|
||||||
( !_plugin.Configuration.TempDirectory.Any() || Path.IsPathRooted( _plugin.Configuration.TempDirectory ) ).ToString() );
|
( !Penumbra.Config.TempDirectory.Any() || Path.IsPathRooted( Penumbra.Config.TempDirectory ) ).ToString() );
|
||||||
PrintValue( "Mod Manager Temp Path Exists", Directory.Exists( manager.TempPath.FullName ).ToString() );
|
PrintValue( "Mod Manager Temp Path Exists", Directory.Exists( manager.TempPath.FullName ).ToString() );
|
||||||
PrintValue( "Mod Manager Temp Path IsWritable", manager.TempWritable.ToString() );
|
PrintValue( "Mod Manager Temp Path IsWritable", manager.TempWritable.ToString() );
|
||||||
|
|
||||||
|
|
@ -157,70 +157,70 @@ namespace Penumbra.UI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var queue = ( Queue< (int, string, RedrawType) >? )_plugin.ActorRefresher.GetType()
|
var queue = ( Queue< (int, string, RedrawType) >? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_actorIds", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_objectIds", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher )
|
?.GetValue( _penumbra.ObjectReloader )
|
||||||
?? new Queue< (int, string, RedrawType) >();
|
?? new Queue< (int, string, RedrawType) >();
|
||||||
|
|
||||||
var currentFrame = ( int? )_plugin.ActorRefresher.GetType()
|
var currentFrame = ( int? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
var changedSettings = ( bool? )_plugin.ActorRefresher.GetType()
|
var changedSettings = ( bool? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_changedSettings", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_changedSettings", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
var currentActorId = ( int? )_plugin.ActorRefresher.GetType()
|
var currentObjectId = ( int? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_currentActorId", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_currentObjectId", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
var currentActorName = ( string? )_plugin.ActorRefresher.GetType()
|
var currentObjectName = ( string? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_currentActorName", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_currentObjectName", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
var currentActorStartState = ( ActorRefresher.LoadingFlags? )_plugin.ActorRefresher.GetType()
|
var currentObjectStartState = ( ObjectReloader.LoadingFlags? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_currentActorStartState", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_currentObjectStartState", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
var currentActorRedraw = ( RedrawType? )_plugin.ActorRefresher.GetType()
|
var currentRedrawType = ( RedrawType? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_currentActorRedraw", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_currentRedrawType", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
var (currentActor, currentActorIdx) = ( (Actor?, int) )_plugin.ActorRefresher.GetType()
|
var (currentObject, currentObjectIdx) = ( (GameObject?, int) )_penumbra.ObjectReloader.GetType()
|
||||||
.GetMethod( "FindCurrentActor", BindingFlags.NonPublic | BindingFlags.Instance )?
|
.GetMethod( "FindCurrentObject", BindingFlags.NonPublic | BindingFlags.Instance )?
|
||||||
.Invoke( _plugin.ActorRefresher, Array.Empty< object >() )!;
|
.Invoke( _penumbra.ObjectReloader, Array.Empty< object >() )!;
|
||||||
|
|
||||||
var currentRender = currentActor != null
|
var currentRender = currentObject != null
|
||||||
? ( ActorRefresher.LoadingFlags? )Marshal.ReadInt32( ActorRefresher.RenderPtr( currentActor ) )
|
? ( ObjectReloader.LoadingFlags? )Marshal.ReadInt32( ObjectReloader.RenderPtr( currentObject ) )
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
var waitFrames = ( int? )_plugin.ActorRefresher.GetType()
|
var waitFrames = ( int? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_waitFrames", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_waitFrames", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
var wasTarget = ( bool? )_plugin.ActorRefresher.GetType()
|
var wasTarget = ( bool? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_wasTarget", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_wasTarget", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
var gPose = ( bool? )_plugin.ActorRefresher.GetType()
|
var gPose = ( bool? )_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_inGPose", BindingFlags.Instance | BindingFlags.NonPublic )
|
.GetField( "_inGPose", BindingFlags.Instance | BindingFlags.NonPublic )
|
||||||
?.GetValue( _plugin.ActorRefresher );
|
?.GetValue( _penumbra.ObjectReloader );
|
||||||
|
|
||||||
if( ImGui.BeginTable( "##RedrawData", 2, ImGuiTableFlags.SizingFixedFit,
|
if( ImGui.BeginTable( "##RedrawData", 2, ImGuiTableFlags.SizingFixedFit,
|
||||||
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 7 ) ) )
|
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * 7 ) ) )
|
||||||
{
|
{
|
||||||
PrintValue( "Current Wait Frame", waitFrames?.ToString() ?? "null" );
|
PrintValue( "Current Wait Frame", waitFrames?.ToString() ?? "null" );
|
||||||
PrintValue( "Current Frame", currentFrame?.ToString() ?? "null" );
|
PrintValue( "Current Frame", currentFrame?.ToString() ?? "null" );
|
||||||
PrintValue( "Currently in GPose", gPose?.ToString() ?? "null" );
|
PrintValue( "Currently in GPose", gPose?.ToString() ?? "null" );
|
||||||
PrintValue( "Current Changed Settings", changedSettings?.ToString() ?? "null" );
|
PrintValue( "Current Changed Settings", changedSettings?.ToString() ?? "null" );
|
||||||
PrintValue( "Current Actor Id", currentActorId?.ToString( "X8" ) ?? "null" );
|
PrintValue( "Current Object Id", currentObjectId?.ToString( "X8" ) ?? "null" );
|
||||||
PrintValue( "Current Actor Name", currentActorName ?? "null" );
|
PrintValue( "Current Object Name", currentObjectName ?? "null" );
|
||||||
PrintValue( "Current Actor Start State", ( ( int? )currentActorStartState )?.ToString( "X8" ) ?? "null" );
|
PrintValue( "Current Object Start State", ( ( int? )currentObjectStartState )?.ToString( "X8" ) ?? "null" );
|
||||||
PrintValue( "Current Actor Was Target", wasTarget?.ToString() ?? "null" );
|
PrintValue( "Current Object Was Target", wasTarget?.ToString() ?? "null" );
|
||||||
PrintValue( "Current Actor Redraw", currentActorRedraw?.ToString() ?? "null" );
|
PrintValue( "Current Object Redraw", currentRedrawType?.ToString() ?? "null" );
|
||||||
PrintValue( "Current Actor Address", currentActor?.Address.ToString( "X16" ) ?? "null" );
|
PrintValue( "Current Object Address", currentObject?.Address.ToString( "X16" ) ?? "null" );
|
||||||
PrintValue( "Current Actor Index", currentActorIdx >= 0 ? currentActorIdx.ToString() : "null" );
|
PrintValue( "Current Object Index", currentObjectIdx >= 0 ? currentObjectIdx.ToString() : "null" );
|
||||||
PrintValue( "Current Actor Render Flags", ( ( int? )currentRender )?.ToString( "X8" ) ?? "null" );
|
PrintValue( "Current Object Render Flags", ( ( int? )currentRender )?.ToString( "X8" ) ?? "null" );
|
||||||
ImGui.EndTable();
|
ImGui.EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,13 +228,13 @@ namespace Penumbra.UI
|
||||||
&& ImGui.BeginTable( "##RedrawTable", 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX,
|
&& ImGui.BeginTable( "##RedrawTable", 3, ImGuiTableFlags.SizingFixedFit | ImGuiTableFlags.ScrollX,
|
||||||
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * queue.Count ) ) )
|
new Vector2( -1, ImGui.GetTextLineHeightWithSpacing() * queue.Count ) ) )
|
||||||
{
|
{
|
||||||
foreach( var (actorId, actorName, redraw) in queue )
|
foreach( var (objectId, objectName, redraw) in queue )
|
||||||
{
|
{
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( actorName );
|
ImGui.Text( objectName );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( $"0x{actorId:X8}" );
|
ImGui.Text( $"0x{objectId:X8}" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( redraw.ToString() );
|
ImGui.Text( redraw.ToString() );
|
||||||
}
|
}
|
||||||
|
|
@ -245,12 +245,12 @@ namespace Penumbra.UI
|
||||||
if( queue.Any() && ImGui.Button( "Clear" ) )
|
if( queue.Any() && ImGui.Button( "Clear" ) )
|
||||||
{
|
{
|
||||||
queue.Clear();
|
queue.Clear();
|
||||||
_plugin.ActorRefresher.GetType()
|
_penumbra.ObjectReloader.GetType()
|
||||||
.GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic )?.SetValue( _plugin.ActorRefresher, 0 );
|
.GetField( "_currentFrame", BindingFlags.Instance | BindingFlags.NonPublic )?.SetValue( _penumbra.ObjectReloader, 0 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawDebugTabTempFiles()
|
private static void DrawDebugTabTempFiles()
|
||||||
{
|
{
|
||||||
if( !ImGui.CollapsingHeader( "Temporary Files##Debug" ) )
|
if( !ImGui.CollapsingHeader( "Temporary Files##Debug" ) )
|
||||||
{
|
{
|
||||||
|
|
@ -270,18 +270,18 @@ namespace Penumbra.UI
|
||||||
?? new Dictionary< GamePath, MetaManager.FileInformation >();
|
?? new Dictionary< GamePath, MetaManager.FileInformation >();
|
||||||
|
|
||||||
|
|
||||||
foreach( var file in files )
|
foreach( var (file, info) in files )
|
||||||
{
|
{
|
||||||
ImGui.TableNextRow();
|
ImGui.TableNextRow();
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( file.Value.CurrentFile?.FullName ?? "None" );
|
ImGui.Text( info.CurrentFile?.FullName ?? "None" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( file.Key );
|
ImGui.Text( file );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
file.Value.CurrentFile?.Refresh();
|
info.CurrentFile?.Refresh();
|
||||||
ImGui.Text( file.Value.CurrentFile?.Exists ?? false ? "Exists" : "Missing" );
|
ImGui.Text( info.CurrentFile?.Exists ?? false ? "Exists" : "Missing" );
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
ImGui.Text( file.Value.Changed ? "Data Changed" : "Unchanged" );
|
ImGui.Text( info.Changed ? "Data Changed" : "Unchanged" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -299,7 +299,7 @@ namespace Penumbra.UI
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
DrawDebugTabRedraw();
|
DrawDebugTabRedraw();
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
DrawDebugTabActors();
|
DrawDebugTabPlayers();
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
DrawDebugTabTempFiles();
|
DrawDebugTabTempFiles();
|
||||||
ImGui.NewLine();
|
ImGui.NewLine();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Penumbra.Importer;
|
using Penumbra.Importer;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
|
||||||
namespace Penumbra.UI
|
namespace Penumbra.UI
|
||||||
|
|
@ -18,12 +18,12 @@ namespace Penumbra.UI
|
||||||
private readonly List< (bool visible, uint color) > _visibleMods = new();
|
private readonly List< (bool visible, uint color) > _visibleMods = new();
|
||||||
private readonly Dictionary< ModFolder, (bool visible, bool enabled) > _visibleFolders = new();
|
private readonly Dictionary< ModFolder, (bool visible, bool enabled) > _visibleFolders = new();
|
||||||
|
|
||||||
private string _modFilter = "";
|
private string _modFilter = string.Empty;
|
||||||
private string _modFilterChanges = "";
|
private string _modFilterChanges = string.Empty;
|
||||||
private string _modFilterAuthor = "";
|
private string _modFilterAuthor = string.Empty;
|
||||||
private ModFilter _stateFilter = ModFilterExtensions.UnfilteredStateMods;
|
private ModFilter _stateFilter = ModFilterExtensions.UnfilteredStateMods;
|
||||||
private bool _listResetNecessary = false;
|
private bool _listResetNecessary;
|
||||||
private bool _filterResetNecessary = false;
|
private bool _filterResetNecessary;
|
||||||
|
|
||||||
|
|
||||||
public ModFilter StateFilter
|
public ModFilter StateFilter
|
||||||
|
|
@ -167,6 +167,7 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
_visibleMods.Add( CheckFilters( mod ) );
|
_visibleMods.Add( CheckFilters( mod ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
_filterResetNecessary = false;
|
_filterResetNecessary = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using System.Linq;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Penumbra.Api;
|
using Penumbra.Api;
|
||||||
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.GameData.Util;
|
using Penumbra.GameData.Util;
|
||||||
using Penumbra.Meta;
|
using Penumbra.Meta;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
|
|
@ -124,7 +125,7 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
private void Save()
|
private void Save()
|
||||||
{
|
{
|
||||||
_modManager.Collections.CurrentCollection.Save( _base._plugin.PluginInterface! );
|
_modManager.Collections.CurrentCollection.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawAboutTab()
|
private void DrawAboutTab()
|
||||||
|
|
@ -183,13 +184,13 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
if( ret != MouseButton.None )
|
if( ret != MouseButton.None )
|
||||||
{
|
{
|
||||||
_base._plugin.Api.InvokeClick( ret, item.Value );
|
_base._penumbra.Api.InvokeClick( ret, item.Value );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _base._plugin.Api.HasTooltip && ImGui.IsItemHovered() )
|
if( _base._penumbra.Api.HasTooltip && ImGui.IsItemHovered() )
|
||||||
{
|
{
|
||||||
ImGui.BeginTooltip();
|
ImGui.BeginTooltip();
|
||||||
_base._plugin.Api.InvokeTooltip( item.Value );
|
_base._penumbra.Api.InvokeTooltip( item.Value );
|
||||||
ImGui.EndTooltip();
|
ImGui.EndTooltip();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
|
|
@ -523,7 +523,7 @@ namespace Penumbra.UI
|
||||||
DrawEnabledMark();
|
DrawEnabledMark();
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
DrawPriority();
|
DrawPriority();
|
||||||
if( _base._plugin!.Configuration!.ShowAdvanced )
|
if( Penumbra.Config.ShowAdvanced )
|
||||||
{
|
{
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
DrawEditableMark();
|
DrawEditableMark();
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,10 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Dalamud.Interface;
|
using Dalamud.Interface;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Penumbra.Importer;
|
using Penumbra.Importer;
|
||||||
using Penumbra.Mod;
|
using Penumbra.Mod;
|
||||||
|
|
@ -155,7 +154,7 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var newDir = TexToolsImport.CreateModFolder( new DirectoryInfo( _base._plugin.Configuration!.ModDirectory ),
|
var newDir = TexToolsImport.CreateModFolder( new DirectoryInfo( Penumbra.Config!.ModDirectory ),
|
||||||
newName );
|
newName );
|
||||||
var modMeta = new ModMeta
|
var modMeta = new ModMeta
|
||||||
{
|
{
|
||||||
|
|
@ -377,7 +376,7 @@ namespace Penumbra.UI
|
||||||
var folderName = Marshal.PtrToStringUni( payload.Data );
|
var folderName = Marshal.PtrToStringUni( payload.Data );
|
||||||
if( ModFileSystem.Find( folderName!, out var droppedFolder )
|
if( ModFileSystem.Find( folderName!, out var droppedFolder )
|
||||||
&& !ReferenceEquals( droppedFolder, folder )
|
&& !ReferenceEquals( droppedFolder, folder )
|
||||||
&& !folder.FullName.StartsWith( folderName, StringComparison.InvariantCultureIgnoreCase ) )
|
&& !folder.FullName.StartsWith( folderName!, StringComparison.InvariantCultureIgnoreCase ) )
|
||||||
{
|
{
|
||||||
droppedFolder.Move( folder );
|
droppedFolder.Move( folder );
|
||||||
}
|
}
|
||||||
|
|
@ -541,7 +540,7 @@ namespace Penumbra.UI
|
||||||
collection == _modManager.Collections.ActiveCollection );
|
collection == _modManager.Collections.ActiveCollection );
|
||||||
}
|
}
|
||||||
|
|
||||||
collection.Save( _base._plugin.PluginInterface );
|
collection.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DrawRenameFolderInput( ModFolder folder )
|
private void DrawRenameFolderInput( ModFolder folder )
|
||||||
|
|
@ -657,7 +656,7 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
if( item is ModFolder sub )
|
if( item is ModFolder sub )
|
||||||
{
|
{
|
||||||
var (visible, enabled) = Cache.GetFolder( sub );
|
var (visible, _) = Cache.GetFolder( sub );
|
||||||
if( visible )
|
if( visible )
|
||||||
{
|
{
|
||||||
DrawModFolder( sub, ref idx );
|
DrawModFolder( sub, ref idx );
|
||||||
|
|
@ -757,7 +756,7 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_selectorScalingFactor = _base._plugin.Configuration.ScaleModSelector
|
_selectorScalingFactor = Penumbra.Config.ScaleModSelector
|
||||||
? ImGui.GetWindowWidth() / SettingsMenu.MinSettingsSize.X
|
? ImGui.GetWindowWidth() / SettingsMenu.MinSettingsSize.X
|
||||||
: 1f;
|
: 1f;
|
||||||
// Selector pane
|
// Selector pane
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,9 @@ using System;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
using Dalamud.Plugin;
|
using Dalamud.Logging;
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
using Penumbra.Api;
|
using Penumbra.GameData.Enums;
|
||||||
using Penumbra.Interop;
|
using Penumbra.Interop;
|
||||||
using Penumbra.Mods;
|
using Penumbra.Mods;
|
||||||
using Penumbra.Util;
|
using Penumbra.Util;
|
||||||
|
|
@ -39,7 +39,7 @@ namespace Penumbra.UI
|
||||||
public TabSettings( SettingsInterface ui )
|
public TabSettings( SettingsInterface ui )
|
||||||
{
|
{
|
||||||
_base = ui;
|
_base = ui;
|
||||||
_config = _base._plugin.Configuration!;
|
_config = Penumbra.Config;
|
||||||
_configChanged = false;
|
_configChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -115,10 +115,10 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
_config.IsEnabled = enabled;
|
_config.IsEnabled = enabled;
|
||||||
_configChanged = true;
|
_configChanged = true;
|
||||||
_base._plugin.ActorRefresher.RedrawAll( enabled ? RedrawType.WithSettings : RedrawType.WithoutSettings );
|
_base._penumbra.ObjectReloader.RedrawAll( enabled ? RedrawType.WithSettings : RedrawType.WithoutSettings );
|
||||||
if( _config.EnableActorWatch )
|
if( _config.EnablePlayerWatch )
|
||||||
{
|
{
|
||||||
_base._plugin.PlayerWatcher.SetStatus( enabled );
|
Penumbra.PlayerWatcher.SetStatus( enabled );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,16 +156,16 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
private void DrawLogLoadedFilesBox()
|
private void DrawLogLoadedFilesBox()
|
||||||
{
|
{
|
||||||
ImGui.Checkbox( LabelLogLoadedFiles, ref _base._plugin.ResourceLoader.LogAllFiles );
|
ImGui.Checkbox( LabelLogLoadedFiles, ref _base._penumbra.ResourceLoader.LogAllFiles );
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
var regex = _base._plugin.ResourceLoader.LogFileFilter?.ToString() ?? string.Empty;
|
var regex = _base._penumbra.ResourceLoader.LogFileFilter?.ToString() ?? string.Empty;
|
||||||
var tmp = regex;
|
var tmp = regex;
|
||||||
if( ImGui.InputTextWithHint( "##LogFilter", "Matching this Regex...", ref tmp, 64 ) && tmp != regex )
|
if( ImGui.InputTextWithHint( "##LogFilter", "Matching this Regex...", ref tmp, 64 ) && tmp != regex )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var newRegex = tmp.Length > 0 ? new Regex( tmp, RegexOptions.Compiled ) : null;
|
var newRegex = tmp.Length > 0 ? new Regex( tmp, RegexOptions.Compiled ) : null;
|
||||||
_base._plugin.ResourceLoader.LogFileFilter = newRegex;
|
_base._penumbra.ResourceLoader.LogFileFilter = newRegex;
|
||||||
}
|
}
|
||||||
catch( Exception e )
|
catch( Exception e )
|
||||||
{
|
{
|
||||||
|
|
@ -191,11 +191,11 @@ namespace Penumbra.UI
|
||||||
{
|
{
|
||||||
if( http )
|
if( http )
|
||||||
{
|
{
|
||||||
_base._plugin.CreateWebServer();
|
_base._penumbra.CreateWebServer();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_base._plugin.ShutdownWebServer();
|
_base._penumbra.ShutdownWebServer();
|
||||||
}
|
}
|
||||||
|
|
||||||
_config.EnableHttpApi = http;
|
_config.EnableHttpApi = http;
|
||||||
|
|
@ -205,12 +205,12 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
private void DrawEnabledPlayerWatcher()
|
private void DrawEnabledPlayerWatcher()
|
||||||
{
|
{
|
||||||
var enabled = _config.EnableActorWatch;
|
var enabled = _config.EnablePlayerWatch;
|
||||||
if( ImGui.Checkbox( LabelEnabledPlayerWatch, ref enabled ) )
|
if( ImGui.Checkbox( LabelEnabledPlayerWatch, ref enabled ) )
|
||||||
{
|
{
|
||||||
_config.EnableActorWatch = enabled;
|
_config.EnablePlayerWatch = enabled;
|
||||||
_configChanged = true;
|
_configChanged = true;
|
||||||
_base._plugin.PlayerWatcher.SetStatus( enabled );
|
Penumbra.PlayerWatcher.SetStatus( enabled );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ImGui.IsItemHovered() )
|
if( ImGui.IsItemHovered() )
|
||||||
|
|
@ -220,7 +220,7 @@ namespace Penumbra.UI
|
||||||
+ "Penumbra will try to automatically redraw those characters using their collection when they first appear in an instance, or when they change their current equip." );
|
+ "Penumbra will try to automatically redraw those characters using their collection when they first appear in an instance, or when they change their current equip." );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( _config.EnableActorWatch && _config.ShowAdvanced )
|
if( _config.EnablePlayerWatch && _config.ShowAdvanced )
|
||||||
{
|
{
|
||||||
var waitFrames = _config.WaitFrames;
|
var waitFrames = _config.WaitFrames;
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
@ -230,9 +230,9 @@ namespace Penumbra.UI
|
||||||
&& waitFrames > 0
|
&& waitFrames > 0
|
||||||
&& waitFrames < 3000 )
|
&& waitFrames < 3000 )
|
||||||
{
|
{
|
||||||
_base._plugin.ActorRefresher.DefaultWaitFrames = waitFrames;
|
_base._penumbra.ObjectReloader.DefaultWaitFrames = waitFrames;
|
||||||
_config.WaitFrames = waitFrames;
|
_config.WaitFrames = waitFrames;
|
||||||
_configChanged = true;
|
_configChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ImGui.IsItemHovered() )
|
if( ImGui.IsItemHovered() )
|
||||||
|
|
|
||||||
|
|
@ -12,34 +12,34 @@ namespace Penumbra.UI
|
||||||
private static readonly Vector2 AutoFillSize = new( -1, -1 );
|
private static readonly Vector2 AutoFillSize = new( -1, -1 );
|
||||||
private static readonly Vector2 ZeroVector = new( 0, 0 );
|
private static readonly Vector2 ZeroVector = new( 0, 0 );
|
||||||
|
|
||||||
private readonly Plugin _plugin;
|
private readonly Penumbra _penumbra;
|
||||||
|
|
||||||
private readonly ManageModsButton _manageModsButton;
|
private readonly ManageModsButton _manageModsButton;
|
||||||
private readonly MenuBar _menuBar;
|
private readonly MenuBar _menuBar;
|
||||||
private readonly SettingsMenu _menu;
|
private readonly SettingsMenu _menu;
|
||||||
private readonly ModManager _modManager;
|
private readonly ModManager _modManager;
|
||||||
|
|
||||||
public SettingsInterface( Plugin plugin )
|
public SettingsInterface( Penumbra penumbra )
|
||||||
{
|
{
|
||||||
_plugin = plugin;
|
_penumbra = penumbra;
|
||||||
_manageModsButton = new ManageModsButton( this );
|
_manageModsButton = new ManageModsButton( this );
|
||||||
_menuBar = new MenuBar( this );
|
_menuBar = new MenuBar( this );
|
||||||
_menu = new SettingsMenu( this );
|
_menu = new SettingsMenu( this );
|
||||||
_modManager = Service< ModManager >.Get();
|
_modManager = Service< ModManager >.Get();
|
||||||
|
|
||||||
_plugin.PluginInterface.UiBuilder.DisableGposeUiHide = true;
|
Dalamud.PluginInterface.UiBuilder.DisableGposeUiHide = true;
|
||||||
_plugin.PluginInterface.UiBuilder.OnBuildUi += Draw;
|
Dalamud.PluginInterface.UiBuilder.Draw += Draw;
|
||||||
_plugin.PluginInterface.UiBuilder.OnOpenConfigUi += OpenConfig;
|
Dalamud.PluginInterface.UiBuilder.OpenConfigUi += OpenConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_menu.InstalledTab.Selector.Cache.Dispose();
|
_menu.InstalledTab.Selector.Cache.Dispose();
|
||||||
_plugin.PluginInterface.UiBuilder.OnBuildUi -= Draw;
|
Dalamud.PluginInterface.UiBuilder.Draw -= Draw;
|
||||||
_plugin.PluginInterface.UiBuilder.OnOpenConfigUi -= OpenConfig;
|
Dalamud.PluginInterface.UiBuilder.OpenConfigUi -= OpenConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenConfig( object _1, EventArgs _2 )
|
private void OpenConfig()
|
||||||
=> _menu.Visible = true;
|
=> _menu.Visible = true;
|
||||||
|
|
||||||
public void FlipVisibility()
|
public void FlipVisibility()
|
||||||
|
|
@ -58,14 +58,14 @@ namespace Penumbra.UI
|
||||||
private void ReloadMods()
|
private void ReloadMods()
|
||||||
{
|
{
|
||||||
_menu.InstalledTab.Selector.ClearSelection();
|
_menu.InstalledTab.Selector.ClearSelection();
|
||||||
_modManager.DiscoverMods( _plugin.Configuration.ModDirectory );
|
_modManager.DiscoverMods( Penumbra.Config.ModDirectory );
|
||||||
_menu.InstalledTab.Selector.Cache.TriggerListReset();
|
_menu.InstalledTab.Selector.Cache.TriggerListReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveCurrentCollection( bool recalculateMeta )
|
private void SaveCurrentCollection( bool recalculateMeta )
|
||||||
{
|
{
|
||||||
var current = _modManager.Collections.CurrentCollection;
|
var current = _modManager.Collections.CurrentCollection;
|
||||||
current.Save( _plugin.PluginInterface );
|
current.Save();
|
||||||
RecalculateCurrent( recalculateMeta );
|
RecalculateCurrent( recalculateMeta );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,12 +50,13 @@ namespace Penumbra.UI
|
||||||
|
|
||||||
ImGui.SetNextWindowSizeConstraints( MinSettingsSize, MaxSettingsSize );
|
ImGui.SetNextWindowSizeConstraints( MinSettingsSize, MaxSettingsSize );
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
var ret = ImGui.Begin( _base._plugin.PluginDebugTitleStr, ref Visible );
|
var ret = ImGui.Begin( _base._penumbra.PluginDebugTitleStr, ref Visible );
|
||||||
#else
|
#else
|
||||||
var ret = ImGui.Begin( _base._plugin.Name, ref Visible );
|
var ret = ImGui.Begin( _base._plugin.Name, ref Visible );
|
||||||
#endif
|
#endif
|
||||||
if( !ret )
|
if( !ret )
|
||||||
{
|
{
|
||||||
|
ImGui.End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,7 +71,7 @@ namespace Penumbra.UI
|
||||||
_browserTab.Draw();
|
_browserTab.Draw();
|
||||||
InstalledTab.Draw();
|
InstalledTab.Draw();
|
||||||
|
|
||||||
if( _base._plugin!.Configuration!.ShowAdvanced )
|
if( Penumbra.Config.ShowAdvanced )
|
||||||
{
|
{
|
||||||
_effectiveTab.Draw();
|
_effectiveTab.Draw();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,22 +9,18 @@ namespace Penumbra.Util
|
||||||
{
|
{
|
||||||
public static class ChatUtil
|
public static class ChatUtil
|
||||||
{
|
{
|
||||||
private static DalamudPluginInterface? _pi;
|
|
||||||
|
|
||||||
public static void LinkItem( Item item )
|
public static void LinkItem( Item item )
|
||||||
{
|
{
|
||||||
_pi ??= Service< DalamudPluginInterface >.Get();
|
|
||||||
|
|
||||||
var payloadList = new List< Payload >
|
var payloadList = new List< Payload >
|
||||||
{
|
{
|
||||||
new UIForegroundPayload( _pi.Data, ( ushort )( 0x223 + item.Rarity * 2 ) ),
|
new UIForegroundPayload( ( ushort )( 0x223 + item.Rarity * 2 ) ),
|
||||||
new UIGlowPayload( _pi.Data, ( ushort )( 0x224 + item.Rarity * 2 ) ),
|
new UIGlowPayload( ( ushort )( 0x224 + item.Rarity * 2 ) ),
|
||||||
new ItemPayload( _pi.Data, item.RowId, false ),
|
new ItemPayload( item.RowId, false ),
|
||||||
new UIForegroundPayload( _pi.Data, 500 ),
|
new UIForegroundPayload( 500 ),
|
||||||
new UIGlowPayload( _pi.Data, 501 ),
|
new UIGlowPayload( 501 ),
|
||||||
new TextPayload( $"{( char )SeIconChar.LinkMarker}" ),
|
new TextPayload( $"{( char )SeIconChar.LinkMarker}" ),
|
||||||
new UIForegroundPayload( _pi.Data, 0 ),
|
new UIForegroundPayload( 0 ),
|
||||||
new UIGlowPayload( _pi.Data, 0 ),
|
new UIGlowPayload( 0 ),
|
||||||
new TextPayload( item.Name ),
|
new TextPayload( item.Name ),
|
||||||
new RawPayload( new byte[] { 0x02, 0x27, 0x07, 0xCF, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x03 } ),
|
new RawPayload( new byte[] { 0x02, 0x27, 0x07, 0xCF, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x03 } ),
|
||||||
new RawPayload( new byte[] { 0x02, 0x13, 0x02, 0xEC, 0x03 } ),
|
new RawPayload( new byte[] { 0x02, 0x13, 0x02, 0xEC, 0x03 } ),
|
||||||
|
|
@ -32,9 +28,9 @@ namespace Penumbra.Util
|
||||||
|
|
||||||
var payload = new SeString( payloadList );
|
var payload = new SeString( payloadList );
|
||||||
|
|
||||||
_pi.Framework.Gui.Chat.PrintChat( new XivChatEntry
|
Dalamud.Chat.PrintChat( new XivChatEntry
|
||||||
{
|
{
|
||||||
MessageBytes = payload.Encode(),
|
Message = payload,
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ namespace Penumbra.Util
|
||||||
Shown += HiddenForm_Shown;
|
Shown += HiddenForm_Shown;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HiddenForm_Shown( object sender, EventArgs _ )
|
private void HiddenForm_Shown( object? sender, EventArgs _ )
|
||||||
{
|
{
|
||||||
Hide();
|
Hide();
|
||||||
try
|
try
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ namespace Penumbra.Util
|
||||||
public bool Empty
|
public bool Empty
|
||||||
=> _path.Length == 0;
|
=> _path.Length == 0;
|
||||||
|
|
||||||
public int CompareTo( object rhs )
|
public int CompareTo( object? rhs )
|
||||||
{
|
{
|
||||||
return rhs switch
|
return rhs switch
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,6 @@ namespace Penumbra.Util
|
||||||
{
|
{
|
||||||
private static T? _object;
|
private static T? _object;
|
||||||
|
|
||||||
static Service()
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public static void Set( T obj )
|
public static void Set( T obj )
|
||||||
{
|
{
|
||||||
// ReSharper disable once JoinNullCheckWithUsage
|
// ReSharper disable once JoinNullCheckWithUsage
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue