示例#1
0
        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);
        }