vfx replacer?

This commit is contained in:
Anna 2022-09-05 05:56:13 -04:00
parent 4d6565841e
commit d7df600ddc
8 changed files with 124 additions and 1 deletions

View File

@ -8,7 +8,7 @@ using OrangeGuidanceTomestone.Helpers;
namespace OrangeGuidanceTomestone;
internal class Messages : IDisposable {
private const string VfxPath = "bg/ffxiv/fst_f1/common/vfx/eff/b0941trp1d_o.avfx";
internal const string VfxPath = "bg/ffxiv/fst_f1/common/vfx/eff/b0941trp1d_o.avfx";
private Plugin Plugin { get; }

View File

@ -0,0 +1,5 @@
namespace OrangeGuidanceTomestone.MiniPenumbra;
internal class MiniFunctions {
}

View File

@ -0,0 +1,19 @@
using System.Runtime.InteropServices;
using FFXIVClientStructs.FFXIV.Client.System.Resource.Handle;
namespace OrangeGuidanceTomestone.MiniPenumbra;
[StructLayout(LayoutKind.Explicit)]
internal unsafe struct SeFileDescriptor {
[FieldOffset(0x00)]
public SeFileMode FileMode;
[FieldOffset(0x30)]
public void* FileDescriptor;
[FieldOffset(0x50)]
public ResourceHandle* ResourceHandle;
[FieldOffset(0x70)]
public char Utf16FileName;
}

View File

@ -0,0 +1,10 @@
namespace OrangeGuidanceTomestone.MiniPenumbra;
internal enum SeFileMode : byte {
LoadUnpackedResource = 0,
LoadFileResource = 1, // The config files in MyGames use this.
// Probably debug options only.
LoadIndexResource = 0xA, // load index/index2
LoadSqPackResource = 0xB,
}

View File

@ -0,0 +1,70 @@
using Dalamud.Hooking;
using Dalamud.Utility.Signatures;
namespace OrangeGuidanceTomestone.MiniPenumbra;
internal unsafe class VfxReplacer : IDisposable {
private delegate byte ReadSqPackDelegate(void* resourceManager, SeFileDescriptor* pFileDesc, int priority, bool isSync);
[Signature("E8 ?? ?? ?? ?? EB 05 E8 ?? ?? ?? ?? 84 C0 0F 84 ?? 00 00 00 4C 8B C3", DetourName = nameof(ReadSqPackDetour))]
private Hook<ReadSqPackDelegate> _readSqPackHook;
[Signature("E8 ?? ?? ?? ?? 84 C0 0F 84 ?? 00 00 00 4C 8B C3 BA 05")]
private delegate* unmanaged<void*, SeFileDescriptor*, int, bool, byte> _readFile;
private Plugin Plugin { get; }
internal VfxReplacer(Plugin plugin) {
this.Plugin = plugin;
SignatureHelper.Initialise(this);
this._readSqPackHook!.Enable();
}
public void Dispose() {
this._readSqPackHook.Dispose();
}
private byte ReadSqPackDetour(void* resourceManager, SeFileDescriptor* fileDescriptor, int priority, bool isSync) {
if (!this.Plugin.Config.RemoveGlow) {
goto Original;
}
if (fileDescriptor == null || fileDescriptor->ResourceHandle == null) {
goto Original;
}
var path = fileDescriptor->ResourceHandle->FileName.ToString();
if (path != Messages.VfxPath) {
goto Original;
}
return this.DefaultRootedResourceLoad(this.Plugin.AvfxFilePath, resourceManager, fileDescriptor, priority, isSync);
Original:
return this._readSqPackHook.Original(resourceManager, fileDescriptor, priority, isSync);
}
// Load the resource from a path on the users hard drives.
private byte DefaultRootedResourceLoad(string gamePath, void* resourceManager, SeFileDescriptor* fileDescriptor, int priority, bool isSync) {
// Specify that we are loading unpacked files from the drive.
// We need to copy the actual file path in UTF16 (Windows-Unicode) on two locations,
// but since we only allow ASCII in the game paths, this is just a matter of upcasting.
fileDescriptor->FileMode = SeFileMode.LoadUnpackedResource;
var fd = stackalloc byte[0x20 + 2 * gamePath.Length + 0x16];
fileDescriptor->FileDescriptor = fd;
var fdPtr = (char*) (fd + 0x21);
for (var i = 0; i < gamePath.Length; ++i) {
(&fileDescriptor->Utf16FileName)[i] = gamePath[i];
fdPtr[i] = gamePath[i];
}
(&fileDescriptor->Utf16FileName)[gamePath.Length] = '\0';
fdPtr[gamePath.Length] = '\0';
// Use the SE ReadFile function.
var ret = this._readFile(resourceManager, fileDescriptor, priority, isSync);
return ret;
}
}

Binary file not shown.

View File

@ -67,6 +67,8 @@
<ItemGroup>
<EmbeddedResource Include="../server/packs/*.yaml" LinkBase="packs" />
<EmbeddedResource Remove="../server/packs/*_old*.yaml" />
<None Remove="MiniPenumbra\b0941trp1d_o.avfx" />
<EmbeddedResource Include="MiniPenumbra\b0941trp1d_o.avfx" />
</ItemGroup>
</Project>

View File

@ -6,6 +6,7 @@ using Dalamud.Game.Command;
using Dalamud.Game.Gui;
using Dalamud.IoC;
using Dalamud.Plugin;
using OrangeGuidanceTomestone.MiniPenumbra;
namespace OrangeGuidanceTomestone;
@ -37,13 +38,19 @@ public class Plugin : IDalamudPlugin {
internal Vfx Vfx { get; }
internal PluginUi Ui { get; }
internal Messages Messages { get; }
internal VfxReplacer VfxReplacer { get; }
internal Commands Commands { get; }
internal string AvfxFilePath { get; }
public Plugin() {
this.AvfxFilePath = this.CopyAvfxFile();
this.Config = this.Interface!.GetPluginConfig() as Configuration ?? new Configuration();
this.Vfx = new Vfx();
this.Messages = new Messages(this);
this.Ui = new PluginUi(this);
this.VfxReplacer = new VfxReplacer(this);
this.Commands = new Commands(this);
if (this.Config.ApiKey == string.Empty) {
@ -59,6 +66,7 @@ public class Plugin : IDalamudPlugin {
public void Dispose() {
this.Commands.Dispose();
this.VfxReplacer.Dispose();
this.Ui.Dispose();
this.Messages.Dispose();
this.Vfx.Dispose();
@ -67,4 +75,13 @@ public class Plugin : IDalamudPlugin {
internal void SaveConfig() {
this.Interface.SavePluginConfig(this.Config);
}
private string CopyAvfxFile() {
var configDir = this.Interface!.GetPluginConfigDirectory();
Directory.CreateDirectory(configDir);
var stream = Resourcer.Resource.AsStream("MiniPenumbra/b0941trp1d_o.avfx");
var path = Path.Join(configDir, "sign.avfx");
stream.CopyTo(File.Create(path));
return path;
}
}