Beispiel #1
0
        private List<string> GetScripts(string path)
        {
            var scripts = new DirectoryInfo(path).EnumerateFiles(_filter).Select(f => File.ReadAllText(f.FullName)).ToList();

            foreach (var d in new DirectoryInfo(path).EnumerateDirectories())
            {
                scripts.AddRange(GetScripts(d.FullName));
            }

            return scripts;
        }
Beispiel #2
0
        internal static void LoadPlugins()
        {
            string ignoredPluginsFilePath = Path.Combine(ServerPluginsDirectoryPath, "ignoredplugins.txt");

            List<string> ignoredFiles = new List<string>();
            if (File.Exists(ignoredPluginsFilePath))
                ignoredFiles.AddRange(File.ReadAllLines(ignoredPluginsFilePath));

            List<FileInfo> fileInfos = new DirectoryInfo(ServerPluginsDirectoryPath).GetFiles("*.dll").ToList();
            fileInfos.AddRange(new DirectoryInfo(ServerPluginsDirectoryPath).GetFiles("*.dll-plugin"));

            Dictionary<TerrariaPlugin, Stopwatch> pluginInitWatches = new Dictionary<TerrariaPlugin, Stopwatch>();
            foreach (FileInfo fileInfo in fileInfos)
            {
                string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.Name);
                if (ignoredFiles.Contains(fileNameWithoutExtension))
                {
                    LogWriter.ServerWriteLine(
                        string.Format("{0}加载时被忽视", fileNameWithoutExtension), TraceLevel.Verbose);

                    continue;
                }

                try
                {
                    Assembly assembly;
                    // The plugin assembly might have been resolved by another plugin assembly already, so no use to
                    // load it again, but we do still have to verify it and create plugin instances.
                    if (!loadedAssemblies.TryGetValue(fileNameWithoutExtension, out assembly))
                    {
                        try
                        {
                            assembly = Assembly.Load(File.ReadAllBytes(fileInfo.FullName));
                        }
                        catch (BadImageFormatException)
                        {
                            continue;
                        }
                        loadedAssemblies.Add(fileNameWithoutExtension, assembly);
                    }

                    if (!InvalidateAssembly(assembly, fileInfo.Name))
                        continue;

                    foreach (Type type in assembly.GetExportedTypes())
                    {
                        if (!type.IsSubclassOf(typeof(TerrariaPlugin)) || !type.IsPublic || type.IsAbstract)
                            continue;
                        object[] customAttributes = type.GetCustomAttributes(typeof(ApiVersionAttribute), false);
                        if (customAttributes.Length == 0)
                            continue;

                        if (!IgnoreVersion)
                        {
                            var apiVersionAttribute = (ApiVersionAttribute)customAttributes[0];
                            Version apiVersion = apiVersionAttribute.ApiVersion;
                            if (apiVersion.Major != ApiVersion.Major || apiVersion.Minor != ApiVersion.Minor)
                            {
                                LogWriter.ServerWriteLine(
                                    string.Format("插件\"{0}\"使用的API版本({1})不正确",
                                    type.FullName, apiVersion.ToString(2)), TraceLevel.Warning);

                                continue;
                            }
                        }

                        TerrariaPlugin pluginInstance;
                        try
                        {
                            Stopwatch initTimeWatch = new Stopwatch();
                            initTimeWatch.Start();

                            pluginInstance = (TerrariaPlugin)Activator.CreateInstance(type, game);

                            initTimeWatch.Stop();
                            pluginInitWatches.Add(pluginInstance, initTimeWatch);
                        }
                        catch (Exception ex)
                        {
                            // Broken plugins better stop the entire server init.
                            throw new InvalidOperationException(
                                string.Format("Could not create an instance of plugin class \"{0}\".", type.FullName), ex);
                        }
                        plugins.Add(new PluginContainer(pluginInstance));
                    }
                }
                catch (Exception ex)
                {
                    // Broken assemblies / plugins better stop the entire server init.
                    throw new InvalidOperationException(
                        string.Format("Failed to load assembly \"{0}\".", fileInfo.Name), ex);
                }
            }
            IOrderedEnumerable<PluginContainer> orderedPluginSelector =
                from x in Plugins
                orderby x.Plugin.Order, x.Plugin.Name
                select x;

            foreach (PluginContainer current in orderedPluginSelector)
            {
                Stopwatch initTimeWatch = pluginInitWatches[current.Plugin];
                initTimeWatch.Start();

                try
                {
                    current.Initialize();
                }
                catch (Exception ex)
                {
                    // Broken plugins better stop the entire server init.
                    throw new InvalidOperationException(string.Format(
                        "插件 \"{0}\" 在加载时发生错误", current.Plugin.Name), ex);
                }

                initTimeWatch.Stop();
                LogWriter.ServerWriteLine(string.Format(
                    "插件 {0} v{1} (作者 {2}) 加载完毕.", current.Plugin.Name, current.Plugin.Version, current.Plugin.Author),
                    TraceLevel.Info);
            }

            if (Profiler.WrappedProfiler != null)
            {
                foreach (var pluginWatchPair in pluginInitWatches)
                {
                    TerrariaPlugin plugin = pluginWatchPair.Key;
                    Stopwatch initTimeWatch = pluginWatchPair.Value;

                    Profiler.InputPluginInitTime(plugin, initTimeWatch.Elapsed);
                }
            }
        }
 public static void Initialize(Main main)
 {
     if (!Directory.Exists("ServerPlugins"))
     {
         if (Directory.Exists("serverplugins")){
         Console.WriteLine("Case sensitive filesystem detected - fixing your serverplugins directory");
         Directory.Move("serverplugins","ServerPlugins");}
         else{
         Directory.CreateDirectory("ServerPlugins");
         }}
     var ignoredfiles = new List<String>();
     if (File.Exists(Path.Combine("ServerPlugins", "ignoredplugins.txt")))
         ignoredfiles.AddRange(File.ReadAllLines(Path.Combine("ServerPlugins", "ignoredplugins.txt")));
     AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
     List<FileInfo> files = new DirectoryInfo("ServerPlugins").GetFiles("*.dll").ToList();
     files.AddRange(new DirectoryInfo("ServerPlugins").GetFiles("*.dll-plugin"));
     for (int i = 0; i < files.Count; i++)
     {
         FileInfo fileInfo = files[i];
         try
         {
             string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.Name);
             if (ignoredfiles.Contains(fileNameWithoutExtension))
             {
                 Console.WriteLine("{0} was ignored from being loaded.", fileNameWithoutExtension);
                 continue;
             }
             Assembly assembly;
             if (!LoadedAssemblies.TryGetValue(fileNameWithoutExtension, out assembly))
             {
                 assembly = Assembly.Load(File.ReadAllBytes(fileInfo.FullName));
                 LoadedAssemblies.Add(fileNameWithoutExtension, assembly);
             }
             Type[] types = assembly.GetTypes();
             for (int j = 0; j < types.Length; j++)
             {
                 Type type = types[j];
                 if (type.BaseType == typeof (TerrariaPlugin)) // Mono has this as a TODO.
                 {
                     if (Compatible(type))
                     {
                         Plugins.Add(new PluginContainer((TerrariaPlugin) Activator.CreateInstance(type, new object[]
                                                                                                             {
                                                                                                                 main
                                                                                                             })));
                     }
                     else
                     {
                         Console.WriteLine("Outdated plugin: {0} ({1})", fileInfo.Name, type);
                         File.AppendAllText("ErrorLog.txt", string.Format("Outdated plugin: {0} ({1})\n", fileInfo.Name, type));
                     }
                 }
             }
         }
         catch (Exception innerException)
         {
             if (innerException is TargetInvocationException)
             {
                 innerException = (innerException).InnerException;
             }
             else if (innerException is ReflectionTypeLoadException)
             {
                 var exception = (ReflectionTypeLoadException) innerException;
             }
             AppendLog(fileInfo.Name, innerException);
             Console.WriteLine("Plugin {0} failed to load", fileInfo.Name);
         }
     }
     IOrderedEnumerable<PluginContainer> orderedEnumerable =
         from x in Plugins
         orderby x.Plugin.Order , x.Plugin.Name
         select x;
     foreach (PluginContainer current in orderedEnumerable)
     {
         current.Initialize();
         Console.WriteLine("{0} v{1} ({2}) initiated.", current.Plugin.Name, current.Plugin.Version, current.Plugin.Author);
     }
 }
 internal static void LoadExtensions()
 {
     List<FileInfo> fileInfos = new DirectoryInfo(ExtensionsDirectoryPath).GetFiles("*.dll").ToList();
     fileInfos.AddRange(new DirectoryInfo(ExtensionsDirectoryPath).GetFiles("*.extension"));
     foreach (FileInfo fileInfo in fileInfos)
     {
         string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.Name);
         try
         {
             Assembly assembly;
             if (!loadedAssemblies.TryGetValue(fileNameWithoutExtension, out assembly))
             {
                 try
                 {
                     assembly = Assembly.Load(File.ReadAllBytes(fileInfo.FullName));
                 }
                 catch (BadImageFormatException)
                 {
                     continue;
                 }
                 loadedAssemblies.Add(fileNameWithoutExtension, assembly);
             }
             foreach (Type type in assembly.GetExportedTypes())
             {
                 if (!type.IsSubclassOf(typeof(HalcyonExtension)) || !type.IsPublic || type.IsAbstract)
                     continue;
                 object[] customAttributes = type.GetCustomAttributes(typeof(ApiVersionAttribute), false);
                 if (customAttributes.Length == 0)
                     continue;
                 var apiVersionAttribute = (ApiVersionAttribute)customAttributes[0];
                 Version apiVersion = apiVersionAttribute.ApiVersion;
                 if (apiVersion.Major != ApiVersion.Major || apiVersion.Minor != ApiVersion.Minor)
                 {
                     Logger.Log(
                         string.Format("Extension \"{0}\" is designed for a different Halcyon API version ({1}) and was ignored.",
                         type.FullName, apiVersion.ToString(2)));
                     continue;
                 }
                 HalcyonExtension extensionInstance;
                 extensionInstance = (HalcyonExtension)Activator.CreateInstance(type);
                 try
                 {
                     extensionInstance = (HalcyonExtension)Activator.CreateInstance(type);
                 }
                 catch (Exception ex)
                 {
                     Logger.Log(String.Format("Could not create an instance of extension class \"{0}\""), type.FullName + "\n" + ex);
                 }
                 extensions.Add(new ExtensionContainer(extensionInstance));
             }
         }
         catch (Exception ex)
         {
             Logger.Log(string.Format("Failed to load assembly \"{0}\".", fileInfo.Name) + ex);
         }
     }
     IOrderedEnumerable<ExtensionContainer> orderedExtensionSelector =
         from x in Extensions
         orderby x.Extension.Order, x.Extension.Name
         select x;
     try
     {
         int count = 0;
         foreach (ExtensionContainer current in orderedExtensionSelector)
         {
             count++;
         }
         foreach (ExtensionContainer current in orderedExtensionSelector)
         {
             try
             {
                 current.Initialize();
             }
             catch (Exception ex)
             {
                 Logger.LogNoTrace(ex.Message);
                 Logger.LogNoTrace(ex.Source);
                 Logger.LogNoTrace(ex.HelpLink);
                 Logger.LogNoTrace(ex.StackTrace);
                 // Broken extensions better stop the entire server init.
                 break;
             }
             Logger.Log(string.Format(
                 "Extension {0} v{1} (by {2}) initiated.", current.Extension.Name, current.Extension.Version, current.Extension.Author));
         }
     }
     catch
     {
     }
 }
        /// <summary>
        /// Loads all assemblies from folder where target .halcyon file is
        /// </summary>
        public static void LoadAssemblies()
        {
            string ignoredFilesPath = Path.Combine(Folder, "ignore");

            List<string> ignoredFiles = new List<string>();
            if (File.Exists(ignoredFilesPath))
                ignoredFiles.AddRange(File.ReadAllLines(ignoredFilesPath));

            List<FileInfo> fileInfos = new DirectoryInfo(Folder).GetFiles("*.dll").ToList();
            fileInfos.AddRange(new DirectoryInfo(Folder).GetFiles("*.exe"));

            foreach (FileInfo fileInfo in fileInfos)
            {
                string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.Name);
                try
                {
                    Assembly assembly;
                    // The plugin assembly might have been resolved by another plugin assembly already, so checking is required
                    if (!LoadedAssemblies.TryGetValue(fileNameWithoutExtension, out assembly))
                    {
                        try
                        {
                            assembly = Assembly.Load(File.ReadAllBytes(fileInfo.FullName));
                        }
                        catch (BadImageFormatException)
                        {
                            continue;
                        }
                        LoadedAssemblies.Add(fileNameWithoutExtension, assembly);
                    }
                }
                catch (Exception ex)
                {
                    // Broken assemblies better stop the entire referencer init.
                    Logger.Log(string.Format("Failed to load assembly \"{0}\".", fileInfo.Name) + ex);
                }
            }
            RegisterAssemblies();
        }
Beispiel #6
0
        internal static void LoadPlugins()
        {
            string ignoredPluginsFilePath = Path.Combine(ServerPluginsDirectoryPath, "ignoredplugins.txt");

            List<string> ignoredFiles = new List<string>();
            if (File.Exists(ignoredPluginsFilePath))
                ignoredFiles.AddRange(File.ReadAllLines(ignoredPluginsFilePath));

            List<FileInfo> fileInfos = new DirectoryInfo(ServerPluginsDirectoryPath).GetFiles("*.dll").ToList();
            fileInfos.AddRange(new DirectoryInfo(ServerPluginsDirectoryPath).GetFiles("*.dll-plugin"));

            Dictionary<TerrariaPlugin,Stopwatch> pluginInitWatches = new Dictionary<TerrariaPlugin,Stopwatch>();
            foreach (FileInfo fileInfo in fileInfos)
            {
                string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.Name);
                if (ignoredFiles.Contains(fileNameWithoutExtension))
                {
                    LogWriter.ServerWriteLine(
                        string.Format("{0} was ignored from being loaded.", fileNameWithoutExtension), TraceLevel.Verbose);

                    continue;
                }

                Assembly assembly;
                if (!loadedAssemblies.TryGetValue(fileNameWithoutExtension, out assembly))
                {
                    try
                    {
                        assembly = Assembly.Load(File.ReadAllBytes(fileInfo.FullName));

                        // Many types have changed with 1.14 and thus we won't even able to check the ApiVersionAttribute of types,
                        // because the types can not be loaded as they reference the old types of the old TerrariaServer assembly.
                        // We work around this by checking the referenced assemblies, if we notice a reference to the old
                        // TerrariaServer assembly, we expect it to be outdated.
                        AssemblyName[] referencedAssemblies = assembly.GetReferencedAssemblies();
                        AssemblyName terrariaServerReference = referencedAssemblies.FirstOrDefault(an => an.Name == "TerrariaServer");
                        if (terrariaServerReference != null && terrariaServerReference.Version == new Version(0, 0, 0, 0))
                        {
                            LogWriter.ServerWriteLine(
                                string.Format("Plugin assembly \"{0}\" was compiled for a Server API version prior 1.14 and was ignored.",
                                fileInfo.Name), TraceLevel.Warning);

                            continue;
                        }

                        foreach (Type type in assembly.GetExportedTypes())
                        {
                            if (!type.IsSubclassOf(typeof (TerrariaPlugin)) || !type.IsPublic || type.IsAbstract)
                                continue;
                            object[] customAttributes = type.GetCustomAttributes(typeof (ApiVersionAttribute), false);
                            if (customAttributes.Length == 0)
                                continue;

                            if (!IgnoreVersion)
                            {
                                var apiVersionAttribute = (ApiVersionAttribute)customAttributes[0];
                                Version apiVersion = apiVersionAttribute.ApiVersion;
                                if (apiVersion.Major != ApiVersion.Major || apiVersion.Minor != ApiVersion.Minor)
                                {
                                    LogWriter.ServerWriteLine(
                                        string.Format("Plugin \"{0}\" is designed for a different Server API version ({1}) and was ignored.",
                                        type.FullName, apiVersion.ToString(2)), TraceLevel.Warning);

                                    continue;
                                }
                            }

                            TerrariaPlugin pluginInstance;
                            try
                            {
                                Stopwatch initTimeWatch = new Stopwatch();
                                initTimeWatch.Start();

                                pluginInstance = (TerrariaPlugin)Activator.CreateInstance(type, game);

                                initTimeWatch.Stop();
                                pluginInitWatches.Add(pluginInstance, initTimeWatch);
                            }
                            catch (Exception ex)
                            {
                                // Broken plugins better stop the entire server init.
                                throw new InvalidOperationException(
                                    string.Format("Could not create an instance of plugin class \"{0}\".", type.FullName), ex);
                            }
                            plugins.Add(new PluginContainer(pluginInstance));
                        }
                    }
                    catch (Exception ex)
                    {
                        // Broken assemblies / plugins better stop the entire server init.
                        throw new InvalidOperationException(
                            string.Format("Failed to load assembly \"{0}\".", fileInfo.Name), ex);
                    }

                    loadedAssemblies.Add(fileNameWithoutExtension, assembly);
                }
            }
            IOrderedEnumerable<PluginContainer> orderedPluginSelector =
                from x in Plugins
                orderby x.Plugin.Order, x.Plugin.Name
                select x;

            foreach (PluginContainer current in orderedPluginSelector)
            {
                Stopwatch initTimeWatch = pluginInitWatches[current.Plugin];
                initTimeWatch.Start();

                try
                {
                    current.Initialize();
                }
                catch (Exception ex)
                {
                    // Broken plugins better stop the entire server init.
                    throw new InvalidOperationException(string.Format(
                        "Plugin \"{0}\" has thrown an exception during initialization.", current.Plugin.Name), ex);
                }

                initTimeWatch.Stop();
                LogWriter.ServerWriteLine(string.Format(
                    "Plugin {0} v{1} (by {2}) initiated.", current.Plugin.Name, current.Plugin.Version, current.Plugin.Author),
                    TraceLevel.Info);
            }

            if (Profiler.WrappedProfiler != null)
            {
                foreach (var pluginWatchPair in pluginInitWatches)
                {
                    TerrariaPlugin plugin = pluginWatchPair.Key;
                    Stopwatch initTimeWatch = pluginWatchPair.Value;

                    Profiler.InputPluginInitTime(plugin, initTimeWatch.Elapsed);
                }
            }
        }