Merge remote-tracking branch 'upstream/apiX' into feature/itextureprovider-updates

This commit is contained in:
Soreepeong 2024-06-04 23:54:38 +09:00
commit 0d7c0a0375
335 changed files with 1640 additions and 1020 deletions

View file

@ -12,6 +12,7 @@ jobs:
matrix:
branches:
- new_im_hooks
- apiX
defaults:
run:

View file

@ -111,9 +111,17 @@ namespace logging {
* @param arg1 First format parameter.
* @param args Second and further format parameters, if any.
*/
template<typename Arg, typename...Args>
void print(Level level, const char* fmt, Arg&& arg1, Args&&...args) {
print(level, std::vformat(fmt, std::make_format_args(to_format_arg(std::forward<Arg>(arg1)), to_format_arg(std::forward<Args>(args))...)));
template<typename Arg, typename... Args>
void print(Level level, const char* fmt, Arg&& arg1, Args&&... args) {
// make_format_args only accepts references now due to https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2905r2.html
// we can switch std::runtime_format in C++26 :) https://isocpp.org/files/papers/P2918R0.html
auto transformed_args = std::make_tuple(to_format_arg(arg1), to_format_arg(args)...);
auto format_args = std::apply(
[&](auto&... elems) { return std::make_format_args(elems...); },
transformed_args
);
print(level, std::vformat(fmt, format_args));
}
template<typename...Args> void V(Args&&...args) { print(Level::Verbose, std::forward<Args>(args)...); }

View file

@ -27,7 +27,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Lumina" Version="3.16.0" />
<PackageReference Include="Lumina" Version="3.17.0" />
<PackageReference Include="Lumina.Excel" Version="6.5.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
<PackageReference Include="StyleCop.Analyzers" Version="1.2.0-beta.333">

View file

@ -2,7 +2,6 @@ using System;
using System.IO;
using Dalamud.Configuration.Internal;
using Dalamud.Game;
using Dalamud.Game.Command;
using Dalamud.Interface.Windowing;
using Dalamud.Plugin;

View file

@ -42,6 +42,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dalamud.Common", "Dalamud.C
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dalamud.LocExporter", "tools\Dalamud.LocExporter\Dalamud.LocExporter.csproj", "{A568929D-6FF6-4DFA-9D14-5D7DC08FA5E0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteropGenerator", "lib\FFXIVClientStructs\InteropGenerator\InteropGenerator.csproj", "{3620414C-7DFC-423E-929F-310E19F5D930}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteropGenerator.Runtime", "lib\FFXIVClientStructs\InteropGenerator.Runtime\InteropGenerator.Runtime.csproj", "{A6AA1C3F-9470-4922-9D3F-D4549657AB22}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -108,6 +112,14 @@ Global
{A568929D-6FF6-4DFA-9D14-5D7DC08FA5E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A568929D-6FF6-4DFA-9D14-5D7DC08FA5E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A568929D-6FF6-4DFA-9D14-5D7DC08FA5E0}.Release|Any CPU.Build.0 = Release|Any CPU
{3620414C-7DFC-423E-929F-310E19F5D930}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3620414C-7DFC-423E-929F-310E19F5D930}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3620414C-7DFC-423E-929F-310E19F5D930}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3620414C-7DFC-423E-929F-310E19F5D930}.Release|Any CPU.Build.0 = Release|Any CPU
{A6AA1C3F-9470-4922-9D3F-D4549657AB22}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A6AA1C3F-9470-4922-9D3F-D4549657AB22}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A6AA1C3F-9470-4922-9D3F-D4549657AB22}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A6AA1C3F-9470-4922-9D3F-D4549657AB22}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -118,6 +130,8 @@ Global
{2F7FF0A8-B619-4572-86C7-71E46FE22FB8} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
{C9B87BD7-AF49-41C3-91F1-D550ADEB7833} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
{05AB2F46-268B-4915-806F-DDF813E2D59D} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
{3620414C-7DFC-423E-929F-310E19F5D930} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
{A6AA1C3F-9470-4922-9D3F-D4549657AB22} = {E15BDA6D-E881-4482-94BA-BE5527E917FF}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {79B65AC9-C940-410E-AB61-7EA7E12C7599}

View file

@ -1,10 +1,11 @@
namespace Dalamud;
using Dalamud.Utility;
// TODO(v10): Delete this, and use Dalamud.Common.ClientLanguage instead for everything.
namespace Dalamud;
/// <summary>
/// Enum describing the language the game loads in.
/// </summary>
[Api10ToDo("Delete this, and use Dalamud.Common.ClientLanguage instead for everything.")]
public enum ClientLanguage
{
/// <summary>

View file

@ -1,10 +1,11 @@
using System;
using Dalamud.Utility;
namespace Dalamud;
/// <summary>
/// Extension methods for the <see cref="ClientLanguage"/> class.
/// </summary>
[Api10ToDo("Delete this, and use Dalamud.Common.ClientLanguage instead for everything.")]
public static class ClientLanguageExtensions
{
/// <summary>

View file

@ -1,5 +1,4 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
@ -7,6 +6,7 @@ using System.Linq;
using System.Runtime.InteropServices;
using Dalamud.Game.Text;
using Dalamud.Interface;
using Dalamud.Interface.FontIdentifier;
using Dalamud.Interface.Internal.Windows.PluginInstaller;
using Dalamud.Interface.Style;
@ -162,6 +162,12 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
[Obsolete("It happens that nobody touched this setting", true)]
public float FontGammaLevel { get; set; } = 1.4f;
/// <summary>Gets or sets the opacity of the IME state indicator.</summary>
/// <value>0 will hide the state indicator. 1 will make the state indicator fully visible. Values outside the
/// range will be clamped to [0, 1].</value>
/// <remarks>See <see cref="SeIconChar.ImeHiragana"/> to <see cref="SeIconChar.ImeChineseLatin"/>.</remarks>
public float ImeStateIndicatorOpacity { get; set; } = 1f;
/// <summary>
/// Gets or sets a value indicating whether or not plugin UI should be hidden.
/// </summary>
@ -456,7 +462,7 @@ internal sealed class DalamudConfiguration : IInternalDisposableService
/// <summary>
/// Gets or sets the page of the plugin installer that is shown by default when opened.
/// </summary>
public PluginInstallerWindow.PluginInstallerOpenKind PluginInstallerOpen { get; set; } = PluginInstallerWindow.PluginInstallerOpenKind.AllPlugins;
public PluginInstallerOpenKind PluginInstallerOpen { get; set; } = PluginInstallerOpenKind.AllPlugins;
/// <summary>
/// Load a configuration from the provided path.

View file

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
namespace Dalamud.Configuration.Internal;

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Configuration.Internal;
/// <summary>

View file

@ -33,8 +33,9 @@ internal sealed class Dalamud : IServiceType
{
#region Internals
private static int shownServiceError = 0;
private readonly ManualResetEvent unloadSignal;
#endregion
/// <summary>
@ -68,54 +69,47 @@ internal sealed class Dalamud : IServiceType
// Set up FFXIVClientStructs
this.SetupClientStructsResolver(cacheDir);
if (!configuration.IsResumeGameAfterPluginLoad)
void KickoffGameThread()
{
Log.Verbose("=============== GAME THREAD KICKOFF ===============");
Timings.Event("Game thread kickoff");
NativeFunctions.SetEvent(mainThreadContinueEvent);
ServiceManager.InitializeEarlyLoadableServices()
.ContinueWith(t =>
}
void HandleServiceInitFailure(Task t)
{
Log.Error(t.Exception!, "Service initialization failure");
if (Interlocked.CompareExchange(ref shownServiceError, 1, 0) != 0)
return;
Util.Fatal(
"Dalamud failed to load all necessary services.\n\nThe game will continue, but you may not be able to use plugins.",
"Dalamud", false);
}
ServiceManager.InitializeEarlyLoadableServices()
.ContinueWith(
t =>
{
if (t.IsCompletedSuccessfully)
return;
Log.Error(t.Exception!, "Service initialization failure");
Util.Fatal(
"Dalamud failed to load all necessary services.\n\nThe game will continue, but you may not be able to use plugins.",
"Dalamud", false);
HandleServiceInitFailure(t);
});
}
else
{
Task.Run(async () =>
ServiceManager.BlockingResolved.ContinueWith(
t =>
{
try
if (t.IsCompletedSuccessfully)
{
var tasks = new[]
{
ServiceManager.InitializeEarlyLoadableServices(),
ServiceManager.BlockingResolved,
};
await Task.WhenAny(tasks);
var faultedTasks = tasks.Where(x => x.IsFaulted).Select(x => (Exception)x.Exception!).ToArray();
if (faultedTasks.Any())
throw new AggregateException(faultedTasks);
NativeFunctions.SetEvent(mainThreadContinueEvent);
await Task.WhenAll(tasks);
}
catch (Exception e)
{
Log.Error(e, "Service initialization failure");
Util.Fatal("Dalamud could not initialize correctly. Please report this error. \n\nThe game will continue, but you may not be able to use plugins.", "Dalamud", false);
}
finally
{
NativeFunctions.SetEvent(mainThreadContinueEvent);
KickoffGameThread();
return;
}
HandleServiceInitFailure(t);
});
}
this.DefaultExceptionFilter = NativeFunctions.SetUnhandledExceptionFilter(nint.Zero);
NativeFunctions.SetUnhandledExceptionFilter(this.DefaultExceptionFilter);
@ -217,8 +211,10 @@ internal sealed class Dalamud : IServiceType
{
using (Timings.Start("CS Resolver Init"))
{
FFXIVClientStructs.Interop.Resolver.GetInstance.SetupSearchSpace(Service<TargetSigScanner>.Get().SearchBase, new FileInfo(Path.Combine(cacheDir.FullName, $"{this.StartInfo.GameVersion}_cs.json")));
FFXIVClientStructs.Interop.Resolver.GetInstance.Resolve();
// the resolver tracks version as a field in the json
InteropGenerator.Runtime.Resolver.GetInstance.Setup(Service<TargetSigScanner>.Get().SearchBase, $"{this.StartInfo.GameVersion}", new FileInfo(Path.Combine(cacheDir.FullName, "cs.json")));
FFXIVClientStructs.Interop.Generated.Addresses.Register();
InteropGenerator.Runtime.Resolver.GetInstance.Resolve();
}
}
}

View file

@ -8,7 +8,7 @@
</PropertyGroup>
<PropertyGroup Label="Feature">
<DalamudVersion>9.1.0.5</DalamudVersion>
<DalamudVersion>9.1.0.9</DalamudVersion>
<Description>XIV Launcher addon framework</Description>
<AssemblyVersion>$(DalamudVersion)</AssemblyVersion>
<Version>$(DalamudVersion)</Version>
@ -69,9 +69,9 @@
<PackageReference Include="goaaats.Reloaded.Hooks" Version="4.2.0-goat.4" />
<PackageReference Include="goaaats.Reloaded.Assembler" Version="1.0.14-goat.2" />
<PackageReference Include="JetBrains.Annotations" Version="2021.2.0" />
<PackageReference Include="Lumina" Version="3.16.0" />
<PackageReference Include="Lumina" Version="3.17.0" />
<PackageReference Include="Lumina.Excel" Version="6.5.2" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.ObjectPool" Version="9.0.0-preview.1.24081.5" />
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.46-beta">
<PrivateAssets>all</PrivateAssets>
</PackageReference>

View file

@ -1,4 +1,3 @@
using System.Diagnostics;
using System.IO;
using System.Threading;
@ -52,15 +51,12 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
DefaultExcelLanguage = this.Language.ToLumina(),
};
var processModule = Process.GetCurrentProcess().MainModule;
if (processModule != null)
this.GameData = new(
Path.Combine(Path.GetDirectoryName(Environment.ProcessPath)!, "sqpack"),
luminaOptions)
{
this.GameData = new GameData(Path.Combine(Path.GetDirectoryName(processModule.FileName)!, "sqpack"), luminaOptions);
}
else
{
throw new Exception("Could not main module.");
}
StreamPool = new(),
};
Log.Information("Lumina is ready: {0}", this.GameData.DataPath);
@ -107,7 +103,8 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
}
catch (Exception ex)
{
Log.Error(ex, "Could not download data.");
Log.Error(ex, "Could not initialize Lumina");
throw;
}
}
@ -161,6 +158,7 @@ internal sealed class DataManager : IInternalDisposableService, IDataManager
void IInternalDisposableService.DisposeService()
{
this.luminaCancellationTokenSource.Cancel();
this.GameData.Dispose();
}
private class LauncherTroubleshootingInfo

