Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion Penumbra.CrashHandler/Buffers/AnimationInvocationBuffer.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Text.Json.Nodes;

Expand All @@ -9,6 +9,7 @@ public enum AnimationInvocationType : int
{
PapLoad,
ActionLoad,
GetClipResources,
ScheduleClipUpdate,
LoadTimelineResources,
LoadCharacterVfx,
Expand Down Expand Up @@ -111,6 +112,7 @@ private static string ToName(AnimationInvocationType type)
{
AnimationInvocationType.PapLoad => "PAP Load",
AnimationInvocationType.ActionLoad => "Action Load",
AnimationInvocationType.GetClipResources => "Get Clip Resources",
AnimationInvocationType.ScheduleClipUpdate => "Schedule Clip Update",
AnimationInvocationType.LoadTimelineResources => "Load Timeline Resources",
AnimationInvocationType.LoadCharacterVfx => "Load Character VFX",
Expand Down
2 changes: 1 addition & 1 deletion Penumbra.GameData
8 changes: 1 addition & 7 deletions Penumbra/Api/ModAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,5 @@ private Mod Mod
}

public void Dispose()
{
_mod.SetTarget(null!);
GC.SuppressFinalize(this);
}

~ModAdapter()
=> Dispose();
=> _mod.SetTarget(null!);
}
26 changes: 0 additions & 26 deletions Penumbra/CommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ private void OnCommand(string command, string arguments)
"toggle" => SetPenumbraState(arguments, null),
"reload" => Reload(arguments),
"redraw" => Redraw(arguments),
"lockui" => SetUiLockState(arguments),
"size" => SetUiMinimumSize(arguments),
"debug" => SetDebug(arguments),
"collection" => SetCollection(arguments),
Expand Down Expand Up @@ -112,9 +111,6 @@ private bool PrintHelp(string arguments)
_chat.Print(new SeStringBuilder().AddCommand("reload", "Rediscover the mod directory and reload all mods.").BuiltString);
_chat.Print(new SeStringBuilder()
.AddCommand("redraw", "Redraw all game objects. Specify a placeholder or a name to redraw specific objects.").BuiltString);
_chat.Print(new SeStringBuilder()
.AddCommand("lockui", "Toggle the locked state of the main Penumbra window. Can be used with [on|off] to force specific state.")
.BuiltString);
_chat.Print(new SeStringBuilder().AddCommand("size", "Reset the minimum config window size to its default values.").BuiltString);
_chat.Print(new SeStringBuilder()
.AddCommand("debug", "Toggle debug mode for Penumbra. Can be used with [on|off] to force specific state.").BuiltString);
Expand Down Expand Up @@ -202,28 +198,6 @@ private bool SetPenumbraState(string _, bool? newValue)
return _penumbra.SetEnabled(value);
}

private bool SetUiLockState(string arguments)
{
var value = ParseTrueFalseToggle(arguments) ?? !_config.Ephemeral.FixMainWindow;
if (value == _config.Ephemeral.FixMainWindow)
return false;

if (value)
{
Print("Penumbra UI locked in place.");
_mainWindow.Flags |= WindowFlags.NoMove | WindowFlags.NoResize;
}
else
{
Print("Penumbra UI unlocked.");
_mainWindow.Flags &= ~(WindowFlags.NoMove | WindowFlags.NoResize);
}

_config.Ephemeral.FixMainWindow = value;
_config.Ephemeral.Save();
return true;
}

