From 8f8b1bfa5a642934af5d02f54b9c12c131174f1e Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Tue, 7 Nov 2017 15:53:45 -0500 Subject: [PATCH 01/11] Normalize instance paths before storing --- TGServerService/DeprecatedInstanceConfig.cs | 2 +- TGServerService/Program.cs | 12 ++++++++++++ TGServerService/Service.cs | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/TGServerService/DeprecatedInstanceConfig.cs b/TGServerService/DeprecatedInstanceConfig.cs index 0c201ae057..9eff86cc04 100644 --- a/TGServerService/DeprecatedInstanceConfig.cs +++ b/TGServerService/DeprecatedInstanceConfig.cs @@ -20,7 +20,7 @@ namespace TGServerService public static IInstanceConfig CreateFromNETSettings() { var Config = Properties.Settings.Default; - var result = new DeprecatedInstanceConfig(LoadPreviousNetPropertyOrDefault("ServerDirectory", "C:\\tgstation-server-3")); + var result = new DeprecatedInstanceConfig(Program.NormalizePath(LoadPreviousNetPropertyOrDefault("ServerDirectory", "C:\\tgstation-server-3"))); // using nameof for sanity where possible result.ProjectName = LoadPreviousNetPropertyOrDefault(nameof(ProjectName), result.ProjectName); result.Port = LoadPreviousNetPropertyOrDefault("ServerPort", result.Port); diff --git a/TGServerService/Program.cs b/TGServerService/Program.cs index a9c208a629..5184c9f194 100644 --- a/TGServerService/Program.cs +++ b/TGServerService/Program.cs @@ -175,5 +175,17 @@ namespace TGServerService { return input.Replace("%", "%25").Replace("=", "%3d").Replace(";", "%3b").Replace("&", "%26").Replace("+", "%2b"); } + + /// + /// Normalizes different versions of a path + /// + /// The path to normalize + /// The normalized path + public static string NormalizePath(string path) + { + return Path.GetFullPath(new Uri(path).LocalPath) + .TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar) + .ToUpperInvariant(); + } } } diff --git a/TGServerService/Service.cs b/TGServerService/Service.cs index c4835b0a66..a47c89511b 100644 --- a/TGServerService/Service.cs +++ b/TGServerService/Service.cs @@ -471,6 +471,7 @@ namespace TGServerService /// public string CreateInstance(string Name, string path) { + path = Program.NormalizePath(path); var res = CheckInstanceName(Name); if (res != null) return res; @@ -529,6 +530,7 @@ namespace TGServerService /// public string ImportInstance(string path) { + path = Program.NormalizePath(path); var Config = Properties.Settings.Default; lock (this) { From 506c98c59200a48a16862a1e7338e8b026d67254 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Tue, 7 Nov 2017 16:59:56 -0500 Subject: [PATCH 02/11] Breaks up ITGSService into itself, ITGLanding, and ITGInstanceManager --- TGCommandLine/Program.cs | 2 +- TGCommandLine/ServiceCommands.cs | 43 +++++++------ TGControlPanel/InstanceSelector.cs | 23 +++---- ...Manager.cs => RootAuthorizationManager.cs} | 10 ++- .../ServerInstance/Administration.cs | 9 +++ .../ServerInstance/ServerInstance.cs | 1 + TGServerService/Service.cs | 10 +-- TGServerService/TGServerService.csproj | 2 +- TGServiceInterface/Components/Connectivity.cs | 7 -- TGServiceInterface/Components/Instance.cs | 7 ++ .../Components/InstanceManager.cs | 62 ++++++++++++++++++ TGServiceInterface/Components/Landing.cs | 25 ++++++++ TGServiceInterface/Components/Service.cs | 64 +------------------ TGServiceInterface/Interface.cs | 40 +++++++----- TGServiceInterface/TGServiceInterface.csproj | 2 + 15 files changed, 180 insertions(+), 127 deletions(-) rename TGServerService/{AdministrativeAuthorizationManager.cs => RootAuthorizationManager.cs} (73%) create mode 100644 TGServiceInterface/Components/InstanceManager.cs create mode 100644 TGServiceInterface/Components/Landing.cs diff --git a/TGCommandLine/Program.cs b/TGCommandLine/Program.cs index 738434571d..fb0e245d09 100644 --- a/TGCommandLine/Program.cs +++ b/TGCommandLine/Program.cs @@ -85,7 +85,7 @@ namespace TGCommandLine } else if (interactive && !saidSrvVersion) { - Console.WriteLine("Connectd to service version: " + currentInterface.GetService().Version()); + Console.WriteLine("Connectd to service version: " + currentInterface.GetServiceComponent().Version()); saidSrvVersion = true; } diff --git a/TGCommandLine/ServiceCommands.cs b/TGCommandLine/ServiceCommands.cs index efbc628e7d..a52cd40dec 100644 --- a/TGCommandLine/ServiceCommands.cs +++ b/TGCommandLine/ServiceCommands.cs @@ -1,11 +1,12 @@ using System; using System.Collections.Generic; using TGServiceInterface; +using TGServiceInterface.Components; namespace TGCommandLine { /// - /// Used for managing the + /// Used for managing the components /// class ServiceCommand : RootCommand { @@ -26,7 +27,7 @@ namespace TGCommandLine } /// - /// Command for calling + /// Command for calling /// class ServiceCreateInstanceCommand : ConsoleCommand { @@ -54,7 +55,7 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetService().CreateInstance(parameters[0], parameters[1]); + var res = Interface.GetServiceComponent().CreateInstance(parameters[0], parameters[1]); if (res != null) { OutputProc(res); @@ -65,7 +66,7 @@ namespace TGCommandLine } /// - /// Command for calling + /// Command for calling /// class ServiceListInstancesCommand : ConsoleCommand { @@ -86,14 +87,14 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - foreach (var I in Interface.GetService().ListInstances()) + foreach (var I in Interface.GetServiceComponent().ListInstances()) OutputProc(String.Format("{0} ({1}):\t{2}{3}", I.Name, I.Path, I.Enabled ? "Online" : "Offline", I.Enabled ? String.Format(" ({0})", I.LoggingID) : "")); return ExitCode.Normal; } } /// - /// Command for calling + /// Command for calling /// class ServiceDetachInstanceCommand : ConsoleCommand { @@ -121,7 +122,7 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetService().DetachInstance(parameters[0]); + var res = Interface.GetServiceComponent().DetachInstance(parameters[0]); if (res != null) { OutputProc(res); @@ -132,7 +133,7 @@ namespace TGCommandLine } /// - /// Command for calling + /// Command for calling /// class ServiceImportInstanceCommand : ConsoleCommand { @@ -160,7 +161,7 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetService().ImportInstance(parameters[0]); + var res = Interface.GetServiceComponent().ImportInstance(parameters[0]); if (res != null) { OutputProc(res); @@ -171,7 +172,7 @@ namespace TGCommandLine } /// - /// Command for calling + /// Command for calling /// class ServicePythonPathCommand : ConsoleCommand { @@ -192,7 +193,7 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetService().PythonPath(); + var res = Interface.GetServiceComponent().PythonPath(); if (res != null) { OutputProc(res); @@ -203,7 +204,7 @@ namespace TGCommandLine } /// - /// Command for calling + /// Command for calling /// class ServiceSetPythonPathCommand : ConsoleCommand { @@ -231,13 +232,13 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - Interface.GetService().SetPythonPath(parameters[0]); + Interface.GetServiceComponent().SetPythonPath(parameters[0]); return ExitCode.Normal; } } /// - /// Command for calling with a parameter + /// Command for calling with a parameter /// class ServiceEnableInstanceCommand : ConsoleCommand { @@ -265,7 +266,7 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetService().SetInstanceEnabled(parameters[0], true); + var res = Interface.GetServiceComponent().SetInstanceEnabled(parameters[0], true); if (res != null) { OutputProc(res); @@ -276,7 +277,7 @@ namespace TGCommandLine } /// - /// Command for calling with a parameter + /// Command for calling with a parameter /// class ServiceDisableInstanceCommand : ConsoleCommand { @@ -304,7 +305,7 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetService().SetInstanceEnabled(parameters[0], false); + var res = Interface.GetServiceComponent().SetInstanceEnabled(parameters[0], false); if (res != null) { OutputProc(res); @@ -336,7 +337,7 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - OutputProc(Interface.GetService().RemoteAccessPort().ToString()); + OutputProc(Interface.GetServiceComponent().RemoteAccessPort().ToString()); return ExitCode.Normal; } } @@ -381,7 +382,7 @@ namespace TGCommandLine return ExitCode.BadCommand; } - var res = Interface.GetService().SetRemoteAccessPort(port); + var res = Interface.GetServiceComponent().SetRemoteAccessPort(port); if (res != null) { OutputProc(res); @@ -393,7 +394,7 @@ namespace TGCommandLine } /// - /// Command for calling + /// Command for calling /// class ServiceRenameInstanceCommand : ConsoleCommand { @@ -421,7 +422,7 @@ namespace TGCommandLine /// protected override ExitCode Run(IList parameters) { - var res = Interface.GetService().RenameInstance(parameters[0], parameters[1]); + var res = Interface.GetServiceComponent().RenameInstance(parameters[0], parameters[1]); if (res != null) { OutputProc(res); diff --git a/TGControlPanel/InstanceSelector.cs b/TGControlPanel/InstanceSelector.cs index 607227b771..15f3f9e360 100644 --- a/TGControlPanel/InstanceSelector.cs +++ b/TGControlPanel/InstanceSelector.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using System.Windows.Forms; using TGServiceInterface; +using TGServiceInterface.Components; namespace TGControlPanel { @@ -77,13 +78,13 @@ namespace TGControlPanel } /// - /// Loads the using + /// Loads the using /// async void RefreshInstances() { InstanceListBox.Items.Clear(); await WrapServerOp(() => { - InstanceData = masterInterface.GetService().ListInstances(); + InstanceData = masterInterface.GetServiceComponent().ListInstances(); }); foreach(var I in InstanceData) InstanceListBox.Items.Add(String.Format("{0}: {1} - {2} - {3}", I.LoggingID, I.Name, I.Path, I.Enabled ? "ONLINE" : "OFFLINE")); @@ -92,7 +93,7 @@ namespace TGControlPanel /// /// Tries to start a for a given /// - /// The name of the to connect to + /// The name of the to connect to async void TryConnectToInstance(string instanceName) { if(ControlPanel.InstancesInUse.TryGetValue(instanceName, out ControlPanel activeCP)) @@ -123,7 +124,7 @@ namespace TGControlPanel } /// - /// Prompts the user for parameters to + /// Prompts the user for parameters to /// /// The sender of the event /// The @@ -135,7 +136,7 @@ namespace TGControlPanel if (MessageBox.Show(String.Format("This will dissociate the server instance at \"{0}\"! Are you sure?", imd.Path), "Instance Detach", MessageBoxButtons.YesNo) != DialogResult.Yes) return; string res = null; - await WrapServerOp(() => { res = masterInterface.GetService().DetachInstance(imd.Name); }); + await WrapServerOp(() => { res = masterInterface.GetServiceComponent().DetachInstance(imd.Name); }); if (res != null) MessageBox.Show(res); RefreshInstances(); @@ -152,7 +153,7 @@ namespace TGControlPanel } /// - /// Prompts the user for parameters to + /// Prompts the user for parameters to /// /// The sender of the event /// The @@ -167,14 +168,14 @@ namespace TGControlPanel if (imd.Enabled && MessageBox.Show(String.Format("This will temporarily offline the server instance! Are you sure?", imd.Path), "Instance Restart", MessageBoxButtons.YesNo) != DialogResult.Yes) return; string res = null; - await WrapServerOp(() => { res = masterInterface.GetService().RenameInstance(imd.Name, new_name); }); + await WrapServerOp(() => { res = masterInterface.GetServiceComponent().RenameInstance(imd.Name, new_name); }); if (res != null) MessageBox.Show(res); RefreshInstances(); } /// - /// Prompts the user for parameters to + /// Prompts the user for parameters to /// /// The sender of the event /// The @@ -184,14 +185,14 @@ namespace TGControlPanel if (instance_path == null) return; string res = null; - await WrapServerOp(() => { res = masterInterface.GetService().ImportInstance(instance_path); }); + await WrapServerOp(() => { res = masterInterface.GetServiceComponent().ImportInstance(instance_path); }); if (res != null) MessageBox.Show(res); RefreshInstances(); } /// - /// Prompts the user for parameters to + /// Prompts the user for parameters to /// /// The sender of the event /// The @@ -204,7 +205,7 @@ namespace TGControlPanel if (instance_path == null) return; string res = null; - await WrapServerOp(() => { res = masterInterface.GetService().CreateInstance(instance_name, instance_path); }); + await WrapServerOp(() => { res = masterInterface.GetServiceComponent().CreateInstance(instance_name, instance_path); }); if (res != null) MessageBox.Show(res); RefreshInstances(); diff --git a/TGServerService/AdministrativeAuthorizationManager.cs b/TGServerService/RootAuthorizationManager.cs similarity index 73% rename from TGServerService/AdministrativeAuthorizationManager.cs rename to TGServerService/RootAuthorizationManager.cs index e5aaf062d5..f3f45d0983 100644 --- a/TGServerService/AdministrativeAuthorizationManager.cs +++ b/TGServerService/RootAuthorizationManager.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.Diagnostics; +using System.Linq; using System.Security.Principal; using System.ServiceModel; using TGServiceInterface.Components; @@ -9,21 +11,23 @@ namespace TGServerService /// /// A used to determine only if the caller is an admin /// - sealed class AdministrativeAuthorizationManager : ServiceAuthorizationManager + sealed class RootAuthorizationManager : ServiceAuthorizationManager { string LastSeenUser; + public static readonly IList InstanceAuthManagers = new List(); protected override bool CheckAccessCore(OperationContext operationContext) { var contract = operationContext.EndpointDispatcher.ContractName; - if (contract == typeof(ITGConnectivity).Name) //always allow connectivity checks return true; - + var windowsIdent = operationContext.ServiceSecurityContext.WindowsIdentity; var wp = new WindowsPrincipal(windowsIdent); //first allow admins var authSuccess = wp.IsInRole(WindowsBuiltInRole.Administrator); + if(!authSuccess && contract == typeof(ITGLanding).Name) + return InstanceAuthManagers.FirstOrDefault(x => x.CheckAccess(operationContext)) != null; var user = windowsIdent.Name; if (LastSeenUser != user) diff --git a/TGServerService/ServerInstance/Administration.cs b/TGServerService/ServerInstance/Administration.cs index 87891795af..affe43a2b7 100644 --- a/TGServerService/ServerInstance/Administration.cs +++ b/TGServerService/ServerInstance/Administration.cs @@ -73,6 +73,7 @@ namespace TGServerService /// The name of the group allowed to access the if it could be found, otherwise string FindTheDroidsWereLookingFor(string search = null, bool useDomain = false) { + RootAuthorizationManager.InstanceAuthManagers.Add(this); //find the group that is authorized to use the tools var pc = new PrincipalContext(useDomain ? ContextType.Domain : ContextType.Machine); var groupName = search ?? Config.AuthorizedUserGroupSID; @@ -95,6 +96,14 @@ namespace TGServerService } return gp.Name; } + + /// + /// Cleans up the component + /// + void DisposeAdministration() + { + RootAuthorizationManager.InstanceAuthManagers.Remove(this); + } /// /// Called by WCF whenever a component call is made. Checks to see that the supplied user account has access to the requested component diff --git a/TGServerService/ServerInstance/ServerInstance.cs b/TGServerService/ServerInstance/ServerInstance.cs index ec239dcb80..a92406939d 100644 --- a/TGServerService/ServerInstance/ServerInstance.cs +++ b/TGServerService/ServerInstance/ServerInstance.cs @@ -51,6 +51,7 @@ namespace TGServerService DisposeByond(); DisposeRepo(); DisposeChat(); + DisposeAdministration(); Config.Save(); } diff --git a/TGServerService/Service.cs b/TGServerService/Service.cs index a47c89511b..5634597406 100644 --- a/TGServerService/Service.cs +++ b/TGServerService/Service.cs @@ -15,7 +15,7 @@ namespace TGServerService /// The windows service the application runs as /// [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.Single)] - class Service : ServiceBase, ITGSService, ITGConnectivity + class Service : ServiceBase, ITGSService, ITGConnectivity, ITGLanding, ITGInstanceManager { /// /// The logging ID used for events @@ -233,9 +233,9 @@ namespace TGServerService void SetupService() { serviceHost = CreateHost(this, Interface.MasterInterfaceName); - AddEndpoint(serviceHost, typeof(ITGSService)); - AddEndpoint(serviceHost, typeof(ITGConnectivity)); - serviceHost.Authorization.ServiceAuthorizationManager = new AdministrativeAuthorizationManager(); //only admins can diddle us + foreach (var I in Interface.ValidServiceInterfaces) + AddEndpoint(serviceHost, I); + serviceHost.Authorization.ServiceAuthorizationManager = new RootAuthorizationManager(); //only admins can diddle us } /// @@ -350,7 +350,7 @@ namespace TGServerService var host = CreateHost(instance, String.Format("{0}/{1}", Interface.InstanceInterfaceName, instanceName)); hosts.Add(instanceName, host); - foreach (var J in Interface.ValidInterfaces) + foreach (var J in Interface.ValidInstanceInterfaces) AddEndpoint(host, J); host.Authorization.ServiceAuthorizationManager = instance; diff --git a/TGServerService/TGServerService.csproj b/TGServerService/TGServerService.csproj index 375c542010..97aa35035d 100644 --- a/TGServerService/TGServerService.csproj +++ b/TGServerService/TGServerService.csproj @@ -92,7 +92,7 @@ - + diff --git a/TGServiceInterface/Components/Connectivity.cs b/TGServiceInterface/Components/Connectivity.cs index 81975e6f84..d3077d3dd9 100644 --- a/TGServiceInterface/Components/Connectivity.cs +++ b/TGServiceInterface/Components/Connectivity.cs @@ -13,12 +13,5 @@ namespace TGServiceInterface.Components /// [OperationContract] void VerifyConnection(); - - /// - /// Retrieve's the service's version - /// - /// The service's version - [OperationContract] - string Version(); } } diff --git a/TGServiceInterface/Components/Instance.cs b/TGServiceInterface/Components/Instance.cs index 9172aee46b..c4c771d4ef 100644 --- a/TGServiceInterface/Components/Instance.cs +++ b/TGServiceInterface/Components/Instance.cs @@ -14,5 +14,12 @@ namespace TGServiceInterface.Components /// The path to the directory on success, null on failure [OperationContract] string ServerDirectory(); + + /// + /// Retrieve's the service's version + /// + /// The service's version + [OperationContract] + string Version(); } } diff --git a/TGServiceInterface/Components/InstanceManager.cs b/TGServiceInterface/Components/InstanceManager.cs new file mode 100644 index 0000000000..3467c009c1 --- /dev/null +++ b/TGServiceInterface/Components/InstanceManager.cs @@ -0,0 +1,62 @@ +using System.ServiceModel; + +namespace TGServiceInterface.Components +{ + /// + /// Used for managing s + /// + [ServiceContract] + public interface ITGInstanceManager + { + /// + /// Creates a new + /// + /// The name of the instance + /// The path to the instance + /// on success, error message on failure + [OperationContract] + string CreateInstance(string Name, string path); + + /// + /// Registers an existing server instance + /// + /// The path to the instance + /// on success, error message on failure + [OperationContract] + string ImportInstance(string path); + + /// + /// Checks if an instance is online + /// + /// The name of the instance + /// if the Instance exists and is online, otherwise + [OperationContract] + bool InstanceEnabled(string Name); + + /// + /// Sets an instance's enabled status + /// + /// The instance whom's status should be changed + /// to enable the instance, to disable it + /// on success, error message on failure + [OperationContract] + string SetInstanceEnabled(string Name, bool enabled); + + /// + /// Renames an instance, this will restart the instance if it is enabled + /// + /// The current name of the instance + /// The new name of the instance + /// on success, error message on failure + [OperationContract] + string RenameInstance(string name, string new_name); + + /// + /// Disables and unregisters an instance, allowing the folder and data to be manipulated manually + /// + /// The instance to detach + /// on success, error message on failure + [OperationContract] + string DetachInstance(string name); + } +} diff --git a/TGServiceInterface/Components/Landing.cs b/TGServiceInterface/Components/Landing.cs new file mode 100644 index 0000000000..42bbf2706c --- /dev/null +++ b/TGServiceInterface/Components/Landing.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; +using System.ServiceModel; + +namespace TGServiceInterface.Components +{ + /// + /// Used for general authentication and listing s + /// + public interface ITGLanding + { + /// + /// Retrieve's the service's version + /// + /// The service's version + [OperationContract] + string Version(); + + /// + /// List instances that the caller can access + /// + /// A of instance names relating to their paths + [OperationContract] + IList ListInstances(); + } +} diff --git a/TGServiceInterface/Components/Service.cs b/TGServiceInterface/Components/Service.cs index e9057d957c..d9fecd397f 100644 --- a/TGServiceInterface/Components/Service.cs +++ b/TGServiceInterface/Components/Service.cs @@ -16,13 +16,6 @@ namespace TGServiceInterface.Components [OperationContract] void PrepareForUpdate(); - /// - /// Retrieve's the service's version - /// - /// The service's version - [OperationContract] - string Version(); - /// /// Get the port used for remote operation /// @@ -40,62 +33,11 @@ namespace TGServiceInterface.Components string SetRemoteAccessPort(ushort port); /// - /// List instances + /// Retrieve's the service's version /// - /// A of instance names relating to their paths + /// The service's version [OperationContract] - IList ListInstances(); - - /// - /// Creates a new server instance - /// - /// The name of the instance - /// The path to the instance - /// on success, error message on failure - [OperationContract] - string CreateInstance(string Name, string path); - - /// - /// Registers an existing server instance - /// - /// The path to the instance - /// on success, error message on failure - [OperationContract] - string ImportInstance(string path); - - /// - /// Checks if an instance is online - /// - /// The name of the instance - /// if the Instance exists and is online, otherwise - [OperationContract] - bool InstanceEnabled(string Name); - - /// - /// Sets an instance's enabled status - /// - /// The instance whom's status should be changed - /// to enable the instance, to disable it - /// on success, error message on failure - [OperationContract] - string SetInstanceEnabled(string Name, bool enabled); - - /// - /// Renames an instance, this will restart the instance if it is enabled - /// - /// The current name of the instance - /// The new name of the instance - /// on success, error message on failure - [OperationContract] - string RenameInstance(string name, string new_name); - - /// - /// Disables and unregisters an instance, allowing the folder and data to be manipulated manually - /// - /// The instance to detach - /// on success, error message on failure - [OperationContract] - string DetachInstance(string name); + string Version(); /// /// Sets the path to the python 2.7 installation diff --git a/TGServiceInterface/Interface.cs b/TGServiceInterface/Interface.cs index 34b9003911..4a3bd34b5b 100644 --- a/TGServiceInterface/Interface.cs +++ b/TGServiceInterface/Interface.cs @@ -52,17 +52,17 @@ namespace TGServiceInterface bool VersionMismatch(out string errorMessage); /// - /// Returns the requested component for the instance . This does not guarantee a successful connection. s created this way are recycled for minimum latency and bandwidth usage + /// Returns the requested component for the instance . This does not guarantee a successful connection. /// /// The component to retrieve /// The correct component T GetComponent(); /// - /// Returns the component for the service + /// Returns a root service component /// /// The component for the service - ITGSService GetService(); + T GetServiceComponent(); /// /// Used to test if the is avaiable on the target machine. Note that state can change at any time and any call into the may throw an exception because of communcation errors @@ -82,9 +82,14 @@ namespace TGServiceInterface sealed public class Interface : IInterface { /// - /// List of s that can be used with and + /// List of s that can be used with /// - public static readonly IList ValidInterfaces = CollectComponents(); + public static readonly IList ValidServiceInterfaces = new List { typeof(ITGSService), typeof(ITGInstanceManager), typeof(ITGConnectivity), typeof(ITGLanding) }; + + /// + /// List of s that can be used with + /// + public static readonly IList ValidInstanceInterfaces = CollectComponents(); /// /// The maximum message size to and from a local server @@ -145,13 +150,13 @@ namespace TGServiceInterface /// A of s that can be used with the service static IList CollectComponents() { - var ServiceComponent = typeof(ITGSService); //this is special - //find all interfaces in this assembly in this namespace that have the service contract attribute + var ConnectivityComponent = typeof(ITGConnectivity); + //find all interfaces in this assembly in this namespace that have the service contract attribute var query = from t in Assembly.GetExecutingAssembly().GetTypes() where t.IsInterface - && t.Namespace == ServiceComponent.Namespace + && t.Namespace == ConnectivityComponent.Namespace && t.GetCustomAttribute(typeof(ServiceContractAttribute)) != null - && t != ServiceComponent + && (t == ConnectivityComponent || !ValidServiceInterfaces.Contains(t)) select t; return query.ToList(); } @@ -288,7 +293,7 @@ namespace TGServiceInterface /// public bool VersionMismatch(out string errorMessage) { - var splits = GetService().Version().Split(' '); + var splits = GetServiceComponent().Version().Split(' '); var theirs = new Version(splits[splits.Length - 1].Substring(1)); var ours = new Version(FileVersionInfo.GetVersionInfo(System.Reflection.Assembly.GetExecutingAssembly().Location).FileVersion); if(theirs.Major != ours.Major || theirs.Minor != ours.Minor || theirs.Revision != ours.Revision) //don't care about the patch level @@ -314,7 +319,7 @@ namespace TGServiceInterface public T GetComponent() { var ToT = typeof(T); - if (!ValidInterfaces.Contains(ToT) && ToT != typeof(ITGSService)) + if (!ValidInstanceInterfaces.Contains(ToT)) throw new Exception("Invalid type!"); return GetComponentImpl(true); } @@ -357,9 +362,12 @@ namespace TGServiceInterface } /// - public ITGSService GetService() + public T GetServiceComponent() { - return GetComponentImpl(false); + var ToT = typeof(T); + if (!ValidServiceInterfaces.Contains(ToT)) + throw new Exception("Invalid type!"); + return GetComponentImpl(false); } /// @@ -420,10 +428,9 @@ namespace TGServiceInterface error = e.ToString(); return ConnectivityLevel.None; } - var service = GetService(); try { - service.Version(); + GetServiceComponent().Version(); } catch(Exception e) { @@ -432,8 +439,7 @@ namespace TGServiceInterface } try { - // TODO - + GetServiceComponent().Version(); error = null; return ConnectivityLevel.Administrator; } diff --git a/TGServiceInterface/TGServiceInterface.csproj b/TGServiceInterface/TGServiceInterface.csproj index 5e9befc3be..cabc4e5c69 100644 --- a/TGServiceInterface/TGServiceInterface.csproj +++ b/TGServiceInterface/TGServiceInterface.csproj @@ -54,6 +54,8 @@ + + From 515764821ecf07583c2556fef2f14fb1df9949c0 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 11:01:45 -0500 Subject: [PATCH 03/11] Removes direct instance connection from CP --- TGControlPanel/Login.cs | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/TGControlPanel/Login.cs b/TGControlPanel/Login.cs index 75b1a508b3..1a63abd79c 100644 --- a/TGControlPanel/Login.cs +++ b/TGControlPanel/Login.cs @@ -73,28 +73,8 @@ namespace TGControlPanel MessageBox.Show("Authentication error: Username/password/windows identity is not authorized! Ensure you are a system administrator or in the correct Windows group on the service machine."); return; } - - if (!res.HasFlag(ConnectivityLevel.Administrator)) - { - while (true) - { - var InstanceToConnectTo = Program.TextPrompt("Select instance", "You do not have permission to list server instances. Please enter the name of the instance to connect to:"); - if (InstanceToConnectTo == null) - return; - - res = I.ConnectToInstance(InstanceToConnectTo); - if (!res.HasFlag(ConnectivityLevel.Connected)) - MessageBox.Show("Unable to connect to instance! Does it exist?"); - else if (!res.HasFlag(ConnectivityLevel.Authenticated)) - MessageBox.Show("The current user is not authorized to access this instance!"); - else - break; - } - - new ControlPanel(I).Show(); - } - else - new InstanceSelector(I).Show(); + + new InstanceSelector(I).Show(); Close(); } catch From cbcde73c5182e36b67d904e7c9e7dec108f07879 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 11:15:10 -0500 Subject: [PATCH 04/11] Adds missing ServiceContractAttribute to ITGLanding --- TGServiceInterface/Components/Landing.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TGServiceInterface/Components/Landing.cs b/TGServiceInterface/Components/Landing.cs index 42bbf2706c..a1d18c8c88 100644 --- a/TGServiceInterface/Components/Landing.cs +++ b/TGServiceInterface/Components/Landing.cs @@ -6,6 +6,7 @@ namespace TGServiceInterface.Components /// /// Used for general authentication and listing s /// + [ServiceContract] public interface ITGLanding { /// From 5f4c30b0809a90c6fdeac888f34ba48842fdcf09 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 11:46:02 -0500 Subject: [PATCH 05/11] Cleanup and add missing functionality to InstanceSelector --- TGControlPanel/InstanceSelector.Designer.cs | 33 +++++++- TGControlPanel/InstanceSelector.cs | 84 +++++++++++++++++---- 2 files changed, 103 insertions(+), 14 deletions(-) diff --git a/TGControlPanel/InstanceSelector.Designer.cs b/TGControlPanel/InstanceSelector.Designer.cs index 4b07446a17..cfaf0a5ab5 100644 --- a/TGControlPanel/InstanceSelector.Designer.cs +++ b/TGControlPanel/InstanceSelector.Designer.cs @@ -36,6 +36,8 @@ this.RenameInstanceButton = new System.Windows.Forms.Button(); this.DetachInstanceButton = new System.Windows.Forms.Button(); this.RefreshButton = new System.Windows.Forms.Button(); + this.ConnectButton = new System.Windows.Forms.Button(); + this.EnabledCheckBox = new System.Windows.Forms.CheckBox(); this.SuspendLayout(); // // InstanceListBox @@ -46,6 +48,7 @@ this.InstanceListBox.Name = "InstanceListBox"; this.InstanceListBox.Size = new System.Drawing.Size(339, 238); this.InstanceListBox.TabIndex = 0; + this.InstanceListBox.SelectedIndexChanged += new System.EventHandler(this.InstanceListBox_SelectedIndexChanged); // // CreateInstanceButton // @@ -94,7 +97,7 @@ // RefreshButton // this.RefreshButton.Anchor = System.Windows.Forms.AnchorStyles.Right; - this.RefreshButton.Location = new System.Drawing.Point(358, 226); + this.RefreshButton.Location = new System.Drawing.Point(358, 195); this.RefreshButton.Name = "RefreshButton"; this.RefreshButton.Size = new System.Drawing.Size(148, 25); this.RefreshButton.TabIndex = 19; @@ -102,12 +105,37 @@ this.RefreshButton.UseVisualStyleBackColor = true; this.RefreshButton.Click += new System.EventHandler(this.RefreshButton_Click); // + // ConnectButton + // + this.ConnectButton.Anchor = System.Windows.Forms.AnchorStyles.Right; + this.ConnectButton.Location = new System.Drawing.Point(358, 226); + this.ConnectButton.Name = "ConnectButton"; + this.ConnectButton.Size = new System.Drawing.Size(148, 25); + this.ConnectButton.TabIndex = 20; + this.ConnectButton.Text = "Connect"; + this.ConnectButton.UseVisualStyleBackColor = true; + this.ConnectButton.Click += new System.EventHandler(this.ConnectButton_Click); + // + // EnabledCheckBox + // + this.EnabledCheckBox.AutoSize = true; + this.EnabledCheckBox.ForeColor = System.Drawing.Color.White; + this.EnabledCheckBox.Location = new System.Drawing.Point(396, 149); + this.EnabledCheckBox.Name = "EnabledCheckBox"; + this.EnabledCheckBox.Size = new System.Drawing.Size(65, 17); + this.EnabledCheckBox.TabIndex = 21; + this.EnabledCheckBox.Text = "Enabled"; + this.EnabledCheckBox.UseVisualStyleBackColor = true; + this.EnabledCheckBox.CheckedChanged += new System.EventHandler(this.EnabledCheckBox_CheckedChanged); + // // InstanceSelector // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(40)))), ((int)(((byte)(34))))); this.ClientSize = new System.Drawing.Size(518, 261); + this.Controls.Add(this.EnabledCheckBox); + this.Controls.Add(this.ConnectButton); this.Controls.Add(this.RefreshButton); this.Controls.Add(this.DetachInstanceButton); this.Controls.Add(this.RenameInstanceButton); @@ -119,6 +147,7 @@ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Server Instances"; this.ResumeLayout(false); + this.PerformLayout(); } @@ -130,5 +159,7 @@ private System.Windows.Forms.Button RenameInstanceButton; private System.Windows.Forms.Button DetachInstanceButton; private System.Windows.Forms.Button RefreshButton; + private System.Windows.Forms.Button ConnectButton; + private System.Windows.Forms.CheckBox EnabledCheckBox; } } \ No newline at end of file diff --git a/TGControlPanel/InstanceSelector.cs b/TGControlPanel/InstanceSelector.cs index 15f3f9e360..318b3d5c30 100644 --- a/TGControlPanel/InstanceSelector.cs +++ b/TGControlPanel/InstanceSelector.cs @@ -8,7 +8,7 @@ using TGServiceInterface.Components; namespace TGControlPanel { /// - /// Form used for managing manipulation functions + /// Form used for managing manipulation functions /// partial class InstanceSelector : CountedForm { @@ -20,6 +20,11 @@ namespace TGControlPanel /// List of from /// IList InstanceData; + /// + /// Used for modifying without invoking its side effects + /// + bool UpdatingEnabledCheckbox = false; + public InstanceSelector(IInterface I) { InitializeComponent(); @@ -48,15 +53,13 @@ namespace TGControlPanel } /// - /// Connects to a if it is double clicked in + /// Connects to a if it is double clicked in /// /// The sender of the event /// The void InstanceListBox_MouseDoubleClick(object sender, MouseEventArgs e) { - var index = InstanceListBox.IndexFromPoint(e.Location); - if (index != ListBox.NoMatches) - TryConnectToInstance(InstanceData[index].Name); + TryConnectToIndexInstance(InstanceListBox.IndexFromPoint(e.Location)); } /// @@ -88,15 +91,26 @@ namespace TGControlPanel }); foreach(var I in InstanceData) InstanceListBox.Items.Add(String.Format("{0}: {1} - {2} - {3}", I.LoggingID, I.Name, I.Path, I.Enabled ? "ONLINE" : "OFFLINE")); + var HasServerAdmin = masterInterface.ConnectionStatus().HasFlag(ConnectivityLevel.Administrator); + CreateInstanceButton.Enabled = HasServerAdmin; + ImportInstanceButton.Enabled = HasServerAdmin; + RenameInstanceButton.Enabled = HasServerAdmin; + DetachInstanceButton.Enabled = HasServerAdmin; + EnabledCheckBox.Enabled = HasServerAdmin; + if(InstanceData.Count > 0) + InstanceListBox.SelectedIndex = 0; } /// - /// Tries to start a for a given + /// Tries to start a for a given /// - /// The name of the to connect to - async void TryConnectToInstance(string instanceName) + /// The of to connect to + async void TryConnectToIndexInstance(int index) { - if(ControlPanel.InstancesInUse.TryGetValue(instanceName, out ControlPanel activeCP)) + if (index == ListBox.NoMatches) + return; + var instanceName = InstanceData[index].Name; + if (ControlPanel.InstancesInUse.TryGetValue(instanceName, out ControlPanel activeCP)) { activeCP.BringToFront(); return; @@ -136,7 +150,7 @@ namespace TGControlPanel if (MessageBox.Show(String.Format("This will dissociate the server instance at \"{0}\"! Are you sure?", imd.Path), "Instance Detach", MessageBoxButtons.YesNo) != DialogResult.Yes) return; string res = null; - await WrapServerOp(() => { res = masterInterface.GetServiceComponent().DetachInstance(imd.Name); }); + await WrapServerOp(() => res = masterInterface.GetServiceComponent().DetachInstance(imd.Name)); if (res != null) MessageBox.Show(res); RefreshInstances(); @@ -168,7 +182,7 @@ namespace TGControlPanel if (imd.Enabled && MessageBox.Show(String.Format("This will temporarily offline the server instance! Are you sure?", imd.Path), "Instance Restart", MessageBoxButtons.YesNo) != DialogResult.Yes) return; string res = null; - await WrapServerOp(() => { res = masterInterface.GetServiceComponent().RenameInstance(imd.Name, new_name); }); + await WrapServerOp(() => res = masterInterface.GetServiceComponent().RenameInstance(imd.Name, new_name)); if (res != null) MessageBox.Show(res); RefreshInstances(); @@ -185,7 +199,7 @@ namespace TGControlPanel if (instance_path == null) return; string res = null; - await WrapServerOp(() => { res = masterInterface.GetServiceComponent().ImportInstance(instance_path); }); + await WrapServerOp(() => res = masterInterface.GetServiceComponent().ImportInstance(instance_path)); if (res != null) MessageBox.Show(res); RefreshInstances(); @@ -205,10 +219,54 @@ namespace TGControlPanel if (instance_path == null) return; string res = null; - await WrapServerOp(() => { res = masterInterface.GetServiceComponent().CreateInstance(instance_name, instance_path); }); + await WrapServerOp(() => res = masterInterface.GetServiceComponent().CreateInstance(instance_name, instance_path)); if (res != null) MessageBox.Show(res); RefreshInstances(); } + + /// + /// Attempts to connect the user to an based on the of + /// + /// The sender of the event + /// The + private void ConnectButton_Click(object sender, EventArgs e) + { + TryConnectToIndexInstance(InstanceListBox.SelectedIndex); + } + + /// + /// Prompts the user if they want to call to either online or offline an based on its current state + /// + /// The sender of the event + /// The + async void EnabledCheckBox_CheckedChanged(object sender, EventArgs e) + { + if (UpdatingEnabledCheckbox) + return; + var enabling = EnabledCheckBox.Checked; + if (MessageBox.Show(String.Format("Are you sure you want to {0} this instance?", enabling ? "online" : "offline"), "Instance Status Change", MessageBoxButtons.YesNo) != DialogResult.Yes) + return; + string res = null; + await WrapServerOp(() => res = masterInterface.GetServiceComponent().SetInstanceEnabled(InstanceData[InstanceListBox.SelectedIndex].Name, enabling)); + if (res != null) + MessageBox.Show(res); + } + + /// + /// Update based on the selected 's property + /// + /// The sender of the event + /// The + void InstanceListBox_SelectedIndexChanged(object sender, EventArgs e) + { + var index = InstanceListBox.SelectedIndex; + if (index != ListBox.NoMatches) + { + UpdatingEnabledCheckbox = true; + EnabledCheckBox.Checked = InstanceData[index].Enabled; + UpdatingEnabledCheckbox = false; + } + } } } From 158bde237578d58d94f6d956fdaa848b520b158e Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 13:54:21 -0500 Subject: [PATCH 06/11] Fixes on/offlining an instance in the CP not updating the list --- TGControlPanel/InstanceSelector.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/TGControlPanel/InstanceSelector.cs b/TGControlPanel/InstanceSelector.cs index 318b3d5c30..82a92efc08 100644 --- a/TGControlPanel/InstanceSelector.cs +++ b/TGControlPanel/InstanceSelector.cs @@ -25,6 +25,10 @@ namespace TGControlPanel /// bool UpdatingEnabledCheckbox = false; + /// + /// Construct an + /// + /// An connected a the public InstanceSelector(IInterface I) { InitializeComponent(); @@ -248,9 +252,11 @@ namespace TGControlPanel if (MessageBox.Show(String.Format("Are you sure you want to {0} this instance?", enabling ? "online" : "offline"), "Instance Status Change", MessageBoxButtons.YesNo) != DialogResult.Yes) return; string res = null; - await WrapServerOp(() => res = masterInterface.GetServiceComponent().SetInstanceEnabled(InstanceData[InstanceListBox.SelectedIndex].Name, enabling)); + var index = InstanceListBox.SelectedIndex; + await WrapServerOp(() => res = masterInterface.GetServiceComponent().SetInstanceEnabled(InstanceData[index].Name, enabling)); if (res != null) MessageBox.Show(res); + RefreshInstances(); } /// From 0237e3b4f8fe38e995c677f9446d24ac3b3e6a50 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 13:55:04 -0500 Subject: [PATCH 07/11] Improves CP class declarations --- TGControlPanel/ControlPanel/ControlPanel.cs | 2 +- TGControlPanel/CountedForm.cs | 2 +- TGControlPanel/InstanceSelector.cs | 4 ++-- TGControlPanel/Login.cs | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/TGControlPanel/ControlPanel/ControlPanel.cs b/TGControlPanel/ControlPanel/ControlPanel.cs index 7a7ead308e..015bfccae7 100644 --- a/TGControlPanel/ControlPanel/ControlPanel.cs +++ b/TGControlPanel/ControlPanel/ControlPanel.cs @@ -10,7 +10,7 @@ namespace TGControlPanel /// /// The main form /// - partial class ControlPanel : CountedForm + sealed partial class ControlPanel : CountedForm { /// /// List of instances being used by open control panels diff --git a/TGControlPanel/CountedForm.cs b/TGControlPanel/CountedForm.cs index 064c2f9b23..9b442e756e 100644 --- a/TGControlPanel/CountedForm.cs +++ b/TGControlPanel/CountedForm.cs @@ -5,7 +5,7 @@ namespace TGControlPanel /// /// Calls when all s are d /// - class CountedForm : Form + abstract class CountedForm : Form { /// /// The current number of active s diff --git a/TGControlPanel/InstanceSelector.cs b/TGControlPanel/InstanceSelector.cs index 82a92efc08..315868f3cc 100644 --- a/TGControlPanel/InstanceSelector.cs +++ b/TGControlPanel/InstanceSelector.cs @@ -10,7 +10,7 @@ namespace TGControlPanel /// /// Form used for managing manipulation functions /// - partial class InstanceSelector : CountedForm + sealed partial class InstanceSelector : CountedForm { /// /// The we build instance connections from @@ -234,7 +234,7 @@ namespace TGControlPanel /// /// The sender of the event /// The - private void ConnectButton_Click(object sender, EventArgs e) + void ConnectButton_Click(object sender, EventArgs e) { TryConnectToIndexInstance(InstanceListBox.SelectedIndex); } diff --git a/TGControlPanel/Login.cs b/TGControlPanel/Login.cs index 1a63abd79c..364746a652 100644 --- a/TGControlPanel/Login.cs +++ b/TGControlPanel/Login.cs @@ -4,7 +4,7 @@ using TGServiceInterface; namespace TGControlPanel { - partial class Login : CountedForm + sealed partial class Login : CountedForm { /// /// Create a form From 3f00ffcec78215cdcd17c23f87c7a6719d032348 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 13:58:45 -0500 Subject: [PATCH 08/11] Fixes enable checkbox not reversing if the descision was cancelled in CP --- TGControlPanel/InstanceSelector.cs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/TGControlPanel/InstanceSelector.cs b/TGControlPanel/InstanceSelector.cs index 315868f3cc..238f422f04 100644 --- a/TGControlPanel/InstanceSelector.cs +++ b/TGControlPanel/InstanceSelector.cs @@ -249,14 +249,20 @@ namespace TGControlPanel if (UpdatingEnabledCheckbox) return; var enabling = EnabledCheckBox.Checked; - if (MessageBox.Show(String.Format("Are you sure you want to {0} this instance?", enabling ? "online" : "offline"), "Instance Status Change", MessageBoxButtons.YesNo) != DialogResult.Yes) - return; - string res = null; - var index = InstanceListBox.SelectedIndex; - await WrapServerOp(() => res = masterInterface.GetServiceComponent().SetInstanceEnabled(InstanceData[index].Name, enabling)); - if (res != null) - MessageBox.Show(res); - RefreshInstances(); + try + { + if (MessageBox.Show(String.Format("Are you sure you want to {0} this instance?", enabling ? "online" : "offline"), "Instance Status Change", MessageBoxButtons.YesNo) != DialogResult.Yes) + return; + string res = null; + var index = InstanceListBox.SelectedIndex; + await WrapServerOp(() => res = masterInterface.GetServiceComponent().SetInstanceEnabled(InstanceData[index].Name, enabling)); + if (res != null) + MessageBox.Show(res); + } + finally + { + RefreshInstances(); + } } /// From 5a1e8f2f842ed50c52b7d48c05f5ad7a4ca4c375 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 14:10:43 -0500 Subject: [PATCH 09/11] Fixes instances being detached when they are disabled --- TGServerService/Service.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/TGServerService/Service.cs b/TGServerService/Service.cs index 5634597406..2bb9cb32f6 100644 --- a/TGServerService/Service.cs +++ b/TGServerService/Service.cs @@ -277,7 +277,7 @@ namespace TGServerService WriteEntry(String.Format("Instance at {0} has a duplicate name! Detaching...", I.Directory), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); pathsToRemove.Add(I.Directory); } - if (SetupInstance(I) == null) + if (I.Enabled && SetupInstance(I) == null) pathsToRemove.Add(I.Directory); else seenNames.Add(I.Name); @@ -331,7 +331,6 @@ namespace TGServerService { var datInstance = ((ServerInstance)hosts[config.Directory].SingletonInstance); WriteEntry(String.Format("Unable to start instance at path {0}. Has the same name as instance at path {1}. Detaching...", config.Directory, datInstance.ServerDirectory()), EventID.InstanceInitializationFailure, EventLogEntryType.Error, LoggingID); - Properties.Settings.Default.InstancePaths.Remove(config.Directory); return null; } if (!config.Enabled) @@ -511,6 +510,8 @@ namespace TGServerService /// on success, error message on failure string SetupOneInstance(IInstanceConfig config) { + if (!config.Enabled) + return null; try { var host = SetupInstance(config); From dcce37d645f0754cd95601509f5c3e8166fe3a15 Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 14:15:55 -0500 Subject: [PATCH 10/11] Fixes newly onlined instances being listed as offline --- TGServerService/Service.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/TGServerService/Service.cs b/TGServerService/Service.cs index 2bb9cb32f6..9ab72310a6 100644 --- a/TGServerService/Service.cs +++ b/TGServerService/Service.cs @@ -600,6 +600,7 @@ namespace TGServerService { path = ic.Directory; ic.Enabled = true; + ic.Save(); return SetupOneInstance(ic); } } From b124d61289f050bbd002445a0c185159463ef68c Mon Sep 17 00:00:00 2001 From: Cyberboss Date: Wed, 8 Nov 2017 14:17:42 -0500 Subject: [PATCH 11/11] Removes unecessary try/catch --- TGServerService/Service.cs | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/TGServerService/Service.cs b/TGServerService/Service.cs index 9ab72310a6..51e7149592 100644 --- a/TGServerService/Service.cs +++ b/TGServerService/Service.cs @@ -590,25 +590,14 @@ namespace TGServerService { if (hostIsOnline) return null; - //now this is a bit awkward because we need to check each instance config for the one named Name - string LastCheckedConfig = null; - try - { - foreach (var ic in GetInstanceConfigs()) + foreach (var ic in GetInstanceConfigs()) + if (ic.Name == Name) { - if (ic.Name == Name) - { - path = ic.Directory; - ic.Enabled = true; - ic.Save(); - return SetupOneInstance(ic); - } + path = ic.Directory; + ic.Enabled = true; + ic.Save(); + return SetupOneInstance(ic); } - } - catch (Exception e) - { - return String.Format("An error occurred while checking instance config at {0}! Error: ", LastCheckedConfig, e.ToString()); - } return String.Format("Instance {0} does not exist!", Name); } else