Skip to content
This repository has been archived by the owner on Aug 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #308 from RiotNOR/dev-testing
Browse files Browse the repository at this point in the history
Refactor of RotationUpdater and RotationUpdater, tidied up Rotation list
  • Loading branch information
ArchiDog1998 authored May 18, 2023
2 parents 0127162 + ccba5b1 commit ead458b
Show file tree
Hide file tree
Showing 13 changed files with 554 additions and 326 deletions.
1 change: 1 addition & 0 deletions RotationSolver/Commands/RSCommands_Actions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Dalamud.Game.ClientState.Conditions;
using Dalamud.Logging;
using Lumina.Excel.GeneratedSheets;
using RotationSolver.Helpers;
using RotationSolver.Localization;
using RotationSolver.Updaters;

Expand Down
17 changes: 17 additions & 0 deletions RotationSolver/Data/AssemblyInfo.cs
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);
}
10 changes: 10 additions & 0 deletions RotationSolver/Data/CustomRotationGroup.cs
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);
}
17 changes: 17 additions & 0 deletions RotationSolver/Data/DownloadOption.cs
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,
}
}
6 changes: 6 additions & 0 deletions RotationSolver/Data/LoadedAssembly.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace RotationSolver.Data
{
internal record LoadedAssembly(
string FilePath,
string LastModified);
}
172 changes: 172 additions & 0 deletions RotationSolver/Helpers/RotationHelper.cs
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;
}


}
}
83 changes: 83 additions & 0 deletions RotationSolver/Helpers/RotationLoadContext.cs
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;
}

}
}
Loading

0 comments on commit ead458b

Please sign in to comment.