private bool SetUiMinimumSize(string _)
{
if (_config.MinimumSize.X == Configuration.Constants.MinimumSizeX && _config.MinimumSize.Y == Configuration.Constants.MinimumSizeY)
Expand Down
2 changes: 0 additions & 2 deletions Penumbra/Config/EphemeralConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
using Luna.Generators;
using Newtonsoft.Json;
using Penumbra.Files;
using Penumbra.Services;
using Penumbra.UI;
using Penumbra.UI.ManagementTab;
using Penumbra.UI.ModsTab;
Expand Down Expand Up @@ -31,7 +30,6 @@ public sealed partial class EphemeralConfig : ISavable, IService
[ConfigProperty]
private ModPanelTab _selectedModPanelTab = ModPanelTab.Settings;

public bool FixMainWindow { get; set; } = false;
public HashSet<string> AdvancedEditingOpenForModPaths { get; set; } = [];
public bool ForceRedrawOnFileChange { get; set; } = false;
public bool IncognitoMode { get; set; } = false;
Expand Down
21 changes: 12 additions & 9 deletions Penumbra/Import/TexToolsImport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public partial class TexToolsImporter : IDisposable
private readonly CancellationTokenSource _cancellation = new();
private readonly CancellationToken _token;

public ImporterState State { get; private set; }
public readonly List<(FileInfo File, DirectoryInfo? Mod, Exception? Error)> ExtractedMods;
public ImporterState State { get; private set; }
public readonly List<ModImportResult> ExtractedMods;

private readonly Configuration _config;
private readonly DuplicateManager _duplicates;
Expand All @@ -37,8 +37,9 @@ public partial class TexToolsImporter : IDisposable
private readonly MigrationManager _migrationManager;

public TexToolsImporter(int count, IEnumerable<FileInfo> modPackFiles, Action<FileInfo, DirectoryInfo?, Exception?> handler,
Configuration config, DuplicateManager duplicates, ModNormalizer modNormalizer, ModManager modManager, FileCompactor compactor,
MigrationManager migrationManager, TexToolsImporter? previous)
TaskCompletionSource<ModImportResult[]> taskCompletionSource, Configuration config, DuplicateManager duplicates,
ModNormalizer modNormalizer, ModManager modManager, FileCompactor compactor, MigrationManager migrationManager,
TexToolsImporter? previous)
{
if (previous is not null)
{
Expand All @@ -58,7 +59,7 @@ public TexToolsImporter(int count, IEnumerable<FileInfo> modPackFiles, Action<Fi
_compactor = compactor;
_migrationManager = migrationManager;
_modPackCount = count + _previousModPackCount;
ExtractedMods = new List<(FileInfo, DirectoryInfo?, Exception?)>(count + _previousModPackCount);
ExtractedMods = new List<ModImportResult>(count + _previousModPackCount);
_token = _cancellation.Token;
if (previous is not null)
ExtractedMods.AddRange(previous.ExtractedMods);
Expand All @@ -68,7 +69,9 @@ public TexToolsImporter(int count, IEnumerable<FileInfo> modPackFiles, Action<Fi
{
foreach (var (file, dir, error) in ExtractedMods.Skip(_previousModPackCount))
handler(file, dir, error);
}, TaskScheduler.Default);
}, TaskScheduler.Default)
.ContinueWith(_ => { taskCompletionSource.SetResult(ExtractedMods.Skip(_previousModPackCount).ToArray()); },
TaskScheduler.Default);
}

private void CloseStreams()
Expand Down Expand Up @@ -100,14 +103,14 @@ private void ImportFiles()
_currentModDirectory = null;
if (_token.IsCancellationRequested)
{
ExtractedMods.Add((file, null, new TaskCanceledException("Task canceled by user.")));
ExtractedMods.Add(new ModImportResult(file, null, new TaskCanceledException("Task canceled by user.")));
continue;
}

