This repository has been archived by the owner on Aug 28, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 82
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #308 from RiotNOR/dev-testing
Refactor of RotationUpdater and RotationUpdater, tidied up Rotation list
- Loading branch information
Showing
13 changed files
with
554 additions
and
326 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace RotationSolver.Data | ||
{ | ||
internal record AssemblyInfo( | ||
string Name, | ||
string Author, | ||
string FilePath, | ||
string SupportLink, | ||
string HelpLink, | ||
string ChangeLog, | ||
string DonateLink); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace RotationSolver.Data | ||
{ | ||
internal record CustomRotationGroup(ClassJobID JobId, ClassJobID[] ClassJobIds, ICustomRotation[] Rotations); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.Threading.Tasks; | ||
|
||
namespace RotationSolver.Data | ||
{ | ||
[Flags] | ||
public enum DownloadOption : byte | ||
{ | ||
Local = 0, | ||
Download = 1 << 0, | ||
MustDownload = Download | 1 << 1, | ||
ShowList = 1 << 2, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
namespace RotationSolver.Data | ||
{ | ||
internal record LoadedAssembly( | ||
string FilePath, | ||
string LastModified); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
using Dalamud.Interface.Colors; | ||
using Dalamud.Logging; | ||
using RotationSolver.Data; | ||
using System.Diagnostics; | ||
|
||
namespace RotationSolver.Helpers | ||
{ | ||
internal static class RotationHelper | ||
{ | ||
private static readonly Dictionary<Assembly, AssemblyInfo> _assemblyInfos = new(); | ||
|
||
public static List<LoadedAssembly> LoadedCustomRotations { get; } = new List<LoadedAssembly>(); | ||
|
||
public static string[] AllowedAssembly { get; private set; } = Array.Empty<string>(); | ||
|
||
public static async Task LoadListAsync() | ||
{ | ||
try | ||
{ | ||
using var client = new HttpClient(); | ||
var response = await client.GetAsync("https://raw.githubusercontent.com/ArchiDog1998/RotationSolver/main/Resources/whitelist.json"); | ||
response.EnsureSuccessStatusCode(); | ||
var content = await response.Content.ReadAsStringAsync(); | ||
AllowedAssembly = JsonConvert.DeserializeObject<string[]>(content); | ||
} | ||
catch (Exception ex) | ||
{ | ||
PluginLog.Log(ex, "Failed to load white List."); | ||
} | ||
} | ||
|
||
public static AssemblyInfo GetInfo(this Assembly assembly) | ||
{ | ||
if (_assemblyInfos.TryGetValue(assembly, out var info)) | ||
{ | ||
return info; | ||
} | ||
|
||
var name = assembly.GetName().Name; | ||
var location = assembly.Location; | ||
var version = assembly.GetName().Version?.ToString(); | ||
var description = assembly.GetCustomAttribute<AssemblyDescriptionAttribute>()?.Description; | ||
var company = assembly.GetCustomAttribute<AssemblyCompanyAttribute>()?.Company; | ||
var product = assembly.GetCustomAttribute<AssemblyProductAttribute>()?.Product; | ||
var trademark = assembly.GetCustomAttribute<AssemblyTrademarkAttribute>()?.Trademark; | ||
|
||
var assemblyInfo = new AssemblyInfo(name, version, location, description, company, product, trademark); | ||
|
||
_assemblyInfos[assembly] = assemblyInfo; | ||
|
||
return assemblyInfo; | ||
} | ||
|
||
public static bool IsAllowed(this ICustomRotation rotation, out string name) | ||
{ | ||
name = "Unknown"; | ||
if (rotation == null) return false; | ||
|
||
var assembly = GetTypeAssembly(rotation); | ||
if (assembly == null) return false; | ||
|
||
name = assembly.GetName().Name; | ||
return assembly.IsAllowed(); | ||
} | ||
|
||
public static bool IsAllowed(this Assembly assembly) | ||
{ | ||
if (_assemblyInfos.TryGetValue(assembly, out var info)) | ||
{ | ||
var assemblyName = $"{info.Name} - {info.Author}"; | ||
return AllowedAssembly.Contains(assemblyName); | ||
} | ||
return false; | ||
} | ||
|
||
public static Assembly GetTypeAssembly(this ICustomRotation rotation) | ||
{ | ||
try | ||
{ | ||
return rotation.GetType().Assembly; | ||
} | ||
catch (Exception ex) | ||
{ | ||
PluginLog.LogError($"Failed to get assembly for rotation {rotation.GetType().Name}: {ex}"); | ||
return null; | ||
} | ||
} | ||
|
||
public static Vector4 GetColor(this ICustomRotation rotation) | ||
{ | ||
if (!rotation.IsValid) | ||
{ | ||
return ImGuiColors.DPSRed; | ||
} | ||
|
||
if (!rotation.IsAllowed(out _)) | ||
{ | ||
return ImGuiColors.DalamudViolet; | ||
} | ||
|
||
if (rotation.IsBeta()) | ||
{ | ||
return ImGuiColors.DalamudOrange; | ||
} | ||
|
||
return ImGuiColors.DalamudWhite; | ||
} | ||
|
||
public static bool IsBeta(this ICustomRotation rotation) | ||
{ | ||
var betaAttribute = rotation.GetType().GetCustomAttribute<BetaRotationAttribute>(); | ||
return betaAttribute != null; | ||
} | ||
|
||
public static Assembly LoadCustomRotationAssembly(string filePath) | ||
{ | ||
var directoryInfo = new FileInfo(filePath).Directory; | ||
var loadContext = new RotationLoadContext(directoryInfo); | ||
var assembly = loadContext.LoadFromFile(filePath); | ||
|
||
var assemblyName = assembly.GetName().Name; | ||
var author = GetAuthor(filePath, assemblyName); | ||
|
||
var attr = assembly.GetCustomAttribute<AssemblyLinkAttribute>(); | ||
var assemblyInfo = new AssemblyInfo( | ||
assemblyName, | ||
author, | ||
filePath, | ||
attr?.SupportLink, | ||
attr?.HelpLink, | ||
attr?.ChangeLog, | ||
attr?.Donate); | ||
|
||
var existingAssembly = GetAssemblyFromPath(filePath); | ||
if (existingAssembly != null) | ||
{ | ||
_assemblyInfos.Remove(existingAssembly); | ||
} | ||
|
||
_assemblyInfos[assembly] = assemblyInfo; | ||
|
||
var loadedAssembly = new LoadedAssembly( | ||
filePath, | ||
File.GetLastWriteTimeUtc(filePath).ToString()); | ||
|
||
LoadedCustomRotations.RemoveAll(item => item.FilePath == loadedAssembly.FilePath); | ||
LoadedCustomRotations.Add(loadedAssembly); | ||
|
||
return assembly; | ||
} | ||
|
||
private static Assembly GetAssemblyFromPath(string filePath) | ||
{ | ||
foreach (var asm in _assemblyInfos) | ||
{ | ||
if (asm.Value.FilePath == filePath) | ||
{ | ||
return asm.Key; | ||
} | ||
} | ||
return null; | ||
} | ||
|
||
private static string GetAuthor(string filePath, string assemblyName) | ||
{ | ||
var fileVersionInfo = FileVersionInfo.GetVersionInfo(filePath); | ||
return string.IsNullOrWhiteSpace(fileVersionInfo.CompanyName) ? assemblyName : fileVersionInfo.CompanyName; | ||
} | ||
|
||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
using System.Runtime.Loader; | ||
|
||
using Dalamud.Logging; | ||
using Dalamud.Plugin; | ||
|
||
using FFXIVClientStructs.Interop; | ||
|
||
using Lumina.Excel; | ||
using Lumina.Excel.CustomSheets; | ||
|
||
namespace RotationSolver.Helpers | ||
{ | ||
internal class RotationLoadContext : AssemblyLoadContext | ||
{ | ||
readonly DirectoryInfo _directory; | ||
|
||
static Dictionary<string, Assembly> _handledAssemblies; | ||
public RotationLoadContext(DirectoryInfo directoryInfo) : base(true) | ||
{ | ||
_directory = directoryInfo; | ||
} | ||
|
||
|
||
|
||
static RotationLoadContext() | ||
{ | ||
var assemblies = new Assembly[] | ||
{ | ||
typeof(RotationSolverPlugin).Assembly, | ||
typeof(Resolver).Assembly, | ||
typeof(DalamudPluginInterface).Assembly, | ||
typeof(DataCenter).Assembly, | ||
typeof(SheetAttribute).Assembly, | ||
typeof(QuestDialogueText).Assembly, | ||
}; | ||
|
||
_handledAssemblies = new Dictionary<string, Assembly>(); | ||
|
||
foreach (var assembly in assemblies) | ||
{ | ||
_handledAssemblies.Add(assembly.GetName().Name, assembly); | ||
} | ||
} | ||
|
||
protected override Assembly Load(AssemblyName assemblyName) | ||
{ | ||
if (assemblyName.Name != null && _handledAssemblies.TryGetValue(assemblyName.Name, out Assembly value)) | ||
{ | ||
return value; | ||
} | ||
|
||
var file = Path.Join(_directory.FullName, $"{assemblyName.Name}.dll"); | ||
if (File.Exists(file)) | ||
{ | ||
try | ||
{ | ||
return LoadFromFile(file); | ||
} | ||
catch | ||
{ | ||
// | ||
} | ||
} | ||
return base.Load(assemblyName); | ||
} | ||
|
||
internal Assembly LoadFromFile(string filePath) | ||
{ | ||
using var file = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.Read); | ||
var pdbPath = Path.ChangeExtension(filePath, ".pdb"); | ||
if (!File.Exists(pdbPath)) | ||
{ | ||
PluginLog.Information($"Failed to load {pdbPath}"); | ||
return LoadFromStream(file); | ||
} | ||
using var pdbFile = File.Open(pdbPath, FileMode.Open, FileAccess.Read, FileShare.Read); | ||
var assembly = LoadFromStream(file, pdbFile); | ||
|
||
return assembly; | ||
} | ||
|
||
} | ||
} |
Oops, something went wrong.