View file

@ -21,11 +21,11 @@ internal unsafe class AddonEventEntry
/// Gets the pointer to the addons AtkUnitBase.
/// </summary>
required public nint Addon { get; init; }
/// <summary>
/// Gets the name of the addon this args referrers to.
/// </summary>
public string AddonName => this.Addon == nint.Zero ? InvalidAddonName : this.addonName ??= MemoryHelper.ReadString((nint)((AtkUnitBase*)this.Addon)->Name, 0x20);
public string AddonName => this.Addon == nint.Zero ? InvalidAddonName : this.addonName ??= ((AtkUnitBase*)this.Addon)->NameString;
/// <summary>
/// Gets the pointer to the event source.

View file

@ -23,10 +23,10 @@ internal unsafe class AddonEventListener : IDisposable
this.receiveEventDelegate = eventHandler;
this.eventListener = (AtkEventListener*)Marshal.AllocHGlobal(sizeof(AtkEventListener));
this.eventListener->vtbl = (void*)Marshal.AllocHGlobal(sizeof(void*) * 3);
this.eventListener->vfunc[0] = (delegate* unmanaged<void>)&NullSub;
this.eventListener->vfunc[1] = (delegate* unmanaged<void>)&NullSub;
this.eventListener->vfunc[2] = (void*)Marshal.GetFunctionPointerForDelegate(this.receiveEventDelegate);
this.eventListener->VirtualTable = (AtkEventListener.AtkEventListenerVirtualTable*)Marshal.AllocHGlobal(sizeof(void*) * 3);
this.eventListener->VirtualTable->Dtor = (delegate* unmanaged<AtkEventListener*, byte, void>)(delegate* unmanaged<void>)&NullSub;
this.eventListener->VirtualTable->ReceiveGlobalEvent = (delegate* unmanaged<AtkEventListener*, AtkEventType, int, AtkEvent*, nint, void>)(delegate* unmanaged<void>)&NullSub;
this.eventListener->VirtualTable->ReceiveEvent = (delegate* unmanaged<AtkEventListener*, AtkEventType, int, AtkEvent*, nint, void>)Marshal.GetFunctionPointerForDelegate(this.receiveEventDelegate);
}
/// <summary>
@ -49,7 +49,7 @@ internal unsafe class AddonEventListener : IDisposable
{
if (this.eventListener is null) return;
Marshal.FreeHGlobal((nint)this.eventListener->vtbl);
Marshal.FreeHGlobal((nint)this.eventListener->VirtualTable);
Marshal.FreeHGlobal((nint)this.eventListener);
this.eventListener = null;

View file

@ -173,14 +173,14 @@ internal unsafe class AddonEventManager : IInternalDisposableService
{
try
{
var atkStage = AtkStage.GetSingleton();
var atkStage = AtkStage.Instance();
if (this.cursorOverride is not null && atkStage is not null)
{
var cursor = (AddonCursorType)atkStage->AtkCursor.Type;
if (cursor != this.cursorOverride)
{
AtkStage.GetSingleton()->AtkCursor.SetCursorType((AtkCursor.CursorType)this.cursorOverride, 1);
AtkStage.Instance()->AtkCursor.SetCursorType((AtkCursor.CursorType)this.cursorOverride, 1);
}
return nint.Zero;
@ -221,7 +221,7 @@ internal class AddonEventManagerPluginScoped : IInternalDisposableService, IAddo
{
this.plugin = plugin;
this.eventManagerService.AddPluginEventController(plugin.Manifest.WorkingPluginId);
this.eventManagerService.AddPluginEventController(plugin.EffectiveWorkingPluginId);
}
/// <inheritdoc/>
@ -233,16 +233,16 @@ internal class AddonEventManagerPluginScoped : IInternalDisposableService, IAddo
this.eventManagerService.ResetCursor();
}
this.eventManagerService.RemovePluginEventController(this.plugin.Manifest.WorkingPluginId);
this.eventManagerService.RemovePluginEventController(this.plugin.EffectiveWorkingPluginId);
}
/// <inheritdoc/>
public IAddonEventHandle? AddEvent(IntPtr atkUnitBase, IntPtr atkResNode, AddonEventType eventType, IAddonEventManager.AddonEventHandler eventHandler)
=> this.eventManagerService.AddEvent(this.plugin.Manifest.WorkingPluginId, atkUnitBase, atkResNode, eventType, eventHandler);
=> this.eventManagerService.AddEvent(this.plugin.EffectiveWorkingPluginId, atkUnitBase, atkResNode, eventType, eventHandler);
/// <inheritdoc/>
public void RemoveEvent(IAddonEventHandle eventHandle)
=> this.eventManagerService.RemoveEvent(this.plugin.Manifest.WorkingPluginId, eventHandle);
=> this.eventManagerService.RemoveEvent(this.plugin.EffectiveWorkingPluginId, eventHandle);
/// <inheritdoc/>
public void SetCursor(AddonCursorType cursor)

View file

@ -5,6 +5,7 @@ using Dalamud.Game.Gui;
using Dalamud.Logging.Internal;
using Dalamud.Memory;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Addon.Events;
@ -46,7 +47,7 @@ internal unsafe class PluginEventController : IDisposable
var eventHandle = new AddonEventHandle
{
AddonName = MemoryHelper.ReadStringNullTerminated((nint)addon->Name),
AddonName = addon->NameString,
ParamKey = eventId,
EventType = atkEventType,
EventGuid = eventGuid,

View file

@ -1,4 +1,6 @@
using Dalamud.Memory;
using System.Runtime.CompilerServices;
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Component.GUI;
@ -64,9 +66,14 @@ public abstract unsafe class AddonArgs
return false;
var addonPointer = (AtkUnitBase*)this.Addon;
if (addonPointer->Name is null) return false;
if (addonPointer->Name[0] == 0) return false;
return MemoryHelper.EqualsZeroTerminatedString(name, (nint)addonPointer->Name, null, 0x20);
// note: might want to rewrite this to just compare to NameString
return MemoryHelper.EqualsZeroTerminatedString(
name,
(nint)Unsafe.AsPointer(ref addonPointer->Name[0]),
null,
0x20);
}
/// <summary>
@ -78,8 +85,8 @@ public abstract unsafe class AddonArgs
if (this.Addon == nint.Zero) return InvalidAddon;
var addonPointer = (AtkUnitBase*)this.Addon;
if (addonPointer->Name is null) return InvalidAddon;
if (addonPointer->Name[0] == 0) return InvalidAddon;
return this.addonName ??= MemoryHelper.ReadString((nint)addonPointer->Name, 0x20);
return this.addonName ??= addonPointer->NameString;
}
}

