mirror of
https://github.com/xivdev/Penumbra.git
synced 2026-01-03 06:13:45 +01:00
tmp
This commit is contained in:
parent
3c564add0e
commit
73e2793da6
48 changed files with 4231 additions and 456 deletions
168
Penumbra/Services/DalamudServices.cs
Normal file
168
Penumbra/Services/DalamudServices.cs
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
using System;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Game;
|
||||
using Dalamud.Game.ClientState;
|
||||
using Dalamud.Game.ClientState.Conditions;
|
||||
using Dalamud.Game.ClientState.Keys;
|
||||
using Dalamud.Game.ClientState.Objects;
|
||||
using Dalamud.Game.Command;
|
||||
using Dalamud.Game.Gui;
|
||||
using Dalamud.Interface;
|
||||
using Dalamud.IoC;
|
||||
using Dalamud.Plugin;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Local
|
||||
|
||||
namespace Penumbra.Services;
|
||||
|
||||
public class DalamudServices
|
||||
{
|
||||
public DalamudServices(DalamudPluginInterface pluginInterface)
|
||||
{
|
||||
pluginInterface.Inject(this);
|
||||
try
|
||||
{
|
||||
var serviceType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "Service`1" && t.IsGenericType);
|
||||
var configType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudConfiguration");
|
||||
var interfaceType = typeof(DalamudPluginInterface).Assembly.DefinedTypes.FirstOrDefault(t => t.Name == "DalamudInterface");
|
||||
if (serviceType == null || configType == null || interfaceType == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var configService = serviceType.MakeGenericType(configType);
|
||||
var interfaceService = serviceType.MakeGenericType(interfaceType);
|
||||
var configGetter = configService.GetMethod("Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
_interfaceGetter = interfaceService.GetMethod("Get", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (configGetter == null || _interfaceGetter == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_dalamudConfig = configGetter.Invoke(null, null);
|
||||
if (_dalamudConfig != null)
|
||||
{
|
||||
_saveDalamudConfig = _dalamudConfig.GetType().GetMethod("Save", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (_saveDalamudConfig == null)
|
||||
{
|
||||
_dalamudConfig = null;
|
||||
_interfaceGetter = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
_dalamudConfig = null;
|
||||
_saveDalamudConfig = null;
|
||||
_interfaceGetter = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddServices(IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton(PluginInterface);
|
||||
services.AddSingleton(Commands);
|
||||
services.AddSingleton(GameData);
|
||||
services.AddSingleton(ClientState);
|
||||
services.AddSingleton(Chat);
|
||||
services.AddSingleton(Framework);
|
||||
services.AddSingleton(Conditions);
|
||||
services.AddSingleton(Targets);
|
||||
services.AddSingleton(Objects);
|
||||
services.AddSingleton(TitleScreenMenu);
|
||||
services.AddSingleton(GameGui);
|
||||
services.AddSingleton(KeyState);
|
||||
services.AddSingleton(SigScanner);
|
||||
services.AddSingleton(this);
|
||||
}
|
||||
|
||||
// @formatter:off
|
||||
[PluginService][RequiredVersion("1.0")] public DalamudPluginInterface PluginInterface { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public CommandManager Commands { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public DataManager GameData { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public ClientState ClientState { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public ChatGui Chat { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public Framework Framework { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public Condition Conditions { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public TargetManager Targets { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public ObjectTable Objects { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public TitleScreenMenu TitleScreenMenu { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public GameGui GameGui { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public KeyState KeyState { get; private set; } = null!;
|
||||
[PluginService][RequiredVersion("1.0")] public SigScanner SigScanner { get; private set; } = null!;
|
||||
// @formatter:on
|
||||
|
||||
public const string WaitingForPluginsOption = "IsResumeGameAfterPluginLoad";
|
||||
|
||||
private readonly object? _dalamudConfig;
|
||||
private readonly MethodInfo? _interfaceGetter;
|
||||
private readonly MethodInfo? _saveDalamudConfig;
|
||||
|
||||
public bool GetDalamudConfig<T>(string fieldName, out T? value)
|
||||
{
|
||||
value = default;
|
||||
try
|
||||
{
|
||||
if (_dalamudConfig == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var getter = _dalamudConfig.GetType().GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (getter == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var result = getter.GetValue(_dalamudConfig);
|
||||
if (result is not T v)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value = v;
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Error while fetching Dalamud Config {fieldName}:\n{e}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public bool SetDalamudConfig<T>(string fieldName, in T? value, string? windowFieldName = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_dalamudConfig == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var getter = _dalamudConfig.GetType().GetProperty(fieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
if (getter == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
getter.SetValue(_dalamudConfig, value);
|
||||
if (windowFieldName != null)
|
||||
{
|
||||
var inter = _interfaceGetter!.Invoke(null, null);
|
||||
var settingsWindow = inter?.GetType().GetField("settingsWindow", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.GetValue(inter);
|
||||
settingsWindow?.GetType().GetField(windowFieldName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)?.SetValue(settingsWindow, value);
|
||||
}
|
||||
|
||||
_saveDalamudConfig!.Invoke(_dalamudConfig, null);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Penumbra.Log.Error($"Error while fetching Dalamud Config {fieldName}:\n{e}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
66
Penumbra/Services/ObjectIdentifier.cs
Normal file
66
Penumbra/Services/ObjectIdentifier.cs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Dalamud.Data;
|
||||
using Dalamud.Plugin;
|
||||
using Lumina.Excel.GeneratedSheets;
|
||||
using OtterGui.Classes;
|
||||
using Penumbra.GameData;
|
||||
using Penumbra.GameData.Enums;
|
||||
using Penumbra.GameData.Structs;
|
||||
using Penumbra.Util;
|
||||
using Action = System.Action;
|
||||
|
||||
namespace Penumbra.Services;
|
||||
|
||||
public sealed class ObjectIdentifier : IObjectIdentifier
|
||||
{
|
||||
private const string Prefix = $"[{nameof(ObjectIdentifier)}]";
|
||||
|
||||
public IObjectIdentifier? Identifier { get; private set; }
|
||||
|
||||
public bool IsDisposed { get; private set; }
|
||||
|
||||
public bool Ready
|
||||
=> Identifier != null && !IsDisposed;
|
||||
|
||||
public event Action? FinishedCreation;
|
||||
|
||||
public ObjectIdentifier(StartTimeTracker<StartTimeType> tracker, DalamudPluginInterface pi, DataManager data)
|
||||
{
|
||||
Task.Run(() =>
|
||||
{
|
||||
using var timer = tracker.Measure(StartTimeType.Identifier);
|
||||
var identifier = GameData.GameData.GetIdentifier(pi, data);
|
||||
if (IsDisposed)
|
||||
{
|
||||
identifier.Dispose();
|
||||
}
|
||||
else
|
||||
{
|
||||
Identifier = identifier;
|
||||
Penumbra.Log.Verbose($"{Prefix} Created.");
|
||||
FinishedCreation?.Invoke();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Identifier?.Dispose();
|
||||
IsDisposed = true;
|
||||
Penumbra.Log.Verbose($"{Prefix} Disposed.");
|
||||
}
|
||||
|
||||
public IGamePathParser GamePathParser
|
||||
=> Identifier?.GamePathParser ?? throw new Exception($"{Prefix} Not yet ready.");
|
||||
|
||||
public void Identify(IDictionary<string, object?> set, string path)
|
||||
=> Identifier?.Identify(set, path);
|
||||
|
||||
public Dictionary<string, object?> Identify(string path)
|
||||
=> Identifier?.Identify(path) ?? new Dictionary<string, object?>();
|
||||
|
||||
public IEnumerable<Item> Identify(SetId setId, WeaponType weaponType, ushort variant, EquipSlot slot)
|
||||
=> Identifier?.Identify(setId, weaponType, variant, slot) ?? Array.Empty<Item>();
|
||||
}
|
||||
97
Penumbra/Services/ValidityChecker.cs
Normal file
97
Penumbra/Services/ValidityChecker.cs
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Plugin;
|
||||
using Penumbra.Util;
|
||||
|
||||
namespace Penumbra;
|
||||
|
||||
public class ValidityChecker
|
||||
{
|
||||
public const string Repository = "https://raw.githubusercontent.com/xivdev/Penumbra/master/repo.json";
|
||||
public const string RepositoryLower = "https://raw.githubusercontent.com/xivdev/penumbra/master/repo.json";
|
||||
public const string TestRepositoryLower = "https://raw.githubusercontent.com/xivdev/penumbra/test/repo.json";
|
||||
|
||||
public readonly bool DevPenumbraExists;
|
||||
public readonly bool IsNotInstalledPenumbra;
|
||||
public readonly bool IsValidSourceRepo;
|
||||
|
||||
public readonly List<Exception> ImcExceptions = new();
|
||||
|
||||
public readonly string Version;
|
||||
public readonly string CommitHash;
|
||||
|
||||
public ValidityChecker(DalamudPluginInterface pi)
|
||||
{
|
||||
DevPenumbraExists = CheckDevPluginPenumbra(pi);
|
||||
IsNotInstalledPenumbra = CheckIsNotInstalled(pi);
|
||||
IsValidSourceRepo = CheckSourceRepo(pi);
|
||||
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
Version = assembly.GetName().Version?.ToString() ?? string.Empty;
|
||||
CommitHash = assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? "Unknown";
|
||||
}
|
||||
|
||||
public void LogExceptions()
|
||||
{
|
||||
if( ImcExceptions.Count > 0 )
|
||||
ChatUtil.NotificationMessage( $"{ImcExceptions} IMC Exceptions thrown during Penumbra load. Please repair your game files.", "Warning", NotificationType.Warning );
|
||||
}
|
||||
|
||||
// Because remnants of penumbra in devPlugins cause issues, we check for them to warn users to remove them.
|
||||
private static bool CheckDevPluginPenumbra( DalamudPluginInterface pi )
|
||||
{
|
||||
#if !DEBUG
|
||||
var path = Path.Combine( pi.DalamudAssetDirectory.Parent?.FullName ?? "INVALIDPATH", "devPlugins", "Penumbra" );
|
||||
var dir = new DirectoryInfo( path );
|
||||
|
||||
try
|
||||
{
|
||||
return dir.Exists && dir.EnumerateFiles( "*.dll", SearchOption.AllDirectories ).Any();
|
||||
}
|
||||
catch( Exception e )
|
||||
{
|
||||
Penumbra.Log.Error( $"Could not check for dev plugin Penumbra:\n{e}" );
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check if the loaded version of Penumbra itself is in devPlugins.
|
||||
private static bool CheckIsNotInstalled( DalamudPluginInterface pi )
|
||||
{
|
||||
#if !DEBUG
|
||||
var checkedDirectory = pi.AssemblyLocation.Directory?.Parent?.Parent?.Name;
|
||||
var ret = checkedDirectory?.Equals( "installedPlugins", StringComparison.OrdinalIgnoreCase ) ?? false;
|
||||
if( !ret )
|
||||
{
|
||||
Penumbra.Log.Error( $"Penumbra is not correctly installed. Application loaded from \"{pi.AssemblyLocation.Directory!.FullName}\"." );
|
||||
}
|
||||
|
||||
return !ret;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Check if the loaded version of Penumbra is installed from a valid source repo.
|
||||
private static bool CheckSourceRepo( DalamudPluginInterface pi )
|
||||
{
|
||||
#if !DEBUG
|
||||
return pi.SourceRepository.Trim().ToLowerInvariant() switch
|
||||
{
|
||||
null => false,
|
||||
RepositoryLower => true,
|
||||
TestRepositoryLower => true,
|
||||
_ => false,
|
||||
};
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue