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

Commit

Permalink
fix: safe loading rotations.
Browse files Browse the repository at this point in the history
  • Loading branch information
ArchiDog1998 committed Jul 1, 2023
1 parent 910e0d0 commit 0cd704f
Show file tree
Hide file tree
Showing 3 changed files with 134 additions and 141 deletions.
247 changes: 122 additions & 125 deletions RotationSolver/Helpers/RotationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,170 +3,167 @@
using RotationSolver.Data;
using System.Diagnostics;

namespace RotationSolver.Helpers
namespace RotationSolver.Helpers;

internal static class RotationHelper
{
internal static class RotationHelper
{
private static readonly Dictionary<Assembly, AssemblyInfo> _assemblyInfos = new();
private static readonly Dictionary<Assembly, AssemblyInfo> _assemblyInfos = new();

public static List<LoadedAssembly> LoadedCustomRotations { get; } = new List<LoadedAssembly>();
public static List<LoadedAssembly> LoadedCustomRotations { get; } = new List<LoadedAssembly>();

public static string[] AllowedAssembly { get; private set; } = Array.Empty<string>();
public static string[] AllowedAssembly { get; private set; } = Array.Empty<string>();

public static async Task LoadListAsync()
public static async Task LoadListAsync()
{
try
{
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.");
}
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)
public static AssemblyInfo GetInfo(this Assembly assembly)
{
if (_assemblyInfos.TryGetValue(assembly, out var info))
{
if (_assemblyInfos.TryGetValue(assembly, out var info))
{
return 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 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);
var assemblyInfo = new AssemblyInfo(name, version, location, description, company, product, trademark);

_assemblyInfos[assembly] = assemblyInfo;
_assemblyInfos[assembly] = assemblyInfo;

return assemblyInfo;
}
return assemblyInfo;
}

public static bool IsAllowed(this ICustomRotation rotation, out string name)
{
name = "Unknown";
if (rotation == null) return false;
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;
var assembly = GetTypeAssembly(rotation);
if (assembly == null) return false;

name = assembly.GetName().Name;
return assembly.IsAllowed();
}
name = assembly.GetName().Name;
return assembly.IsAllowed();
}

public static bool IsAllowed(this Assembly assembly)
public static bool IsAllowed(this Assembly assembly)
{
if (_assemblyInfos.TryGetValue(assembly, out var info))
{
if (_assemblyInfos.TryGetValue(assembly, out var info))
{
var assemblyName = $"{info.Name} - {info.Author}";
return AllowedAssembly.Contains(assemblyName);
}
return false;
var assemblyName = $"{info.Name} - {info.Author}";
return AllowedAssembly.Contains(assemblyName);
}
return false;
}

public static Assembly GetTypeAssembly(this ICustomRotation rotation)
public static Assembly GetTypeAssembly(this ICustomRotation rotation)
{
try
{
try
{
return rotation.GetType().Assembly;
}
catch (Exception ex)
{
PluginLog.LogError($"Failed to get assembly for rotation {rotation.GetType().Name}: {ex}");
return null;
}
return rotation.GetType().Assembly;
}

public static Vector4 GetColor(this ICustomRotation rotation)
catch (Exception ex)
{
if (!rotation.IsValid)
{
return ImGuiColors.DPSRed;
}

if (!rotation.IsAllowed(out _))
{
return ImGuiColors.DalamudViolet;
}
PluginLog.LogError($"Failed to get assembly for rotation {rotation.GetType().Name}: {ex}");
return null;
}
}

if (rotation.IsBeta())
{
return ImGuiColors.DalamudOrange;
}
public static Vector4 GetColor(this ICustomRotation rotation)
{
if (!rotation.IsValid)
{
return ImGuiColors.DPSRed;
}

return ImGuiColors.DalamudWhite;
if (!rotation.IsAllowed(out _))
{
return ImGuiColors.DalamudViolet;
}

public static bool IsBeta(this ICustomRotation rotation)
if (rotation.IsBeta())
{
var betaAttribute = rotation.GetType().GetCustomAttribute<BetaRotationAttribute>();
return betaAttribute != null;
return ImGuiColors.DalamudOrange;
}

public static Assembly LoadCustomRotationAssembly(string filePath)
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)
{
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.Remove(existingAssembly);
}

_assemblyInfos[assembly] = assemblyInfo;
_assemblyInfos[assembly] = assemblyInfo;

var loadedAssembly = new LoadedAssembly(
filePath,
File.GetLastWriteTimeUtc(filePath).ToString());
var loadedAssembly = new LoadedAssembly(
filePath,
File.GetLastWriteTimeUtc(filePath).ToString());

LoadedCustomRotations.RemoveAll(item => item.FilePath == loadedAssembly.FilePath);
LoadedCustomRotations.Add(loadedAssembly);
LoadedCustomRotations.RemoveAll(item => item.FilePath == loadedAssembly.FilePath);
LoadedCustomRotations.Add(loadedAssembly);

return assembly;
}
return assembly;
}