try
{
var directory = VerifyVersionAndImport(file);
ExtractedMods.Add((file, directory, null));
ExtractedMods.Add(new ModImportResult(file, directory, null));
if (_config.AutoDeduplicateOnImport)
{
State = ImporterState.DeduplicatingFiles;
Expand All @@ -116,7 +119,7 @@ private void ImportFiles()
}
catch (Exception e)
{
ExtractedMods.Add((file, _currentModDirectory, e));
ExtractedMods.Add(new ModImportResult(file, _currentModDirectory, e));
_currentNumOptions = 0;
_currentOptionIdx = 0;
_currentFileIdx = 0;
Expand Down
59 changes: 59 additions & 0 deletions Penumbra/Interop/Hooks/Animation/GetClipResources.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
using FFXIVClientStructs.FFXIV.Client.System.Scheduler.Clip;
using Luna;
using Penumbra.Collections;
using Penumbra.CrashHandler.Buffers;
using Penumbra.GameData;
using Penumbra.GameData.Interop;
using Penumbra.Interop.PathResolving;
using Penumbra.Services;

namespace Penumbra.Interop.Hooks.Animation;

public sealed unsafe class GetClipResources : FastHook<GetClipResources.Delegate>
{
private readonly delegate* unmanaged<BaseClip*, Actor> _clipGameObject;
private readonly GameState _state;
private readonly CollectionResolver _collectionResolver;
private readonly CrashHandlerService _crashHandler;

public GetClipResources(HookManager hooks, GameState state, CollectionResolver collectionResolver, ObjectManager objects,
CrashHandlerService crashHandler)
{
_state = state;
_collectionResolver = collectionResolver;
_crashHandler = crashHandler;
_clipGameObject = (delegate* unmanaged < BaseClip*, Actor >)hooks.SigScanner.ScanText(Sigs.BaseClipGetGameObject);
if (_clipGameObject is null)
throw new Exception($"Could not scan address {Sigs.BaseClipGetGameObject}.");

Task = hooks.CreateHook<Delegate>("Get Clip Resources", Sigs.BaseClipGetClipResources, Detour,
!HookOverrides.Instance.Animation.GetClipResources);
}

public delegate nint Delegate(BaseClip* clip);


[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]
private nint Detour(BaseClip* clip)
{
if (clip is null)
return Task.Result!.Original(clip);

var gameObject = _clipGameObject(clip);
var data = gameObject.Valid ? _collectionResolver.IdentifyCollection(gameObject.AsObject, true) : ResolveData.Invalid;
if (!data.Valid)
{
var ret2 = Task.Result!.Original(clip);
Penumbra.Log.Excessive($"[Get Clip Resources] Invoked on {(nint)clip:X} -> {ret2:X}.");
return ret2;
}

var last = _state.SetSoundData(data);
_crashHandler.LogAnimation(data.AssociatedGameObject, data.ModCollection, AnimationInvocationType.GetClipResources);
var ret = Task.Result!.Original(clip);
_state.RestoreAnimationData(last);
Penumbra.Log.Excessive(
$"[Get Clip Resources] Invoked on {(nint)clip:X} for {data.AssociatedGameObject:X} ({data.ModCollection}) -> {ret:X}.");
return ret;
}
}
3 changes: 2 additions & 1 deletion Penumbra/Interop/Hooks/Animation/ScheduleClipUpdate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public ScheduleClipUpdate(HookManager hooks, GameState state, CollectionResolver
_collectionResolver = collectionResolver;
_objects = objects;
_crashHandler = crashHandler;
Task = hooks.CreateHook<Delegate>("Schedule Clip Update", Sigs.ScheduleClipUpdate, Detour, !HookOverrides.Instance.Animation.ScheduleClipUpdate);
Task = hooks.CreateHook<Delegate>("Schedule Clip Update", Sigs.ScheduleClipUpdate, Detour,
!HookOverrides.Instance.Animation.ScheduleClipUpdate);
}

public delegate void Delegate(ClipScheduler* x);
Expand Down
1 change: 1 addition & 0 deletions Penumbra/Interop/Hooks/HookSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public struct AnimationHooks
public bool LoadTimelineResources;
public bool PlayFootstep;
public bool ScheduleClipUpdate;
public bool GetClipResources;
public bool SomeActionLoad;
public bool SomeMountAnimation;
public bool SomePapLoad;
Expand Down
16 changes: 8 additions & 8 deletions Penumbra/Meta/Files/CmpFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ public sealed unsafe class CmpFile : MetaBaseFile
public static readonly CharacterUtility.InternalIndex InternalIndex =
CharacterUtility.ReverseIndices[(int)MetaIndex.HumanCmp];

public new GameData.Files.CmpData* Data
=> (GameData.Files.CmpData*)base.Data;
public new CmpData* Data
=> (CmpData*)base.Data;

public RspEntry this[SubRace subRace, RspAttribute attribute]
{
get => new(Data->GetScale(subRace).Get(attribute));
set => Data->GetScale(subRace).Get(attribute) = value.Value;
get => new(Data->GetScaleWrite(subRace).Get(attribute));
set => Data->GetScaleWrite(subRace).Get(attribute) = value.Value;
}

public override void Reset()
Expand All @@ -43,15 +43,15 @@ public CmpFile(MetaFileManager manager)

public static RspEntry GetDefault(MetaFileManager manager, SubRace subRace, RspAttribute attribute)
{
var data = (GameData.Files.CmpData*)manager.CharacterUtility.DefaultResource(InternalIndex).Address;
return new RspEntry(data->GetScale(subRace).Get(attribute));
var data = (CmpData*)manager.CharacterUtility.DefaultResource(InternalIndex).Address;
return new RspEntry(data->GetScaleWrite(subRace).Get(attribute));
}

public static RspEntry* GetDefaults(MetaFileManager manager, SubRace subRace, RspAttribute attribute)
{
{
var data = (GameData.Files.CmpData*)manager.CharacterUtility.DefaultResource(InternalIndex).Address;
return (RspEntry*)Unsafe.AsPointer(ref data->GetScale(subRace).Get(attribute));
var data = (CmpData*)manager.CharacterUtility.DefaultResource(InternalIndex).Address;
return (RspEntry*)Unsafe.AsPointer(ref data->GetScaleWrite(subRace).Get(attribute));
}
}
}
Loading
Loading