View file

@ -10,6 +10,7 @@ using Dalamud.IoC.Internal;
using Dalamud.Logging.Internal;
using Dalamud.Memory;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Addon.Lifecycle;
@ -133,6 +134,9 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
/// <param name="listener">The listener to unregister.</param>
internal void UnregisterListener(AddonLifecycleEventListener listener)
{
// Set removed state to true immediately, then lazily remove it from the EventListeners list on next Framework Update.
listener.Removed = true;
this.framework.RunOnTick(() =>
{
this.EventListeners.Remove(listener);
@ -167,6 +171,10 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
if (listener.EventType != eventType)
continue;
// If the listener is pending removal, and is waiting until the next Framework Update, don't invoke listener.
if (listener.Removed)
continue;
// Match on string.empty for listeners that want events for all addons.
if (!string.IsNullOrWhiteSpace(listener.AddonName) && !args.IsAddon(listener.AddonName))
continue;
@ -186,8 +194,8 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
{
// Hook the addon's ReceiveEvent function here, but only enable the hook if we have an active listener.
// Disallows hooking the core internal event handler.
var addonName = MemoryHelper.ReadStringNullTerminated((nint)addon->Name);
var receiveEventAddress = (nint)addon->VTable->ReceiveEvent;
var addonName = addon->NameString;
var receiveEventAddress = (nint)addon->VirtualTable->ReceiveEvent;
if (receiveEventAddress != this.disallowedReceiveEventAddress)
{
// If we have a ReceiveEvent listener already made for this hook address, add this addon's name to that handler.
@ -267,7 +275,7 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
{
try
{
var addonName = MemoryHelper.ReadStringNullTerminated((nint)atkUnitBase[0]->Name);
var addonName = atkUnitBase[0]->NameString;
this.UnregisterReceiveEventHook(addonName);
}
catch (Exception e)
@ -363,7 +371,7 @@ internal unsafe class AddonLifecycle : IInternalDisposableService
try
{
addon->OnUpdate(numberArrayData, stringArrayData);
addon->OnRequestedUpdate(numberArrayData, stringArrayData);
}
catch (Exception e)
{

View file

@ -26,6 +26,11 @@ internal class AddonLifecycleEventListener
/// </summary>
public string AddonName { get; init; }
/// <summary>
/// Gets or sets a value indicating whether this event has been unregistered.
/// </summary>
public bool Removed { get; set; }
/// <summary>
/// Gets the event type this listener is looking for.
/// </summary>

View file

@ -4,6 +4,7 @@ using Dalamud.Game.Addon.Lifecycle.AddonArgTypes;
using Dalamud.Hooking;
using Dalamud.Logging.Internal;
using Dalamud.Memory;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Addon.Lifecycle;
@ -71,7 +72,7 @@ internal unsafe class AddonLifecycleReceiveEventListener : IDisposable
private void OnReceiveEvent(AtkUnitBase* addon, AtkEventType eventType, int eventParam, AtkEvent* atkEvent, nint data)
{
// Check that we didn't get here through a call to another addons handler.
var addonName = MemoryHelper.ReadString((nint)addon->Name, 0x20);
var addonName = addon->NameString;
if (!this.AddonNames.Contains(addonName))
{
this.Hook!.Original(addon, eventType, eventParam, atkEvent, data);

View file

@ -1,10 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using JetBrains.Annotations;
namespace Dalamud.Game;
/// <summary>

View file

@ -12,11 +12,11 @@ using Dalamud.Game.Gui;
using Dalamud.Game.Text;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Game.Text.SeStringHandling.Payloads;
using Dalamud.Interface;
using Dalamud.Interface.ImGuiNotification;
using Dalamud.Interface.ImGuiNotification.Internal;
using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal.Windows;
using Dalamud.Interface.Internal.Windows.PluginInstaller;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Internal;
using Dalamud.Utility;
@ -125,7 +125,7 @@ internal class ChatHandlers : IServiceType
this.openInstallerWindowLink = chatGui.AddChatLinkHandler("Dalamud", 1001, (i, m) =>
{
Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo(PluginInstallerWindow.PluginInstallerOpenKind.InstalledPlugins);
Service<DalamudInterface>.GetNullable()?.OpenPluginInstallerTo(PluginInstallerOpenKind.InstalledPlugins);
});
}
@ -139,7 +139,7 @@ internal class ChatHandlers : IServiceType
/// </summary>
public bool IsAutoUpdateComplete { get; private set; }
private void OnCheckMessageHandled(XivChatType type, uint senderid, ref SeString sender, ref SeString message, ref bool isHandled)
private void OnCheckMessageHandled(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
{
var textVal = message.TextValue;
@ -165,7 +165,7 @@ internal class ChatHandlers : IServiceType
}
}
private void OnChatMessage(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
private void OnChatMessage(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
{
var clientState = Service<ClientState.ClientState>.GetNullable();
if (clientState == null)

View file

@ -60,9 +60,9 @@ public sealed class AetheryteEntry
public bool IsSharedHouse => this.data.IsSharedHouse;
/// <summary>
/// Gets a value indicating whether this Aetheryte is an Appartment or not.
/// Gets a value indicating whether this Aetheryte is an Apartment or not.
/// </summary>
public bool IsAppartment => this.data.IsAppartment;
public bool IsApartment => this.data.IsApartment;
/// <summary>
/// Gets the Aetheryte data related to this aetheryte.

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Game.UI;
using Serilog;
@ -44,7 +45,7 @@ internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteLis
if (this.telepoInstance->TeleportList.First == this.telepoInstance->TeleportList.Last)
return 0;
return (int)this.telepoInstance->TeleportList.Size();
return this.telepoInstance->TeleportList.Count;
}
}
@ -61,7 +62,7 @@ internal sealed unsafe partial class AetheryteList : IServiceType, IAetheryteLis
if (this.clientState.LocalPlayer == null)
return null;
return new AetheryteEntry(this.telepoInstance->TeleportList.Get((ulong)index));
return new AetheryteEntry(this.telepoInstance->TeleportList[index]);
}
}

View file

@ -1,11 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using Serilog;
namespace Dalamud.Game.ClientState.Buddy;
@ -97,13 +98,13 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
/// <inheritdoc/>
public unsafe IntPtr GetCompanionBuddyMemberAddress()
{
return (IntPtr)(&this.BuddyListStruct->Companion);
return (IntPtr)this.BuddyListStruct->CompanionInfo.Companion;
}
/// <inheritdoc/>
public unsafe IntPtr GetPetBuddyMemberAddress()
{
return (IntPtr)(&this.BuddyListStruct->Pet);
return (IntPtr)this.BuddyListStruct->PetInfo.Pet;
}
/// <inheritdoc/>
@ -112,7 +113,7 @@ internal sealed partial class BuddyList : IServiceType, IBuddyList
if (index < 0 || index >= 3)
return IntPtr.Zero;
return (IntPtr)(this.BuddyListStruct->BattleBuddies + (index * BuddyMemberSize));
return (IntPtr)Unsafe.AsPointer(ref this.BuddyListStruct->BattleBuddies[index]);
}
/// <inheritdoc/>

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.ClientState.Resolvers;
@ -31,7 +29,7 @@ public unsafe class BuddyMember
/// <summary>
/// Gets the object ID of this buddy.
/// </summary>
public uint ObjectId => this.Struct->ObjectID;
public uint ObjectId => this.Struct->EntityId;
/// <summary>
/// Gets the actor associated with this buddy.
@ -54,7 +52,7 @@ public unsafe class BuddyMember
/// <summary>
/// Gets the data ID of this buddy.
/// </summary>
public uint DataID => this.Struct->DataID;
public uint DataID => this.Struct->DataId;
/// <summary>
/// Gets the Mount data related to this buddy. It should only be used with companion buddies.

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState;
/// <summary>

View file

@ -1,6 +1,7 @@
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using Serilog;
namespace Dalamud.Game.ClientState.Conditions;

View file

@ -1,4 +1,3 @@
using System;
using System.Numerics;
using Dalamud.Data;

View file

@ -1,10 +1,10 @@
using System;
using System.Collections;
using System.Collections.Generic;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using Serilog;
namespace Dalamud.Game.ClientState.Fates;
@ -49,7 +49,7 @@ internal sealed partial class FateTable : IServiceType, IFateTable
if (Struct->Fates.First == null || Struct->Fates.Last == null)
return 0;
return (int)Struct->Fates.Size();
return Struct->Fates.Count;
}
}
@ -89,7 +89,7 @@ internal sealed partial class FateTable : IServiceType, IFateTable
if (fateTable == IntPtr.Zero)
return IntPtr.Zero;
return (IntPtr)this.Struct->Fates.Get((ulong)index).Value;
return (IntPtr)this.Struct->Fates[index].Value;
}
/// <inheritdoc/>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.GamePad;
/// <summary>

View file

@ -1,10 +1,10 @@
using System;
using System.Numerics;
using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using ImGuiNET;
using Serilog;

View file

@ -1,6 +1,4 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Enums;
namespace Dalamud.Game.ClientState.JobGauge.Enums;
/// <summary>
/// MNK Nadi types.

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Enums;
/// <summary>

View file

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Reflection;
@ -6,6 +5,7 @@ using Dalamud.Game.ClientState.JobGauge.Types;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using Serilog;
namespace Dalamud.Game.ClientState.JobGauge;

View file

@ -1,4 +1,3 @@
using System;
using System.Linq;
using Dalamud.Game.ClientState.JobGauge.Enums;

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.JobGauge.Enums;
using FFXIVClientStructs.FFXIV.Client.Game.Gauge;

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,4 +1,3 @@
using System;
using System.Linq;
using Dalamud.Game.ClientState.JobGauge.Enums;

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.JobGauge.Enums;
namespace Dalamud.Game.ClientState.JobGauge.Types;

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.JobGauge.Enums;
namespace Dalamud.Game.ClientState.JobGauge.Types;

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.JobGauge.Enums;
using FFXIVClientStructs.FFXIV.Client.Game.Gauge;

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.JobGauge.Types;
/// <summary>

View file

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
@ -6,6 +5,7 @@ using System.Runtime.InteropServices;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using Serilog;
namespace Dalamud.Game.ClientState.Keys;

View file

@ -1,6 +1,4 @@
using System;
namespace Dalamud.Game.ClientState.Keys;
namespace Dalamud.Game.ClientState.Keys;
/// <summary>
/// Attribute describing a VirtualKey.

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.ClientState.Objects.Enums;
/// <summary>

View file

@ -83,16 +83,16 @@ internal sealed partial class ObjectTable : IServiceType, IObjectTable
}
/// <inheritdoc/>
public GameObject? SearchById(ulong objectId)
public GameObject? SearchById(ulong gameObjectId)
{
_ = this.WarnMultithreadedUsage();
if (objectId is GameObject.InvalidGameObjectId or 0)
if (gameObjectId is 0)
return null;
foreach (var e in this.cachedObjectTable)
{
if (e.Update() is { } o && o.ObjectId == objectId)
if (e.Update() is { } o && o.GameObjectId == gameObjectId)
return o;
}

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.Objects.Types;
namespace Dalamud.Game.ClientState.Objects.SubKinds;

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.Objects.Types;
namespace Dalamud.Game.ClientState.Objects.SubKinds;

View file

@ -21,15 +21,15 @@ public unsafe class PlayerCharacter : BattleChara
/// <summary>
/// Gets the current <see cref="ExcelResolver{T}">world</see> of the character.
/// </summary>
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> CurrentWorld => new(this.Struct->Character.CurrentWorld);
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> CurrentWorld => new(this.Struct->CurrentWorld);
/// <summary>
/// Gets the home <see cref="ExcelResolver{T}">world</see> of the character.
/// </summary>
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> HomeWorld => new(this.Struct->Character.HomeWorld);
public ExcelResolver<Lumina.Excel.GeneratedSheets.World> HomeWorld => new(this.Struct->HomeWorld);
/// <summary>
/// Gets the target actor ID of the PlayerCharacter.
/// </summary>
public override ulong TargetObjectId => this.Struct->Character.Gaze.Controller.GazesSpan[0].TargetInfo.TargetId;
public override ulong TargetObjectId => this.Struct->LookAt.Controller.Params[0].TargetParam.TargetId;
}

View file

@ -1,8 +1,7 @@
using System;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
#pragma warning disable CS0618
namespace Dalamud.Game.ClientState.Objects;

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.Statuses;
using Dalamud.Utility;
@ -23,37 +21,37 @@ public unsafe class BattleChara : Character
/// <summary>
/// Gets the current status effects.
/// </summary>
public StatusList StatusList => new(this.Struct->GetStatusManager);
public StatusList StatusList => new(this.Struct->GetStatusManager());
/// <summary>
/// Gets a value indicating whether the chara is currently casting.
/// </summary>
public bool IsCasting => this.Struct->GetCastInfo->IsCasting > 0;
public bool IsCasting => this.Struct->GetCastInfo()->IsCasting > 0;
/// <summary>
/// Gets a value indicating whether the cast is interruptible.
/// </summary>
public bool IsCastInterruptible => this.Struct->GetCastInfo->Interruptible > 0;
public bool IsCastInterruptible => this.Struct->GetCastInfo()->Interruptible > 0;
/// <summary>
/// Gets the spell action type of the spell being cast by the actor.
/// </summary>
public byte CastActionType => (byte)this.Struct->GetCastInfo->ActionType;
public byte CastActionType => (byte)this.Struct->GetCastInfo()->ActionType;
/// <summary>
/// Gets the spell action ID of the spell being cast by the actor.
/// </summary>
public uint CastActionId => this.Struct->GetCastInfo->ActionID;
public uint CastActionId => this.Struct->GetCastInfo()->ActionId;
/// <summary>
/// Gets the object ID of the target currently being cast at by the chara.
/// </summary>
public uint CastTargetObjectId => this.Struct->GetCastInfo->CastTargetID;
public ulong CastTargetObjectId => this.Struct->GetCastInfo()->CastTargetId;
/// <summary>
/// Gets the current casting time of the spell being cast by the chara.
/// </summary>
public float CurrentCastTime => this.Struct->GetCastInfo->CurrentCastTime;
public float CurrentCastTime => this.Struct->GetCastInfo()->CurrentCastTime;
/// <summary>
/// Gets the total casting time of the spell being cast by the chara.
@ -63,7 +61,7 @@ public unsafe class BattleChara : Character
/// Use AdjustedTotalCastTime if you always need the total cast time.
/// </remarks>
[Api10ToDo("Rename so it is not confused with AdjustedTotalCastTime")]
public float TotalCastTime => this.Struct->GetCastInfo->TotalCastTime;
public float TotalCastTime => this.Struct->GetCastInfo()->TotalCastTime;
/// <summary>
/// Gets the <see cref="TotalCastTime"/> plus any adjustments from the game, such as Action offset 2B. Used for display purposes.
@ -72,7 +70,7 @@ public unsafe class BattleChara : Character
/// This is the actual total cast time for all actions.
/// </remarks>
[Api10ToDo("Rename so it is not confused with TotalCastTime")]
public float AdjustedTotalCastTime => this.Struct->GetCastInfo->AdjustedTotalCastTime;
public float AdjustedTotalCastTime => this.Struct->GetCastInfo()->AdjustedTotalCastTime;
/// <summary>
/// Gets the underlying structure.

View file

@ -1,3 +1,5 @@
using System.Runtime.CompilerServices;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.ClientState.Resolvers;
using Dalamud.Game.Text.SeStringHandling;
@ -80,12 +82,12 @@ public unsafe class Character : GameObject
/// Gets a byte array describing the visual appearance of this Chara.
/// Indexed by <see cref="CustomizeIndex"/>.
/// </summary>
public byte[] Customize => MemoryHelper.Read<byte>((IntPtr)this.Struct->DrawData.CustomizeData.Data, 28);
public byte[] Customize => this.Struct->DrawData.CustomizeData.Data.ToArray();
/// <summary>
/// Gets the Free Company tag of this chara.
/// </summary>
public SeString CompanyTag => MemoryHelper.ReadSeString((IntPtr)this.Struct->FreeCompanyTag, 6);
public SeString CompanyTag => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->FreeCompanyTag[0]), 6);
/// <summary>
/// Gets the target object ID of the character.
@ -95,7 +97,7 @@ public unsafe class Character : GameObject
/// <summary>
/// Gets the name ID of the character.
/// </summary>
public uint NameId => this.Struct->NameID;
public uint NameId => this.Struct->NameId;
/// <summary>
/// Gets the current online status of the character.