private static Assembly GetAssemblyFromPath(string filePath)
private static Assembly GetAssemblyFromPath(string filePath)
{
foreach (var asm in _assemblyInfos)
{
foreach (var asm in _assemblyInfos)
if (asm.Value.FilePath == filePath)
{
if (asm.Value.FilePath == filePath)
{
return asm.Key;
}
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;
}
return null;
}


private static string GetAuthor(string filePath, string assemblyName)
{
var fileVersionInfo = FileVersionInfo.GetVersionInfo(filePath);
return string.IsNullOrWhiteSpace(fileVersionInfo.CompanyName) ? assemblyName : fileVersionInfo.CompanyName;
}
}
15 changes: 9 additions & 6 deletions RotationSolver/Helpers/RotationLoadContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ public RotationLoadContext(DirectoryInfo directoryInfo) : base(true)
_directory = directoryInfo;
}



static RotationLoadContext()
{
var assemblies = new Assembly[]
Expand Down Expand Up @@ -70,13 +68,18 @@ internal Assembly LoadFromFile(string filePath)
var pdbPath = Path.ChangeExtension(filePath, ".pdb");
if (!File.Exists(pdbPath))
{
PluginLog.Information($"Failed to load {pdbPath}");
PluginLog.Information($"Failed to find {pdbPath}");
return LoadFromStream(file);
}
using var pdbFile = File.Open(pdbPath, FileMode.Open, FileAccess.Read, FileShare.Read);
var assembly = LoadFromStream(file, pdbFile);

return assembly;
try
{
return LoadFromStream(file, pdbFile);
}
catch
{
return LoadFromStream(file);
}
}

}
Expand Down
13 changes: 3 additions & 10 deletions RotationSolver/Updaters/RotationUpdater.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,14 @@ private static void LoadRotationsFromLocal(string relayFolder)
{
if (Directory.Exists(dir))
{
var dlls = Directory.GetFiles(dir, "*.dll");
foreach (var dll in dlls)
foreach (var dll in Directory.GetFiles(dir, "*.dll"))
{
var assembly = LoadOne(dll);

if (assembly != null)
{
assemblies.Add(assembly);
}
else
{
return;
}
}
}
}
Expand Down Expand Up @@ -136,7 +131,6 @@ private static void LoadRotationsFromLocal(string relayFolder)
var sortedCustomRotationGroups = customRotationGroups.OrderBy(crg => crg.JobId).ToArray();
CustomRotationsDict[jobRole] = sortedCustomRotationGroups;
}

}

private static CustomRotationGroup[] LoadCustomRotationGroup(List<Assembly> assemblies)
Expand Down Expand Up @@ -274,12 +268,11 @@ private static Assembly LoadOne(string filePath)
}
catch (Exception ex)
{
PluginLog.Log(ex, "Failed to load " + filePath);
PluginLog.Warning(ex, "Failed to load " + filePath);
}
return null;
}


// This method watches for changes in local rotation files by checking the
// last modified time of the files in the directories specified in the configuration.
// If there are new changes, it triggers a reload of the custom rotation.
Expand Down Expand Up @@ -344,7 +337,7 @@ private static ICustomRotation GetRotation(Type t)
}
catch (Exception ex)
{
PluginLog.LogError(ex, $"Failed to load the rotation: {t.Name}");
PluginLog.Error(ex, $"Failed to load the rotation: {t.Name}");
return null;
}
}
Expand Down

0 comments on commit 0cd704f

Please sign in to comment.