public static ModRuleGenerator LoadModRuleGeneratorAssembly(string assemblyName) { if (_assemblyLoadFailure.ContainsKey(assemblyName)) { return(null); } if (_ruleGenerators.TryGetValue(assemblyName, out ModRuleGenerator ruleGenerator)) { return(ruleGenerator); } try { ruleGenerator = ModRuleGenerator.GetRuleGenerator(Assembly.LoadFrom(assemblyName)); if (ruleGenerator != null) { _ruleGenerators[assemblyName] = ruleGenerator; } else { _assemblyLoadFailure[assemblyName] = true; return(null); } } catch (FileNotFoundException ex) { Debug.LogException(ex, $"File {assemblyName} was not found:"); return(null); } catch (FileLoadException ex) { Debug.LogException(ex, $"A FileLoadException happened while loading assembly {assemblyName}:"); return(null); } catch (Exception ex) { Debug.LogException(ex, $"Could not load {assemblyName} due to an exception. It is being skipped for the rest of this session."); _assemblyLoadFailure[assemblyName] = true; return(null); } return(ruleGenerator); }
public static ModRuleGenerator GetRuleGenerator(Assembly assembly) { var ruleGeneratorType = assembly.GetSafeTypes().FirstOrDefault(t => t.FullName != null && t.FullName.EndsWith("AbstractRuleGenerator")); if (ruleGeneratorType == null) { throw new Exception($"Could not find AbstractRuleGenerator class in assembly {assembly}"); } var implementsType = assembly.GetSafeTypes().Where(p => ruleGeneratorType.IsAssignableFrom(p)).FirstOrDefault(t => t != ruleGeneratorType) ?? ruleGeneratorType; var initRNGMethod = ruleGeneratorType.GetMethods(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(m => m.Name.Equals("InitializeRNG") && m.ReturnType == typeof(void) && m.GetParameters().Length == 2 && m.GetParameters()[0].ParameterType == typeof(int) && m.GetParameters()[1].ParameterType == typeof(Type)); if (initRNGMethod == null) { throw new Exception($"Could not find InitializeRNG method, or its return type/parameters are of the wrong types in assembly {assembly}"); } var getHTMLMethod = implementsType.GetMethods(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(m => m.Name.Equals("GetHTMLManual") && m.ReturnType == typeof(string) && m.GetParameters().Length == 1); if (getHTMLMethod == null) { throw new Exception($"Could not find GetHTMLManual method, or its return type/parameters are of the wrong types in assembly {assembly}"); } var createRulesMethod = implementsType.GetMethods(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(m => m.Name.Equals("CreateRules") && m.ReturnType == typeof(void) && m.GetParameters().Length == 0); if (createRulesMethod == null) { throw new Exception($"Could not find CreateRules method, or its return type/parameters are of the wrong types in assembly {assembly}"); } var getTextFilesMethod = implementsType.GetMethods(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(m => m.Name.Equals("GetTextFiles") && m.ReturnType == typeof(string[]) && m.GetParameters().Length == 1 && m.GetParameters()[0].IsOut); if (getTextFilesMethod == null) { throw new Exception($"Could not find GetTextFiles method, or its return type/parameters are of the wrong types in assembly {assembly}"); } var getBinaryFilesMethod = implementsType.GetMethods(BindingFlags.Public | BindingFlags.Instance) .FirstOrDefault(m => m.Name.Equals("GetBinaryFiles") && m.ReturnType == typeof(byte[][]) && m.GetParameters().Length == 1 && m.GetParameters()[0].IsOut); if (getBinaryFilesMethod == null) { throw new Exception($"Could not find GetBinaryFiles method, or its return type/parameters are of the wrong types in assembly {assembly}"); } var ruleGen = new ModRuleGenerator { _ruleGeneratorType = implementsType, _createRules = createRulesMethod, _initRNG = initRNGMethod, _getHTMLManual = getHTMLMethod, _getTextFiles = getTextFilesMethod, _getBinaryFiles = getBinaryFilesMethod }; return(ruleGen); }