View file

@ -1,5 +1,5 @@
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using Dalamud.Game.ClientState.Objects.Enums;
using Dalamud.Game.Text.SeStringHandling;
@ -12,11 +12,6 @@ namespace Dalamud.Game.ClientState.Objects.Types;
/// </summary>
public unsafe partial class GameObject : IEquatable<GameObject>
{
/// <summary>
/// IDs of non-networked GameObjects.
/// </summary>
public const uint InvalidGameObjectId = 0xE0000000;
/// <summary>
/// Initializes a new instance of the <see cref="GameObject"/> class.
/// </summary>
@ -79,13 +74,13 @@ public unsafe partial class GameObject : IEquatable<GameObject>
public bool IsValid() => IsValid(this);
/// <inheritdoc/>
bool IEquatable<GameObject>.Equals(GameObject other) => this.ObjectId == other?.ObjectId;
bool IEquatable<GameObject>.Equals(GameObject other) => this.GameObjectId == other?.GameObjectId;
/// <inheritdoc/>
public override bool Equals(object obj) => ((IEquatable<GameObject>)this).Equals(obj as GameObject);
/// <inheritdoc/>
public override int GetHashCode() => this.ObjectId.GetHashCode();
public override int GetHashCode() => this.GameObjectId.GetHashCode();
}
/// <summary>
@ -96,22 +91,32 @@ public unsafe partial class GameObject
/// <summary>
/// Gets the name of this <see cref="GameObject" />.
/// </summary>
public SeString Name => MemoryHelper.ReadSeString((IntPtr)this.Struct->Name, 64);
public SeString Name => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref this.Struct->Name[0]), 64);
/// <summary>
/// Gets the object ID of this <see cref="GameObject" />.
/// Gets the GameObjectID for this GameObject. The Game Object ID is a globally unique identifier that points to
/// this specific object. This ID is used to reference specific objects on the local client (e.g. for targeting).
///
/// Not to be confused with <see cref="EntityId"/>.
/// </summary>
public uint ObjectId => this.Struct->ObjectID;
public ulong GameObjectId => this.Struct->GetObjectId();
/// <summary>
/// Gets the Entity ID for this GameObject. Entity IDs are assigned to networked GameObjects.
///
/// A value of <c>0xE000_0000</c> indicates that this entity is not networked and has specific interactivity rules.
/// </summary>
public uint EntityId => this.Struct->EntityId;
/// <summary>
/// Gets the data ID for linking to other respective game data.
/// </summary>
public uint DataId => this.Struct->DataID;
public uint DataId => this.Struct->BaseId;
/// <summary>
/// Gets the ID of this GameObject's owner.
/// </summary>
public uint OwnerId => this.Struct->OwnerID;
public uint OwnerId => this.Struct->OwnerId;
/// <summary>
/// Gets the index of this object in the object table.
@ -185,5 +190,5 @@ public unsafe partial class GameObject
protected internal FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject* Struct => (FFXIVClientStructs.FFXIV.Client.Game.Object.GameObject*)this.Address;
/// <inheritdoc/>
public override string ToString() => $"{this.ObjectId:X}({this.Name.TextValue} - {this.ObjectKind}) at {this.Address:X}";
public override string ToString() => $"{this.GameObjectId:X}({this.Name.TextValue} - {this.ObjectKind}) at {this.Address:X}";
}

