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; }
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(); }
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); } } }