using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace SpeedUpBounties.Helpers // original code from rrrix quest tools
{
/// <summary>
/// This class well get and set static Trinity Properties and Fields. It does not support instances.
/// </summary>
class TrinityApi
{
// Trinity_635346394618921335.dll
private const string AssemblyName = "Trinity";
// namespace Trinity, public class Trinity
private const string MainClass = "Trinity.Trinity";
private static Assembly _mainAssembly;
private static Dictionary<Tuple<string, Type>, PropertyInfo> _propertyInfoDictionary = new Dictionary<Tuple<string, Type>, PropertyInfo>();
private static Dictionary<Tuple<string, Type>, FieldInfo> _fieldInfoDictionary = new Dictionary<Tuple<string, Type>, FieldInfo>();
private static Dictionary<string, Type> _typeDictionary = new Dictionary<string, Type>();
public static Dictionary<Tuple<string, Type>, PropertyInfo> PropertyInfoDictionary
{
get { return _propertyInfoDictionary; }
set { _propertyInfoDictionary = value; }
}
public static Dictionary<Tuple<string, Type>, FieldInfo> FieldInfoDictionary
{
get { return _fieldInfoDictionary; }
set { _fieldInfoDictionary = value; }
}
public static Dictionary<string, Type> TypeDictionary
{
get { return _typeDictionary; }
set { _typeDictionary = value; }
}
/// <summary>
/// Gets a value from a Field
/// </summary>
/// <param name="typeName">The Type Name</param>
/// <param name="memberName">The Member Name</param>
/// <param name="value">The Value</param>
/// <returns>If the field was successfully returned</returns>
internal static bool GetField(string typeName, string memberName, out object value)
{
value = null;
try
{
Type targetType;
if (!SetType(typeName, out targetType))
{
return false;
}
if (targetType == null)
return false;
FieldInfo fieldInfo;
if (_fieldInfoDictionary.TryGetValue(new Tuple<string, Type>(memberName, targetType), out fieldInfo))
{
value = fieldInfo.GetValue(null);
return true;
}
fieldInfo = targetType.GetField(memberName,BindingFlags.NonPublic | BindingFlags.Instance); // [kleinerMann] add ",BindingFlags.NonPublic | BindingFlags.Instance" to get private fields
if (fieldInfo != null)
{
_fieldInfoDictionary.Add(new Tuple<string, Type>(memberName, targetType), fieldInfo);
value = fieldInfo.GetValue(null);
return true;
}
}
catch (Exception ex)
{
Logger.Log("Error reading Property {0} from Type {1} - {2}", memberName, typeName, ex.Message);
return false;
}
return false;
}
/// <summary>
/// Caches the given type by name
/// </summary>
/// <param name="name">The Type name</param>
/// <param name="result">The Type</param>
/// <returns>If the type was found</returns>
private static bool SetType(string name, out Type result)
{
result = null;
try
{
SetAssembly();
if (_mainAssembly == null)
{
return false;
}
if (TypeDictionary.TryGetValue(name, out result) && result != null)
return true;
result = _mainAssembly.GetType(name);
if (TypeDictionary.ContainsKey(name))
TypeDictionary[name] = result;
else
TypeDictionary.Add(name, result);
return true;
}
catch (Exception ex)
{
Logger.Log("Unable to read type {0} from Assembly: {2}", name, ex.Message);
return false;
}
}
/// <summary>
/// Caches the Assembly
/// </summary>
private static void SetAssembly()
{
try
{
if (_mainAssembly != null)
return;
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies().Where(x => x.GetName().Name.StartsWith(AssemblyName)).Where(asm => asm != null))
{
try
{
Type T = asm.GetType(MainClass);
if (T != null) //[kleinerMann] added to verify the correct assembly
_mainAssembly = asm;
}
catch
{
// Not the Plugin, probably the routine, keep trying
}
}
}
catch (Exception ex)
{
Logger.Log("Unable to set Assembly {2}", ex.Message);
}
}
}
}