View file

@ -1,11 +1,12 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using Serilog;
namespace Dalamud.Game.ClientState.Party;
@ -50,10 +51,10 @@ internal sealed unsafe partial class PartyList : IServiceType, IPartyList
public IntPtr GroupManagerAddress => this.address.GroupManager;
/// <inheritdoc/>
public IntPtr GroupListAddress => (IntPtr)GroupManagerStruct->PartyMembers;
public IntPtr GroupListAddress => (IntPtr)Unsafe.AsPointer(ref GroupManagerStruct->PartyMembers[0]);
/// <inheritdoc/>
public IntPtr AllianceListAddress => (IntPtr)this.GroupManagerStruct->AllianceMembers;
public IntPtr AllianceListAddress => (IntPtr)Unsafe.AsPointer(ref this.GroupManagerStruct->AllianceMembers[0]);
/// <inheritdoc/>
public long PartyId => this.GroupManagerStruct->PartyId;

View file

@ -1,5 +1,5 @@
using System;
using System.Numerics;
using System.Runtime.CompilerServices;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types;
@ -42,12 +42,12 @@ public unsafe class PartyMember
/// <summary>
/// Gets the content ID of the party member.
/// </summary>
public long ContentId => this.Struct->ContentID;
public long ContentId => (long)this.Struct->ContentId;
/// <summary>
/// Gets the actor ID of this party member.
/// </summary>
public uint ObjectId => this.Struct->ObjectID;
public uint ObjectId => this.Struct->EntityId;
/// <summary>
/// Gets the actor associated with this buddy.
@ -90,7 +90,7 @@ public unsafe class PartyMember
/// <summary>
/// Gets the displayname of this party member.
/// </summary>
public SeString Name => MemoryHelper.ReadSeString((IntPtr)Struct->Name, 0x40);
public SeString Name => MemoryHelper.ReadSeString((nint)Unsafe.AsPointer(ref Struct->Name[0]), 0x40);
/// <summary>
/// Gets the sex of this party member.

View file

@ -1,4 +1,5 @@
using Dalamud.Data;
using Lumina.Excel;
namespace Dalamud.Game.ClientState.Resolvers;

View file

@ -1,5 +1,3 @@
using System;
using Dalamud.Game.ClientState.Objects;
using Dalamud.Game.ClientState.Objects.Types;
using Dalamud.Game.ClientState.Resolvers;
@ -28,12 +26,12 @@ public unsafe class Status
/// <summary>
/// Gets the status ID of this status.
/// </summary>
public uint StatusId => this.Struct->StatusID;
public uint StatusId => this.Struct->StatusId;
/// <summary>
/// Gets the GameData associated with this status.
/// </summary>
public Lumina.Excel.GeneratedSheets.Status GameData => new ExcelResolver<Lumina.Excel.GeneratedSheets.Status>(this.Struct->StatusID).GameData;
public Lumina.Excel.GeneratedSheets.Status GameData => new ExcelResolver<Lumina.Excel.GeneratedSheets.Status>(this.Struct->StatusId).GameData;
/// <summary>
/// Gets the parameter value of the status.
@ -53,7 +51,7 @@ public unsafe class Status
/// <summary>
/// Gets the source ID of this status.
/// </summary>
public uint SourceId => this.Struct->SourceID;
public uint SourceId => this.Struct->SourceId;
/// <summary>
/// Gets the source actor associated with this status.

