mirror of
https://github.com/goatcorp/Dalamud.git
synced 2026-01-02 05:43:40 +01:00
Merge remote-tracking branch 'origin/master' into v9-rollup
This commit is contained in:
commit
5da34cbc81
91 changed files with 3849 additions and 1089 deletions
|
|
@ -21,6 +21,7 @@ using Dalamud.Interface.Internal;
|
|||
using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
using Dalamud.Plugin.Internal;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
using Dalamud.Plugin.Ipc;
|
||||
using Dalamud.Plugin.Ipc.Exceptions;
|
||||
using Dalamud.Plugin.Ipc.Internal;
|
||||
|
|
@ -208,7 +209,7 @@ public sealed class DalamudPluginInterface : IDisposable
|
|||
/// <summary>
|
||||
/// Gets a list of installed plugins along with their current state.
|
||||
/// </summary>
|
||||
public IEnumerable<InstalledPluginState> InstalledPlugins => Service<PluginManager>.Get().InstalledPlugins.Select(p => new InstalledPluginState(p.Name, p.Manifest.InternalName, p.IsLoaded, p.Manifest.EffectiveVersion));
|
||||
public IEnumerable<InstalledPluginState> InstalledPlugins => Service<PluginManager>.Get().InstalledPlugins.Select(p => new InstalledPluginState(p.Name, p.Manifest.InternalName, p.IsLoaded, p.EffectiveVersion));
|
||||
|
||||
/// <summary>
|
||||
/// Opens the <see cref="PluginInstallerWindow"/> with the plugin name set as search target.
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ using Dalamud.Networking.Http;
|
|||
using Dalamud.Plugin.Internal.Exceptions;
|
||||
using Dalamud.Plugin.Internal.Profiles;
|
||||
using Dalamud.Plugin.Internal.Types;
|
||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
using Dalamud.Plugin.Ipc.Internal;
|
||||
using Dalamud.Utility;
|
||||
using Dalamud.Utility.Timing;
|
||||
|
|
@ -247,7 +248,7 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
/// </summary>
|
||||
/// <param name="manifest">The manifest to test.</param>
|
||||
/// <returns>Whether or not a testing version is available.</returns>
|
||||
public static bool HasTestingVersion(PluginManifest manifest)
|
||||
public static bool HasTestingVersion(IPluginManifest manifest)
|
||||
{
|
||||
var av = manifest.AssemblyVersion;
|
||||
var tv = manifest.TestingAssemblyVersion;
|
||||
|
|
@ -317,7 +318,7 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
/// </summary>
|
||||
/// <param name="manifest">Manifest to check.</param>
|
||||
/// <returns>A value indicating whether testing should be used.</returns>
|
||||
public bool HasTestingOptIn(PluginManifest manifest)
|
||||
public bool HasTestingOptIn(IPluginManifest manifest)
|
||||
{
|
||||
return this.configuration.PluginTestingOptIns!.Any(x => x.InternalName == manifest.InternalName);
|
||||
}
|
||||
|
|
@ -328,7 +329,7 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
/// </summary>
|
||||
/// <param name="manifest">Manifest to check.</param>
|
||||
/// <returns>A value indicating whether testing should be used.</returns>
|
||||
public bool UseTesting(PluginManifest manifest)
|
||||
public bool UseTesting(IPluginManifest manifest)
|
||||
{
|
||||
if (!this.configuration.DoPluginTest)
|
||||
return false;
|
||||
|
|
@ -746,8 +747,9 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
/// <param name="repoManifest">The plugin definition.</param>
|
||||
/// <param name="useTesting">If the testing version should be used.</param>
|
||||
/// <param name="reason">The reason this plugin was loaded.</param>
|
||||
/// <param name="inheritedWorkingPluginId">WorkingPluginId this plugin should inherit.</param>
|
||||
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
|
||||
public async Task<LocalPlugin> InstallPluginAsync(RemotePluginManifest repoManifest, bool useTesting, PluginLoadReason reason)
|
||||
public async Task<LocalPlugin> InstallPluginAsync(RemotePluginManifest repoManifest, bool useTesting, PluginLoadReason reason, Guid? inheritedWorkingPluginId = null)
|
||||
{
|
||||
Log.Debug($"Installing plugin {repoManifest.Name} (testing={useTesting})");
|
||||
|
||||
|
|
@ -834,6 +836,9 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
// Reload as a local manifest, add some attributes, and save again.
|
||||
var manifest = LocalPluginManifest.Load(manifestFile);
|
||||
|
||||
if (manifest == null)
|
||||
throw new Exception("Plugin had no valid manifest");
|
||||
|
||||
if (manifest.InternalName != repoManifest.InternalName)
|
||||
{
|
||||
Directory.Delete(outputDir.FullName, true);
|
||||
|
|
@ -841,6 +846,11 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
$"Distributed internal name does not match repo internal name: {manifest.InternalName} - {repoManifest.InternalName}");
|
||||
}
|
||||
|
||||
if (manifest.WorkingPluginId != Guid.Empty)
|
||||
throw new Exception("Plugin shall not specify a WorkingPluginId");
|
||||
|
||||
manifest.WorkingPluginId = inheritedWorkingPluginId ?? Guid.NewGuid();
|
||||
|
||||
if (useTesting)
|
||||
{
|
||||
manifest.Testing = true;
|
||||
|
|
@ -849,7 +859,7 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
// Document the url the plugin was installed from
|
||||
manifest.InstalledFromUrl = repoManifest.SourceRepo.IsThirdParty ? repoManifest.SourceRepo.PluginMasterUrl : LocalPluginManifest.FlagMainRepo;
|
||||
|
||||
manifest.Save(manifestFile);
|
||||
manifest.Save(manifestFile, "installation");
|
||||
|
||||
Log.Information($"Installed plugin {manifest.Name} (testing={useTesting})");
|
||||
|
||||
|
|
@ -1023,6 +1033,10 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
{
|
||||
var plugin = metadata.InstalledPlugin;
|
||||
|
||||
var workingPluginId = metadata.InstalledPlugin.Manifest.WorkingPluginId;
|
||||
if (workingPluginId == Guid.Empty)
|
||||
throw new Exception("Existing plugin had no WorkingPluginId");
|
||||
|
||||
var updateStatus = new PluginUpdateStatus
|
||||
{
|
||||
InternalName = plugin.Manifest.InternalName,
|
||||
|
|
@ -1082,7 +1096,7 @@ internal partial class PluginManager : IDisposable, IServiceType
|
|||
|
||||
try
|
||||
{
|
||||
await this.InstallPluginAsync(metadata.UpdateManifest, metadata.UseTesting, PluginLoadReason.Update);
|
||||
await this.InstallPluginAsync(metadata.UpdateManifest, metadata.UseTesting, PluginLoadReason.Update, workingPluginId);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -219,7 +219,7 @@ internal class Profile
|
|||
{
|
||||
if (!this.IsDefaultProfile)
|
||||
{
|
||||
await this.manager.DefaultProfile.AddOrUpdateAsync(internalName, entry.IsEnabled, false);
|
||||
await this.manager.DefaultProfile.AddOrUpdateAsync(internalName, this.IsEnabled && entry.IsEnabled, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ using System.Threading.Tasks;
|
|||
using Dalamud.Configuration.Internal;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@ using Dalamud.Game.Gui.Dtr;
|
|||
using Dalamud.Interface.GameFonts;
|
||||
using Dalamud.Interface.Internal;
|
||||
using Dalamud.IoC.Internal;
|
||||
using Dalamud.Logging;
|
||||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Plugin.Internal.Exceptions;
|
||||
using Dalamud.Plugin.Internal.Loader;
|
||||
using Dalamud.Plugin.Internal.Profiles;
|
||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
using Dalamud.Utility;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
|
@ -39,6 +39,8 @@ internal class LocalPlugin : IDisposable
|
|||
private Type? pluginType;
|
||||
private IDalamudPlugin? instance;
|
||||
|
||||
private LocalPluginManifest manifest;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="LocalPlugin"/> class.
|
||||
/// </summary>
|
||||
|
|
@ -111,7 +113,7 @@ internal class LocalPlugin : IDisposable
|
|||
// If the parameter manifest was null
|
||||
if (manifest == null)
|
||||
{
|
||||
this.Manifest = new LocalPluginManifest()
|
||||
this.manifest = new LocalPluginManifest()
|
||||
{
|
||||
Author = "developer",
|
||||
Name = Path.GetFileNameWithoutExtension(this.DllFile.Name),
|
||||
|
|
@ -125,36 +127,51 @@ internal class LocalPlugin : IDisposable
|
|||
|
||||
// Save the manifest to disk so there won't be any problems later.
|
||||
// We'll update the name property after it can be retrieved from the instance.
|
||||
this.Manifest.Save(this.manifestFile);
|
||||
this.manifest.Save(this.manifestFile, "manifest was null");
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Manifest = manifest;
|
||||
this.manifest = manifest;
|
||||
}
|
||||
|
||||
var needsSaveDueToLegacyFiles = false;
|
||||
|
||||
// This converts from the ".disabled" file feature to the manifest instead.
|
||||
this.disabledFile = LocalPluginManifest.GetDisabledFile(this.DllFile);
|
||||
if (this.disabledFile.Exists)
|
||||
{
|
||||
#pragma warning disable CS0618
|
||||
this.Manifest.Disabled = true;
|
||||
this.manifest.Disabled = true;
|
||||
#pragma warning restore CS0618
|
||||
this.disabledFile.Delete();
|
||||
|
||||
needsSaveDueToLegacyFiles = true;
|
||||
}
|
||||
|
||||
// This converts from the ".testing" file feature to the manifest instead.
|
||||
this.testingFile = LocalPluginManifest.GetTestingFile(this.DllFile);
|
||||
if (this.testingFile.Exists)
|
||||
{
|
||||
this.Manifest.Testing = true;
|
||||
this.manifest.Testing = true;
|
||||
this.testingFile.Delete();
|
||||
|
||||
needsSaveDueToLegacyFiles = true;
|
||||
}
|
||||
|
||||
// Create an installation instance ID for this plugin, if it doesn't have one yet
|
||||
if (this.manifest.WorkingPluginId == Guid.Empty)
|
||||
{
|
||||
this.manifest.WorkingPluginId = Guid.NewGuid();
|
||||
|
||||
needsSaveDueToLegacyFiles = true;
|
||||
}
|
||||
|
||||
var pluginManager = Service<PluginManager>.Get();
|
||||
this.IsBanned = pluginManager.IsManifestBanned(this.Manifest) && !this.IsDev;
|
||||
this.BanReason = pluginManager.GetBanReason(this.Manifest);
|
||||
this.IsBanned = pluginManager.IsManifestBanned(this.manifest) && !this.IsDev;
|
||||
this.BanReason = pluginManager.GetBanReason(this.manifest);
|
||||
|
||||
this.SaveManifest();
|
||||
if (needsSaveDueToLegacyFiles)
|
||||
this.SaveManifest("legacy");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -168,9 +185,9 @@ internal class LocalPlugin : IDisposable
|
|||
public FileInfo DllFile { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin manifest, if one exists.
|
||||
/// Gets the plugin manifest.
|
||||
/// </summary>
|
||||
public LocalPluginManifest Manifest { get; private set; }
|
||||
public ILocalPluginManifest Manifest => this.manifest;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current state of the plugin.
|
||||
|
|
@ -186,12 +203,12 @@ internal class LocalPlugin : IDisposable
|
|||
/// <summary>
|
||||
/// Gets the plugin name from the manifest.
|
||||
/// </summary>
|
||||
public string Name => this.Manifest.Name;
|
||||
public string Name => this.manifest.Name;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the plugin internal name from the manifest.
|
||||
/// </summary>
|
||||
public string InternalName => this.Manifest.InternalName;
|
||||
public string InternalName => this.manifest.InternalName;
|
||||
|
||||
/// <summary>
|
||||
/// Gets an optional reason, if the plugin is banned.
|
||||
|
|
@ -213,23 +230,23 @@ internal class LocalPlugin : IDisposable
|
|||
/// INCLUDES the default profile.
|
||||
/// </summary>
|
||||
public bool IsWantedByAnyProfile =>
|
||||
Service<ProfileManager>.Get().GetWantStateAsync(this.Manifest.InternalName, false, false).GetAwaiter().GetResult();
|
||||
Service<ProfileManager>.Get().GetWantStateAsync(this.manifest.InternalName, false, false).GetAwaiter().GetResult();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin's API level is out of date.
|
||||
/// </summary>
|
||||
public bool IsOutdated => this.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel;
|
||||
public bool IsOutdated => this.manifest.DalamudApiLevel < PluginManager.DalamudApiLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is for testing use only.
|
||||
/// </summary>
|
||||
public bool IsTesting => this.Manifest.IsTestingExclusive || this.Manifest.Testing;
|
||||
public bool IsTesting => this.manifest.IsTestingExclusive || this.manifest.Testing;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not this plugin is orphaned(belongs to a repo) or not.
|
||||
/// </summary>
|
||||
public bool IsOrphaned => !this.IsDev &&
|
||||
!this.Manifest.InstalledFromUrl.IsNullOrEmpty() && // TODO(api8): Remove this, all plugins will have a proper flag
|
||||
!this.manifest.InstalledFromUrl.IsNullOrEmpty() && // TODO(api8): Remove this, all plugins will have a proper flag
|
||||
this.GetSourceRepository() == null;
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -237,7 +254,7 @@ internal class LocalPlugin : IDisposable
|
|||
/// </summary>
|
||||
public bool IsDecommissioned => !this.IsDev &&
|
||||
this.GetSourceRepository()?.State == PluginRepositoryState.Success &&
|
||||
this.GetSourceRepository()?.PluginMaster?.FirstOrDefault(x => x.InternalName == this.Manifest.InternalName) == null;
|
||||
this.GetSourceRepository()?.PluginMaster?.FirstOrDefault(x => x.InternalName == this.manifest.InternalName) == null;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin has been banned.
|
||||
|
|
@ -249,12 +266,23 @@ internal class LocalPlugin : IDisposable
|
|||
/// </summary>
|
||||
public bool IsDev => this is LocalDevPlugin;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this manifest is associated with a plugin that was installed from a third party
|
||||
/// repo.
|
||||
/// </summary>
|
||||
public bool IsThirdParty => this.manifest.IsThirdParty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin should be allowed to load.
|
||||
/// </summary>
|
||||
public bool ApplicableForLoad => !this.IsBanned && !this.IsDecommissioned && !this.IsOrphaned && !this.IsOutdated
|
||||
&& !(!this.IsDev && this.State == PluginState.UnloadError) && this.CheckPolicy();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the effective version of this plugin.
|
||||
/// </summary>
|
||||
public Version EffectiveVersion => this.manifest.EffectiveVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the service scope for this plugin.
|
||||
/// </summary>
|
||||
|
|
@ -270,7 +298,7 @@ internal class LocalPlugin : IDisposable
|
|||
if (this.instance != null)
|
||||
{
|
||||
didPluginDispose = true;
|
||||
if (this.Manifest.CanUnloadAsync || framework == null)
|
||||
if (this.manifest.CanUnloadAsync || framework == null)
|
||||
this.instance.Dispose();
|
||||
else
|
||||
framework.RunOnFrameworkThread(() => this.instance.Dispose()).Wait();
|
||||
|
|
@ -309,7 +337,7 @@ internal class LocalPlugin : IDisposable
|
|||
await Service<InterfaceManager>.GetAsync();
|
||||
await Service<GameFontManager>.GetAsync();
|
||||
|
||||
if (this.Manifest.LoadRequiredState == 0)
|
||||
if (this.manifest.LoadRequiredState == 0)
|
||||
_ = await Service<InterfaceManager.InterfaceManagerWithScene>.GetAsync();
|
||||
|
||||
await this.pluginLoadStateLock.WaitAsync();
|
||||
|
|
@ -322,8 +350,11 @@ internal class LocalPlugin : IDisposable
|
|||
}
|
||||
|
||||
// If we reload a plugin we don't want to delete it. Makes sense, right?
|
||||
this.Manifest.ScheduledForDeletion = false;
|
||||
this.SaveManifest();
|
||||
if (this.manifest.ScheduledForDeletion)
|
||||
{
|
||||
this.manifest.ScheduledForDeletion = false;
|
||||
this.SaveManifest("Scheduled for deletion, but loading");
|
||||
}
|
||||
|
||||
switch (this.State)
|
||||
{
|
||||
|
|
@ -353,13 +384,13 @@ internal class LocalPlugin : IDisposable
|
|||
throw new ArgumentOutOfRangeException(this.State.ToString());
|
||||
}
|
||||
|
||||
if (pluginManager.IsManifestBanned(this.Manifest) && !this.IsDev)
|
||||
if (pluginManager.IsManifestBanned(this.manifest) && !this.IsDev)
|
||||
throw new BannedPluginException($"Unable to load {this.Name}, banned");
|
||||
|
||||
if (this.Manifest.ApplicableVersion < startInfo.GameVersion)
|
||||
if (this.manifest.ApplicableVersion < startInfo.GameVersion)
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, no applicable version");
|
||||
|
||||
if (this.Manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !pluginManager.LoadAllApiLevels)
|
||||
if (this.manifest.DalamudApiLevel < PluginManager.DalamudApiLevel && !pluginManager.LoadAllApiLevels)
|
||||
throw new InvalidPluginOperationException($"Unable to load {this.Name}, incompatible API level");
|
||||
|
||||
// We might want to throw here?
|
||||
|
|
@ -380,8 +411,8 @@ internal class LocalPlugin : IDisposable
|
|||
{
|
||||
Log.Error(
|
||||
"==== IMPORTANT MESSAGE TO {0}, THE DEVELOPER OF {1} ====",
|
||||
this.Manifest.Author!,
|
||||
this.Manifest.InternalName);
|
||||
this.manifest.Author!,
|
||||
this.manifest.InternalName);
|
||||
Log.Error(
|
||||
"YOU ARE INCLUDING DALAMUD DEPENDENCIES IN YOUR BUILDS!!!");
|
||||
Log.Error(
|
||||
|
|
@ -449,7 +480,7 @@ internal class LocalPlugin : IDisposable
|
|||
this.ServiceScope = ioc.GetScope();
|
||||
this.ServiceScope.RegisterPrivateScopes(this); // Add this LocalPlugin as a private scope, so services can get it
|
||||
|
||||
if (this.Manifest.LoadSync && this.Manifest.LoadRequiredState is 0 or 1)
|
||||
if (this.manifest.LoadSync && this.manifest.LoadRequiredState is 0 or 1)
|
||||
{
|
||||
this.instance = await framework.RunOnFrameworkThread(
|
||||
() => this.ServiceScope.CreateAsync(this.pluginType!, this.DalamudInterface!)) as IDalamudPlugin;
|
||||
|
|
@ -470,10 +501,10 @@ internal class LocalPlugin : IDisposable
|
|||
}
|
||||
|
||||
// In-case the manifest name was a placeholder. Can occur when no manifest was included.
|
||||
if (this.Manifest.Name.IsNullOrEmpty())
|
||||
if (this.manifest.Name.IsNullOrEmpty() && !this.IsDev)
|
||||
{
|
||||
this.Manifest.Name = this.instance.Name;
|
||||
this.Manifest.Save(this.manifestFile);
|
||||
this.manifest.Name = this.instance.Name;
|
||||
this.manifest.Save(this.manifestFile, "manifest name null or empty");
|
||||
}
|
||||
|
||||
this.State = PluginState.Loaded;
|
||||
|
|
@ -505,7 +536,6 @@ internal class LocalPlugin : IDisposable
|
|||
{
|
||||
var configuration = Service<DalamudConfiguration>.Get();
|
||||
var framework = Service<Framework>.GetNullable();
|
||||
var ioc = await Service<ServiceContainer>.GetAsync();
|
||||
|
||||
await this.pluginLoadStateLock.WaitAsync();
|
||||
try
|
||||
|
|
@ -534,7 +564,7 @@ internal class LocalPlugin : IDisposable
|
|||
this.State = PluginState.Unloading;
|
||||
Log.Information($"Unloading {this.DllFile.Name}");
|
||||
|
||||
if (this.Manifest.CanUnloadAsync || framework == null)
|
||||
if (this.manifest.CanUnloadAsync || framework == null)
|
||||
this.instance?.Dispose();
|
||||
else
|
||||
await framework.RunOnFrameworkThread(() => this.instance?.Dispose());
|
||||
|
|
@ -602,7 +632,7 @@ internal class LocalPlugin : IDisposable
|
|||
if (startInfo.NoLoadPlugins)
|
||||
return false;
|
||||
|
||||
if (startInfo.NoLoadThirdPartyPlugins && this.Manifest.IsThirdParty)
|
||||
if (startInfo.NoLoadThirdPartyPlugins && this.manifest.IsThirdParty)
|
||||
return false;
|
||||
|
||||
if (manager.SafeMode)
|
||||
|
|
@ -617,8 +647,8 @@ internal class LocalPlugin : IDisposable
|
|||
/// <param name="status">Schedule or cancel the deletion.</param>
|
||||
public void ScheduleDeletion(bool status = true)
|
||||
{
|
||||
this.Manifest.ScheduledForDeletion = status;
|
||||
this.SaveManifest();
|
||||
this.manifest.ScheduledForDeletion = status;
|
||||
this.SaveManifest("scheduling for deletion");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -626,14 +656,14 @@ internal class LocalPlugin : IDisposable
|
|||
/// </summary>
|
||||
public void ReloadManifest()
|
||||
{
|
||||
var manifest = LocalPluginManifest.GetManifestFile(this.DllFile);
|
||||
if (manifest.Exists)
|
||||
var manifestPath = LocalPluginManifest.GetManifestFile(this.DllFile);
|
||||
if (manifestPath.Exists)
|
||||
{
|
||||
// var isDisabled = this.IsDisabled; // saving the internal state because it could have been deleted
|
||||
this.Manifest = LocalPluginManifest.Load(manifest) ?? throw new Exception("Could not reload manifest.");
|
||||
// this.Manifest.Disabled = isDisabled;
|
||||
this.manifest = LocalPluginManifest.Load(manifestPath) ?? throw new Exception("Could not reload manifest.");
|
||||
// this.manifest.Disabled = isDisabled;
|
||||
|
||||
this.SaveManifest();
|
||||
this.SaveManifest("dev reload");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -649,10 +679,10 @@ internal class LocalPlugin : IDisposable
|
|||
var repos = Service<PluginManager>.Get().Repos;
|
||||
return repos.FirstOrDefault(x =>
|
||||
{
|
||||
if (!x.IsThirdParty && !this.Manifest.IsThirdParty)
|
||||
if (!x.IsThirdParty && !this.manifest.IsThirdParty)
|
||||
return true;
|
||||
|
||||
return x.PluginMasterUrl == this.Manifest.InstalledFromUrl;
|
||||
return x.PluginMasterUrl == this.manifest.InstalledFromUrl;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -665,5 +695,5 @@ internal class LocalPlugin : IDisposable
|
|||
config.SharedAssemblies.Add(typeof(Lumina.Excel.ExcelSheetImpl).Assembly.GetName());
|
||||
}
|
||||
|
||||
private void SaveManifest() => this.Manifest.Save(this.manifestFile);
|
||||
private void SaveManifest(string reason) => this.manifest.Save(this.manifestFile, reason);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types.Manifest;
|
||||
|
||||
/// <summary>
|
||||
/// Public interface for the local plugin manifest.
|
||||
/// </summary>
|
||||
public interface ILocalPluginManifest : IPluginManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the 3rd party repo URL that this plugin was installed from. Used to display where the plugin was
|
||||
/// sourced from on the installed plugin view. This should not be included in the plugin master. This value is null
|
||||
/// when installed from the main repo.
|
||||
/// </summary>
|
||||
public string InstalledFromUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin should be deleted during the next cleanup.
|
||||
/// </summary>
|
||||
public bool ScheduledForDeletion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an ID uniquely identifying this specific installation of a plugin.
|
||||
/// </summary>
|
||||
public Guid WorkingPluginId { get; }
|
||||
}
|
||||
111
Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs
Normal file
111
Dalamud/Plugin/Internal/Types/Manifest/IPluginManifest.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types.Manifest;
|
||||
|
||||
/// <summary>
|
||||
/// Public interface for the base plugin manifest.
|
||||
/// </summary>
|
||||
public interface IPluginManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the internal name of the plugin, which should match the assembly name of the plugin.
|
||||
/// </summary>
|
||||
public string InternalName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the public name of the plugin.
|
||||
/// </summary>
|
||||
public string Name { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a punchline of the plugins functions.
|
||||
/// </summary>
|
||||
public string? Punchline { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the author/s of the plugin.
|
||||
/// </summary>
|
||||
public string Author { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin can be unloaded asynchronously.
|
||||
/// </summary>
|
||||
public bool CanUnloadAsync { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the assembly version of the plugin.
|
||||
/// </summary>
|
||||
public Version AssemblyVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the assembly version of the plugin's testing variant.
|
||||
/// </summary>
|
||||
public Version? TestingAssemblyVersion { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DIP17 channel name.
|
||||
/// </summary>
|
||||
public string? Dip17Channel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last time this plugin was updated.
|
||||
/// </summary>
|
||||
public long LastUpdate { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a changelog, null if none exists.
|
||||
/// </summary>
|
||||
public string? Changelog { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of tags that apply to this plugin.
|
||||
/// </summary>
|
||||
public List<string>? Tags { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API level of this plugin. For the current API level, please see <see cref="PluginManager.DalamudApiLevel"/>
|
||||
/// for the currently used API level.
|
||||
/// </summary>
|
||||
public int DalamudApiLevel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of downloads this plugin has.
|
||||
/// </summary>
|
||||
public long DownloadCount { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin supports profiles.
|
||||
/// </summary>
|
||||
public bool SupportsProfiles { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an URL to the website or source code of the plugin.
|
||||
/// </summary>
|
||||
public string? RepoUrl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a description of the plugins functions.
|
||||
/// </summary>
|
||||
public string? Description { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a message that is shown to users when sending feedback.
|
||||
/// </summary>
|
||||
public string? FeedbackMessage { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is only available for testing.
|
||||
/// </summary>
|
||||
public bool IsTestingExclusive { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of screenshot image URLs to show in the plugin installer.
|
||||
/// </summary>
|
||||
public List<string>? ImageUrls { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an URL for the plugin's icon.
|
||||
/// </summary>
|
||||
public string? IconUrl { get; }
|
||||
}
|
||||
|
|
@ -3,14 +3,15 @@ using System.IO;
|
|||
|
||||
using Dalamud.Utility;
|
||||
using Newtonsoft.Json;
|
||||
using Serilog;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
namespace Dalamud.Plugin.Internal.Types.Manifest;
|
||||
|
||||
/// <summary>
|
||||
/// Information about a plugin, packaged in a json file with the DLL. This variant includes additional information such as
|
||||
/// if the plugin is disabled and if it was installed from a testing URL. This is designed for use with manifests on disk.
|
||||
/// </summary>
|
||||
internal record LocalPluginManifest : PluginManifest
|
||||
internal record LocalPluginManifest : PluginManifest, ILocalPluginManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Flag indicating that a plugin was installed from the official repo.
|
||||
|
|
@ -37,18 +38,15 @@ internal record LocalPluginManifest : PluginManifest
|
|||
/// </summary>
|
||||
public bool Testing { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether the plugin should be deleted during the next cleanup.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public bool ScheduledForDeletion { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the 3rd party repo URL that this plugin was installed from. Used to display where the plugin was
|
||||
/// sourced from on the installed plugin view. This should not be included in the plugin master. This value is null
|
||||
/// when installed from the main repo.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public string InstalledFromUrl { get; set; } = string.Empty;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public Guid WorkingPluginId { get; set; } = Guid.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this manifest is associated with a plugin that was installed from a third party
|
||||
/// repo. Unless the manifest has been manually modified, this is determined by the InstalledFromUrl being null.
|
||||
|
|
@ -60,16 +58,25 @@ internal record LocalPluginManifest : PluginManifest
|
|||
/// </summary>
|
||||
public Version EffectiveVersion => this.Testing && this.TestingAssemblyVersion != null ? this.TestingAssemblyVersion : this.AssemblyVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin is eligible for testing.
|
||||
/// </summary>
|
||||
public bool IsAvailableForTesting => this.TestingAssemblyVersion != null && this.TestingAssemblyVersion > this.AssemblyVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Save a plugin manifest to file.
|
||||
/// </summary>
|
||||
/// <param name="manifestFile">Path to save at.</param>
|
||||
public void Save(FileInfo manifestFile) => Util.WriteAllTextSafe(manifestFile.FullName, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||
/// <param name="reason">The reason the manifest was saved.</param>
|
||||
public void Save(FileInfo manifestFile, string reason)
|
||||
{
|
||||
Log.Verbose("Saving manifest for '{PluginName}' because '{Reason}'", this.InternalName, reason);
|
||||
|
||||
try
|
||||
{
|
||||
Util.WriteAllTextSafe(manifestFile.FullName, JsonConvert.SerializeObject(this, Formatting.Indented));
|
||||
}
|
||||
catch
|
||||
{
|
||||
Log.Error("Could not write out manifest for '{PluginName}' because '{Reason}'", this.InternalName, reason);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads a plugin manifest from file.
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
using JetBrains.Annotations;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
namespace Dalamud.Plugin.Internal.Types.Manifest;
|
||||
|
||||
/// <summary>
|
||||
/// Information about a plugin, packaged in a json file with the DLL. This variant includes additional information such as
|
||||
|
|
@ -16,4 +16,9 @@ internal record RemotePluginManifest : PluginManifest
|
|||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public PluginRepository SourceRepo { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin is eligible for testing.
|
||||
/// </summary>
|
||||
public bool IsAvailableForTesting => this.TestingAssemblyVersion != null && this.TestingAssemblyVersion > this.AssemblyVersion;
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
using System.IO;
|
||||
|
||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Dalamud.Plugin.Internal.Types;
|
||||
|
|
@ -9,41 +10,29 @@ namespace Dalamud.Plugin.Internal.Types;
|
|||
/// <summary>
|
||||
/// Information about a plugin, packaged in a json file with the DLL.
|
||||
/// </summary>
|
||||
internal record PluginManifest
|
||||
internal record PluginManifest : IPluginManifest
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the author/s of the plugin.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public string? Author { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the public name of the plugin.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public string Name { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a punchline of the plugins functions.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public string? Punchline { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a description of the plugins functions.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public string? Description { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a changelog.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public string? Changelog { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of tags defined on the plugin.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public List<string>? Tags { get; init; }
|
||||
|
||||
|
|
@ -60,33 +49,23 @@ internal record PluginManifest
|
|||
[JsonProperty]
|
||||
public bool IsHide { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the internal name of the plugin, which should match the assembly name of the plugin.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public string InternalName { get; init; } = null!;
|
||||
public string InternalName { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current assembly version of the plugin.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public Version AssemblyVersion { get; init; } = null!;
|
||||
public Version AssemblyVersion { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current testing assembly version of the plugin.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public Version? TestingAssemblyVersion { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin is only available for testing.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public bool IsTestingExclusive { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an URL to the website or source code of the plugin.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public string? RepoUrl { get; init; }
|
||||
|
||||
|
|
@ -97,24 +76,17 @@ internal record PluginManifest
|
|||
[JsonConverter(typeof(GameVersionConverter))]
|
||||
public GameVersion? ApplicableVersion { get; init; } = GameVersion.Any;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the API level of this plugin. For the current API level, please see <see cref="PluginManager.DalamudApiLevel"/>
|
||||
/// for the currently used API level.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public int DalamudApiLevel { get; init; } = PluginManager.DalamudApiLevel;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the number of downloads this plugin has.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public long DownloadCount { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the last time this plugin was updated.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public long LastUpdate { get; init; }
|
||||
public long LastUpdate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the download link used to install the plugin.
|
||||
|
|
@ -156,26 +128,18 @@ internal record PluginManifest
|
|||
[JsonProperty]
|
||||
public int LoadPriority { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin can be unloaded asynchronously.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public bool CanUnloadAsync { get; init; }
|
||||
public bool CanUnloadAsync { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the plugin supports profiles.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty]
|
||||
public bool SupportsProfiles { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of screenshot image URLs to show in the plugin installer.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public List<string>? ImageUrls { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an URL for the plugin's icon.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public string? IconUrl { get; init; }
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -183,21 +147,10 @@ internal record PluginManifest
|
|||
/// </summary>
|
||||
public bool AcceptsFeedback { get; init; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a message that is shown to users when sending feedback.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
public string? FeedbackMessage { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this plugin is DIP17.
|
||||
/// To be removed.
|
||||
/// </summary>
|
||||
[JsonProperty("_isDip17Plugin")]
|
||||
public bool IsDip17Plugin { get; init; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the DIP17 channel name.
|
||||
/// </summary>
|
||||
/// <inheritdoc/>
|
||||
[JsonProperty("_Dip17Channel")]
|
||||
public string? Dip17Channel { get; init; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using System.Threading.Tasks;
|
|||
|
||||
using Dalamud.Logging.Internal;
|
||||
using Dalamud.Networking.Http;
|
||||
using Dalamud.Plugin.Internal.Types.Manifest;
|
||||
using Dalamud.Utility;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
|
|
|
|||
61
Dalamud/Plugin/Services/IBuddyList.cs
Normal file
61
Dalamud/Plugin/Services/IBuddyList.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
using Dalamud.Game.ClientState.Buddy;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This collection represents the buddies present in your squadron or trust party.
|
||||
/// It does not include the local player.
|
||||
/// </summary>
|
||||
public interface IBuddyList : IReadOnlyCollection<BuddyMember>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the amount of battle buddies the local player has.
|
||||
/// </summary>
|
||||
public int Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active companion buddy.
|
||||
/// </summary>
|
||||
public BuddyMember? CompanionBuddy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active pet buddy.
|
||||
/// </summary>
|
||||
public BuddyMember? PetBuddy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a battle buddy at the specified spawn index.
|
||||
/// </summary>
|
||||
/// <param name="index">Spawn index.</param>
|
||||
/// <returns>A <see cref="BuddyMember"/> at the specified spawn index.</returns>
|
||||
public BuddyMember? this[int index] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the companion buddy.
|
||||
/// </summary>
|
||||
/// <returns>The memory address of the companion buddy.</returns>
|
||||
public nint GetCompanionBuddyMemberAddress();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the pet buddy.
|
||||
/// </summary>
|
||||
/// <returns>The memory address of the pet buddy.</returns>
|
||||
public nint GetPetBuddyMemberAddress();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the battle buddy at the specified index of the buddy list.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the battle buddy.</param>
|
||||
/// <returns>The memory address of the battle buddy.</returns>
|
||||
public nint GetBattleBuddyMemberAddress(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Create a reference to a buddy.
|
||||
/// </summary>
|
||||
/// <param name="address">The address of the buddy in memory.</param>
|
||||
/// <returns><see cref="BuddyMember"/> object containing the requested data.</returns>
|
||||
public BuddyMember? CreateBuddyMemberReference(nint address);
|
||||
}
|
||||
46
Dalamud/Plugin/Services/ICommandManager.cs
Normal file
46
Dalamud/Plugin/Services/ICommandManager.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
using System.Collections.ObjectModel;
|
||||
|
||||
using Dalamud.Game.Command;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This class manages registered in-game slash commands.
|
||||
/// </summary>
|
||||
public interface ICommandManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a read-only list of all registered commands.
|
||||
/// </summary>
|
||||
public ReadOnlyDictionary<string, CommandInfo> Commands { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Process a command in full.
|
||||
/// </summary>
|
||||
/// <param name="content">The full command string.</param>
|
||||
/// <returns>True if the command was found and dispatched.</returns>
|
||||
public bool ProcessCommand(string content);
|
||||
|
||||
/// <summary>
|
||||
/// Dispatch the handling of a command.
|
||||
/// </summary>
|
||||
/// <param name="command">The command to dispatch.</param>
|
||||
/// <param name="argument">The provided arguments.</param>
|
||||
/// <param name="info">A <see cref="CommandInfo"/> object describing this command.</param>
|
||||
public void DispatchCommand(string command, string argument, CommandInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Add a command handler, which you can use to add your own custom commands to the in-game chat.
|
||||
/// </summary>
|
||||
/// <param name="command">The command to register.</param>
|
||||
/// <param name="info">A <see cref="CommandInfo"/> object describing the command.</param>
|
||||
/// <returns>If adding was successful.</returns>
|
||||
public bool AddHandler(string command, CommandInfo info);
|
||||
|
||||
/// <summary>
|
||||
/// Remove a command from the command handlers.
|
||||
/// </summary>
|
||||
/// <param name="command">The command to remove.</param>
|
||||
/// <returns>If the removal was successful.</returns>
|
||||
public bool RemoveHandler(string command);
|
||||
}
|
||||
181
Dalamud/Plugin/Services/IDataManager.cs
Normal file
181
Dalamud/Plugin/Services/IDataManager.cs
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
using System.Collections.ObjectModel;
|
||||
|
||||
using ImGuiScene;
|
||||
using Lumina;
|
||||
using Lumina.Data;
|
||||
using Lumina.Data.Files;
|
||||
using Lumina.Excel;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This class provides data for Dalamud-internal features, but can also be used by plugins if needed.
|
||||
/// </summary>
|
||||
public interface IDataManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the current game client language.
|
||||
/// </summary>
|
||||
public ClientLanguage Language { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the OpCodes sent by the server to the client.
|
||||
/// </summary>
|
||||
public ReadOnlyDictionary<string, ushort> ServerOpCodes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the OpCodes sent by the client to the server.
|
||||
/// </summary>
|
||||
public ReadOnlyDictionary<string, ushort> ClientOpCodes { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="Lumina"/> object which gives access to any excel/game data.
|
||||
/// </summary>
|
||||
public GameData GameData { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets an <see cref="ExcelModule"/> object which gives access to any of the game's sheet data.
|
||||
/// </summary>
|
||||
public ExcelModule Excel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether Game Data is ready to be read.
|
||||
/// </summary>
|
||||
public bool IsDataReady { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the game data files have been modified by another third-party tool.
|
||||
/// </summary>
|
||||
public bool HasModifiedGameDataFiles { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get an <see cref="ExcelSheet{T}"/> with the given Excel sheet row type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The excel sheet type to get.</typeparam>
|
||||
/// <returns>The <see cref="ExcelSheet{T}"/>, giving access to game rows.</returns>
|
||||
public ExcelSheet<T>? GetExcelSheet<T>() where T : ExcelRow;
|
||||
|
||||
/// <summary>
|
||||
/// Get an <see cref="ExcelSheet{T}"/> with the given Excel sheet row type with a specified language.
|
||||
/// </summary>
|
||||
/// <param name="language">Language of the sheet to get.</param>
|
||||
/// <typeparam name="T">The excel sheet type to get.</typeparam>
|
||||
/// <returns>The <see cref="ExcelSheet{T}"/>, giving access to game rows.</returns>
|
||||
public ExcelSheet<T>? GetExcelSheet<T>(ClientLanguage language) where T : ExcelRow;
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="FileResource"/> with the given path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path inside of the game files.</param>
|
||||
/// <returns>The <see cref="FileResource"/> of the file.</returns>
|
||||
public FileResource? GetFile(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="FileResource"/> with the given path, of the given type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of resource.</typeparam>
|
||||
/// <param name="path">The path inside of the game files.</param>
|
||||
/// <returns>The <see cref="FileResource"/> of the file.</returns>
|
||||
public T? GetFile<T>(string path) where T : FileResource;
|
||||
|
||||
/// <summary>
|
||||
/// Check if the file with the given path exists within the game's index files.
|
||||
/// </summary>
|
||||
/// <param name="path">The path inside of the game files.</param>
|
||||
/// <returns>True if the file exists.</returns>
|
||||
public bool FileExists(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TexFile"/> containing the icon with the given ID.
|
||||
/// </summary>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <param name="highResolution">Return high resolution version.</param>
|
||||
/// <returns>The <see cref="TexFile"/> containing the icon.</returns>
|
||||
public TexFile? GetIcon(uint iconId, bool highResolution = false);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TexFile"/> containing the icon with the given ID, of the given language.
|
||||
/// </summary>
|
||||
/// <param name="iconLanguage">The requested language.</param>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <param name="highResolution">Return high resolution version.</param>
|
||||
/// <returns>The <see cref="TexFile"/> containing the icon.</returns>
|
||||
public TexFile? GetIcon(ClientLanguage iconLanguage, uint iconId, bool highResolution = false);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TexFile"/> containing the icon with the given ID, of the given type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of the icon (e.g. 'hq' to get the HQ variant of an item icon).</param>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <param name="highResolution">Return high resolution version.</param>
|
||||
/// <returns>The <see cref="TexFile"/> containing the icon.</returns>
|
||||
public TexFile? GetIcon(string? type, uint iconId, bool highResolution = false);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TextureWrap"/> containing the icon with the given ID.
|
||||
/// </summary>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <param name="highResolution">Return the high resolution version.</param>
|
||||
/// <returns>The <see cref="TextureWrap"/> containing the icon.</returns>
|
||||
public TextureWrap? GetImGuiTextureIcon(uint iconId, bool highResolution = false);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TexFile"/> containing the icon with the given ID, of the given quality.
|
||||
/// </summary>
|
||||
/// <param name="isHq">A value indicating whether the icon should be HQ.</param>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <returns>The <see cref="TexFile"/> containing the icon.</returns>
|
||||
public TexFile? GetIcon(bool isHq, uint iconId);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TexFile"/> containing the HQ icon with the given ID.
|
||||
/// </summary>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <returns>The <see cref="TexFile"/> containing the icon.</returns>
|
||||
public TexFile? GetHqIcon(uint iconId);
|
||||
|
||||
/// <summary>
|
||||
/// Get the passed <see cref="TexFile"/> as a drawable ImGui TextureWrap.
|
||||
/// </summary>
|
||||
/// <param name="tex">The Lumina <see cref="TexFile"/>.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> that can be used to draw the texture.</returns>
|
||||
public TextureWrap? GetImGuiTexture(TexFile? tex);
|
||||
|
||||
/// <summary>
|
||||
/// Get the passed texture path as a drawable ImGui TextureWrap.
|
||||
/// </summary>
|
||||
/// <param name="path">The internal path to the texture.</param>
|
||||
/// <returns>A <see cref="TextureWrap"/> that can be used to draw the texture.</returns>
|
||||
public TextureWrap? GetImGuiTexture(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TextureWrap"/> containing the icon with the given ID, of the given quality.
|
||||
/// </summary>
|
||||
/// <param name="isHq">A value indicating whether the icon should be HQ.</param>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <returns>The <see cref="TextureWrap"/> containing the icon.</returns>
|
||||
public TextureWrap? GetImGuiTextureIcon(bool isHq, uint iconId);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TextureWrap"/> containing the icon with the given ID, of the given language.
|
||||
/// </summary>
|
||||
/// <param name="iconLanguage">The requested language.</param>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <returns>The <see cref="TextureWrap"/> containing the icon.</returns>
|
||||
public TextureWrap? GetImGuiTextureIcon(ClientLanguage iconLanguage, uint iconId);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TextureWrap"/> containing the icon with the given ID, of the given type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type of the icon (e.g. 'hq' to get the HQ variant of an item icon).</param>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <returns>The <see cref="TextureWrap"/> containing the icon.</returns>
|
||||
public TextureWrap? GetImGuiTextureIcon(string type, uint iconId);
|
||||
|
||||
/// <summary>
|
||||
/// Get a <see cref="TextureWrap"/> containing the HQ icon with the given ID.
|
||||
/// </summary>
|
||||
/// <param name="iconId">The icon ID.</param>
|
||||
/// <returns>The <see cref="TextureWrap"/> containing the icon.</returns>
|
||||
public TextureWrap? GetImGuiTextureHqIcon(uint iconId);
|
||||
}
|
||||
22
Dalamud/Plugin/Services/IDtrBar.cs
Normal file
22
Dalamud/Plugin/Services/IDtrBar.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
|
||||
using Dalamud.Game.Gui.Dtr;
|
||||
using Dalamud.Game.Text.SeStringHandling;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Class used to interface with the server info bar.
|
||||
/// </summary>
|
||||
public interface IDtrBar
|
||||
{
|
||||
/// <summary>
|
||||
/// Get a DTR bar entry.
|
||||
/// This allows you to add your own text, and users to sort it.
|
||||
/// </summary>
|
||||
/// <param name="title">A user-friendly name for sorting.</param>
|
||||
/// <param name="text">The text the entry shows.</param>
|
||||
/// <returns>The entry object used to update, hide and remove the entry.</returns>
|
||||
/// <exception cref="ArgumentException">Thrown when an entry with the specified title exists.</exception>
|
||||
public DtrBarEntry Get(string title, SeString? text = null);
|
||||
}
|
||||
36
Dalamud/Plugin/Services/IDutyState.cs
Normal file
36
Dalamud/Plugin/Services/IDutyState.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents the state of the currently occupied duty.
|
||||
/// </summary>
|
||||
public interface IDutyState
|
||||
{
|
||||
/// <summary>
|
||||
/// Event that gets fired when the duty starts.
|
||||
/// Triggers when the "Duty Start" message displays, and on the removal of the ring at duty's spawn.
|
||||
/// Does not trigger when loading into a duty that was in progress, or from loading in after a disconnect.
|
||||
/// </summary>
|
||||
public event EventHandler<ushort> DutyStarted;
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when everyone in the party dies and the screen fades to black.
|
||||
/// </summary>
|
||||
public event EventHandler<ushort> DutyWiped;
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when the "Duty Recommence" message displays, and on the removal of the ring at duty's spawn.
|
||||
/// </summary>
|
||||
public event EventHandler<ushort> DutyRecommenced;
|
||||
|
||||
/// <summary>
|
||||
/// Event that gets fired when the duty is completed successfully.
|
||||
/// </summary>
|
||||
public event EventHandler<ushort> DutyCompleted;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the current duty has been started.
|
||||
/// </summary>
|
||||
public bool IsDutyStarted { get; }
|
||||
}
|
||||
42
Dalamud/Plugin/Services/IFateTable.cs
Normal file
42
Dalamud/Plugin/Services/IFateTable.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Dalamud.Game.ClientState.Fates;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This collection represents the currently available Fate events.
|
||||
/// </summary>
|
||||
public interface IFateTable : IReadOnlyCollection<Fate>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the address of the Fate table.
|
||||
/// </summary>
|
||||
public nint Address { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of currently active Fates.
|
||||
/// </summary>
|
||||
public int Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get an actor at the specified spawn index.
|
||||
/// </summary>
|
||||
/// <param name="index">Spawn index.</param>
|
||||
/// <returns>A <see cref="Fate"/> at the specified spawn index.</returns>
|
||||
public Fate? this[int index] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the Fate at the specified index of the fate table.
|
||||
/// </summary>wo
|
||||
/// <param name="index">The index of the Fate.</param>
|
||||
/// <returns>The memory address of the Fate.</returns>
|
||||
public nint GetFateAddress(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Create a reference to a FFXIV actor.
|
||||
/// </summary>
|
||||
/// <param name="offset">The offset of the actor in memory.</param>
|
||||
/// <returns><see cref="Fate"/> object containing requested data.</returns>
|
||||
public Fate? CreateFateReference(nint offset);
|
||||
}
|
||||
321
Dalamud/Plugin/Services/IGameConfig.cs
Normal file
321
Dalamud/Plugin/Services/IGameConfig.cs
Normal file
|
|
@ -0,0 +1,321 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
using Dalamud.Game.Config;
|
||||
using FFXIVClientStructs.FFXIV.Common.Configuration;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents the game's configuration.
|
||||
/// </summary>
|
||||
public interface IGameConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// Event which is fired when a game config option is changed.
|
||||
/// </summary>
|
||||
public event EventHandler<ConfigChangeEvent> Changed;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of config options that persist between characters.
|
||||
/// </summary>
|
||||
public GameConfigSection System { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of config options that are character specific.
|
||||
/// </summary>
|
||||
public GameConfigSection UiConfig { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the collection of config options that are control mode specific. (Mouse and Keyboard / Gamepad).
|
||||
/// </summary>
|
||||
public GameConfigSection UiControl { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a boolean config value from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a uint config value from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out uint value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a float config value from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out float value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a string config value from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out string value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a UInt option from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Minimum, Maximum, and Default values.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out UIntConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a Float option from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Minimum, Maximum, and Default values.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out FloatConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a String option from the System section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Default Value</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(SystemConfigOption option, out StringConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a boolean config value from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a uint config value from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out uint value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a float config value from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out float value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a string config value from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out string value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a UInt option from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Minimum, Maximum, and Default values.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out UIntConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a Float option from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Minimum, Maximum, and Default values.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out FloatConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a String option from the UiConfig section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Default Value</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiConfigOption option, out StringConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a boolean config value from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a uint config value from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out uint value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a float config value from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out float value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get a string config value from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the value of.</param>
|
||||
/// <param name="value">The returned value of the config option.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out string value);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a UInt option from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Minimum, Maximum, and Default values.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out UIntConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a Float option from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Minimum, Maximum, and Default values.</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out FloatConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Attempts to get the properties of a String option from the UiControl section.
|
||||
/// </summary>
|
||||
/// <param name="option">Option to get the properties of.</param>
|
||||
/// <param name="properties">Details of the option: Default Value</param>
|
||||
/// <returns>A value representing the success.</returns>
|
||||
public bool TryGet(UiControlOption option, out StringConfigProperties? properties);
|
||||
|
||||
/// <summary>
|
||||
/// Set a boolean config option in the System config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(SystemConfigOption option, bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a unsigned integer config option in the System config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(SystemConfigOption option, uint value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a float config option in the System config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(SystemConfigOption option, float value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a string config option in the System config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(SystemConfigOption option, string value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a boolean config option in the UiConfig section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiConfigOption option, bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a unsigned integer config option in the UiConfig section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiConfigOption option, uint value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a float config option in the UiConfig section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiConfigOption option, float value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a string config option in the UiConfig section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiConfigOption option, string value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a boolean config option in the UiControl config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiControlOption option, bool value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a uint config option in the UiControl config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiControlOption option, uint value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a float config option in the UiControl config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiControlOption option, float value);
|
||||
|
||||
/// <summary>
|
||||
/// Set a string config option in the UiControl config section.
|
||||
/// Note: Not all config options will be be immediately reflected in the game.
|
||||
/// </summary>
|
||||
/// <param name="option">Name of the config option.</param>
|
||||
/// <param name="value">New value of the config option.</param>
|
||||
/// <exception cref="ConfigOptionNotFoundException">Throw if the config option is not found.</exception>
|
||||
/// <exception cref="UnreachableException">Thrown if the name of the config option is found, but the struct was not.</exception>
|
||||
public void Set(UiControlOption option, string value);
|
||||
}
|
||||
112
Dalamud/Plugin/Services/IGameGui.cs
Normal file
112
Dalamud/Plugin/Services/IGameGui.cs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
using System;
|
||||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Game.Text.SeStringHandling.Payloads;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// A class handling many aspects of the in-game UI.
|
||||
/// </summary>
|
||||
public unsafe interface IGameGui
|
||||
{
|
||||
/// <summary>
|
||||
/// Event which is fired when the game UI hiding is toggled.
|
||||
/// </summary>
|
||||
public event EventHandler<bool> UiHideToggled;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is fired when the currently hovered item changes.
|
||||
/// </summary>
|
||||
public event EventHandler<ulong> HoveredItemChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Event that is fired when the currently hovered action changes.
|
||||
/// </summary>
|
||||
public event EventHandler<HoveredAction> HoveredActionChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the game UI is hidden.
|
||||
/// </summary>
|
||||
public bool GameUiHidden { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the item ID that is currently hovered by the player. 0 when no item is hovered.
|
||||
/// If > 1.000.000, subtract 1.000.000 and treat it as HQ.
|
||||
/// </summary>
|
||||
public ulong HoveredItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the action ID that is current hovered by the player. 0 when no action is hovered.
|
||||
/// </summary>
|
||||
public HoveredAction HoveredAction { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Opens the in-game map with a flag on the location of the parameter.
|
||||
/// </summary>
|
||||
/// <param name="mapLink">Link to the map to be opened.</param>
|
||||
/// <returns>True if there were no errors and it could open the map.</returns>
|
||||
public bool OpenMapWithMapLink(MapLinkPayload mapLink);
|
||||
|
||||
/// <summary>
|
||||
/// Converts in-world coordinates to screen coordinates (upper left corner origin).
|
||||
/// </summary>
|
||||
/// <param name="worldPos">Coordinates in the world.</param>
|
||||
/// <param name="screenPos">Converted coordinates.</param>
|
||||
/// <returns>True if worldPos corresponds to a position in front of the camera and screenPos is in the viewport.</returns>
|
||||
public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos);
|
||||
|
||||
/// <summary>
|
||||
/// Converts in-world coordinates to screen coordinates (upper left corner origin).
|
||||
/// </summary>
|
||||
/// <param name="worldPos">Coordinates in the world.</param>
|
||||
/// <param name="screenPos">Converted coordinates.</param>
|
||||
/// <param name="inView">True if screenPos corresponds to a position inside the camera viewport.</param>
|
||||
/// <returns>True if worldPos corresponds to a position in front of the camera.</returns>
|
||||
public bool WorldToScreen(Vector3 worldPos, out Vector2 screenPos, out bool inView);
|
||||
|
||||
/// <summary>
|
||||
/// Converts screen coordinates to in-world coordinates via raycasting.
|
||||
/// </summary>
|
||||
/// <param name="screenPos">Screen coordinates.</param>
|
||||
/// <param name="worldPos">Converted coordinates.</param>
|
||||
/// <param name="rayDistance">How far to search for a collision.</param>
|
||||
/// <returns>True if successful. On false, worldPos's contents are undefined.</returns>
|
||||
public bool ScreenToWorld(Vector2 screenPos, out Vector3 worldPos, float rayDistance = 100000.0f);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a pointer to the game's UI module.
|
||||
/// </summary>
|
||||
/// <returns>IntPtr pointing to UI module.</returns>
|
||||
public nint GetUIModule();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the pointer to the Addon with the given name and index.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of addon to find.</param>
|
||||
/// <param name="index">Index of addon to find (1-indexed).</param>
|
||||
/// <returns>nint.Zero if unable to find UI, otherwise nint pointing to the start of the addon.</returns>
|
||||
public nint GetAddonByName(string name, int index = 1);
|
||||
|
||||
/// <summary>
|
||||
/// Find the agent associated with an addon, if possible.
|
||||
/// </summary>
|
||||
/// <param name="addonName">The addon name.</param>
|
||||
/// <returns>A pointer to the agent interface.</returns>
|
||||
public nint FindAgentInterface(string addonName);
|
||||
|
||||
/// <summary>
|
||||
/// Find the agent associated with an addon, if possible.
|
||||
/// </summary>
|
||||
/// <param name="addon">The addon address.</param>
|
||||
/// <returns>A pointer to the agent interface.</returns>
|
||||
public nint FindAgentInterface(void* addon);
|
||||
|
||||
/// <summary>
|
||||
/// Find the agent associated with an addon, if possible.
|
||||
/// </summary>
|
||||
/// <param name="addonPtr">The addon address.</param>
|
||||
/// <returns>A pointer to the agent interface.</returns>
|
||||
public IntPtr FindAgentInterface(IntPtr addonPtr);
|
||||
}
|
||||
24
Dalamud/Plugin/Services/IGameLifecycle.cs
Normal file
24
Dalamud/Plugin/Services/IGameLifecycle.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using System.Threading;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Class offering cancellation tokens for common gameplay events.
|
||||
/// </summary>
|
||||
public interface IGameLifecycle
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a token that is cancelled when Dalamud is unloading.
|
||||
/// </summary>
|
||||
public CancellationToken DalamudUnloadingToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a token that is cancelled when the game is shutting down.
|
||||
/// </summary>
|
||||
public CancellationToken GameShuttingDownToken { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a token that is cancelled when a character is logging out.
|
||||
/// </summary>
|
||||
public CancellationToken LogoutToken { get; }
|
||||
}
|
||||
68
Dalamud/Plugin/Services/IGamepadState.cs
Normal file
68
Dalamud/Plugin/Services/IGamepadState.cs
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
using System.Numerics;
|
||||
|
||||
using Dalamud.Game.ClientState.GamePad;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the game gamepad state to dalamud.
|
||||
///
|
||||
/// Will block game's gamepad input if <see cref="ImGuiConfigFlags.NavEnableGamepad"/> is set.
|
||||
/// </summary>
|
||||
public interface IGamepadState
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the pointer to the current instance of the GamepadInput struct.
|
||||
/// </summary>
|
||||
public nint GamepadInputAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the left analogue sticks tilt vector.
|
||||
/// </summary>
|
||||
public Vector2 LeftStick { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the right analogue sticks tilt vector.
|
||||
/// </summary>
|
||||
public Vector2 RightStick { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether <paramref name="button"/> has been pressed.
|
||||
///
|
||||
/// Only true on first frame of the press.
|
||||
/// If ImGuiConfigFlags.NavEnableGamepad is set, this is unreliable.
|
||||
/// </summary>
|
||||
/// <param name="button">The button to check for.</param>
|
||||
/// <returns>1 if pressed, 0 otherwise.</returns>
|
||||
public float Pressed(GamepadButtons button);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether <paramref name="button"/> is being pressed.
|
||||
///
|
||||
/// True in intervals if button is held down.
|
||||
/// If ImGuiConfigFlags.NavEnableGamepad is set, this is unreliable.
|
||||
/// </summary>
|
||||
/// <param name="button">The button to check for.</param>
|
||||
/// <returns>1 if still pressed during interval, 0 otherwise or in between intervals.</returns>
|
||||
public float Repeat(GamepadButtons button);
|
||||
|
||||
/// <summary>
|
||||
/// Gets whether <paramref name="button"/> has been released.
|
||||
///
|
||||
/// Only true the frame after release.
|
||||
/// If ImGuiConfigFlags.NavEnableGamepad is set, this is unreliable.
|
||||
/// </summary>
|
||||
/// <param name="button">The button to check for.</param>
|
||||
/// <returns>1 if released, 0 otherwise.</returns>
|
||||
public float Released(GamepadButtons button);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the raw state of <paramref name="button"/>.
|
||||
///
|
||||
/// Is set the entire time a button is pressed down.
|
||||
/// </summary>
|
||||
/// <param name="button">The button to check for.</param>
|
||||
/// <returns>1 the whole time button is pressed, 0 otherwise.</returns>
|
||||
public float Raw(GamepadButtons button);
|
||||
}
|
||||
21
Dalamud/Plugin/Services/IJobGauges.cs
Normal file
21
Dalamud/Plugin/Services/IJobGauges.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using Dalamud.Game.ClientState.JobGauge.Types;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This class converts in-memory Job gauge data to structs.
|
||||
/// </summary>
|
||||
public interface IJobGauges
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the address of the JobGauge data.
|
||||
/// </summary>
|
||||
public nint Address { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get the JobGauge for a given job.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">A JobGauge struct from ClientState.Structs.JobGauge.</typeparam>
|
||||
/// <returns>A JobGauge.</returns>
|
||||
public T Get<T>() where T : JobGaugeBase;
|
||||
}
|
||||
26
Dalamud/Plugin/Services/ILibcFunction.cs
Normal file
26
Dalamud/Plugin/Services/ILibcFunction.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System.Text;
|
||||
|
||||
using Dalamud.Game.Libc;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This class handles creating cstrings utilizing native game methods.
|
||||
/// </summary>
|
||||
public interface ILibcFunction
|
||||
{
|
||||
/// <summary>
|
||||
/// Create a new string from the given bytes.
|
||||
/// </summary>
|
||||
/// <param name="content">The bytes to convert.</param>
|
||||
/// <returns>An owned std string object.</returns>
|
||||
public OwnedStdString NewString(byte[] content);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new string form the given bytes.
|
||||
/// </summary>
|
||||
/// <param name="content">The bytes to convert.</param>
|
||||
/// <param name="encoding">A non-default encoding.</param>
|
||||
/// <returns>An owned std string object.</returns>
|
||||
public OwnedStdString NewString(string content, Encoding? encoding = null);
|
||||
}
|
||||
49
Dalamud/Plugin/Services/IObjectTable.cs
Normal file
49
Dalamud/Plugin/Services/IObjectTable.cs
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This collection represents the currently spawned FFXIV game objects.
|
||||
/// </summary>
|
||||
public interface IObjectTable : IReadOnlyCollection<GameObject>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the address of the object table.
|
||||
/// </summary>
|
||||
public nint Address { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the length of the object table.
|
||||
/// </summary>
|
||||
public int Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get an object at the specified spawn index.
|
||||
/// </summary>
|
||||
/// <param name="index">Spawn index.</param>
|
||||
/// <returns>An <see cref="GameObject"/> at the specified spawn index.</returns>
|
||||
public GameObject? this[int index] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Search for a game object by their Object ID.
|
||||
/// </summary>
|
||||
/// <param name="objectId">Object ID to find.</param>
|
||||
/// <returns>A game object or null.</returns>
|
||||
public GameObject? SearchById(ulong objectId);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the game object at the specified index of the object table.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the object.</param>
|
||||
/// <returns>The memory address of the object.</returns>
|
||||
public nint GetObjectAddress(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Create a reference to an FFXIV game object.
|
||||
/// </summary>
|
||||
/// <param name="address">The address of the object in memory.</param>
|
||||
/// <returns><see cref="GameObject"/> object or inheritor containing the requested data.</returns>
|
||||
public GameObject? CreateObjectReference(nint address);
|
||||
}
|
||||
81
Dalamud/Plugin/Services/IPartyList.cs
Normal file
81
Dalamud/Plugin/Services/IPartyList.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Dalamud.Game.ClientState.Party;
|
||||
|
||||
namespace Dalamud.Plugin.Services;
|
||||
|
||||
/// <summary>
|
||||
/// This collection represents the actors present in your party or alliance.
|
||||
/// </summary>
|
||||
public interface IPartyList : IReadOnlyCollection<PartyMember>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the amount of party members the local player has.
|
||||
/// </summary>
|
||||
public int Length { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the index of the party leader.
|
||||
/// </summary>
|
||||
public uint PartyLeaderIndex { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this group is an alliance.
|
||||
/// </summary>
|
||||
public bool IsAlliance { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the Group Manager.
|
||||
/// </summary>
|
||||
public nint GroupManagerAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the party list within the group manager.
|
||||
/// </summary>
|
||||
public nint GroupListAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the alliance member list within the group manager.
|
||||
/// </summary>
|
||||
public nint AllianceListAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID of the party.
|
||||
/// </summary>
|
||||
public long PartyId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Get a party member at the specified spawn index.
|
||||
/// </summary>
|
||||
/// <param name="index">Spawn index.</param>
|
||||
/// <returns>A <see cref="PartyMember"/> at the specified spawn index.</returns>
|
||||
public PartyMember? this[int index] { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the party member at the specified index of the party list.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the party member.</param>
|
||||
/// <returns>The memory address of the party member.</returns>
|
||||
public nint GetPartyMemberAddress(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Create a reference to an FFXIV party member.
|
||||
/// </summary>
|
||||
/// <param name="address">The address of the party member in memory.</param>
|
||||
/// <returns>The party member object containing the requested data.</returns>
|
||||
public PartyMember? CreatePartyMemberReference(nint address);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the address of the alliance member at the specified index of the alliance list.
|
||||
/// </summary>
|
||||
/// <param name="index">The index of the alliance member.</param>
|
||||
/// <returns>The memory address of the alliance member.</returns>
|
||||
public nint GetAllianceMemberAddress(int index);
|
||||
|
||||
/// <summary>
|
||||
/// Create a reference to an FFXIV alliance member.
|
||||
/// </summary>
|
||||
/// <param name="address">The address of the alliance member in memory.</param>
|
||||
/// <returns>The party member object containing the requested data.</returns>
|
||||
public PartyMember? CreateAllianceMemberReference(nint address);
|
||||
}
|
||||
150
Dalamud/Plugin/Services/ISigScanner.cs
Normal file
150
Dalamud/Plugin/Services/ISigScanner.cs
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
using System;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Dalamud.Game;
|
||||
|
||||
/// <summary>
|
||||
/// A SigScanner facilitates searching for memory signatures in a given ProcessModule.
|
||||
/// </summary>
|
||||
public interface ISigScanner
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the search on this module is performed on a copy.
|
||||
/// </summary>
|
||||
public bool IsCopy { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the ProcessModule is 32-bit.
|
||||
/// </summary>
|
||||
public bool Is32BitProcess { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base address of the search area. When copied, this will be the address of the copy.
|
||||
/// </summary>
|
||||
public IntPtr SearchBase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base address of the .text section search area.
|
||||
/// </summary>
|
||||
public IntPtr TextSectionBase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the offset of the .text section from the base of the module.
|
||||
/// </summary>
|
||||
public long TextSectionOffset { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the text section.
|
||||
/// </summary>
|
||||
public int TextSectionSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base address of the .data section search area.
|
||||
/// </summary>
|
||||
public IntPtr DataSectionBase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the offset of the .data section from the base of the module.
|
||||
/// </summary>
|
||||
public long DataSectionOffset { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the .data section.
|
||||
/// </summary>
|
||||
public int DataSectionSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the base address of the .rdata section search area.
|
||||
/// </summary>
|
||||
public IntPtr RDataSectionBase { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the offset of the .rdata section from the base of the module.
|
||||
/// </summary>
|
||||
public long RDataSectionOffset { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the size of the .rdata section.
|
||||
/// </summary>
|
||||
public int RDataSectionSize { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ProcessModule on which the search is performed.
|
||||
/// </summary>
|
||||
public ProcessModule Module { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Scan for a .data address using a .text function.
|
||||
/// This is intended to be used with IDA sigs.
|
||||
/// Place your cursor on the line calling a static address, and create and IDA sig.
|
||||
/// The signature and offset should not break through instruction boundaries.
|
||||
/// </summary>
|
||||
/// <param name="signature">The signature of the function using the data.</param>
|
||||
/// <param name="offset">The offset from function start of the instruction using the data.</param>
|
||||
/// <returns>An IntPtr to the static memory location.</returns>
|
||||
public nint GetStaticAddressFromSig(string signature, int offset = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Try scanning for a .data address using a .text function.
|
||||
/// This is intended to be used with IDA sigs.
|
||||
/// Place your cursor on the line calling a static address, and create and IDA sig.
|
||||
/// </summary>
|
||||
/// <param name="signature">The signature of the function using the data.</param>
|
||||
/// <param name="result">An IntPtr to the static memory location, if found.</param>
|
||||
/// <param name="offset">The offset from function start of the instruction using the data.</param>
|
||||
/// <returns>true if the signature was found.</returns>
|
||||
public bool TryGetStaticAddressFromSig(string signature, out nint result, int offset = 0);
|
||||
|
||||
/// <summary>
|
||||
/// Scan for a byte signature in the .data section.
|
||||
/// </summary>
|
||||
/// <param name="signature">The signature.</param>
|
||||
/// <returns>The real offset of the found signature.</returns>
|
||||
public nint ScanData(string signature);
|
||||
|
||||
/// <summary>
|
||||
/// Try scanning for a byte signature in the .data section.
|
||||
/// </summary>
|
||||
/// <param name="signature">The signature.</param>
|
||||
/// <param name="result">The real offset of the signature, if found.</param>
|
||||
/// <returns>true if the signature was found.</returns>
|
||||
public bool TryScanData(string signature, out nint result);
|
||||
|
||||
/// <summary>
|
||||
/// Scan for a byte signature in the whole module search area.
|
||||
/// </summary>
|
||||
/// <param name="signature">The signature.</param>
|
||||
/// <returns>The real offset of the found signature.</returns>
|
||||
public nint ScanModule(string signature);
|
||||
|
||||
/// <summary>
|
||||
/// Try scanning for a byte signature in the whole module search area.
|
||||
/// </summary>
|
||||
/// <param name="signature">The signature.</param>
|
||||
/// <param name="result">The real offset of the signature, if found.</param>
|
||||
/// <returns>true if the signature was found.</returns>
|
||||
public bool TryScanModule(string signature, out nint result);
|
||||
|
||||
/// <summary>
|
||||
/// Resolve a RVA address.
|
||||
/// </summary>
|
||||
/// <param name="nextInstAddr">The address of the next instruction.</param>
|
||||
/// <param name="relOffset">The relative offset.</param>
|
||||
/// <returns>The calculated offset.</returns>
|
||||
public nint ResolveRelativeAddress(nint nextInstAddr, int relOffset);
|
||||
|
||||
/// <summary>
|
||||
/// Scan for a byte signature in the .text section.
|
||||
/// </summary>
|
||||
/// <param name="signature">The signature.</param>
|
||||
/// <returns>The real offset of the found signature.</returns>
|
||||
public nint ScanText(string signature);
|
||||
|
||||
/// <summary>
|
||||
/// Try scanning for a byte signature in the .text section.
|
||||
/// </summary>
|
||||
/// <param name="signature">The signature.</param>
|
||||
/// <param name="result">The real offset of the signature, if found.</param>
|
||||
/// <returns>true if the signature was found.</returns>
|
||||
public bool TryScanText(string signature, out nint result);
|
||||
}
|
||||
44
Dalamud/Plugin/Services/ITargetManager.cs
Normal file
44
Dalamud/Plugin/Services/ITargetManager.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using Dalamud.Game.ClientState.Objects.Types;
|
||||
|
||||
namespace Dalamud.Game.ClientState.Objects;
|
||||
|
||||
/// <summary>
|
||||
/// Get and set various kinds of targets for the player.
|
||||
/// </summary>
|
||||
public interface ITargetManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the address of the target manager.
|
||||
/// </summary>
|
||||
public nint Address { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the current target.
|
||||
/// Set to null to clear the target.
|
||||
/// </summary>
|
||||
public GameObject? Target { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the mouseover target.
|
||||
/// Set to null to clear the target.
|
||||
/// </summary>
|
||||
public GameObject? MouseOverTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the focus target.
|
||||
/// Set to null to clear the target.
|
||||
/// </summary>
|
||||
public GameObject? FocusTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the previous target.
|
||||
/// Set to null to clear the target.
|
||||
/// </summary>
|
||||
public GameObject? PreviousTarget { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the soft target.
|
||||
/// Set to null to clear the target.
|
||||
/// </summary>
|
||||
public GameObject? SoftTarget { get; set; }
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue