/// <summary> /// Trys to start the given modules. /// Print's hint if a module was created the wrong way /// </summary> private void StartModules() { bool possibleAfterEffects = false; // Process each module foreach (Assembly moduleAssembly in _moduleAssemblies) { try { // Search for "ModulePropert" interface class in assembly // and, if given, start the module4 foreach (Type moduleClass in moduleAssembly.GetTypes()) { foreach (Type moduleInterface in moduleClass.GetInterfaces()) { if (Attribute.IsDefined(moduleInterface, typeof(ModuleProperties))) { // Load module properties from interface ModuleProperties moduleProperties = (ModuleProperties) Attribute.GetCustomAttribute(moduleInterface, typeof(ModuleProperties)); // Moduletype is not given as startup parameter -> next module; if (!ModuleTypeHandler.IsModuleTypeValid (moduleProperties.ModuleType)) { continue; } try { ConsoleOutput.AppendPrefix("\t"); // Start module _kernel.Get(moduleClass); } finally { ConsoleOutput.ResetPrefix(); } } } } } catch (ActivationException e) { ConsoleOutput.WriteLine(ConsoleType.Error, $"The module ~o~{moduleAssembly.FullName}~;~ could not start, because one or more dependecies are missing!."); if (possibleAfterEffects) { ConsoleOutput.WriteLine(ConsoleType.Note, "This could be a follow-up error, " + "because other modules have not been started."); } ConsoleOutput.WriteLine(ConsoleType.Error, $"{e.Message}"); possibleAfterEffects = true; //#if DEBUG // throw; //#endif } }
public Main() { DbConfiguration.SetConfiguration(new QueryLogDbConfiguration()); try { #region Core preparing / initialization // Clear console, set console color & write copyright ConsoleUtils.Clear(); // Prepare Console set title ConsoleHandler.Server.ConsoleHandler.PrepareConsole(); #endregion // Core preparing / initialization ConsoleUtils.SetConsoleTitle("EvoMp GT-MP Server Core. All rights reserverd."); // Load Console params ParameterHandler.LoadParams(); CheckDatabaseReset(); // Load logo ParameterHandler.SetDefault("LogoPath", "./ServerFiles/Default_Logo.txt"); string asciiLogoFile = ParameterHandler.GetValue("LogoPath"); #region Logo, Copyright, Server informations ConsoleOutput.PrintLine("-", "~#E6E6E6~"); // Write logo from logo file ConsoleOutput.WriteCentredText(ConsoleType.Note, ConsoleUtils.ParseTextFileForConsole($"{asciiLogoFile}", 2, 1)); // No Logo defined -> message and use default Logo if (ParameterHandler.IsDefault("LogoPath")) { ConsoleOutput.WriteCentredText(ConsoleType.Config, $"Using logo file ~o~\"{Path.GetFullPath($"{asciiLogoFile}")}\"~;~.\n" + $"Please start your server with the ~b~" + $"logopath ~;~ " + $"parameter."); } // GetServerGamemodes writes cfg message to if not setten string moduleTypesString = string.Join(", ", ModuleTypeHandler.GetServerGamemodes().ToList().ConvertAll(input => input.ToUpper())); const string leftServerInfo = "~#90A4AE~"; const string rightServerInfo = "~#ECEFF1~"; // Tiny gray line & Empty ConsoleOutput.PrintLine(" "); // Small centered line with headline & developer ConsoleOutput.WriteCentredText(ConsoleType.Note, "".PadRight(80, '-') + "\n" + "Server information\n" + "".PadRight(80, '-')); ConsoleOutput.WriteCentredText(ConsoleType.Info, $"{leftServerInfo}{"Server mode:".PadRight(35)}{string.Empty.PadRight(5)}{rightServerInfo}{$"{moduleTypesString}".PadRight(35)}\n" + $"{leftServerInfo}{"Runtime mode:".PadRight(35)}{string.Empty.PadRight(5)}{rightServerInfo}{$"{(Debug ? "Debugging" : "Release")}".PadRight(35)}\n" + $"{leftServerInfo}{"Server name:".PadRight(35)}{string.Empty.PadRight(5)}{rightServerInfo}{API.getServerName()}{"".PadRight(ColorUtils.CleanUp(API.getServerName()).Length > 35 ? 0 : 35 - ColorUtils.CleanUp(API.getServerName()).Length)}\n" + $"{leftServerInfo}{"Server port:".PadRight(35)}{string.Empty.PadRight(5)}{rightServerInfo}{$"{API.getServerPort():0000}".PadRight(35)}\n" + $"{leftServerInfo}{"Max players:".PadRight(35)}{string.Empty.PadRight(5)}{rightServerInfo}{$"{API.getMaxPlayers():0000}".PadRight(35)}\n"); // One empty lines ConsoleOutput.PrintLine(" "); // Small centered line with headline & developer ConsoleOutput.WriteCentredText(ConsoleType.Note, "".PadRight(80, '-') + "\n" + "Developer team\n" + "".PadRight(80, '-')); const string usernameColor = "~#ECEFF1~"; const string diTitleColor = "~#03A9F4~"; const string depyTitleColor = "~#4FC3F7~"; const string staffTitleColor = "~#B3E5FC~"; ConsoleOutput.WriteCentredText(ConsoleType.Note, $"{diTitleColor}{"Freeroam Director".PadRight(35)}{string.Empty.PadRight(5)}{usernameColor}{"Ruffo ~c~(Christian Groothoff)".PadRight(35 + 3)}\n" + $"{depyTitleColor}{"Freeroam Deputy".PadRight(35)}{string.Empty.PadRight(5)}{usernameColor}{"Koka".PadRight(35)}\n" + $"{depyTitleColor}{"Freeroam Staff".PadRight(35)}{string.Empty.PadRight(5)}{usernameColor}{"Sascha".PadRight(35)}\n" + $"{staffTitleColor}{"Freeroam Staff".PadRight(35)}{string.Empty.PadRight(5)}{usernameColor}{"James".PadRight(35)}\n" ); ConsoleOutput.PrintLine(" "); // Startup parameters ConsoleOutput.WriteCentredText(ConsoleType.Note, "".PadRight(80, '-') + "\n" + "Startup Parameters\n" + "".PadRight(80, '-')); ParameterHandler.PrintArgs(); ConsoleOutput.PrintLine(" "); ConsoleOutput.PrintLine("-"); #endregion Logo, Copyright, Server informations // Only copy and then stop. Used for docker ParameterHandler.SetDefault("onlyCopy", "false"); // Write information about Core startup ConsoleOutput.WriteLine(ConsoleType.Core, "Initializing EvoMp Core..."); // Init ModuleStructurer ModuleStructurer moduleStructurer = new ModuleStructurer(); // Copy modules & NuGet files to Server moduleStructurer.CopyModulesToServer(); moduleStructurer.CopyNuGetPackagesToServer(); // Write complete & loading modules message ConsoleOutput.WriteLine(ConsoleType.Core, "Initializing EvoMp Core completed."); if (!ParameterHandler.IsDefault("onlyCopy")) { // Finish sequence SharedEvents.OnOnCoreStartupCompleted(); ConsoleOutput.WriteLine(ConsoleType.Core, "Core startup completed"); ConsoleOutput.PrintLine("-"); ConsoleOutput.WriteLine(ConsoleType.Core, "OnlyCopy parameter has been detected! Stopping Server!"); Environment.Exit(0); } else { SharedEvents.OnOnModuleLoadingStart(API); // Load Modules new ModuleLoader(API).Load(); // Finish sequence SharedEvents.OnOnCoreStartupCompleted(); ConsoleOutput.WriteLine(ConsoleType.Core, "Core startup completed"); ConsoleOutput.PrintLine("-"); } SharedEvents.OnOnAfterCoreStartupCompleted(); } catch (Exception e) { //#if DEBUG ConsoleOutput.WriteException(e.ToString()); Exception innerException = e.InnerException; while (innerException != null) { ConsoleOutput.WriteException(innerException.ToString()); innerException = innerException.InnerException; } //throw lastInnerException; //#endif } }
/// <summary> /// Trys to bind the given modules. /// Print's hint if a module was created the wrong way /// </summary> /// <param name="modulePaths">Path to the modules, wich should binded</param> /// <returns>IKernel</returns> private void BindModules(IEnumerable <string> modulePaths) { ConsoleOutput.AppendPrefix("\t"); // Progressing each module foreach (string modulePath in modulePaths) { bool hasNeededInterface = false; // load assembly Assembly moduleAssembly = Assembly.LoadFrom(modulePath); //Search for interface that's using the ModuleProperties attribute foreach (Type moduleClass in moduleAssembly.GetTypes()) { foreach (Type moduleInterface in moduleClass.GetInterfaces()) { if (Attribute.IsDefined(moduleInterface, typeof(ModuleProperties))) { hasNeededInterface = true; // Main module class didn't based on BaseModule -> Exception if (!moduleClass.GetAllBaseTypes().Contains(typeof(BaseModule))) { throw new NotValidModuleException( $"The module {modulePath} didn't base on the \"BaseModule\" abstract class." + Environment.NewLine + "Inherit from the BaseModule class."); } // Load module interface Attribute, to get module informations ModuleProperties moduleProperties = (ModuleProperties) Attribute.GetCustomAttribute(moduleInterface, typeof(ModuleProperties)); // Moduletype is not given as startup parameter -> Message & next module; if (!ModuleTypeHandler.IsModuleTypeValid(moduleProperties.ModuleType)) { ConsoleOutput.WriteLine(ConsoleType.Core, $"~#51ff76~{moduleInterface.Name}~;~ skipped. Wrong gamemode. ~c~{moduleProperties.ModuleType}"); continue; } // Console output ConsoleOutput.WriteLine(ConsoleType.Core, $"~#51ff76~{moduleInterface.Name}~;~ -> ~#83ff9d~{moduleClass.FullName}~;~."); // Add to list & bind module _moduleAssemblies.Add(moduleAssembly); _kernel.Bind(moduleInterface, moduleClass).To(moduleClass).InSingletonScope() .WithConstructorArgument("api", context => Api).OnActivation(SharedEvents.OnOnModuleLoaded); } } } // No implemention of "ModuleProperties" -> exception if (!hasNeededInterface) { throw new NotValidModuleException( $"The module {modulePath} didn't implement the \"ModuleAttribute\" " + "in the main Interface. " + Environment.NewLine + "Please add the needed interface"); } } // Sort modules by priority _moduleAssemblies.Sort((assembly1, assembly2) => { int GetAssemblyPrio(Assembly ass) { foreach (Type moduleClass in ass.GetTypes()) { foreach (Type moduleInterface in moduleClass.GetInterfaces()) { if (Attribute.IsDefined(moduleInterface, typeof(ModuleProperties))) { // Load module properties from interface ModuleProperties moduleProperties = (ModuleProperties) Attribute.GetCustomAttribute(moduleInterface, typeof(ModuleProperties)); // Moduletype is not given as startup parameter -> next module; if (!ModuleTypeHandler.IsModuleTypeValid (moduleProperties.ModuleType)) { continue; } return(moduleProperties.Priority); } } } return(int.MaxValue); } return(GetAssemblyPrio(assembly1).CompareTo(GetAssemblyPrio(assembly2))); }); ConsoleOutput.WriteLine(ConsoleType.Core, "Sort modules done."); ConsoleOutput.ResetPrefix(); // return created kernel }