View file

@ -1,6 +1,6 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
namespace Dalamud.Game.ClientState.Statuses;
@ -99,16 +99,16 @@ public sealed unsafe partial class StatusList
}
/// <summary>
/// Gets the address of the party member at the specified index of the party list.
/// Gets the address of the status at the specific index in the status list.
/// </summary>
/// <param name="index">The index of the party member.</param>
/// <returns>The memory address of the party member.</returns>
/// <param name="index">The index of the status.</param>
/// <returns>The memory address of the status.</returns>
public IntPtr GetStatusAddress(int index)
{
if (index < 0 || index >= this.Length)
return IntPtr.Zero;
return (IntPtr)(this.Struct->Status + (index * StatusSize));
return (IntPtr)Unsafe.AsPointer(ref this.Struct->Status[index]);
}
}

View file

@ -1,5 +1,3 @@
using System.Reflection;
namespace Dalamud.Game.Command;
/// <summary>

View file

@ -135,9 +135,9 @@ internal sealed class CommandManager : IInternalDisposableService, ICommandManag
this.chatGui.CheckMessageHandled -= this.OnCheckMessageHandled;
}
private void OnCheckMessageHandled(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
private void OnCheckMessageHandled(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
{
if (type == XivChatType.ErrorMessage && senderId == 0)
if (type == XivChatType.ErrorMessage && timestamp == 0)
{
var cmdMatch = this.currentLangCommandRegex.Match(message.TextValue).Groups["command"];
if (cmdMatch.Success)

View file

@ -1,6 +1,4 @@
using System;
namespace Dalamud.Game.Config;
namespace Dalamud.Game.Config;
public abstract record ConfigChangeEvent(Enum Option);

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.Config;
/// <summary>

View file

@ -34,7 +34,7 @@ internal sealed class GameConfig : IInternalDisposableService, IGameConfig
{
Log.Verbose("[GameConfig] Initializing");
var csFramework = FFXIVClientStructs.FFXIV.Client.System.Framework.Framework.Instance();
var commonConfig = &csFramework->SystemConfig.CommonSystemConfig;
var commonConfig = &csFramework->SystemConfig.SystemConfigBase;
this.tcsSystem.SetResult(new("System", framework, &commonConfig->ConfigBase));
this.tcsUiConfig.SetResult(new("UiConfig", framework, &commonConfig->UiConfig));
this.tcsUiControl.SetResult(

View file

@ -1,7 +1,3 @@
using System;
using FFXIVClientStructs.FFXIV.Common.Configuration;
namespace Dalamud.Game.Config;
/// <summary>

View file

@ -1,7 +1,3 @@
using System;
using FFXIVClientStructs.FFXIV.Common.Configuration;
namespace Dalamud.Game.Config;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game;
/// <summary>

View file

@ -12,7 +12,6 @@ using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Logging.Internal;
using Dalamud.Memory;
using Dalamud.Plugin.Internal;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.System.String;
@ -20,11 +19,6 @@ using FFXIVClientStructs.FFXIV.Client.UI.Misc;
namespace Dalamud.Game.Gui;
// TODO(api10): Update IChatGui, ChatGui and XivChatEntry to use correct types and names:
// "uint SenderId" should be "int Timestamp".
// "IntPtr Parameters" should be something like "bool Silent". It suppresses new message sounds in certain channels.
// This has to be a 1 byte boolean, so only change it to bool if marshalling is disabled.
/// <summary>
/// This class handles interacting with the native chat UI.
/// </summary>
@ -179,7 +173,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
var sender = Utf8String.FromSequence(chat.Name.Encode());
var message = Utf8String.FromSequence(replacedMessage.BuiltString.Encode());
this.HandlePrintMessageDetour(RaptureLogModule.Instance(), chat.Type, sender, message, (int)chat.SenderId, (byte)(chat.Parameters != 0 ? 1 : 0));
this.HandlePrintMessageDetour(RaptureLogModule.Instance(), chat.Type, sender, message, chat.Timestamp, (byte)(chat.Silent ? 1 : 0));
sender->Dtor(true);
message->Dtor(true);
@ -321,7 +315,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
try
{
var messageHandledDelegate = @delegate as IChatGui.OnCheckMessageHandledDelegate;
messageHandledDelegate!.Invoke(chatType, (uint)timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
messageHandledDelegate!.Invoke(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
}
catch (Exception e)
{
@ -337,7 +331,7 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
try
{
var messageHandledDelegate = @delegate as IChatGui.OnMessageDelegate;
messageHandledDelegate!.Invoke(chatType, (uint)timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
messageHandledDelegate!.Invoke(chatType, timestamp, ref parsedSender, ref parsedMessage, ref isHandled);
}
catch (Exception e)
{
@ -364,12 +358,12 @@ internal sealed unsafe class ChatGui : IInternalDisposableService, IChatGui
// Print the original chat if it's handled.
if (isHandled)
{
this.ChatMessageHandled?.Invoke(chatType, (uint)timestamp, parsedSender, parsedMessage);
this.ChatMessageHandled?.Invoke(chatType, timestamp, parsedSender, parsedMessage);
}
else
{
messageId = this.printMessageHook.Original(manager, chatType, sender, message, timestamp, silent);
this.ChatMessageUnhandled?.Invoke(chatType, (uint)timestamp, parsedSender, parsedMessage);
this.ChatMessageUnhandled?.Invoke(chatType, timestamp, parsedSender, parsedMessage);
}
}
catch (Exception ex)
@ -501,15 +495,15 @@ internal class ChatGuiPluginScoped : IInternalDisposableService, IChatGui
public void PrintError(SeString message, string? messageTag = null, ushort? tagColor = null)
=> this.chatGuiService.PrintError(message, messageTag, tagColor);
private void OnMessageForward(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.ChatMessage?.Invoke(type, senderId, ref sender, ref message, ref isHandled);
private void OnMessageForward(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.ChatMessage?.Invoke(type, timestamp, ref sender, ref message, ref isHandled);
private void OnCheckMessageForward(XivChatType type, uint senderId, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.CheckMessageHandled?.Invoke(type, senderId, ref sender, ref message, ref isHandled);
private void OnCheckMessageForward(XivChatType type, int timestamp, ref SeString sender, ref SeString message, ref bool isHandled)
=> this.CheckMessageHandled?.Invoke(type, timestamp, ref sender, ref message, ref isHandled);
private void OnMessageHandledForward(XivChatType type, uint senderId, SeString sender, SeString message)
=> this.ChatMessageHandled?.Invoke(type, senderId, sender, message);
private void OnMessageHandledForward(XivChatType type, int timestamp, SeString sender, SeString message)
=> this.ChatMessageHandled?.Invoke(type, timestamp, sender, message);
private void OnMessageUnhandledForward(XivChatType type, uint senderId, SeString sender, SeString message)
=> this.ChatMessageUnhandled?.Invoke(type, senderId, sender, message);
private void OnMessageUnhandledForward(XivChatType type, int timestamp, SeString sender, SeString message)
=> this.ChatMessageUnhandled?.Invoke(type, timestamp, sender, message);
}

View file

@ -17,6 +17,7 @@ using FFXIVClientStructs.FFXIV.Client.System.Memory;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
using FFXIVClientStructs.FFXIV.Component.GUI.AtkModuleInterface;
using FFXIVClientStructs.Interop;
using ValueType = FFXIVClientStructs.FFXIV.Component.GUI.ValueType;
@ -40,7 +41,7 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
private ContextMenu()
{
this.raptureAtkModuleOpenAddonByAgentHook = Hook<RaptureAtkModuleOpenAddonByAgentDelegate>.FromAddress((nint)RaptureAtkModule.Addresses.OpenAddonByAgent.Value, this.RaptureAtkModuleOpenAddonByAgentDetour);
this.addonContextMenuOnMenuSelectedHook = Hook<AddonContextMenuOnMenuSelectedDelegate>.FromAddress((nint)AddonContextMenu.StaticVTable.OnMenuSelected, this.AddonContextMenuOnMenuSelectedDetour);
this.addonContextMenuOnMenuSelectedHook = Hook<AddonContextMenuOnMenuSelectedDelegate>.FromAddress((nint)AddonContextMenu.StaticVirtualTablePointer->OnMenuSelected, this.AddonContextMenuOnMenuSelectedDetour);
this.raptureAtkModuleOpenAddon = Marshal.GetDelegateForFunctionPointer<RaptureAtkModuleOpenAddonDelegate>((nint)RaptureAtkModule.Addresses.OpenAddon.Value);
this.raptureAtkModuleOpenAddonByAgentHook.Enable();
@ -268,11 +269,15 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
foreach (var item in items)
{
if (!item.Prefix.HasValue && !item.UseDefaultPrefix)
if (!item.Prefix.HasValue)
{
item.Prefix = MenuItem.DalamudDefaultPrefix;
item.PrefixColor = MenuItem.DalamudDefaultPrefixColor;
Log.Warning($"Menu item \"{item.Name}\" has no prefix, defaulting to Dalamud's. Menu items outside of a submenu must have a prefix.");
if (!item.UseDefaultPrefix)
{
Log.Warning($"Menu item \"{item.Name}\" has no prefix, defaulting to Dalamud's. Menu items outside of a submenu must have a prefix.");
}
}
}
@ -312,8 +317,8 @@ internal sealed unsafe class ContextMenu : IInternalDisposableService, IContextM
this.SelectedMenuType = ContextMenuType.Default;
var menu = AgentContext.Instance()->CurrentContextMenu;
var handlers = new Span<Pointer<AtkEventInterface>>(menu->EventHandlerArray, 32);
var ids = new Span<byte>(menu->EventIdArray, 32);
var handlers = menu->EventHandlers;
var ids = menu->EventIds;
var count = (int)values[0].UInt;
handlers = handlers.Slice(7, count);
ids = ids.Slice(7, count);

View file

@ -24,7 +24,7 @@ public abstract unsafe class MenuArgs
/// <param name="eventInterfaces">List of AtkEventInterfaces associated with the context menu.</param>
protected internal MenuArgs(AtkUnitBase* addon, AgentInterface* agent, ContextMenuType type, IReadOnlySet<nint>? eventInterfaces)
{
this.AddonName = addon != null ? MemoryHelper.ReadString((nint)addon->Name, 32) : null;
this.AddonName = addon != null ? addon->NameString : null;
this.AddonPtr = (nint)addon;
this.AgentPtr = (nint)agent;
this.MenuType = type;

View file

@ -2,6 +2,7 @@ using System.Collections.Generic;
using Dalamud.Game.Text.SeStringHandling;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Gui.ContextMenu;

View file

@ -1,5 +1,6 @@
using System.Collections.Generic;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Gui.ContextMenu;

View file

@ -11,6 +11,7 @@ using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Logging.Internal;
using Dalamud.Plugin.Services;
using FFXIVClientStructs.FFXIV.Client.Graphics;
using FFXIVClientStructs.FFXIV.Client.System.Memory;
using FFXIVClientStructs.FFXIV.Component.GUI;
@ -73,13 +74,16 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
this.configuration.QueueSave();
}
/// <inheritdoc/>
public IReadOnlyList<IReadOnlyDtrBarEntry> Entries => this.entries;
/// <inheritdoc/>
public DtrBarEntry Get(string title, SeString? text = null)
{
if (this.entries.Any(x => x.Title == title) || this.newEntries.Any(x => x.Title == title))
throw new ArgumentException("An entry with the same title already exists.");
var entry = new DtrBarEntry(title, null);
var entry = new DtrBarEntry(this.configuration, title, null);
entry.Text = text;
// Add the entry to the end of the order list, if it's not there already.
@ -196,7 +200,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
foreach (var data in this.entries)
{
var isHide = this.configuration.DtrIgnore!.Any(x => x == data.Title) || !data.Shown;
var isHide = data.UserHidden || !data.Shown;
if (data is { Dirty: true, Added: true, Text: not null, TextNode: not null })
{
@ -272,7 +276,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
var node = addon->UldManager.NodeList[index];
if (node->IsVisible)
{
var nodeId = node->NodeID;
var nodeId = node->NodeId;
var nodeType = node->Type;
if (nodeType == NodeType.Collision)
@ -326,7 +330,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
for (var i = 0; i < dtr->UldManager.NodeListCount; i++)
{
if (dtr->UldManager.NodeList[i]->NodeID > 1000)
if (dtr->UldManager.NodeList[i]->NodeId > 1000)
return true;
}
@ -353,8 +357,8 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
var dtr = this.GetDtr();
if (dtr == null || dtr->RootNode == null || dtr->UldManager.NodeList == null || node == null) return false;
this.eventHandles.TryAdd(node->AtkResNode.NodeID, new List<IAddonEventHandle>());
this.eventHandles[node->AtkResNode.NodeID].AddRange(new List<IAddonEventHandle>
this.eventHandles.TryAdd(node->AtkResNode.NodeId, new List<IAddonEventHandle>());
this.eventHandles[node->AtkResNode.NodeId].AddRange(new List<IAddonEventHandle>
{
this.uiEventManager.AddEvent(AddonEventManager.DalamudInternalKey, (nint)dtr, (nint)node, AddonEventType.MouseOver, this.DtrEventHandler),
this.uiEventManager.AddEvent(AddonEventManager.DalamudInternalKey, (nint)dtr, (nint)node, AddonEventType.MouseOut, this.DtrEventHandler),
@ -382,8 +386,8 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
var dtr = this.GetDtr();
if (dtr == null || dtr->RootNode == null || dtr->UldManager.NodeList == null || node == null) return;
this.eventHandles[node->AtkResNode.NodeID].ForEach(handle => this.uiEventManager.RemoveEvent(AddonEventManager.DalamudInternalKey, handle));
this.eventHandles[node->AtkResNode.NodeID].Clear();
this.eventHandles[node->AtkResNode.NodeId].ForEach(handle => this.uiEventManager.RemoveEvent(AddonEventManager.DalamudInternalKey, handle));
this.eventHandles[node->AtkResNode.NodeId].Clear();
var tmpPrevNode = node->AtkResNode.PrevSiblingNode;
var tmpNextNode = node->AtkResNode.NextSiblingNode;
@ -410,7 +414,7 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
return null;
}
newTextNode->AtkResNode.NodeID = nodeId;
newTextNode->AtkResNode.NodeId = nodeId;
newTextNode->AtkResNode.Type = NodeType.Text;
newTextNode->AtkResNode.NodeFlags = NodeFlags.AnchorLeft | NodeFlags.AnchorTop | NodeFlags.Enabled | NodeFlags.RespondToMouse | NodeFlags.HasCollision | NodeFlags.EmitsEvents;
newTextNode->AtkResNode.DrawFlags = 12;
@ -455,11 +459,11 @@ internal sealed unsafe class DtrBar : IInternalDisposableService, IDtrBar
switch (atkEventType)
{
case AddonEventType.MouseOver:
AtkStage.GetSingleton()->TooltipManager.ShowTooltip(addon->ID, node, dtrBarEntry.Tooltip.Encode());
AtkStage.Instance()->TooltipManager.ShowTooltip(addon->Id, node, dtrBarEntry.Tooltip.Encode());
break;
case AddonEventType.MouseOut:
AtkStage.GetSingleton()->TooltipManager.HideTooltip(addon->ID);
AtkStage.Instance()->TooltipManager.HideTooltip(addon->Id);
break;
}
}
@ -499,6 +503,9 @@ internal class DtrBarPluginScoped : IInternalDisposableService, IDtrBar
private readonly DtrBar dtrBarService = Service<DtrBar>.Get();
private readonly Dictionary<string, DtrBarEntry> pluginEntries = new();
/// <inheritdoc/>
public IReadOnlyList<IReadOnlyDtrBarEntry> Entries => this.dtrBarService.Entries;
/// <inheritdoc/>
void IInternalDisposableService.DisposeService()
@ -510,7 +517,7 @@ internal class DtrBarPluginScoped : IInternalDisposableService, IDtrBar
this.pluginEntries.Clear();
}
/// <inheritdoc/>
public DtrBarEntry Get(string title, SeString? text = null)
{

View file

@ -1,37 +1,114 @@
using System;
using System.Linq;
using Dalamud.Configuration.Internal;
using Dalamud.Game.Text.SeStringHandling;
using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Component.GUI;
namespace Dalamud.Game.Gui.Dtr;
/// <summary>
/// Interface representing a read-only entry in the server info bar.
/// </summary>
public interface IReadOnlyDtrBarEntry
{
/// <summary>
/// Gets the title of this entry.
/// </summary>
public string Title { get; }
/// <summary>
/// Gets a value indicating whether this entry has a click action.
/// </summary>
public bool HasClickAction { get; }
/// <summary>
/// Gets the text of this entry.
/// </summary>
public SeString Text { get; }
/// <summary>
/// Gets a tooltip to be shown when the user mouses over the dtr entry.
/// </summary>
public SeString Tooltip { get; }
/// <summary>
/// Gets a value indicating whether this entry should be shown.
/// </summary>
public bool Shown { get; }
/// <summary>
/// Gets a value indicating whether or not the user has hidden this entry from view through the Dalamud settings.
/// </summary>
public bool UserHidden { get; }
/// <summary>
/// Triggers the click action of this entry.
/// </summary>
/// <returns>True, if a click action was registered and executed.</returns>
public bool TriggerClickAction();
}
/// <summary>
/// Interface representing an entry in the server info bar.
/// </summary>
public interface IDtrBarEntry : IReadOnlyDtrBarEntry
{
/// <summary>
/// Gets or sets the text of this entry.
/// </summary>
public new SeString? Text { get; set; }
/// <summary>
/// Gets or sets a tooltip to be shown when the user mouses over the dtr entry.
/// </summary>
public new SeString? Tooltip { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this entry is visible.
/// </summary>
public new bool Shown { get; set; }
/// <summary>
/// Gets or sets a action to be invoked when the user clicks on the dtr entry.
/// </summary>
public Action? OnClick { get; set; }
/// <summary>
/// Remove this entry from the bar.
/// You will need to re-acquire it from DtrBar to reuse it.
/// </summary>
public void Remove();
}
/// <summary>
/// Class representing an entry in the server info bar.
/// </summary>
public sealed unsafe class DtrBarEntry : IDisposable
public sealed unsafe class DtrBarEntry : IDisposable, IDtrBarEntry
{
private readonly DalamudConfiguration configuration;
private bool shownBacking = true;
private SeString? textBacking = null;
private SeString? textBacking;
/// <summary>
/// Initializes a new instance of the <see cref="DtrBarEntry"/> class.
/// </summary>
/// <param name="configuration">Dalamud configuration, used to check if the entry is hidden by the user.</param>
/// <param name="title">The title of the bar entry.</param>
/// <param name="textNode">The corresponding text node.</param>
internal DtrBarEntry(string title, AtkTextNode* textNode)
internal DtrBarEntry(DalamudConfiguration configuration, string title, AtkTextNode* textNode)
{
this.configuration = configuration;
this.Title = title;
this.TextNode = textNode;
}
/// <summary>
/// Gets the title of this entry.
/// </summary>
/// <inheritdoc/>
public string Title { get; init; }
/// <summary>
/// Gets or sets the text of this entry.
/// </summary>
/// <inheritdoc cref="IDtrBarEntry.Text" />
public SeString? Text
{
get => this.textBacking;
@ -41,10 +118,8 @@ public sealed unsafe class DtrBarEntry : IDisposable
this.Dirty = true;
}
}
/// <summary>
/// Gets or sets a tooltip to be shown when the user mouses over the dtr entry.
/// </summary>
/// <inheritdoc cref="IDtrBarEntry.Tooltip" />
public SeString? Tooltip { get; set; }
/// <summary>
@ -52,9 +127,10 @@ public sealed unsafe class DtrBarEntry : IDisposable
/// </summary>
public Action? OnClick { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this entry is visible.
/// </summary>
/// <inheritdoc/>
public bool HasClickAction => this.OnClick != null;
/// <inheritdoc cref="IDtrBarEntry.Shown" />
public bool Shown
{
get => this.shownBacking;
@ -65,6 +141,10 @@ public sealed unsafe class DtrBarEntry : IDisposable
}
}
/// <inheritdoc/>
[Api10ToDo("Maybe make this config scoped to internalname?")]
public bool UserHidden => this.configuration.DtrIgnore?.Any(x => x == this.Title) ?? false;
/// <summary>
/// Gets or sets the internal text node of this entry.
/// </summary>
@ -73,17 +153,27 @@ public sealed unsafe class DtrBarEntry : IDisposable
/// <summary>
/// Gets a value indicating whether this entry should be removed.
/// </summary>
internal bool ShouldBeRemoved { get; private set; } = false;
internal bool ShouldBeRemoved { get; private set; }
/// <summary>
/// Gets or sets a value indicating whether this entry is dirty.
/// </summary>
internal bool Dirty { get; set; } = false;
internal bool Dirty { get; set; }
/// <summary>
/// Gets or sets a value indicating whether this entry has just been added.
/// </summary>
internal bool Added { get; set; } = false;
internal bool Added { get; set; }
/// <inheritdoc/>
public bool TriggerClickAction()
{
if (this.OnClick == null)
return false;
this.OnClick.Invoke();
return true;
}
/// <summary>
/// Remove this entry from the bar.

View file

@ -7,6 +7,7 @@ using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Memory;
using Dalamud.Plugin.Services;
using Serilog;
namespace Dalamud.Game.Gui.FlyText;

View file

@ -12,6 +12,7 @@ using Dalamud.Utility;
using FFXIVClientStructs.FFXIV.Client.Graphics.Kernel;
using FFXIVClientStructs.FFXIV.Client.System.String;
using FFXIVClientStructs.FFXIV.Client.UI;
using FFXIVClientStructs.FFXIV.Client.UI.Agent;
using FFXIVClientStructs.FFXIV.Common.Component.BGCollision;
using FFXIVClientStructs.FFXIV.Component.GUI;
using ImGuiNET;
@ -272,7 +273,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
if (framework == null)
return IntPtr.Zero;
var uiModule = framework->GetUiModule();
var uiModule = framework->GetUIModule();
if (uiModule == null)
return IntPtr.Zero;
@ -282,7 +283,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
/// <inheritdoc/>
public IntPtr GetAddonByName(string name, int index = 1)
{
var atkStage = AtkStage.GetSingleton();
var atkStage = AtkStage.Instance();
if (atkStage == null)
return IntPtr.Zero;
@ -322,7 +323,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
return IntPtr.Zero;
var addon = (AtkUnitBase*)addonPtr;
var addonId = addon->ParentID == 0 ? addon->ID : addon->ParentID;
var addonId = addon->ParentId == 0 ? addon->Id : addon->ParentId;
if (addonId == 0)
return IntPtr.Zero;
@ -330,7 +331,7 @@ internal sealed unsafe class GameGui : IInternalDisposableService, IGameGui
var index = 0;
while (true)
{
var agent = agentModule->GetAgentByInternalID((uint)index++);
var agent = agentModule->GetAgentByInternalId((AgentId)index++);
if (agent == uiModule || agent == null)
break;

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.Gui;
/// <summary>

View file

@ -6,6 +6,7 @@ using Dalamud.Hooking;
using Dalamud.IoC;
using Dalamud.IoC.Internal;
using Dalamud.Plugin.Services;
using Serilog;
namespace Dalamud.Game.Gui.PartyFinder;

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.Gui.PartyFinder.Types;
/// <summary>

View file

@ -11,9 +11,9 @@ public enum DutyCategory
Duty = 0,
/// <summary>
/// The quest battle category.
/// The gold saucer category.
/// </summary>
QuestBattles = 1 << 0,
GoldSaucer = 1 << 0,
/// <summary>
/// The fate category.
@ -43,5 +43,16 @@ public enum DutyCategory
/// <summary>
/// The adventuring forays category.
/// </summary>
[Obsolete("Adventuring Forays have been renamed to Field Operations")]
AdventuringForays = 1 << 6,
/// <summary>
/// The field operations category.
/// </summary>
FieldOperations = 1 << 6,
/// <summary>
/// The variant and criterion dungeons category.
/// </summary>
VariantAndCriterionDungeons = 1 << 7,
}

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.Gui.PartyFinder.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.Gui.PartyFinder.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.Gui.PartyFinder.Types;
/// <summary>

View file

@ -1,5 +1,3 @@
using System;
namespace Dalamud.Game.Gui.PartyFinder.Types;
/// <summary>

View file

@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Dalamud.Data;
using Dalamud.Game.Gui.PartyFinder.Internal;
using Dalamud.Game.Text.SeStringHandling;
using Lumina.Excel.GeneratedSheets;
namespace Dalamud.Game.Gui.PartyFinder.Types;

View file

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;

Some files were not shown because too many files have changed in this diff Show more